Install Prawn gem in SketchUp 2016

Hi All,

When I trying to install prawn gem in SketchUp 2016, it’s showing error.

Gem::install "prawn"
Error: #<Gem::SpecificGemNotFoundException: Could not find a valid gem 'prawn' (>= 0) locally or in a repository>
C:/Program Files/SketchUp/SketchUp 2016/Tools/RubyStdLib/rubygems/dependency_installer.rb:301:in `find_spec_by_name_and_version'
C:/Program Files/SketchUp/SketchUp 2016/Tools/RubyStdLib/rubygems/dependency_installer.rb:110:in `available_set_for'
C:/Program Files/SketchUp/SketchUp 2016/Tools/RubyStdLib/rubygems/dependency_installer.rb:322:in `install'
C:/Program Files/SketchUp/SketchUp 2016/Tools/RubyStdLib/rubygems.rb:526:in `install'
<main>:in `<main>'
SketchUp:1:in `eval'

Anyone, please help me for install prawn gem in sketchup 2016.

Thanks,
Siva S

1 Like

I wasn’t able to install in SU2016 either.

I was however able to installer in newer SU versions, SU2017 and SU2018.

My guess is that the rubygems version in SU2016 is too old to connect to the RubyGems repository. (I’m actually surprised there isn’t an error in that respect.)

I’m not sure if you are able to patch it, the gems system inside a desktop application is a tricky thing.

Note that the gem system isn’t something we’re supporting. There are number of issues with using it in SU.

  • We’re not able to apply patches to RubyGems for older SU versions. So whenever they make changes that require an update to RubyGems we’re stuck.
  • We’ve been struggling with OpenSSL issues over the years. Certificates getting out of date eventually, which suffer the same problem with RubyGems in that we cannot provide a patch. There’s also been bugs in Ruby that’s caused issues.
  • When OpenSSL have worked, in the current versions on Windows it can cause SU to hang/freeze for a very long time (many minutes). (This should be fixed in newer OpenSSL versions, but for that we’ll need to upgrade Ruby inside of SU)
  • If using gems for an extension you plan to publish, then you’d risk clashing with other extensions trying to use a different version of the gem.
  • Some gems require compilation, which under Windows require DevKit. This isn’t available on users machines. Nor is DevKit able to detect SketchUp’s Ruby.

Our recommendation if you want to use gems for your extension development is:

  • Use standalone Ruby (matching the versions for your target SketchUp) and install the gem there. Then you can copy the gem to your extension.
  • Make sure to wrap the gem into your own namespace so you don’t clash with other extensions. (If you only use it for your own development then you don’t need to do that step.)
1 Like

I have prawn v 2.1.0 installed into SketchUp 2016 appraently successfully.
It is the last version of prawn before they bumped the required Ruby version up to 2.1.
It seems I installed it back in May of 2016.

If I type …

require "prawn"

… at the console I get true returned.

So, try this …

Gem::install( "prawn", "2.1.0" )
2 Likes

Ah, yea. Ruby 2.0 have long since reached end of life and Ruby community in general is starting to drop support. (One of the reasons why we updated to Ruby 2.2 in SketchUp 2017)

2 Likes

What is the suggested way of wrapping the prawn gem into my own namespace. Sorry I’m not really familiar with Ruby gems yet but I would really like to try and implement the functionality of prawn into some of my plugins.

Would it be better just to have the plugin check to see if prawn is installed:

if (require "prawn")

and then install it like Dan’s line above:

Gem::install( "prawn", "2.x.x" )

or include the full gem with my plugin’s distribution (part of the .rbz file)?

This is not a correct install test. It is a load test.
IF you read the documentation for the Kernel#require method, you’ll realize you test will fail if Prawn is already loaded.

You’d need to get the source code, and modify it so it is within your namespace / plugin modules.
If it is a C extension, you’ll need to modify it and recompile it for whatever versions of Ruby your targeted SketchUp versions use for both OSX and MS Windows. (There are several topic threads here that already discuss this. Please search the forum.)


What does prawn really do for you ?

Generally speaking, adding in an external dependency that you have no control over will complicate your plugin maintenance in addition to all the problems using a gem with SketchUp can cause the end users.

1 Like

Prawn installs and runs fine on a mac, but it has 3 libraries that come in at 2.5 MB…

you really don’t want them loading each time the user opens SU…

so distribute them in your rbz, within your namespace and ‘Lazy Load’ only when needed…

the downside is encryption avoidance, as you are meant to only distribute in human readable form…

you can rename all the files to .txt when encrypting and then have a small File.rename() script invoked on first run…

I have done that successfully in the past…

the main issue with this and any of the gems that output printable pages is getting the users printer settings…

e.g. Prawn defaults to US Letter, but I use A4 Borderless for most output…

to a large extent SVG is a better option as it’s size can be set to content size…

there are SVG gems out there…

EDIT: I should add that your loader ‘should’ bypass all the gem files and directly load the ‘core’ loader from the gem files…

in my use it’s

# NB: my extensions gem folder
require_relative '/gems/jcb_prawn/prawn-2.2.2/lib/prawn.rb'

john

1 Like

I’m trying to find a good gem for generating PDF documents within the plugins, and prawn seems to fit the bill. I’m still learning and experimenting with it and seeing what I can do but it seems like the right solution for creating PDF documents.

However I am a little concerned with being able to set it up correctly so that I don’t bog down SketchUp, cause namespace collisions and create additional issues for my users.

it’s an excellent gem, and only bogs SU down if loaded on start, when there’s no need for it…

when someones using your tool, loading the core, which is only 435 829 bytes (709 KB on disk) for 130 items,
will barely register…

what’s it outputting to i.e. screen or print?

I can give you the mac code for the registered printer settings…

although it can be ‘iffy’ on laptops, desktops usually have a default printer…

john

1 Like

Disclaimer: Working with gems is way outside of my current comfort zone so if I ask a lot of dumb questions please excuse my ignorance.

I’m going to be outputting to a PDF file, the location of the file will be determined by the user using the “savepanel” method, basic SketchUp API. A very quick example would be:

require "prawn"

pdf_path = UI.savepanel("Medeek Wall - Export PDF Drawings", "", "mdkwall_test.pdf")

pdf = Prawn::Document.new
pdf.text "Hello World"

pdf.render_file pdf_path

This essentially just creates the PDF file and dumps it to the location / filename that I specified in the savepanel menu.

If I’m saving to a file (PDF) do I really need to worry about printer settings and all that? I wouldn’t think so.

Do you mean that the loader should load your copy of the gem in your statement here:

EDIT: I should add that your loader ‘should’ bypass all the gem files and directly load the ‘core’ loader from the gem files…

not if it’s text and ‘not to scale’ geometry, but if it’s a multi page ‘scaled’ template then yes…

require 'medeek_prawn' is better…

john

1 Like

You are correct in that it will probably be a multi page document that I create and I am also hoping to be able to let the user select the page size (eg. letter, tabloid, Arch C, Arch D, Arch E, etc…), not even sure if I can do that with prawn yet, but I’m assuming such a functionality exists.

I’ve only just started mucking around with this just last night so I’m not even really sure how it will all shake out but it does looking promising.

Along with setting the page size I would also be scaling some of the output from SU that I will be applying to the PDF document (user definable).

A few items with RubyGems (RG).

Essentially, RG does two things. First, it selects what gem(s) to install, then it installs them.

At present, even with RG 3.0.1, the gem selection process is ignorant of Ruby version constraints. It will chose the highest gem version that is compatible with your platform, and try to install it. If the chosen gem is incompatible with your Ruby version, you’ll have an error on install. Note that this can also be an issue with gem dependencies of the gem you’re installing.

If you really want to use/experiment with a gem, find the gem on RubyGems.org, and in the bottom right of the web page you’ll see ‘Required Ruby Version’. You need to find a version that is compatible with whatever Ruby version you’re using, given the SU version you’re targeting.

The Gem.install method takes a 2nd parameter that allows one to specify a version to install. If installing a single gem, Gem.install "prawn:1.1.0" might work, as it does from the CLI.

Lastly, and Windows specific. On the RG web page, you may see a gem listed with ‘x64-mingw32’. This indicates that the gem contains c source code, and the gem owner has been nice enough to compile it for Windows users. This type of gem always has Ruby version constraints, and is the only gem that will install on a normal SU installation.

Off Topic:

  1. The issues with RG and Ruby version constraints hopefully will be addressed soon, but the fixes may not be backported to earlier versions.

  2. Feel free to ping me re RG issues.

  3. In another thread discussing gems, I think I used the term ‘knowledgeable Ruby user’. I was in a hurry, apologies for that. I should have said ‘very knowledgeable stand-alone Ruby user’…

Happy New Year… Greg

1 Like

Since I want to maintain backward compatibility with SU 2016 I think it makes sense to go with prawn 2.1.0.

I just installed the gem in my local copy of SU 2017 Make for testing purposes and it does not appear to have any problems even though I have not taken the time to adjust the code for namespace collisions.

However, without extensive testing I probably cannot assume that it will not at some point have an issue with some other feature in SU that I am not using at the moment or some other plugin.

It would seem easier just to have some code that only runs when the PDF creation process is invoked that checks that prawn is installed and then installs it if necessary.

If I do have my own version of prawn (ie. medeek_prawn), how do I ensure that it will work on both Mac and Window?

As for sizing of documents the prawn methods are quite nice:

size_ARCHD = [1728, 2592] #24x36
pdf.start_new_page(:size => size_ARCHD, :layout => :landscape)
pdf.text "Landscape page"

Any page size is possible

Modify the source code by adding your extension’s namespace at its root. (Yes, tedious I know. But only way to assure you won’t clash with other extensions.)

Using Gem.install outside of a development environment is not good. There is no way to ensure it won’t clash with other extensions if they for instance try to use a different version of the gem. See more information in the rubocop-sketchup manual on the multiple issues of Gem.install: https://github.com/SketchUp/rubocop-sketchup/blob/master/manual/cops_requirements.md#sketchuprequirementsgeminstall

Bundle the modified gem with your RBZ. Modified to be nested under your own namespace.

2 Likes

The prawn gem has well over 100+ separate ruby files (.rb). To wrap this I would probably need to modify each and everyone of these files.

I have created a tool that combines an entire source of separate ruby files into 1 single .rb
I needed this because I also distribute modified gems in my extensions and thus had the same problem of needing it to wrap in my own namespace. Secondly, I prefer to distribute my entire extension in 1 file while I want to code it in separate files, so I use the same tool to combine my own sources.

I noticed prawn is using relative_require which my tool is not recognizing yet. But it should be a matter of minutes to add relative_require as well.

Feel free to PM me if you have any questions or interest in a single .rb

2 Likes

Is this a tool you might consider open sourcing? I see a few extensions that do this thing manually.

Coincidence is that today I have created a github repository where I want to gradually add examples, templates and tools for SketchUp Ruby developers: https://github.com/kengey/sketchup-dev-tools-and-examples
For now it only contains my example I wrote today to demonstrate how to store data persistently in Sketchup and how to use dependency injection. I will take your proposal to open source the above mentioned tool into consideration, without making promises. I have a double feeling about it. Since creating Sketchup extensions is my core business, having a tool to combine an infinite tree of source files into 1 gives me a slight advantage. On the other hand, it is not a masterpiece of code. Let me think about it.

2 Likes