Skip to content

feat: add preferences.density preset to scale spacing tokens uniformly#127

Open
smur89 wants to merge 1 commit into
mainfrom
feat/issue-50-density-preset-v2
Open

feat: add preferences.density preset to scale spacing tokens uniformly#127
smur89 wants to merge 1 commit into
mainfrom
feat/issue-50-density-preset-v2

Conversation

@smur89

@smur89 smur89 commented Jun 14, 2026

Copy link
Copy Markdown
Owner

Summary

Adds preferences.density — a single coherent knob that scales every vertical spacing em-token uniformly. Three presets: "compact" (× 0.85), "comfortable" (× 1.0, default), "spacious" (× 1.15).

Closes #50. Supersedes #87 (predates the lib.typinternal//sections/ split, internal/labels-en.toml extraction, and example_full.typ demo).

Design

The multiplier is threaded through a new _spacing_scale_state (alongside the existing _body_size_state / _accent_state) and applied at every block above / below, every v(), par.spacing / leading, and list.spacing. Text sizes, icon dimensions, and rating-dot geometry are intentionally left alone — density is purely vertical whitespace; font-size scaling stays under bodySize.

"comfortable" (default) is render-identical to a no-density build — verified by regenerating every examples/tests/*.pdf against the tree before and after the change; all byte sizes unchanged.

Latent fix in sections/projects.typ

The /review pass surfaced an unscaled block(below: 0.6em, ...) on the projects description line. The accompanying comment said the gap "matches the institution-line → term spacing in _experience / _education" — which routes through name(), which IS scaled. So the literal 0.6em would have broken that contract under non-default density. Now uses 0.6 * scale * body-size to mirror name()'s below. Fixture-byte-identical at density 1.0; only differs at compact/spacious.

Test plan

  • make test — every fixture compiles green, including the new tests/density.typ (three pages: compact / comfortable / spacious).
  • Default render is byte-identical to a pre-feature build (PNG cmp on examples/example_full.typ, all tracked PDFs unchanged).
  • README's Preferences table updated with the new key.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added a new density preference to control vertical spacing throughout your resume. Select from "compact" (0.85× tighter spacing), "comfortable" (default), or "spacious" (1.15× looser spacing). Text sizes, icon dimensions, and other formatting remain unaffected.
  • Documentation

    • Updated configuration documentation with density setting details and behaviour.
  • Tests

    • Added regression test suite for density preference variants.

Adds `preferences.density` — a single coherent knob that scales every
vertical spacing em-token uniformly, replacing the need for users to
hand-tune `bodySize`, `margin`, and individual em-multipliers when
they want a tighter (one-page fit) or roomier (print presentation)
layout. Three presets: `"compact"` (× 0.85), `"comfortable"` (× 1.0,
default), `"spacious"` (× 1.15). Closes #50.

The multiplier is threaded through a new `_spacing_scale_state` and
applied at every block `above`/`below`, every `v()`, `par.spacing` /
`leading`, and `list.spacing`. Text sizes, icon dimensions, and
rating-dot geometry are intentionally left alone — density is purely
about vertical whitespace, so font-size scaling stays under
`bodySize`.

Default ("comfortable") is render-identical to a no-density build —
verified by re-running `examples/tests/*.pdf` against the tree before
and after the change; all byte sizes unchanged.

Also fixes a latent issue in `sections/projects.typ` where the
description → term gap used a literal `0.6em` and so didn't scale with
density, breaking the "matches institution-line → term spacing"
invariant the comment claimed. Now uses `0.6 * scale * body-size` to
mirror `name()`'s `below`.
@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a preferences.density setting with three presets—"compact" (×0.85), "comfortable" (×1.0, default), and "spacious" (×1.15). A new _spacing_scale_state cell and _density_scales map are introduced in internal/state.typ; the alta entry point validates and applies the scale uniformly to all vertical spacing em-tokens across header, layout primitives, and section renderers.

Changes

Density Preset Feature

Layer / File(s) Summary
State cell and default preference
internal/state.typ, internal/layout.typ
Adds _spacing_scale_state (default 1.0) and _density_scales preset map; adds density: "comfortable" to _default_preferences.
Template entry point: validation, state update, layout scaling
lib.typ
alta(...) validates preferences.density against _density_scales, stores the result in _spacing_scale_state, and applies scale to paragraph leading, list spacing, and heading vertical spacing for levels 2–4.
Layout primitives and header
internal/primitives.typ, internal/header.typ
name, term, divider, and _labelled_divider read _spacing_scale_state.get() and multiply their v(...) / below values by scale; header-text block, label, portrait container, and _summary padding similarly switch to scale * body-size multiples.
Section renderers
sections/projects.typ, sections/skills.typ
Project description below spacing and skills row-gap both change from fixed em constants to scale * body-size context-computed values.
Documentation and visual regression test
README.md, tests/density.typ
Adds one density row to the README preferences table; adds a three-page visual regression test rendering all three presets.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A rabbit hops through compact halls,
Then comfortable, spacious calls —
One knob to scale the gaps between,
The tightest résumé you've seen!
🐇 ×0.85, ×1.0, ×1.15 ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add preferences.density preset to scale spacing tokens uniformly' accurately describes the main change—introducing a new density preference that uniformly scales vertical spacing across the layout.
Description check ✅ Passed The PR description comprehensively covers the feature (three density presets, scaling ratios, state threading), design rationale, a latent bug fix, and lists the test plan, though rendered output screenshots are not explicitly attached.
Linked Issues check ✅ Passed All requirements from #50 are met: preferences.density with three presets ('compact' ×0.85, 'comfortable' ×1.0 default, 'spacious' ×1.15) uniformly scale spacing tokens via _spacing_scale_state threading through all layout components.
Out of Scope Changes check ✅ Passed All changes directly support the density feature goal. The only tangential change—a latent bug fix in sections/projects.typ where 0.6em block spacing now scales proportionally—is explicitly acknowledged and justified as maintaining visual contracts.
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-50-density-preset-v2

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

@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 `@tests/density.typ`:
- Around line 10-50: The test CV data in the cv variable is missing a projects
section, which means the density spacing fix in sections/projects.typ (where
hardcoded 0.6em spacing now scales with density) is not being exercised by the
regression test. Add a projects section to the cv data structure with
appropriate project entries (name, description, startDate, endDate, etc.) to
ensure the spacing behavior is tested and any future regressions in project
description spacing are caught.
🪄 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: aa783a29-c83f-4b46-babe-ea3dd88da50e

📥 Commits

Reviewing files that changed from the base of the PR and between 200dc34 and 8d7adc8.

⛔ Files ignored due to path filters (1)
  • examples/tests/density.pdf is excluded by !**/*.pdf
📒 Files selected for processing (9)
  • README.md
  • internal/header.typ
  • internal/layout.typ
  • internal/primitives.typ
  • internal/state.typ
  • lib.typ
  • sections/projects.typ
  • sections/skills.typ
  • tests/density.typ

Comment thread tests/density.typ
Comment on lines +10 to +50
#let cv = (
basics: (
name: "Jane Doe",
label: "Senior Software Engineer",
summary: [Backend engineer; the summary block exercises the
pre/post `v()` gaps that flank it.],
email: "jane@example.com",
phone: "+353 1 555 0100",
location: "Dublin, Ireland",
),
work: (
(
name: "Acme Corp",
position: "Senior Software Engineer",
location: "Dublin, Ireland",
startDate: "Jan 2022",
highlights: ([Led the migration.], [Designed the platform.]),
),
(
name: "Foo Ltd",
position: "Software Engineer",
startDate: "Jan 2018",
endDate: "Dec 2021",
highlights: ([Shipped the thing.],),
),
),
skills: (
(name: "Languages", keywords: ("Scala", "Python")),
(name: "Infra", keywords: ("Kafka", "AWS", "Kubernetes")),
),
languages: (
(language: "English", fluency: "Native"),
(language: "Irish", fluency: "Professional Working"),
),
education: (
(institution: "Example U", studyType: "B.Sc.", endDate: "2017"),
),
certificates: (
(name: "CKA", issuer: "CNCF"),
),
)

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

Consider adding a projects section to cover the sections/projects.typ spacing fix.

The PR objectives mention a latent bug fix in sections/projects.typ where hardcoded 0.6em spacing now scales with density. The test CV data doesn't include a projects section, so the regression test won't exercise that fix or catch future regressions in project description spacing.

📋 Suggested addition to CV data
   education: (
     (institution: "Example U", studyType: "B.Sc.", endDate: "2017"),
   ),
+  projects: (
+    (
+      name: "Open Source Tool",
+      description: [Built a CLI tool; exercises the project description spacing that was fixed.],
+      highlights: ([Released v1.0.],),
+    ),
+  ),
   certificates: (
     (name: "CKA", issuer: "CNCF"),
   ),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#let cv = (
basics: (
name: "Jane Doe",
label: "Senior Software Engineer",
summary: [Backend engineer; the summary block exercises the
pre/post `v()` gaps that flank it.],
email: "jane@example.com",
phone: "+353 1 555 0100",
location: "Dublin, Ireland",
),
work: (
(
name: "Acme Corp",
position: "Senior Software Engineer",
location: "Dublin, Ireland",
startDate: "Jan 2022",
highlights: ([Led the migration.], [Designed the platform.]),
),
(
name: "Foo Ltd",
position: "Software Engineer",
startDate: "Jan 2018",
endDate: "Dec 2021",
highlights: ([Shipped the thing.],),
),
),
skills: (
(name: "Languages", keywords: ("Scala", "Python")),
(name: "Infra", keywords: ("Kafka", "AWS", "Kubernetes")),
),
languages: (
(language: "English", fluency: "Native"),
(language: "Irish", fluency: "Professional Working"),
),
education: (
(institution: "Example U", studyType: "B.Sc.", endDate: "2017"),
),
certificates: (
(name: "CKA", issuer: "CNCF"),
),
)
`#let` cv = (
basics: (
name: "Jane Doe",
label: "Senior Software Engineer",
summary: [Backend engineer; the summary block exercises the
pre/post `v()` gaps that flank it.],
email: "jane@example.com",
phone: "+353 1 555 0100",
location: "Dublin, Ireland",
),
work: (
(
name: "Acme Corp",
position: "Senior Software Engineer",
location: "Dublin, Ireland",
startDate: "Jan 2022",
highlights: ([Led the migration.], [Designed the platform.]),
),
(
name: "Foo Ltd",
position: "Software Engineer",
startDate: "Jan 2018",
endDate: "Dec 2021",
highlights: ([Shipped the thing.],),
),
),
skills: (
(name: "Languages", keywords: ("Scala", "Python")),
(name: "Infra", keywords: ("Kafka", "AWS", "Kubernetes")),
),
languages: (
(language: "English", fluency: "Native"),
(language: "Irish", fluency: "Professional Working"),
),
education: (
(institution: "Example U", studyType: "B.Sc.", endDate: "2017"),
),
projects: (
(
name: "Open Source Tool",
description: [Built a CLI tool; exercises the project description spacing that was fixed.],
highlights: ([Released v1.0.],),
),
),
certificates: (
(name: "CKA", issuer: "CNCF"),
),
)
🤖 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 `@tests/density.typ` around lines 10 - 50, The test CV data in the cv variable
is missing a projects section, which means the density spacing fix in
sections/projects.typ (where hardcoded 0.6em spacing now scales with density) is
not being exercised by the regression test. Add a projects section to the cv
data structure with appropriate project entries (name, description, startDate,
endDate, etc.) to ensure the spacing behavior is tested and any future
regressions in project description spacing are caught.

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: density preset (compact / comfortable / spacious)

1 participant