> /home/jd
ES / EN

CV as Code: Structured Data and Linear PDFs with LuaLaTeX

How one content model feeds the website and two verifiable PDFs without turning technical checks into a universal ATS guarantee.

A web resume and a separately edited document inevitably drift. A date changes in one place, a project is revised in another, and neither file is clearly the current professional record.

The first iteration of this portfolio printed /cv and /en/cv through a headless browser. Its text was extractable, but the PDFs also inherited icons, badges, and screen-oriented alignment. Those features added no value when the download reached a recruiting parser.

The current workflow assigns different jobs to each output:

  • the website keeps the visual presentation;
  • the download follows a predictable linear structure.

Both are built from the same data.

One Content Model, Two Editorial Versions

src/data/cvProfile.js stores the shared identity and two explicit editorial objects, one for Spanish and one for English. Each object owns its summary, experience, education, projects, skills, languages, and metadata.

Nothing automatically translates or approves the English version. Sharing the model prevents the web page and PDF for a given language from disagreeing; human review still determines whether both languages describe the same facts naturally and accurately.

Astro receives that data for the web routes, while the PDF generator derives a temporary LaTeX source:

Text
cvProfile.js
├── CvPage.astro → /cv and /en/cv
└── generate-cv-pdf.js → LuaLaTeX → Spanish and English PDFs

The .tex file is disposable build output, not another resume to maintain by hand.

Why the Download Uses a Linear Layout

Greenhouse lists graphics, complex tables, headers, footers, text boxes, and columns among common causes of incomplete parsing. Lever recommends checking whether PDF text can be selected as a basic diagnostic. SAP explicitly notes that resume parsing is not completely accurate.

No layout can guarantee identical behavior across every applicant tracking system. The project can still make conservative, testable choices. The download:

  • has one column;
  • contains no tables, images, icons, headers, footers, or text boxes;
  • places contact details, summary, skills, experience, projects, education, and languages in one sequence;
  • uses conventional section names;
  • is compiled as a tagged PDF 1.7 document with LuaLaTeX;
  • embeds fonts with Unicode mappings.

The official LaTeX tagging guidance provides the document-level mechanism used to produce that structure.

Generation That Refuses Partial Success

PDF generation remains an explicit maintenance action:

Bash
npm run cv:gen

Both locales are compiled in a temporary directory. Before either public file is replaced, the script checks:

  1. A4 size, no more than two pages, and a file size below 2.5 MB;
  2. expected metadata, tags, and encryption state;
  3. embedded Unicode fonts and the absence of Type 3 fonts;
  4. extractable text without replacement characters;
  5. the expected identity, organizations, projects, and education;
  6. linear section order.

A compile or validation failure exits with a non-zero status and prevents a half-updated pair from being published. The same checks can run independently:

Bash
npm run cv:check

Final review also compares extraction through Poppler, pypdf, and pdfplumber. Each page is rendered to an image to catch clipping, overlap, or damaged glyphs.

What the Checks Actually Establish

The current PDFs are compact, selectable, and linear. Those properties reduce documented parsing risks and make regressions observable.

They do not prove that a specific platform will map every field correctly, and they do not support a “100% ATS compatible” label. A platform may still impose its own requirements or prefer another format such as DOCX.

The durable result is more modest and more useful: one source of professional facts per language, a machine-oriented download, and tests that fail when its technical contract is broken. Professional accuracy still depends on deliberate editorial review.