DocBook XML to PDF on Debian Lenny

by Sander Marechal

I have recently been writing some documentation in DocBook XML format that I wanted to convert to PDF. Debian has a really useful package called xmlto that you can use for this, but it did not work for me. The xmlto tool converts DocBook to PDF through LaTeX and I was getting all kinds of errors. Instead I opted to use the DocBook-XSL stylesheets to convert DocBook to fo and use Apache fop to convert it to PDF.

DocBook-XSL and Apache fop work wonderfully well but there were a couple of bumps that I had to sort out before everything worked as it should, especially regarding the Java setup and getting images to work correctly. Here is how I set up my DocBook toolchain on Debian Lenny.

Installing the required packages

There are quite a few packages you need to install. You will need the stylesheets, fop, xsltproc and a Sun version of Java, because the image libraries don’t seem to work with the java-gcj that comes with Debian by default. Perhaps this is simply caused by the fop script not setting the correct classpath, but I am not knowledgeable enough about Java to be able to fix that. So I am using Sun’s Java6 instead.

  1. # aptitude install sun-java6-jre xsltproc docbook-xsl fop

Don’t forget to update your alternatives to point to the new Java.

  1. # update-java-alternatives -l
  2. java-6-sun 63 /usr/lib/jvm/java-6-sun
  3. java-gcj 1042 /usr/lib/jvm/java-gcj
  4. # update-java-alternatives -s java-6-sun

Installing the Java image libraries

Now you need to install the image libraries JAI and JIMI that fop needs to add images to PDF documents. Let’s start off with JAI, the Java Advanced Imaging library. You can download it from https://jai.dev.java.net/binary-builds.html. Download the file jai-1_1_3-lib-linux-i586.jar.zip and unzip it. Inside you will find a file called jai_linux-i586.jar. Copy that to /usr/share/java.

  1. # wget http://download.java.net/media/jai/builds/release/1_1_3/jai-1_1_3-lib-linux-i586.jar.zip
  2. # unzip jai-1_1_3-lib-linux-i586.jar.zip -d /usr/share/java

Next you can install JIMI which you can download from http://java.sun.com/products/jimi/. Download it and unzip it. There are quite a few files but you need only one of them: JimiProClasses.zip. Move that file to /usr/share/java and rename it to jimi-1.0.jar.

Convert a DocBook to PDF

Now you’re ready to convert your DocBook file to PDF. First use xsltproc to convert it from DocBook to fo.

  1. $ xsltproc -o document.fo \
  2.   --stringparam use.extensions 0 \
  3.   --stringparam fop1.extensions 1 \
  4.   /usr/share/xml/docbook/stylesheet/nwalsh/fo/docbook.xsl \
  5.   document.xml

Don’t worry if you see warnings and errors, you should end up with a good document.fo file. There are many, many more flags that you can set during this transformation stage to take care of errors later on. Now you can use fop to convert it to PDF.

  1. $ fop -fo document.fo -pdf document.pdf

Because I do not want to type all of that everytime I want to update my PDF file, I have written a short Makefile to do it for me. In it I use a couple more options for the DocBook stylesheets.

  1. all: document.pdf
  2.  
  3. document.pdf: document.fo
  4.         fop -fo document.fo -pdf document.pdf
  5.  
  6. document.fo: document.xml
  7.         xsltproc -o document.fo \
  8.                 --stringparam use.extensions 0 \  # Don't use XSL extensions
  9.                 --stringparam fop1.extensions 1 \ # Do use extensions to make fop work better
  10.                 --stringparam draft.mode no \     # Don't watermark "draft" in the document
  11.                 --stringparam hyphenate false \   # Don't hyphenate (because I lack a dutch hyphenation library)
  12.                 --stringparam l10n.gentext.default.language nl \ # Generate Dutch words
  13.                 --stringparam admon.graphics 1 \                 # Add graphics to notes and warnings
  14.                 --stringparam admon.graphics.extension .svg \    # Use SVG graphics
  15.                 /usr/share/xml/docbook/stylesheet/nwalsh/fo/docbook.xsl \
  16.                 document.xml

Simply run the command make in the directory where the Makefile and document.xml are and it will generate the PDF document for you. As an added bonus, running make works from inside (g)vim as well. When I am editing my DocBook document I can simply issue the :make command to rebuild by PDF file. After that I switch to my document viewer and hit Ctrl+R to reload it and see the changes.

Have fun writing (Doc)Books!

Creative Commons Attribution-ShareAlike

Comments

#1 Dmitri Minaev (http://minaev.blogspot.com)

I spent about half a year using DocBook for my documents at work: IT policies, short instruction sheets, and so on. Earlier this year I posted my impressions from DocBook at Ubuntu Forums:

Docbook is not for work. First, it's awkward. Even an XML dialect could be less prolix. I was really surprised that ISO, NIST and Russian ministry of heavy industry are not the only bodies able to produce a standard that takes seven lines to insert a screenshot:

<screenshot>
<mediaobject>
<imageobject>
<imagedata fileref="qwerty.png" format="PNG"/>
</imageobject>
</mediaobject>
</screenshot>

Okay, I know there could be only five lines, but why five if one is enough?

And the culmination of the docbook spirit. Ta-da! The first place goes to the tag <confsponsor>. I really miss <cellphoneofconfsponsorsprettiestdaughter>.

Second, Docbook toolchain is next to non-existent. Docbook-utils require a half-dead jadetex. Xmlto requires a completely dead passivetex. Two xsl:fo formatters: Java-based dinosaur fop (not in Ubuntu repositories) and the newborn xmlroff, which has two backends, neither of which was able to produce a readable text on my files. And Dblatex, which "just works", and produces the results it wants, but not the results I need.

And the last point. "You can concentrate on the content and forget about the presentation," say the proponents of Docbook. No, guys, I can't. Because if I give a manuals written in Docbook to my customers, I will lose my job. I have to think about presentation. Some days ago I needed to make a pdf for a 3.5"x4.5" screen (eInk device) with the font a couple of points smaller than usual. Guess how much time it required? Two hours. And the last 15 minutes I spent reformatting the text in OOo.

Now, I'm back with LaTeX and I'm happy. Okay, relatively happy :). Still looking for an alternative, but DocBook is not one of them.

#2 Sander Marechal (http://www.jejik.com)

You're calling fop a dinosaur but you use LaTeX yourself? That's a bit of a contradiction isn't it? :-) You make a few good points, but I don't agree with everything you wrote.

The screenshot example you gave is five/seven lines for a good reason. A media object can contain multiple things, a bit like MIME has alternative parts. You can have a video and an image and some text in there. The imagedata is separate from the imageobject because there are multiple ways to represent your image. Inline SVG is another example.

As for the large number of tags, DocBook 5 removes many of them. They were there because of the limitations in DTD which is used to specify DocBook 4.5 and below. DocBook 5 uses RELAX-NG and Schematron so they could combine a large number of tags into one tag. Also, there's simplified DocBook.

As for the toolchains, there are plenty. There are multiple XSL sheets that you can use with multiple XSLT processors. There are also multiple FO formatters. If you count just the Free software ones you end up with at least 5 or so different toolchains. If you count commercial implementations as well then you have many, many more.

I agree that the presentation is quite hard to change, but DocBook is aimed at situations where you usually don't need to do that. You set it up once (e.g. an XSL customisation layer) and then use it to convert many documents instead of just one. Take a look at the GNOME documentation project for example.

As for LaTeX, I use it as well. And ODF (OpenOffice.org). It depends on what I am working on. If I need multiple output formats (like documentation) I use DocBook. If I am writing a paper of some kind that is intended just for print/pdf (i.e. it's read-only) then I use LaTeX. For works that require lots of collaboration or that require full control of the presentation I use ODF.

#3 Dmitri Minaev (http://minaev.blogspot.com)

The specific dinosaurity per feature (wow...) is much lower for LaTeX :). I mean, it's huge, too, but it does much more.

As for the screenshots, how many screenshots have you met that were not media objects? Even text "screenshots" are not semantically different from any other screenshots. Then again, if we have the "format" attribute, do we need to indicate explicitly that this PNG file is an image, not a sound? Well, to wrap it up, I presumptuously assume that just plain <screenshot fileref="qwer.png" format="PNG" /> should be enough. An embedded SVG might look like, say, <screenshot format="SVG>[svg source here]</screenshot>.

Another option, which I would prefer, could decrease the semantic cancer of DocBook: use attributes instead. <image src="qwer.png" format="PNG" class="screenshot"> might look old-fashioned, but it would do the job much better than all that tag tower.

Yes, I spoke about free and open-source toolchains, because an open document format needs an open reference implementation, at the very least. The implementations I have seen have problems with non-Latin alphabets. Fop doesn't, but the last time I saw it, the FO coverage was insufficient for a serious typesetting.

A huge advantage of LaTeX is the ability to fix the defects inevitable after automatic typesetting, to add some non-formalizable tweaks. AFAIK, there's no way in DocBook to specify that the leading in a certain paragraph should be 1 point more than usual. You can't get a decent, pretty looking document without such tricks.

#4 Sander Marechal (http://www.jejik.com)

I think your screenshot example is too minimalistic. A minimum example for me would be this:

<screenshot>
  <image fileref="file.png" format="PNG" />
</screenshot>


Because you need to be able to expand it to something like this:

<screenshot>
  <imageobject fileref="file.png" format="PNG" />
  <textobject><phase>This is for the blind</phrase></textobject>
  <caption><para>A screenshot caption</para></caption>
</screenshot>


The downside is of course that not every image is a screenshot. So you'd need to add tags for other types of images as well.

op doesn't, but the last time I saw it, the FO coverage was insufficient for a serious typesetting.


When is the last time you used fop? I have had no problems with fop-0.95

A huge advantage of LaTeX is the ability to fix the defects inevitable after automatic typesetting


True. And DocBooks great advantages are the umpteen output formats and indexability/searchability. I use whatever fits the job I'm doing. Sometimes that's docbook. Sometimes that's LaTeX.

#5 Dmitri Minaev (http://minaev.blogspot.com)


<screenshot>
<imageobject fileref="file.png" format="PNG" />
<textobject><phase>This is for the blind</phrase></textobject>
<caption><para>A screenshot caption</para></caption>
</screenshot>

Could be. There's something in this example I don't quite like, though. Perhaps, it's that all three subelements are equal while they are not. Imageobject and textobject are alternatives, they should not be used together, while caption will always follow the imageobject. Perhaps, an attribute (remember the 'alt' from html? it was meant to be an alternative way of rendering) could do the job of that textobject.

If I remember correctly, fop was 0.92 when I decided I'd had enough. There were problems with footnotes and widow/orphan control. Perhaps, with insets, too, but my memory may be failing here.

As for the multiple output formats, I often use HeVeA and latex2rtf. Their output is almost as unmanageable as the output of docbook/fop, but at least I can open them in an editor and polish them.

I think I've found the right words to describe what annoys me in DocBook. The absolute separation of presentation (xsl:fo) and content (docbook) is an exaggeration. A step too far. Purely semantic markup is hardly useful. The more semantic it is, the fewer are the cases where it may be used. You can't invent tags for everything. As for the deficiencies of purely presentational markup, we know them very well. So, the two must be balanced. LaTeX is good because one can easily (hmm...) use macros to add a semantic pseudo-layer on the top of the mostly presentational foundation.

#6 Sander Marechal (http://www.jejik.com)

Perhaps, an attribute (remember the 'alt' from html? it was meant to be an alternative way of rendering) could do the job of that textobject.


It would work for a small piece of text, but not for other possible alternatives. Imagine a video which has an inline SVG as alternative content for output formats that don't support video. What to do then? Wrap a tag around all the alternative parts like MIME does with MIME boundaries? As you see, it's not that easy to eliminate tags and not loose much (semantic) functionality :-)

I think I've found the right words to describe what annoys me in DocBook. The absolute separation of presentation (xsl:fo) and content (docbook) is an exaggeration. A step too far.


I like it, when I need it. In case of software documentation it's a blessing because you're rendering to so many output formats. Take the documentation for gnome-hearts. It goes to HTML, Yelp, PDF, plain text and more. You want the absolute separation here or your document would be littered with presentational mark-up. Better split that off in a separate layer. But if you're just rendering to one or two formats (e.g. PDF) then I agree it can be a curse.

Perhaps you problem isn't so much the separation itself but the fact that changing the presentation layer is too hard? After all, everything you described could be handled by an XSL customisation layer over the standard DocBook-XSL stylesheets. It's just that writing such a customisation layer is harder than adding some inline presentational markup to a LaTeX document.

#7 dehemcajusttraj

<p>The requested URL /forxru1/zadanie.txt was not found on this server.</p>
<h1>Not Found</h1>
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
</body></html>
<address>Apache/2.2.3 (Debian) mod_python/3.2.10 Python/2.4.4 PHP/5.2.0-8+etch15 mod_ssl/2.2.3 OpenSSL/0.9.8c Server at allhomedecor.org Port 80</address>
<hr>
</head><body>
<title>404 Not Found</title>

#8 Tom

You can use http://docbookpublishing.com. It is a free web service for DocBook XML to PDF conversion. And there is no need for installing and configuring numerous packages.

Comments have been retired for this article.