Repository navigation
Fix #218 — one stem direction per beam group, every stem placed for it - #220
Merged
Merged
Conversation
Each beamed note used to be placed — stem x, and the stem's base on the notehead — for the direction it would have taken alone, and then drawn the way the group's first note went. In `Gd` the d was placed stem-down at its notehead's left edge and drawn up to the beam. - SVGEmitter decides each group's direction before drawing any of it, as abcm2ps does: down where the highest note is farther above the middle line than the lowest is below, up in the opposite case, and a group as far above as below follows the part's previous stem (up if none). - That previous stem is threaded across bars, systems and pages alongside the pending ties and slurs. - A voice with a direction of its own (stem=, pipeformat, a shared staff's opposition) is left as it was. - The jig and Canzonetta snapshots are re-recorded: both had a group with stems on the wrong side of their noteheads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix #218
Summary
A beam group now has one stem direction, and every stem in it is placed for that direction: on the notehead's right for up, its left for down. Before, each beamed note was placed for the direction it would have taken alone (stem x, and the stem's base from the
stemUpSE/stemDownNWanchor), then drawn the way the group's first note went. InGdthedgot an upward stem on its notehead's left edge.The direction follows abcm2ps 8.14 (checked against
abcm2ps -g):GB Ac→ up,ce Ac→ down); up if there is none.A voice with a direction of its own (
V:stem=,%%ceolkit:pipeformat, a shared staff's opposition) is unchanged.How
SVGEmitter.beamGroupStemDirections(in:staffIndex:lastStemUp:)runs before a measure's events are drawn and returns a direction per beamed event.emitEventtakes it asstemOverride.lastStemUp: [PartKey: Bool]) is threaded through pages, systems and measures alongsidependingTies/pendingSlurs, so the tie-break works across bar lines and system breaks.Tests
BeamGroupStemTests:Gdfstems down, every stem on itsstemDownNWanchor.GB Ac | ce Ac | ce Gd | GA Gd | GcBd | dGBc |match abcm2ps, each stem on its anchor.stem=downstill wins.IntegrationTestsjig (both modes) and Canzonetta. Each had a group drawn up with some stems at down-stem x positions. They now draw one consistent direction (the jig'sGABcdestems down, as abcm2ps does).Note
Independent of #217 and mergeable in either order. Together they render "Monsieur de la Miranda" (
B2A G2din 6/8) correctly. Until #217 lands, the still-beamedG2dcan tip the tie-break for the group after it.🤖 Generated with Claude Code