Source code Erro
That cool thing to look interesting in the world of work
#About
Yup. I host my LaTeX CV on a dedicated repository on GitHub and release every version of it using dedicated Releases. I really enjoyed the idea to review it as a coding project, making it buildable as a common project using build automation tools and release its binary (PDF) version.
Download
To download latest version, please, reach latest GitHub repository release. Otherwise, if you want to grab it from the shell (or in any other way you prefer), you can use (or adapt) the following snippet:
lang="en"
variant="europass"
release="https://github.com/streambinder/erro/releases/latest"
curl "${release}/download/${variant}_${lang}.pdf" -o resume.pdf
Design
The first issue I faced was about few companies being very strict on the allowed CV format, hence asking for the EuroPass one, for example. On the other hand, I really enjoyed my custom format and didn't want to just drop it. And what if another company would have come asking for a CV formatted following another format?
All of this led me considering templating my documents: many tex
files as many formats I wanted to support and a single database file keeping the information used to fill the templates.
On the other hand, I wanted my CV to be internationalized, maintaining a different version of each different format for each language supported.
After a first round in which I did implement all the features on my own (look at erro@be0c83e if interested), I moved to a more solid structure.
Templating
Different formats, or templates, are to be made and accessing same data based on a sort of identifiers. Despite how simple this issue could look, it's definitely not, at least if you want to keep something to be somehow proud.
Looking for a nice way to replace my old and misfiring templating engine, I discovered jinja.
This library allows you to define block_start_string
, variable_start_string
and many other nice things to make it able to detect where exactly in your template you want placeholders and identifiers to be replaced with actual content.
This scales really good for LaTeX documents, actually:
- Python renderer:
latex = jinja2.Environment(
block_start_string='\\jblock{',
block_end_string='}',
variable_start_string='\\jvar{',
variable_end_string='}'
)
latex.get_template('template.tex')
.render(author = 'streambinder')
.dump('resume.tex')
- LaTeX template
template.tex
:
\begin{document}
\jvar{author}'s CV.
\jblock{for i in range(5)}
\jblock{if i % 2 == 0}
\textit{ \jvar{i} }
\jblock{endif}
\jblock{endfor}
\end{document}
- LaTeX rendered
resume.tex
:
\begin{document}
streambinder's CV.
\textit{ 0 }
\textit{ 2 }
\textit{ 4 }
\end{document}
Making the engine take the rendering parameters from a database file was pretty easy, too. The same result above can be achieved the following way:
with open('database.yaml', 'r') as database_fd:
latex.get_template('template.tex')
.stream(yaml.safe_load(database_fd))
.dump('resume.tex')
With database.yaml
like below:
author: streambinder
Internationalization
Once you have a perfectly working template engine with support for external data source, supporting internationalization is straightforward: introduce a different database file for each language.
- Python renderer:
for lang in ['en', 'it']:
with open('database_{}.yaml'.format(lang), 'r') as database_fd:
latex.get_template('template.tex')
.stream(yaml.safe_load(database_fd))
- YAML english database
database_en.yaml
:
author: streambinder in english
- YAML italian database
database_it.yaml
:
author: streambinder in italiano