Skip to content

feat: render JSON Resume references section#83

Closed
smur89 wants to merge 3 commits into
mainfrom
feat/issue-46-references-section
Closed

feat: render JSON Resume references section#83
smur89 wants to merge 3 commits into
mainfrom
feat/issue-46-references-section

Conversation

@smur89

@smur89 smur89 commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #46. Renders the JSON Resume references[] section: each entry's name as a level-3 heading with the reference quote in italic beneath, joined by the standard divider rule. Entries missing the reference quote are silently skipped; entries with no name render as an anonymous quote.

Adds preferences.referencesAvailableOnRequest (default false). When true and the section is rendered with no valid entries (empty data, missing data, or every entry skipped), emits the conventional "References available upon request." line under the heading instead of suppressing the section. Localisable via labels.referencesAvailableOnRequest.

Wired into _sections at column: "right"; appended to the default rightColumnSections order so existing users get the section automatically once they populate references[].

Rendered output

Compiles via typst compile --root . tests/references.typ — three-page fixture exercises the populated case, the empty + opt-in fallback case, and the empty + default suppressed case. CI will upload the rendered PDFs.

Test plan

  • typst compile --root . examples/example.typ examples/example.pdf succeeds
  • Each tests/*.typ fixture compiles (including new tests/references.typ)
  • Added a fixture under tests/ covering populated entries, the available-upon-request fallback, and the default-suppressed path
  • Updated the README — new "References" subsection, label table entry, referencesAvailableOnRequest preference row, removal from the "not yet rendered" list, and added to the section-keys list

Notes for the reviewer

  • The issue spec named the new preference availableOnRequest. I prefixed it to referencesAvailableOnRequest so it's self-documenting in the flat preferences namespace (consistent with groupCertificates, uppercaseName, linkContactInfo, etc).
  • The fallback string is exposed as labels.referencesAvailableOnRequest rather than hard-coded so it can be localised alongside the other display strings the template emits.

JSON Resume alignment

ALIGNS — JSON Resume defines references[] with name and reference fields (https://jsonresume.org/schema/). This PR renders both. The preferences.referencesAvailableOnRequest opt-in is a template extension for the no-references-supplied case.

Summary by CodeRabbit

  • New Features
    • Added full JSON Resume-style References section rendering, including filtering out incomplete entries.
    • Introduced a “References available upon request” preference to control whether an empty References section shows a fallback line.
  • Documentation
    • Updated the template documentation/schema and labels to include References and the new preference.
  • Tests
    • Added fixtures covering populated References, skipped invalid entries, and both empty-list rendering behaviors.

@smur89 smur89 force-pushed the feat/issue-46-references-section branch 7 times, most recently from f3abec5 to a97da10 Compare June 14, 2026 10:58
@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a references section renderer to the alta-typst CV template. The implementation filters reference entries lacking a usable quote, conditionally shows a "References available upon request" fallback line via a new referencesAvailableOnRequest boolean preference, wires the section into the right column by default, and validates the preference type at runtime. README and test fixtures are updated accordingly.

Changes

References Section Feature

Layer / File(s) Summary
References renderer, labels, preferences, section registration, and documentation
lib.typ, README.md
Adds referencesAvailableOnRequest to the default labels map and _default_preferences (defaulting to false). Implements _references(...) which filters entries missing a reference quote and emits either the filtered list or the fallback line. Registers the section in the catalogue with right-column placement and adds boolean validation to alta(). README removes the prior "references not rendered" note, documents the new section structure and filtering behavior, the preference and its effect on empty sections, updated rightColumnSections default, and new label keys for localization.
Test fixtures
tests/references.typ, tests/empty_sections.typ
Adds tests/references.typ with three scenarios: a populated list with mixed valid/skipped entries, an empty list with referencesAvailableOnRequest: true producing the fallback line, and an empty list under default preferences suppressing the section entirely. Extends tests/empty_sections.typ with an empty references: () field.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • smur89/alta-typst#103: Both PRs add or refactor boolean-type preference validation in alta(); this PR introduces referencesAvailableOnRequest validation while the related PR extracts shared boolean-checking logic.

Poem

🐇 A section once missing, now hops into view,
References rendered, or hidden — your cue!
Filter the blanks, keep the quotes nice and neat,
"Available upon request" — a fallback so sweet.
The rabbit has typed, and the resume's complete! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: render JSON Resume references section' directly and clearly summarizes the main change: implementing rendering support for the references section from JSON Resume schema.
Description check ✅ Passed The PR description is comprehensive and well-structured, covering summary, rendered output, test plan with all checkboxes, and detailed notes. It addresses all template sections and explains design decisions.
Linked Issues check ✅ Passed All objectives from issue #46 are met: references section renders with name as heading and reference as italic text, entries without reference are skipped, anonymous entries supported, referencesAvailableOnRequest preference implemented with localisable text, and wired into _sections for right column.
Out of Scope Changes check ✅ Passed All changes are directly aligned with implementing JSON Resume references rendering. README documents the feature, lib.typ adds the renderer and preference, and tests/references.typ provides comprehensive test coverage. No extraneous changes detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/issue-46-references-section

Comment @coderabbitai help to get the list of available commands and usage tips.

@smur89 smur89 force-pushed the feat/issue-46-references-section branch from a97da10 to e8a31b3 Compare June 14, 2026 11:09
Shane Murphy added 3 commits June 14, 2026 15:16
Renders `references[]` entries (each `{name, reference}`) as a
referee heading with the quote attributed beneath in italic, joined
by the standard divider rule. Entries missing the `reference` quote
are silently skipped; entries with no `name` render as an anonymous
quote.

Adds `preferences.referencesAvailableOnRequest` (default `false`).
When `true` and the section is rendered with no valid entries, emits
the conventional "References available upon request." line under
the heading instead of suppressing the section — a common CV idiom
that removes the need to manually toggle the section on or off.
Localisable via `labels.referencesAvailableOnRequest`.

Wired into `_sections` at `column: "right"`, appended to the default
`rightColumnSections` order so it surfaces automatically.

Closes #46
@smur89 smur89 force-pushed the feat/issue-46-references-section branch from c5d3352 to 0fd8f4c Compare June 14, 2026 13:17

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib.typ`:
- Line 1175: Rename the parameter `available_on_request` to
`available-on-request` in the `_references` function signature at line 1175 to
match the file's established kebab-case convention for multi-word parameter
names. Then update the function call site at line 1329 to use the new kebab-case
parameter name `available-on-request` instead of snake_case.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2d873cce-4cdc-4590-82fc-cc2134740788

📥 Commits

Reviewing files that changed from the base of the PR and between a97da10 and 0fd8f4c.

⛔ Files ignored due to path filters (2)
  • examples/preview.png is excluded by !**/*.png
  • examples/tests/references.pdf is excluded by !**/*.pdf
📒 Files selected for processing (4)
  • README.md
  • lib.typ
  • tests/empty_sections.typ
  • tests/references.typ

Comment thread lib.typ
// it. When `availableOnRequest` is true and no valid entries remain
// (empty list, missing list, or all entries lacked a quote), render
// the conventional "References available upon request" line instead.
#let _references(entries, labels, available_on_request: false) = {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Use kebab-case for the parameter name to match file convention.

The parameter available_on_request uses snake_case, but the file's established convention for multi-word parameter names is kebab-case (e.g., image-size, link-contact-info, header-text-align in _header at lines 659–665). Rename it to available-on-request for consistency.

♻️ Proposed fix
-#let _references(entries, labels, available_on_request: false) = {
+#let _references(entries, labels, available-on-request: false) = {
   let valid = entries.filter(r => _present(r.at("reference", default: none)))
   if valid.len() == 0 {
-    if not available_on_request { return }
+    if not available-on-request { return }
     [== `#labels.references`]

Also update the call site at line 1329:

     render: (cv, labels, prefs) => _references(
       cv.at("references", default: ()),
       labels,
-      available_on_request: prefs.referencesAvailableOnRequest,
+      available-on-request: prefs.referencesAvailableOnRequest,
     ),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib.typ` at line 1175, Rename the parameter `available_on_request` to
`available-on-request` in the `_references` function signature at line 1175 to
match the file's established kebab-case convention for multi-word parameter
names. Then update the function call site at line 1329 to use the new kebab-case
parameter name `available-on-request` instead of snake_case.

@smur89

smur89 commented Jun 14, 2026

Copy link
Copy Markdown
Owner Author

Superseded by #121 — fresh branch off main rather than rebasing across the internal//sections/ module split, the move of label defaults into internal/labels-en.toml, and the example_full demo. The design is unchanged (level-3 name heading, italic reference quote, divider rule between, referencesAvailableOnRequest opt-in for the fallback line) — just rebuilt against the current layout kernel. Leaving this PR open for history; close at your convenience.

@smur89 smur89 closed this Jun 14, 2026
smur89 pushed a commit that referenced this pull request Jun 14, 2026
Closes #46. Adds `_references` renderer for JSON Resume's
`references[]`: each entry's `name` as a level-3 heading with the
`reference` quote in italic beneath, joined by the standard divider
rule. Entries missing the `reference` quote are silently skipped (no
orphan heading); entries with no `name` render the quote anonymously.

Adds `preferences.referencesAvailableOnRequest` (default `false`).
When `true` and the section has no valid entries (empty / missing
data, or every entry skipped), emits the conventional
`References available upon request.` line under the heading instead
of suppressing the section. The line text is
`labels.referencesAvailableOnRequest` so it localises alongside the
other display strings.

Wired into `_sections` at `column: "right"`; appended to the default
`rightColumnSections` order so existing users get the section
automatically once they populate `references[]`.

Supersedes #83 — that branch predates the `internal/`/`sections/`
module split and the move of label defaults into
`internal/labels-en.toml`.
smur89 added a commit that referenced this pull request Jun 14, 2026
## Summary

Closes #46. Renders JSON Resume's `references[]` — each entry's `name`
as a level-3 heading with the `reference` quote in italic beneath,
joined by the standard divider rule. Entries missing the `reference`
quote are silently skipped (no orphan heading); entries with no `name`
render the quote anonymously so the data still surfaces.

Adds `preferences.referencesAvailableOnRequest` (default `false`). When
`true` and the section has no valid entries, emits the conventional
`References available upon request.` line under the heading instead of
suppressing the section. Localised via
`labels.referencesAvailableOnRequest`.

Wired into `_sections` at `column: "right"`; appended to the default
`rightColumnSections` order so existing users get the section
automatically once they populate `references[]`.

Supersedes #83 — that branch predates the `internal/`/`sections/` module
split and the move of label defaults into `internal/labels-en.toml`.

## Design

- `name` rendered as `===` (level-3 heading), matching `awards` /
`projects`.
- `reference` rendered as `emph(...)` underneath the name.
- Entries joined by the standard `_join_with_dividers` rule, wrapped in
a `breakable: false` block so a single entry doesn't split across pages.
- Renderer logic is a three-way cascade: no valid entries + no fallback
→ suppress; no valid entries + fallback → heading + italic line; valid
entries → heading + dividered blocks.
- `references` and `referencesAvailableOnRequest` keys added to
`internal/labels-en.toml` so translators have a single resource file to
update.
- `_check_bool("referencesAvailableOnRequest", ...)` added alongside the
other bool validations in `alta()`.
- `example_full.typ` gains a populated `references` block (one named +
one anonymous quote) so the gallery exercises both paths.

## Test plan

- [x] `make test` — every example + fixture compiles
- [x] `make test-template` — `template/cv.typ` still compiles via the
sed-swap path
- [x] `make example-full` — regenerated `examples/example_full.pdf` and
the page-2 PNG; gallery alt text updated
- [x] `make examples/tests/references.pdf` — 3-page fixture covering
populated entries, the available-upon-request fallback, and the
default-suppressed path
- [x] Visual check of all three fixture pages — heading, dividers,
italic quotes, and the anonymous-quote path all render as designed
- [x] README updated — new `References` subsection, label table entries
(`references`, `referencesAvailableOnRequest`),
`referencesAvailableOnRequest` preferences row, removal from the "not
yet rendered" list, addition to the top-level keys list, addition to
both column-keys lists (right-column default + single-column streaming
order)

## JSON Resume alignment

ALIGNS — JSON Resume defines `references[]` with `name` and `reference`
fields (https://jsonresume.org/schema/); this PR renders both. The
`preferences.referencesAvailableOnRequest` opt-in is a template
extension for the no-references-supplied case.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added support for rendering a References section from JSON Resume
`references[]`, with an option to show “References available upon
request” when no usable reference data is present.

* **Documentation**
* Expanded README with References schema and preference configuration
details.
* Added new English labels for the References heading and the on-request
fallback.
* Updated gallery alt text to mention references in the rendered
content.

* **Examples & Tests**
  * Updated the full CV example to include populated References entries.
* Added/updated test coverage for populated, empty-with-fallback, and
empty-suppressed rendering paths.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Shane Murphy <shane@swissborg.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add references section

1 participant