https://github.com/avivace/j2-resume
An opinionated (and probably over-engineered) workflow to produce a fancy LaTeX, web or docx Curriculum Vitae document from a JSON data source using Jinja2 (a data-driven CV)
https://github.com/avivace/j2-resume
curriculum curriculum-vitae cv cv-template data-driven datadriven jinja2 json-schema latex latex-resume latex-resume-template latex-template-cv templating
Last synced: 11 days ago
JSON representation
An opinionated (and probably over-engineered) workflow to produce a fancy LaTeX, web or docx Curriculum Vitae document from a JSON data source using Jinja2 (a data-driven CV)
- Host: GitHub
- URL: https://github.com/avivace/j2-resume
- Owner: avivace
- Created: 2017-08-02T21:10:28.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2023-10-11T22:16:00.000Z (over 1 year ago)
- Last Synced: 2025-03-30T23:04:54.415Z (about 2 months ago)
- Topics: curriculum, curriculum-vitae, cv, cv-template, data-driven, datadriven, jinja2, json-schema, latex, latex-resume, latex-resume-template, latex-template-cv, templating
- Language: TeX
- Homepage: https://avivace.com/cv.pdf
- Size: 168 KB
- Stars: 23
- Watchers: 3
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# J2-résumé
> 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.
### Example
If you want to take a look at a potential final result, [my CV](http://avivace.com/cv.pdf) is built using this tool.
## Architecture

## Goals
- 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).## How the code looks like
This is your *JSON data source*:
```json
{
[...]
"name": "Maximilian Mustermann",
"address": "Wien, Austria",
"age": "44",
"phone": "(+43) 231 7484174 ",
"website": "https://maxmusterman.com",
"github": "https://github.com/maxmusterman",
"email": "[email protected]",
[...]
"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."
}
]
}
```### LaTeX
This is how a Jinja2-templated LaTeX document looks like:
```tex
[...]
\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:
### React/Vue
Recent tools have native support for plugging JSON data.
E.g. on a Vue component:```
{{ name }} résumé
Name: {{ name }}
Address: {{ address }}
Age: {{ age }}
Phone: {{ phone }}
Website: {{ website }}
GitHub: {{ github }}
Email: {{ email }}Education
{{ degree.title }}
{{ degree.school }}
{{ degree.field }}```
## Build
### Requirements
- a TeX distribution
- XeLaTeX
- Python3On Debian:
```bash
sudo apt install texlive-base pandoc python3 texlive-xetex fonts-roboto
```On Fedora:
```bash
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
```### LaTeX workflow
```bash
python j2tex.py
xelatex resume.tex
```## TODO
- [ ] 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.## Related projects
If you wish to remain sane, something like [pandoc-resume](https://github.com/mszep/pandoc_resume) could fit your use-case with less effort (BUT it doesn't provide a serialized data source, it's markdown).
## References
Various resources, links and threads examined for the project.
- [How to loop over the JSON object / list?](https://tex.stackexchange.com/questions/489417/how-to-loop-over-the-json-object-list)
- [Error as I try to read and display the results from JSON file](https://tex.stackexchange.com/questions/489395/error-as-i-try-to-read-and-display-the-results-from-json-file/489397#489397)
- [API JSON in Latex](https://tex.stackexchange.com/questions/272401/api-json-in-latex)
- [jq json processor](https://stedolan.github.io/jq/manual/)
- [Transform a JSON file into a formated Latex](https://groups.google.com/forum/#!topic/pandoc-discuss/VBHwMj6IVOY)
- [How to iterate over a comma separated list?](https://tex.stackexchange.com/questions/159118/how-to-iterate-over-a-comma-separated-list)
- [Why choose LuaLaTeX over XeLaTeX?](https://tex.stackexchange.com/questions/126206/why-choose-lualatex-over-xelatex)
- [Considerations when migrating from XeTeX to LuaTeX?](https://tex.stackexchange.com/questions/23598/considerations-when-migrating-from-xetex-to-luatex)