Skip to content

Song Map Feature {flow: ...} #2296

Description

@isaiahdahl

RFC: Song Map for ChordSheetJS

Summary

This RFC proposes a Song Map capability for ChordSheetJS.

A Song Map is an ordered list of section occurrences. It describes the order in which a musician performs a song. Each occurrence refers to reusable section content such as a verse, chorus, bridge, or pre-chorus.

Authors continue to write ordinary sectioned ChordPro. ChordSheetJS can generate an initial Song Map from the linear chart. A consumer can then activate the Song Map to control formatter output.

The canonical Song Map stores every occurrence explicitly:

V1 C1 V2 C1 C1 B1 C1

The canonical map does not store a compressed token such as C1x2. A formatter may present adjacent repeated occurrences once as Chorus (2x).

This RFC defines product behavior. It does not select system or program design.

Normative language

The terms must, must not, can, and may define requirement strength in this RFC.

Motivation

Authors need one path from ordinary charts to structured arrangements

ChordSheetJS already recognizes section boundaries, section labels, and chorus recalls. It does not expose one complete arrangement that controls formatter output.

Authors currently express performance order through copied content, recall directives, and written repeat instructions. Different consumers can interpret those patterns differently.

A generated Song Map lets an author begin with a normal linear chart. The author does not need to write a second arrangement format before seeing useful output.

Musicians need a reliable view of song order

A musician must understand the next section during rehearsal and performance. Repeated sections must appear at the correct point in the song.

A compact Song Map can communicate the complete order before the musician starts. A mapped chart can then present content in that same order.

Formatter consumers need consistent arrangement behavior

Formatter consumers need one selected arrangement to produce one observable section order. Consumers also need a source-order mode for editing, inspection, and compatibility output.

Goals

The first release has these goals:

  1. Generate an initial Song Map from recognized sections in linear ChordPro.
  2. Represent one performance occurrence with one map token.
  3. Infer compact section tokens such as V1, C1, and B1.
  4. Convert recognized repeat instructions into explicit occurrences.
  5. Let an active Song Map control mapped rendering.
  6. Preserve source-order rendering as an explicit mode.
  7. Support full and condensed repeat presentation.
  8. Return diagnostics for missing, invalid, and ambiguous input.
  9. Preserve current output for charts without an active Song Map.
  10. Provide an accessible visual or textual Song Map in the selected formatter scope.

Non-goals

The first release does not provide:

  • Audio playback or waveform synchronization
  • Bar, beat, or timestamp alignment
  • MIDI, scene, or lighting actions
  • Real-time leader and follower synchronization
  • A drag-and-drop arrangement editor
  • Setlist-item arrangement overrides
  • Multiple named arrangements
  • Conditional branches
  • D.S., D.C., or coda execution
  • Unbounded vamps
  • Automatic merging based on similar but different text
  • Automatic replacement of source ChordPro after generation

Terminology

Term Definition
Section A reusable unit of chart content, such as a verse or chorus.
Section type The semantic category of a section, such as verse, chorus, or bridge.
Section token A compact section identifier, such as V1 or C1.
Occurrence One appearance of a section in the performance order.
Song Map The ordered list of section occurrences.
Flow A ChordPro or application representation of the same ordered sequence concept.
Source order The order in which section content and recall instructions occur in the input chart.
Mapped rendering Formatter output that follows the active Song Map.
Source-order rendering Formatter output that follows the original source chart.
Full presentation Presentation that renders each occurrence in full.
Condensed presentation Presentation that can combine adjacent equal occurrences into one visible section with a repeat label.
Active map The Song Map selected to control mapped rendering.

Current behavior

ChordSheetJS currently provides these related behaviors:

  • ChordPro section directives assign semantic section types to parsed lines.
  • Section labels remain available to paragraph and formatter behavior.
  • {chorus} can recall the nearest preceding chorus when chorus expansion is enabled.
  • Measurement-based formatters can hide or reduce repeated section content.
  • Formatters use source paragraphs or chorus-expanded paragraphs as their content order.

These behaviors do not form one occurrence-aware arrangement. Repeat presentation can depend on formatter heuristics instead of explicit section identity.

Proposed product behavior

Authors start with ordinary linear ChordPro

An author can write a sectioned chart without a Song Map directive.

{start_of_verse: Verse 1}
[G]First verse
{end_of_verse}

{start_of_chorus: Chorus}
[C]Chorus lyrics
{end_of_chorus}

{start_of_verse: Verse 2}
[G]Second verse
{end_of_verse}

{chorus}

A consumer can request Song Map generation after parsing the chart.

Generation must return a proposed map and diagnostics. Generation must not replace or reorder source content.

Generation derives tokens from semantic sections

The generator uses recognized section types before it uses label text.

Section Generated token
First verse V1
Second verse V2
First chorus C1
First bridge B1
First pre-chorus PC1

A missing label does not prevent token generation when the section type is known.

The generator must preserve each original label. A generated token must not replace the display label in source content.

The Song Map stores explicit occurrences

One token represents one performance occurrence.

For the example above, the generated map is:

V1 C1 V2 C1

The final C1 is a separate occurrence of the same chorus section.

Each occurrence must remain distinguishable to a consumer. A player can highlight the first and second C1 separately.

Repeat instructions can create additional occurrences

The generator can recognize common finite repeat instructions.

Initial recognized forms include:

2x
x2
(2x)
Repeat 2x
Repeat 2 times

If Chorus (2x) identifies one chorus occurrence, generation can produce:

C1 C1

The generator must preserve the original instruction. The generated result must record that the additional occurrence came from repeat inference.

The generator must not convert these values into occurrences:

  • Zero
  • Negative values
  • Decimal values
  • Unbounded values such as repeat until cue

The generator returns a diagnostic for a malformed finite repeat instruction.

An active map controls mapped rendering

When mapped rendering is selected, formatter content follows the active Song Map.

Given:

V1 C1 V2 C1 B1 C1

mapped rendering presents sections in that order. The formatter must not fall back to source order without reporting that result.

Source-order rendering remains available. Source-order rendering does not apply the active map.

A chart without an active Song Map preserves current formatter behavior.

Repeat presentation does not change Song Map data

Full presentation renders all occurrences:

Verse 1
Chorus
Verse 2
Chorus
Bridge
Chorus
Chorus

Condensed presentation can combine adjacent equal occurrences:

Verse 1
Chorus
Verse 2
Chorus
Bridge
Chorus (2x)

The underlying Song Map remains:

V1 C1 V2 C1 B1 C1 C1

Non-adjacent equal occurrences must remain at their map positions.

A consumer must be able to identify every canonical occurrence even when presentation is condensed.

The visual Song Map communicates order without color

A visual Song Map displays section tokens, section labels, or both. The displayed order must match mapped rendering.

Color may communicate section type. Color must not be the only way to identify a section.

Interactive HTML output must expose the active occurrence to assistive technology. Interactive controls must have accessible labels. Keyboard control is required when the formatter provides direct navigation.

End-to-end examples

A linear chart generates an initial map

Input:

{start_of_verse: Verse 1}
[G]Verse one
{end_of_verse}

{start_of_chorus: Chorus}
[C]Chorus
{end_of_chorus}

{start_of_verse: Verse 2}
[G]Verse two
{end_of_verse}

{chorus}

Generated Song Map:

V1 C1 V2 C1

Full mapped presentation:

Verse 1
Chorus
Verse 2
Chorus

A repeat instruction expands into explicit occurrences

Source instruction:

Chorus (2x)

Generated Song Map fragment:

C1 C1

Full presentation:

Chorus
Chorus

Condensed presentation:

Chorus (2x)

A changed map changes mapped output only

Source order:

V1 C1 V2 C1 B1 C1

Active Song Map:

C1 V1 C1 B1 C1

Mapped rendering follows the active Song Map. Source-order rendering retains the original source order.

Product states

State Required behavior
No Song Map Preserve current source rendering. Generation is available.
Generated map Return the proposed map and diagnostics without replacing source content.
Active map Use the map for mapped rendering. Keep source-order rendering available.
Empty map Render no mapped sections and return a diagnostic. Source-order rendering remains available.
Invalid reference Return a diagnostic. Do not silently choose another section.
Ambiguous inference Keep the source text and return candidate information when available.

Diagnostics and failure behavior

Missing labels

A known section type can receive an ordinal token without a label. The generated display fallback uses the section type and ordinal.

Duplicate labels

A duplicate label does not establish section identity by itself. The generator must report ambiguity when available evidence cannot select one section.

Unknown section types

The generator preserves an unknown section type. It returns a deterministic fallback token and an inference diagnostic.

Conflicting ordinals

An explicit identity takes precedence over an ordinal inferred from label text. The generator reports the conflict.

Ambiguous repeat placement

A repeat instruction must identify one occurrence. The generator does not create additional occurrences when repeat placement is ambiguous.

Missing recall targets

A recall without a resolvable prior section returns a diagnostic. ChordSheetJS must not select an unrelated section.

Empty maps

An explicit empty map represents no mapped sections. Mapped rendering returns an empty result and a diagnostic. Source-order rendering remains available.

Conditional source sections

Formatter configuration can exclude source sections. Mapped rendering must not redirect an excluded occurrence to another section.

The consumer receives an explicit omission result or diagnostic.

Acceptance criteria

The first release must satisfy these observable checks:

  1. A supported linear fixture generates the expected tokens in source order.
  2. A recognized 2x instruction creates two explicit occurrences.
  3. A mapped-rendering fixture follows the active Song Map order.
  4. A source-order fixture ignores the active Song Map.
  5. Full presentation renders each occurrence.
  6. Condensed presentation can render adjacent equal occurrences once with (2x).
  7. Non-adjacent equal occurrences remain separate in presentation order.
  8. A missing reference produces a diagnostic.
  9. An ambiguous reference does not silently resolve.
  10. A chart without an active map preserves current formatter output.
  11. An accessible visual map remains understandable without color.
  12. An interactive visual map exposes active state and accessible control names.

Compatibility

Existing charts

Existing charts without an active Song Map retain current behavior.

Generation is opt-in. Generation does not modify source content.

Existing formatter configuration

Source-order rendering remains available for compatibility and inspection.

The project must cover current formatter fixtures before it changes any default rendering mode.

ChordPro and OnSong

OnSong implements {flow: ...} as an application extension. The current ChordPro standard does not define general Flow syntax.

The ChordPro roadmap lists Flow as a planned ChordPro 7 topic. The roadmap does not publish final syntax.

ChordSheetJS must identify application-specific Flow behavior accurately. It must not claim that OnSong Flow is current standard ChordPro behavior.

Unsupported directives must remain available for round-trip output.

Accessibility

A textual map is the required fallback for every visual map.

A visual formatter must not communicate section identity through color alone.

An interactive map must provide:

  • A programmatic name for each occurrence
  • A programmatic active state
  • Keyboard access to each direct navigation action
  • Reading order that matches performance order
  • Repeat information in text

Security and privacy

Song Map generation processes local song content. It introduces no remote permission or account model.

ChordSheetJS does not save, publish, or synchronize maps. A host application owns persistence, authorization, and collaboration behavior.

Diagnostics must not execute instruction text as code.

Rollout

The first release remains opt-in for existing consumers.

The rollout has these product stages:

  1. Expose Song Map generation and diagnostics.
  2. Enable mapped rendering through explicit formatter configuration.
  3. Enable full and condensed repeat presentation.
  4. Add visual Song Map presentation to the selected formatter scope.
  5. Evaluate a default change only after compatibility fixtures pass.

The project must not change current no-map output during the initial rollout.

Alternatives considered

Keep source order as the only arrangement

This option preserves current behavior but does not provide one reusable performance order. Consumers would continue to interpret recalls and repeat instructions independently.

Disposition: Rejected because it does not solve the user problem.

Make Song Map a visualization only

This option derives a compact summary but leaves formatter content order unchanged.

Disposition: Rejected because the displayed map and rendered chart could disagree.

Require map-first authoring

This option requires authors to create Flow before rendering a useful chart.

Disposition: Rejected because authors must be able to start with ordinary linear ChordPro.

Store compressed repeat tokens

This option stores C1x2 instead of C1 C1.

Disposition: Rejected because one canonical token must represent one occurrence.

Let each formatter infer repeated sections

This option keeps arrangement behavior inside formatter heuristics.

Disposition: Rejected because formatters could produce different occurrence order or identity.

Resolved product decisions

  1. Authors can start with ordinary linear ChordPro.
  2. ChordSheetJS can generate an initial Song Map from the linear chart.
  3. Generation does not replace source content.
  4. An active Song Map controls mapped rendering.
  5. Source-order rendering remains available.
  6. One Song Map token represents one occurrence.
  7. Canonical repeats use explicit occurrences such as C1 C1.
  8. Presentation may condense adjacent repeated occurrences to one section with (2x).
  9. Presentation condensation does not modify canonical Song Map data.
  10. The visual product feature is called Song Map.
  11. Flow describes the underlying ordered sequence in ChordPro and compatible applications.

Open product questions

P1. How does generation identify repeated section content?

A linear chart can contain a recall, an explicit repeat instruction, or a copied section body. The generator needs a user-visible rule for deciding whether a later block is another occurrence of C1 or a new section such as C2.

Option A — Explicit evidence only

Only recalls, repeat instructions, and explicit identities reuse a section token. A copied section block becomes a new section definition.

  • Advantage: Generation does not merge independent sections silently.
  • Cost: Fully copied repeated choruses can generate C2 instead of another C1.

Option B — Exact semantic equality

Blocks with the same section type, normalized label, and exact content reuse one section token.

  • Advantage: Fully written linear charts can generate repeated occurrences automatically.
  • Cost: Formatting or instruction differences can prevent reuse.

Option C — Label-based identity

Blocks with the same section type and normalized label reuse one section token.

  • Advantage: Authors can repeat content without exact text equality.
  • Cost: Generic labels such as Verse can merge different content.

Recommendation: Select Option B, with a diagnostic when labels conflict. Exact equality supports linear-first generation without approximate text matching.

P2. Which formatters honor Song Map order in the first release?

Option A — Layout-engine formatters first

PDF and measured HTML honor mapped order. Other formatters retain source order during the first release.

  • Advantage: The first release targets page layout and visual performance output.
  • Cost: Different display formatters can produce different section order.

Option B — All display formatters

PDF, measured HTML, HTML div, HTML table, text, and chords-over-words output honor mapped order when selected.

  • Advantage: One selected map produces consistent display output.
  • Cost: The compatibility and acceptance surface is larger.

Recommendation: Select Option B.

P3. How does a generated Song Map become durable input?

Option A — OnSong-compatible Flow

Store {flow: V1 C1 V2 C1} in ChordPro.

  • Advantage: Existing OnSong compatibility.
  • Cost: The syntax is not current standard ChordPro and can conflict with future ChordPro 7 syntax.

Option B — Namespaced ChordSheetJS Flow

Store the map in a ChordSheetJS extension directive.

  • Advantage: Clear ownership and lower future collision risk.
  • Cost: Other applications do not understand the map.

Option C — Host-managed data

Keep the durable map outside the source chart.

  • Advantage: Rich map data does not depend on ChordPro syntax.
  • Cost: The chart does not carry its arrangement when copied alone.

Recommendation: Support OnSong Flow import and export as a named compatibility mode. Keep the full-fidelity map host-managed until ChordPro 7 syntax is stable.

P4. What is the default repeat presentation?

Option A — Full

Render every occurrence in full.

  • Advantage: The musician can read continuously from top to bottom.
  • Cost: Output can become longer.

Option B — Condense adjacent repeats

Render adjacent equal occurrences once with (2x).

  • Advantage: Output is compact.
  • Cost: The musician must perform the visible section more than once.

Option C — Preserve each formatter default

Mapped rendering follows the current repeat presentation default for each formatter.

  • Advantage: Lower compatibility impact.
  • Cost: The same map can have different repeat presentation across formatters.

Recommendation: Select Option A for mapped rendering. Consumers can request condensed presentation.

P5. Where does the visual Song Map appear?

Option A — Host-controlled placement

The formatter returns map content and lets the host select placement.

Option B — Formatter defaults

Each formatter selects a default placement, such as a PDF footer or HTML header.

Option C — One cross-formatter placement

All visual formatters place the map before chart content.

Recommendation: Select Option A. Hosts have different stage, print, and player constraints.

References

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions