Near Infinity

Introduction to PDF::TechBook

By Jim Clark

Apr 30, 2007

Recently I had an interest in producing PDF documents using Ruby on Rails.  A quick Google search brought me to a Ruby PDF library called PDF::Writer for Ruby written by Austin Ziegler.  As far as I can tell from the online manual PDF::Writer is a fairly robust library.  The manual was well written and generated by PDF::Writer itself, very impressive.  By reading Austin's introductory PDF::Writer article I was able to get up and running quickly.  The article demonstrates creating text, tables, drawings and inserting images.  However, I didn't need to do anything fancy like create charts or drawings (see the PACMAN example).   All I wanted was some basic header, text and code styling.  Out of the box PDF::Writer allows you to do these sort of things but it requires some additional work on your part.  PDF::Writer gives you the primitives to work with to create whatever you want, but I didn't have the time to go through the effort to create my own styling from scratch.  Fortunately, Austin extended PDF::Writer to create PDF::TechBook.  TechBook gives you the ability to mark up and style your content that can then be used to generate a PDF document.  This is a brief introduction to TechBook.

The TechBook class extends PDF::Writer and is an interpreter that interprets a lightweight markup language.  You feed the TechBook class a string or a file that contains content and TechBook markup to generate a PDF document.  TechBook markup provides styling for basic headings, preformatted blocks, code sections, columns, table of contents, bulleted lists and a few other items.  I equate this to something like an HTML-lite or textile for PDFs.  The markup uses directives to indicate the start and end of a block of text.  Some directives are line oriented like headers that only require a start directive.  Other directives can span multiple lines like bulleted lists.  We'll start with a basic example. 

Headers, similar to the <H1-5> tags in HTML, are supported up to five headers by using the somewhat awkward format #<heading-text>, e.g.

    1&lt;Level 1&gt;
    2&lt;Level 2&gt;
    3&lt;Level 3&gt;
    4&lt;Level 4&gt;
produces...

headings.JPG


With TechBook you can create bulleted lists using "discs" or standard bullets.  Here's an example showing how to create a bulleted list using the disc bullets.  (To create standard bullets replace "disc" with "bullet")
    .blist disc
    Line item 1 with disc
    .endblist
    .blist disc
    Line item 2 with disc
    .endblist
    .blist disc
    Line item 3 with disc
    .endblist
produces...

disc.JPG

In addition to headings and lists, TechBook allows you to preformat text and identify code sections.   E.g.

    .pre
           Pre line 1
           Pre line 2
    .endpre
    
produces...

pre.JPG
 

and
    .code
    pdf = PDF::Writer.new
    pdf.select_font "Times-Roman"
    pdf.text "Hello Ruby", :font =&gt;14, :justification =&gt; :left
    pdf.save_as("e:/hello_ruby.pdf")
    .endcode
    
produces...

code.jpg
 

After you've created your content using the TechBook markup, it's easy to create a new instance of the PDF::TechBook class and produce the PDF file. The following is an example, where "my_content" is your marked-up content

    pdf = PDF::TechBook.new
    pdf.select_font "Times-Roman"
    pdf.techbook_parse <span style="color: blue;">my_content</span>
    pdf.save_as("c:/temp/hello_ruby.pdf")
    

Download a sample program 

my_pdf_writer.rb

There are other features supported by TechBook such as table of contents and the eval directive, but hopefully this will give you a start to using TechBook. If you view the raw version of the PDF::Writer manual that comes with gem you can get a good idea of what you can accomplish with PDF::Writer.

I'm interested in other solutions. Leave me a comment if you know of other ways and/or better ways to create PDF documents using Ruby or have additional tips using PDF::Writer.