Skip to content

XSL-FO Processors Strugle

by peterdk on March 23rd, 2010

Currently I am working on a new service for songbook creation.

I originally worked on this project when CSR Delft, my christian student union, needed a new songbook with guitarsongs. (Think 300+ songs).
I don’t really know anymore how I got involved, but somehow I ended up creating a webdev environment in Ruby on Rails, using ChordPro as the main songlayout method. While we were at it, we needed to find a way to be able to control the rendering of the songs. Back then we opted for rendering HTML => PDF using the browsers print method and a PDF printer service. CSS has some interesting options for page-breaks like: page-break-after:always;  and things like keep-with-previous:always;. Using this, you can/could control the layout pretty good like: titles always need to be on the same page as the first verse.

Too bad these days only Opera really supported al these CSS commands (we´re talking 2006, though I doubt firefox implements them these days). So for the final design we used Opera to render the html that got send to the pdf printerservice.

We didn’t just only used chordpro, we also had database records for every song with title information, authors, bibleverses, etc. These data was used for creation of the songbook’s indexes and the copyright info on the bottom of every song.

It was really cool to do. I learned a lot about Ruby on Rails, back then a very new framework. And the whole creation of a platform that enabled people to work together on a big project was really cool.

3 years later,   the songbook needed a addition, and I had left Ruby on Rails for C# and .Net. I just discovered ASP.NET MVC, quite similar to Ruby on Rails, and decided to port over the project to C#. That was fun and the project now is sustainable.

But hey, this post was about XSl-FO. Suffice to say, I hadn’t heard or discovered XSL-FO back when we started and also with the second version of the platform I didn’t know any better way to auto-layout large PDF’s. And that wasn’t really a problem. It worked, the results look very good and the process was streamlined.

During volunteer work for a organization that needed a new website I discovered XSl-FO and for that matter XML. I was really excited about it. And frankly, I still am. It was just the right tool I needed to be able to try and create a more commercial version of the songbook project. I had the knowledge of the whole process, I could build a more generic platform and with XSL-FO the user wouldn’t need to use specialised Opera browsers and PDF printers, but the server could just handle the whole PDF generation.

The first results where quite promising, however Fop didn’t support auto-table-layout.
That’s more of a problem then you would expect. The chords above the lyrics need to be displayed exactly above the right part of the lyrics. Since we don’t want to use fixed-width-fonts, we couldn’t rely on spaces to position them. To get a good result you need to split every line up into a table, and put the chords in the first row and the lyrics in the second. The tablecells need to shrink until they fit the content exactly. This way you don’t even see that there is a table present.

So, with FOP not able to render the layout in any way, I looked to alternatives.
The best, and really the best, I found was XEP’s RenderX. They really implemented the standard in such a way that it just worked like you expected. Really professional, really good. And really expensive.
They charge like 350$ for a desktop version, and the server edition we would need would cost around 6000$ dollar.
Oops. As a student side-project that’s not funded in any way, that’s just too much.

So I looked to alternatives, and I found a bunch of other ones, but they all didn’t support the stuff we really needed: the tables. Or they just rendered basic layout totally garbaged. So I kept coming back to XEP.
Somehow in the process of optimizing my XSLT for XSl-FO I decided to see how FOP would render them, and to my surprise FOP did complete render them according to design. It didn’t made stupid errors like other non-XEP commercial FO Processors, it was just on par with XEP, except for the table-layout.
I almost decided to buy the desktop version of XEP and just forget about server-side PDF generation, until I came by a patch that was submitted to FOP’s bugzilla that added auto table layout. It had a bunch of limitations, but I really don’t need any advanced table-layout, just the auto-fitting of the cells. I tried it, and wow, it worked on one of my templates!

Unfortunately… it has a big bug: it doesn’t work when the block that contains the table or the table itself has a margin-left set.
And that’s quite a bummer, since I do need to layout the table somewhere on the page.

I decided that I am going to try to fund the development of that feature or put a bounty on it, so FOP can be usable for us on the server. It’s a nice way of giving something back to the opensource developers, and also making that feature available to other users.
If it works, we can use FOP on our server, without stupid licensing restrictions and costly software purchases.
And maybe we can even make some money! That would be great. 🙂

Check some example XSL-FO PDF output on our website: (or
All the PDF examples are rendered with FOP. , except for the first SongBook Example (Hemelsbreed template), that was rendered with XEP.


I found a way to get margin-left working. You just wrap the table in another table with 2 cells: the first cell you make as wide as you want your margin. The second cell you put in your auto-layout table. Auto Layout just keeps on working now.
So now: All examples on the site are rendered with FOP. Amazing!

From → .Net, C#, Linux, Software

  1. Roger Weiss permalink

    Hi Peter,

    Thanks for sharing your FO experience. I’m also a C# developer and have been using NFOP, the .NET port, but its stuck on a very old version of FOP. Are you using FOP natively from JAVA or are you still using NFOP too?

    We’ve also hit a crossroads now and have to decide to go for a commercial FO product like RenderX or try use FOP.

    One of the main stumbling blocks we’ve hit now is that we can only use the 4 base fonts in FOP. You can extend the fonts, but NFOP crashes when we do.

    So yeah, those are our pains and identify with yours. I’m still leaning toward FOP, but we’re C# dev shop and I fear bringing a java solution.

    Some of the Commercial offering are very slick, especially in terms of performance and other cool things…like embedding images rather than using an external graphic.

    Are you still using FOP?

    Once again, thanks for sharing, thought I’d share some of my experiences too.

  2. peterdk permalink

    Hi Roger,

    I recently revisited this project since we have a church group that wanted to use our system.

    Currently I am developing the system as follows:
    – ASP.NET MVC Website
    – Seperate Ruby powered FOP queue server, that handles incoming documents and calls the standalone Java FOP bin to initiate pdf generation.

    The website communicates to the queue server, that one takes the document, generates the pdf and communicates all steps of the process and it’s result back to the webserver.

    I could image you create somehow a C# FOP Rendering Server, that calls to the java fop one. But I would say that highly depends on your budget constraints, since if you can afford XEP or equivalent, it’s highly recommended. I solely don’t use XEP because of the money I don’t have.

    I have never used NFOP, but have tested it I guess when I compared all the other renderers.

  3. Julius permalink

    Hi peterdk,

    could you please show exact example, how table within table should be formatted and with what attributes?
    I want to use FOP processor and want to use table-layout=”auto”. I tried to do as you mentioned in your article, but it didn’t work.
    I tried something like this:

  4. Julius permalink

    sorry, couldn’t paste XML.
    But here is direct link:

  5. Sorry, I don’t know the details anymore, haven’t worked on the project for a long time… Sorry.

Comments are closed.