Skip to content

Render semantic chord parts, Unicode symbols, and muted rhythm markers - #2248

Merged
isaiahdahl merged 18 commits into
publish/directive-name-normalization-canaryfrom
feat/superscript-demo
Sep 18, 2026
Merged

isaiahdahl merged 18 commits into
publish/directive-name-normalization-canaryfrom
feat/superscript-demo

Conversation

@isaiahdahl

@isaiahdahl isaiahdahl commented Jul 28, 2026 •

Copy link
Copy Markdown
Collaborator

Stack position

3 of 4

The effective diff contains chord shaping, Unicode/font work, configurable chord-part rendering, and muted-x styling. Directive and token-model changes remain in the base PR.

Review first

  1. src/rendering/chord_shaper.ts
  2. src/layout/engine/item_processor.ts
  3. src/rendering/pdf/js_pdf_renderer.ts
  4. src/rendering/html/chord_run_renderer.ts
  5. src/chord_sheet/chord_line_token.ts for muted x
  6. script/build_symbol_fonts.py and script/check-symbol-fonts.sh

Problem

PDF and measured HTML need the same understanding of a displayed chord. Roots, qualities, extensions, and basses can use different sizes, baselines, and fallback fonts, but measurement and rendering must still agree or line wrapping changes between passes.

Unicode accidentals also need glyphs and metrics that are available in generated PDFs. Relying on an environment font can change output between machines.

Changes

Semantic chord shaping

Displayed chords are split into semantic runs:

marker | root | quality | extensions | bass | marker

The same run model drives:

  • line measurement and wrapping;
  • PDF chord rendering;
  • measured-HTML spans and classes;
  • chord-diagram titles.

Public configuration

new PdfFormatter({
  useUnicodeModifiers: true,
  chordRendering: {
    quality: {
      fontSizeRatio: 0.9,
    },
    extensions: {
      fontSizeRatio: 0.85,
      baselineShiftRatio: 0.3,
    },
  },
});

Omitted values keep neutral rendering. The older chordSuperscript input remains readable for compatibility but is not part of the new configuration surface.

Unicode fonts

  • Parse Unicode accidentals in roots, extensions, keys, and slash basses.
  • Add a generated ChordSheet Symbols font with source attribution and drift checks.
  • Install pinned uv in CI for deterministic font generation.
  • Skip binary font sources in the trailing-whitespace text check.
  • Use the same glyph metrics during measurement and PDF output.
  • Preserve Unicode text extraction.

Muted rhythm symbols

  • Keep x semantically classified as rhythm-symbol with variant mute.
  • Resolve only its visual role to noChord.
  • Keep / and - on the ordinary rhythm-symbol role.
  • Apply the role consistently to measurement and positioned HTML.

Integration guarantees

Boundaries

This layer does not choose contextual enharmonic spellings. It renders the finalized Chord model supplied by the parser and song operations. That provenance work is in #2237.

Validation

  • Full suite at this layer: 184 suites passed; 45,525 tests passed; 3 skipped.
  • Type checks, ESLint, package exports, and symbol-font drift checks passed.
  • Tests cover PDF, measured HTML, positioned HTML, chord-diagram titles, Unicode extraction, responsive pagination, and muted x semantics.

@isaiahdahl
isaiahdahl force-pushed the feat/superscript-demo branch from a86a284 to 9b89822 Compare August 7, 2026 16:59
@isaiahdahl isaiahdahl changed the title Render semantic chord parts and Unicode PDF symbols Render semantic chord parts, Unicode symbols, and muted rhythm markers Aug 7, 2026
@isaiahdahl
isaiahdahl force-pushed the feat/superscript-demo branch from 80711af to 37c0d9c Compare August 7, 2026 17:14
@isaiahdahl
isaiahdahl marked this pull request as ready for review August 7, 2026 18:25
@isaiahdahl
isaiahdahl force-pushed the feat/superscript-demo branch from 37c0d9c to bbcbbcb Compare August 7, 2026 18:26
@isaiahdahl
isaiahdahl force-pushed the feat/superscript-demo branch 2 times, most recently from dc45a06 to f592b61 Compare August 13, 2026 20:51
Comment thread script/build_symbol_fonts.py Outdated
Comment thread src/rendering/chord_shaper.ts Outdated
Comment thread src/key.ts
@isaiahdahl
isaiahdahl force-pushed the feat/superscript-demo branch from f592b61 to d1fb5da Compare August 17, 2026 18:18
@isaiahdahl
isaiahdahl force-pushed the feat/superscript-demo branch 3 times, most recently from fefb631 to efa37f3 Compare August 17, 2026 22:08
@isaiahdahl
isaiahdahl force-pushed the feat/superscript-demo branch from efa37f3 to e5bb771 Compare August 18, 2026 15:45
@isaiahdahl
isaiahdahl force-pushed the feat/superscript-demo branch from e5bb771 to 27169e0 Compare August 24, 2026 22:55
Comment thread package.json Outdated
@isaiahdahl
isaiahdahl force-pushed the feat/superscript-demo branch from 48c930a to dd6da8d Compare August 28, 2026 22:26
@isaiahdahl
isaiahdahl force-pushed the feat/superscript-demo branch from dd6da8d to 5307877 Compare September 14, 2026 16:20
@isaiahdahl
isaiahdahl force-pushed the feat/superscript-demo branch from 5307877 to c307e51 Compare September 18, 2026 15:45
@isaiahdahl
isaiahdahl merged commit 071353a into master Sep 18, 2026
22 checks passed
@isaiahdahl
isaiahdahl deleted the feat/superscript-demo branch September 18, 2026 15:54
@github-project-automation github-project-automation Bot moved this from In Progress to Done in ChordSheetJS project board Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

2 participants