Files
santifer--career-ops/modes/latex.md
T
wehub-resource-sync d083df1fdb
CodeQL Analysis / Analyze (javascript-typescript) (push) Failing after 2s
Web CI / web typecheck + build (push) Failing after 1s
Release Please / release-please (push) Failing after 1s
CodeQL Analysis / Analyze (go) (push) Failing after 16s
chore: import upstream snapshot with attribution
2026-07-13 12:02:43 +08:00

6.7 KiB

Mode: latex — LaTeX/Overleaf CV Export

Export a tailored, ATS-optimized CV as a .tex file and compile it to PDF via tectonic or pdflatex.

Pipeline

  1. Read cv.md as source of truth
  2. Read config/profile.yml for candidate identity and contact info
  3. Ask the user for the JD if not already in context (text or URL)
  4. Extract 15-20 keywords from the JD
  5. Detect JD language → CV language (EN default)
  6. Detect role archetype → adapt framing
  7. Rewrite Professional Summary injecting JD keywords (same rules as pdf mode — NEVER invent skills)
  8. Select top 3-4 most relevant projects for the offer
  9. Reorder experience bullets by JD relevance
  10. Inject keywords naturally into existing achievements
  11. Build a JSON payload (see schema below) and write to /tmp/cv-{candidate}-{company}.json
  12. Run: node build-cv-latex.mjs /tmp/cv-{candidate}-{company}.json output/cv-{candidate}-{company}-{YYYY-MM-DD}.tex
  13. Run: node generate-latex.mjs output/cv-{candidate}-{company}-{YYYY-MM-DD}.tex output/cv-{candidate}-{company}-{YYYY-MM-DD}.pdf (Replace {candidate}, {company}, {YYYY-MM-DD} with actual values.)
  14. Report: .tex path, .pdf path, file sizes, section count, keyword coverage %

Requires: tectonic (preferred — brew install tectonic, auto-downloads packages) or pdflatex (MiKTeX / TeX Live) on PATH.

Language support

  • Localized section titles are fine. The validator counts \section{} blocks instead of matching English titles, so a Spanish/French/German CV (e.g. \section{Educación}) validates normally.
  • CJK (Japanese / Chinese / Korean) is NOT supported on this path yet. The template is a pdfLaTeX / Computer-Modern setup with no CJK font, so kana/kanji/hangul cannot render. generate-latex.mjs detects CJK characters and stops with guidance. For a Japanese CV, use pdf mode (HTML → PDF), which renders CJK via a lang="ja" font fallback.

JSON Input Schema

Write a JSON file with this structure. build-cv-latex.mjs handles template merge and LaTeX escaping — no need to escape special characters yourself.

{
  "name": "Jane Smith",
  "contact_line": "San Francisco, CA | +1 415 555 0100",
  "email": { "url": "jane@example.com", "display": "jane@example.com" },
  "linkedin": { "url": "https://linkedin.com/in/janesmith", "display": "linkedin.com/in/janesmith" },
  "github": { "url": "https://github.com/janesmith", "display": "github.com/janesmith" },
  "education": [
    {
      "institution": "University Name",
      "location": "City, State",
      "degree": "Bachelor of Science in Computer Science",
      "dates": "2018 - 2022",
      "coursework": ["Data Structures", "Algorithms", "Machine Learning"]
    }
  ],
  "experience": [
    {
      "company": "Company Name",
      "role": "Job Title",
      "location": "Remote",
      "dates": "June 2022 - Present",
      "bullets": [
        "Achievement bullet with JD keywords injected",
        "Another bullet with quantified impact"
      ]
    }
  ],
  "projects": [
    {
      "name": "Project Name",
      "context": "Tech stack summary for the project line",
      "dates": "",
      "bullets": [
        "What you built and what it does"
      ]
    }
  ],
  "skills": [
    { "category": "Languages", "items": "Python, JavaScript, C++" },
    { "category": "Frameworks", "items": "FastAPI, React, PyTorch" }
  ]
}

Field reference

Field Type Source
name string profile.yml → candidate.full_name
contact_line string Phone / City, State / Visa — built from profile.yml
email.url string Email for \href{mailto:...} (sanitized via sanitizeUrl, not LaTeX-escaped)
email.display string Display text for the email link
linkedin.url string Full URL with scheme for \href{} (sanitized via sanitizeUrl, not LaTeX-escaped)
linkedin.display string Display text only (no scheme)
github.url string Full URL with scheme for \href{} (sanitized via sanitizeUrl, not LaTeX-escaped)
github.display string Display text only (no scheme)
education[].institution string From cv.md Education
education[].location string Institution location
education[].degree string Degree name
education[].dates string Date range
education[].coursework string[] Optional — generates a coursework line if present
experience[].company string From cv.md Experience
experience[].role string Job title
experience[].location string Work location
experience[].dates string Date range
experience[].bullets string[] Reordered and keyword-injected achievement bullets
projects[].name string From cv.md Projects
projects[].context string Tech stack — appears next to project name
projects[].dates string Date range (or empty)
projects[].bullets string[] Selected project achievements
skills[].category string Skill category name (e.g. "Languages", "Frameworks")
skills[].items string Comma-separated skills in that category

LaTeX Escaping (handled by the script)

build-cv-latex.mjs automatically escapes all user-supplied text before insertion:

Character Escape
& \&
% \%
$ \$
# \#
_ \_
{ \{
} \}
~ \textasciitilde{}
^ \textasciicircum{}
\ \textbackslash{}
± $\pm$
$\rightarrow$

Exception: URLs inside \href{} are NOT escaped by the LaTeX escaper, but sanitizeUrl() still validates the scheme (mailto/http/https) and removes dangerous characters to prevent injection.

ATS Rules (same as pdf mode)

  • Single-column layout (enforced by template)
  • Standard section headers: Education, Work Experience, Personal Projects, Technical Skills
  • UTF-8, machine-readable via \pdfgentounicode=1
  • Keywords distributed: first bullet of each role, skills section
  • No images, no graphics, no color in body text

Keyword Injection Strategy

Same ethical rules as modes/pdf.md:

  • NEVER add skills the candidate doesn't have
  • Only reformulate existing experience using JD vocabulary
  • Examples:
    • JD says "RAG pipelines" → reword "LLM workflows with retrieval" to "RAG pipeline design"
    • JD says "MLOps" → reword "observability, evals" to "MLOps and observability"

Overleaf Compatibility

The generated .tex file uses only standard CTAN packages (no custom or bundled dependencies):

  • latexsym, fullpage, titlesec, marvosym, color, verbatim, enumitem
  • hyperref, fancyhdr, babel, tabularx, fontawesome5, multicol, glyphtounicode

Upload the .tex file directly to Overleaf — compiles with no extra configuration.