Repository navigation
Fix #223 — accept a K: that names a clef but no key, and draw clef changes - #227
Merged
Merged
Conversation
…anges K:bass, K:clef=bass and [K:clef=bass] were rejected as malformed and the clef was dropped. A K: with no tonic is now read as options only (§3.1.14, §4.6), and KeySignature records whether a key and a clef were stated (statesKey, statesClef). The semantic pass resolves what was left unsaid against what is in force: in the header an empty key is K:none; part way through a voice the key carries on, and a K: with no clef keeps the clef (K:G after K:bass stays bass, as in abcm2ps). An unreadable K: still warns and now changes nothing. A clef change part way through a voice is a new Event.clefChange where the field was written; Measure.key is set only by a K: that names a key. The renderer tracks the clef in force per column and per event, as abcm2ps -g 8.14 draws it: a change against a bar line is a small clef before that bar (the courtesy clef at the end of a line, with the new clef full size at the head of the next), a change mid-bar is a small clef between the notes, and a clef change alone draws no key signature. Notes, ledger lines and ledger space follow the clef in force. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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 #223
Problem
K:bass,K:clef=bassand[K:clef=bass]were rejected ("Key must start with A–G…") and the clef was dropped. EvenK:C clef=basspart way through a tune never reached the page, because the renderer drew one clef per voice for the whole tune.Parsing and semantics
KeyFieldParser: a payload with no tonic is read as options only (§3.1.14, §4.6). An emptyK:is accepted too. A payload that is neither a key nor options still warns, and now changes nothing.KeySignature.statesKey/statesClefrecord what the field stated. The semantic pass resolves both, so the domain model only carries decided keys:K:none;K:with no clef keeps the clef in force (K:GafterK:bassstays bass, as in abcm2ps).Event.clefChange(ClefSpec), at the point the field was written.Measure.keyis set only by aK:that names a key.Rendering (checked against
abcm2ps -g8.14)ResolvedEvent.clef). The emitter's per-system clef is gone.Tests
KeyWithoutTonicTests(parser/semantic, 15) andMidTuneClefChangeTests(renderer, 6).🤖 Generated with Claude Code