fix(cv): print course-table column headers as written in the record - #21
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Stop deriving casing of course-table column headers so row keys print verbatim
What Changed
tableHeaderinscripts/build-cv-data.mjstakes adisplayKeythat defaults to identity, andweb/src/pages/cv.astrodrops itsheadingCaselabel wrapper from<th>anddata-label. The per-section\cv<Key>Headermacros keep title case by passingheadingCaseexplicitly, so section headings and the printed layout are unchanged.content/cv.yamland the website fixture record carry the capitals themselves (Course,Programme,Topics,Points), since casing is now the adopter's to write.headingCasecopies andcontent/README.mdwere rewritten to state the narrower rule — derived section/announcement keys are recased, record keys are not — and the tests inscripts/build-cv-data.test.mjsandweb/src/lib/cv.test.tswere updated to match.Risk Assessment
✅ Low: The follow-up commit restores
cv/generated/cv-data.texbyte-for-byte to the base commit while keeping course-table headers verbatim, pins both callers oftableHeaderwith tests, and leaves only a one-line stale comment.Testing
Ran the generator unit suite and the website record self-checks (cv, live-record, announcements) plus the generated-data freshness gate — all green. Because both the bundled record and the fixture record now use already-capitalised course keys, unit passes alone cannot show verbatim behaviour, so I built two PDFs: the real record (course table and small-caps section headers unchanged) and a scratch repo copy whose course keys are deliberately mixed-case, where the printed table shows "Programme / level", "Key topics" and "points" exactly as written instead of the old derived "Programme / Level", "Key Topics", "Points". The same mixed-case record served through astro dev renders those keys verbatim in the table markup, in the mobile data-label, and in the visible "keys read" provenance line; the site's own CSS uppercases table headers, so on-screen header glyphs look identical either way and the casing evidence there is the provenance line and markup rather than the header cells. Screenshots of both surfaces are attached; PDF and staged web build outputs were removed afterwards, leaving the worktree clean.
/tmp/no-mistakes-evidence/01KYTDGGBAG1JJRXT834TTPZZF/pdf-verbatim-course-table-1.png)/tmp/no-mistakes-evidence/01KYTDGGBAG1JJRXT834TTPZZF/pdf-real-course-table-1.png)/tmp/no-mistakes-evidence/01KYTDGGBAG1JJRXT834TTPZZF/site-cv-verbatim-keys.png)/tmp/no-mistakes-evidence/01KYTDGGBAG1JJRXT834TTPZZF/site-cv-courses-real-record.png)/tmp/no-mistakes-evidence/01KYTDGGBAG1JJRXT834TTPZZF/page-1.png)Evidence: Generated LaTeX and website markup for the mixed-case record
/tmp/no-mistakes-evidence/01KYTDGGBAG1JJRXT834TTPZZF/verbatim-build)Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
scripts/build-cv-data.mjs:586-tableHeaderis used by two callers, and only one is a course table. Line 586 builds the per-section\cv<Key>Headermacros from entry field names, which are schema-fixed (title,org,place,dates,items,announced) and always lowercase — an adopter cannot re-case them in the record without breakingreadCv. DroppingheadingCasethere regressed the committed output:cv/generated/cv-data.tex:119now reads\textbf{title} & \textbf{org} & \textbf{place} & \textbf{dates} & \textbf{detail} & \textbf{url} & \textbf{items} & \textbf{announced} \\where it read\textbf{Title} & \textbf{Org} & …. The bundled layout supplies its own headings (cv/preamble.tex:195), so no PDF or baseline moves, but the generator's own header comment (scripts/build-cv-data.mjs:17) documents\cv<Key>Headeras one of the six macros an adopter gets for free, and a fork printing\cvAppointmentsRowsunder\cvAppointmentsHeadernow gets lowercase column headings with no record-side fix. The intent covers course-table column headers only; keepheadingCase(k)on the line-586 path and print verbatim only fromentry().web/src/lib/cv-schema.ts:611- The rewritten doc comments and the deleted cv.test.ts note removed the "two copies of one rule across the build boundary, they must agree" warning from bothheadingCasedefinitions. That invariant is narrower now but still live: section keys go throughsectionHeading(scripts/build-cv-data.mjs:277) for the printed heading and throughsingular(web/src/lib/announcements.ts:264) for the /lately/ chip, sofield_workmust read "Field Work" in both, and nothing crosses the plain-node/Vite boundary to enforce it. The new comment says only "Used for announcement kind chips on /lately/", which no longer warns an editor of the other copy. Restore a one-line cross-reference on both sides scoped to section keys.web/src/pages/cv.astro:75-const label = (key: string) => key;is now an identity function, called at cv.astro:202 and cv.astro:210. Inlinekeyat both call sites and delete the binding.web/src/lib/cv.test.ts:200- The retainedheadingCaseassertions still use course-column examples (programme / level,key topics,kōwhai level) that no caller produces any more — announcement kinds are section keys such asfield_work/fieldwork. The assertions are still valid for the function, but they no longer anchor to a real consumer; re-anchoring one case to a section key would keep the test meaningful.🔧 Fix: Restore section header casing without altering course labels
1 info still open:
scripts/build-cv-data.mjs:223-/** One word, capitalised. The generator's only casing rule; every heading uses it. */is no longer true after this branch: course-table column headers now bypass all casing (tableHeader's defaultdisplayKeyis identity, used byentry()at line 248). The very next comment block draws the distinction correctly, so this one line is the only stale claim left in the neighbourhood — trim it to "every derived heading uses it" or drop the second clause.✅ **Test** - passed
✅ No issues found.
node --test scripts/build-cv-data.test.mjs(45 tests, includes new verbatimtableHeaderand\cvAppointmentsHeadertitle-case cases)node --experimental-strip-types web/src/lib/cv.test.ts(fixture record now uses capitalised course keys;headingCaseassertions retained)node --experimental-strip-types web/src/lib/live-record.test.tsLEDGERPRESS_RECORD_ROOT=src/lib/fixtures/record node --experimental-strip-types web/src/lib/announcements.test.ts(headingCase's remaining consumer)node scripts/build-cv-data.mjs --check— committedcv/generated/cv-data.texis fresh againstcontent/cv.yamllatexmk -xelatex -cd cv/cv.texon the real record, page 1 rendered withpdftoppmto confirm the printed course table and section headers are unchangedManual verbatim proof:git archive HEADinto /tmp, rewrote course row keys toProgramme / level/Key topics/points, rannode scripts/build-cv-data.mjs+latexmk -xelatex -cd cv/cv.tex, cropped the course table from the PDFManual website check:astro devon that mixed-case copy, read<th scope="col">/data-labelmarkup via curl and screenshotted /cv/ with "inspect sources" on✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.