Skip to content

Honor expandChorusDirective in PdfFormatter - #2271

Open
martijnversluis wants to merge 1 commit into
masterfrom
pdfformatter-does-not-honor-expandchorusdirective
Open

Honor expandChorusDirective in PdfFormatter#2271
martijnversluis wants to merge 1 commit into
masterfrom
pdfformatter-does-not-honor-expandchorusdirective

Conversation

@martijnversluis

@martijnversluis martijnversluis commented Aug 15, 2026

Copy link
Copy Markdown
Owner

Fixes #2240

The PDF layout engine always read the song's bodyParagraphs, so {chorus} directives were never expanded in PDF output — unlike TextFormatter and HtmlFormatter, which honor expandChorusDirective.

Changes

  • LayoutEngine now resolves the paragraphs to lay out from the config: it uses expandedBodyParagraphs when expandChorusDirective is enabled, and returns the resolved array instead of writing it back onto the song.
  • expandChorusDirective is added to LayoutConfig and passed through from PdfFormatter.
  • Dropped the redundant song.clone() in paragraph selection: the source paragraphs are never mutated (all pushed paragraphs are clones), and cloning stripped line numbers, which LineExpander needs to expand {chorus}.
  • Song#renderParagraphs is no longer used internally and is deprecated.

Note on repeatedSections

The PDF default repeatedSections: 'title_only' collapses repeated sections to their title. Since an expanded {chorus} reproduces the chorus, it is treated as a repeat and collapsed to its title under the default config. To get output identical to text/HTML (the expanded chorus rendered in full), combine expandChorusDirective: true with a non-collapsing repeatedSections such as 'full'.

Tests

Added PDF formatter tests asserting chorus lyrics are laid out twice when expandChorusDirective: true and once when false (with repeatedSections: 'full').

@martijnversluis
martijnversluis force-pushed the pdfformatter-does-not-honor-expandchorusdirective branch 4 times, most recently from 2bfb382 to b56b75c Compare August 15, 2026 13:18
The PDF layout engine always read the song's bodyParagraphs, so
{chorus} directives were never expanded in PDF output, unlike the
text and HTML formatters. The engine now resolves the paragraphs to
lay out from the config (expanding {chorus} when enabled) and returns
them, instead of writing them back onto the song.

Song#renderParagraphs is no longer used internally and is deprecated.
@martijnversluis
martijnversluis force-pushed the pdfformatter-does-not-honor-expandchorusdirective branch from b56b75c to 1d3c38d Compare August 15, 2026 13:27
Comment on lines +115 to +118
.configure({
layout: { sections: { base: { display: { repeatedSections: 'full' } } } },
expandChorusDirective,
})

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Noticing the fact that repeatedSections needs to be set to full for this to work. So I dug around on that.

  1. expandChorusDirective recalls the chorus.
  2. repeatedSections then processes the recalled section.
  3. PDF defaults repeatedSections to title_only.

As a result, {chorus} is expanded, but the default PDF configuration can remove its lyrics and retain only its label. hide can remove the recalled section. full retains the full section.

Labels also affect the result. A bare {chorus} can match the original chorus label and be reduced as a repeat. {chorus: Sing it} can use a different label and avoid that match. The same configuration can therefore produce different output based on the directive label.

I see three possible paths:

  1. Keep the current processing order. Treat repeatedSections as the final display rule. Add a warning and document the interaction.
  2. Make expandChorusDirective: true always render the full recalled chorus. This requires cloned lines and source tracking so repeat processing can skip generated sections.
  3. Add a separate chorus-directive display option. This is a larger configuration and migration change.

I prefer path 1 for this PR because it keeps the fix small. I suggest these amendments:

  • Pass expandChorusDirective through MeasuredHtmlFormatter as well. It uses the same layout engine.

  • Use the shared warn() helper when expandChorusDirective is true and repeatedSections is not full.

  • Use wording such as:

    │ expandChorusDirective runs before repeatedSections. The current repeated-section mode can hide part or all of the recalled chorus. Use repeatedSections:
    │ "full" to show the full chorus.

Warn only in this case:

  expandChorusDirective === true &&
  repeatedSections !== 'full'

This would make the current behavior explicit without expanding this bug fix into a larger API redesign, since we kinda have overlapping responsibility in the config with repeatedSections and expandChorusDirective

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

PdfFormatter does not honor expandChorusDirective

2 participants