{"id":13419887,"url":"https://github.com/avivace/j2-resume","last_synced_at":"2025-05-05T19:29:33.726Z","repository":{"id":44543266,"uuid":"99161158","full_name":"avivace/j2-resume","owner":"avivace","description":"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)","archived":false,"fork":false,"pushed_at":"2023-10-11T22:16:00.000Z","size":172,"stargazers_count":23,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-30T23:04:54.415Z","etag":null,"topics":["curriculum","curriculum-vitae","cv","cv-template","data-driven","datadriven","jinja2","json-schema","latex","latex-resume","latex-resume-template","latex-template-cv","templating"],"latest_commit_sha":null,"homepage":"https://avivace.com/cv.pdf","language":"TeX","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/avivace.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-08-02T21:10:28.000Z","updated_at":"2025-02-24T17:16:37.000Z","dependencies_parsed_at":"2025-01-24T03:30:47.308Z","dependency_job_id":null,"html_url":"https://github.com/avivace/j2-resume","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avivace%2Fj2-resume","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avivace%2Fj2-resume/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avivace%2Fj2-resume/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avivace%2Fj2-resume/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/avivace","download_url":"https://codeload.github.com/avivace/j2-resume/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252562532,"owners_count":21768307,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["curriculum","curriculum-vitae","cv","cv-template","data-driven","datadriven","jinja2","json-schema","latex","latex-resume","latex-resume-template","latex-template-cv","templating"],"created_at":"2024-07-30T22:01:22.366Z","updated_at":"2025-05-05T19:29:33.718Z","avatar_url":"https://github.com/avivace.png","language":"TeX","funding_links":[],"categories":["TeX"],"sub_categories":[],"readme":"# J2-résumé\n\n\u003e 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.\n\n### Example\n\nIf you want to take a look at a potential final result, [my CV](http://avivace.com/cv.pdf) is built using this tool.\n\n## Architecture\n\n![Architecture](.meta/flow.svg)\n\n\n## Goals\n\n- Logically and practically separate templates/tools and data source;\n- 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);\n- 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;\n- Allow a sane versioning of both the data source and templates, separately;\n- Easily update and version the data source using a text editor or a (visual) JSON editor;\n- Keep the hybrid Jinja2 templates clean and similar to their plain format versions (that's why a LuaLaTeX solution was scraped).\n\n## How the code looks like\n\nThis is your *JSON data source*:\n\n```json\n\n{\n    [...]\n    \"name\": \"Maximilian Mustermann\",\n    \"address\": \"Wien, Austria\",\n    \"age\": \"44\",\n    \"phone\": \"(+43) 231 7484174 \",\n    \"website\": \"https://maxmusterman.com\",\n    \"github\": \"https://github.com/maxmusterman\",\n    \"email\": \"max@mustermann.at\",\n    [...]\n    \"education\": [\n        {\n            \"title\":\"Bachelor's Degree\",\n            \"field\":\"Engineering Science\",\n            \"school\":\" Technical University of Munich\",\n        },\n        {\n            \"title\":\"Master of Science\",\n            \"field\":\"Computational Science and Engineering\",\n            \"school\":\"Vienna University of Technology\",\n        }\n    ],\n    \"work\": [\n        {\n            \"position\": \"API Developer\",\n            \"place\": \"Time Lord Academy (Mount Cadon)\",\n            \"field\": \"Untempered Schism\",\n            \"period\": \"453 -- Present\",\n            \"description\": \"Protecting the ancient Law of Gallifrey exposing time-travel-as-a-service. Implementing psychic paper proof authentication protocol.\"\n        }\n    ]\n}\n```\n\n### LaTeX\n\nThis is how a Jinja2-templated LaTeX document looks like:\n\n```tex\n[...]\n\\begin{document}\n\n\\jv{data.name}\n\n\\address{ \n\\href{\\jv{data.website}}{\\jv{data.website[8:]}}\\\\ \n\\href{\\jv{data.github}}{\\jv{data.github[8:]}}\\\\\n\\jv{data.email}\\\\ \n} % Your address 2\n\n\\address{\n\\jv{data.address} \\\\\n\\jv{data.age} years old\\\\\n\\jv{data.phone}\n}\n\n\\jb{ for edu in data.education }\n    {\\sl \\jv{edu.school}} \\hfill \\jv{edu.period} \\\\ \n    {\\sbb \\jv{edu.title}}, \\jv{edu.field} \\\\\n\\jb{ endfor }\n\n\n\\jb{ for experience in data.work }\n    {\\sl \\jv{experience.place} } \\hfill \\jv{experience.period}\\\\\n    {\\sbb \\jv{experience.position} } \\hfill \\jv{experience.field}}\\vspace{4pt} \\\\\n    \\small{\\textcolor{darkgray}{\n    \\jv{experience.description}\n    }\n\\jb{ endfor }\n\n[...]\n```\n\nBasically, a clean TeX file with some Jinja2 syntax inside the `\\jb` and `\\jv` special tags.\n\nWe plug those two and we get a fancy LaTeX render, obtaining:\n\n\u003cimg src=\".meta/pdf_sample.png\" alt=\"latex preview\"\u003e\n\n### React/Vue\n\nRecent tools have native support for plugging JSON data.\nE.g. on a Vue component:\n\n```\n\u003ctitle\u003e{{ name }} résumé\u003c/title\u003e\nName: {{ name }}\nAddress: {{ address }}\nAge: {{ age }}\nPhone: {{ phone }}\nWebsite: {{ website }}\nGitHub: {{ github }}\nEmail: {{ email }} \n\n\u003csubtitle\u003e Education \u003c/subtitle\u003e\n\u003ctemplate v-for=\"degree in education\"\u003e\n    \u003ch3\u003e{{ degree.title }}\u003c/h3\u003e\n    \u003csubtitle\u003e{{ degree.school }}\u003cbr\u003e\n    \u003ci\u003e{{ degree.field }}\u003c/i\u003e\u003c/subtitle\u003e\n\u003c/template\u003e\n```\n\n## Build\n\n### Requirements\n\n- a TeX distribution\n- XeLaTeX\n- Python3\n\nOn Debian:\n\n```bash\nsudo apt install texlive-base pandoc python3 texlive-xetex fonts-roboto\n```\n\nOn Fedora:\n\n```bash\nsudo dnf install texlive-collection-fontsrecommended texlive-xetex texlive-latex texlive-collection-latexextra texlive-titlesec 'tex(datetime.sty)' 'tex(eu1enc.def)' 'tex(polyglossia.sty)'\nsudo dnf install google-roboto-fonts.noarch\n```\n\n### LaTeX workflow\n\n```bash\npython j2tex.py\nxelatex resume.tex\n```\n\n## TODO\n\n- [ ] Résumé JSON schema\n- [ ] Example Vue template for the web workflow\n- [ ] Example MD/HTML5 template for the pandoc workflow\n- [ ] pandoc preprocessor to allow Markdown in the field of the json, then preprocess to the target language in each workflow.\n\n## Related projects\n\nIf 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).\n\n## References\n\nVarious resources, links and threads examined for the project.\n\n- [How to loop over the JSON object / list?](https://tex.stackexchange.com/questions/489417/how-to-loop-over-the-json-object-list)\n- [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)\n- [API JSON in Latex](https://tex.stackexchange.com/questions/272401/api-json-in-latex)\n- [jq json processor](https://stedolan.github.io/jq/manual/)\n- [Transform a JSON file into a formated Latex](https://groups.google.com/forum/#!topic/pandoc-discuss/VBHwMj6IVOY)\n- [How to iterate over a comma separated list?](https://tex.stackexchange.com/questions/159118/how-to-iterate-over-a-comma-separated-list)\n- [Why choose LuaLaTeX over XeLaTeX?](https://tex.stackexchange.com/questions/126206/why-choose-lualatex-over-xelatex)\n- [Considerations when migrating from XeTeX to LuaTeX?](https://tex.stackexchange.com/questions/23598/considerations-when-migrating-from-xetex-to-luatex)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favivace%2Fj2-resume","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Favivace%2Fj2-resume","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favivace%2Fj2-resume/lists"}