Skip to content

api: round-trip fingering and pluck technical marks#199

Merged
webern merged 1 commit into
mainfrom
issue-185
Jun 17, 2026
Merged

api: round-trip fingering and pluck technical marks#199
webern merged 1 commit into
mainfrom
issue-185

Conversation

@webern

@webern webern commented Jun 16, 2026

Copy link
Copy Markdown
Owner

Summary

Addresses audit section 1c. Fingering and pluck were commented out of `technicalMarkMap` because
they carry text payloads that a flat `MarkType` cannot hold. This reuses the existing
`MarkData` text-payload pattern (same as `fret`/`string`): the element text lives in
`MarkData::name`.

Adds `MarkType::fingering` and `MarkType::pluck`. Two optional `Bool` fields
`fingeringSubstitution` and `fingeringAlternate` are added to `MarkData` for the
`` substitution/alternate attributes, following the existing `hasMordent*`
optionality convention. Placement and position already round-trip via `MarkData::positionData`.
`isMarkTechnical` updated to include the new types.

Scoped out: `hammer-on`, `pull-off`, `bend`, `tap`. These require spanner start/stop state
or multi-element payloads and warrant a dedicated api type. Their reader cases are unchanged
(return false) -- no regression.

Testing

  • New `technical_fingering_pluck_roundtrip` test in `NoteDataTest.cpp`
  • `make test` passes (223 cases, 3941 assertions)
  • `make check` (fmt-check) passes
  • `make test-api-roundtrip` baseline unchanged

References

@github-actions

Copy link
Copy Markdown

gen-quality gen/

gen-quality: 84.5 / 100   (floor 84.5, +0.0)

  structure     86.5  x0.50   [fn 90.5 / file 82.6]
  cyclomatic    88.4  x0.25
  cognitive     76.6  x0.25

  409 functions across 31 files, 7702 lines (largest file 1044)
  max cc 56  max cognitive 44  max fn loc 152

Worst offenders (top 5 per axis; full lists in score.json):
  cyclomatic gen/xsd/analyze.py:311     report                             56
  cyclomatic gen/plates/build.py:956    _validate_config_against_ir        35
  cyclomatic gen/press/context.py:145   plate_context                      34
  cyclomatic gen/__main__.py:46         _ir                                23
  cyclomatic gen/tests/test_ir.py:102   _check_references                  20
  cognitive  gen/xsd/analyze.py:311     report                             44
  cognitive  gen/ir/resolve.py:119      flat_elements                      40
  cognitive  gen/tests/test_ir.py:102   _check_references                  38
  cognitive  gen/press/context.py:145   plate_context                      37
  cognitive  gen/xsd/analyze.py:207     _sccs                              37
  size       gen/xsd/analyze.py:311     report                             152
  size       gen/press/context.py:145   plate_context                      96
  size       gen/plates/build.py:533    _value_plate                       89
  size       gen/plates/build.py:956    _validate_config_against_ir        89
  size       gen/ir/resolve.py:119      flat_elements                      78

Commit f3a1b9a204301c25dfbc9fa432af2dbbf2f1489e.

@github-actions

Copy link
Copy Markdown

Coverage report

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

Metric Coverage Covered / Total
Lines 77.9% 28539 / 36619
Functions 74.4% 6360 / 8547
Branches 50.7% 22672 / 44725

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

Metric Coverage Covered / Total
Lines 68.9% 4771 / 6926
Functions 56.1% 1551 / 2763
Branches 40.4% 3888 / 9616

Core HTML report | API HTML report

Commit f3a1b9a204301c25dfbc9fa432af2dbbf2f1489e.

@webern webern changed the title Round-trip fingering and pluck technical marks (#185) api: support fingering and pluck technical marks Jun 17, 2026
@github-actions

Copy link
Copy Markdown

gen-quality gen/

(no report produced)

Commit b249738a354b9a41368494ba72092b594f6b65fd.

Summary
-------
Technical elements <fingering> and <pluck> were deliberately commented out
of technicalMarkMap because they carry text payloads a flat api::MarkType
could not hold, so they fell back to MarkType::unspecified and were lost on
both read and write.

Reuse the existing MarkData text-payload pattern (the same approach <fret>
and <string> already use): the element text (e.g. "1", "2-3" for fingering;
"p", "i", "m", "a" for pluck) is carried in MarkData::name. Add
api::MarkType::fingering and api::MarkType::pluck, and two optional Bool
fields on MarkData (fingeringSubstitution, fingeringAlternate) to carry the
<fingering> substitution/alternate attributes, following the existing
hasMordent* optionality convention. Placement and other position attributes
already round-trip via MarkData::positionData.

Wire both directions: technicalMarkMap rows, the reader
(TechnicalFunctions::parseTechicalMark) and the writer
(NotationsWriter::addTechnical), plus isMarkTechnical.

Scope
-----
Covers fingering and pluck with full read+write round-trip (the two most
common and most tractable of the section-1c marks). The remaining
payload-bearing technical marks -- hammer-on, pull-off, bend, tap -- are
NOT covered here: they need start/stop+number spanner state (hammer-on,
pull-off) or a multi-element bend-alter/pre-bend/release/with-bar payload
(bend) that does not fit the flat MarkData::name model and warrants a
dedicated api type in a follow-up. They continue to return false in the
reader (unchanged behavior, no regression). The section-1c tracker row is
marked done for the fingering/pluck scope.

Test plan
---------
- New TEST(technical_fingering_pluck_roundtrip, NoteData) in NoteDataTest.cpp:
  builds notes with fingering "1", fingering "2-3" (substitution=yes,
  alternate=no) and pluck "p", round-trips through XML, asserts markType,
  text, placement, and the substitution/alternate flags survive.
- make test: all 223 cases / 3941 assertions pass.
- make fmt + make check: clean.
- make test-api-roundtrip: 1 passed, 0 failed (pinned baseline unchanged).
@github-actions

Copy link
Copy Markdown

gen-quality gen/

(no report produced)

Commit 7bc9d3d0761095728c344b0a547b2f3bc6d6610d.

@webern webern changed the title api: support fingering and pluck technical marks feat: round-trip fingering and pluck technical marks Jun 17, 2026
@webern webern added feature new feature request non-breaking fixes or implementation that do not require breaking changes area/mx::api area/mx::impl ai Issues opened by, or through, a coding agent. labels Jun 17, 2026
@github-actions

Copy link
Copy Markdown

gen-quality gen/

gen-quality: 84.5 / 100   (floor 84.5, +0.0)

  structure     86.5  x0.50   [fn 90.5 / file 82.6]
  cyclomatic    88.4  x0.25
  cognitive     76.6  x0.25

  409 functions across 31 files, 7702 lines (largest file 1044)
  max cc 56  max cognitive 44  max fn loc 152

Worst offenders (top 5 per axis; full lists in score.json):
  cyclomatic gen/xsd/analyze.py:311     report                             56
  cyclomatic gen/plates/build.py:956    _validate_config_against_ir        35
  cyclomatic gen/press/context.py:145   plate_context                      34
  cyclomatic gen/__main__.py:46         _ir                                23
  cyclomatic gen/tests/test_ir.py:102   _check_references                  20
  cognitive  gen/xsd/analyze.py:311     report                             44
  cognitive  gen/ir/resolve.py:119      flat_elements                      40
  cognitive  gen/tests/test_ir.py:102   _check_references                  38
  cognitive  gen/press/context.py:145   plate_context                      37
  cognitive  gen/xsd/analyze.py:207     _sccs                              37
  size       gen/xsd/analyze.py:311     report                             152
  size       gen/press/context.py:145   plate_context                      96
  size       gen/plates/build.py:533    _value_plate                       89
  size       gen/plates/build.py:956    _validate_config_against_ir        89
  size       gen/ir/resolve.py:119      flat_elements                      78

Commit 54e7bee1d76e9935e350d0af9c5c84bed2a2f6ca.

@github-actions

Copy link
Copy Markdown

Coverage report

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

Metric Coverage Covered / Total
Lines 77.9% 28539 / 36620
Functions 74.4% 6360 / 8548
Branches 50.7% 22672 / 44725

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

Metric Coverage Covered / Total
Lines 70.6% 5034 / 7132
Functions 57.6% 1679 / 2914
Branches 42.0% 4167 / 9933

Core HTML report | API HTML report

Commit 54e7bee1d76e9935e350d0af9c5c84bed2a2f6ca.

@webern webern changed the title feat: round-trip fingering and pluck technical marks api: round-trip fingering and pluck technical marks Jun 17, 2026
@webern webern merged commit f95464e into main Jun 17, 2026
7 checks passed
@webern webern deleted the issue-185 branch June 17, 2026 07:14
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. area/mx::api area/mx::impl feature new feature request non-breaking fixes or implementation that do not require breaking changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

model technical marks with payloads (fingering, pluck, bend, ...) in mx::api

1 participant