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"

Installing an e-ID in 47 Simple Steps (Not Counting the Eternal Loop)

(Please note that this post is from 2007 and things have become much better).

When you are on parental leave you have to register which days you are away fro work with the Swedish Social Insurance Agency. To access the online services of an agency you have to have an electronic ID. In Sweden this is a locally installed certificate issued by your bank or large telecom provider.

In my case my identity is checked by my bank and then I am forwarded to Telia, which handles the process of generating the ceritificate and installing the appropriate software on my computer. What could have been a simple well guided procedure is instead an exercise in ambiguity and a complete lack of usability:

  • The process involves 47 (!) steps,
  • an eternal loop (yes, really),
  • require you to install a new browser,
  • configuring the same browser to run in Rosetta mode and
  • a revoked server certificate (for the server that generates my certificate!).

I seriously doubt that non-programmers manage to install and use one of these certificates. Let’s go through the steps required to install an electronic ID in Sweden:


  1. We start at the the Social Insurance Agency and choose the login link.
  2. To login you need an electronic ID. Fair enough. I am redirected to the electronic ID information page.
  3. The electronic ID info page tells me to get an ID through my bank.
  4. I visit my bank and login.
  5. My bank seems to have done their homework. It is easy to find the e-ID link.
  6. To prove my identity I use the device provded by the bank.
  7. After proving my identity my bank informs me that they will redirect me to Telia, the once-was state-run monopoly telco.
  8. Telia greets me with a wizard-like interface that looks like a standard Windows 98 dialog window. It is, however, a regular HTML page that someone forgot to test in Safari.
  9. Clicking the “Next” button displays a text informing me that I have the wrong web browser. This service only works with Firefox. Okidokee.
  10. I visit the Mozilla website and download Firefox for my platform.
  11. We start again by visiting the bank with Firefox this time.
  12. History repeats itself.
  13. I once again prove my identity to the bank and…
  14. …get forwarded to Telia.
  15. The welcome page looks familiar. However, someone forgot to test this in Firefox. The text is now in Times Roman and barely readable.
  16. Telia asks me to accept their tems and conditions. Ok.
  17. I am now informed that I am using an Intel Mac. For my e-ID to work I have to “activate Rosetta”. A step by step instruction tells me to set Firefox to run in Rosetta mode and then restart Firefox. Am I supposed to do this now? The instructions continue and tell me that “software for Linux has to be installed manually”. And then there is a “Next” button. Thank you for narrowing ot down to three choices in this step. I decide to go with the first instruction.
  18. I set Firefox to run in Rosetta mode.
  19. And then I restart Firefox as per the instructions.
  20. Firefox is restarted (rather sluggish due to running it in Rosetta mode) and page is displayed. The page says that an “unexpected error has occurred. Try again in 10 minutes”. I wait 10 minutes and reload the page, same result. No further instructions. Maybe I have to start the proccess again?
  21. So, I go back to the bank for the third time.
  22. I prove my identity o them again and get redirected to telia again.
  23. Hello! You look familiar.
  24. I accept the terms and conditions again and click the “Next” button.
  25. A new page appears and a warning message from Firefox asking me if I want to install a security module named Net ID. The text in the wizard talks about downloading stuff for Linux to my desktop. Do I have to do both? I accept the Net ID install question even if “libiidp11.dylib” sounds scary.
  26. After clicking OK Firefox displays an alert informing me that a “new security module has been installed”. I click OK. There is still a text that tells me to download something to my desktop and run it there. Should I, or was it just installed for me? I decide to skip that and click the “Next” button instead.
  27. Ok, now I have to choose a password for my e-ID. Looks like everything was alright in the previous step then. I enter a password and click the “Next” button.
  28. A progress bar appears. My e-ID is being created it seems. When the progressbar completes I click the “Next” button.
  29. A message appears saying that my ID and the required software was successfully installed. Sounds nice. It also tells me that since I am using Firefox I have to restart the browser. There is also a button which says “Complete process”. Should I restart the browser now or click the button? I choose to click the “Complete process” button.
  30. The layout tells me that this isn’t part of the previous wizard. The text starts with an introduction to what e-IDs are and then goes on to tell me that I have to “upgrade” my e-ID. There is also a button that says “upgrade”. I click the “upgrade” button.
  31. Bang! Firefox displays a certificate warning. Has the site been hijacked? Hard to say. What are the odds that a certificate issuer is using untrusted certificates on their own site? Low I guess. I decide to go with Firefox’ recommendation and trust the site for this session.
  32. I am back in the fake Windows dialog interface again. This time it says that it will guide me through an “upgrade” of my e-ID and software. Sounds ok. I click the “Next” button.
  33. The next dialog looks familiar. The text tells me to download software to my desktop for installation if I am using Linux but the Firefox confirmation dialog asks if it is OK to install a security module. Must be the software upgrade so I click OK even if “libiidp11.dylib” sounds scary.
  34. Firefox displays an alert: “the security module already exists”. Does this mean the upgrade wasn’t needed? What do I have to do? I click OK and then I click the “Next” button.
  35.  Getting tired of describing each step…
  36. Win!

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.