01
Scores
A score is one printout: it plays the file's unnamed form — or the one its
form NAME item names — on a set of rows. It is a vertical stack of
bands: what a row means comes from where it sits.
score {
chords prog // a chord row above ...
staff melody "Melody" // ... the staff it belongs to
lyrics words // ... and that staff's verse below it
}
| Item | Row it draws |
|---|---|
staff NAME | a notation staff for that part |
staff NAME "Label" | …with a printed name |
staff CLEF NAME | …on another clef: staff bass melody prints the melody in the bass clef. A clef word that is also a part's name reads as the part (LYS1046 says how to write either) |
staff NAME as lines N | …with N staff lines (1–5). as lines 1 is a rhythm staff |
staff NAME as removeEmpty true | …hidden in systems where it only rests (all: in the first system too) |
staff NAME as pitch transposed | …a transposing part in its player's key (concert: as it sounds), whatever the score's pitch — see Transposing instruments |
tab NAME | tablature — see below |
chords NAME | a chord row |
lyrics NAME | a lyric row |
ossia NAME | a small alternative staff |
NAME (bare) | played to MIDI only, never engraved — a click track, a cue part |
staff chords lyrics (no name) | the file's unnamed part { }, chords { } or lyrics { } |
form NAME | not a row: the form this score plays, instead of the unnamed one (form { … }: a form of its own) |
title "…", fonts { … }, layout NAME | not rows: this score's own header, faces and display switches, over the file's |
title / composer | restate the file's metadata for this score alone |
paper NAME / fonts NAME / layout NAME | use a named block for this score |
A staff's display name is always a quoted string, so a bare word after
staff NAME is always another score item — staff flute click is
flute's staff plus the MIDI-only click part. Position never changes what a
word means.
A score's name is optional and a bare word, like a part's. The unnamed
score { … } is the file's default: it writes song.svg and the
preview shows it first, listed as (Default). score parts { … } writes
song-parts.svg and is parts in the preview and in
lysc --score. A quoted name (score "parts") is an error that names
the word to write.
A book that has music needs at least one score: sections with no score is an
error, and the editor's quick fix adds one with a staff for every part.
Grouping staves
| Group | Left edge | Barlines between staves | For |
|---|---|---|---|
grandStaff | brace | drawn through | one instrument on two staves |
staffGroup | bracket | drawn through | one family |
choirStaff | bracket | not drawn through | independent voices |
staffGroup reverses the word order on purpose — it is not a slip for
groupStaff: the other …Staff items each produce a staff, while a
staff group produces a group of staves.
Two more put several parts on one staff, and take bare part names:
condensedStaff { fl1 fl2 } gives each part its own voice of a single staff;
combinedStaff { fl1 fl2 } merges them the way an orchestral score condenses
two players — unisons become one notehead marked a2, different notes in the
same rhythm within a ninth become one voice of chords, a lone part is marked
Solo. The chord case is the usual outcome, not a corner; use
condensedStaff when the lines must stay visibly separate. A condensed staff
takes one key, one meter and one clef at a moment: a time both parts write is
drawn once, and a later part's change that differs from the first part's at the same
moment is not applied and warns — write the same change in every part.
Because these are score items, one source prints both the condensed score and the separate parts:
score full { condensedStaff { fl1 fl2 } }
score parts { staff fl1 staff fl2 }
02
Tablature
Give a part a tuning and render it with tab:
part gt { clef treble_8 tuning guitar }
score {
staff gt // the notation
tab gt // the tablature under it
}
A tab standing beside a staff prints fret numbers only — the staff above it
already carries the meter, stems, beams, rests and ties. A tab on its own carries the
meter, stems, rests and ties itself (beams are not drawn yet). That is the default;
say which you want with
tab gt as numbers or tab gt as full.
\N pins a note to string N when the automatic choice is not the one your
fingers want: c'\2. Technique letters (@tap @hammerOn @pullOff
@pluck(i)) print on the tab, because they are ink a guitarist reads there.
A note below the lowest string shows on the staff only, and the editor warns. A bass
reads an octave above what it sounds, so its lowest string is the written E2: begin a bass
part at octave 2 (part bs { clef bass octave 2 tuning bass }) and
its e is that string.
Fret numbers are set in the regular weight; fonts { tab bold } brings the
bold face back, and fonts { tab size 3 } makes them a little larger (the
default is 2.8). A word after tab that names a declared part is that part —
tab bass click is part bass's tab plus the MIDI-only
click, as after a staff; for a tuning over a part that shares a
tuning word's name, write the synonym: tab bass4 click.
Chord diagrams over the staff, and chord(C x32013) — a chord written as a
fretboard shape, which the tab then shows string for string — are on
Chords and chord diagrams.
03
Paper and fonts
Both are optional blocks whose defaults equal LilyPond's, so an absent block changes nothing. Both can also be named at the top level and referenced (or partly overridden) per score.
paper {
size b5 // width, height AND scaled margins, by name
paperWidth 210mm // bare numbers are staff spaces; units are GLUED
paperHeight 0 // 0 = one content-driven page
leftMargin 15mm rightMargin 15mm topMargin 10mm bottomMargin 10mm
indent 15mm shortIndent 0
raggedRight // a bare flag: do not justify
raggedBottom // a bare flag: every page keeps its natural spacing
spacingIncrement 1.2
systemSystemSpacing { basicDistance 12 minimumDistance 8 padding 1 stretchability 60 }
}
The staff-spacing family lives here, not in override. Unknown keys are an
error; a key set twice warns and the last wins. size takes LilyPond's paper
names, bare and lower case (a4, b5, letter —
size A4 is refused), plus jisb5, the Japanese B5 that ISO
b5 is not.
fonts {
serif "Georgia" // the two generic families together are
sans "Verdana" // "the whole document's text"
lyrics "Charis SIL" "Noto Serif CJK JP" // several names = a fallback chain
tempo "Playfair Display" // one role beats the group it belongs to
title "Cormorant" size 3.8 bold // a face, an absolute size, a weight; or step +1, a LilyPond font-size step
embedded // subset the named faces into the PDF
}
Keys are a generic family, a group, or a single role, and the narrower spelling
wins in either source order. Groups map to roles as: header → title, composer,
instrument · lyrics → the syllables (no key of their own), stanza ·
chords → chord, diagram, figuredBass · marks → tempo, mark,
pedal, navigation, text, dynamics, partCombineText · numbers → barNumbers,
finger, tuplet, volta, ottava, bend, tabTechnique · notation → clefOctave,
time, tab. A key is spelled as the source writes what it styles (@chord →
chord, time 6/8 → time, a tab staff →
tab); a key with no single source word names the family (pedal,
dynamics) or the printed text (stanza, volta).
The keyword is fonts, plural, and it takes a block — there is
no font keyword and no one-line form. A named face is measured as well
as drawn, so naming one that a machine lacks makes the page machine-dependent; a missing
face warns rather than passing quietly.
The music font
The glyphs — noteheads, clefs, rests, accidentals, dynamics — come from the
music entry. Without one the page is drawn in Emmentaler, LilyPond's own
font. Bravura, Petaluma and Leland, three
SMuFL fonts, ship with Lily#; any other
SMuFL font installed where the specification puts its metadata is found too, and so is one in
a folder named by the VS Code setting lilysharp.fontPaths or the environment variable
LILYSHARP_FONT_PATH — a score names a font, never a file, so it opens the same on
every machine.
fonts { music "Leland" } // the whole file in Leland
fonts { music "Petaluma" "Bravura" } // a fallback chain, glyph by glyph
score sketch { fonts { music "Petaluma" } staff melody } // one score only
The font is not only a different drawing: its own sizes and line thicknesses — staff
lines, stems, ledger lines, beams, bar lines — are used too, unless a layout { }
entry or --set says otherwise. Each glyph comes from the first named font that
has it; one that none has (Leland has no figured-bass digits, for one) is drawn in
Emmentaler and warns once. Dynamics are the font's own p, f,
sfz… glyphs. Chord symbols take the font's ♭ ♯ △ ° ø glyphs, and under Petaluma the
page's text — chord letters, titles, tempo, marks, instrument names, everything but the lyrics
— is set in Petaluma Script, the handwritten face shipped beside it, unless a
fonts key names a face for it. music takes quoted names only; a
glyph's size is its grob's (layout { NoteHead.scale 1.2 }). From the command
line, lysc svg --set music=Leland song.lys lays a font over the file's. The
LilyPond export stays in Emmentaler, since LilyPond reads no SMuFL font, and says so.
04
Layout — display switches
layout { } holds the score-wide switches that pick one of a few drawings.
Like paper and fonts, one unnamed block is the file's default and
a named one is referenced by a score (layout chart, or
layout chart { barNumbers none } to override part of it there).
layout {
markTempo stacked // the default: LilyPond's arrangement
barNumbers lines // the default: a number at the start of every line but the first
accidentals default // the default: the 18th-century rule
sectionLabels boxed // the default: the section's name in a frame
partCombineText true // the default: a combinedStaff prints a2 / Solo
chordQualities symbols // the default: C°, C+, Cø, C°7
minorChords upper // the default: Am, Am7
voltaBracket all // the default: an ending's bracket covers all of it
}
layout chart { markTempo beside barNumbers every 4 chordQualities words }
score { staff melody } // the file's default
score parts { layout chart staff melody } // this score's own
| Key | Values | Chooses |
|---|---|---|
markTempo | stacked · beside | a section label and a metronome mark at the same bar: stacked, or on one line (“[Chorus] ♩ = 132”) |
barNumbers | lines · none · every N | which bars carry a number: each line's first, none, or every Nth bar wherever it stands |
accidentals | default · modern · modernCautionary · forget · noReset | LilyPond's accidental styles for a staff |
sectionLabels | boxed · plain · none | how a form section's name is drawn — framed, bare, or not at all (a part sheet) |
partCombineText | true · false | whether a combinedStaff prints a2 / Solo |
chordQualities | symbols · words | C° C+ Cø C°7, or Cdim Caug Cm7♭5 Cdim7 |
minorChords | upper · lower | Am, or a lowercase root with no m (a) |
chordDiagrams | a tuning word · none, then optionally capo N, all, { a shape table } | which instrument chord diagrams are drawn for, a capo, whether every chord draws one, and which listed chords draw — see Chords and chord diagrams |
chordNames | shape · sounding · both | under a capo, whether a chord name is the pressed chord's, the sounding chord's, or both (“E♭m7 (Cm7)”) — see A capo |
chordList | true · false | whether the chords the score uses are drawn at its head, each over its diagram — see The chord list |
voltaBracket | all · line · N | how far a repeat ending's bracket reaches: all of the ending, to the end of its first line, or its first N bars (cut short, it ends straight); one ending overrides it with [1. B]@voltaBracket(…) — see Forms |
Keys and values are case-sensitive (barnumbers is refused with “write
'barNumbers'”), an unknown key is an error, and a key set twice warns. None of them is a
reserved word. markTempo was called marks before; the old key is
refused.
05
Override / revert
override NoteHead.color = red c4 d e f | revert NoteHead.color once override Stem.transparent = true // 'once' applies to the next note only c4 d e f |
The syntax accepts any Grob.property, but the vocabulary is deliberately
four properties: NoteHead.transparent, Stem.transparent,
NoteHead.color, Stem.color. Anything outside that list is
refused with a message listing what is supported, rather than silently doing nothing. The
list grows, and each addition removes one error.
Grob names are PascalCase and properties are lisp-case; both are case-sensitive.
Show the whole file
// The override vocabulary is four properties. `once` applies to the next note only,
// and `revert` puts the default back.
time 4/4
part melody { clef treble }
section A {
melody {
override NoteHead.color = red
c4 d e f |
revert NoteHead.color
once override Stem.transparent = true
g4 a b c |
}
}
form { ~A }
score { staff melody }