Generating LaTeX code with a template engine

Sometimes, you get stuck with repetitive tasks, like generating the very same document over and over with a few changes in the content. I’m the coordinator of a small choir in a parish, and twice a month I have to print songsheets for the community. I usually try to automate as many tasks as I can, but LaTeX output is quite tricky. Here’s my attempt to write a program that spits out a



For my task, I decided to rely on a Java solution, but the idea applies to every programming language. I already have the songs organized in a database, so I only need to iterate through the records and generate a


file. But how? First, I need to define how my


file should look.

I came up with a simple


file which has basically one command and two environments:

  • \sheet{}

    : the “title” of the songsheet. For me, it’s useful to put an identifier as title, so we can reuse sheets for other occasions.

  • songs

    : this is the main environment of my document, which is basically a wrapper to the awesome


    package. There’s also an optional argument with the number of columns – the default is set to two. I decided to use this approach in order to keep a more semantic document.

  • song

    : every song will be inside this environment. I used the


    package to put the song numbers as if they were drop capitals. Well, it might not be the best layout ever, but it works for me, as I need to save as much space as I can.

And now? Reading the songs from the database is the easy part. But how am I supposed to make my code print a LaTeX line? Think of the headache of escaping every single potential character, like,

out.write("\\\textbf{Hello world}\n");

or worse. There is a better solution for this: using a template engine.

According to Wikipedia, “A template processor (also known as a template engine, template parser or template language) is software or a software component that is designed to combine one or more templates with a data model to produce one or more result documents.” And there’s even a pretty image which summarizes the whole idea:

A diagram illustrating all of the basic elements and processing flow of a template engine. Courtesy of Wikipedia.


It sounds very appealing. There’s one particular template engine I like a lot: Apache Velocity. There are other engines you can use, and there is even a mention to Cheetah in one of the questions in our main site.

I won’t enter in details of the template language, but I can tell it’s very straightforward. The documentation is also a great resource. Let’s take a look in my template:


\usepackage[top=1cm, bottom=1cm, left=1cm, right=1cm]{geometry}



\sheet{Folheto de cantos \texttt{\#}${title}}


\#foreach( $song in $songs )


Wait a minute, that’s it?! You simply tell the engine the values for every variable. When calling the template engine, data and template are merged. Writing a LaTeX code was very easy, after all. My final program:

In the first screen, I select which songs I want to include in my new songsheet. Then it’s just a matter of pressing Generate:

The screen asks me for the title of my songsheet. And pressing OK, both template and data are merged:

Done! My new songsheet was easily generated. Let’s see how the final document looks like:

There we go, a nice LaTeX document!


7 thoughts

  1. Very nice, but of course the real coup de grace would be to have the template engine written in TeX. (Not completely facetious comment: I do this – without realising that it was what I was doing – in creating “lesson plans” from my beamer presentations.)

    1. Sure, writing the template engine in Tex would be both a good and challenging exercise and a great feat to accomplish.

      But why re-invent the wheel? No one off personal template engine could rival the features and stability of something like velocity or any other ‘professional’ template engine that has a team of active developers and maintainers behind it.

      I was a bit afraid of LaTex and Velocity not interacting well, because of the mutual use of ‘$’; googling for it led me to this post. Good to read that it is possible.

Leave a Reply

Your email address will not be published. Required fields are marked *