Some time ago, I wrote a blog post about generating LaTeX code with a template engine. Yesterday, I finished an application for a client which had a lot of templates; since my hands were already dirty in the template clay, I decided to revisit the whole idea and come up with some sort of merging tool. And yes, there’s also a duck involved.
I was playing with some code and, all of a sudden, I actually came up with something interesting: what if we have a tool that merges a list of datasources into a template and generate the output? Of course, I was aiming at TeX and friends, but the tool could be used for other contexts as well. Everything was ready, but I needed a name. Then:
and duckity
was born. I wrote it in Java, and I plan to release it soon. I still need to improve some parts of the code, but the tool is already finished. Let’s see an example of use. Consider the following code:
The input file is divided in two parts: the definition of datasources and the template itself. The definition part is written in the JSON format, while the template can be written in any format (.tex
for example), and supported by Apache Velocity.
In the definition part, there are at least two mandatory elements: file
and identifier
. Two formats are supported: JSON and CSV. The file
element contains the actual data, and the identifier
is used to refer to this data in the template. Let’s say we have the following grades.csv
file:
In our example, students
refer to the content of the grades.csv
file. Merging our template with our data file:
If I omit the --output
flag, the output name would be rep1.new.tex
instead. Let’s take a look at the generated file:
Cool, it works! Now, let’s try something more neat: what if, when typesetting the grades, if the value is below 5.0, the number is displayed in the red colour? Leave it to the template, the helper $math
class and some conditionals:
After applying duckity rep2.tex
, the newly created rep2.new.tex
will have the following content:
Let’s compile it, shall it?
Yay! But we can get more intricate stuff. Let’s add a new datasource, this time, a JSON file. Consider the following template:
Two datasources for the price of only one. The subject.json
has the following structure:
Note that we map each key of the JSON file to identifier + . + key
in the template to get its value. We can even iterate through elements of a list (in our JSON file, schedule
has a list of dates) and add conditionals according to their positions. Let’s see the result:
Now we want the final note. We can easily tell the template to calculate the value for us, and even apply the colour conditional:
Here we go! After merging the data and the template, we have the following file:
Let’s compile it!
We can add an arbitrary number of datasources (JSON or CSV). Let’s add another one:
A list of tutors will be added at the end of the document. This is the JSON file:
Let’s see the final code:
And of course, the output:
I know that Velocity’s syntax (including the $
) might sound like a mess in an editor (you can already tell what it did to my Vim). But the nice thing about it is that the template engine is actually smart enough to know what to resolve and what to leave intact. And besides, we don’t compile templates, but their results. :)
Consider the following example:
Note that this file doesn’t have the declaration part. If we run duckity
on it, nothing will be merged. On the other hand, we can provide the datasources via command line. Thanks to Aditya for the suggestion!
We provide both --datasource/--identifier
pairs (or its shorter form -d/-i
and duckity
does the dirty job for us:
That’s it. I plan to release this humble tool in a few days, under the New BSD license. I’ll update this blog post with the link to the proper GitHub repository, with the binary available for download and also the sources. :)
Awesome! That’s bound to be handy for a lot of people with repetitive tasks.
Interesting. I really like the feature of merging multiple data sources.
For comparison, here are some Lua based solutions for creating templates in (Con)TeX
@phg’s csv parser + template interface .
Jaroslav Hajtmar’s t-scancsv library. Some usage examples are available here.
And, as I mentioned in the chat, Hans Hagen’s experimental Lua Templates.
Thanks for the links, Aditya!
hi, that is great–I need to look at Velocity. I do something like this, but using Cheetah templates, and tags that look like this:
\Template[student=Bob, grade=71]{student}
Cheetah applies the first argument as the data dictionary to the template named as the argument. Your way is more flexible.
thanks,
–Tim
Is it published already? I don’t see any link to github repo…
I am also collecting related work for https://github.com/latextemplates/latex-template-generator. Gooling for “duckity” resulted in https://github.com/cereda/duckity, but this is not this software.