Skip to content

feat: model damp, damp-all, eyeglasses, string-mute, and staff-divide directions - #358

Merged
webern merged 1 commit into
mainfrom
claude/direction-types-ordering-9l60vv
Jul 19, 2026
Merged

feat: model damp, damp-all, eyeglasses, string-mute, and staff-divide directions#358
webern merged 1 commit into
mainfrom
claude/direction-types-ordering-9l60vv

Conversation

@webern

@webern webern commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Human Summary

Adds missing direction types.

Summary

First slice of #324, working through the unmodeled direction-type stubs from easiest to hardest. This models the five attribute-only direction types: damp, damp-all, eyeglasses, string-mute, and staff-divide (the latter was silently skipped in the dispatch as "new in MusicXML 4.0" — it is a 3.1 feature — and was not part of the stub block).

  • New api types DampData/DampAllData, EyeglassesData, StringMuteData (+ StringMuteType), StaffDivideData (+ StaffDivideType), following the SegnoData shape; absent-able attributes use std::optional per the current convention.
  • DirectionData gains the five vectors, DirectionComponentKind gains the five kinds, and the reader/writer wire them through DirectionReader/DirectionWriter, including orderedComponents fidelity.
  • While here: DirectionData's equality block was missing rehearsals (a rehearsal-only difference compared equal, silently excluding rehearsals from round-trip equality checks) and isDirectionDataEmpty was missing rehearsals too; both fixed, and the new vectors are included in both.

Planned ordering for the remaining #324 work, easiest to hardest: principal-voice, other-direction, image, accordion-registration (next PR); harp-pedals, scordatura; then the percussion family; metronome extras and the pedal-type gaps last.

Testing

  • New DirectionMarksRoundTrip tests: one per element plus a formatting/id round-trip (18 assertions in 6 test cases)
  • Full api/impl suite passes (5001 assertions in 433 test cases)
  • Discovery: 236 PASS, zero regressions; baseline 227 -> 236 (all nine synthetic fixtures for these five elements); regression mode 236/236

References

… directions

The five attribute-only direction-type stubs from #324 are now modeled in
mx::api: DampData, DampAllData, EyeglassesData, StringMuteData, and
StaffDivideData, wired through DirectionReader and DirectionWriter with
orderedComponents fidelity. Also fixes DirectionData's equality block and
isDirectionDataEmpty, which were both missing rehearsals.

Round-trip baseline 227 -> 236.
@webern webern added feature new feature request non-breaking fixes or implementation that do not require breaking changes api Affects the mx::api layer impl Affects the mx::impl layer ai Issues opened by, or through, a coding agent. labels Jul 17, 2026 — with Claude
@webern

webern commented Jul 17, 2026

Copy link
Copy Markdown
Owner Author

/coverage

@github-actions

Copy link
Copy Markdown

Coverage report

Core-dev coverage src/private/mx/core/

Metric Coverage Covered / Total
Lines 77.8% 28514 / 36652
Functions 74.2% 6352 / 8558
Branches 50.7% 22680 / 44751

API coverage src/private/mx/{api,impl,utility}/

Metric Coverage Covered / Total
Lines 85.0% 7414 / 8722
Functions 76.2% 2726 / 3578
Branches 52.6% 6491 / 12336

Core HTML report | API HTML report

Commit 75101713a04faf8f657b621e27a11f47a69f4f49.

@webern
webern merged commit 328f601 into main Jul 19, 2026
7 checks passed
@webern
webern deleted the claude/direction-types-ordering-9l60vv branch July 19, 2026 05:17
webern added a commit that referenced this pull request Jul 19, 2026
…gistration directions (#359)

## Human Summary

More direction types that were todos in the code.

## Summary

Second slice of #324 (stacked on #358), continuing through the unmodeled
direction-type stubs in order of implementation simplicity. This models
the four simple-payload direction types: principal-voice,
other-direction, image, and accordion-registration.

- New api types `PrincipalVoiceData` (+
`PrincipalVoiceType`/`PrincipalVoiceSymbol`), `OtherDirectionData`,
`ImageData`, and `AccordionRegistrationData`, wired through
`DirectionData`, `DirectionReader`, and `DirectionWriter` with
`orderedComponents` fidelity.
- `<image>`'s valign is the valign-image type (top/middle/bottom, no
baseline), which the generic SFINAE position helpers cannot convert; the
reader and writer handle it on the element directly, and the
inexpressible baseline value is not written.
- An accordion-registration with nothing engaged is legal (it draws the
empty diagram) and round-trips as such.

Remaining #324 order: harp-pedals and scordatura next; then the
percussion family; metronome extras and the pedal-type gaps last. Note
`lysuite/ly31a_Directions.xml` also needs `<pedal type="change"/>`, so
it stays blocked until the pedal-type work.

## Testing

- [x] New `DirectionMarksRoundTrip` tests for the four elements, incl.
image geometry/valign and the empty accordion registration (49
assertions in 11 test cases across the file)
- [x] Full api/impl suite passes (5032 assertions in 438 test cases)
- [x] Discovery: 245 PASS, zero regressions; baseline 236 -> 245,
including the real-world lysuite/ly75a_AccordionRegistrations.xml;
regression mode 245/245

## References

- Progresses #324
- Stacked on #358; part of #208

---
_Generated by [Claude
Code](https://claude.ai/code/session_01VUEm27jNmUo4pTWovA4Xua)_
webern added a commit that referenced this pull request Jul 19, 2026
## Human Summary

Changes the way pedals are modeled into two different things. Pedal
marks, which are the old fashioned Ped and * marks, and a separate type
for more modern lines.

## Summary

`DirectionReader::parsePedal` handled only `PedalType` start/stop and
silently dropped
`sostenuto`, `change`, `continue`, `discontinue`, and `resume`, even
though `core::PedalType`
carries all seven tags. This was the last unmodeled item in #324.

The shape decision (called for in #324) was to store the pedal type as
one fact in one field
rather than scatter it across start/stop/other vectors. This replaces
the `pedalStarts` /
`pedalStops` spanner vectors on `DirectionData` with a single
`std::vector<PedalData> pedals`,
where each `PedalData` carries a `PedalKind` enum covering every
pedal-line type. Each pedal event
stands on its own and is placed at its own tick, so the model has no
neighbor-dependent meaning.

- New `PedalData.h`: the `PedalKind` enum (`start`, `stop`, `sostenuto`,
`change`, `continueLine`,
  `discontinue`, `resume`) and the `PedalData` struct.
- Reader: line pedals (`line="yes"`, plus the inherently line-formatting
types
`sostenuto`/`change`/`continue`/`discontinue`/`resume`) go to `pedals`;
sign start/stop still
  route through `MarkData` as `MarkType::pedal` / `damp`, unchanged.
- Writer: a single `emitPedal` maps `PedalKind` back to
`core::PedalType`, emits `line="yes"`, and
  emits nothing for an unspecified kind.

Only two corpus files use these types (`lysuite/ly31a_Directions.xml`,
`lysuite/ly33a_Spanners.xml`)
and both fail first on unrelated features, so this does not flip any
file to PASS. It is validated
by a focused unit test that round-trips each pedal type through the api.

This is a breaking change: it reshapes `DirectionData`'s pedal fields.

## Testing

- [x] New `PedalAllKinds` round-trips all seven pedal types through the
api; `PedalPlacement` covers
  placement (`*Pedal*`: 44 assertions in 5 test cases)
- [x] Full unit suite passes (5130 assertions in 451 test cases)
- [x] api round-trip regression unchanged (284 passed, 0 failed of 284
pinned)

## References

- Closes #324 (the `symbol` item from that worklist is tracked
separately by #294 and is not
  included here)
- Follows the merged direction-type stack #358#363
- Part of #208
- Spanner-numbering context: #320, #351
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai Issues opened by, or through, a coding agent. api Affects the mx::api layer feature new feature request impl Affects the mx::impl layer non-breaking fixes or implementation that do not require breaking changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant