Skip to content

feat: support elisions in lyrics - #427

Merged
webern merged 1 commit into
webern:mainfrom
rpatters1:lyric-elisions
Aug 24, 2026
Merged

feat: support elisions in lyrics#427
webern merged 1 commit into
webern:mainfrom
rpatters1:lyric-elisions

Conversation

@rpatters1

Copy link
Copy Markdown
Contributor

Human Summary

Adds support for elisions in lyrics.

Summary

A <lyric> occasionally splits one syllable's display text into more than one <text> run joined by <elision> -- for example when the source embeds a non-breaking space or an undertie between two words that are meant to be sung as one syllable. mx::api had nowhere to keep the extra runs: the reader flattened them into a single string (substituting an undertie glyph for empty elisions), and the writer never emitted <elision> at all, so any file using it lost that structure on round trip.

LyricData gains continuations, a std::vector<LyricTextSegment> holding the runs after the first. Each LyricTextSegment carries its own syllabic, text, and the <elision> that joins it to the run before -- elisionText and elisionSmufl, both optional and independent of each other, since MusicXML only consults smufl when the text content is empty but does not forbid a source from setting both. elisionSmufl is a plain glyph-name string rather than a closed enum: the schema only requires a lyrics-prefixed name (lyrics\c+), not one of the three elision-specific glyphs.

Non-breaking: two new fields on LyricTextSegment, one new vector field on LyricData, all empty/absent by default.

Testing

  • New elidedSyllablesRoundTripThroughApi test covers a mix of text-only, smufl-only, both-at-once, neither, and a non-elision lyrics* glyph name, verifying each round-trips independently
  • make api-test (6357 assertions in 580 test cases)
  • Confirmed against the corpus: lysuite/ly61j_Lyrics_Elisions.xml now passes api-roundtrip (previously failed with a flattened-text mismatch)

🤖 Generated with Claude Code

## Human Summary

Adds support for elisions in lyrics.

## Summary

A `<lyric>` occasionally splits one syllable's display text into more
than one `<text>` run joined by `<elision>` -- for example when the
source embeds a non-breaking space or an undertie between two words
that are meant to be sung as one syllable. `mx::api` had nowhere to
keep the extra runs: the reader flattened them into a single string
(substituting an undertie glyph for empty elisions), and the writer
never emitted `<elision>` at all, so any file using it lost that
structure on round trip.

`LyricData` gains `continuations`, a `std::vector<LyricTextSegment>`
holding the runs after the first. Each `LyricTextSegment` carries its
own `syllabic`, `text`, and the `<elision>` that joins it to the run
before -- `elisionText` and `elisionSmufl`, both optional and
independent of each other, since MusicXML only consults `smufl` when
the text content is empty but does not forbid a source from setting
both. `elisionSmufl` is a plain glyph-name string rather than a closed
enum: the schema only requires a `lyrics`-prefixed name
(`lyrics\c+`), not one of the three elision-specific glyphs.

Non-breaking: two new fields on `LyricTextSegment`, one new vector
field on `LyricData`, all empty/absent by default.

## Round-trip corpus

Adds 2 files to `roundtrip-baseline.txt` (402 -> 404):
`lysuite/ly61j_Lyrics_Elisions.xml` and `synthetic/lyric.3.0.xml`. Both
previously failed with a flattened-text mismatch (e.g. `d‿e` in place
of the elided `d` / `e` runs).

## Testing

- [x] New `elidedSyllablesRoundTripThroughApi` test covers a mix of
text-only, smufl-only, both-at-once, neither, and a non-elision
`lyrics*` glyph name, verifying each round-trips independently
- [x] `make api-test` (6357 assertions in 580 test cases)
- [x] `make api-roundtrip` (404 passed, 0 failed of 404 pinned)
- [x] `make api-roundtrip-discover` reports exactly the 2 new passes
and no regressions

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@webern
webern merged commit e8c75f3 into webern:main Aug 24, 2026
8 checks passed
@rpatters1
rpatters1 deleted the lyric-elisions branch August 24, 2026 11:40
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.

2 participants