An opinionated workflow to produce different versions of a Curriculum Vitae (résumé) document allowing different localisations, templates, styles and formats without having to mantain them all.
If you want to take a look at a potential final result, my CV is built using this tool.
- Logically and practically separate templates/tools and data source;
- Have an agnostic data source (JSON) and edit ONLY that when updating the informations (API access to a remote endpoint exposing a compliant JSON is trivially implementable, too);
- Have data source compliant and validated against a formal specification or schema (use JSON schema and possibly the JSON-Resume specification?). Templates must respect this schema too;
- Allow a sane versioning of both the data source and templates, separately;
- Easily update and version the data source using a text editor or a (visual) JSON editor;
- Keep the hybrid Jinja2 templates clean and similar to their plain format versions (that's why a LuaLaTeX solution was scraped).
This is your JSON data source:
{
[...]
"name": "Maximilian Mustermann",
"address": "Wien, Austria",
"age": "44",
"phone": "(+43) 231 7484174 ",
"website": "https://maxmusterman.com",
"github": "https://github.com/maxmusterman",
"email": "max@mustermann.at",
[...]
"education": [
{
"title":"Bachelor's Degree",
"field":"Engineering Science",
"school":" Technical University of Munich",
},
{
"title":"Master of Science",
"field":"Computational Science and Engineering",
"school":"Vienna University of Technology",
}
],
"work": [
{
"position": "API Developer",
"place": "Time Lord Academy (Mount Cadon)",
"field": "Untempered Schism",
"period": "453 -- Present",
"description": "Protecting the ancient Law of Gallifrey exposing time-travel-as-a-service. Implementing psychic paper proof authentication protocol."
}
]
}
This is how a Jinja2-templated LaTeX document looks like:
[...]
\begin{document}
\jv{data.name}
\address{
\href{\jv{data.website}}{\jv{data.website[8:]}}\\
\href{\jv{data.github}}{\jv{data.github[8:]}}\\
\jv{data.email}\\
} % Your address 2
\address{
\jv{data.address} \\
\jv{data.age} years old\\
\jv{data.phone}
}
\jb{ for edu in data.education }
{\sl \jv{edu.school}} \hfill \jv{edu.period} \\
{\sbb \jv{edu.title}}, \jv{edu.field} \\
\jb{ endfor }
\jb{ for experience in data.work }
{\sl \jv{experience.place} } \hfill \jv{experience.period}\\
{\sbb \jv{experience.position} } \hfill \jv{experience.field}}\vspace{4pt} \\
\small{\textcolor{darkgray}{
\jv{experience.description}
}
\jb{ endfor }
[...]
Basically, a clean TeX file with some Jinja2 syntax inside the \jb
and \jv
special tags.
We plug those two and we get a fancy LaTeX render, obtaining:
Recent tools have native support for plugging JSON data. E.g. on a Vue component:
<title>{{ name }} résumé</title>
Name: {{ name }}
Address: {{ address }}
Age: {{ age }}
Phone: {{ phone }}
Website: {{ website }}
GitHub: {{ github }}
Email: {{ email }}
<subtitle> Education </subtitle>
<template v-for="degree in education">
<h3>{{ degree.title }}</h3>
<subtitle>{{ degree.school }}<br>
<i>{{ degree.field }}</i></subtitle>
</template>
- a TeX distribution
- XeLaTeX
- Python3
On Debian:
sudo apt install texlive-base pandoc python3 texlive-xetex fonts-roboto
On Fedora:
sudo dnf install texlive-collection-fontsrecommended texlive-xetex texlive-latex texlive-collection-latexextra texlive-titlesec 'tex(datetime.sty)' 'tex(eu1enc.def)' 'tex(polyglossia.sty)'
sudo dnf install google-roboto-fonts.noarch
python j2tex.py
xelatex resume.tex
- Résumé JSON schema
- Example Vue template for the web workflow
- Example MD/HTML5 template for the pandoc workflow
- pandoc preprocessor to allow Markdown in the field of the json, then preprocess to the target language in each workflow.
If you wish to remain sane, something like pandoc-resume could fit your use-case with less effort (BUT it doesn't provide a serialized data source, it's markdown).
Various resources, links and threads examined for the project.
- How to loop over the JSON object / list?
- Error as I try to read and display the results from JSON file
- API JSON in Latex
- jq json processor
- Transform a JSON file into a formated Latex
- How to iterate over a comma separated list?
- Why choose LuaLaTeX over XeLaTeX?
- Considerations when migrating from XeTeX to LuaTeX?