Single-source CV. Edit cv.yaml, run make, get every format.
make # render the web page + all 3 PDFs + Markdown + LaTeX source
make publish # build, then refresh the repo-root cv.html + resume.pdf
make open # build, then open the HTML page in your browser
make docx # also produce dist/cv.docx (Markdown → Word, for ATS portals)
make clean # remove dist/cv.html and resume.pdf live at the repo root because external sites link to
them directly — those paths must stay put. make publish regenerates them from
cv.yaml (web page → cv.html, two-column PDF → resume.pdf) without changing
the URLs. Everything else is build output under dist/ (gitignored).
| File | What it is | Use for |
|---|---|---|
cv.html |
Modern responsive two-column page | View / host on Pages; share with humans |
cv-singlecol.pdf |
Modern single-column PDF | Upload to job portals (ATS-clean) |
cv-latex.pdf |
Classic LaTeX-typeset PDF | Upload (ATS-clean); the "on paper" look |
cv-twocol.pdf |
Two-column sidebar PDF | Share with humans — not for ATS |
cv.md |
Plain Markdown | ATS, LinkedIn, web forms |
cv.tex |
LaTeX source | Compiled into cv-latex.pdf |
See docs/design/ats-review.md for why the two-column layout is web/human-only:
parsers read its sidebar out of order. Single-column and LaTeX parse cleanly.
build.py loads cv.yaml and renders the Jinja2 templates in templates/,
then drives headless Chrome (single- and two-column PDFs) and tectonic (LaTeX
PDF). Inline **bold** / *italic* in cv.yaml is converted to the right
markup per format, so the content stays format-agnostic.
- HTML, single/two-column PDF, Markdown: Python 3 with
pyyaml+jinja2, and Google Chrome. - LaTeX PDF:
tectonic(brew install tectonic). If absent,makebuilds everything else and skipscv-latex.pdf. make docx:pandoc.