Skip to content

feat: chord degree display options in mx::api - #376

Merged
webern merged 2 commits into
webern:mainfrom
rpatters1:chord-display-options
Jul 31, 2026
Merged

feat: chord degree display options in mx::api#376
webern merged 2 commits into
webern:mainfrom
rpatters1:chord-display-options

Conversation

@rpatters1

Copy link
Copy Markdown
Contributor

Human Summary

Add parenthesesDegrees and stackDegrees to ChordData. Also modified writer to write print-object for Degree. (It was already being read.)

Summary

Three MusicXML attributes that control how a chord symbol's degrees are displayed were unreachable through mx::api.

ChordData gains stackDegrees and parenthesesDegrees, both api::Bool defaulting to unspecified. They map to the <kind> attributes stack-degrees (degrees stacked vertically rather than left to right) and parentheses-degrees (all degrees wrapped in parentheses, e.g. C7(#9b13)). DirectionReader reads them off core::Kind; DirectionWriter emits them only when the field is set, so an author who never touches them gets the same XML as before. The core type already supported both. No behavior change for existing callers.

Separately, DirectionWriter was dropping Extension::printObject: each core::Degree was built with only degree-type, degree-value, and degree-alter, so the <degree> print-object attribute was never written. The read side already populated the field, so it round-tripped to nothing. MusicXML marks a degree print-object="no" when the <kind> text attribute already spells it out — Finale exports <kind text="7sus4">suspended-fourth</kind> followed by a hidden added seventh, and without the writer support that seventh prints twice.

data/synthetic/kind.3.0.xml is now registered with MxFileRepository so it can serve as a read fixture. No new corpus files, so no pinned-count or audit regeneration.

Testing

  • harmonyDegreePrintObjectRoundTrip fails before the writer fix (2 assertions), passes after
  • Six new cases in HarmonyExtrasApiTest.cpp: round-trip, negative (unspecified writes no attribute), and read-path coverage for both features
  • Read path pinned against real files: synthetic/kind.3.0.xml for the kind attributes, and the three hidden degrees in recsuite/BrookeWestSample.xml for print-object
  • All harmony tests pass (harmony*: 32 assertions in 9 test cases)
  • Full api suite passes (5242 assertions in 469 test cases)
  • make api-roundtrip clean (295 passed, 0 failed of 295 pinned)
  • make fmt-check clean on touched files

Discovery is unchanged. synthetic/kind.3.0.xml still fails the strict compare, now on bracket-degrees rather than stack-degrees; recsuite/BrookeWestSample.xml fails earlier in the document on a credit-words attribute count. Neither is baseline-eligible yet.

Expose the MusicXML kind stack-degrees and parentheses-degrees attributes,
which control how a chord symbol's degree alterations are laid out. Both are
api::Bool defaulting to unspecified, so the writer emits nothing unless the
field is set.

DirectionReader reads them off core::Kind; DirectionWriter writes them back.
Adds round-trip, negative, and file-based tests in HarmonyExtrasApiTest, and
registers data/synthetic/kind.3.0.xml with MxFileRepository.
DirectionWriter built each core::Degree with only degree-type, degree-value,
and degree-alter, so api::Extension::printObject was dropped on write. The read
side already populated it, meaning the field round-tripped to nothing.

MusicXML marks a degree print-object="no" when the kind text attribute already
spells it out; Finale exports <kind text="7sus4">suspended-fourth</kind> with a
hidden added seventh. Without this the seventh prints twice.

Covered by a round-trip test, a negative test, and a read of the three hidden
degrees in recsuite/BrookeWestSample.xml.
myNameSubdirectoryMap.emplace("segno.3.1.xml", "synthetic");
myNameSubdirectoryMap.emplace("coda.3.0.xml", "synthetic");
myNameSubdirectoryMap.emplace("coda.3.1.xml", "synthetic");
myNameSubdirectoryMap.emplace("kind.3.0.xml", "synthetic");

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Nice.

@webern
webern merged commit ba99d36 into webern:main Jul 31, 2026
7 checks passed
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