Lily# Reference — look-up: reserved words, diagnostics, LilyPond

01

Reserved words

section form using tab ossia transpose octave pitch instrument percussion drummap
score part staff grandStaff staffGroup choirStaff condensedStaff combinedStaff
voice phrase repeat break noBreak pageBreak noPageBreak partial cue embedded fonts paper layout
title subtitle composer poet tempo time key clef
major minor ionian dorian phrygian lydian mixolydian aeolian locrian
treble bass alto tenor treble_8 bass_8 soprano mezzosoprano baritone
tuplet grace acciaccatura appoggiatura lyrics chords tuning
override revert once
segno fine coda dc ds al to
ppp pp p mp mf ff fff

Most of them may still name a part or a section — only the structural words are refused (see Parts). A phrase name is narrower, because a phrase is played bare in the music: an identifier, the four clef words treble bass alto tenor, or a dynamic word (phrase p { … }, played by a bare p); any other keyword is refused at the declaration. Single letters a–g are pitches and r/R/s are rests — note that f is a pitch, while @f still works because dynamics resolve from the annotation's text. q, chord and the drum names are reserved in music only: a phrase cannot be named them, a part can. Articulation, ornament and mark names are not reserved at all; they resolve from the @name text, so they stay free for your own identifiers.

02

Diagnostics

Lily# would rather refuse than quietly do the wrong thing, and its messages are written to be acted on. A few worth knowing, quoted as the compiler prints them:

You wroteIt says
c4 g. a4This '.' belongs to nothing. A duration dot needs a number in front of it - write g4., not g. …
c4.5'4.5' is not a duration - a duration is a whole number (c4, c8), lengthened by dots…
<c e g2>A chord member can't carry a duration - members share one, written after the closing '>': <c e g>2. …
4 g f e opening a part's musicA bare duration repeats the previous note, chord or slash - and nothing repeatable comes before this one…
c4 d e f :|':|' is a repeat, so it belongs in the form, not in the music…
repeat volta 2 { … }'repeat volta' is LilyPond's spelling. In Lily# a repeat is written in the form…
|: A [1. B] :|*3 [2. C]A repeat with endings takes its passes from the endings' numbers: remove '*3' and number every pass instead — the pass an ending plays on is the number it prints: three passes, the first two on B, are '|: A [1-2. B] :| [3. C]'.
[1.3. B]An ending's passes are separated by ',' or '-', not by points: write '[1,3.' for passes 1 and 3, or '[1-3.' for the range. The bracket prints the points itself.
@text("say \^")'\^' is not an escape sequence. A string follows C#'s escapes (\" \\ \n \t \uXXXX …); write '\\' for a backslash, or use a verbatim string @"…", which takes a backslash as written.
\relative { … }Lily# is relative by default — drop '\relative …'; switch modes with 'octave absolute'.
clef TrebleUnknown clef 'Treble'. clef names are case-sensitive; known: alto, baritone, bass, …
fonts "Georgia"fonts binds a face per text role, so it takes a block…
paperWidth 210 mmmm is a unit, and a unit is spelled glued to its number: 210mm, one word.
override Beam.thickness = 2'Beam.thickness' is not supported in this version of Lily# — this 'override' would change nothing. Supported: NoteHead.color, NoteHead.transparent, Stem.color, Stem.transparent. …
c4@rit d e f (never closed)a text spanner is never closed, so neither its word nor its line is drawn; write '@!rit' (or '@!textSpan') on the note it should reach…
c4~ d4the note after a tie '~' does not repeat the tied pitch; a tie joins two notes of the same pitch - use a slur '( )' to connect different pitches
a slur crossing a cue edgea slur cannot cross a cue boundary…
c4@upbowUnknown annotation '@upbow' — it is ignored. Names are case-sensitive: write '@upBow'.
c( || ending a section, nothing closing it in the nexta slur '(' is carried from section C into section D, which follows it in the form, and is not closed there, so no slur is drawn; close it with ')' in section D…
@chord(C x02210)'x02210' sounds A C E, which is Am, not C (A is not a tone of C) - write @chord(Am x02210) or another shape.
r1@chord@chord on a rest has no notes to name a chord from, so nothing is drawn; write the name, e.g. @chord(C).

Warnings are for things that are legal but probably not what you meant; errors are for things with no defensible reading.

03

Coming from LilyPond

Lily#'s engraving engine is a port of LilyPond's, but the language is deliberately not LilyPond's. LilyPond's backslash commands are rejected outright, with a message naming the Lily# spelling.

LilyPondLily#
\relative c' { … }relative is the default; or octave absolute
\new Staff, \new Voicepart declarations and score rows
<< … \\ … >>voice { … } { … }
<< … >> (parallel)in Lily# this spelling is a written-out arpeggio
\repeat volta 2 { … }form { |: A :| }
\alternative[1. B] :| [2. C] in the form
c4\staccato, c4-.c4@staccato
c:maj7, fis:m7.5-Cmaj7, F#m7-5 — the printed symbol, with +/- for an altered tension
\fret-diagram-terse, FretBoards@chord(C x32010), @diagram(x32010), C(x32010) in a chord row — see Chords and chord diagrams
\repeatTie after a voltanothing: a tie into a repeat or an ending is written as a tie, and the repeat tie is drawn for you
q (no marks)q, and q' to repeat the chord an octave up
\versionnothing; there is no version pragma
\includeusing "other.lys"

Chord entry is the sharpest difference and the one most worth knowing: LilyPond asks you to encode a chord, Lily# asks you to type it as it prints.

04

Rough edges

Measured against Lily# 0.12.0 while this page was built. These are real and current; they are listed here rather than smoothed over.

One typo can still produce three diagnostics. c4@bend.half reports the stray dot, then @bend missing its argument, then an undefined variable half. The middle line now names the fix — @bend(half) — but the other two remain.

Collapsing them means letting the parser eat the .half, and the obvious rule for that (an argument-taking name followed by a dot) is wrong: @ottava.bassa is a legitimate dotted name, and ottava is in the same vocabulary. The correct test is whether the whole dotted name is known, and that lives downstream.

lysc ly cannot express a displaced q. LilyPond's q takes no octave marks, and wrapping it in \transpose does not work either: LilyPond expands chord repetitions after transposition, so the wrapper moves an empty placeholder and the expansion then fills in the untransposed pitches (measured against 2.26.0 — it compiles and changes nothing). The twin writes a plain q and warns; write the chord out by hand if the twin must match.

A chart that is nothing but a rhythm staff opens with a small gap. A one-line staff draws no clef, but the room for one is reserved per score rather than per staff, so a score with no other staff to fill it leaves the space empty. In a multi-staff score the reservation is right and nothing shows.

Documented gaps that are known and tracked: cross-staff beam layout and a LilyPond-to-Lily# converter. The long tail of specialist notation — early music, microtonal, clusters, ambitus — is deliberately out of scope.