og:image

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:

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')
\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}
\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.

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))
author: streambinder in english
author: streambinder in italiano