# ScoreScript syntax wiki Reference for writing, reading, and embedding ScoreScript 0.3. Each page gives the syntax, its meaning, and examples. Read any section independently; typing the examples is optional. The notation beside each example is its generated output, not an exercise to solve. ## Core syntax 1. [File syntax](first-score.md): a complete file and its components. 2. [Notes and pitch](pitch.md): octaves, accidentals, chords, and solfège. 3. [Rhythm and silence](rhythm.md): note values, dots, tuplets, grace notes, and rests. 4. [Parts, voices, and measures](structure.md): organize a solo or an ensemble. ## Musical detail - [Articulations, dynamics, and text](marks.md) - [Slurs, ties, and lines](connectors.md) - [Meter, key, tempo, and clef](context.md) - [Repeats, endings, and navigation](repeats.md) - [Lyrics and chord symbols](lyrics.md) - [Chord spellings and implementation status](chords.md) - [Percussion and sticking](percussion.md) ## Larger works - [Page and system layout](layout.md) - [Named exercises, shared passages, and transposition](reuse.md) - [Consolidation and normalization](normalization.md) - [Source arrangements and output views](representations.md) - [Movements, exercises, and books](collections.md) - [Checking, formatting, and fixing mistakes](checking.md) ## Installation and integration - [Install and use in other tools](integration.md): CLI, Node, editors, and agents. - [Embed on a website](embedding.md): static notation or a browser engine. - [Self-host this wiki](self-hosting.md): build and publish the documentation. ## Reading the examples An example beginning with `scorescript 0.3` explicitly declares its version and score context. Bare musical rows are also valid ScoreScript source: they can compile on their own with default context, or go inside a musical body. Header settings and structural blocks belong in their stated scope; do not paste every source form inside a part. Unless specified, bare music uses 4/4, quarter-note durations, absolute pitch spelling, and an initial unnumbered pitch in octave 4. Set the instrument and tempo explicitly when they matter. Non-ScoreScript code blocks are host code, commands, or labeled syntax excerpts; they are not standalone score files. Examples use the current label-before-brace arrangements. Older accepted spellings appear only in compatibility notes. Acceptance by the parser does not make a spelling the recommended form for new source. Pitch examples anchor the opening register, then use relative contour and apostrophe or comma octave shifts. Repeating absolute octave digits at every bar is not the recommended style. See [notes and pitch](pitch.md). The reference describes the current native engine. Provisional features and unsupported notation are identified where you encounter them. A successful syntax check does not by itself prove every mark will print or play; inspect the rendered result as well. --- # File syntax A complete file contains a version header, a score, optional settings, and music. This example is two bars for flute: four quarter notes, then a half note and a half rest. ```scorescript scorescript 0.3 score "First melody" { composer "A. Writer" arranger "A. Arranger" meter 4/4 key C tempo 96 parts { flute } flute { m1-2 { 4C5 D E F | 2G 2r } } } ``` ## File components `scorescript 0.3` identifies the language version. `score "First melody"` names the work; its braces contain the settings and music. `composer` and `arranger` are optional printed credits. Quote names containing spaces. `meter 4/4` gives each measure four quarter-note beats. `key C` sets the key signature. `tempo 96` sets a quarter-note metronome speed of 96. `parts { flute }` declares the instrument. `flute { ... }` contains its music; `m1-2 { ... }` addresses measures 1–2, and `|` separates the two bars. Read `4C5` as three pieces: `4` is a quarter note, `C` is the pitch, and `5` is the octave. `D E F` retain the quarter-note duration. They choose nearby pitches in the same melodic line. `2G` is a half note; `2r` is a half rest. The opening octave anchors the phrase; later notes follow relative contour. ## Marks and bare music Parenthesized marks attach to a note. A musical fragment can omit the file wrapper when no instrument or non-default setting is needed: ```scorescript 4C5(p) D E F | 2G(mf) 2r ``` `(p)` is piano and `(mf)` is mezzo-forte. The barline separates two measures. This shorter example is a fragment with the default 4/4 meter. ## Comments Comments start with `//` and continue to the end of that physical line. They explain the source without adding music or printed performance text. Use a [quoted musical text mark](marks.md) when the player should see words. ```scorescript // This comment is not printed on the staff. 4C5 D E F ``` ## File operations To use the complete example, save it as `first-melody.scorescript` and open it in a ScoreScript editor, or use the [CLI](integration.md): ```text scorescript check first-melody.scorescript scorescript format first-melody.scorescript --write scorescript pdf first-melody.scorescript -o first-melody.pdf ``` Formatting may replace explicit measure lines with compact measure ranges. See [parts and measures](structure.md), [pitch](pitch.md), and [rhythm](rhythm.md) for the individual rules. Copying or downloading source is optional; the example and its notation describe the result directly. --- # Notes and pitch ## Pitch letters and accidentals Use `A B C D E F G`. Place an accidental immediately after the letter and an optional octave after that: `Eb4`, `F#5`, `Bbb3`, `G##4`, `Fn4`. The spellings `b`, `#`, `bb`, `##`, and `n` mean flat, sharp, double flat, double sharp, and natural. Case does not select the octave. Case does distinguish tokens: `Eb` is E-flat; `eB` is an eighth-note B. `eb` and `EB` are not equivalent spellings. Attach a letter duration to its pitch (`qC5`), without an intervening space (`q C5` is invalid). ```scorescript 4C4 C# D Eb | E F F# G ``` Microtonal alterations use `+q`, `-q`, `+3q`, and `-3q` for quarter-tone and three-quarter-tone raises or lowers. Their notation and playback depend on the output's capabilities; ordinary MIDI pitch alone cannot represent a quarter tone exactly. ## How an omitted octave is read `C4` states an absolute octave. With no digit, choose the octave nearest the previous pitch in that voice. A voice's first unnumbered note starts in the middle-C octave. A rest does not reset the reference. The reference can cross barlines and source lines; a line break alone is not an octave reset. An apostrophe raises the nearest choice one octave; a comma lowers it one octave. These are relative to the nearest choice, not always to octave 4. Prefer relative contour after the opening anchor: bare pitches for the nearest reading, an apostrophe (`'`) to shift that choice up an octave, and a comma (`,`) to shift it down. Do not restate the octave at each barline. Absolute digits remain available when deliberately specifying an absolute register; they are not the preferred way to spell ordinary melodic leaps. ```scorescript 4F4 G A F | G A G A | C A' G F ``` The opening F4 anchors the passage. The next bar continues with bare G. In the last bar, C is C5; the nearest A is A4, so `A'` selects A5. The following G and F continue in octave 5. This is the preferred spelling of the contour, rather than repeating `G4` and replacing the shift with `A5`. ```scorescript 4C4 G C' G, | C' B A G ``` “Nearest” normally uses diatonic letter distance; a sounding tritone tie chooses upward. Thus `G4 D` reaches D4, `C5 G` reaches G4, and `B4 F` reaches F5. An omitted octave does not necessarily mean “stay in the same numbered octave.” The formatter writes an explicit octave on the first sounding note of each authored section and voice, not every bar or physical line. Later bars can continue by relative contour. It cannot infer what register you intended after an incorrect edit; check the notes before accepting a format operation. ## Chords Put simultaneous pitches in square brackets. Duration belongs before the whole chord. Member order matters: each omitted octave is read relative to the previous member, and the next node follows the first written member. ```scorescript 2[C4 E G] 2[F A C] | 1[C E G] ``` Do not sort the members merely to tidy the text. For an octave below inside a chord, use an explicit digit: a comma inside the brackets is a member separator, not the octave-down mark. Put marks outside the chord, such as `4[C4 E G](p)`. See [ties](connectors.md) for tying individual members. `[A]` is one pitch; `[AM]` generates an A-major triad. A boxed rehearsal landmark defaults to `RH {5, 9, 13}` (boxed actual measure numbers), or inline `[[5]]` at measure 5, so it cannot swallow a chord. For `[CMM7]`, `[CMm7]`, Roman numerals, extensions, and inversions, see [chord formulas](chords.md). ## Key-aware spelling The default `spell absolute` reads a bare `F` as F-natural even in a sharp key. With `spell key`, a bare letter takes its alteration from the signature. An explicit accidental still states the written alteration; `n` cancels it. An explicit accidental applies to its own source note, not every later same-letter note in the bar. `4C#5 C C C` sounds C-sharp followed by three C-naturals. With `key G` and `spell key`, `4F5 Fn F F` sounds F-sharp, F-natural, F-sharp, F-sharp. Do not copy the printed score's within-bar accidental-carry convention into source spelling. ```scorescript scorescript 0.3 score "Signature spelling" { key G spell key parts { flute } flute { m1 { 4F5 Fn F# G } } } ``` Here the first F is sharp, the second natural, and the third explicitly sharp. An inline `[spell key]` changes the mode at a musical point. ## Solfège Use `do re mi fa sol la ti`; `so` is another spelling of `sol`. Movable do is the default solfège reading. In D major, `do re mi` sounds D, E, F-sharp. `solfege fixed` selects fixed do. Chromatic syllables include `di ri fi si li` and `ra me se le te`. In movable do, `si` is raised sol; in fixed do it is the seventh degree, equivalent to `ti` (B). Movable do in a minor key uses the relative-major signature: with `key Cm`, `do` is E-flat, not C. ```scorescript scorescript 0.3 score "Movable do" { key D parts { flute } flute { m1-2 { 4do re mi fa | so la ti do } } } ``` The quarter duration continues through the barline: do not repeat `4` before `so` merely because a new measure begins. This is the same duration inheritance used with letter pitches; solfège is not a separate rhythm grammar. Related: [key signatures](context.md), [transposition](reuse.md). --- # Rhythm and silence ## Duration comes first | Value | Meaning | Accepted letter | | --- | --- | --- | | `1` | Whole note | `w` | | `2` | Half note | `h` | | `4` | Quarter note | `q` | | `8` | Eighth note | `e` | | `16` | Sixteenth note | `s` | | `32` | Thirty-second note | `t` | | `64` | Sixty-fourth note | Use the number | Write `8C5`, not a duration after the pitch. The last duration stays in force on a music line: `8C D E F` is four eighths. State the opening duration of each new row. A continued row retains it across `|`; a separately addressed measure starts its duration context again. Octave inference is separate and can carry across that boundary. Numeric and letter durations are both supported. Prefer a consistent spelling within a file; the formatter can normalize to either. Mixing them is accepted, but does not cancel inheritance or relax the meter. `4G` and `qG` both mean a quarter-note G; `4G A B C` and `qG A B C` both describe four quarters. The difference is spelling, not rhythm. For example, `4G D E Eb | hD F r |` is overfull in 4/4: the first bar has four quarters, but `hD` makes D, F, and the inline rest half-note values. That second bar totals six quarter beats. If half D, quarter F, quarter rest is intended, state the new quarter duration explicitly: ```scorescript 4G4 D E Eb | 2D 4F r ``` This is one possible correction, not a rule for guessing intended rhythms. A literal `?` after the music is not a comment; use `//` for commentary. ```scorescript 8C5 D E F 4G G | 2C, 4r 8D E ``` ## Dots and exact fractions Put dots on the duration: `4.C5` is a dotted quarter and `4..C5` a double-dotted quarter. `1/6C5` is exactly one sixth of a whole note. `&` supplies the complementary shorter duration after a dotted value: a dotted quarter plus `&D` gives a dotted quarter and an eighth, totaling a half note. The complement does not replace the inherited duration: in `4.C5 &D E`, E is another dotted quarter. State its duration when a different value is intended. ```scorescript 4.C5 &D 2E | 4..C 16D 2E ``` ## Tuplets Braces collect the notes in a tuplet. `{3: 8C D E}` is three eighths in the time of two. Write an explicit normal count for another ratio, as in `{5:3 8C D E F G}`: five eighths occupy three eighth-note units. ```scorescript {3: 8C5 D E} 4F G A ``` The displayed tuplet bracket and rhythmic scaling refer to the same group. Do not separately shorten the notes to compensate for the ratio. An inherited eighth after the group is an ordinary eighth, not a tuplet eighth: `{3: 8C D E} F` leaves F at one eighth. The example above explicitly switches to quarters with `4F`. ## Rests and incomplete bars `4r` is a quarter rest and `2r` a half rest. A lone bare `r` fills one whole measure in the current meter. `r8` means eight measures of rest, while `8r` means one eighth rest. The order changes the meaning. | Source | Reading | | --- | --- | | `4C D E r` | Three quarter notes and a quarter rest | | `2C D \| r` | Two half notes, then a full-bar rest | | `r C D E` | Overfull: the opening bare rest claims a whole bar | | `4r C D E` | A quarter rest, then three quarter notes | Bare `r` does **not** mean “fill the remaining beats.” Inside a musical row it inherits the established duration; standing alone in its bar it means a full-bar rest, even after a bar of halves or eighths. ```scorescript 4C5 D 2r | r | r2 | 1C ``` A short ordinary bar is completed with rests and diagnosed. A pickup labeled `m0:` stays short. An overfull bar is an error; a barline does not discard the extra duration. Omitted ranges in a part can represent silence; see [structure](structure.md). ## Grace notes A slash before the duration marks a grace note, which takes no measured time from the bar. Multiple grace notes may precede the main note. The grace's duration can still change the inherited note value. State the first main note's duration explicitly when it differs, as `4C` does here. ```scorescript /8D5 4C D E F ``` The slash before a note is different from a slash after it: the latter is a [glissando connector](connectors.md). --- # Parts, voices, and measures ## Parts first Declare instruments with `parts`, then write each part's music in its body. A measure range labels a run of bars. Separate bars with `|`. ```scorescript scorescript 0.3 score "Duet" { meter 4/4 parts { fl ob } fl { m1-2 { 4C5 D E F | 1G } } ob { m1-2 { 2C4 E | 1G } } } ``` Instrument keys and roster abbreviations identify instruments. A count such as `fl: 2` declares two flutes. A printed name containing spaces is quoted: `"Flute 1" { ... }`. See the instrument reference for catalog keys. Counts must be positive whole numbers representable by the engine: `fl: 0` is an error, not a way to omit a player. Remove the roster entry to omit it. ## Measures first To compare ensemble parts at the same moment, put the range outside the parts. The following has the same two lines of music as the duet above. ```scorescript scorescript 0.3 score "Duet" { meter 4/4 parts { fl ob } m1-2 { fl { 4C5 D E F | 1G } ob { 2C4 E | 1G } } } ``` Each row supplies bars for its selected part. A plain trailing barline can continue a row onto the next physical line while the promised range still needs bars. A blank line ends a row. Do not turn rows into arbitrary newlines: the part-first and measure-first forms have different row structure. Keep a newline after the outer measure-first header (`m1-2 {`) before the instrument rows. Do not flatten it into `m1-2 { fl { ... } }`. Within a music row, a plain physical newline is not an arbitrary within-bar wrap: use a lone trailing backslash to continue an unfinished bar onto the next line. For smaller source, use [native compaction](normalization.md), not a generic minifier. The older colon grid is accepted and is produced by `to-grid` as a reading view. Ordinary formatting writes one of the label-before-body arrangements shown here. A label belongs before its opening brace. ### Keep `m` on measure blocks Write `m10-50 { ... }`, not `10-50 { ... }`, in both arrangements. The range is inclusive: measures 10 through 50, or 41 measures. The `m` identifies an address; it is not part of the music's duration. A single measure uses `m10 { ... }` or an addressed music row such as `m10: 1C5`. Bare numeric block headers are not accepted by the current grammar. Maps have a different, explicitly named context: `system-map {10, 50}` lists two system starts, and `tempo {96, 10:120}` changes tempo at measure 10. Their bare addresses do not make `10-50 { ... }` a valid music block. Native formatting retains the `m` on measure-block addresses, including when compacting source; do not strip it with a text replacement. Formatting can regroup a long part-first range into smaller blocks without changing its measure addresses or music. ## Simultaneous voices Inside a **measure-first** block, separate rows under one instrument are simultaneous voices on that staff. The first row is voice 1; the second is voice 2. Each has its own rhythm and pitch reference. ```scorescript scorescript 0.3 score "Two voices" { parts { violin } m1 { violin { 2C5 D 1G4 } } } ``` Measure 1 contains C5 and D5 as half notes above a whole-note G4. Both rows start at the same time. This is one measure, not two. Scope matters: `violin { m1 { ... } }` is part-first. Putting the same two rows there advances through successive bars; it does not declare two voices. Use the measure-first arrangement above for simultaneous rows. Do not assume that multiple voices automatically mean two separately extractable players, an ossia, or a piano grand staff. Those are distinct musical requirements. Multi-staff `rh:`/`lh:` notation is not part of this documented authoring surface. ## Silence, pickups, and names In part-first source, gaps between explicitly addressed ranges are silent. A part that begins at `m9` has eight preceding measures of rest. Check the range before changing it: deleting music and leaving its next addressed range can leave silence rather than renumber the score. `m0` addresses a pickup. `=name` gives a note or a measure an authored name. ```scorescript scorescript 0.3 score "Pickup" { parts { flute } flute { m0 { 4G4 } m1=intro { 4C5=theme D E F } } } ``` Measure ranges also support names and reuse; see [shared passages](reuse.md). For multiple complete movements, use [collections](collections.md). ## Compatibility spellings Older files may contain `part flute: Flute { m1: ... }`, colon grids, or numbered `voice N { ... }` blocks. These remain accepted input; they are not the default examples for new files. The older direct part body does not accept all nested ranges, shared readers, and layout maps supported by the current roster-plus-body form. --- # Articulations, dynamics, and text ## Articulations Use parentheses. Square brackets have other jobs, including chords and changes of musical context. | Type | Mark | | --- | --- | | Staccato | `(.)` | | Staccatissimo | `(..)` | | Accent | `(>)` | | Tenuto | `(-)` | | Marcato | `(^)` | | Portato | `(.-)` | | Fermata | `(!)` | | Breath | `(,)` | | Caesura | `(caesura)` | ```scorescript (.)4C5 (..)D (>)E (-)F | (^)4G (.-)F (!)2E ``` Several articulations may share a group, such as `(>.)`. An articulation normally belongs to one note. Its side follows the engraving rules for the staff and voices; moving it before or after the pitch is not a general manual placement command for articulations. Breaths and caesuras mark a point in the phrase without adding a written rest duration. ```scorescript 4C5 D E F(,) | 2G(caesura) 2r ``` ## Repeat an articulation `(sim)` continues the articulation in force. `(non)` ends that run. Rests receive no articulation and do not by themselves end a run. An explicit new articulation group interrupts it. ```scorescript (-)4C5 (sim)D E F | (non)4G F E D ``` ## Dynamics and expression Common dynamics include `(ppp)`, `(pp)`, `(p)`, `(mp)`, `(mf)`, `(f)`, `(ff)`, `(fff)`, and `(sfz)`. A dynamic stays in force until another changes it. Expression words include `(dolce)` and `(cresc)`. Use a quoted string for your own text, such as `("sul pont.")`. For dynamics, expression, and text, before the node means above the staff; after the node means below. Touch the intended node to avoid ambiguous attachment. A detached floating mark binds left. | Source | Placement and attachment | | --- | --- | | `4C5(p) D E F` | Below C | | `4C5 (p)D E F` | Above D | | `4C5 (p) D E F` | Detached; binds left, below C | ```scorescript 4C5(pp "softly") D E F | (mf)2G 2E(dolce) ``` One parenthesized group prints as one line. Put the dynamic and description together when you want them together. `((p))` is an editorial dynamic, printed with an enclosure. ## Ornaments and tremolo `(tr)` marks a trill, `(mord)` a mordent, `(turn)` a turn, and `(iturn)` an inverted turn. For a trill extending over several notes, use a [trill line](connectors.md). ```scorescript 4C5(tr) D(mord) E(turn) F(iturn) ``` `(trem)`, `(trem2)`, and `(trem3)` select stem tremolo marks. `(z)` marks a buzz roll. These are single-note marks; they do not spell an alternating two-note tremolo. ```scorescript 2C5(trem2) 2D(trem3) ``` Printing an ornament does not guarantee a particular sampled performance. Check the sound you intend to deliver. --- # Slurs, ties, and lines ## Two endpoints make one slur A trailing connector opens at its note. A leading connector closes at its note. Leave interior notes unmarked. ```scorescript 4D5~ E ~F G ``` This is one slur from D through E to F. `D~ E~ F` means adjacent spans, not one three-note slur. A lone trailing `~` can connect to the next node. ## Ties require adjacent matching pitches When adjacent endpoint notes have the same pitch, `~` makes a tie. ```scorescript 2C5~ 2C | 1D ``` A later matching pitch with sounding notes between the endpoints is a slur, not a tie. For a chord, put a member tie on the member that continues: ```scorescript 2[C5~ E G] 2[C F A] ``` A trailing `~~` ties forward and opens a slur at the same node: ```scorescript 4C5~~ C D ~E ``` The first two C notes tie; the whole C-to-E passage has one slur. ## Hairpins `<` is crescendo and `>` diminuendo. Open after the first node and close before the destination. A destination can also open the next hairpin. ```scorescript 4C5(p)< D >F(p) ``` An open hairpin can end at the next dynamic. If it has no destination, the current engine warns and leaves a short local mark; it does not establish an intentional crescendo through the rest of the piece. Write the intended end explicitly for a finished score. ## Glissando A slash after a node connects it to the next node. It needs no closing slash. ```scorescript 2C5/ 2G' ``` Compare `/8C5 4D`: the leading slash makes a grace note instead. ## Bracketed lines The dots picture the continuation: `[word..]` opens, `[..word]` closes. The closer ends the line on the preceding node. In the examples below, E is the last covered note and F is outside the line. The first note after an ottava closer is no longer under that octave line. ```scorescript [ped..] 4C4 D E [..ped] F ``` ```scorescript [8va..] 4C5 D E [..8va] F ``` ```scorescript [8vb..] 4C4 D E [..8vb] F ``` The related two-octave forms are `[15ma..]` and `[15mb..]`. `(loco)` can close an ottava. Inspect the pitches and output when using octave lines; do not add another manual octave change to compensate for the same sign. ```scorescript [tr..] 4C5 D E [..tr] F ``` Tempo transitions use `[rit..]`, `[rall..]`, or `[accel..]` with `[...]` as a close. `[a tempo]` restores the indicated tempo context. ```scorescript [rit..] 4C5 D E [...] F | [a tempo] 1C ``` ## Custom lines Custom lines have no supported compact engraving form. The older `span custom-line` statement can reach the resolved score, but the current renderer does not draw it. Substituting an arbitrary word in `[word..]` does not create a custom line. Use the named supported lines above; quoted text can print an instruction but does not draw an extending line. --- # Meter, key, tempo, and clef ## Opening settings and later changes Set `meter`, `key`, and `tempo` in the score header. A setting stays in force until another replaces it. For several changes, a compact map puts the timeline together. The first unaddressed entry is the opening value; later entries begin with their measure number. ```scorescript scorescript 0.3 score "Changing meter" { meter {4/4, 2:3/4, 3:4/4} key {C, 3:G} tempo {Andante 80, 3:Allegro 120} parts { flute } flute { m1-3 { 4C5 D E F | 4G A B | 1C } } } ``` An addressed block such as `at m2 { meter 3/4 }` states the same kind of change. Inside a part, `[meter 3/4]`, `[key G]`, and `[tempo 120]` place changes at a musical point. Score-wide changes should be stated once in the score timeline, rather than repeated in every player's music. `meter none` allows unmetered music. Compound meters such as `6/8` have their own standard beam grouping. A key signature and the pitch-reading mode are different settings; see [key-aware spelling](pitch.md). ## Tempo words and beat units A tempo entry can contain a word, a metronome value, or both. Use quotes for several words. An explicit metronome beat retains its printed unit: `tempo 4.=88` gives dotted-quarter equals 88. `tempo 8=164` gives eighth equals 164. Two note values instead of a metronome number express metric modulation, such as `tempo 4=8` or `tempo 4=e.~s`. ```scorescript scorescript 0.3 score "Compound pulse" { meter 6/8 tempo 4.=88 parts { flute } flute { m1 { 8C5 D E F G A } } } ``` `*Andante` and `*"Molto Andante"` place tempo text above the music. A physical line containing only tempo words is a preamble for the following musical row; it does not create a silent measure. ```scorescript *"Andante" 4C5 D E F ``` In a tempo map, prefix a direction with the comma down-mark to request player-facing text below the staff, as in `tempo {80, 2:,"molto rit."}`. Above-system directions remain visible to resting players; below directions are omitted in a resting part. ## Clefs and instruments Catalog instruments provide their normal clef. Use `clef bass`, `clef alto`, or another supported clef where necessary, and `[clef bass]` for an inline change. Numeric clefs `1` through `7` mean treble, soprano, mezzo-soprano, alto, tenor, baritone, and bass respectively. An instrument change is written `[instrument piccolo]`; inspect the resulting range and written part when doubling instruments. ## Beams Standard grouping follows the meter. An override such as `[beams 3+3+2/8]` counts in eighths and fits a whole 4/4 measure. Without `/8`, the numbers count in the current meter's denominator unit. ```scorescript [beams 3+3+2/8] 8C5 D E F G A B C ``` `[beams none]` separates the notes; `[beams beat]` groups by beat; `[beams standard]` restores the standard grouping. A custom grouping is remembered for its meter when that meter returns. `standard` clears that meter's remembered override. ## Rehearsal marks **Default and recommended: boxed actual measure numbers, including inside the measures themselves.** Choose the placement that suits your source: | Placement | Source | Meaning | | --- | --- | --- | | Inside a continuous measure block | `... F \| [[5]] G ...` | A boxed 5 on the measure containing G | | Inside an addressed measure | `m5: [[5]] 1G` | A boxed 5 on measure 5 | | In a score-level map | `RH {5, 9, 13}` | Boxed 5, 9, and 13 at those measures across the score | ### Inside continuous measures Place the box after the barline and before that measure's first note. It takes no musical time and does not reset the inherited duration or octave. ```scorescript scorescript 0.3 score "Measure-number landmarks" { meter 4/4 piano { m1-16 { 1C5 | D | E | F | [[5]] G | F | E | D | [[9]] C | D | E | F | [[13]] G | F | D | C } } } ``` ### Inside separately addressed measures The same music and boxes can be written with explicit measure rows: ```scorescript scorescript 0.3 score "Measure-number landmarks" { meter 4/4 piano { m1-4 { 1C5 | D | E | F } m5: [[5]] 1G m6-8 { 1F | E | D } m9: [[9]] 1C m10-12 { 1D | E | F } m13: [[13]] 1G m14-16 { 1F | D | C } } } ``` ### In a map These same landmarks can instead live in `RH {5, 9, 13}`. Each map entry is both the address and displayed number; no repeated label or extra brackets are needed. Include `1` only when an opening box is wanted: `RH {1, 5, 9, 13}`. The equivalent inline opening is `m1: [[1]] 1C5`. ```scorescript scorescript 0.3 score "Measure-number landmarks" { meter 4/4 RH {5, 9, 13} piano { m1-16 { 1C5 | D | E | F | G | F | E | D | C | D | E | F | G | F | D | C } } } ``` An inline `[[5]]` is a **label on its containing measure**, not a jump to measure 5 or an automatic current-measure placeholder. Keep that explicit number aligned with its measure when inserting or renumbering bars. The map is score-wide; an inline mark inside one part belongs to that part. The three examples above are equivalent because they contain one part. A custom boxed letter such as `[[A]]` or `RH A`, and a circled `(A)`, are optional alternatives—not the recommended default. In a map, `RH {5:[[A]], 9:(B)}` explicitly chooses those alternate labels/shapes. Single `[A]` is a sounding pitch, not a box. The default is manual placement: only requested marks are printed. `rehearsal auto` is an optional, separate scheme that derives sequential letter marks at structural seams; it is not needed for the recommended numbered map. Written marks take precedence. Check the rendered rehearsal sequence before extracting parts. --- # Repeats, endings, and navigation ## Barlines `|` is a plain barline, `||` a double barline, and `|||` a final barline. Keep the pipes touching. Spaced `| |` includes an empty bar between two barlines. ```scorescript 4C5 D E F || 1G ||| ``` ## Repeated sections `|:` opens a repeat; `:|` closes it. The repeat sign already includes its double-bar geometry. Do not add another double bar beside it. The checker reports redundant pipes and the formatter removes them. `:|:` closes one repeat where the next begins. ```scorescript |: 4C5 D E F | 1G :| ``` ## Repeat or borrow a measure A measure containing only `&&` repeats the preceding bar and prints a simile sign. `&&!` repeats it with the notes written out. `&&4` repeats four bars. These forms must occupy a bar on their own and need earlier music to borrow. ```scorescript 4C5 D E F | && | &&! | &&2 ``` `%` borrows the preceding bar as written-out notes. `%m1` borrows the addressed earlier measure. This older form uses colon-addressed measure lines; `%m1` is not accepted inside a modern nested `m2 { ... }` body. For new range-based source, use [named range assignments](reuse.md). The borrowed rhythm must fit the destination meter. ```scorescript m1: 4C5 D E F m2: %m1 ``` ## First and second endings `[1..]` opens a first ending and `[2..]` the second. `[1,2..]` names several passes. The closing repeat closes the first ending. A final ending can close at an explicit double or final barline; without one it follows the length of the ending it parallels. ```scorescript 4C5 D E F [1..] | 1G :| [2..] | 1C, ||| ``` ## Navigation words Use bracketed musical instructions: `[segno]`, `[coda]`, `[to coda]`, `[fine]`, `[D.C.]`, `[D.C. al Fine]`, or `[D.S. al Coda]`. Navigation is case-insensitive and periods are optional: `[DC]`, `[dc]`, and `[D.C.]` all mean da capo; `[DS]`, `[ds]`, and `[D.S.]` mean dal segno. A deliberately named boxed label is `[[DC]]`, not a jump; prefer actual measure-number rehearsal maps such as `RH {5, 9, 13}` for ordinary landmarks. ```scorescript [segno] 4C5 D E F | 1G [fine] ``` Printed navigation and a playback itinerary are separate acceptance checks. Inspect and listen to the finished work; do not assume that a renderer showing an instruction proves every player follows its return path. --- # Lyrics and chord symbols ## A lyric row follows its music Write `lyrics:` immediately below the musical row. Separate syllables with spaces and align lyric barlines with the music's barlines. ```scorescript 4C5 D E F | 2G E lyrics: Sing- ing a song | for you ``` `Sing- ing` divides a word across two notes. `_` extends the previous syllable over the next note, `*` skips a note, and `~` joins two words on one note. A second lyric row, or `lyrics 2:`, supplies another verse. ```scorescript 4C5 D E F lyrics: Joy _ * to~you ``` A multirest is one printed column even when it occupies several semantic measures. Lyric alignment counts the row's columns. The checker reports misaligned bars. A music continuation backslash does not join a lyric row to the music above it. ## Chord symbols stand above the music Prefix a chord symbol with `@`: `@F7`, `@fm7`, or `@Bbmaj7`. A chord symbol is text/harmony information; it does not add sounding chord notes. See [chord spellings](chords.md) for the full implemented quality vocabulary, explicit sounding chords, and the requested compact-chord grammar. ```scorescript @C 4C5 D E F | @G7 1G ``` Without `@`, `F7` is the pitch F in octave 7. Lowercase roots can carry minor-side quality; case never substitutes for an octave. Seventh qualities include `maj7`, `m7`, `mMaj7`, `dd7`, `dm7`, `+M7`, and `+m7`. Extended chords use forms such as `m9b5`, `9#5`, and `13`. `no5` describes an omitted fifth; it does not remove separately written pitches. Unknown suffixes can survive checking, so a successful check is not complete chord validation. See the chord reference for slash-bass and formatter limitations. ## Figured bass Figured bass appears in the element registry as an incomplete feature. The statement reader recognizes it, but the resolved model does not yet carry a complete figured-bass realization. It is not a supported finished engraving workflow. Ordinary quoted text can print figures as text, but that does not give them figured-bass semantics. --- # Chords, Roman numerals, and inversions ## Choose the right bracket | Purpose | Spelling | Meaning | | --- | --- | --- | | Specify sounding notes | `4[C4 E G]` | Plays the three written pitches together | | Print a harmony symbol | `@C` before music | Labels the harmony; adds no sounding pitches | | Generate a sounding chord | `4[CMm7:4]` | C4 E4 G4 Bb4 together | | Generate a key-relative chord | `4[V65:4]` in C major | B4 D5 F5 G5 together | | Print boxed measure-number landmarks | `RH {5, 9, 13}` | Recommended rehearsal default; no sounding notes | Sounding formulas are implemented in the native engine accompanying this reference. Older installed builds may not recognize them. Compile with the matching build before relying on a host's editor highlighting. `[C]` is one pitch, **not C major**. `[C7]` is one C in octave 7, not a dominant seventh. Use `[CM]` and `[CMm7]` for those harmonies. Boxed rehearsal marks use `RH {5, 9, 13}` by default, or inline `[[5]]` at measure 5. Custom letters are optional; replace an older boxed `[A]` with `[[A]]`. ## Triads and seventh qualities Named roots are uppercase `A`–`G`, optionally followed by `b`, `bb`, `#`, `##`, or `n`. Their spelling is absolute even under `spell key`: `[FM]` always starts on F-natural. `[F#M]` starts on F-sharp. | Triad | Example | Tones | | --- | --- | --- | | Major | `[CM]` | C E G | | Minor | `[Cm]` | C Eb G | | Diminished | `[Cd]` | C Eb Gb | | Augmented | `[C+]` | C E G# | The first quality describes the triad; the second describes the seventh **above the root**, not the third stacked above the fifth. This is established academic notation, explicitly documented in the [UMTA skills syllabus, page 7](https://www.usu.edu/ycpiano/files/Level9.pdf). | Spelling | Triad quality | Seventh quality | Spelled tones | | --- | --- | --- | --- | | `[CMM7]` | Major | Major | C E G B | | `[CMm7]` | Major | Minor | C E G Bb | | `[CmM7]` | Minor | Major | C Eb G B | | `[Cmm7]` | Minor | Minor | C Eb G Bb | | `[Cdm7]` | Diminished | Minor | C Eb Gb Bb | | `[Cdd7]` | Diminished | Diminished | C Eb Gb Bbb | | `[CdM7]` | Diminished | Major | C Eb Gb B | | `[C+M7]` | Augmented | Major | C E G# B | | `[C+m7]` | Augmented | Minor | C E G# Bb | The formatter preserves the quality pair instead of replacing it with another tradition's shorter label. The square brackets and plain-text encoding are ScoreScript's choices; the chord classification is established music theory, not a new naming system. `[CM7]`, `[Cm7]`, and `[DMm]` are not abbreviations in this grammar. State both seventh qualities and a figure: `[CMM7]`, `[Cmm7]`, `[DMm7]`. Case matters. The `d` in `dd7` means diminished, so C's seventh is **Bbb**, not an enharmonically respelled A. ```scorescript 4[CMM7:4] [CMm7] [Cmm7] [Cdd7] ``` ## Duration and register are separate fields Put duration **before** the bracket: `4[CMm7]` or `q[CMm7]`. Both are a quarter-note chord. Duration continues across later chords, ordinary notes, and barlines within the same row/continuation; separately addressed rows have their own duration start. Digits inside a formula are chord structure, not duration. Put an explicit **root octave** after a colon inside the bracket: `[CMm7:4]`. It anchors C4, not whichever member an inversion puts in the bass. This avoids confusing a seventh or inversion figure with an octave. Formula register accepts `:-10` through `:10`; the instrument's playable range is a separate check. Prefer a useful musical register. Without `:octave`, the root follows the ordinary nearest-note rule. A final apostrophe or comma **inside a formula** shifts that root up or down: `[CMm7']`, `[CMm7,]`. Do not put spaces inside a formula. Formatter output anchors the first sounding root of a section, then uses relative register. The next event follows the formula's root, including after inversions. ```scorescript 4C4 [DMm7] [EMm7'] [FMm7,] ``` ## Inversions: figured-bass placement Figures select the bass member. The conventional printed figures are often stacked; ScoreScript writes them consecutively. The inversion figure **replaces** `7`; do not write a suffix such as `765` or `742`. | Figure | Bass | Named chord | Roman example | | --- | --- | --- | --- | | None | Triad root | `[CM]` | `[I]` | | `6` | Triad third | `[CM6]` | `[I6]` | | `64` | Triad fifth | `[CM64]` | `[I64]` | | `7` | Seventh-chord root | `[CMm7]` | `[V7]` | | `65` | Seventh-chord third | `[CMm65]` | `[V65]` | | `43` | Seventh-chord fifth | `[CMm43]` | `[V43]` | | `42` | Seventh-chord seventh | `[CMm42]` | `[V42]` | With C4 as the root anchor, `[CMm65:4]` produces E4 G4 Bb4 C5; `[CMm43:4]` produces G4 Bb4 C5 E5; `[CMm42:4]` produces Bb4 C5 E5 G5. The engine starts with the root-position stack and raises the members below the requested bass by an octave. This is ScoreScript's deterministic voicing policy—not a claim that figured bass requires that spacing. ```scorescript 4[CMm7:4] [CMm65] [CMm43] [CMm42] ``` `6` means inversion here, not an added sixth. Full figures `53`, `63`, `753`, the abbreviated seventh inversion `2`, and arbitrary figures above a separately written bass are not accepted in this constructor grammar. See the [figured-bass reference](https://viva.pressbooks.pub/openmusictheory/chapter/figured-bass/). ## Roman numerals: the active key supplies the root Uppercase `I`–`VII` specifies a major triad; lowercase `i`–`vii` specifies a minor triad. The numeral selects a scale degree of the active **major or minor tonic**. A minor therefore starts on A, not its relative-major C. Append `o` (or `°`) for diminished, `+` for augmented, and `ø` for a diminished triad with a minor seventh. `ø` needs a seventh figure or extension. ```scorescript scorescript 0.3 score "Key-relative harmony" { meter 4/4 key {C, 2:G, 3:Am} piano { m1-3 { 4[I:4] [vi] [ii6] [V7] | [I] [vi] [ii6] [V7] | [i] [iv6] [V7] [i] } } } ``` | Key | Formula | Tones, in root order | | --- | --- | --- | | C | `[I]` | C E G | | G | `[I]` | G B D | | Am | `[i]` | A C E | | Am | `[v]` | E G B | | Am | `[V]` | E G# B | | Am | `[VII]` | G B D | | Am | `[viio7]` | G# B D F | | Am | `[viiø7]` | G# B D F# | In minor, diminished `vii` raises the unstated seventh-degree root to the leading tone; uppercase `VII` remains the natural-minor subtonic. This does not turn every other chord into a harmonic-minor stack. An initial `b`, `bb`, `#`, or `##` alters the root relative to the active key's scale degree. In C major, `[bII6]` is Db major in first inversion. In A minor, `[VI]` already starts on F; `[bVI]` starts on Fb. An explicit prefix replaces the implicit leading-tone adjustment on diminished `vii`. `key open` has no tonic and rejects Roman formulas. An omitted key uses the engine's C-major default; state the key explicitly when authoring reusable Roman-numeral material. ### Roman sevenths and explicit quality Plain `7`, `65`, `43`, and `42` take the seventh from the local key, except where `o` or `ø` explicitly selects its quality. Thus `[I7]` in C major is C E G B, while `[V7]` is G B D F. In A minor, `[i7]` is A C E G. Use `M` or `m` before the figure to state the seventh independently: `[IM7]` is major–major; `[Im7]` is major–minor; `[iM7]` is minor–major; `[im7]` is minor–minor. The numeral's case already supplies the triad quality. `[viio7]` selects a diminished seventh; `[viiø7]` selects a minor seventh. Do not append another quality to `ø`. This key-diatonic default follows one established academic practice, not a universal spelling rule: [Open Music Theory](https://viva.pressbooks.pub/openmusictheory/chapter/roman-numerals/) uses contextual sevenths, while [Puget Sound](https://musictheory.pugetsound.edu/mt21c/RomanNumeralsOfDiatonicSeventhChords.html) uses an explicit `M7` convention. Explicit quality avoids that ambiguity. ### Applied chords: slash means “of,” not “over” `[V7/V]` means the dominant seventh **of V**. In C major it produces D F# A C. `[V7/ii]` produces A C# E G; `[viio7/ii]` produces C# E G Bb. The target's case determines its local major/minor key. Add inversion before the slash and register last: `[V65/V:4]` produces F#4 A4 C5 D5. ```scorescript [key C] 4[I:4] [V65/V] [V7] [I] ``` Only one target numeral is accepted, optionally with a root accidental. Nested chains, a figured target, and diminished-key targets are not supported. `[V7/V]` is unrelated to repetition and to an `@F7/A` printed slash-bass label. ## Ninths, elevenths, thirteenths, and alterations Replace the root-position `7` with `9`, `11`, or `13`. The two named quality letters retain their meanings: the second still describes the **seventh**. Every intervening third is included. These are complete stacks, not automatically thinned performance voicings. | Formula | Included tones, root order | | --- | --- | | `[CMM9]` | C E G B D | | `[Cmm11]` | C Eb G Bb D F | | `[CMm13]` | C E G Bb D F A | | `[CMm13b9#11b13]` | C E G Bb Db F# Ab | Named formulas use a major ninth, perfect eleventh, and major thirteenth above the root before alterations. Roman formulas instead take extension tones from the local key: A-minor `[V9]` has F-natural; named `[EMm9]` has F#. ```scorescript [key Am] 2[V9:4] [EMm9] ``` Append `b` or `#` plus `5`, `9`, `11`, or `13` to alter a member already present. The alteration is relative to that formula's unaltered member. `[CMm9b9]` is valid; `[CMm7b9]` is not, because a seventh stack has no ninth. Repeated alterations of the same degree are rejected. `add`, `sus`, `no5`, slash-bass named constructors, and combined extension/inversion digits are not part of the sounding-formula grammar. Write a literal chord for custom omissions, suspensions, spacing, doublings, or extended-chord inversions. ## Explicit sounding chords Put the duration before the whole bracket. Within the same musical row or continuation, it carries to later chords and notes until another duration changes it. Separately addressed rows can reset it. Anchor the opening register, then use relative pitches where they express the intended voicing. ```scorescript 4[C4 E G] [D F# A C] [E G C] [F A C] ``` Member order controls relative octave reading. The next event follows the first written member, so sorting members is not a harmless formatting change. Inside brackets a comma separates members; it is not the downward-octave operator. Use an explicit octave when a member needs that lower register. Key-aware letters and solfège are pitch spellings here too; they use the same modes described under [notes and pitch](pitch.md). ## Chord-symbol qualities The following table describes the **`@` annotation vocabulary**, which is separate from sounding formulas. Every entry needs `@` when used in music. The preferred column names the resolved quality; aliases are accepted input. | Quality | Preferred symbol | Other accepted spellings | | --- | --- | --- | | Major triad | `@F` | `@FM`, `@Fmaj`, `@Fmajor`, `@FMaj` | | Minor triad | `@Fm` | `@Fmin`, `@Fminor`, `@F-` | | Diminished triad | `@Fd` | `@Fdim`, `@Fo` | | Augmented triad | `@F+` | `@Faug` | | Major–minor seventh (dominant) | `@F7` | `@Fdom7`, `@FMm7` | | Major–major seventh | `@Fmaj7` | `@FM7`, `@FMM7`, `@Fmajor7`, `@FMaj7` | | Minor–minor seventh | `@Fm7` | `@Fmm7`, `@Fmin7`, `@F-7` | | Minor–major seventh | `@FmMaj7` | `@FmM7`, `@Fmmaj7`, `@Fminmaj7` | | Diminished–diminished seventh | `@Fdd7` | `@Fdim7`, `@Fo7` | | Diminished–minor seventh (half-diminished) | `@Fdm7` | `@Fm7b5`, `@Fm7-5`, `@Fmin7b5`, `@Fhalfdim7` | | Diminished–major seventh | `@FdM7` | `@FdMaj7`, `@Fdmaj7`; rare-quality warning | | Augmented–major seventh | `@F+M7` | `@F+maj7`, `@Faugmaj7`, `@F+Maj7` | | Augmented–minor seventh | `@F+m7` | `@Faug7`, `@F+7`, `@F7#5` | In quality pairs, the first component describes the triad and the second the seventh. An accepted annotation alias does not automatically become an accepted sounding-formula spelling. ```scorescript @C 1[C4 E G] | @DMm7 [D F# A C] | @G7 [G B D F] | @C [C E G] ``` `@DMm7` labels the explicitly written D seventh chord; the bracket supplies its notes. Bare `D7`, without `@` or brackets, means the pitch D in octave 7. ## Case, accidentals, and omissions Roots accept `b`, `bb`, `#`, and `##`. Prefer uppercase roots with explicit qualities. Lowercase `@f` means F minor and `@f7` means F minor seventh. Lowercase roots with explicit major or augmented quality, such as `@fmaj7`, raise `chord.quality-case-mismatch` errors. `@FdM7` instead raises the non-fatal `chord.rare-quality` warning. Append `no5` to omit the fifth in the symbol description: `@Fm7no5`. The alias `^5` is accepted and formatted to `no5`. A symbol omission does not delete any notes you separately wrote in a sounding chord. ## Extensions, slash bass, and validation limits Compact suffixes such as `sus2`, `sus4`, `7sus4`, `add9`, `6`, `9`, `11`, `13`, `m9b5`, and `9#5` are accepted as symbol text. Extended suffixes are not comprehensively checked: even an unknown word can survive checking. Acceptance is not proof of a recognized chord formula or automatic voicing. `@F7/A` prints a slash suffix. The current implementation does not resolve it as a validated bass field or export a structured MusicXML bass. Keep the slash and bass adjacent to the symbol, and write the sounding bass explicitly. Do not use slash-symbol acceptance as proof that the bass spelling is valid. Parenthesized alterations such as `@F7(b9)` do not form one chord symbol: the parenthesis is read separately and can produce `notation.unknown`. `@Fø7`, `@FΔ7`, and `@"Cmaj7"` are not accepted alternatives. Use the tested ASCII quality spellings above. Quoted text marks can print arbitrary text, but do not acquire chord semantics. ## Formatting is not complete quality normalization The source formatter rewrites selected spellings, including `@FMm7` → `@F7`, `@FMM7` → `@Fmaj7`, `@FmM7` → `@FmMaj7`, and `^5` → `no5`. It does not rewrite every accepted alias into the table's preferred spelling. **Known defect:** avoid lowercase `@fdom7`. Formatting currently changes it to `@Fdom7`, changing the resolved harmony from minor seventh to dominant. Use explicit `@Fm7` or `@F7`. Checking MIDI alone cannot detect a changed annotation because symbols do not generate notes. Related: [lyrics](lyrics.md), [marks](marks.md), [normalization](normalization.md). ## Formatting, reuse, export, and current boundaries | Operation | Formula behavior | | --- | --- | | Ordinary formatting | Keeps quality, numeral, inversion, and sounding spelling; normalizes root register | | Grid/part arrangement | Retains the formula and its music | | Change the written key | Roman formulas intentionally follow the new key; named formulas keep their root spelling | | Sound-preserving key normalization | Explicitly refuses Roman formulas rather than reinterpreting them | | Shared reader register | Anchors the formula's root, not its inverted bass | | Shared reader interval | Supported for spellable named roots; Roman interval readings explicitly refuse for now | | Consolidation | Uses the existing musical equivalence check; a root/bass register mismatch can refuse consolidation | | MIDI, rendering, MusicXML | Consume the generated notes; a formula does not add a printed harmony label | | Edit one generated member | Refused as an individual written-pitch edit; author a literal voicing to edit its members independently | Use `@` separately if a printed chord label is wanted. MusicXML transports the resolved notes, not the compact authored formula; importing it is not a promise to recover the original Roman numeral or quality-pair source. General figured-bass realization, SATB voice-leading, and host gestures for expanding/editing formula members are later work. They are not implied by correct chord construction. Unsupported formulas report an error; a suffix being accepted as loose `@` label text is not validation of sounding harmony. --- # Percussion and sticking ## The hand can be the note On an unpitched percussion part, `R` and `L` are stroke notes. Durations work exactly as they do for pitched notes. A rest is still lowercase `r`. ```scorescript scorescript 0.3 score "Single strokes" { parts { snare-drum } snare-drum { staff-lines 1 m1-2 { 4R L R L | 8R L R R L R L L } } } ``` The catalog drum supplies its percussion clef. A custom part can explicitly use `clef percussion`. `staff-lines 1` selects a one-line staff. ## Flams and drags Use the ordinary grace slash: `/R L` is a right grace stroke into a left main stroke; `/L /L R` is two left grace strokes into a right main stroke. ```scorescript scorescript 0.3 score "Grace strokes" { parts { snare-drum } snare-drum { m1 { /R 4L R /L /L R L } } } ``` Do not use `rL` as a musical note: `r` already means rest. Lowercase hands printed by the engraver are not the source spelling of a grace note. ## Hands on pitched notes On a pitched part, keep the pitch and attach the hand as a mark after it. ```scorescript 4C5(R) D(L) E(R) F(L) ``` Bare `R` on a pitched part is refused. Hand marks are technical indications, not lyric syllables. ## Named rudiments A score-level `rudiment` declares a hand pattern. An exercise's `sticking` statement applies that pattern to its attacks. The title alone does not apply hands. ```scorescript scorescript 0.3 score "Paradiddle" { rudiment "Single paradiddle" R L R R | L R L L exercises { exercise =study { title "Paradiddle study" sticking "Single paradiddle" section m1 } } parts { snare-drum } snare-drum { m1 { 8R L R R L R L L } } } ``` The pattern cycles through attacks. Rests and tied arrivals consume no stroke. An explicit hand wins while retaining its place in the cycle. Rudiment pattern tokens can include `lR` and `rL` for flams, and roll marks such as `(trem3)` or `(z)`; the corresponding notes must actually contain the grace or roll structure. Mismatches are diagnosed. Rudiments and exercise collections remain provisional language features. --- # Page and system layout ## Start systems and pages at musical places A `system-map` lists the first measure of each new system; a `page-map` lists the first measure of each new page. Measure 1 is implicit. Put the map inside a part when it describes that player's page. ```scorescript scorescript 0.3 score "Four lines" { parts { fl } fl { system-map {3, 5, 7} page-map {5} m1-8 { 1C5 | D | E | F | G | F | E | C } } } ``` `system-map {5:2}` starts a system at measure 5 and requests exactly two semantic measures. A plain `5` starts a system without prescribing its count. When copying a printed part, read each system's first measure number directly. Page starts imply system starts; system starts alone do not imply new pages. Conflicting authored cuts can cause the renderer to decline an exact-count span; inspect the render report instead of treating it as an override. The example requests systems beginning at 1, 3, 5, and 7, with measure 5 starting a new page. The inline preview is flowing SVG; use paginated SVG or PDF output to see page boundaries. ## Local cuts `\n` starts a system **before its containing measure**. `\p` starts a page and system there. Prefer placing either immediately after the preceding barline, before the target measure's first note. A trailing cut before a barline still belongs to the current measure; it does not mean “after this bar.” | Source within a musical row | Result | | --- | --- | | `1C5 \| D \n \| E` | New system before D, measure 2 | | `1C5 \| D \| \n E` | New system before E, measure 3 | | `1C5 \| D \| \p E` | New page and system before E, measure 3 | Address a cut inside omitted silence by attaching its number, such as `\n29`. A part's cut belongs to that part. A score-level `layout { \n13 \p46 }` applies globally. These are actual backslash letters in the source, not escaped newlines in a programming string. A lone backslash at the end of a physical source line continues the same musical row instead of requesting an engraved break. ## Inside parts-first and measures-first music These two sources request the same notes and player-local cuts. In both, flute starts a system at measure 2 and a page at measure 4; oboe has no player-local cuts. Parts-first: ```scorescript scorescript 0.3 score "Part-local cuts" { parts { fl ob } fl { m1-4 { 1C5 | \n D | E | \p F } } ob { m1-4 { 1C4 | D | E | F } } } ``` Measures-first: ```scorescript scorescript 0.3 score "Measure-row cuts" { parts { fl ob } m1-4 { fl { 1C5 | \n D | E | \p F } ob { 1C4 | D | E | F } } } ``` In a parts-first body, `system-map {2}` and `page-map {4}` can express those same flute boundaries. Do not put these maps inside the flute's measures-first row or invent a map-only detached flute body beside it: those placements are not supported. Use inline cuts in that row, or a score-level map when the intent is genuinely global. ## Duration inheritance still applies around cuts ```scorescript qEb5 Bb D E | wD | A | \n eD D D D hr | eEb G Bb er hr ``` The first bar has four quarters. `wD` changes the inherited duration to a whole note, so the next `A` is also whole. In measure 4, `eD` changes it to an eighth; four eighth notes plus `hr` fill the bar. The `\n` begins a system before that measure and consumes no duration. After `hr`, the inherited duration is a half. Therefore measure 5 needs the explicit `e` on `Eb`: three eighth notes, an eighth rest, and a half rest fill 4/4. Writing only `Eb G Bb er hr` there would overfill the bar. Layout placement and rhythmic validity are independent checks. ## Score Page versus Parts Page | Placement | Combined score | Extracted player part | | --- | --- | --- | | Score-level map or `layout` block | Applies globally | Also applies to every extracted part | | Cut in one player's music | Does not alone force an ensemble break | Applies to that player | | Same local cut on every present part | Also becomes an ensemble boundary | Applies individually | | Selected view's layout configuration | Refines that selected score view | Refines that selected part view | Global and player-local source cuts **add together**. A part map does not override or remove global cuts. For a full-score-only paper arrangement, use a score view's layout configuration instead of imposing global source cuts that every extracted player will inherit. A “Score Page” configuration and a “Flute Page” configuration can select different page settings and additional breaks from the same source. A part view is not a parts-first source file; a score view is not a measures-first source file. See [source arrangements and output views](representations.md). ## What normalization changes `arrange=parts` and `arrange=measures` reorganize source music. `maps=top|inline` moves musical context such as meter; it does **not** toggle system/page maps versus inline cuts. Break formatting independently uses maps for multiple cuts of a kind or exact-count system entries. `hoist-breaks` can move matching per-part break maps to global scope; it is not a command to discard player-specific layout. Physical source wrapping changes code readability. Engraved systems and pages follow musical layout directives and the selected output settings, not the width of your code editor. Normalization is an optional source rewrite; choosing another output view need not rewrite the music. ## Rest groups `[|]` begins a new engraved multirest group at a silent bar. `multi-map {3, 7}` records several such points compactly. This splits rest grouping without forcing a system or page break. Keep the map in the same scope as the intended rest grouping. ## Paper and engraving settings The score source carries musical layout intent. An optional `name.layouts.json` beside `name.scorescript` carries named paper and engraving configurations. It can refine page size, margins, staff size, spacing, and the selected part. A score still opens without the sidecar. Use the editor's layout controls to create a configuration rather than guessing JSON property names. Layout affects the printed view. It does not change the pitches, durations, or identities in the music. Always inspect the exported pages: a source system map alone does not prove good spacing or correct pagination. --- # Named exercises, shared passages, and transposition ## Define once; repeat and transpose A named passage is reusable music, not a pasted copy or a formatting shortcut. Give its first range an identity, then assign that identity to later ranges. Editing the original notes changes every derived occurrence when the source is compiled again. ```scorescript scorescript 0.3 score "Primary Exercises" { meter 4/4 parts { fl tpt } fl5, tpt4 { m1-3=primary { 1F4 | E | r } m4-6 = primary +P5 m7-9 = primary -P4 } } ``` | Source | Meaning | | --- | --- | | `m1-3` | The original occupies measures 1 through 3, inclusive | | `=primary` | Its reusable identity; later assignments refer to this name | | `{ 1F4 \| E \| r }` | Whole F, whole E, then a full-bar rest in 4/4 | | `m4-6 = primary +P5` | Those three bars again, up a perfect fifth | | `m7-9 = primary -P4` | The original again, down a perfect fourth | | `fl5, tpt4` | Both instruments read the music, starting in their stated registers | This is the language's variable-like reuse form. It is **not** a standalone `"Primary Exercises" = [...]` declaration: the definition has a real place in the score, and its music belongs in braces. Square brackets have other musical meanings, including chords. `wF4` is also accepted for a whole F; numeric durations are the default canonical spelling. Use a spelled interval such as `+P5`, not an ambiguous `+5`. The number is an interval size, not a count of semitones: `+P5` is seven semitones. `+P4` is five semitones. Each assignment is relative to the named original, never to the preceding assignment. Use the passage's exact identity, not a quoted display title. The definition and its references belong in the same shared-reader body. Keep source and target lengths equal and their measure ranges distinct. A plain `m4-6 = primary` repeats without transposition. An apostrophe or comma adjusts the derived register: `= primary'` raises an octave; `= primary +P4,` raises a fourth and then lowers an octave. Named reuse does not currently create printed exercise headings or book collection entries automatically. An optional quoted title after the name is accepted by the parser, but is currently dropped by formatting and does not print an exercise heading. Do not rely on that title form. Use explicit [collection metadata](collections.md) for displayed titles, variant ranges, numbering, book membership, and cross-file exercise identity. These shared-line and collection features are implemented but provisional. ## Share one line among instruments Declare the instruments, then name several readers in one head. A register digit says where the first note lands. A signed interval changes the reading in concert pitch. These shared-line forms are provisional. ```scorescript scorescript 0.3 score "Shared tune" { parts { fl ob } fl5, ob4 { m1-2 { 4C4 D E F | 1G } } } ``` The flute receives the line beginning in octave 5 and the oboe in octave 4. A head such as `fl5, ob4 +P5` gives the oboe a fifth-up reading as well. A repeated instrument key binds occurrences in source order; a key named once can select all instances of that instrument. Too many readers are an error, not extra implicitly created instruments. ## The band warm-up pattern There are two independent savings: several instruments share one musical body, and later exercises reuse a named range of that body. Neither reduces the number of measures the musicians receive. For example, a 16-bar primary exercise can supply a 48-bar sequence: ```text m1-16=primary { ...sixteen bars of music... } m17-32 = primary +P4 m33-48 = primary -P5 ``` This is a structural excerpt, not runnable music: replace the placeholder with the actual sixteen bars. A smaller complete example follows. ```scorescript scorescript 0.3 score "Sequence" { parts { fl } fl5 { m1-2=theme { 4C4 D E F | 1G } m3-4 = theme +P4 m5-6 = theme -P5 } } ``` Each interval is relative to the named original. The second derivation does not chain through the first. `+P4` raises a perfect fourth; `-P5` lowers a perfect fifth. The source and target lengths must agree. Apostrophe and comma can adjust the derived register, as in `= theme +P4,`. The old `expand` keyword is retired. Use the range assignment form above. Shared source reuse prints the derived music; it is different from a notated repeat sign that instructs a performer to return. Only the old **source keyword** is retired. The CLI's `scorescript expand` command and the normalization pass `expand` are available editing operations. See [normalization](normalization.md) for automatically finding shared parts and named returns in already-written music with `--normalize consolidate`. ## Instrument sections and individual changes The roster `parts { fl: 2, ob, tpt: 2 }` declares five players. In a shared head, `fl5, ob4, tpt4` addresses both flutes, the oboe, and both trumpets. To give the flutes different readings, write `fl5, fl4, ob4, tpt4` instead: the repeated `fl` entries bind the first and second flute in roster order. The digit is an octave anchor, **not** a player number. ```scorescript scorescript 0.3 score "Section readings" { parts { fl: 2, ob, tpt: 2 } fl5, fl4, ob4, tpt4 { m1-2=tones { 1C4 | D } m3-4 = tones +P4 } } ``` An instrument section shares music through its readers; a book `section` groups exercises. They are different concepts, not interchangeable block heads. An explicit individual part block overrides its shared reading. That override replaces the covered head's reading, not just one edited cell. To change one player safely, expand its shared passage first and retain all required bars in the resulting part. The selective CLI operation is: ```text scorescript expand piece.scorescript --part "Flute 1" --bars 1-16 ``` It prints the proposed source without replacing the file. It can materialize more than the requested bars to preserve the whole shared head. Read its diagnostics and the diff; targeting later repeated instances can be refused when they cannot be addressed independently. For a fully written-out editing view, use `scorescript format piece.scorescript --normalize expand`. ## Concert and written pitch Catalog instruments carry their transpositions. Ordinary score source can be authored in concert pitch and extracted as the player's written part. Do not add a manual interval merely because an instrument is transposing. A part-scoped `transpose` region can mark source already written for the player. Its two values are diatonic and chromatic displacement, not a pair of octave values. The explicit no-transposition value is `0`. ```scorescript scorescript 0.3 score "Written region" { parts { clarinet } clarinet { transpose {0, 2:-1 -2, 3:0} m1-3 { 1C5 | 1D | 1C } } } ``` This provisional feature changes how the region is read. Inspect both concert and extracted written output and listen before combining differently authored sources. A transposition map belongs to the player, while meter/key/tempo maps normally belong to the whole score. --- # Movements, exercises, and books ## Several movements in one file Each movement has its own music and settings, an authored identity, and a title. The outer `movements` block selects numbering style. ```scorescript scorescript 0.3 score "Little suite" { movements roman { movement =prelude { number 1 title "Prelude" meter 4/4 parts { flute } flute { m1 { 1C5 } } } movement =dance { number 2 title "Dance" meter 3/4 parts { flute } flute { m1 { 4C5 D E } } } } } ``` The movement IDs `prelude` and `dance` select movements independently of their current display order. A single score can also use `movement-title` for a heading; that alone does not create multiple movement programs. ```text scorescript pdf suite.scorescript --movement dance -o dance.pdf ``` ## Exercises as an index of existing music An exercise gives an existing range a title and optional concert-key label. It does not contain a duplicate copy of the music. Exercise collections and their numbering/layout behavior are provisional. ```scorescript scorescript 0.3 score "Long tones" { exercises { exercise =tones { number 1 title "Long tones" systems 2 section m1-4 { concert C } } } parts { flute } flute { m1-4 { 1C5 | 1D | 1E | 1C } } } ``` `systems 2` means two measures per system within this exercise, not two systems in total. Several `section` lines create variants. A section may omit its concert key for an unpitched or atonal exercise. `may-split` opts out of the one-page rule. Numbering styles include `arabic`, `roman`, `roman-lower`, `alpha`, and `alpha-lower`. An exercise can specify `reading P5 { hn } as "at the 5th"` for selected readers and `sticking "Pattern name"` for a declared rudiment. Use the [shared passages](reuse.md) and [percussion](percussion.md) chapters for those musical operations. ## Exercises that contain their music An exercise can instead own a body, with local measure numbers starting at m1. This is another supported arrangement, not a duplicate score to keep in sync with a separate index. ```scorescript scorescript 0.3 score "Practice set" { parts { fl tpt } exercise "Long Tones" =tones { fl5, tpt4 { m1-2 { 1F4 | E } } } exercise "Articulation" =articulation { fl5, tpt4 { m1-2 { 4C4 D E F | 1G } } } } ``` The two exercises each start locally at m1. `exercises=top` converts containers to an index and continuous timeline; `exercises=inline` converts back. Plain formatting preserves the selected arrangement. A [named range](reuse.md), such as `m1-16=primary { ... }`, is the compact way to identify music for transposed reuse. A container is useful when an exercise should be edited as its own locally numbered unit. An index describes exercise divisions over an already numbered score. Choose the organization you need instead of copying the notes into all three forms. ## Sections group exercises into a book `sections` groups exercise identities, not instrument keys. Here `band-exercises` contains `primary` and `articulation`; `flow-warm-ups` contains `divided`. ```scorescript scorescript 0.3 score "Warm-up book" { book { } numbering per-section sections { band-exercises { primary, articulation } flow-warm-ups { divided } } exercises { 1:"Primary" =primary, 3:"Articulation" =articulation, 5:"Divided" =divided } parts { fl tpt } fl5, tpt4 { m1-2 { 1F4 | E } m3-4 { 4C4 D E F | 1C } m5-6 { 1G4 | A } } } ``` `numbering per-section` gives A1, A2, B1 here. `numbering continuous` gives 1, 2, 3 across the book instead. Section names supply headings such as “Band Exercises.” The contents and exercise headings use the same numbering. The inline arrangement places `exercise` containers inside `section band-exercises { ... }`. Convert with `exercises=inline,sections=inline`; reverse with both set to `top`. Three meanings must not be confused: a book section groups exercises; an exercise's `section m1-4 { concert C }` describes a variant's range; an instrument section shares a line through [reader selection](reuse.md), such as `fl5` addressing both declared flutes. They do not use the same declaration. ## Link an exercise from another file The provisional linked-source form is: ```text exercises { exercise from "studies.scorescript" =tones } ``` The referenced file must declare `exercise =tones`. Paths are relative to the file containing the reference, not the terminal's working directory. This requires a filesystem-aware reader. A text-only compile endpoint cannot fetch an arbitrary local path. The optional `concert` override on a linked exercise is reserved in v0 and must not be relied on to transpose the pull. ## Book furniture `book { cover, contents, folios, running-heads }` opts into the named pieces of page furniture. A bare `book { }` requests all four. This is provisional and concerns exported pages: it does not create another score container. Check contents-page numbers against the actual final pagination. ```text scorescript pdf studies.scorescript --book -o studies.pdf ``` --- # Consolidation and normalization Normalization changes how existing music is represented. Choose the operation by what you want to change; “shorter source” can mean several different things. | Operation | What changes | | --- | --- | | Formatting | Canonical spelling and layout of the chosen source arrangement | | Compaction | Indentation, padding, and unnecessary blank lines | | Consolidation | Repeated musical material becomes shared readers and named returns | | Expansion | Shared music becomes separately written-out player parts | | Orientation | Parts-first versus measures-first, systems, or rehearsal groups | | Map placement | Settings or collection structure at the top versus beside the music | The source language for defining and reusing an exercise is in [named exercises and shared passages](reuse.md). The operations below can discover that structure in existing written-out music. They do not require rewriting every part by hand. ## Find the options in your installed engine ```text scorescript format --list scorescript docs normalization ``` The [normalization option reference](normalization-options.md) is generated from the native engine's menu, including presets and unavailable entries. Use the names shown by your installed engine. If an older installed CLI lacks an option, update that CLI; a `scorescript 0.3` file header alone does not establish which implementation features are installed. ### Updated option names Current builds use the shorter names below. Earlier names are refused with replacement guidance; they are not additional aliases. Update saved commands and application selections when updating the engine. This does not rename keywords inside your music or require rewriting your score files. | Earlier name | Current name | | --- | --- | | `orientation` | `arrange` | | `compression` | `preset` | | `maps-labels` | `labels` | | `maps-exercises` | `exercises` | | `maps-sections` | `sections` | | `chromatic-spelling` | `chromatic` | The measure-first choice is `arrange=measures`, formerly `orientation=grid`. `maps=top|inline` is unchanged and still covers musical context placement, not every map or every kind of layout break. ## Automatic musical consolidation ```sh scorescript check piece.scorescript scorescript format piece.scorescript --normalize consolidate > piece.review.scorescript scorescript check piece.review.scorescript ``` Review the new source and rendered parts before replacing the original. Never redirect output onto the input filename: the shell truncates it before the formatter can read it. `--write` is the explicit in-place alternative. Consolidation recognizes identical part material, constant spelled transpositions, octave-related readings, and repeated ranges that can become named transposed returns. It can produce both `fl5, ob4 { ... }` and `m17-32 = primary +P4`: actual reuse, not merely fewer line breaks. It re-analyzes the proposed music and abandons a rewrite if its musical comparison changes. This is not permission to discard a saved revision: printed layout and editorial text still need review. ### When consolidation leaves music alone - Fewer than two eligible parts: automatic discovery needs parts to share. It is not a general solo repetition finder. Manually authored named ranges still work for one reader. - Already-shared source: the current pass leaves a score with reader heads alone, including mixed source with additional written-out parts. - Measure-first source: first request `arrange=parts`. - Exercise containers: first request `exercises=top` if a flat collection is appropriate. The current pass acts on the score's own parts, not nested movement programs. Preserve movement boundaries. - Different musical material: a genuine variant stays written out; the pass does not approximate it to make it fit a shared line. - Independent voices, implicit parts, unaddressable names, or unsafe repeated instrument selection can prevent a part from joining. - Player-specific state and layout can require retaining a part block. `hoist-breaks` moves only matching per-part system/page maps to score scope; do not manually globalize one player's distinct page breaks. Read the operation notes on standard error. A successful command can report that a requested transformation was refused and leave that structure unchanged. Do not treat exit status alone as proof that consolidation happened. Comments attached to bodies that consolidation folds are removed. Comments in surviving bodies and at file level remain. This is separate from `strip-comments`, which explicitly removes all `//` comments. Keep important editorial commentary in a saved revision before folding its owning body. ## Presets and deliberate combinations ```text scorescript format piece.scorescript --normalize preset=readable scorescript format piece.scorescript --normalize preset=condensed scorescript format piece.scorescript --normalize preset=max ``` `readable` aligns columns and puts maps at the top. `condensed` also requests compact spacing, numeric durations, and matching-break hoisting. `max` adds actual consolidation and removal of recognized development text. It is **not** just a whitespace setting, and it is not a promise that every score can be reduced to one body. The generated reference lists each exact expansion. For an eligible written-out grid or exercise collection, an explicit request is: ```text scorescript format piece.scorescript --normalize arrange=parts,exercises=top,consolidate ``` Passes run in the engine's defined pipeline order, not as a left-to-right sequence of arbitrary rewrites. For repeated choices of the same option, the last written value wins, including across repeated `--normalize` flags. A preset expands where it appears, so `preset=max,align=on` restores alignment while keeping that preset's other selections. Do not select `expand` and `consolidate` together: they are opposing operations and the request is refused. Prefer one preset plus explicit overrides: a later preset does not cancel an earlier action that its own expansion does not mention. Spaces around `=` are allowed inside a quoted selection, such as `--normalize 'preset = condensed'`. A preset requires a value: bare `preset` is an error. Switches use `on` or `off`; bare `align` and `compact` mean `on`. Argumentless actions such as `strip-comments` do not take `=off` or any other value. To leave comments alone, omit the action; `strip-comments=off` is refused. ## Readability without changing musical ownership ```text scorescript format piece.scorescript --durations numbers scorescript format piece.scorescript --durations letters scorescript format piece.scorescript --compact scorescript format piece.scorescript --normalize arrange=measures,maps=top scorescript format piece.scorescript --normalize arrange=systems scorescript format piece.scorescript --normalize arrange=rehearsals ``` Choose part-first source to follow one player's line, and measure-first source to compare players at the same bars. System and rehearsal orientations group around those landmarks. Orientation changes can be refused when the current structure cannot be safely represented; inspect the operation notes. Use the native formatter for compaction. Newlines can separate measures or simultaneous voices; arbitrary whitespace removal can change or invalidate the music. Canonical compact source preserves the required boundaries. ## Maps, exercises, and book sections `maps=top|inline` controls meter, key, tempo, and transpose placement. It does **not** select inline versus mapped system/page cuts. The formatter chooses break-map emission separately; see [page and system layout](layout.md). It does not mean “convert every kind of map.” Written headings have `labels=top|inline`; exercises have `exercises=top|inline`; book sections have `sections=top|inline`. ```text scorescript format piece.scorescript --normalize exercises=inline,sections=inline scorescript format piece.scorescript --normalize exercises=top,sections=top ``` At the inline door, each exercise owns its music and starts locally at m1. At the top/index door, the timeline is numbered continuously. Book sections need exercise containers before they can hold them inline; request both inline operations together. See [collections](collections.md) for both forms. ## Implemented reuse versus reserved menu entries Named passage definitions and assignments are implemented. So is automatic `consolidate`, including its named returns inside shared heads. The separate `named-spans` normalization option is still marked coming: it is not the switch required to use existing named exercises. Likewise `octaves=minimal|explicit` is a reserved option, not an available setting. The formatter's current octave anchoring operates without that selector. For key-signature and accidental-spelling normalization, inspect the native menu's `key` and `chromatic` options and check both the sounding and written results. These change notation choices, not just visual padding. ## Expand before an independent rewrite ```text scorescript format piece.scorescript --normalize expand ``` This writes shared music out for its readers. Expansion preserves music, not the ongoing edit-once relationship: independently edited copies no longer follow a named source. Keep the shared original when that relationship matters. Use selective `scorescript expand --part ... --bars ...` for an individual player, with the whole-head override precautions in [shared passages](reuse.md). --- # Source arrangements and output views ## Choose the axis you actually want to change Source organization, musical reuse, and printed layout are separate choices. A measures-first file can print a full score or one player's pages. A parts-first file can do both as well. Neither arrangement means “Score Page” or “Parts Page.” | Choice | Forms | How to change it | Important boundary | | --- | --- | --- | --- | | Music organization | Parts-first; measures-first | `arrange=parts` or `arrange=measures` | Reorganizes code, not selected output | | Source grouping | System or rehearsal groups | `arrange=systems` or `arrange=rehearsals` | Uses existing musical/layout boundaries; may decline unsupported structure | | Repeated music | Written-out parts; shared reader heads and named returns | `consolidate`; supported `expand` operations | Actual reuse is not whitespace compression | | Musical settings | Header maps; in-place settings | `maps=top` or `maps=inline` | Meter/key/tempo/transpose, not system/page cuts | | Headings | Label maps; inline headings | `labels=top` or `labels=inline` | Keep heading identity and address | | Exercise organization | Exercise index; exercise containers | `exercises=top` or `exercises=inline` | Different from naming a reusable music span | | Book organization | Section index; section containers | `sections=top` or `sections=inline` | Book sections are not instrument sections | | Engraved breaks | Inline cuts; addressed maps/layout block | Author in the correct scope; formatter chooses compact projection | No general `maps=inline` break switch | | Duration spelling | Numeric; letter values | `durations=numbers` or `durations=letters` | `4G` and `qG` mean the same duration | | Key presentation | Open key; signature; inferred choice | `key=open`, `key=signature`, or `key=auto` | Review the selected signature; this is not transposition | | Chromatic pitch spelling | Authored spelling; directional chromatic spelling | `chromatic` | Changes enharmonic notation; inspect the musical context | | Octave spelling | Relative contour; explicit digits | Current formatter uses its built-in relative ladder | `octaves=minimal|explicit` is reserved, not an available switch | | Code spacing | Aligned/readable; compact | Alignment/compact selectors and presets | A source newline is not a printed system break | | Output selection | Combined score; extracted part | Select output part/configuration | Does not require changing source orientation | | Pitch view | Concert; written/transposed | Select the output pitch view | Not the same operation as rewriting musical pitches | | Paper and engraving | Named score/part page configurations | Optional `.layouts.json` and host layout controls | Settings refine the selected view; source cuts still apply | Text cleanup and linting are separate operations, not alternate music arrangements. `strip-comments` and `strip-dev-text` deliberately remove text; `jargon-lint` is advisory. Do not treat cleanup as lossless preservation of everything an author wrote. The standalone `named-spans` menu entry is still reserved even though `consolidate` already creates named spans inside shared heads. These are supported choices, not a promise that every combination is transformable. Check the [native option reference](normalization-options.md) for this build's availability, and read [normalization](normalization.md) for prerequisites, refusal conditions, and comment handling. ## Scope is a separate decision | Fact belongs to | Place it in | Do not confuse it with | | --- | --- | --- | | Whole score | Score-level setting or layout map | A full-score-only page configuration; global source cuts also affect parts | | One player | That part's body, or its row inside a measure block | Every player in an instrument section | | Shared passage | Shared reader head and addressed body | A detached variable that occupies no measures | | One voice | That voice's music | A setting inherited by unrelated voices | | One musical time | Its addressed measure or inline point | The physical text line containing it | | One printed view | The selected score/part layout configuration | Changing the underlying music | For paired parts-first and measures-first break examples, see [page and system layout](layout.md). For instrument sections, per-reader registers, and named exercise returns, see [shared passages](reuse.md). ## Preview normalization before applying it In Studio builds with the Normalize menu, choose the native options, preview the source changes, then apply them when the result is what you want. Optional normalization on save repeats the selected rewrite; it is not merely a display filter. Use the host's layout/view controls when you only want a different printed score or part page. From the CLI, inspect the result without overwriting your file: ```sh scorescript format piece.scorescript --normalize arrange=measures,maps=inline scorescript format piece.scorescript --normalize arrange=parts,consolidate ``` Add `--write` only when you want to replace the source. Review diagnostics and the diff, then check and render the result. Host controls depend on the installed host version; the website's native menu is not proof that an older application already exposes every option. --- # Checking, formatting, and fixing mistakes ## Read a chapter in the terminal ```text scorescript docs --list scorescript docs first-score scorescript docs connectors ``` The `docs` command prints one chapter as Markdown, without needing a network connection. It is included in builds containing this wiki; an older installed CLI may need updating. MCP readers can list the same chapters under `scorescript://docs/`, starting with `scorescript://docs/index`. ## Check the actual file ```text scorescript check piece.scorescript scorescript format piece.scorescript scorescript format piece.scorescript --write scorescript render piece.scorescript -o piece.svg scorescript pdf piece.scorescript -o piece.pdf scorescript midi piece.scorescript -o piece.mid ``` Without `--write`, formatting reports canonical source without replacing the file. Keep a saved revision before a broad edit. After formatting, check again and inspect the rendered music. MIDI output is useful for checking sounding duration and instrumentation but cannot certify printed spelling or layout. ## Read diagnostic severity An error means the requested source was not fully understood or is inconsistent. A warning can describe unfinished or ambiguous notation. Information may explain a derived rest or other normal completion. Read the code, location, and message together; do not just look for a green preview, since the engine can draw the portions it did understand. ## Common mistakes | Symptom | Check | | --- | --- | | A note is in the wrong octave | The previous pitch, apostrophe/comma, and first-note octave anchor | | A rhythm exceeds the bar | Sticky duration, dotted values, tuplet ratio, and current meter | | Eight bars of rest instead of an eighth rest | `r8` versus `8r` | | Several short slurs instead of one long slur | Mark only the opening and closing endpoint | | A chord becomes a label | Preserve its duration and use clear bracketed pitch members | | Text lands on the other side | Before the node is above; after is below for text/dynamics | | Extra silent measures | Addressed range gaps and misplaced physical row breaks | | A dynamic prints but does not sound as expected | Playback interpretation and the selected sound source | ## What formatting does It normalizes accepted duration spellings, groups measures compactly, anchors the first sounding pitch of each authored section and voice, and condenses equivalent timeline points into maps where useful. It preserves the selected sanctioned arrangement and the order of chord members. Formatting is not a substitute for choosing the right musical notes. Plain formatting is not automatic musical consolidation. The [normalization menu](normalization.md) separately controls orientation, maps, duration spelling, whitespace density, shared readers, and named reuse. ## Import and export The native reader can import MusicXML and the exporter can produce MusicXML for interchange. Check diagnostics and the full piece after a conversion; another notation program can carry constructs that this engine cannot yet represent. A successfully opened first page does not prove every part or movement survived. ```sh scorescript import source.musicxml -o piece.scorescript scorescript check piece.scorescript scorescript musicxml piece.scorescript -o roundtrip.musicxml ``` Installation, editor connections, and host APIs are covered in [integration](integration.md). Website display is covered in [embedding](embedding.md). ## Unsupported or limited notation Do not assume that arbitrary drum-kit pitch names, multi-staff `rh:`/`lh:` instruments, cue-note styling, arpeggio roll marks, or alternating two-note tremolo have a supported compact spelling. Figured bass and custom lines have the limits described in their chapters. Named bracket lines and navigation can have rendering or playback limitations. Treat a diagnostic or render report as part of the result, and verify the delivered pages and audio for the features you use. For AI-assisted writing, use this same wiki and the actual compile/format tools. Supply complete source and address the exact file, movement, part, and measures being edited. Never substitute a similar instrument or score revision because its filename looks close. --- # Normalization option reference Generated from the native formatter menu built with this wiki. Read [consolidation and normalization](normalization.md) for recipes, refusal conditions, comment handling, and the difference between compact spacing and musical reuse. Check your installed build with `scorescript format --list`. ## arrange part streams, measure systems, system breaks or rehearsal sections. | Group | Values | Availability | Default on | | --- | --- | --- | --- | | orientation | parts, measures, systems, rehearsals | Implemented | No | ## maps meter/key/tempo/transpose: header maps, or `at mN { … }` in place; system/page cuts are separate. | Group | Values | Availability | Default on | | --- | --- | --- | --- | | maps | top, inline | Implemented | No | ## hoist-breaks replace matching per-part system/page maps with ONE score-level map. | Group | Values | Availability | Default on | | --- | --- | --- | --- | | maps | Bare switch | Implemented | No | ## labels written headings as a map at the top, or on the bars they head. | Group | Values | Availability | Default on | | --- | --- | --- | --- | | maps | top, inline | Implemented | No | ## exercises the collection as a header index, or each exercise owning its music from m1. | Group | Values | Availability | Default on | | --- | --- | --- | --- | | maps | top, inline | Implemented | No | ## sections the book's sections as a map at the top, or holding their exercises. | Group | Values | Availability | Default on | | --- | --- | --- | --- | | maps | top, inline | Implemented | No | ## expand one line the rest read -> every reader's part written out (consolidate, backwards). | Group | Values | Availability | Default on | | --- | --- | --- | --- | | consolidation | Bare switch | Implemented | No | ## consolidate identical, transposed or octave-translated part bodies -> one line the rest read. | Group | Values | Availability | Default on | | --- | --- | --- | --- | | consolidation | Bare switch | Implemented | No | ## named-spans a repeated bar range written once and named. | Group | Values | Availability | Default on | | --- | --- | --- | --- | | consolidation | Bare switch | Coming | No | Not available: `consolidate` writes them inside a head; spans have no door outside one. ## durations how a duration is written: `4Eb` or `qEb`. | Group | Values | Availability | Default on | | --- | --- | --- | --- | | spelling | numbers, letters | Implemented | Yes | ## key decide the file's key spelling: no signature, or the one it implies. | Group | Values | Availability | Default on | | --- | --- | --- | --- | | spelling | open, signature, auto | Implemented | No | ## chromatic inside a chromatic run: sharps ascending, flats descending. | Group | Values | Availability | Default on | | --- | --- | --- | --- | | spelling | Bare switch | Implemented | No | ## octaves the octave digit: only where the ladder needs it, or pinned on every note. | Group | Values | Availability | Default on | | --- | --- | --- | --- | | spelling | minimal, explicit | Coming | No | Not available: the octave ladder runs unconditionally inside emit; needs a Style axis. ## preset a PRESET: one word for a whole selection (see the presets below). | Group | Values | Availability | Default on | | --- | --- | --- | --- | | compression | readable, condensed, max | Implemented | No | ## align pad grid cells so the barlines line up down the page. | Group | Values | Availability | Default on | | --- | --- | --- | --- | | compression | on, off | Implemented | Yes | ## compact no indent, no padding, no blank lines — one edit, one line. | Group | Values | Availability | Default on | | --- | --- | --- | --- | | compression | on, off | Implemented | No | ## strip-dev-text remove header text that is dev jargon, never a name or a real subtitle. | Group | Values | Availability | Default on | | --- | --- | --- | --- | | lint | Bare switch | Implemented | No | ## strip-comments remove every `//` comment, so a score can be made comment-free by the tool. | Group | Values | Availability | Default on | | --- | --- | --- | --- | | lint | Bare switch | Implemented | No | ## jargon-lint report (never rewrite) student-facing text carrying internal jargon. | Group | Values | Availability | Default on | | --- | --- | --- | --- | | lint | Bare switch | Implemented | No | ## Presets | Selector | Exact expansion | | --- | --- | | preset=readable | align=on, compact=off, maps=top | | preset=condensed | compact=on, align=off, hoist-breaks, maps=top, durations=numbers | | preset=max | compact=on, align=off, hoist-breaks, maps=top, durations=numbers, strip-dev-text, consolidate | The `named-spans` entry being marked coming does not mean named reuse is missing: `consolidate` already writes named ranges inside shared reader heads. [Write a named exercise](reuse.md). [Machine-readable menu](/reference/normalization.json) --- # Element reference Look up a spelling and follow its chapter for worked examples. These entries come from the current native element registry. Recorded limitations are shown as recorded; they are not a claim that every older limitation has been re-audited. ## node/note | Spelling | Duration of effect | Placement | | --- | --- | --- | | 4Eb | OneShot | None | Deleting it restores: the bar is that much shorter, and completes itself with rests. [Read the explanation](pitch.md) ## node/chord | Spelling | Duration of effect | Placement | | --- | --- | --- | | [Eb G Bb] | OneShot | None | Deleting it restores: the bar is that much shorter; a chord is one node, so it goes as one. [Read the explanation](chords.md) · [Read the explanation](pitch.md) ## node/rest | Spelling | Duration of effect | Placement | | --- | --- | --- | | r | OneShot | None | Deleting it restores: the silence is still there — a short bar fills itself with rests. [Read the explanation](rhythm.md) ## node/multirest | Spelling | Duration of effect | Placement | | --- | --- | --- | | r8 | OneShot | None | Deleting it restores: the bars it stood for are gone, not unpacked; a lone r is one bar. Recorded limitation: the H-bar covers the first bar while the bars it stands for still take their own width (docs/LANGUAGE-COVERAGE.md names it as an honest approximation the render report says out loud) [Read the explanation](rhythm.md) ## node/grace | Spelling | Duration of effect | Placement | | --- | --- | --- | | /8C | OneShot | None | Deleting it restores: the note it leaned on keeps its full value; a grace steals no measured time. [Read the explanation](rhythm.md) ## node/measure-repeat | Spelling | Duration of effect | Placement | | --- | --- | --- | | && | OneShot | None | Deleting it restores: the bar is empty, which reads as a bar of rest. [Read the explanation](repeats.md) ## mark/staccato | Spelling | Duration of effect | Placement | | --- | --- | --- | | (.) | OneShot | FlipsWithStem | Deleting it restores: the note is played plain; the next note was never affected anyway. [Read the explanation](marks.md) ## mark/staccatissimo | Spelling | Duration of effect | Placement | | --- | --- | --- | | (..) | OneShot | FlipsWithStem | Deleting it restores: the note is played plain. [Read the explanation](marks.md) ## mark/accent | Spelling | Duration of effect | Placement | | --- | --- | --- | | (>) | OneShot | FlipsWithStem | Deleting it restores: the note takes the dynamic in force, unaccented. [Read the explanation](marks.md) ## mark/tenuto | Spelling | Duration of effect | Placement | | --- | --- | --- | | (-) | OneShot | FlipsWithStem | Deleting it restores: the note takes its plain written length. [Read the explanation](marks.md) ## mark/marcato | Spelling | Duration of effect | Placement | | --- | --- | --- | | (^) | OneShot | FlipsWithStem | Deleting it restores: the note is played plain. [Read the explanation](marks.md) ## mark/portato | Spelling | Duration of effect | Placement | | --- | --- | --- | | (.-) | OneShot | FlipsWithStem | Deleting it restores: the note is played plain; portato is the PAIR, so deleting it drops both. [Read the explanation](marks.md) ## mark/fermata | Spelling | Duration of effect | Placement | | --- | --- | --- | | (!) | OneShot | Above | Deleting it restores: the note takes its written length and the beat keeps going. Recorded limitation: a fermata on a REST draws nothing — `paint_articulations` is reached from `paint_note` only [Read the explanation](marks.md) ## mark/trill | Spelling | Duration of effect | Placement | | --- | --- | --- | | (tr) | OneShot | Above | Deleting it restores: the note sounds once, plain. [Read the explanation](marks.md) ## mark/mordent | Spelling | Duration of effect | Placement | | --- | --- | --- | | (mord) | OneShot | Above | Deleting it restores: the note sounds once, plain. [Read the explanation](marks.md) ## mark/turn | Spelling | Duration of effect | Placement | | --- | --- | --- | | (turn) | OneShot | Above | Deleting it restores: the note sounds once, plain. [Read the explanation](marks.md) ## mark/inverted-turn | Spelling | Duration of effect | Placement | | --- | --- | --- | | (iturn) | OneShot | Above | Deleting it restores: the note sounds once, plain. [Read the explanation](marks.md) ## mark/sim | Spelling | Duration of effect | Placement | | --- | --- | --- | | (sim) | Sticky | None | Deleting it restores: every node in the run loses the copied marks and is plain again; the node that was typed once keeps its own. [Read the explanation](marks.md) ## mark/non | Spelling | Duration of effect | Placement | | --- | --- | --- | | (non) | OneShot | None | Deleting it restores: the run keeps running to the end of the line instead of stopping here. [Read the explanation](marks.md) ## mark/tremolo | Spelling | Duration of effect | Placement | | --- | --- | --- | | (trem2) | OneShot | None | Deleting it restores: the note sounds as one stroke of its written value. [Read the explanation](marks.md) ## mark/dynamic | Spelling | Duration of effect | Placement | | --- | --- | --- | | (p) | Sticky | ByPosition | Deleting it restores: the level in force before it keeps sounding. Recorded limitation: sticky in the clock only: `scorescript_perform/src/dynamics.rs` carries the level forward, while the model and the page treat a dynamic as a one-shot decoration on one event — two implementations of one law, with no shared authority [Read the explanation](marks.md) ## mark/expression | Spelling | Duration of effect | Placement | | --- | --- | --- | | (dolce) | OneShot | ByPosition | Deleting it restores: the passage is played without the instruction. [Read the explanation](marks.md) ## mark/text | Spelling | Duration of effect | Placement | | --- | --- | --- | | ("sul pont.") | OneShot | ByPosition | Deleting it restores: the passage is played without the instruction. [Read the explanation](marks.md) ## mark/tempo-text | Spelling | Duration of effect | Placement | | --- | --- | --- | | *Andante / tempo {44:,"molto rit."} | Sticky | ByPosition | Deleting it restores: the tempo in force before it stands; the words are the character, not the rate. [Read the explanation](context.md) ## mark/chord-symbol | Spelling | Duration of effect | Placement | | --- | --- | --- | | @F7 | OneShot | Above | Deleting it restores: the harmony is whatever the notes say; the letter was a reading aid. Recorded limitation: the v0.2 statement door lands an `auto` chord symbol BELOW in the model; the painter then draws it above anyway, because it never reads the side [Read the explanation](chords.md) · [Read the explanation](lyrics.md) ## mark/rehearsal | Spelling | Duration of effect | Placement | | --- | --- | --- | | RH {5, 9, 13} | OneShot | Above | Deleting it restores: the bar is an ordinary bar and the section it opened is unnamed. [Read the explanation](context.md) ## mark/rehearsal-circled | Spelling | Duration of effect | Placement | | --- | --- | --- | | (A) | OneShot | Above | Deleting it restores: the bar is an ordinary bar; the ring was the face, not the mark. [Read the explanation](context.md) ## mark/rehearsal-spoken | Spelling | Duration of effect | Placement | | --- | --- | --- | | RH A | OneShot | Above | Deleting it restores: the bar is an ordinary bar. [Read the explanation](context.md) ## mark/navigation | Spelling | Duration of effect | Placement | | --- | --- | --- | | [segno] | OneShot | Above | Deleting it restores: the piece plays straight through this point. [Read the explanation](repeats.md) ## mark/barline | Spelling | Duration of effect | Placement | | --- | --- | --- | | \|\| | OneShot | None | Deleting it restores: the bar closes with a plain single barline. [Read the explanation](repeats.md) ## mark/repeat-barline | Spelling | Duration of effect | Placement | | --- | --- | --- | | :\| | OneShot | None | Deleting it restores: the music plays once and goes on; any volta it closed loses its end. [Read the explanation](repeats.md) ## mark/lyric | Spelling | Duration of effect | Placement | | --- | --- | --- | | lyrics: | OneShot | Below | Deleting it restores: the line is vocalised or played; the notes do not move. [Read the explanation](lyrics.md) ## mark/breath | Spelling | Duration of effect | Placement | | --- | --- | --- | | (,) | OneShot | Above | Deleting it restores: the phrase runs on without a lift. [Read the explanation](marks.md) ## mark/caesura | Spelling | Duration of effect | Placement | | --- | --- | --- | | (caesura) | OneShot | Above | Deleting it restores: the phrase runs on without a break. [Read the explanation](marks.md) ## mark/sticking | Spelling | Duration of effect | Placement | | --- | --- | --- | | (R) | OneShot | Below | Deleting it restores: the note is struck with no hand named, and the player chooses. [Read the explanation](percussion.md) ## mark/figured-bass | Spelling | Duration of effect | Placement | | --- | --- | --- | | figured-bass | OneShot | None | Deleting it restores: the bass note stands alone and the harmony is the player's to read. Recorded limitation: the reader checks it and throws it away — the model seam has no figured-bass field, so nothing is drawn (the breath lane fixed the twin of this on 2026-09-01; the same shape of fix is what this row wants) [Read the explanation](lyrics.md) ## span/slur | Spelling | Duration of effect | Placement | | --- | --- | --- | | 4C~ D | OneShot | FlipsWithStem | Deleting it restores: the notes are played separately; nothing else moves. [Read the explanation](connectors.md) ## span/tie | Spelling | Duration of effect | Placement | | --- | --- | --- | | 4C~ C | OneShot | FlipsWithStem | Deleting it restores: the second note is struck again instead of held. [Read the explanation](connectors.md) ## span/hairpin-crescendo | Spelling | Duration of effect | Placement | | --- | --- | --- | | 4C< D | OneShot | Below | Deleting it restores: the level in force holds flat across the passage. Recorded limitation: an authored `above` on the statement door is stored and never read [Read the explanation](connectors.md) ## span/hairpin-diminuendo | Spelling | Duration of effect | Placement | | --- | --- | --- | | 4C> D | OneShot | Below | Deleting it restores: the level in force holds flat across the passage. Recorded limitation: an authored `above` on the statement door is stored and never read [Read the explanation](connectors.md) ## span/glissando | Spelling | Duration of effect | Placement | | --- | --- | --- | | 4C/ G | OneShot | None | Deleting it restores: the two notes are separate; the slide between them was the figure. Recorded limitation: a glissando across a system break is not drawn, and says so on the render report [Read the explanation](connectors.md) ## span/pedal | Spelling | Duration of effect | Placement | | --- | --- | --- | | [ped..] | OneShot | Below | Deleting it restores: the passage is played without the sustain pedal. [Read the explanation](connectors.md) ## span/ottava-up | Spelling | Duration of effect | Placement | | --- | --- | --- | | [8va..] | OneShot | Above | Deleting it restores: the notes print where they sound, ledger lines and all. Recorded limitation: the line moves no notes — the model already resolved the octaves — so it is ink over music that is already in the right place [Read the explanation](connectors.md) ## span/ottava-down | Spelling | Duration of effect | Placement | | --- | --- | --- | | [8vb..] | OneShot | Below | Deleting it restores: the notes print where they sound. Recorded limitation: the AUTO-CLEF octave line in `paint/staff.rs` puts a downward shift ABOVE the staff, disagreeing with this row and with the authored spelling [Read the explanation](connectors.md) ## span/trill-line | Spelling | Duration of effect | Placement | | --- | --- | --- | | [tr..] | OneShot | Above | Deleting it restores: the note sounds once and plain for its written length. Recorded limitation: the extension is dashed rather than a wiggle — Bravura's wiggle glyphs are not in the baked roster, and the render report says so [Read the explanation](connectors.md) ## span/custom-line | Spelling | Duration of effect | Placement | | --- | --- | --- | | span custom-line | OneShot | None | Deleting it restores: the passage carries no bracketed line. Recorded limitation: reaches the model through the v0.2 statement door and is not painted at all [Read the explanation](connectors.md) ## span/volta | Spelling | Duration of effect | Placement | | --- | --- | --- | | [1..] | OneShot | Above | Deleting it restores: the bars are played on every pass; there is no first or second time. Recorded limitation: the inline door makes voltas NAVIGATION words on the bar, not spans — only the v0.2 statement door builds a `SpanKind::Volta`, and that one is not drawn [Read the explanation](repeats.md) ## span/tuplet-bracket | Spelling | Duration of effect | Placement | | --- | --- | --- | | {3: 8C D E} | OneShot | FlipsWithStem | Deleting it restores: the notes take their written values and the bar no longer adds up. [Read the explanation](rhythm.md) ## span/tempo-transition | Spelling | Duration of effect | Placement | | --- | --- | --- | | [rit..] | OneShot | Above | Deleting it restores: the tempo steps rather than ramps between its two ends. [Read the explanation](connectors.md) ## state/meter | Spelling | Duration of effect | Placement | | --- | --- | --- | | [meter 3/4] | Sticky | None | Deleting it restores: the meter in force before it continues (4/4 when nothing ever said). [Read the explanation](context.md) ## state/key | Spelling | Duration of effect | Placement | | --- | --- | --- | | [key G] | Sticky | None | Deleting it restores: the signature in force before it continues (C major when nothing ever said). [Read the explanation](context.md) ## state/tempo | Spelling | Duration of effect | Placement | | --- | --- | --- | | [tempo 120] | Sticky | Above | Deleting it restores: the rate in force before it continues; with none, the clock's default. [Read the explanation](context.md) ## state/clef | Spelling | Duration of effect | Placement | | --- | --- | --- | | [clef bass] | Sticky | None | Deleting it restores: the part's own clef returns — the one it was declared with, or the instrument catalog's, or the painter's auto choice. [Read the explanation](context.md) ## state/instrument | Spelling | Duration of effect | Placement | | --- | --- | --- | | [instrument piccolo] | Sticky | Above | Deleting it restores: the player stays on the instrument the part was declared with. [Read the explanation](context.md) ## state/beams | Spelling | Duration of effect | Placement | | --- | --- | --- | | [beams 3+3+2] | DefaultRedefining | None | Deleting it restores: `[beams standard]` returns this meter to its own grouping AND forgets — which is what category three needs an explicit spelling for, since simply deleting the override leaves the memory it already made. [Read the explanation](context.md) ## state/spell | Spelling | Duration of effect | Placement | | --- | --- | --- | | spell key | Sticky | None | Deleting it restores: `spell absolute` returns: a written accidental means exactly itself. [Read the explanation](pitch.md) ## state/solfege | Spelling | Duration of effect | Placement | | --- | --- | --- | | solfege fixed | Sticky | None | Deleting it restores: movable do returns — the cores are read against the key in force. [Read the explanation](pitch.md) ## state/rehearsal-scheme | Spelling | Duration of effect | Placement | | --- | --- | --- | | rehearsal auto | Sticky | None | Deleting it restores: `rehearsal manual` returns: the marks you write are the marks you get. [Read the explanation](context.md) ## state/transpose | Spelling | Duration of effect | Placement | | --- | --- | --- | | transpose | Sticky | None | Deleting it restores: `transpose 0` returns: the bar is concert pitch again and the instrument catalog's own interval derives the page. Recorded limitation: the map spelling `transpose {0, 149:-1 -2}` is PROVISIONAL, open for Brandon's veto [Read the explanation](reuse.md) ## identity/version | Spelling | Duration of effect | Placement | | --- | --- | --- | | scorescript 0.3 | Sticky | None | Deleting it restores: a fragment, read as the current spec — which is why the container swap made the header required: the same text can mean different music in two versions. [Read the explanation](first-score.md) ## identity/title | Spelling | Duration of effect | Placement | | --- | --- | --- | | score "Title" | Sticky | None | Deleting it restores: the page prints no title and page one starts at the top margin like any other. [Read the explanation](first-score.md) ## identity/composer | Spelling | Duration of effect | Placement | | --- | --- | --- | | composer "…" | Sticky | None | Deleting it restores: the title block loses that line and closes up. [Read the explanation](first-score.md) ## identity/arranger | Spelling | Duration of effect | Placement | | --- | --- | --- | | arranger "…" | Sticky | None | Deleting it restores: the title block loses that line and closes up. [Read the explanation](first-score.md) ## identity/movement-title | Spelling | Duration of effect | Placement | | --- | --- | --- | | movement-title "…" | Sticky | None | Deleting it restores: the title block loses that line and closes up. [Read the explanation](collections.md) ## identity/part-name | Spelling | Duration of effect | Placement | | --- | --- | --- | | part fl: Flute 1 | Sticky | None | Deleting it restores: the catalog's own printed name returns, auto-numbered among its duplicates. [Read the explanation](first-score.md) ## identity/node-name | Spelling | Duration of effect | Placement | | --- | --- | --- | | 4Eb=theme | Sticky | None | Deleting it restores: the node keeps a deterministic path id, so hosts still address it — they just address it by where it is instead of by what it is called. [Read the explanation](structure.md) ## identity/measure-name | Spelling | Duration of effect | Placement | | --- | --- | --- | | m1=intro: | Sticky | None | Deleting it restores: the bar keeps its label and its ordinal; only the stable name goes. [Read the explanation](structure.md) --- # Instrument reference Use catalog keys in the roster, such as `parts { flute oboe }`, then place music under the corresponding labels: `flute { m1 { 1C5 } }`. The aliases below are catalog aliases; compact roster abbreviations such as `fl`, `ob`, and `vln` are a separate accepted vocabulary. See [parts and measures](structure.md) for counts, names, and simultaneous voices. | Key | Instrument | Aliases | Clef | | --- | --- | --- | --- | | accordion | Accordion | | Treble | | alto-flute | Alto Flute | | Treble | | alto-sax | Alto Saxophone | sax, saxophone | Treble | | alto-trombone | Alto Trombone | | Alto | | alto-voice | Alto | alto | Treble | | banjo | Banjo | | Treble | | baritone-sax | Baritone Saxophone | | Treble | | baritone-voice | Baritone | baritone | Bass | | bass-clarinet-bb | Bass Clarinet | bass-clarinet | Treble | | bass-drum | Bass Drum | | Percussion | | bass-flute | Bass Flute | | Treble | | bass-trombone | Bass Trombone | | Bass | | bass-voice | Bass | | Bass | | bassoon | Bassoon | | Bass | | celesta | Celesta | | Treble | | cello | Cello | | Bass | | chimes | Chimes | tubular-bells | Treble | | clarinet-a | A Clarinet | | Treble | | clarinet-bb | B-flat Clarinet | clarinet | Treble | | clarinet-eb | E-flat Clarinet | | Treble | | classical-guitar | Classical Guitar | guitar | Treble8vb | | contrabass-clarinet-bb | Contrabass Clarinet | contrabass-clarinet | Treble | | contrabassoon | Contrabassoon | | Bass | | cornet | Cornet | | Treble | | countertenor-voice | Countertenor | countertenor | Treble | | cymbals | Cymbals | | Percussion | | double-bass | Double Bass | contrabass | Bass | | drum-set | Drum Set | drums | Percussion | | electric-bass | Electric Bass | | Bass | | electric-guitar | Electric Guitar | | Treble8vb | | english-horn | English Horn | | Treble | | euphonium | Euphonium | | Bass | | flugelhorn | Flugelhorn | flugel | Treble | | flute | Flute | | Treble | | glockenspiel | Glockenspiel | bells | Treble | | harp | Harp | | Treble | | harpsichord | Harpsichord | | Treble | | horn-f | Horn in F | horn | Treble | | lute | Lute | | Treble8vb | | mallet-percussion | Mallet Percussion | | Treble | | mandolin | Mandolin | | Treble | | marimba | Marimba | | Treble | | mezzo-soprano-voice | Mezzo-soprano | mezzo, mezzo-soprano | Treble | | oboe | Oboe | | Treble | | organ | Organ | | Treble | | percussion | Percussion | | Percussion | | piano | Piano | | Treble | | piccolo | Piccolo | | Treble | | piccolo-trumpet | Piccolo Trumpet | | Treble | | recorder | Recorder | | Treble | | snare-drum | Snare Drum | | Percussion | | soprano-sax | Soprano Saxophone | | Treble | | soprano-voice | Soprano | soprano | Treble | | tenor-sax | Tenor Saxophone | | Treble | | tenor-trombone | Tenor Trombone | trombone | Bass | | tenor-voice | Tenor | tenor | Treble8vb | | timpani | Timpani | | Bass | | treble-voice | Treble | treble | Treble | | trumpet-bb | B-flat Trumpet | trumpet | Treble | | trumpet-c | C Trumpet | | Treble | | tuba | Tuba | | Bass | | ukulele | Ukulele | | Treble | | vibraphone | Vibraphone | | Treble | | viola | Viola | | Alto | | violin | Violin | | Treble | | voice | Voice | | Treble | | xylophone | Xylophone | | Treble | --- # Diagnostic reference Search for the exact code from your checker. Severity below is the registered default; the actual diagnostic includes its location and message. ## syntax.expected error — the parser expected a different token here ## syntax.notation error — this notation is not part of the grammar at this position ## notation.conflict error — these marks contradict each other (e.g. [p, f] or [., ..]) ## chord.quality-case-mismatch error — the root's case sits on one side of the quality axis and the explicit quality on the other (e.g. fmaj7); case carries quality ## chord.rare-quality warning — dM7 is the diminished-major seventh, an unusual chord — did you mean dm7 (half-diminished)? ## tempo.unsupported-suffix error — tempo text takes no attachment; put the period in the string (*"Andante.") or the beat unit in the tempo directive ## tempo.placement-needs-text error — the comma down-mark places tempo words below a sounding part; metronome values remain global above the staff ## hairpin.kind-mismatch error — a crescendo was closed by a diminuendo marker (or vice versa); both endpoints carry the kind ## spanner.unterminated warning — a span opened but never closed; a hairpin with nothing to arrive at stays one note wide, where you typed it (close it with a leading < or > , or a dynamic, to say how far it reaches), and a slur or glissando with no note to reach draws nothing ## spanner.stop-without-start error — a closing span marker with no opening in effect ## slur.adjacent-spans info — notes are nodes and one slur is one span between endpoint nodes; interior notes stay unmarked (D~ E ~F), while D~ E~ F spells two slurs ## version.header-required error — from the container swap onward a source must declare its spec version — the same text can mean different music in different versions (/h) ## syntax.unexpected error — this token cannot start anything the grammar knows at this position ## syntax.incomplete error — the source ended (or the line ended) before this construct was finished ## syntax.pitch error — a pitch is an uppercase letter A–G, an optional accidental, then an optional octave number (Eb, F#5); r is a rest ## syntax.anchor error — an anchor is a measure label and an offset: m1:0, m2:q, m3:1/2 ## version.invalid error — the header is `scorescript` followed by a version like 0.3 ## repeat.invalid-target error — a measure repeat repeats the previous bar (%) or a labeled earlier bar (%m5); there must be one ## repeat.mixed-content error — a repeat bar holds nothing else: && (or %) IS the bar's content, so a note beside it would be a second bar's worth of music in one bar ## chord.empty error — a chord needs at least one pitch between [ and ] ## pitch.invalid error — this is not a pitch: letters A–G (uppercase — case carries quality, never octave), accidentals b bb # ##, then an optional octave number ## spanner.detached warning — a connector binds by adjacency: Eb< opens a crescendo on Eb, , the slash bass ## chord-symbol.conflicting-bass error — a chord symbol names at most one bass pitch ## chord-symbol.empty-display error — an explicit chord-symbol spelling replaces the generated one, so it cannot be empty ## tie.pitch-mismatch error — a tie joins the SAME written pitch; ~ between different pitches is a slur, which is what you want here ## tie.no-common-pitch error — a tie between chords needs at least one written pitch present in both ## tie.partial-pitch-mismatch error — a tied chord member must exist in the next chord; a tie that lands on nothing is not engravable ## tie.missing-endpoint error — a tie needs a pitched note immediately after it to arrive at ## tie.conflicting-scope error — tie the whole event (tie-next) or single chord members ([Eb~ G]), never both — the two scopes contradict each other ## tie.invalid-endpoint error — a tie statement names two pitched notes that exist in this part ## tie.double-connector-no-pitch warning — a trailing ~~ says BOTH things at once — tie forward and open a slur (4C~~ C D ~E) — so its tie half needs the very next node to repeat the written pitch; with no repeat there is nothing to tie and the second ~ quietly spells a second slur instead. Write one ~ for the slur alone, or repeat the pitch to tie ## tie.connector-run-too-long warning — a node trails one ~ (a tie when the next node repeats the pitch, a slur otherwise) or two (~~ — tie forward AND open a slur); there is deliberately no third form, so every ~ past the second says nothing ## tie.not-adjacent info — a tie says two notes are ONE SOUND, so it only ever joins ADJACENT notes of the same pitch; X~ … ~X with anything in between is a slur across all of them, however the endpoints are spelled (N34) — if two ties were meant, the pitch has to repeat on the very next note ## range.above-practical info — the catalog's practical range is the band a DEVELOPING player can be counted on for, and this note is above it; one strong player will have it and a section will not, which is worth knowing now rather than at the first rehearsal — the instrument's full range is stated separately, and this note is still inside it ## range.below-practical info — the bottom of a range is where tone and intonation go first, and this note is below the band a DEVELOPING player owns; the note is on the instrument — the section playing it will simply be quiet, flat and late ## range.outside-professional warning — this note is outside the instrument's range as the orchestration literature states it — not merely hard but very likely not there at all for whoever is handed the part; ranges are stated in WRITTEN pitch, so a transposing part is judged by what its player reads and not by what it sounds ## hairpin.unterminated warning — an inline cresc/dim ends at the next node carrying a dynamic; without one it has no printed length ## transition.stop-without-start warning — [...] is the last dash of a tempo transition's dashed line, so it needs an earlier [rit..], [rall..] or [accel..] to end; with none open it prints nothing ## transition.overlapping warning — one tempo transition is in force at a time: a second [rit..]/[accel..] closes the one already running where it stands, exactly as a tempo event would — write [...] where you meant the first to end ## expressive.invalid-symbol error — a stable identifier names the expression so edits elsewhere keep pointing at it ## expressive.duplicate-symbol error — each expression in a part carries its own name ## expressive.invalid-placement error — placement is above, below, or auto ## expressive.unknown-measure error — an anchor names a bar this part declares ## expressive.invalid-offset error — an anchor offset is a position inside the bar: 0, a note value (q), or an exact N/M ## dynamic.invalid-mark error — dynamics are pppp…ffff plus fp, sfz, sf, sfp, fz, rfz and n ## text.invalid-role error — a text role is tempo, rehearsal, technique, staff, or system — the role decides how it is engraved ## text.empty error — a text expression prints something; an empty one is invisible ## breath.invalid-symbol error — a breath is `breath` (comma) or `caesura` (railroad tracks) ## breath.always-above warning — a breath is drawn above the stave, so `below` cannot move it ## figured-bass.invalid-figures error — figured bass is a non-empty comma-separated list of figures ## lyric.invalid-target error — a lyric syllable attaches to a pitched note; rests are not sung ## lyric.invalid-verse error — lyric verses are numbered from 1 ## lyric.invalid-syllabic error — a syllable is single, begin, middle, or end — this is what draws the hyphens between syllables ## lyric.unknown-option error — lyric options are extender (the melisma line) and elision ## lyric.duplicate-verse error — a note carries one syllable per verse; a second one would print on top of the first ## lyric.duplicate-option error — a lyric states each option once ## lyric.empty error — an empty syllable prints nothing; delete it instead ## sticking.grace-spelling error — a grace stroke is written with the language's grace slash (/R L is a flam), because r is already the rest letter and the slot law refuses a second meaning for it ## sticking.pitched-part error — R and L are hands, and they stand where a note stands only on an unpitched part; on a pitched one the sticking is a mark after the note (4C(R)), which is the side that prints below ## sticking.duplicate error — a note is struck by one hand, so it carries one sticking; a second would print on top of the first ## sticking.unknown-rudiment error — an exercise applies a rudiment by naming a declared one, so a name the score's dictionary does not hold says nothing about which hands the notes take ## sticking.pattern-mismatch info — a rudiment's strokes are laid under the attacks in order and restart when they run out, so a count that is not a whole number of times through leaves the last pass cut short — and a flam or a roll in the pattern wants a grace stroke or the same roll mark in the music ## staff-lines.invalid error — a staff has one to five lines — five is the standard staff and one is the unpitched percussion line ## span.invalid-kind error — span kinds are slur, hairpin, pedal, ottava, volta, glissando, trill-line, custom-line and tuplet-bracket ## span.invalid-range error — a span ends at or after where it starts ## span.unknown-option error — each span kind has its own options; this one is not among them ## span.conflicting-options error — these options contradict each other (a hairpin grows or shrinks, never both) ## span.duplicate-option error — a span states each option once ## span.empty-text error — a labelled span prints its label, so the label cannot be empty ## volta.empty-text error — a volta prints its ending numbers and label; an empty label leaves the bracket blank ## tuplet.invalid-ratio error — a tuplet plays at least 2 notes in the time of 1 or more (3:2, 5:4) ## tuplet.too-few-events error — a tuplet groups at least two events; one note in the time of another is just a different duration ## tuplet.unknown-option error — tuplet options are bracket-auto/show/hide and number-ratio/actual/none ## tuplet.conflicting-options error — a tuplet states its bracket once and its number once ## tuplet.duplicate-symbol error — a tuplet name addresses one group; two groups with one name make that address ambiguous ## tuplet.invalid-symbol error — a stable name is a letter or _ then letters, digits, _ and - ## transform.source-has-errors error — a transform rewrites text it fully understood — the formatter's own contract; fix the errors and the same command will run ## transform.unnamed-rows error — a grid row belongs to a DECLARED part; rows the parser had to name for itself ("row 2") have no braced form to become, and inventing one would print a name on a staff nobody wrote — declare the parts, or label the rows ## transform.score-spine error — a block head's spine states a fact about a SCORE POINT — a double bar, a rehearsal mark, a key change — not about a player, which is why it stands outside the rows; part-first has no shared head to carry it, so a score with a spine keeps the block road (`m1-8 { … }`), where the head still exists ## transform.part-statements error — a grid row holds bars; a transpose, a span, a lyric, a part-level clef or an `at` block that changes more than the clef has no cell to print in, so that part keeps its braced form ## transform.bar-head error — a grid cell prints its bar's music alone — navigation words (a repeat, an ending, a jump) and a stable bar name live on a labelled measure line, which a row has no room for ## transform.bar-count error — a grid is a rectangle and a re-woven part is a replacement: every row spans the same bars, and an edited part hands back exactly the bars it was given — adding or removing one is a change to the SCORE ## transform.group-label error — rows past a group label's parts are those parts' further voices, taken in turn — so a part with more than one voice needs a label that names it ALONE; give it a printed name nothing else answers to ## transform.woven-context error — a direction written inside another player's bar has a beat, and this part's bar has different notes in it; move it to the bar's head, where every part can read it at the same moment ## transform.part-not-found error — a part is addressed by its PRINTED name ("Flute 1") or by an instrument key that names only one part; `scorescript parts` lists what this score answers to ## transform.part-ambiguous error — an instrument key that names several parts cannot pick one of them; the printed name disambiguates it ## transform.not-one-part error — `part put` takes the file `part get` made — one part — because it re-weaves that part into the score it came from, and a whole score has nothing to weave into ## transform.voices-changed error — a part's voice rows are its staff layout, not its notes; `part put` replaces bars one for one, so adding or dropping a voice is a change to the SCORE and belongs there ## transform.meter-changed error — a bar line cannot move for one player: the meter belongs to the score, so a part whose bars are measured differently is describing different music ## transform.context-changed error — the key and the tempo are the conductor's; a part file CARRIES them so the player can read them, but changing one there would silently rewrite every other part — change it in the score ## import.malformed error — the file is not well-formed XML, so nothing in it can be trusted to mean what it looks like; the position given is where the document stopped making sense ## import.not-musicxml error — the importer reads score-partwise MusicXML — the root element every notation program exports by default; score-timewise and other XML dialects are a different grammar ## import.archive error — a .mxl is a bounded zip container whose META-INF/container.xml names one primary MusicXML score; malformed, ambiguous, encrypted, unsafe, or expansion-heavy archives are refused before importing ## import.size error — the imported score expands beyond the host's bounded MusicXML limit; reduce or split the source rather than letting one document exhaust the process ## import.encoding error — MusicXML and every text entry in an .mxl container are UTF-8; replacing invalid bytes would silently change names or notation, so the importer refuses instead ## import.empty warning — the file parsed but holds no music — no parts, or parts with no measures; an importer that returned an empty score would look like it worked ## import.unsupported warning — this element has no home in ScoreScript, so it did not come across; it is named rather than dropped in silence, because a file that is quietly smaller than it was is worse than one that says what it lost ## import.lossy info — this came across, but not exactly as it was written — a spelling the language has no glyph for, a span drawn a different way, a value rounded; the music is there and the notation moved --- # CLI reference The command list below is emitted by the native CLI built with this wiki. Start with `check`, use `format` to inspect canonical text, and add `--write` only when you want to save it. ```text scorescript — the ScoreScript toolchain USAGE scorescript docs [|--list] scorescript import [-o ] scorescript musicxml [-o ] [--movement ] [--concert] scorescript check [--severity error|warning|info] [--format text|json] [--delta ] scorescript format [--write] [--durations numbers|letters] [--no-align] [--compact] [--normalize [,...]] scorescript format --list scorescript render [-o ] [--movement ] [--staff-space ] [--width ] [--transposed] [--layout ] scorescript pdf [-o ] [--page letter|a4] [--part ] [--concert|--transposed] [--book] [--movement ] [--layout ] [--save-layout ] scorescript parts scorescript layouts scorescript geometry [--flowing] [--systems] scorescript to-grid [-o ] [--by measures|systems|rehearsals] scorescript to-parts [-o ] scorescript part get "" [-o ] scorescript part put "" [--write] scorescript expand --part "" --bars [-] [--write] scorescript midi [-o ] [--movement ] scorescript play [--movement ] scorescript jam [--loop m9-16] [--part ] [--mute ] [--program [=]] [--movement ] [--soundfont ] [--audio-driver ] [--render ] [--for ] [--dry-run] [--tick ] [--view code|score|none] [--score] [--gfx kitty|braille|blocks|none] scorescript view [--port ] [--no-open] scorescript install-desktop [--uninstall] scorescript lsp COMMANDS docs read a wiki chapter offline as Markdown; --list prints chapter names. Uses the same teaching documents as the website and MCP resources. import read MusicXML and print the canonical ScoreScript it becomes (stdout when no -o). Everything the language cannot hold is a diagnostic on stderr, named and counted. Compressed .mxl follows META-INF/container.xml and is opened with bounded decompression. musicxml write uncompressed MusicXML 4.0 (stdout when no -o) — the door out, so a score is never hostage to this toolchain. Each part is written at the pitch its player READS, with a saying how to reach concert; --concert writes the sounding score with no transposition instead. A two-staff piano is ONE part with two staves, as the format means it. Anything that cannot make the crossing is named on stderr as `not exported: …`, never dropped. check print diagnostics as file:line:col: severity[code]: message — teaches (exit 1 when any of them is an error). --severity prints that tier and everything more serious, and --severity error skips the layout-borne alignment check, so it is parse + analyze only. --format json prints one object per line — severity, code, message, file, line, column, part, bar, range — with no teaching prose and a trailing {"summary"} line. --delta prints only what a previous --format json run did not have, keyed on (code, part, bar, message) so an edit that shifts lines reports nothing. format print the canonical spelling; --write rewrites the file in place. A source with errors is left untouched and its errors are printed. The three skin flags re-spell the same music without changing it: --durations letters writes q e h w s t instead of 4 8 2 1 16 32, --no-align stops padding the grid's columns, and --compact drops the indentation and the blank lines as well. Every skin re-reads as the same score, and every one of them is idempotent. --normalize runs named passes from the normalization menu on top of the canonical form (hoist-breaks, key=open, chromatic, strip-dev-text, jargon-lint …); what each pass did is reported on stderr as file:line:col. `format --list` prints the whole menu. render write a self-contained SVG, one long page (stdout when no -o). pdf write a paginated PDF (stdout when no -o). --part prints one player's part, laid out for that part alone AND transposed to the pitch that player reads; it still carries the tempo, the rehearsal marks and the repeats, wherever they were written. Nothing is embedded: notation is vector outlines and words use the standard PDF faces. parts print the parts' printed names, one per line — what --part accepts. layouts print this score's layout configurations, one per line, from the sidecar beside it (.layouts.json). A score with no sidecar prints the built-in configuration and how to write one. `*` marks the one a viewer opens on. geometry print where every event landed on the printed pages, one per line: id, page (1-based), then x y w h in that page's own coordinates — one unit per staff space, the origin at the top-left of the sheet. The pages are the ones `pdf` prints and the ids are the ones `play` sounds, so this is the map a click, a selection and a playhead are built from. --flowing measures the OTHER layout instead — the one tall picture `render` draws — because the two put a note in different places. --systems prints the system bands rather than the events: system, page, x y w h, and how many events the band holds, which is the vertical extent a playhead spans and the region a click resolves into. to-grid print the same program as editable measure blocks: one row per part. --by measures uses compact structural ranges, --by systems follows authored \n / \p cuts, and --by rehearsals follows rehearsal sections. Each is one formatting of the same score. to-parts print the same program part-first: one `Part { … }` group each, with compact `mN-M { … }` ranges that can span mapped changes. Both directions are checked by analysing before and after — the music may not move. part get print ONE part as a score of its own, carrying the tempo, the key changes, the rehearsal marks and the repeats that were written on other players' lines. Edit that file, then: part put re-weave the edited part into the score and print the result (--write rewrites the score). It moves NOTES: a different bar count, meter, key or tempo is refused by name, never reconciled. expand print the ScoreScript one player would carry if they wrote a shared line's bars out themselves — the head's music with their interval and register applied, as the block that overrides it (--write splices it in). A head is taken WHOLE, because a part that writes one of its bars stops reading all of them, so the bars it covers are usually more than were asked for; the whole-document form is `format --normalize expand`. midi write a Standard MIDI File (stdout when no -o). play say what the performance contains, and how to hear it. There is no audio engine in this toolchain, by design — `jam` sequences an external one rather than becoming one. jam the live session: loop a bar range and keep playing while you write. On every save the file is recompiled; a clean save is swapped in AT THE NEXT BARLINE without the clock stopping, and a broken one prints its diagnostics and keeps the last good take sounding. A typo never causes silence. --loop takes a bar range (m9-16); --part solos and --mute excludes, both repeatable, so 'play me just the strings' is one flag. Sound is fluidsynth's, driven over a pipe on our clock; --dry-run prints the loop and starts nothing. While it plays the terminal shows YOUR SOURCE, and the notes light up in it as they sound — the loop's lines, with the currently sounding events in reverse video. It is pure ANSI, so every terminal gets it. --view score instead engraves the loop's bars and sweeps a playhead over real notation (kitty graphics where the terminal has them, braille cells everywhere else; --gfx forces a tier), and --view none draws neither. view open the file as a living page: real sheets on a dark desk, a Play button, and a redraw within half a second of ANY editor saving the file. A local server on 127.0.0.1, GET only; stop it with Ctrl-C or by visiting /quit. install-desktop register the file type with the desktop, so a double-click opens the viewer: writes ~/.local/share/mime/packages (the MIME type text/x-scorescript for *.scorescript, *.ss and *.score) and ~/.local/share/applications (the launcher), and nothing else. --uninstall removes exactly those two files. lsp speak the Language Server Protocol over stdio. OPTIONS -w, --write format / part put: rewrite the file instead of printing --durations format: numbers (default, canonical) or letters --no-align format: leave the grid's cells unpadded --compact format: no indentation, no padding, no blank lines -o, --output render/pdf/midi/to-grid/to-parts/part get: write here instead of stdout --movement render/pdf/midi/play: select one authored movement --by to-grid: measures, systems, or rehearsals --staff-space render: pixels per staff space (default 8) --width render: the width systems wrap inside, in pixels --page pdf: letter (default) or a4, 0.75in margins --part pdf: one part, by printed name ("Flute 1") or by instrument key when it names only one part --transposed render/pdf: the transposed-score view — every part at the pitch its player reads. The text is concert pitch, so a score is concert unless you ask. --concert pdf: keep concert pitch, even for --part --layout render/pdf: draw this score the way the named configuration says — paper, margins, staff size, spacing, the engraving flags, concert or written, and its part if it has one. It IS the page decision, so it is refused alongside the flags it would overrule. `scorescript layouts ` lists them. --save-layout pdf: store this command line as a configuration in the sidecar, creating it if there is none — the other knobs start at the engine's defaults, and the file is yours to edit. The PDF is still printed. -p, --port view: listen here (default 4321; a port in use moves to the next free one) --no-open view: print the URL instead of opening a browser --uninstall install-desktop: remove the two files it wrote -h, --help print this -V, --version print the tool and spec versions ``` Read [checking and fixing mistakes](checking.md) for the normal workflow. --- # Read with an agent Fetch only the chapter relevant to the musical task. The Markdown links below carry the same explanations and source examples as these pages, without navigation or rendered SVG. - [Compact discovery index](/llms.txt) - [Chapter index](/docs/index.md) - [Element lookup](/reference/elements.json) - [Diagnostic lookup](/reference/diagnostics.json) - [Instrument lookup](/reference/instruments.json) - [Complete text, when needed](/llms-full.txt) ## An efficient writing loop 1. Read the task's chapter and look up unfamiliar instrument keys or marks. 2. Write complete `scorescript 0.3` source, or explicitly request a fragment. 3. Compile with the native CLI or `compile_score`. Resolve errors and read warnings. 4. Format, compile again, and inspect the rendered music. 5. For edits, preserve the actual file, movement, part, and measure scope. Use `update_score` with a newer revision for an existing MCP document. Retrieve long source in bounded `read_score` ranges. A successful preview alone does not establish complete export or playback. --- # Install and use in other tools | Setup | Interface | What it provides | | --- | --- | --- | | Terminal or build pipeline | Native `scorescript` CLI | Check, format, import, and export files | | Personal website | SVG/PDF, or browser WASM | Static notation, or local interactive rendering | | Node or Electron | Generated Node WASM package | A reusable compiled document | | Code editor | `scorescript lsp` | Language-server integration | | Agent client | `scorescript-mcp` | Native tools and reference resources | The source-build instructions below require authorized access to the ScoreScript repository. They do not require a public npm or crates.io package. This documentation does not provide a verified public package-install route; do not assume an identically named registry package is this engine. ## Install the command-line tool Prerequisites: an authorized checkout, Rust/Cargo compatible with that checkout, and the platform's Rust build tools. From the repository root: ```sh cargo install --locked --path crates/scorescript_cli --no-default-features scorescript --help scorescript docs --list ``` Cargo installs the binary into its configured bin directory; that directory must be on `PATH`. Omit `--no-default-features` if the terminal-score picture feature is wanted. The smaller build still checks, formats, renders SVG, and exports PDF and MIDI. Installing the CLI does not install the Studio desktop app. ```sh scorescript check piece.scorescript scorescript render piece.scorescript -o piece.svg scorescript pdf piece.scorescript -o piece.pdf scorescript midi piece.scorescript -o piece.mid ``` For an automated build, stop when `check` exits nonzero. Preserve diagnostics; a renderer can draw partial output even when source has errors. Pin the engine revision used by a build so upgrading it is a deliberate change. ## Node and Electron Prerequisites: the checkout, Rust/Cargo, `wasm-pack`, and Node. From the repository root, build the Node-target package: ```sh bash crates/scorescript_wasm/build.sh node ``` This creates `crates/scorescript_wasm/pkg-node/` and runs its packaged-runtime smoke check. Copy the whole generated package into your application's `vendor/scorescript/` directory. Keep its JavaScript and WASM from the same build. Save this example as `render.cjs` in your application root: ```js const { readFileSync, writeFileSync } = require("node:fs"); const { CompiledDocument } = require("./vendor/scorescript/scorescript.js"); const score = new CompiledDocument(readFileSync("piece.scorescript", "utf8")); try { const diagnostics = JSON.parse(score.diagnostics_json()); if (diagnostics.length) console.error(diagnostics); if (diagnostics.some(d => d.severity === "error")) { throw new Error("ScoreScript source contains errors"); } writeFileSync("piece.svg", score.render_svg(JSON.stringify({ width_px: 800 }))); } finally { score.free(); } ``` Run `node render.cjs`. The Node build uses CommonJS and needs no asynchronous initialization. The browser build uses ES modules and does require initialization; the two generated packages are not interchangeable. For an editor, retain one `CompiledDocument` per open file and call `update(source)` when its text changes. Then read diagnostics, notation, and performance from that same document. Call `free()` when closing it. In Electron, keep filesystem access behind the application's existing trusted host boundary; do not enable Node access in an untrusted page to run this example. ## Document API The generated type declarations (`scorescript.d.ts`) describe the exact API of your build. JSON-returning methods return strings; decode them with `JSON.parse`. Option arguments are JSON strings, not JavaScript objects. | Method | Result | | --- | --- | | `update(source)` | Compile changed text; unchanged text keeps the same revision | | `revision()` | Current revision as a decimal string | | `diagnostics_json()` | Codes, severity, messages, and source ranges | | `render_svg(optionsJson)` | Flowing SVG; options include `width_px` and `foreground` | | `render_pages_json(optionsJson)` | Paginated SVG sheets and a layout report | | `event_geometry_json(optionsJson)` | Event boxes and system positions for hit testing | | `performance_json()` | Notes and timing data, not audio output | | `performance_json_for(movement)` | Performance for an authored movement ID | | `format()` | Canonical source text; it does not save the file | | `free()` | Release the document when it is no longer used | Use the option shape belonging to the output method; flowing and paginated layout options are not interchangeable. `parse_json()` exposes the parsed structure, not a substitute for checking semantic diagnostics. ## Code editors and Markdown pipelines Configure an editor's language-server client to launch `scorescript lsp` over stdio for `.scorescript` files. Syntax highlighting and preview UI are separate editor integrations; launching the server does not add those automatically. A Markdown fence tagged `scorescript` is source text, not a universal embed standard. A Markdown site needs a build plugin or browser component that sends that fence to the native CLI or WASM engine. The simplest pipeline renders an SVG during the site build and replaces the fence with an image and source link. See [website embedding](embedding.md) for both approaches. ## Agent clients Build the native stdio server from the repository root: ```sh cargo install --locked --path hosts/chatgpt-mcp ``` Set the client's MCP server command to the installed `scorescript-mcp` binary, with no arguments, using that client's configuration format. Client setup and support for previews or attachments vary; a stdio process is not a public HTTP endpoint. The server exposes `compile_score`, `update_score`, `format_score`, `read_score`, `render_score`, `export_score_file`, and `import_musicxml`. Read `scorescript://docs/index` first, then the specific chapter resource, such as `scorescript://docs/structure`. These are the same authored chapters available through `scorescript docs` and this website. For an existing document, use `update_score` with an increasing revision. The server returns artifacts for the client to save; it does not accept an arbitrary path and write into the client's filesystem. Ordinary terminal file work can use the CLI directly without an MCP round trip. --- # Embed on a website | Requirement | Use | | --- | --- | | Display a finished score on any static site | Exported SVG, with optional PDF/source downloads | | Let visitors change source and redraw | Self-hosted browser WASM and a small component | | Publish a copy of the documentation | [Self-host this wiki](self-hosting.md) | Neither notation approach needs a ScoreScript account or a rendering server at page-view time. Browser rendering is an engine interface, not a prebuilt drop-in Studio application or a sound player. ## Static notation With the [CLI installed](integration.md), render during your site build: ```sh scorescript check piece.scorescript scorescript render piece.scorescript -o piece.svg scorescript pdf piece.scorescript -o piece.pdf ``` Put the generated files and the source in your site's `music/` directory. In an HTML page: ```html ``` The SVG contains the notation glyphs; no music-font download is needed. Use a meaningful description for the actual piece. Editing the source does not change an already uploaded SVG: rerun the build and redeploy the outputs. An ordinary Markdown image link to the SVG works when the host permits SVG. ## Interactive browser rendering This path requires authorized repository access and permission to redistribute the engine. Build the web package from the repository root with Rust/Cargo and `wasm-pack` installed: ```sh bash crates/scorescript_wasm/build.sh web ``` Copy the generated `crates/scorescript_wasm/pkg/` directory into your website as `vendor/scorescript/`. Copy the package, including its JavaScript, WASM, and notices; do not mix files from different builds. ```text site/ index.html score.js piece.scorescript vendor/scorescript/ scorescript.js scorescript_bg.wasm ...generated package files ``` `index.html`: ```html ScoreScript notation

Notation generated from the source above


```

`score.js`:

```js
import init, { CompiledDocument } from "./vendor/scorescript/scorescript.js";

const source = document.querySelector("#source");
const status = document.querySelector("#status");
const notation = document.querySelector("#notation");
const button = document.querySelector("#render");
let score;
let imageUrl;

function clearImage() {
  notation.removeAttribute("src");
  if (imageUrl) URL.revokeObjectURL(imageUrl);
  imageUrl = undefined;
}

function render() {
  try {
    score.update(source.value);
    const diagnostics = JSON.parse(score.diagnostics_json());
    status.textContent = diagnostics.map(d => `${d.severity}: ${d.message}`).join("\n");
    clearImage();
    if (diagnostics.some(d => d.severity === "error")) return;
    const svg = score.render_svg(JSON.stringify({ width_px: 800, foreground: "#111" }));
    imageUrl = URL.createObjectURL(new Blob([svg], { type: "image/svg+xml" }));
    notation.src = imageUrl;
    if (!diagnostics.length) status.textContent = "Rendered.";
  } catch (error) {
    clearImage();
    status.textContent = String(error);
  }
}

try {
  await init();
  const response = await fetch("./piece.scorescript");
  if (!response.ok) throw new Error(`Source download failed: ${response.status}`);
  source.value = await response.text();
  score = new CompiledDocument(source.value);
  button.addEventListener("click", render);
  button.disabled = false;
  render();
} catch (error) {
  status.textContent = String(error);
}

window.addEventListener("pagehide", event => {
  if (event.persisted) return;
  clearImage();
  score?.free();
}, { once: false });
```

Supply a valid `piece.scorescript`, for example the complete [file syntax](first-score.md)
example. Serve the directory over HTTP(S), not by opening `index.html` as a
`file:` URL. The initial page loads the local JS, WASM, and score; subsequent
render clicks compile in the visitor's browser without uploading their text.
This example does not save edits; add explicit save/download controls if needed.

## Hosting requirements and boundaries

- Serve `.wasm` as `application/wasm` and JavaScript with a JavaScript MIME type.
- If your site sets Content Security Policy, allow its own modules and fetches,
  WebAssembly compilation (`'wasm-unsafe-eval'` in `script-src` where required),
  and `blob:` in `img-src` for this example. Do not disable the site's policy.
- Render generated SVG as an image, as above. Do not insert user source or
  arbitrary uploaded SVG into the page with `innerHTML`.
- For large or untrusted input, impose size/time limits and move compilation to
  a terminable Web Worker. The minimal example is for bounded scores, not an
  unrestricted public compilation service.
- Keep the editable source; SVG and PDF are outputs. Do not edit SVG to change
  the musical document.

Browser requirements are documented in MDN's [WebAssembly streaming reference](https://developer.mozilla.org/en-US/docs/WebAssembly/Reference/JavaScript_interface/instantiateStreaming_static)
and [script-src policy reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/script-src).

`render_svg` produces flowing notation. `render_pages_json` provides paginated
SVG and a report. `performance_json` provides note/timing data; your application
must supply its own audio engine. It does not start playback by itself.

## Updates and distribution

Pin a tested engine revision and replace the generated package as one unit
when upgrading. Rerun representative scores and inspect their diagnostics and
output. Hosting this wiki does not install the browser engine, and publishing
the wiki does not publish an npm package.

The renderer embeds font assets. The current package build does not copy all
font license files automatically: include the applicable notices from
`crates/scorescript_render/assets/*/OFL.txt` with any distribution.
Repository access alone does not establish permission to redistribute private
source or engine artifacts. Confirm the applicable distribution terms before
uploading those artifacts publicly.


---

# Self-host this wiki

This builds the reference website, not an interactive ScoreScript editor.
For notation on an existing site, see [embedding](embedding.md).

## Build

Prerequisites: authorized repository access, Rust/Cargo, and Node with the
built-in test runner. From the repository root:

```sh
npm --prefix website run build
```

The build reads the authored Markdown in `docs/wiki/`, validates every
ScoreScript example with the native engine, and generates reference tables
from that engine. It also checks local links and the published artifact set.
A failed check stops the build; publish only a successful build's output.

Output goes to `website/dist/`. That directory contains HTML, CSS, JavaScript,
notation SVGs, example downloads, Markdown chapters, and machine-readable
reference files. No runtime database or Rust installation is needed on the
web server.

## Publish

Upload **only `website/dist/`** to a static host. Do not upload the repository,
private documents, build caches, or credentials. Use a dedicated domain or
subdomain: the current site has root-relative `/docs/`, `/examples/`, and asset
paths, so uploading unchanged beneath `/some/subdirectory/` is not supported.

The generated `_headers` and `_redirects` files are hosting metadata. Hosts
that do not understand them need equivalent configuration, including security
headers and the documented redirects. Check a chapter URL directly, not just
navigation from the home page.

The discovery index uses `https://scorescript.org` as its canonical origin.
For an independent mirror, change that origin in `website/scripts/build.mjs`
to your own domain before building. Do not use a global text replacement on
all documentation: external reference links may intentionally point elsewhere.

## Update from code

Edit the relevant `docs/wiki/*.md` file, run the same build, then publish the
new `dist/`. A native language change regenerates the tables and rechecks the
examples on the next build. It cannot automatically write a correct explanation
of a changed language rule; that prose must be reviewed alongside the code.

The CLI and MCP embed the authored Markdown at compilation time. Rebuild those
binaries to pick up chapter edits; deploying the website alone does not update
an already installed CLI or agent server.

A source-control deployment can run this build whenever relevant code or
Markdown changes. Keep publication behind the successful checks, and retain
the previous deployed artifact for rollback. A filesystem watcher by itself
is not a deployment pipeline.

Before making a public mirror, confirm permission to publish the selected
documentation and artifacts. Access to a private checkout is not a public
redistribution license.
Flute melody in C major
PDF ScoreScript source