fix(cv-template): use ASCII hyphens and explicit ranges in CV date fields (#276)

* fix(cv-template): use ASCII hyphens and explicit ranges in CV date fields

LaTeX ligatures `--` into an en-dash (U+2013), so a `\cventry` date written
`2016--2024` reaches the PDF text layer as `2016<U+2013>2024`. Many ATS
parsers split date ranges only on an ASCII hyphen and therefore extract no
range at all. Separately, a bare single year gives the parser a start date
with no end.

Confirmed against a real Workday resume import: a CV built from this
template lost the end date of a short contract role and imported no
education entries whatsoever, forcing manual re-entry. The failure is
silent - extraction was otherwise clean, with literal contact details, no
(cid:) markers and correct reading order, so every existing check in the
ATS Parseability section passed.

- main_example.tex: date placeholders now use a single hyphen
- 05-cv-templates.md: document both causes, with examples, and add the
  check to step 5d

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BFNdaj4fB6Xrd29PQ6hc9B

* chore(cv-template): bump framework_version to 1.4.0

The ATS date-format guidance added in the previous commit modifies a
framework template, which the CI framework version guard requires to be
accompanied by a version bump. Minor bump: new documented subsection,
no breaking change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs(changelog): record the CV date-field hyphen fix and fork reconciliation

Documents the U+FFFD extraction failure under lualatex, the fix, and the
framework_version bump. Includes the fork reconciliation note requested in
review: the five changed lines in cv/main_example.tex are the \cventry date
fields every fork personalizes, so rebasing forks should expect conflicts
there, resolve in favour of their own dates, and reapply the -- to - change
by hand. Adds a grep to locate remaining instances and a pdftotext check to
verify.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: kgb <kevingblackman@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
kblackma
2026-08-03 21:10:00 +02:00
committed by GitHub
co-authored by Claude Opus 5 kgb
parent 6392ca1628
commit befaaf5eef
3 changed files with 55 additions and 6 deletions
@@ -1,5 +1,5 @@
---
framework_version: 1.3.0
framework_version: 1.4.0
---
# CV Templates and Tailoring Guide
@@ -244,6 +244,31 @@ What to check in the extraction:
- **Reading order.** The stock banking style is single-column, so extraction order matches visual order. Custom templates (via `/add-template`) with sidebars or multi-column layouts can interleave unrelated lines; if extraction order is scrambled, the user is trading ATS compatibility for looks and should be told.
- **Keyword coverage.** Match the posting's required/preferred terms against the extracted text, in the posting's language. Prefer the posting's exact term over a synonym when it is truthfully applicable - ATS matching is often literal. Never add a keyword the profile does not support.
### Date fields must be ASCII ranges (confirmed ATS import failure)
This one is worth knowing about because it fails **silently**. A CV that passes every other check in this section - clean extraction, no `(cid:)` markers, contact details intact, correct reading order - can still have its dates dropped on import. In a real Workday resume import, a CV built from this template lost the end date of a short contract role and failed to import **any** education entry at all, forcing manual re-entry. Nothing about the PDF or its text layer looked wrong.
Two independent causes, both easy to avoid:
1. **`--` in a `\cventry` date renders as an en-dash (U+2013), not a hyphen.** LaTeX ligatures `--` (two ASCII hyphens, U+002D) into a single en-dash glyph, so `2016--2024` reaches the PDF text layer as `2016<U+2013>2024`. Many parsers split date ranges only on an ASCII hyphen and see no range at all. Write the date argument with a **single hyphen**:
```latex
\item{\cventry{2016-2024}{Role Title}{Organization}{Location}{}{...}} % parses
\item{\cventry{2016--2024}{Role Title}{Organization}{Location}{}{...}} % en-dash, may not
```
This applies to the **date argument only**. Keep `--` everywhere it is typographically correct in prose, for example a numeric range like `EUR 600k--1M`.
2. **A bare single year gives the parser no end date.** A short contract, mandate or internship written as `\cventry{2016}` imports as a start date with nothing to close it. Use an explicit range, with months where the role ran under a year:
```latex
\item{\cventry{Mar 2016 - Jul 2016}{Contract Role}{Client}{Location}{}{...}}
```
Where a genuine range exists, use it even when a single year would be factually accurate - a degree written `1995` is true but imports worse than `1992-1995`. Do not invent a start date you do not have; a lone graduation year is fine, just expect it to be typed in by hand.
**Add this to the step 5d checks**: after extracting the text layer, confirm every experience entry shows a start *and* an end separated by an ASCII hyphen. Because the failure is silent and invisible in the PDF, the candidate otherwise discovers it only while filling in the application form.
## Page Budget - Hard 2-Page Limit
The CV **must** fit on exactly 2 pages when compiled. Use these content limits as a guide: