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
file.
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
multicolpackage. 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
lettrinepackage 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,
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:
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:
\documentclass[a4paper,${size}]{extarticle}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[top=1cm, bottom=1cm, left=1cm, right=1cm]{geometry}
\usepackage{mysongs}
\begin{document}
\sheet{Folheto de cantos \texttt{\#}${title}}
\begin{songs}
\#foreach( $song in $songs )
\begin{song}
$song.getBody()
\end{song}
\#end
\end{songs}
\end{document}
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!
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.)
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.
Awesome, Andrew!
It might take a while for me to come up with a full TeX solution.
Very interesting! Another possibility would be running LuaLaTeX with wxLua for the GUI and LuaSQL for reading the database entries.
It is so interesting. I didn’t know apache velocity, but now, It would be easy to integrate java and latex.
Thank you!