Archive for May, 2007

Working with UTF-8 in PDF::Writer and Ruby on Rails

Googling for information on how to use PDF::Writer shows that there are many european developers frustrated with the lack of UTF-8 support in PDF::Writer. As Ruby on Rails works great with UTF-8 these days this can be a bit of an issue.

Part of the problem lies in the fact that the PDF specification (at least up to 1.6) does not support UTF-8 (you can use UTF-16 if you like). I had the misfortune of plowing thorugh it a couple of years ago when developing a PDF form filler library for a customer (don’t ask).

In Ruby on Rails, this is easy to solve as long as you only use Latin characters with diacritics. The solution is to switch encoding back to ISO-8859-15 for text strings you feed to PDF::Writer.

A simple extension to the String class will do the trick:

class String
  require 'iconv'
  def to_iso
    c = Iconv.new('ISO-8859-15','UTF-8')
    c.iconv(self)
  end
end

If you are working in Rails you can put this code in the lib folder (I usually call the file string_extensions.rb).

Then, when you call the text method on your PDF::Writer intance you can easily pass a correctly encoded string.

Overriding PDF::Writer text method

A much cleaner approach, as Aníbal describes in the comment below, is to override PDF::Writer’s text method.

Put the following code in a file called pdfwriter_extensions.rb (or whatever you choose to call it) in your lib directory:

CONVERTER = Iconv.new( 'ISO-8859-15//IGNORE//TRANSLIT', 'utf-8')

module PDF
	class Writer
		alias_method :old_text, :text

		def text(textto, options = {})
			old_text(CONVERTER.iconv(textto), options)
		end

	end
end

In your controller that handles the PDF output you add:

  require 'pdf/writer'
  require 'pdfwriter_extensions'

…after which you can use PDF::Writer like in the tutorial:

    pdf = PDF::Writer.new
    pdf.select_font "Helvetica", :encoding => nil 
    pdf.text "User name: <b>#{@user.name}</b>", :font_size => 16, :justification => :left
    send_data pdf.render, :disposition => 'inline', :filename => "user_details.pdf", :type => "application/pdf"

Enterprise Rails Deployment Getting Closer (thanks to Ola Bini and the JRuby team)…

Let’s forget about that for a while. Ola Bini and the JRuby team is quickly moving forward with something I would consider a breakthrough in Rails deployment options. In fact, it could well mean a breakthrough in Rails adoption in many organizations. Read more…

First impressions of Mercurial (as an alternative to subversion)

So, I was in the mall the other day where I bumped into Marcus Ahnve. He mentioned that he had been using Mercurial instead of Subversion for his latest project.

Just before I met Marcus I had been coding on a rails project housed in subversion. I was sitting in a cafe without internet access which means that it wasn’t possible to commit changes to subversion. As my son was asleep time was scarce and I wanted to get as much done as possible. So what do you do? Well I continued coding on a different part of the application and in the end I had a fairly large changeset waiting to be committed.

This makes for bad coding practices. A large changeset is more likely to create problems for your colleagues when the do an update from the repository. I really wanted to be able to create several changesets offline and put them back in when my connection was restored.

Trying Mercurial as an alternative to Subversion

This is where Mercurial comes in. With Mercurial it is easy to create changesets when you are offline. These can be pushed to a central repository (of you have one).

Installing Mercurial in a shared hosting account should be easy if you have access to ssh, Python and Apache. Following the step by step instructions by Bill de hÓra it was easy to get Mercurial running on TextDrive.

My initial impression is that mercurial looks very promising:

  • Mercurial commands are very similar to those of subversion and it was easy to set up a new repository.
  • The web interface looks very nice compared to that of subversion.
  • Capistrano can be used with mercurial.
  • It feels marginally snappier than subversion.
  • Mercurial doesn’t litter your folder tree with myriads of folders (just one in the root folder).

The next step is to migrate my subversion repository history using Tailor. If that goes well I may well become a mercurial switcher.