LilyPond
The music typesetter
Extending
The LilyPond development team
ā˜›
āœŸ
This ļ¬le explains how to extend the functionality of LilyPond version 2.23.82.
āœ” āœ 
ā˜›
āœŸ
For more information about how this manual ļ¬ts with the other documentation, or to read this
manual i n ot he r f orm at s, see S ec t i on ā€œManualsā€ in General Information.
If you are missing any manuals, the complete documentation can be found at
https://lilypond.org/.
āœ” āœ 
Copyright
c
āƒ 2004ā€“2022 by the authors.
Permission is granted to copy, distribute and/or modify this document under the
terms of the GNU Free Documentation License , Version 1.1 or any later version
published by the Free Software Foundation; with no Invariant Sections. A copy of
the license is included in the section entitled ā€œGNU Free Documentation Licenseā€.
For Lil y Pond version 2.23.82
i
Table of Contents
1 Scheme tutorial. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1 Introduction to Scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1.1 Scheme sandbox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1.2 Scheme variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1.3 Scheme simple data types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.4 Scheme compound data types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Pairs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Lists. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Association lists (alists) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Hash t ab l es . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.5 Calculations in Scheme. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.6 Scheme procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Deļ¬ning procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Predicates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Return values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.1.7 Scheme conditionals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
cond . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2 Scheme in LilyPond. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2.1 LilyPond Scheme syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2.2 LilyPond variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2.3 Debugging Scheme code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2.4 Input variables and Scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2.5 Importing Scheme in LilyPond . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.2.6 Object properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.2.7 LilyPond compound variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Oļ¬€sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Fractions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Extents. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Property alists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Alist chains . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.2.8 Internal music representation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.3 Building complicated functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.3.1 Displaying music expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.3.2 Music properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.3.3 Doubling a note with slurs (example). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.3.4 Adding articulation to notes (example) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2 Interfaces for pro gr am me rs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.1 LilyPond code blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.2 Scheme functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.2.1 Scheme function deļ¬nitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.2.2 Scheme function usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.2.3 Void scheme functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.3 Music functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.3.1 Music function deļ¬nitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.3.2 Music function usage. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.3.3 Simple substitution functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
ii
2.3.4 Intermediate substitution functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.3.5 Mathematics in functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.3.6 Functions without arguments. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.3.7 Void music functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.4 Event functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.5 Markup functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.5.1 Markup construction in Scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.5.2 How mar k u ps work internally . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.5.3 New markup command deļ¬nition. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Markup command deļ¬nition syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
On properties. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
A comp l et e exam pl e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Adapting builtin commands. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Converting markups to strings
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
2.5.4 New markup list command deļ¬nition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.6 Contexts for programmers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.6.1 Context evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.6.2 Running a function on all layout objects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.7 Callback functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.8 Unpure-pure containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
2.9 Diļ¬ƒcult tweaks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3 LilyPond Scheme inter f a ces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Appendix A GNU Free Documentation License . . . . . . . . . . . . . . 42
Appendix B LilyPond index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
1
1 Scheme tutorial
LilyPond uses the Scheme programming lan gu age, both as part of the input syntax, and as inter-
nal mechanism to glue modules of the program together. This section is a very brief overview of
entering data in Scheme. If you want to know more about Scheme, see https://www.schemers
.org.
LilyPond uses the GNU Guile implementation of Scheme, which is based on the Scheme
ā€œR5RSā€ stan dar d . If you are learning Scheme to use with LilyPond, working with a diļ¬€erent
implementation (or referring to a diļ¬€erent standard) is not recommended. Information on guile
can be found at https://www.gnu.org/software/guile/. The ā€œR5RSā€ Scheme standard is
located at https://www.schemers.org/Documents/Standards/R5RS/.
1.1 Introduction to Scheme
We begin with an introduction to Scheme. For this brief introduction, we will use the GUILE
interpreter to explore how the lan guage works. Once we are familiar with Scheme, we will show
how the lan gu age can be integrated in Lily Pond ļ¬les.
1.1.1 Scheme sandbox
The LilyPond installation includes the Guile implementation of Scheme. A hands-on Scheme
sandbox wi t h all of Li l y Pond loaded is availab l e with th is command line:
lilypond scheme-sandbox
Once the sandbox is running, you will receive a guile prompt:
guile>
You can enter S cheme expressions at this prompt to experiment with Scheme. If you want
to be able to use the GNU readl i ne library for nic er editing of the Scheme command line, check
the ļ¬le ly/scheme-sandbox.ly for more information. If you already have enabled the readline
library for your interactive Guile sessions outside of LilyPond, this should work in the sandbox
as well.
1.1.2 Scheme variables
Scheme variables can have any vali d scheme value, including a Scheme procedure.
Scheme variables are created with
define
:
guile> (define a 2)
guile>
Scheme variables can be e valu at ed at the gui l e prom pt si m pl y by typing the variable name:
guile> a
2
guile>
Scheme variables can be p r inted on the displ ay by using the display function:
guile> (display a)
2guile>
Note that both the value 2 and t h e guile prompt guile showed up on the same line. Th i s can
be avoided by calling the newli n e proced ur e or disp l aying a newline character.
guile> (display a)(newline)
2
guile> (display a)(display "\n")
2
guile>
Chapter 1: Scheme tutorial 2
Once a var iab l e has been created , its value can be changed with set!:
guile> (set! a 12345)
guile> a
12345
guile>
1.1.3 Scheme simple data ty pes
The most basic concept in a language is data typing: numbers, character strings, lists, etc. Here
is a li st of simple Scheme data types that are often used with LilyPond.
Booleans Boolean values ar e Tru e or False. The Scheme for True is #t and False is #f.
Numbers Numbers are entered in the standard fashion, 1 is the (integer) number one, while
-1.5 i s a ļ¬‚oatin g point number (a non-integer number).
Strings Strings are enclosed in double quotes:
"this is a string"
Strings may span several lines:
"this
is
a string"
and the newline characters at the end of each line will be included in the string.
Newline characters can also be added by including \n in the string.
"this\nis a\nmultiline string"
Quotation marks and backslashes are added to strings by preceding them with a
backslash. The string \a said "b" is entered as
"\\a said \"b\""
There are additional Scheme data types that are not discussed here. For a complete list-
ing see the Guile reference guide, https://www.gnu.org/software/guile/docs/docs-1.8/
guile-ref/Simple-Data-Types.html.
1.1.4 Scheme compound data types
There are also compound data types in Scheme. The types commonly used in LilyPond pro-
gramming include pairs, lists, alists, and hash tables.
Pairs
The foundational compound data type of Scheme is the pair. As m ight be expected from its
name, a p ai r is two values glued toget he r. The operator used to form a pair is called cons.
guile> (cons 4 5)
(4 . 5)
guile>
Note that t he pair is d i sp l ayed as two items surrounded by parenthese s and separated by
whitespace, a period (.), and more whi t es pac e. Th e period is not a decimal point, but rather
an i nd i cat or of t h e pair .
Pairs can al s o be entered as literal values by preceding the m wit h a sin gle qu ot e character.
guile> '(4 . 5)
(4 . 5)
guile>
The two ele ments of a pair may be any valid Scheme value:
guile> (cons #t #f)
Chapter 1: Scheme tutorial 3
(#t . #f)
guile> '("blah-blah" . 3.1415926535)
("blah-blah" . 3.1415926535)
guile>
The ļ¬rst and second elements of the pair can be accessed by the Scheme procedures car and
cdr, r es pect i vely.
guile> (define mypair (cons 123 "hello there")
... )
guile> (car mypair)
123
guile> (cdr mypair)
"hello there"
guile>
Note:
cdr
is pronounced
"
could-er
"
, according Sussman and Abelson, see
https://
mitpress.mit.edu/sites/default/files/sicp/full-text/book/book-Z-H-14.html#
footnote_Temp_133
Lists
A ver y common Scheme data structure is the lis t. Formally, a ā€˜properā€™ list is deļ¬ned to be either
the empty list with its input form '() and length 0, or a pair whose cdr in t ur n is a shorte r list.
There are many ways of creating lists. Perhaps the most common is with the list procedure:
guile> (list 1 2 3 "abc" 17.5)
(1 2 3 "abc" 17.5)
Representing a list as individual elements separated by whitespace and enclosed in parenthe-
ses is actually a compacted rendition of the actual dotted pairs consti t ut i n g the list, where the
dot and an immediately following starting paren are removed along with t he matching closing
paren. Without this compaction, the output would have been
(1 . (2 . (3 . ("abc" . (17.5 . ())))))
As with the output , a list can also be entered (after adding a quote to avoid interpretation
as a func t i on call ) as a literal list by enclosing its elements in parentheses:
guile> '(17 23 "foo" "bar" "bazzle")
(17 23 "foo" "bar" "bazzle")
Lists are a central part of Scheme. In, fact, Scheme is considered a dialect of lisp, where ā€˜lispā€™
is an ab br ev i at i on for ā€˜ Li st P rocess i ngā€™ . Scheme expressions are all lists.
Association lists (alists)
A special type of list is an association list or alist. An alist is used to store data for easy retrieval.
Alists are lists whose elements are pairs. T he car of each element i s called the key, and the
cdr of each element is called the value. The Scheme pro ce du re assoc is used to retrieve an entry
from the alist, and cdr is used to retrieve the value:
guile> (define my-alist '((1 . "A") (2 . "B") (3 . "C")))
guile> my-alist
((1 . "A") (2 . "B") (3 . "C"))
guile> (assoc 2 my-alist)
(2 . "B")
guile> (cdr (assoc 2 my-alist))
"B"
guile>
Alists are widely used in LilyPond to store properties and other data.
Chapter 1: Scheme tutorial 4
Hash tables
A data structure that is used occasionally in LilyPond. A hash table is similar to an array, but
the indexes to the array can be any type of Scheme value, not just integers.
Hash tables are more eļ¬ƒcient than alists if there is a lot of data to store and the data changes
very infrequently.
The syntax to create hash tables is a bit complex , but you can see examples of it in the
LilyPond source.
guile> (define h (make-hash-table 10))
guile> h
#<hash-table 0/31>
guile> (hashq-set! h 'key1 "val1")
"val1"
guile> (hashq-set! h 'key2 "val2")
"val2"
guile> (hashq-set! h 3 "val3")
"val3"
Values ar e r et r ie ved from hash tables wit h hashq-ref.
guile> (hashq-ref h 3)
"val3"
guile> (hashq-ref h 'key2)
"val2"
guile>
Keys and values are retrieved as a pair with hashq-get-handle. This is a preferred way,
because it will return #f if a key is not found.
guile> (hashq-get-handle h 'key1)
(key1 . "val1")
guile> (hashq-get-handle h 'frob)
#f
guile>
1.1.5 Calculations in Scheme
Scheme can be used to do cal cu lat i on s. It uses preļ¬x syntax. Adding 1 and 2 is written as (+
1 2) rat he r th an th e trad i t ion al 1 + 2.
guile> (+ 1 2)
3
Calculations may be nes t ed ; t h e resu l t of a func t i on may be used for another calcul at ion .
guile> (+ 1 (* 3 4))
13
These calculations are examples of evaluations; an expression like (* 3 4) is replaced by its
value 12.
Scheme calculations are sensitive to the diļ¬€erences between integers and non-i ntegers. Integer
calculations are exact, while non-integers are calculated to the appropriate limits of pr ec i si on:
guile> (/ 7 3)
7/3
guile> (/ 7.0 3.0)
2.33333333333333
When the scheme interpreter encounters an expression that is a list, the ļ¬rs t e l eme nt of the
list is treated as a procedure to be evaluated with the arguments of t he remainder of the list.
Therefore, all operators in Scheme are preļ¬x operators.
Chapter 1: Scheme tutorial 5
If the ļ¬rst element of a Scheme expressi on that is a list passed to th e interpreter is not an
operator or procedure, an error will occur:
guile> (1 2 3)
Backtrace:
In current input:
52: 0* [1 2 3]
<unnamed port>:52:1: In expression (1 2 3):
<unnamed port>:52:1: Wrong type to apply: 1
ABORT: (misc-error)
guile>
Here you can see that the interpreter was trying to treat 1 as an operator or procedure, and
it couldnā€™t. Hence the error is "Wrong type to apply: 1".
Therefore, to create a list we need to use the list operator, or to quote the lis t so that the
interpreter will not try to evaluate it.
guile> (list 1 2 3)
(1 2 3)
guile> '(1 2 3)
(1 2 3)
guile>
This is an error that can appear as you ar e working with Scheme in LilyPond.
1.1.6 Scheme procedures
Scheme procedures are executable scheme expressions that return a value result i ng from their
execution. They can also manipulate variables deļ¬ned outside of the proced ur e.
Deļ¬ning procedures
Procedures are deļ¬ned in Scheme with deļ¬ne
(define (function-name arg1 arg2 ... argn)
scheme-expression-that-gives-a-return-value)
For exam pl e, we could deļ¬ne a procedure to c alc ul at e th e average:
guile> (define (average x y) (/ (+ x y) 2))
guile> average
#<procedure average (x y)>
Once a procedure is deļ¬ned, it is called by putting the proc ed ur e name and the arguments
in a li s t . For example, we can calculate the average of 3 and 12:
guile> (average 3 12)
15/2
Predicates
Scheme procedures that return boolean values are often called predicates. By convention (but
not necessity), predicate names typically end in a question mark:
guile> (define (less-than-ten? x) (< x 10))
guile> (less-than-ten? 9)
#t
guile> (less-than-ten? 15)
#f
Chapter 1: Scheme tutorial 6
Return values
Scheme procedures always return a return value, which is the value of the last expression executed
in the procedure. The return value can be any valid Scheme value, including a complex data
structure or a procedure.
Sometimes the user would like to have multiple Scheme expressions in a procedu r e. There are
two ways that multiple e x pr es si on s can be combined. The ļ¬rst is the begin procedure, which
allows multiple e x pr es si on s to be evaluated, and ret u rn s t h e value of the last ex p re ss ion .
guile> (begin (+ 1 2) (- 5 8) (* 2 2))
4
The second way to combine multiple expressions is in a let block. In a let block, a series
of bindings are created, and then a sequence of expressions that can include those bindings is
evaluated. The return value of the let block is the return value of the last statement in the let
block:
guile> (let ((x 2) (y 3) (z 4)) (display (+ x y)) (display (- z 4))
... (+ (* x y) (/ z x)))
508
1.1.7 Scheme conditionals
if
Scheme has an if p r ocedure :
(if test-expression true-expression false-expression)
test-expression is an expression that returns a boolean value. If test-expression retu r ns #t,
the if procedure returns the value of true-expression, otherwise it returns the value of false-
expression.
guile> (define a 3)
guile> (define b 5)
guile> (if (> a b) "a is greater than b" "a is not greater than b")
"a is not greater than b"
cond
Another conditional procedure in scheme is cond:
(cond (test-expression-1 result-expression-sequence-1)
(test-expression-2 result-expression-sequence-2)
...
(test-expression-n result-expression-sequence-n))
For exam pl e:
guile> (define a 6)
guile> (define b 8)
guile> (cond ((< a b) "a is less than b")
... ((= a b) "a equals b")
... ((> a b) "a is greater than b"))
"a is less than b"
1.2 Scheme in LilyPond
1.2.1 LilyPond Scheme syntax
The Guil e interpreter is part of LilyPond, which means that Scheme can be included i n LilyPond
input ļ¬les. There are several methods for including Scheme in LilyPond.
Chapter 1: Scheme tutorial 7
The simplest way is to use a hash mark # before a Scheme expression.
Now LilyPondā€™s input is structured into tokens and expressions, much like human language
is structured into words and sentences. LilyPond has a lex er that recognizes tokens (literal
numbers, strings, Scheme elements, pitches and so on), and a parser that understands the
syntax, Section ā€œLilyPond grammarā€ in Contributorā€™s Guide. Once it knows that a parti cu l ar
syntax rule applies, it executes actions associated with it.
The hash mark # method of embedding Scheme is a natur al ļ¬t for this system. Once the
lexer sees a hash mark, it calls the Scheme reader to read one full Scheme expression (this can be
an identiļ¬er, an expression enclosed in parentheses, or several other things). After t h e Scheme
expression is read, it is stored away as the value for an SCM_TOKEN in the grammar. Once the
parser knows how to make use of this token, it calls Guile for evaluating the Scheme expression.
Since the parser usually requir es a bit of lookahead from the lexer to make its parsin g decisions,
this separati on of reading and evaluation between lexer and parser is exactly what is needed to
keep the execution of LilyPond and Scheme expressions in sync. For this reason, you should use
the hash mark # for calling Scheme whenever this is feasible.
Another way to cal l the Scheme interpreter from LilyPond i s the use of dollar $ instead of a
hash mark for intr oducin g Scheme expressions. In this case, LilyPond evaluates the code right
after the lexer has read it . It checks the re su lt i n g type of the Scheme expression and then picks
a token type ( on e of several xxx_IDENTIFIER in the s y ntax) for it. It creates a copy of the value
and uses that for the value of the token. If the valu e of the expression is voi d (Guileā€™s value of
*unspecified*), nothing at all is passed to the parser.
This is, in fact, exactly the same mechanism that LilyPond employs when you call any variab le
or music function by name, as \name, with the only diļ¬€erence that the name is determined by the
LilyPond lexe r without consulting the Scheme reader, and thus only variable names consistent
with the current LilyPond m ode are acce pt e d.
The immediate action of $ can lead to surprises, see Section 1.2.5 [ Import i n g Scheme in
LilyPond], page 9. Using # wh er e the parser supports it is usually preferable. Inside of music
expressions, expressions created using # are interpreted as music. However, they are not copied
before use. If they are part of some structure that might still get used, you may need to use
ly:music-deep-copy ex p li c it l y.
There are also ā€˜list splicingā€™ operat ors $@ an d #@ that insert all elements of a list in the
surrounding context.
Now letā€™s take a look at some ac t ual Scheme code. Scheme procedures can be deļ¬ned in
LilyPond input ļ¬les:
#(define (average a b c) (/ (+ a b c) 3))
Note that LilyPond comments (% and %{ %}) cannot be used within Scheme code, even in a
LilyPond input ļ¬le, because the Guile interpreter, not the LilyPond lexer, is reading the Scheme
expression. Comments in Guile Scheme are entered as follows:
; this is a single-line comment
#!
This a (non-nestable) Guile-style block comment
But these are rarely used by Schemers and never in
LilyPond source code
!#
For the rest of this section, we will assume that the data is entered in a music ļ¬le, so we add
a # at the begin ni n g of each Scheme expression.
All of the top-level Scheme expressions in a LilyPond input ļ¬le can be c ombined into a single
Scheme expression by use of the begin statement:
#(begin
Chapter 1: Scheme tutorial 8
(define foo 0)
(define bar 1))
1.2.2 LilyPond variable s
LilyPond variables are stored internally in the form of Scheme variables. Thus,
twelve = 12
is equivalent to
#(define twelve 12)
This means that LilyPond variables are available for use in Scheme expressions. For example,
we coul d use
twentyFour = #(* 2 twelve)
which would re su lt in the number 24 being stored i n the LilyPond (and Scheme) variable
twentyFour.
Scheme allows modifying complex expressions in-place and LilyPond makes use of this ā€˜in-
place modiļ¬cati on ā€™ when using music functions. But when music expr es si on s are stored in
variables rather than entered directly the usual expectation, when passing them t o music func-
tions, would be that the original value is unmodiļ¬ed. So when referencing a music variable with
leading backslash (such as \twentyFour), Lil yPond creates a copy of that variableā€™s music value
for use in the surrounding music expression rather than using the variableā€™s value directly.
Therefore, Scheme music expressions written with the # syntax s hou l d be used for material
that is created ā€˜from scratchā€™ (or that is explicitly copied) rather than being used, inste ad, to
directly reference material.
See also
Extending: Section 1.2.1 [LilyPond Scheme syntax], page 6.
1.2.3 Debugging Scheme code
When debugging large Scheme programs, it is helpful when an error occurs to be pointed to the
precise line in the program where it was raised. In order to enable source locations to be shown
for errors in Scheme co de , LilyPond must be run with the command-line op t ion -dcompile-
scheme-code. Altern at ively, writing #(ly:set-option 'compile-scheme-code) at the top of
the LilyPond ļ¬le has the same eļ¬€ect.
Furthermore, to obtain even more information about the error, you may use the -ddebug-
eval option, or the code #(debug-enable 'backtrace) in the ļ¬le. Under this mode, when an
error occurs, a verbose ā€œbacktraceā€ is displayed, containing information about all fu nc t ion calls
that led to the problematic spot.
Known issues and warnings
Due to a limitation in the Guile implementation, the -dcompile-scheme-code option currently
makes it impossible to compile LilyPond ļ¬les wit h more than a few thousand Scheme expressions.
1.2.4 Input variables and Scheme
The input format suppor t s the notion of variables: in the following example, a music expression
is assigned to a variable with the name traLaLa.
traLaLa = { c'4 d'4 }
There is also a form of scoping: in the following example, t h e \layout block also contains a
traLaLa variabl e , which is independent of the outer \traLaLa.
traLaLa = { c'4 d'4 }
Chapter 1: Scheme tutorial 9
\layout { traLaLa = 1.0 }
In eļ¬€ect, each inp ut ļ¬le is a scope, and all \header, \midi, and \layout blocks are scopes
nested inside that toplevel scope.
Both variabl es and scoping are implemented in the GUILE module system. An an onymous
Scheme module is attached to each s cope. An assignment of t h e for m:
traLaLa = { c'4 d'4 }
is internally converted to a Scheme deļ¬nition:
(define traLaLa Scheme value of `...')
This means that LilyPond variables and Scheme variables may be freely mixed. In t h e
following example, a music fragment is stored in the variable traLaLa, and duplicated using
Scheme. The result is imported in a \score block by means of a second variable twice:
traLaLa = { c'4 d'4 }
#(define newLa (map ly:music-deep-copy
(list traLaLa traLaLa)))
#(define twice
(make-sequential-music newLa))
\twice
h
h
h
ī€…
ĀŖ
h
This is actually a rather interesting example. The assignment will only take place after the
parser has ascertained th at nothing akin to \addlyrics foll ows, so it need s to check what comes
next. It reads # and the following Scheme expression without evaluating it, so it can go ahead
with the assignment, and afterwards execute the Scheme code without problem.
1.2.5 Importing Scheme in LilyPond
The above example shows how to ā€˜exportā€™ music expressions from the input to the Scheme
interpreter. The opposite is also possible. By placing it after $, a Scheme value is interpreted
as if it were entered in LilyPond syntax. Ins te ad of deļ¬ni n g \twice, the example above could
also have been wri t t en as
...
$(make-sequential-music newLa)
You can use $ with a Scheme expression anywhere you could use \name after having assigned
the Scheme expression to a variable name. This replacement happens in the ā€˜lexerā€™, so LilyPond
is not even aware of t he di ļ¬€er e nc e.
One drawback, however, is that of ti mi n g. If we had been using $ instead of # for deļ¬nin g
newLa in the above example, t h e following Scheme deļ¬nition would have failed because traLaLa
would not yet have been d eļ¬ ne d. For an explanation of this timing problem, Section 1.2.1
[LilyPond Scheme syntax], page 6.
A further conve ni en ce can be the ā€˜list splicingā€™ operators $@ and #@ for inserting the elements
of a list in the surrounding context. Using those, the last p ar t of the example could have been
written as
...
{ #@newLa }
Chapter 1: Scheme tutorial 10
Here, every element of the list stored in newLa is taken in sequence and inser te d into the list,
as i f we had written
{ #(first newLa) #(second newLa) }
Now in all of these forms, the Scheme code is evaluated while the input is st i l l being consumed,
either in the lexer or in the parser. If you need it to be executed at a later point of time, check
out Section 2.2.3 [Void scheme functions], page 20, or store it in a procedure:
#(define (nopc)
(ly:set-option 'point-and-click #f))
...
#(nopc)
{ c'4 }
1.2.6 Object properties
Object properties are stored in LilyPond in th e form of al i st - chains, which are list s of alists.
Properties are set by adding values at the beginning of the property list. Properties are read by
retrieving values from the alists.
Setting a new value for a pr operty requires ass ign i ng a value to the alist with both a key and
a value. The LilyPond syntax for doing this is:
\override Stem.thickness = #2.6
This inst r uc ti on adjusts the appearance of stems. An alist entry '(thickness . 2.6) is
added to the property list of the Stem object. thickness is measured relative to the thickness
of staļ¬€ lines, so these stem lines will be
2.6
times the width of staļ¬€ lines. This makes stems
almost twice as thick as their normal size. To distinguish between variables deļ¬ned in input
ļ¬les (like twentyFour in t he example above) an d variables of internal objects, we will call the
latter ā€˜propertiesā€™ and th e former ā€˜variables.ā€™ So, the stem object has a thickness property,
while twentyFour is a variable.
1.2.7 LilyPond compound variables
Oļ¬€sets
Two-dimensional oļ¬€sets (X and Y coordinat es ) are stored as pairs. The car of the oļ¬€set is the
X coordi n ate , and th e cdr is th e Y coordinat e.
\override TextScript.extra-offset = #'(1 . 2)
This assigns the pair (1 . 2) to the extra-offset property of the TextScript object. These
numbers are measured in staļ¬€-spaces, so this command moves the object 1 staļ¬€ space to the
right, and 2 spaces up.
Procedures for working with oļ¬€sets are found in scm/lily-library.scm.
Fractions
Fractions as used by LilyPond are again stored as pairs, this time of unsigned integers. While
Scheme can repr es ent rati onal numbers as a native type, musically ā€˜2/4ā€™ and ā€˜1/2ā€™ are not the
same, an d we need to be able to distinguish between them. Similarly there are no negative
ā€˜fractionsā€™ in LilyPondā€™s mind. So 2/4 in LilyPond means (2 . 4) in Scheme, and #2/4 in
LilyPond means 1/2 in Scheme.
Extents
Pairs are also used to store intervals, which represent a range of numbers from the minimum (the
car) to the maximum (the cdr). Intervals are used to store th e X- and Y- exte nts of printable
Chapter 1: Scheme tutorial 11
objects. For X extents, the car is t h e left hand X coordinate, and t h e cdr is the right hand X
coordinate. For Y extents, t h e car is the bottom coordinate, and the cdr is the top coordinate.
Procedures for working with intervals are found in scm/lily-library.scm. These procedures
should be used when possible to ensure consistency of code.
Property alists
A property alist is a LilyPond data st ru ct u r e that is an alist whose keys are properties and
whose values ar e Scheme expression s t h at give the desired valu e for the pr oper ty.
LilyPond properties are Scheme symbols, such as 'thickness.
Alist chains
An al i st chain is a list containing property alists.
The set of all properties that will apply to a grob is typically stored as an alist chain. In
order to ļ¬nd th e value for a particular property that a grob should have, each alist in the chain
is searched in order, looking for an entry containing the property key. The ļ¬rst alist entry found
is returned, and the value is the property value.
The Scheme procedure chain-assoc-get is normally used to get grob property values.
1.2.8 Internal music representation
Internally, music is rep re se nted as a Scheme list. The list contai ns various elements that af-
fect the printed output. Parsing is t h e process of converting music from the LilyPond input
representation to the internal Scheme representation.
When a music expression is parsed, it is converted into a set of Scheme music objects. The
deļ¬ning property of a music object is that it takes up time. The time it takes up is called its
duration. Durations are expressed as a rational number that measures the len gt h of the music
object in w hol e not es.
A music object has three kind s of types:
ā€¢ music name: Each music expression has a name. For example, a note leads to a Section
ā€œNoteEventā€ in Internals Reference, and \simultaneous leads to a Section ā€œSimultaneous-
Musicā€ in Internals Reference. A list of all expressions available is in the Internals Reference
manual, under Section ā€œMusic expressionsā€ in Internals Reference.
ā€¢ ā€˜typeā€™ or interface: Each music name has several ā€˜typesā€™ or interfaces, for examp le , a note is
an event, but it is also a note-event, a rhythmic-event, and a melodic-event. All classes
of music are listed in the Internals Reference, under Section ā€œMusic classesā€ in Internals
Reference.
ā€¢ C++ object: Each music object is represented by an object of the C ++ clas s Music.
The actual information of a music expression is stored in propert i es . For example, a Section
ā€œNoteEventā€ in Internals Reference has pitch and duration properties that store the p i tch and
duration of that note. A list of all properties available can be found i n the Internals Reference,
under Section ā€œMusic propertiesā€ in Internals Reference.
A compound music expression is a music object that contains other music objects in its
properties. A list of objects can be stored in the elements prop er ty of a mu si c object, or a
single ā€˜childā€™ music object in the element property. For example, Section ā€œSequentialMusicā€
in Internals Reference has its children in elements, and Section ā€œGraceMusicā€ in Internals
Reference has its single argument in element. The body of a repeat is stored in the element
property of Section ā€œRepeated M us i cā€ in Internals Reference, and the alternatives in elements.
Chapter 1: Scheme tutorial 12
1.3 Building complicated functions
This section explains how to gather the information necessary to create complicated music
functions.
1.3.1 Displaying music expressions
When writing a music function it is often instructive to inspect how a mu si c expression is stored
internally. This can be done with the music function \displayMusic.
{
\displayMusic { c'4\f }
}
will display
(make-music
'SequentialMusic
'elements
(list (make-music
'NoteEvent
'articulations
(list (make-music
'AbsoluteDynamicEvent
'text
"f"))
'duration
(ly:make-duration 2 0 1/1)
'pitch
(ly:make-pitch 0 0 0))))
By default, LilyPond will print t h ese m es sages to the c ons ol e along with all the other mes-
sages. To split up t he se messages and save the results of \display{STUFF}, you can specify an
optional output port to use:
{
\displayMusic #(open-output-file "display.txt") { c'4\f }
}
This will overwrit e a previous output ļ¬le whenever it is called; if you need to writ e more
than one expression, you would use a variable for your port and reuse it:
{
port = #(open-output-file "display.txt")
\displayMusic \port { c'4\f }
\displayMusic \port { d'4 }
#(close-output-port port)
}
Guileā€™s manual describes ports in detail. Closing the port is actually only necessary if you
need to read the ļ¬le before LilyPond ļ¬nishes; in the ļ¬rst example, we did not bother to do so.
A bi t of ref orm at ti n g makes the above information easie r to read:
(make-music 'SequentialMusic
'elements (list
(make-music 'NoteEvent
'articulations (list
(make-music 'AbsoluteDynamicEvent
'text
"f"))
Chapter 1: Scheme tutorial 13
'duration (ly:make-duration 2 0 1/1)
'pitch (ly:make-pitch 0 0 0))))
A { ... } music sequence has the name SequentialMusic, and its inner expressions are
stored as a list in its 'elements pr operty. A note is represented as a NoteEvent ob-
ject (storing the duration and pitch properties) with attached information (in this case, an
AbsoluteDynamicEvent wi t h a "f" text pr operty) stored i n it s articulations property.
\displayMusic returns the music it displays, so it will get interpreted as well as displayed.
To avoid interpretation, write \void before \displayMusic.
1.3.2 Music properties
Letā€™s look at an example:
someNote = c'
\displayMusic \someNote
===>
(make-music
'NoteEvent
'duration
(ly:make-duration 2 0 1/1)
'pitch
(ly:make-pitch 0 0 0))
The NoteEvent object is the representation of someNote. Straightforward. How about
putting cā€™ in a chord?
someNote = <c'>
\displayMusic \someNote
===>
(make-music
'EventChord
'elements
(list (make-music
'NoteEvent
'duration
(ly:make-duration 2 0 1/1)
'pitch
(ly:make-pitch 0 0 0))))
Now the NoteEvent object is the ļ¬r st object of t he 'elements property of someNote.
The display-scheme-music function is the function used by \displayMusic to di sp l ay the
Scheme representation of a music expression.
#(display-scheme-music (first (ly:music-property someNote 'elements)))
===>
(make-music
'NoteEvent
'duration
(ly:make-duration 2 0 1/1)
'pitch
(ly:make-pitch 0 0 0))
Then the note pitch is accessed through the 'pitch property of the NoteEvent object.
#(display-scheme-music
(ly:music-property (first (ly:music-property someNote 'elements))
'pitch))
Chapter 1: Scheme tutorial 14
===>
(ly:make-pitch 0 0 0)
The note pitch can be changed by setting this 'pitch property.
#(set! (ly:music-property (first (ly:music-property someNote 'elements))
'pitch)
(ly:make-pitch 0 1 0)) ;; set the pitch to d'.
\displayLilyMusic \someNote
===>
d'4
1.3.3 Doubling a note with slurs (example)
Suppose we want to create a function that translates input like a into { a( a) }. We begin by
examining the internal representation of the desired result.
\displayMusic{ a'( a') }
===>
(make-music
'SequentialMusic
'elements
(list (make-music
'NoteEvent
'articulations
(list (make-music
'SlurEvent
'span-direction
-1))
'duration
(ly:make-duration 2 0 1/1)
'pitch
(ly:make-pitch 0 5 0))
(make-music
'NoteEvent
'articulations
(list (make-music
'SlurEvent
'span-direction
1))
'duration
(ly:make-duration 2 0 1/1)
'pitch
(ly:make-pitch 0 5 0))))
The bad news is that the SlurEvent exp re ss ion s must be added ā€˜insideā€™ the note (in its
articulations pr operty).
Now we examine the input.
\displayMusic a'
===>
(make-music
'NoteEvent
'duration
(ly:make-duration 2 0 1/1)
'pitch
Chapter 1: Scheme tutorial 15
(ly:make-pitch 0 5 0))))
So in our function, we need to clone this expression (so that we have two notes to build the
sequence), add a SlurEvent to t h e 'articulations property of each one, and ļ¬nally make a
SequentialMusic with the two NoteEvent elements. For adding to a property, it is useful to
know that an unset property is read out as '(), the empty list, so no special checks are required
before we put another element at the front of the articulations property.
doubleSlur = #(define-music-function (note) (ly:music?)
"Return: { note ( note ) }.
`note' is supposed to be a single note."
(let ((note2 (ly:music-deep-copy note)))
(set! (ly:music-property note 'articulations)
(cons (make-music 'SlurEvent 'span-direction -1)
(ly:music-property note 'articulations)))
(set! (ly:music-property note2 'articulations)
(cons (make-music 'SlurEvent 'span-direction 1)
(ly:music-property note2 'articulations)))
(make-music 'SequentialMusic 'elements (list note note2))))
1.3.4 Adding articulation to notes (example)
The easy way to add arti cu l at i on to notes is to ju x tapose two music expressions. However,
suppose that we want t o wri t e a music function that d oes th is .
A $variable inside the #{...#} notation is like a regular \variable in classical LilyPond
notation. We could write
{ \music -. -> }
but for the sake of this example, we will learn how to do this in Scheme. We begin by examining
our input and desired output.
% input
\displayMusic c4
===>
(make-music
'NoteEvent
'duration
(ly:make-duration 2 0 1/1)
'pitch
(ly:make-pitch -1 0 0))))
=====
% desired output
\displayMusic c4->
===>
(make-music
'NoteEvent
'articulations
(list (make-music
'ArticulationEvent
'articulation-type 'accent))
'duration
(ly:make-duration 2 0 1/1)
'pitch
(ly:make-pitch -1 0 0))
Chapter 1: Scheme tutorial 16
We see that a note (c4) is represented as a NoteEvent expression. To add an accent artic-
ulation, an ArticulationEvent expression must be added to the articulations property of
the NoteEvent expression.
To buil d t h is fu nc t ion , we begin with
(define (add-accent note-event)
"Add an accent ArticulationEvent to the articulations of `note-event',
which is supposed to be a NoteEvent expression."
(set! (ly:music-property note-event 'articulations)
(cons (make-music 'ArticulationEvent
'articulation-type 'accent)
(ly:music-property note-event 'articulations)))
note-event)
The ļ¬rst line is the way to deļ¬ne a function in Scheme: the function name is add-accent,
and has one variabl e called note-event. In Scheme, the type of variable is often clear from its
name. (this is good practice in other programming languages, too!)
"Add an accent..."
is a description of what the function does. This is not strictly necessary, but just like clear
variable n ame s, it is good practice.
You may wonder why we modify the note event directly i ns t ead of working on a copy
(ly:music-deep-copy can be used for that). The reason is a silent contract: music functions are
allowed to modify their arguments: they are either gene rat e d from scratch (like user input) or
are already copied (referenci n g a music variable with ā€˜\nameā€™ or music fr om immediate Scheme
expressions ā€˜$(...)ā€™ provides a copy). S i nc e it would be ineļ¬ƒcient to create unnecessary copies,
the return value from a music function is not copied. So to heed that contract, you must not
use any argu me nts more than once, and re t ur n in g i t counts as one use.
In an earlier example, we constructed music by repeating a given music argument. In that
case, at least one repetition had to be a copy of its own. If it werenā€™t, strange things may happen.
For example, if you use \relative or \transpose on the resulting music containing the same
elements multiple times, those will be subjected to relativation or transposition multiple times.
If you assign them to a music variable, the curse is broken since referencing ā€˜\nameā€™ will again
create a copy which does not retain the identity of the repeated elements.
Now while the above function is not a music function, it will normally be used within music
functions. So it makes sense to heed the same contract we use for music functions: the input
may be modiļ¬ed for producing the output, and the caller is resp on si b l e for cr eat i n g copies if it
still needs the unchanged argument itself. If you take a look at LilyPondā€™s own functions like
music-map, youā€™ll ļ¬nd th at t he y st ick with the same pr in ci p l es.
Where were we? We now have a note-event we may modify, not because of using
ly:music-deep-copy but because of a long-winded explanation. We add the accent to its
'articulations l is t pr oper ty.
(set! place new-value)
Here, what we want to set (the ā€˜placeā€™) is the 'articulations property of note-event
expression.
(ly:music-property note-event 'articulations)
ly:music-property is the function used to access music properties (the 'articulations,
'duration, 'pitch, etc, that we see in the \displayMusic output above). The new value is
the former 'articulations property, wit h an extra item: the ArticulationEvent expression,
which we copy from the \displayMusic output ,
(cons (make-music 'ArticulationEvent
'articulation-type 'accent)
Chapter 1: Scheme tutorial 17
(ly:music-property result-event-chord 'articulations))
cons is used to add an element to the front of a list without modifying the original list. This
is what we want: the same list as before, plus the new ArticulationEvent expression. The
order inside the 'articulations property is not important here.
Finally, once we have added the accent articulation to its articulations property, we can
return note-event, hence the last line of the function.
Now we transform the add-accent function into a music function (a matter of some syntactic
sugar and a declaration of the type of its argument).
addAccent = #(define-music-function (note-event) (ly:music?)
"Add an accent ArticulationEvent to the articulations of `note-event',
which is supposed to be a NoteEvent expression."
(set! (ly:music-property note-event 'articulations)
(cons (make-music 'ArticulationEvent
'articulation-type 'accent)
(ly:music-property note-event 'articulations)))
note-event)
We the n verify that t h i s music function works correctly :
\displayMusic \addAccent c4
18
2 Interfaces for programmers
Advanced tweaks may be performed by using Scheme. If you are not familiar with Scheme, you
may wis h to re ad our Ch ap t er 1 [Scheme tutorial ] , page 1.
2.1 LilyPond code blocks
Creating music e x pr es si ons in Scheme can be tedious, as they are heavily nested and the resulting
Scheme code is large. For some si mp l e tasks this can be avoided by using LilyPond code blocks,
which enable common LilyPond syntax to be used within Scheme.
LilyPond code blocks look like
#{ LilyPond code #}
Here is a t ri v i al e x ampl e :
ritpp = #(define-event-function () ()
#{ ^"rit." \pp #}
)
{ c'4 e'4\ritpp g'2 }
pp
N
h
ī€…
ĀŖ
rit.
h
LilyPond code blocks can be used anywhere where you can write Scheme code. The Scheme
reader actually is changed for accommodating LilyPond code blocks and can deal with embedded
Scheme expressions starting with $ and #.
The reader extracts the LilyPond code block and generates a runtime call to the LilyPond
parser to interpret the LilyPond code. Scheme expressions embedded in the LilyPond code
are evaluated in the lexi c al environment of the LilyPond code block, so all local variables and
function parameter s available at the point the LilyPond code block is written may be accessed.
Variables d eļ¬ n ed in other Scheme modules, like the modules contai n in g \header and \layout
blocks, are not accessible as Scheme variables, i.e., preļ¬xed with #, but they are accessible as
LilyPond variables, i.e. preļ¬xed with \.
All music generated inside the code block has its ā€˜originā€™ set to the current input location.
A LilyPond code block may contain anything that you can use on the right side of an
assignment. In addition, an empty LilyPond block corr es ponds to a void music expression, and
a LilyPond block containing multiple music events gets turne d into a sequential music expression.
2.2 Scheme functions
Scheme functions are Scheme procedures that can create Scheme expr es si ons from input written
in LilyPond syntax. They can be called in pretty much all places where using # for specifying
a value in Scheme syntax is allowed. While Scheme has functions of its own, this chapter
is concerned with syntactic functions, functions that receive arguments speciļ¬ed in LilyPond
syntax.
2.2.1 Scheme function deļ¬nitions
The general form for deļ¬ning scheme functions is:
function =
#(define-scheme-function
Chapter 2: Interfaces for programmers 19
(arg1 arg2 ...)
(type1? type2? ...)
body)
where
argN nth argument.
typeN? A Scheme type predicate for which argN must return #t.
There is also a special form (predicate? default) for spec-
ifying op t ion al arguments. If the actual argument is missing
when the function is being called, the default value is sub-
stituted instead. Default values are evaluated at deļ¬nition
time ( in cl u di n g LilyPond code blocks!), so if you need a de-
fault cal c ul at ed at runtime, instead write a special value you
can easily recognize. If you write the predicate in parenthe-
ses but donā€™t follow it with a default value, #f is used as the
default. Default values are not veriļ¬ ed with predicate? at
either deļ¬nition or run time: it is your responsibility to deal
with the values you specify. Default values that happe n to
be music expressions are copied while setting origin to the
current input location.
body A sequen ce of Scheme forms evaluated in order, the last one
being used as the return value of the scheme function. It
may contain Lily Pond code blocks enclosed in hash ed br ace s
( #{...#} ), like described in Section 2.1 [Lil y Pond code
blocks], page 18. Within LilyPond code blocks, use # to
reference function arguments (eg., ā€˜#arg1ā€™) or to start an in-
line Scheme expression containing function argume nts (eg.,
ā€˜#(cons arg1 arg2)ā€™ ). Where normal Scheme expressions
using # donā€™t do the tri ck, you might need to revert to imme-
diate Scheme expressions using $, for example as ā€˜$musicā€™.
If your function returns a music expression , it is given a
useful value of origin.
Suitability of arguments for the predicates is determined by actually calli ng t h e predicate after
LilyPond has already converted them into a Scheme expression. As a consequence, the argument
can be speciļ¬ed in Scheme syntax if desired (introduced with # or as the result of calling a
scheme function), but LilyPond will also convert a number of LilyPond constructs i nto Scheme
before actually checking the predicate on them. Currently, those include music, postevents,
simple strings (with or without quot es ) , numbers, full markups and markup lists, score, book,
bookpart, context deļ¬nition and output deļ¬nition blocks.
Some ambiguities LilyPond sorts out by checking with predicate functions: is ā€˜-3ā€™ a ļ¬ngering
postevent or a negative number? Is "a" 4 in lyric mode a string followed by a number, or a lyric
event of duration 4? LilyPond tries the argument predicate on successive interpretations until
success, with an order designed to minimize inconsistent interpretations and lookahead.
For example, a predi cat e accepting both music expressions and pitches will consid er c'' to
be a pitch rather than a music expression. Immediately following durations or postevents will
change that interpretation. Itā€™s best to avoid overly permissive predicates like scheme? when
the application rather calls for more speciļ¬c argument types.
For a list of available predeļ¬ned type predicates, see Section ā€œPredeļ¬ned type predicatesā€ in
Notation Reference.
Chapter 2: Interfaces for programmers 20
See also
Notation Reference: Section ā€œPredeļ¬ned type pr ed i cat es ā€ in Notation Reference.
Installed Files: lily/music-scheme.cc, scm/c++.scm, scm/lily.scm.
2.2.2 Scheme function usage
Scheme functions can be called pretty much anywhere wh er e a Scheme expression starting with
# can be written. You call a scheme function from LilyPond by writing its name preceded by \,
followed by its arguments. Once an optional argument predicate does not match an argument,
LilyPond skips this and all following optional arguments, repl aci n g them with their speciļ¬ed
default, and ā€˜backs upā€™ the argument that did not match to the place of the next man dat or y
argument. Since t he backed up argument needs to go somewhere, optional arguments are not
actually considered optional unless followed by a mandatory argument.
There is one e x cep t i on: if you write \default in the place of an optional argument, this
and all following optional argument s are skipped and replaced by their default. This works even
when no mandatory argument follows since \default does not need to get backed up. The mark
and key commands make use of that trick to pr ovide t h ei r default behavior when just followed
by \default.
Apart from places where a Scheme value is required, there are a few places where # expressions
are currently accepted and evaluated for their s i de eļ¬€ects but other wi se ignored. Most ly those
are the places where an assignment would be acceptable as well.
Since it is a bad idea to return values that can be misinterpreted in some cont e xt , you sh ou ld
use normal scheme functions only for those cases where you always return a useful value, and
use void scheme functions (see Section 2.2.3 [Void scheme functions], page 20) otherwise.
For convenience, scheme functions may also be called directly from Scheme bypassing the
LilyPond parser. Their name can be used like the name of an ordinary fu nc t ion . Typechecking of
the arguments and skipping optional arguments will happen in the same manner as when called
from within LilyPond, with the Scheme value *unspecified* taking the role of the \default
reserved word for explicitly skipping optional arguments. Opti onal arguments at the end of an
argument list can just be omitted without indication when called via Scheme.
2.2.3 Void scheme functions
Sometimes a procedure is executed in order to perform an action rather than return a value.
Some programming languages (like C and Scheme) use functions for either concept and jus t
discard the returned value (usually by allowing any expression to act as statement, ignoring the
result). This is clever but error-prone: most C compilers nowadays oļ¬€er warnings for various
non-ā€œvoidā€ expressions being discarded. For many functions executing an action, the Scheme
standards declare the return value to be unspeciļ¬ed. LilyPondā€™s Scheme interpreter Guile has a
unique value *unspecified* that it usually (such when using set! directly on a variable) but
unfortunately not consistently returns in such cases.
Deļ¬ning a LilyPond function with define-void-function makes sure that this special value
(the only value satisfying the predicate void?) will be returned.
noPointAndClick =
#(define-void-function
()
()
(ly:set-option 'point-and-click #f))
...
\noPointAndClick % disable point and click
If you want to evaluate an expression only f or its side-eļ¬€ect and donā€™t want any value it may
return interpreted, you can do so by pr eļ¬ x i ng i t wi th \void:
Chapter 2: Interfaces for programmers 21
\void #(hashq-set! some-table some-key some-value)
That way, you can be sure that LilyPond will not assign meaning to the returned value regard-
less of where it encounters it. This will also work for music functions such as \displayMusic.
2.3 Music functions
Music funct ion s are Scheme procedures that can create music expressions automatically, and
can be use d to gre at l y sim pl i fy t h e i np ut ļ¬ le .
2.3.1 Music function deļ¬nitions
The general form for deļ¬ning music functions is:
function =
#(define-music-function
(arg1 arg2 ...)
(type1? type2? ...)
body)
quite in analogy to Section 2.2.1 [Scheme function deļ¬nitions], page 18. More often than not,
body will be a Section 2.1 [LilyPond code blocks], page 18.
For a list of available ty pe predicates, see Section ā€œPredeļ¬ned type predicatesā€ in Notation
Reference.
See also
Notation Reference: Section ā€œPredeļ¬ned type pr ed i cat es ā€ in Notation Reference.
Installed Files: lily/music-scheme.cc, scm/c++.scm, scm/lily.scm.
2.3.2 Music function usage
With regard to handling the argument list , music functions donā€™t diļ¬€er from scheme functions,
Section 2.2.2 [Scheme function usage], page 20.
A ā€˜music functionā€™ has to return an expression matching the predicat e ly:music?. This
makes music function calls suitabl e as arguments of type ly:music? for another music function
call.
When us i ng a music function call in other contexts, the context may c aus e furt he r semantic
restrictions.
ā€¢ At the top level in a music expression a post-event is not accepted.
ā€¢ When a music function (as opposed to an event function) returns an expression of type
post-event, LilyPond requires one of the named direction indicators (-, ^, and _) in order
to properly integrate the post-event produced by the music function call into the surrounding
expression.
ā€¢ As a chord constituent. The returned expression must be of a rhythmic-event type, most
likely a NoteEvent.
ā€˜Polymorphicā€™ fun ct i on s, like \tweak, can be applied to post-events, chord constituent and top
level music expressions.
2.3.3 Simple substitution functions
Simple substitution functi ons are music functions whose output music expression i s written i n
LilyPond format and contains functi on arguments in the output expression. They are described
in Section ā€œSubstitution function examplesā€ in Notation Reference.
Chapter 2: Interfaces for programmers 22
2.3.4 Intermediate substitution functions
Intermediate substitution functions involve a mix of Scheme code and LilyPond code in the
music expression to be returned.
Some \override commands require an argument consisting of a pair of numbers (called a
cons cell in Scheme).
The pair can be directly passed into the music function, using a pair? variable:
manualBeam =
#(define-music-function
(beg-end)
(pair?)
#{
\once \override Beam.positions = #beg-end
#})
\relative c' {
\manualBeam #'(3 . 6) c8 d e f
}
Alternatively, the numbers making up the p air can be passed as separate arguments, and the
Scheme code u sed t o cr eat e th e pair can be included in the music expression:
manualBeam =
#(define-music-function
(beg end)
(number? number?)
#{
\once \override Beam.positions = #(cons beg end)
#})
\relative c' {
\manualBeam #3 #6 c8 d e f
}
h
h
h
h
ī€…
ĀŖ
Properties are maintain ed conceptually using one stack per property per grob per context.
Music functions may need t o override one or several proper ti e s for the duration of the function,
restoring them to their previous value before exiting. However, normal overrides pop and discard
the top of the current property stack before pushing to it, so the previous value of the property
is lost when it is overridden. When the previous value must be preserved, preļ¬x the \override
command with \temporary, like t h i s:
\temporary \override ...
The use of \temporary causes the (usually set) pop-first pr operty in the override to be
cleared, so the previous value is not popped oļ¬€ the property stack before pushing the new value
onto it. When a subsequent \revert pops oļ¬€ the temporarily overriden value, the previous
value wil l r e- eme rge .
In other words, calling \temporary \override and \revert in succe ss ion on the same prop-
erty will have a net eļ¬€ect of zero. Similarly, pair in g \temporary and \undo on t h e same music
containing overrides will have a net eļ¬€ect of zero.
Chapter 2: Interfaces for programmers 23
Here is an example of a music function which makes use of this. The use of \temporary
ensures the values of the cross-staff and style properties are restored on exit to whatever
values they had when the crossStaff function was called. Without \temporary the default
values would have been set on exit.
crossStaff =
#(define-music-function (notes) (ly:music?)
(_i "Create cross-staff stems")
#{
\temporary \override Stem.cross-staff = #cross-staff-connect
\temporary \override Flag.style = #'no-flag
#notes
\revert Stem.cross-staff
\revert Flag.style
#})
2.3.5 Mathematics in functions
Music functions can involve Scheme programming in addition to simple substitution,
AltOn =
#(define-music-function
(mag)
(number?)
#{
\override Stem.length = #( * 7.0 mag)
\override NoteHead.font-size =
#(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
#})
AltOff = {
\revert Stem.length
\revert NoteHead.font-size
}
\relative {
c'2 \AltOn #0.5 c4 c
\AltOn #1.5 c c \AltOff c2
}
h N
ĀŖ
ī€…
N hh
h
This example may be rewritten to pass in music expressions,
withAlt =
#(define-music-function
(mag music)
(number? ly:music?)
#{
\
override
Stem
.
length
= #(
*
7.0 mag)
\override NoteHead.font-size =
#(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
#music
Chapter 2: Interfaces for programmers 24
\revert Stem.length
\revert NoteHead.font-size
#})
\relative {
c'2 \withAlt #0.5 { c4 c }
\withAlt #1.5 { c c } c2
}
h N
ĀŖ
ī€…
N hh
h
2.3.6 Functions without arguments
In mos t case s a fun ct i on wit h out ar gume nts should be writt en with a variable,
dolce = \markup{ \italic \bold dolce }
However, in r are case s it may be useful to create a music function wit hou t argu ments,
displayBarNum =
#(define-music-function
()
()
(if (eq? #t (ly:get-option 'display-bar-numbers))
#{ \once \override Score.BarNumber.break-visibility = ##f #}
#{#}))
To actual ly display bar numbers where th i s fun ct i on is c all e d, i nvoke lilypond with
lilypond -d display-bar-numbers FILENAME.ly
2.3.7 Void music functions
A music function must return a music expression. If you want to execute a function only
for its side eļ¬€ect, you should use define-void-function. But there may be cases where you
sometimes want to produce a music expression, and sometimes not (like in the previ ous example).
Returning a void music expression via #{ #} will achieve that.
2.4 Event functions
To us e a music function in t he p l ace of an event, you need to wri t e a direction i nd i cat or bef ore
it. But sometime s, this does not quite match the syntax of constructs you want t o replace. For
example, if you want to write dynamics commands, those are usually attached without direction
indicator, like
c'\pp
. Here is a way to write arbitrary dynamics:
dyn=#(define-event-function (arg) (markup?)
(make-dynamic-script arg))
\relative { c'\dyn pfsss }
You could do the same using a music function, but then you always would have to write a
direction indicator before calling it, like c-\dyn pfsss.
Chapter 2: Interfaces for programmers 25
2.5 Markup functions
Markups are implemented as special Scheme function s which produce a Stencil object given a
number of arguments.
2.5.1 Markup construction in Scheme
Markup expressions are internally represented in Scheme using the markup macro:
(markup expr)
To see a markup ex pr es si on i n it s Scheme form, use th e \displayScheme comman d:
\displayScheme
\markup {
\column {
\line { \bold \italic "hello" \raise #0.4 "world" }
\larger \line { foo bar baz }
}
}
Compiling the code above will send the following to the display console:
(markup
#:line
(#:column
(#:line
(#:bold (#:italic "hello") #:raise 0.4 "world")
#:larger
(#:line
(#:simple "foo" #:simple "bar" #:simple "baz")))))
To prevent the markup from printing on the page, u se ā€˜\void \displayScheme markupā€™.
Also, as with the \displayMusic command, the output of \displayScheme can be saved to an
external ļ¬le. See Section 1.3.1 [Displaying music expressions], page 12.
This example demonstrates the main translation rules between regular LilyPond markup syntax
and Sch eme markup syntax. Using #{ ... #} for enter in g in LilyPond syntax will often be most
convenient, but we explain how to use the markup macro to get a Scheme-only solution.
LilyPond Scheme
\markup markup1 (markup markup1)
\markup { markup1
markup2 ... }
(markup markup1
markup2 ... )
\markup-command #:markup-command
\variable variable
\center-column { ... } #:center-column (
... )
string "string"
#scheme-arg scheme-arg
The whole Scheme language is accessible inside the markup macro. For example, You may
use function calls inside markup in order to manipulate character strings. This is useful when
deļ¬ning new markup commands (see Section 2.5.3 [New markup command deļ¬nition], page 26).
Known issues and warnings
The markup-list argument of comm and s such as #:line, #:center, and #:column cannot be a
variable or the result of a function cal l.
(markup #:line (function-that-returns-markups))
Chapter 2: Interfaces for programmers 26
is invalid. One should use the make-line-markup, make-center-markup, or
make-column-markup fu n ct i ons in st e ad,
(markup (make-line-markup (function-that-returns-markups)))
2.5.2 How markups work internally
In a mark up l ike
\raise #0.5 "text example"
\raise is actually represented by the raise-markup function. The markup expression is stored
as
(list raise-markup 0.5 (list simple-markup "text example"))
When the markup is converted to printable objects (Stencils), the raise-markup function is
called as
(apply raise-markup
\layout object
list of property alists
0.5
the "text example" markup)
The raise-markup function ļ¬rst creates the stencil for the text example string, and then it
raises that Stencil by 0.5 staļ¬€ space. This is a rather simple example; more complex examples
are in the rest of this section, and in scm/define-markup-commands.scm.
2.5.3 New markup command deļ¬nition
This section discusses the deļ¬nition of new markup commands.
Markup command deļ¬nition syntax
New mark up commands can be deļ¬ned using the define-markup-command Scheme macro, at
top-level.
(define-markup-command (command-name layout props arg1 arg2 ...)
(arg1-type? arg2-type? ...)
[ #:properties ((property1 default-value1)
...) ]
[ #:as-string expression ]
...command body...)
The arguments are
command-name
the markup command name
layout the ā€˜layoutā€™ deļ¬nition.
props a li st of associati ve lists, containing all acti ve properties.
argi ith command argument
argi-type?
a type predicate for t he i th argument
If the command uses properties from the props arguments, the #:properties keyword can
be use d to speci fy wh ich properties are use d al on g with t he ir default values.
Arguments are distinguished according to their type:
ā€¢ a markup, corresponding to type predicate markup?;
ā€¢ a list of markups, corresponding to type predicate markup-list?;
Chapter 2: Interfaces for programmers 27
ā€¢ any other scheme object, corresponding to type predicates such as list?, number?,
boolean?, e t c.
There is no limitation on the order of ar gum ents (after the standard layout and props
arguments). However, markup functions taking a markup as their last argument are somewhat
special as you can apply them to a markup list, and the result is a markup list where the markup
function (with the speciļ¬ed leading arguments) has been applied to every element of the original
markup list.
Since replicating the leading arguments for applying a markup function to a markup list
is cheap mostly for Scheme arguments, you avoid performance pitfalls by just using Scheme
arguments for the leading arguments of m ark u p functions that take a markup as their last
argument.
Markup commands have a rather complex life cycle. The body of a markup command
deļ¬nition is responsible for converting the arguments of t he markup command into a stencil
expression which is returned. Quite often this is accomplished by calling the interpret-markup
function on a markup expression, passi ng t h e layout and props arguments on to it. Those
arguments are usually only known at a very late stage in typesetting. Markup expressions
have their components assembled into markup expressions already when \markup in a LilyPond
expression or the markup macro in Scheme is expanded. The evaluati on and typecheckin g of
markup command arguments happens at the time \markup/markup are interpreted.
But the actual conversion of markup expressions into stencil expressions by executing the
markup fun ct i on bodies only happens when interpret-markup i s called on a markup expression.
On properties
The layout an d props arguments of markup commands bring a context for the markup i nter-
pretation: font size, line width, etc.
The layout argument allows access to properties deļ¬ned in paper blocks, using the
ly:output-def-lookup function. For ins tan ce , the line width (the same as the one used i n
scores) is read using:
(ly:output-def-lookup layout 'line-width)
The props argument makes s ome properties accessible to markup commands. For instanc e,
when a bo ok tit l e markup is interpreted, all the variables deļ¬ned in the \header block are auto-
matically added to props, so that the book title markup can access the book title, composer, etc.
It is also a way to conļ¬gure the behavior of a markup command: for examp l e, when a command
uses font size during processing, the font size is read from props rather than having a font-size
argument. The caller of a markup command may change the value of the font s i ze property in
order to change the behavior. Use the #:properties keyword of define-markup-command to
specify which properties shall be read from the props arguments.
The example in next section illustrates how to access and override properties in a markup
command.
A complete ex a mpl e
The following example deļ¬nes a markup command to draw a double box around a piece of text.
Firstly, we need to build an app roximative result using markups. Consulting the Section
ā€œText mar k up commandsā€ in Notation Reference shows us the \box command is useful:
\markup \box \box HELLO
HELLO
Chapter 2: Interfaces for programmers 28
Now, we consider that more padding between the text and the boxes is preferable. Accord i ng
to the \box documentation, thi s command uses a box-padding property, which defaults to 0.2.
The documentation also mentions how to override it:
\markup \box \override #'(box-padding . 0.6) \box A
A
Then, the padding between the two boxes is considered too small, so we override it too:
\markup \override #'(box-padding . 0.4) \box
\override #'(box-padding . 0.6) \box A
A
Repeating this lengthy markup would be painful. Th i s is where a markup command is needed.
Thus, we write a double-box markup command, taking one argument (the text). This dr aws
the two boxes, with some paddin g.
#(define-markup-command (double-box layout props text) (markup?)
"Draw a double box around text."
(interpret-markup layout props
#{\markup \override #'(box-padding . 0.4) \box
\override #'(box-padding . 0.6) \box { #text }#}))
or, equivalently
#(define-markup-command (double-box layout props text) (markup?)
"Draw a double box around text."
(interpret-markup layout props
(markup #:override '(box-padding . 0.4) #:box
#:override '(box-padding . 0.6) #:box text)))
text is the name of the command argument, and markup? i t s ty pe: it identiļ¬es i t as a
markup. The interpret-markup function is used in most of markup commands: it buil d s a
stencil, usi n g layout, props, and a markup. In the second case, this markup is built using
the markup scheme macro, see Section 2.5.1 [Markup construction in Scheme], page 25. The
transformation from \markup expression to scheme markup expression is straight-forward.
The new command can be used as follow:
\markup \double-box A
It would be nice to make the double-box command customiz abl e : her e, the box-padding
values are hard coded, and cannot be changed by th e user. Also, it would be better to distinguish
the paddin g between the two boxes, from the padding be tween the inner box and the text. So
we will introduce a new property, inter-box-padding, for the padding between the two boxes.
The box-padding wi l l be used for t h e inn er pad d in g. The new code is now as follows:
#(define-markup-command (double-box layout props text) (markup?)
#:properties ((inter-box-padding 0.4)
(box-padding 0.6))
"Draw a double box around text."
(interpret-markup layout props
#{\markup \override #`(box-padding . ,inter-box-padding) \box
\override #`(box-padding . ,box-padding) \box
{ #text } #}))
Again, the equivalent version using the markup macro would be:
#(define-markup-command (double-box layout props text) (markup?)
Chapter 2: Interfaces for programmers 29
#:properties ((inter-box-padding 0.4)
(box-padding 0.6))
"Draw a double box around text."
(interpret-markup layout props
(markup #:override `(box-padding . ,inter-box-padding) #:box
#:override `(box-padding . ,box-padding) #:box text)))
Here, the #:properties keyword is used so that the inter-box-padding and box-padding
properties are read from the props argument, and default values are given to them if the
properties are not deļ¬ned.
Then, these valu es are used to override the box-padding properties used by the two \box
commands. Note the backquote and the comma in the \override argument: they allow you to
introduce a variable value into a l i t er al ex pr es si on.
Now, th e command can be used in a markup, and the boxes padding be customized:
#(define-markup-command (double-box layout props text) (markup?)
#:properties ((inter-box-padding 0.4)
(box-padding 0.6))
"Draw a double box around text."
(interpret-markup layout props
#{\markup \override #`(box-padding . ,inter-box-padding) \box
\override #`(box-padding . ,box-padding) \box
{ #text } #}))
\markup \double-box A
\markup \override #'(inter-box-padding . 0.8) \double-box A
\markup \override #'(box-padding . 1.0) \double-box A
A
A
A
Adapting builtin commands
A good way to start writing a new markup com mand , is to take example on a builtin
one. Most of the markup comman ds provided with LilyPond can be found in ļ¬le
scm/define-markup-commands.scm.
For instance, we would like to adapt the \draw-line comman d, to draw a doubl e line instead.
The \draw-line c omman d is deļ¬ ne d as fol l ow (documentation stripped):
(define-markup-command (draw-line layout props dest)
(number-pair?)
#:category graphic
#:properties ((thickness 1))
"...documentation..."
(let ((th (* (ly:output-def-lookup layout 'line-thickness)
thickness))
(x (car dest))
(y (cdr dest)))
Chapter 2: Interfaces for programmers 30
(make-line-stencil th 0 0 x y)))
To deļ¬ne a n ew command based on an existing one, copy the deļ¬nition, and change the com-
mand name. The #:category keyword can be safely removed, as it is only used for generatin g
LilyPond documentation, and is of no use for user-deļ¬ned markup commands.
(define-markup-command (draw-double-line layout props dest)
(number-pair?)
#:properties ((thickness 1))
"...documentation..."
(let ((th (* (ly:output-def-lookup layout 'line-thickness)
thickness))
(x (car dest))
(y (cdr dest)))
(make-line-stencil th 0 0 x y)))
Then, a property for setting the gap between two lines is added, called line-gap, defaulting,
e.g., to 0.6:
(define-markup-command (draw-double-line layout props dest)
(number-pair?)
#:properties ((thickness 1)
(line-gap 0.6))
"...documentation..."
...
Finally, the co de for drawing two lines is added. Two calls to make-line-stencil are used
to d r aw the lines, and the re su l t in g sten ci l s are c ombined using ly:stencil-add:
#(define-markup-command (my-draw-line layout props dest)
(number-pair?)
#:properties ((thickness 1)
(line-gap 0.6))
"..documentation.."
(let* ((th (* (ly:output-def-lookup layout 'line-thickness)
thickness))
(dx (car dest))
(dy (cdr dest))
(w (/ line-gap 2.0))
(x (cond ((= dx 0) w)
((= dy 0) 0)
(else (/ w ( sqrt (+ 1 (* (/ dx dy) (/ dx dy))))))))
(y (* (if (< (* dx dy) 0) 1 -1)
(cond ((= dy 0) w)
((= dx 0) 0)
(else (/ w (sqrt (+ 1 (* (/ dy dx) (/ dy dx))))))))))
(ly:stencil-add (make-line-stencil th x y (+ dx x) (+ dy y))
(make-line-stencil th (- x) (- y) (- dx x) (- dy y)))))
\markup \my-draw-line #'(4 . 3)
\markup \override #'(line-gap . 1.2) \my-draw-line #'(4 . 3)
Chapter 2: Interfaces for programmers 31
Converting markups to strings
Markups are occasionally converted to plain strings, such as when outputting PDF metadata
based on the title header ļ¬eld or for converting ly r ic s to MIDI. This conversion is inherently
lossy, but tries to as accurate as feasible. The function used for this i s markup->string.
composerName = \markup \box "Arnold Sch
ĀØ
onberg"
\markup \composerName
\markup \typewriter #(markup->string composerName)
Arnold Schƶnberg
[Arnold Schƶnberg]
For custom markup commands, the default behavior is to convert all markup or mar k up list
arguments ļ¬rst, and join the results by spaces.
#(define-markup-command (authors-and layout props authorA authorB)
(markup? markup?)
(interpret-markup layout props
#{
\markup \fill-line { \box #authorA and \box #authorB }
#}))
defaultBehavior = \markup \authors-and "Bertolt Brecht" "Kurt Weill"
\markup \defaultBehavior
\markup \typewriter #(markup->string defaultBehavior)
Bertolt Brecht and Kurt Weill
Bertolt Brecht Kurt Weill
markup->string can also receive the named arguments #:layout layout and #:props
props, with the same meaning as in t he deļ¬nition of a markup command. However, they are
optional because they cannot always be provided (such as the layout argument when converting
to M ID I) .
To support special conversions in custom markup commands, the #:as-string parameter
can be given to define-markup-command. It expects an expression, which is evaluated by
markup->string i n orde r to y ie l d th e str i ng r es ul t .
#(define-markup-command (authors-and layout props authorA authorB)
(markup? markup?)
#:as-string (format #f "~a and ~a"
(markup->string authorA #:layout layout #:props props)
(markup->string authorB #:layout layout #:props props))
(interpret-markup layout props
#{
\
markup
\
fill-line
{ \
box
#authorA and \
box
#authorB }
#}))
customized = \markup \authors-and "Bertolt Brecht" "Kurt Weill"
Chapter 2: Interfaces for programmers 32
\markup \customized
\markup \typewriter #(markup->string customized)
Bertolt Brecht and Kurt Weill
Bertolt Brecht and Kurt Weill
Within the expression, the same bindings are avai l abl e as i n t h e mai n markup command
body, namel y layout and props, the comm and argument, and option al l y t h e proper t i es.
#(define-markup-command (authors-and layout props authorA authorB)
(markup? markup?)
#:properties ((author-separator " and "))
#:as-string (format #f "~a~a~a"
(markup->string authorA #:layout layout #:props props)
(markup->string author-separator #:layout layout #:props props)
(markup->string authorB #:layout layout #:props props))
(interpret-markup layout props
#{
\markup { \box #authorA #author-separator \box #authorB }
#}))
customized = \markup \override #'(author-separator . ", ")
\authors-and "Bertolt Brecht" "Kurt Weill"
\markup \customized
\markup \typewriter #(markup->string customized)
Bertolt Brecht , Kurt Weill
Bertolt Brecht, Kurt Weill
Most often, a custom handler only needs to call markup->string recursively on certai n
arguments, as demonstrated above. However, it can also make use of the layout and props
directly, in the same way as in the main body. Care mus t be taken t hat the layout argument
is #f if no #:layout has been given to markup->string. The props argument defaults to the
empty list.
2.5.4 New markup list command deļ¬nition
Markup list commands are deļ¬ned with the define-markup-list-command Scheme macro,
which is similar to the define-markup-command macro described in Section 2.5.3 [New markup
command deļ¬nition], page 26, except that where th e latter returns a single stencil, the former
returns a list of stencils.
In a similar vein, interpret-markup-list is used instead of interpret-markup for convert-
ing a mar ku p li st into a list of stenci l s.
In the following example, a \paragraph markup list command is deļ¬ned, which returns a
list of justiļ¬ed lines, the ļ¬rst one being indented. The indent width is taken from the props
argument.
#(define-markup-list-command (paragraph layout props args) (markup-list?)
Chapter 2: Interfaces for programmers 33
#:properties ((par-indent 2))
(interpret-markup-list layout props
#{\markuplist \justified-lines { \hspace #par-indent #args } #}))
The version using just Scheme is more complex:
#(define-markup-list-command (paragraph layout props args) (markup-list?)
#:properties ((par-indent 2))
(interpret-markup-list layout props
(make-justified-lines-markup-list (cons (make-hspace-markup par-indent)
args))))
Besides the usual layout and props arguments, the paragraph markup list command takes
a mark u p li st argument, named args. The predicate for markup lists is markup-list?.
First, th e function gets the indent wid t h , a property here named par-indent, fr om the
property list props. If the property is not found, the default value is 2. Then, a list of justiļ¬ed
lines is made using the built-in markup list command \justified-lines, which is related to the
make-justified-lines-markup-list function. A horizontal space is added at the beginning
using \hspace (or the make-hspace-markup function). Finally, the markup list is interpreted
using the interpret-markup-list function.
This new markup list command can be used as follows:
\markuplist {
\paragraph {
The art of music typography is called \italic {(plate) engraving.}
The term derives from the traditional process of music printing.
Just a few decades ago, sheet music was made by cutting and stamping
the music into a zinc or pewter plate in mirror image.
}
\override-lines #'(par-indent . 4) \paragraph {
The plate would be inked, the depressions caused by the cutting
and stamping would hold ink. An image was formed by pressing paper
to the plate. The stamping and cutting was completely done by
hand.
}
}
2.6 Contexts for progra m me rs
2.6.1 Context evaluatio n
Contexts can be modiļ¬ed during interpretation with Scheme code. In a LilyPond code block,
the syntax for this is:
\applyContext function
In S cheme code, the syntax is:
(make-apply-context function)
function should be a Scheme function that takes a single argument: the context in which
the \applyContext command is being called . The function can access as well as override/set
grob properties and context properties . Any actions taken by the function that depend on the
state of the context are limited to the state of the context when the function is called. Also,
changes eļ¬€ected by a call to \applyContext remain in eļ¬€ect until they are directly modiļ¬ed
again, or reverted, even if the initial conditions that they depended on have changed.
The following scheme functions are useful when using \applyContext:
Chapter 2: Interfaces for programmers 34
ly:context-property
look u p a context property value
ly:context-set-property!
set a context proper ty
ly:context-grob-definition
ly:assoc-get
look u p a grob property value
ly:context-pushpop-property
do a \temporary \override or a \revert on a grob property
The following example looks up the current fontSize value, and then doubles it:
doubleFontSize =
\applyContext
#(lambda (context)
(let ((fontSize (ly:context-property context 'fontSize)))
(ly:context-set-property! context 'fontSize (+ fontSize 6))))
{
\set fontSize = -3
b'4
\doubleFontSize
b'
}
hĀŖ
ī€…
h
The following example looks up the current colors of the NoteHead, Stem, and Beam grobs,
and then changes each to a less saturated shade.
desaturate =
\applyContext
#(lambda (context)
(define (desaturate-grob grob)
(let* ((grob-def (ly:context-grob-definition context grob))
(color (ly:assoc-get 'color grob-def black))
(new-color (map (lambda (x) (min 1 (/ (1+ x) 2))) color)))
(ly:context-pushpop-property context grob 'color new-color)))
(for-each desaturate-grob '(NoteHead Stem Beam)))
\relative {
\time 3/4
g'8[ g] \desaturate g[ g] \desaturate g[ g]
\override NoteHead.color = #darkred
\
override
Stem
.
color
= #darkred
\override Beam.color = #darkred
g[ g] \desaturate g[ g] \desaturate g[ g]
}
Chapter 2: Interfaces for programmers 35
hhh hhhh
3
4
ī€… h
hhh h
This also could be implemented as a music function, in order to restrict the modiļ¬ca-
tions to a single music block. Notice how ly:context-pushpop-property is used both as a
\temporary \override and as a \revert:
desaturate =
#(define-music-function
(music) (ly:music?)
#{
\applyContext
#(lambda (context)
(define (desaturate-grob grob)
(let* ((grob-def (ly:context-grob-definition context grob))
(color (ly:assoc-get 'color grob-def black))
(new-color (
map
(
lambda
(x) (
min
1 (
/
(
1
+ x) 2))) color)))
(ly:context-pushpop-property context grob 'color new-color)))
(for-each desaturate-grob '(NoteHead Stem Beam)))
#music
\applyContext
#(lambda (context)
(define (revert-color grob)
(ly:context-pushpop-property context grob 'color))
(for-each revert-color '(NoteHead Stem Beam)))
#})
\relative {
\override NoteHead.color = #darkblue
\override Stem.color = #darkblue
\override Beam.color = #darkblue
g'8 a b c
\desaturate { d c b a }
g b d b g2
}
h
h
h
N
h
h
h
ī€…
hĀŖ
h
h
h
h
h
2.6.2 Running a function on all layout objects
The most versatile way of tuning an object is \applyOutput which works by i n se rt i n g an event
into the speciļ¬ed context (Section ā€œApplyOutputEventā€ in Internals Reference). Its syntax is
either
\applyOutput Context proc
or
\applyOutput Context.Grob proc
where proc is a S cheme functi on, t aki n g thr ee arguments.
When interpreted, the function proc is called for every layout object (with grob name Grob if
speciļ¬ed) found in t h e context Context at the current time step, with the following arguments:
Chapter 2: Interfaces for programmers 36
ā€¢ the layout object itself,
ā€¢ the context where the layout object was created, and
ā€¢ the context where \applyOutput is processed.
In addition, the cause of the layout object, i.e., the music expression or object that was
responsible for creating it, is in the object property cause. For example, for a note head, this
is a Section ā€œNoteHeadā€ in Internals Reference event, and for a stem object, this is a Section
ā€œStemā€ in Internals Reference object.
Here is a function to use for \applyOutput; it blanks not e -he ads on the center-line and next
to i t :
#(define (blanker grob grob-origin context)
(if (< (abs (ly:grob-property grob 'staff-position)) 2)
(set! (ly:grob-property grob 'transparent) #t)))
\relative {
a'4 e8 <<\applyOutput Voice.NoteHead #blanker a c d>> b2
}
h
N
h
ī€…
ĀŖ
h
To have function interpreted at the Score or Staff level use these forms
\applyOutput Score...
\applyOutput Staff...
2.7 Callback functions
Properties (like thickness, direction, etc.) can be set at ļ¬xed values with \override, e.g.
\override Stem.thickness = #2.0
Properties can also be set to a Scheme procedure:
\override Stem.thickness = #(lambda (grob)
(if (= UP (ly:grob-property grob 'direction))
2.0
7.0))
\relative { c'' b a g b a g b }
h
h
h
h h
h
ī€…
ĀŖ
h
h
In this case, the procedure is execu t ed as soon as the value of the property is requested durin g
the formatting process.
Most of the typesetting engine is d r i ven by such cal l b acks. Properti es that typically use
callbacks include
stencil The printing routine, that constructs a drawing for the symbol
X-offset The routine that sets the horizontal position
X-extent The routine that computes the width of an object
Chapter 2: Interfaces for programmers 37
The procedure always takes a single argument, being the grob.
That procedure may access the usual value of the property, by ļ¬rst calli ng the function that
is the usual callback for that property, which can by found in the Internals Reference or the ļ¬le
ā€™deļ¬ne-grobs.scmā€™:
\relative {
\override Flag.X-offset = #(lambda (flag)
(let ((default (ly:flag::calc-x-offset flag)))
(* default 4.0)))
c''4. d8 a4. g8
}
It is also possible to get the value of the ex i st i ng default by employing the function
grob-transformer:
\relative {
\override Flag.X-offset = #( grob-transformer 'X-offset
(lambda (flag default) ( * default 4.0)))
c''4. d8 a4. g8
}
hP
h
u
h
ī€…
ĀŖ
P
T
h
From within a callback, the easiest method for evaluating a markup is to use grob -i nterpret-
markup. For example:
my-callback = #(lambda (grob)
(grob-interpret-markup grob (markup "foo")))
2.8 Unpure-pure containers
ā˜›
āœŸ
Note: While this sub su bs ect i on reļ¬‚ect s the curre nt stat e, the given
example is moot and does not show any eļ¬€ect.
āœ” āœ 
Unpure-pure containers are useful for overriding Y-axis spacing calculations ā€“ speciļ¬cally
Y-offset and Y-extent ā€“ with a Scheme function ins t ead of a lit e ral (i.e., a number or pair).
For certain grobs, the Y-extent is base d on the stencil property, overr i di n g t h e stencil
property of one of these will requi r e an additional Y-extent override with an un pu re -p ur e
container. When a function overrid es a Y-offset and/or Y-extent it is assumed that this will
trigger line breaking calculations too ear l y during compilation. So the function is not evaluated
at all (usually retur ni n g a value of ā€˜0ā€™ or ā€˜'(0 . 0)ā€™) which can result in collisions. A ā€˜pureā€™
function will not aļ¬€ect propert ie s, objects or grob suicides and therefore will always h ave its
Y-axis-related evaluated correctly.
Currently, there are about thirty functions that are already c ons id er ed ā€˜pureā€™ and Unpure-
pure containers are a way to set functions not on this list as ā€˜ p ur eā€™ . The ā€˜pureā€™ function is
evaluated before any line-breaking and so t he horizontal spacing can be adjusted ā€˜in timeā€™. The
ā€˜unpureā€™ function is then evaluated
after
line breaking.
ā˜›
āœŸ
Note: As it is diļ¬ƒcult to always know which f un ct i on s are on this list
we recommend that any ā€˜pureā€™ functions you creat e do not use Beam or
VerticalAlignment gr obs .
āœ” āœ 
Chapter 2: Interfaces for programmers 38
An u np ur e -pu r e container is const ru ct e d as fol lows;
(ly:make-unpure-pure-container f0 f1)
where f0 is a function taking n arguments (n >= 1) and the ļ¬ r st argument must always be the
grob. This is the function that gives the actual result. f1 is the function being labeled as ā€˜pureā€™
that takes
n
+
2
arguments. Again, the ļ¬rst argument must always still be the grob but the
second and third are ā€˜startā€™ and ā€˜endā€™ arguments.
start and end are, for all intents and purposes, dummy valu es that only m att e r for Spanners
(i.e Hairpin or Beam), that can return diļ¬€erent height estimations based on a start i ng and
ending column.
The rest are the other arguments to the ļ¬rst function (which may be none if n = 1).
The results of the second function are used as an approximation of the value needed which
is then used by the ļ¬rst function to get the real value which is then used for ļ¬ne-tuning mu ch
later during the spacing process.
#(define (square-line-circle-space grob)
(let* ((pitch (ly:event-property (ly:grob-property grob 'cause)
'pitch))
(notename (ly:pitch-notename pitch)))
(if (= 0 ( modulo notename 2))
(make-circle-stencil 0.5 0.0 #t)
(make-filled-box-stencil '(0 . 1.0)
'(-0.5 . 0.5)))))
squareLineCircleSpace = {
\override NoteHead.stencil = #square-line-circle-space
}
smartSquareLineCircleSpace = {
\
squareLineCircleSpace
\override NoteHead.Y-extent =
#(ly:make-unpure-pure-container
ly:grob::stencil-height
(lambda (grob start end) (ly:grob::stencil-height grob)))
}
\new Voice \with { \remove Stem_engraver }
\relative c'' {
\squareLineCircleSpace
cis4 ces disis d
\smartSquareLineCircleSpace
cis4 ces disis d
}
ī€‚ī€š
ī€•
ī€
ī€š
ī€…
ĀŖ
ī€ ī€•
ī€‚
In the ļ¬rst measure, without the unpure-pure container, the spacing engine does not know the
width of the note head and lets it collide with the accidentals. In the second measure, with
unpure-pure containers, the spacing en gi ne knows the width of the note heads and avoids the
collision by lengthening the line accordingly.
Chapter 2: Interfaces for programmers 39
Usually for simple c alc ul at i ons nearly-ide ntical functions for both the ā€˜unpureā€™ and ā€˜pureā€™
parts can be used, by only changing the number of arguments passed to, and the scope of, the
function. This use case is frequent enough that ly:make-unpure-pure-container const ru ct s
such a secon d f un ct i on by default when call ed with only one functi on argum ent.
ā˜›
āœŸ
Note: If a function is labeled as ā€˜pureā€™ and it turns out not to be, the
results can be unexpected.
āœ” āœ 
2.9 Diļ¬ƒcult tweaks
There are a f ew c l asse s of diļ¬ƒc ul t adjustments.
ā€¢ One type of diļ¬ƒcult adjustment involves the appe aran ce of spanner objects, such as slurs
and ties . Usually, on l y one spanner object is created at a time, and it can be ad j us t ed with
the normal mechanism. However, occasionally a spanner crosses a line break. When this
happens, the object is cloned. A separate object is created for every system in whi ch the
spanner appears. Th e new objects are clones of the original object and inherit all properties,
including \overrides.
In other words, an \override always aļ¬€e ct s all pieces of a broken spanner. To change only
one part of a spanner at a line break, it is necessary to hook into the formatting process.
The after-line-breaking callback contains the Scheme procedure that is called after the
line breaks have been determined and layout objects have been split over diļ¬€erent systems.
In t h e foll owing example, we deļ¬ne a procedure
my-callback
. This procedure
ā€¢ determines if the spanner has been split across line breaks
ā€¢ if yes, retrieves all the split objects
ā€¢ checks if this grob is the last of the split objects
ā€¢ if yes, it sets extra-offset.
This procedure is installed into Section ā€œTieā€ i n Internals Reference, so the last part of the
broken tie is repositioned.
#(define (my-callback grob)
(let* (
;; have we been split?
(orig (ly:grob-original grob))
;; if yes, get the split pieces (our siblings)
(siblings (if (ly:grob? orig)
(ly:spanner-broken-into orig)
'())))
(if (and (>= (length siblings) 2)
(eq? (car (last-pair siblings)) grob))
(ly:grob-set-property! grob 'extra-offset '(1 . -4)))))
\relative {
\override Tie.after-line-breaking =
#my-callback
c''1 ~ \break
c2 ~ 2
}
Chapter 2: Interfaces for programmers 40
.
ī€…
ĀŖ
N
ī€…
2
N
When applying this trick, the new after-line-breaking callback should also call
the old one, if such a default exists. For example, if u si n g this with Hairpin,
ly:spanner::kill-zero-spanned-time sh oul d als o be called.
ā€¢ Some objects cannot be changed with \override for technical reasons. They can be changed
with the \overrideProperty function, which works similar to \once \override, but uses
a di ļ¬€e re nt syntax.
1
\overrideProperty [ContextName].GrobName.property-name[.subproperty-name] value
1
Over time, \overrideProperty is being replaced with the more usual \once \override command. If you still
ļ¬nd yourself needing \overrideProperty, a bug report would be appreciated.
41
3 LilyPond Scheme interfaces
This chapter covers the various tools provided by LilyPond to help Scheme pr ogram mer s get
information into and out of the music streams.
TODO ā€“ ļ¬gure out what goes in here and how to or gani ze it
42
Appendix A GN U Free Documentati on Licens e
Version 1.3, 3 November 2008
Copyright
c
āƒ 2000, 2001, 2002, 2007, 2008 Free Software Foun dat i on, Inc.
https://fsf.org/
Everyone is permitted to copy and distribute verbatim copies
of t h is li c en se document, but changing it is not allowed.
0. PREAMBLE
The purpose of this License is to make a manual, textbook, or other fun ct i onal and useful
document free in the sense of freedom: to assure everyone the eļ¬€ective freedom to copy
and redistribute it, with or without modifyi ng it, either commercially or noncommercially.
Secondarily, this License pr es er ves for the author and publisher a way to get credit for their
work, while not being considered responsible for modiļ¬cations made by others.
This License is a kind of ā€œcopyleftā€, which means t h at derivative works of the document
must the mse l ves be free in the same sense. It complements the GNU General Public License,
which is a copyleft license designed for free software.
We have designed this License in order to use it for manuals for free software, because free
software needs free documentation: a free program should come with manuals providing the
same freedoms that the software does. But this License is not limited to software manuals;
it can be used for any textual work, regardless of subject matter or whether it is published
as a printed book. We recommend this License principally for works whose purpose is
instruction or reference.
1. APPLICABILITY AND DEFINITIONS
This License applies to any manual or other work, in any medium, that contains a not i ce
placed by the copyright holder saying it can be distributed under the terms of this License.
Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use th at
work under the conditions stated herein. The ā€œDocumentā€, below, refers to any such manual
or work. Any member of the public is a licensee, and is addre sse d as ā€œyouā€. You accept
the license if you copy, modify or distribu t e the work in a way requiring permission under
copyright law.
A ā€œModiļ¬ed Versionā€ of the Document means any work containing the Document or a
portion of it, either copied verbatim, or wi t h modiļ¬cations and/or translated into another
language.
A ā€œSecondary Sectionā€ is a named appendix or a front-matter section of the Document
that deals exclusively with the relationship of the publishers or authors of the Document
to the Documentā€™s overall subject (or to related matters) and contains nothing that could
fall directly within that overall subject. (Thus, if the Docume nt is in part a tex t book of
mathematics, a Secondary Secti on may not explain any mathematics.) The relationship
could be a matter of historical connection with the subject or with related matters, or of
legal, commercial, philosophical, ethical or political position regardin g th em .
The ā€œInvariant Sectionsā€ are certain Secondary Se ct i ons whose titles are designated, as
being those of Invariant Sections, in the notice that says that the Document is released
under this License. If a section does not ļ¬t the above deļ¬nition of Secondary then it is not
allowed to be designated as Invariant. The D ocument may contain zero Invariant Sect i on s.
If t h e Document does not identify any Invariant Sections then there are none.
The ā€œCover Textsā€ are certain short passages of text that are listed, as Front-Cover Texts or
Back-Cover Texts, in the notice that says that the Document is released under this License.
A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25
words.
Appendix A: GNU Free Documentation License 43
A ā€œTransparentā€ copy of the Document means a machine-readable copy, represented in a
format whose speci ļ¬c at i on is available to the general pub l ic , that is suitable for revising
the docu ment straightforwardly with generic text editors or (for images composed of pixels)
generic pai nt programs or (for drawings) some widely available drawing editor, and th at is
suitable for input to text formatters or for automatic translation to a variety of formats
suitable for input to text formatters. A copy made in an otherw is e Transparent ļ¬l e format
whose markup, or absence of markup, has been arranged to thwart or discourage subsequent
modiļ¬cation by readers is not Transparent. An image format is not Tran sp are nt if used for
any su bs tantial amount of text. A copy that is not ā€œTransp ar entā€ is called ā€œOpaqueā€.
Examples of suitable formats for Transparent copies include plain ASCII wi t hou t m ark u p,
Texinfo input format, LaT
E
X input format, SGML or XML using a publicly available DTD,
and standard-conforming simple HTML, PostScrip t or PDF designed for human modiļ¬-
cation. Examples of transp are nt image formats include PNG, XCF and JPG. Opaque
formats include proprietar y formats that can be read and edited only by proprietary word
processors, SGML or XML for which the DTD and/or processing tools are not generally
available, and the machine-generated HTML, PostScript or PDF produced by some word
processors for output purposes only.
The ā€œTitle Pageā€ means, for a pri nted book, the title page itself, plus such following pages
as are needed to hold, legibly, the material this License requires to appear i n the title page.
For works in formats which do not have any title page as such, ā€œTitle Pageā€ means the
text near the most prominent appearan ce of the workā€™s title, preceding the beginning of the
body of the te x t .
The ā€œpublisher ā€ means any person or entity that distributes copies of the Document to the
public.
A section ā€œEntitled XYZā€ means a named subunit of the Document whose title either
is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in
another language. (Here XYZ stands for a speciļ¬c section name mentioned below, such
as ā€œAcknowledgementsā€, ā€œDed i cat i ons ā€, ā€œEndorsementsā€, or ā€œHistoryā€.) To ā€œPreserve the
Titleā€ of such a section when you modify the Do cu me nt means that it remains a section
ā€œEntitled XYZā€ according to this deļ¬nition.
The Document may include Warranty Disclaimers next to the notice which states that
this License applies to the Document. These Warranty Dis cl ai mer s are considered to be
included by reference in this License, but only as regards disclaiming warranties: any ot h er
implication that these Warranty Disclaimers may have is void and has no eļ¬€ect on the
meaning of this License.
2. VERBATIM COPYING
You may copy and distribute th e Document i n any med i um , either commercially or noncom-
mercially, provided that this License, the copyri ght notices, and the license notice say i ng
this License applies t o the D ocument are reproduced in all copies, and that you add no
other conditi on s whatsoever to th ose of this License. You m ay not use technical measures
to obstruct or control the reading or further copying of the copies you make or distribute.
However, you may accept compensation in exchange for copies. If you distribute a large
enough number of c opi e s you must also follow the conditions in section 3.
You may also lend copies, under the same conditions stated above, and you may publicly
display copies.
3. COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly have printed covers) of the
Document, numbering more than 100, and the Documentā€™s license notice requires Cover
Texts, you must enclose the copies in covers that carry, clearly and legib l y, all these Cover
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both
Appendix A: GNU Free Documentation License 44
covers must also clearly and legibly id entify you as the pub li s he r of these copi es . The front
cover must present the fu l l title with all words of the title equal l y prominent and visible.
You may add other material on the covers in addition. Copying with changes limited to
the covers, as long as they preserve the title of the Document and satisfy these conditions,
can be tr eat e d as verbatim copying in other respects.
If the requi re d texts for either cover are too voluminous to ļ¬t legibly, you should put the
ļ¬rst ones listed (as many as ļ¬t reasonably) on th e actual cover, and continue the rest onto
adjacent pages.
If you publish or distribute Opaque copies of the Document numbering more than 100, you
must eit h er include a machine-readabl e Transparent copy along with each Opaque copy,
or state in or with each Opaque copy a computer-network location from which the general
network-using public has access to download using public-standard network protocols a
complete Transparent copy of the Document, free of added material. If you use the latter
option, you must take reasonably prudent steps, when you begin distribution of Opaque
copies in quantity, to ensure that this Tran sp ar ent copy will remain thus accessible at the
stated location until at least one year after the last time you distribute an Opaque copy
(directly or through your agents or retailers) of that edition to the public.
It is request e d, but not required, that you contact the authors of t h e Document well before
redistributing any large number of copies, to give them a ch an ce to provide you with an
updated version of the Document.
4. MODIFICATIONS
You may copy and distribute a Modiļ¬ed Version of the Document under the conditions
of sections 2 and 3 above, provided that you release the Modiļ¬ed Version under precisely
this License, with the Modiļ¬ed Version ļ¬lling the role of the Document, thus licensing
distribution and modiļ¬cation of the Modiļ¬ed Version to whoever possesses a copy of it. In
addition, you must do these th i ngs in t he M odiļ¬e d Vers ion :
A. Use in the Title Page ( and on the covers, if any) a title dist i nc t from that of the
Document, and from those of previous vers ion s (which should, i f there were any, be
listed in the Hist ory section of th e Document). You may use the same title as a previous
version if the original publisher of that version gives permission.
B. List on the Title Page, as authors, one or more persons or entities responsible for
authorship of the modiļ¬cations in t h e Modiļ¬ed Version, together with at least ļ¬ve of
the principal authors of the Document (all of its principal authors, if it has fewer than
ļ¬ve), unless they release you from this requirement.
C. State on the Title page the name of the publisher of the Modiļ¬ed Version, as the
publisher.
D. Preserve all the copyright notices of the Document.
E. Add an appropriate copyright notice for your modiļ¬cations adjacent to the other copy-
right notices.
F. Include, immediately after the copyright notices, a license notice givi n g the public
permission to use the Modiļ¬ed Version under the terms of this License, in the form
shown i n th e Add en d um below.
G. Preserve in that license notice the full lists of Invariant Sections and r eq u i re d Cover
Texts given in the Documentā€™s license notice.
H. Include an unaltered copy of this License.
I. Preserve the section Entitled ā€œHistoryā€, Preserve its Title, and add to it an item stating
at least the title, year, new authors, and publishe r of the Modiļ¬ed Version as gi ven
on the Title Page. If there is no section Entitled ā€œHistoryā€ in the Document, cr eat e
one stating the title, year, authors, and publ i sh er of the Document as given on its
Appendix A: GNU Free Documentation License 45
Title Page, then add an item describing the Modiļ¬ed Vers ion as stated in the previous
sentence.
J. Preserve the network location, if any, given in the Docu ment for public access to a
Transparent copy of the Document, and likewise the network locations given in the
Document for previous versions it was based on. These may be placed in the ā€œHistoryā€
section. You may omit a network location for a work that was published at least four
years before the Document itself, or if the original publisher of the version it refers to
gives permission.
K. For any section Entitled ā€œAcknowledgementsā€ or ā€œDedicationsā€, Preserve t h e Title
of the section, and preserve in the section all the substance and tone of each of the
contributor acknowledgements and/or dedications given therein.
L. Preserve all the Invariant Sections of th e Document, unaltered in their text and in t h ei r
titles. Section numbers or the equivalent are not considered part of the section titles.
M. Delete any section Entitled ā€œEndorsementsā€. Such a section may not be included in
the Modiļ¬ed Version.
N. Do not retitle any existing secti on to be Entitled ā€œEndorsementsā€ or to conļ¬‚ict in title
with any Invariant S ec t ion .
O. Preserve any Warranty Disclaimers.
If the Modiļ¬ed Version includes new front-matter sections or appendi ces that qualify as
Secondary Sections and contain no material copied from the Document, you may at your
option design at e some or all of these sections as invariant. To do this, add their titles to
the list of Invariant Sections in the Mo d iļ¬ ed Versionā€™s license notice. These titles must be
distinct from any other section titles.
You may add a section E ntitled ā€œEndorsementsā€, provid ed it contains nothing but endorse-
ments of your Modiļ¬ed Version by various partie sā€”f or example, statements of peer review
or that the text has been approved by an organization as the authoritative deļ¬nition of a
standard.
You may add a passage of up to ļ¬ve words as a Front-Cover Text, and a passage of up
to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modiļ¬ed
Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added
by (or through arrangements made by) any one entity. If the Document already includes
a cover text for the same cover, previously added by you or by arrangement made by t h e
same entity you are acting on behalf of, you may not ad d another; but you may replace the
old one, on explicit permission from the previous publisher that added the old one.
The author(s) and publisher(s) of the Document d o not by thi s License gi ve permi s si on to
use their names for publicity for or to assert or imply endorseme nt of any Modiļ¬ed Version.
5. COMBINING DOCUMENTS
You may combine the Document with other documents released under this License, under
the ter ms deļ¬ned in section 4 above for modiļ¬ed versions, provided that you incl u de in the
combination all of the Invariant Sections of all of the original documents, unmodiļ¬ed, and
list them all as Invariant Sections of your combined work in its license notice, and that you
preserve all their Warranty Disclaimers.
The combined work need only contain one copy of this License, and mu l t ip l e identical
Invariant Sect ion s may be replaced with a single copy. If there are multiple Invariant
Sections with the same name but diļ¬€erent contents, make the tit l e of each such section
unique by adding at the end of it, in parentheses, t h e name of the original author or
publisher of that section if k nown, or else a unique number. Make the same adjustment to
the section titles in the list of Invariant Sections in the license notice of the combined work.
Appendix A: GNU Free Documentation License 46
In the combination, you must combine any sections Entitled ā€œHistoryā€ in the various original
documents, f orm i ng one section Entitled ā€œHistoryā€; likewise combine any sect i on s Entitled
ā€œAcknowledgementsā€, and any s ect i on s Entitled ā€œDedicationsā€. You must delete all sections
Entitled ā€œEndorsements.ā€
6. COLLECTIONS OF DOCUMENTS
You may make a collecti on consisting of the Document and other documents released under
this License, and replace the individual copies of th is License in the various do c um ents with
a single copy that is included in the collection, provided that you follow the rules of this
License for verbatim copying of each of the documents in all other respects.
You may extract a single document from s uch a col l ec t i on, and distribute it individually
under this License, provided you inse rt a copy of this License into the ext r act ed document,
and follow this License in all other respects regarding verbatim copying of that document.
7. AGGREGATION WITH INDEPENDENT WORKS
A compilation of the Document or its derivatives with other separate and independent
documents or works, in or on a volume of a storage or distribution medium, is called an
ā€œaggregateā€ if the copyright resulting from the compilation is not used to limi t the legal
rights of the compilationā€™s users beyond what the individual works permit. When the
Document is incl u de d in an aggregate, this License does not apply to the other works in
the aggregate which are not themselves derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these copies of the Document,
then if the Document is less than one half of the entire aggregate, the Documentā€™s Cover
Texts may be placed on covers that bracket the Document within the aggregate, or the
electronic equivalent of covers if the Document is in electronic form. Otherwise they must
appear on p ri nted covers that bracket the whol e aggregat e.
8. TRANSLATION
Translation is considered a kind of modiļ¬cati on, so you may distribute translations of the
Document under the terms of section 4. Replacing Invar iant Sections with translations
requires spec i al permission from their copyright holders, but you may include translations
of some or all Invariant Sect i ons in addition to the ori gin al versions of these Invariant
Sections. You may include a translation of this License, and all t h e license notices in
the Document, and any Warranty Disclaimers, provided that you also include t he original
English version of this License and the original versions of those notices and disclaimers. In
case of a disagreement between the translation and the original version of this License or a
notice or disclaimer, the original version will prevail.
If a section in the Document is Entitled ā€œAcknowledgementsā€, ā€œDedicationsā€, or ā€œHi st or yā€,
the requirement (sec t i on 4) to Prese rve its Title (section 1) will typically require changing
the actual title.
9. TERMINATION
You may not copy, modify, sublicense, or distribute the Document except as expressly pro-
vided under this License. Any attempt ot he rw is e to copy, modify, sublicense, or distribute
it is void, and will automatically terminate your rights under this License.
However, if you cease all violation of this License, then your license from a particular copy-
right holder is reinstated (a) provisionally, unless and until the copyright holder explicitly
and ļ¬nally terminates your license, and (b) perman ently, if the copyright holder fails to
notify you of the violation by some reasonable means prior to 60 days after the cessation.
Moreover, your license from a parti c ul ar copyright holder is reinstated permanently if the
copyright holder notiļ¬es you of the violation by some reasonable means, this is the ļ¬rst
time you have received notice of violation of this License (for any work) from that copyright
holder, and you cure the violation prior to 30 days after your receipt of the notice.
Appendix A: GNU Free Documentation License 47
Termination of your rights under this section does not terminate the licens es of parties
who have received copies or rights from you un de r this License. If your rights have been
terminated and not permanently reinstated, receipt of a copy of some or all of the same
material does not give you any rights to use it.
10. FUTURE REVISIONS OF THIS LICENSE
The Free Software Foundation may publish new, revised versions of the G NU Free Doc-
umentation License from time to time. Such new versions will be similar in spirit to the
present version, but may diļ¬€er in detail to address new problems or concerns. See https://
www.gnu.org/licenses/.
Each version of the License is given a distinguishing version number. If the Docume nt
speciļ¬es that a particular numbered version of this Lic en se ā€œor any later versionā€ applies
to it, you have the option of following the t e rm s and c ond i t ion s ei t h er of that speciļ¬ed
version or of any later version that has been published (not as a draft) by the Free Software
Foundation. If the Document does not specify a version number of this Lic en se, you may
choose any version ever published (not as a draft) by t he Free Software Foundation. If the
Document speciļ¬es that a proxy can decide which future ver si on s of this License can be
used, that proxyā€™s public statement of acceptance of a version permanently aut h ori z es you
to cho os e that version for the D ocume nt.
11. RELICENSING
ā€œMassive Multiauthor Collaboration Siteā€ (or ā€œMMC Siteā€) means any World Wide Web
server th at publishes copyrightable works and also provides prominent facilities for anybody
to edit those works. A public wiki that anybody can edit is an example of such a server. A
ā€œMassive Multiauthor Collaborationā€ (or ā€œMMCā€) contained in the site means any set of
copyrightable works thus published on the MMC site.
ā€œCC-BY-SAā€ means the Creative Commons Attribution-Share Alike 3.0 license published
by Creative Commons Corporation, a not-for-proļ¬t corporation with a principal place of
business in San Francisco, California, as well as future copyleft versions of that license
published by that same organization.
ā€œIncorporateā€ means to publish or republish a Document, in whole or in part, as part of
another Document.
An MMC is ā€œeli gib l e for relicensingā€ if it is licensed under this License, and if all wor k s that
were ļ¬rst published under this License som ewh er e other than this MMC, and subsequently
incorporated in whole or in part into the MMC, (1) had no cover texts or invariant sections,
and (2) were thus incorporated prior to November 1, 2008.
The oper at or of an MMC Site may republish an MMC contained in the site under CC-BY-
SA on the same site at any time before August 1, 2009, provided the MMC is eligible for
relicensing.
Appendix A: GNU Free Documentation License 48
ADDENDUM: How to use thi s License for your documents
To use this License in a document you have written, include a copy of the Lic en se in the document
and put the following copyright and license notices just after the title page:
Copyright (C) year your name.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
Texts. A copy of the license is included in the section entitled ``GNU
Free Documentation License''.
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the
ā€œwith. . . Texts.ā€ line with this:
with the Invariant Sections being list their titles, with
the Front-Cover Texts being list, and with the Back-Cover Texts
being list.
If you have Invariant Sections without Cover Texts, or some other combination of the three,
merge those two alternatives to suit the situation.
If your document contains nontrivial examples of program code, we recommend releasing
these examples in paralle l under your choice of free software license, such as the GNU General
Public License, to permit their use in free software.
49
Appendix B L i ly Pond index
#
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6, 9, 18
##f. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
##t. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
#@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7, 9
#{ ... #} . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
$
$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6, 9, 18
$@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7, 9
A
accessing Scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
\applyContext . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
\applyOutput . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
ApplyOutputEvent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
C
calling co d e during interpreting . . . . . . . . . . . . . . . . . . . 33
calling co d e on layout objects . . . . . . . . . . . . . . . . . . . . . 35
code blocks, LilyPond . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
D
debugging, Scheme code . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
define-event-function . . . . . . . . . . . . . . . . . . . . . . . . . . 24
define-markup-list-command . . . . . . . . . . . . . . . . . . . . 32
define-music-function . . . . . . . . . . . . . . . . . . . . . . . . . . 21
define-scheme-function. . . . . . . . . . . . . . . . . . . . . . . . . 18
define-void-function . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
deļ¬ning markup commands . . . . . . . . . . . . . . . . . . . . . . . 25
deļ¬ning music functions . . . . . . . . . . . . . . . . . . . . . . . . . . 21
displaying music expressions . . . . . . . . . . . . . . . . . . . . . . 12
\displayLilyMusic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
displayMusic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
\displayMusic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
\displayScheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
E
error message, in Scheme code . . . . . . . . . . . . . . . . . . . . . 8
evaluating Scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
event functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
G
GraceMusic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
GUILE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
H
horizontal spac in g , overriding
. . . . . . . . . . . . . . . . . . . . .
37
I
internal representation, displaying . . . . . . . . . . . . . . . . 12
internal storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
interpret-markup. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
interpret-markup-list . . . . . . . . . . . . . . . . . . . . . . . . . . 32
L
LilyPond code blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
LilyPond grammar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
line number, for error message in S cheme code . . . . . 8
LISP
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
ly:assoc-get . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
ly:context-grob-definition . . . . . . . . . . . . . . . . . . . . 33
ly:context-property . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
ly:context-pushpop-property . . . . . . . . . . . . . . . . . . . 33
ly:context-set-property! . . . . . . . . . . . . . . . . . . . . . . 33
M
make-apply-context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Manuals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
\markup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
markup macro. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
markup, to string. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
markup->string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Music classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Music expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
music functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Music prope rti es . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
N
NoteEvent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
NoteHead . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
O
overrides, temporary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
P
Predeļ¬ned type predicates . . . . . . . . . . . . . . . . 19, 20, 21
properties vs. variables . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
properties, popping previous value . . . . . . . . . . . . . . . . 2 2
pure container, Scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
R
RepeatedMusic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Appendix B: LilyPond index 50
S
Scheme. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Scheme functions (LilyPond syntax) . . . . . . . . . . . . . . 18
Scheme, debuggin g . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Scheme, in-line code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Scheme, pure container . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Scheme, unpure container. . . . . . . . . . . . . . . . . . . . . . . . . 37
SequentialMusic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
SimultaneousMusic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
source locat io n s , in error messages
for Scheme code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Stem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Substitution function examples . . . . . . . . . . . . . . . . . . . 21
T
\temporary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
temporary overrides . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Text markup commands . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Tie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
U
unpure container, Scheme. . . . . . . . . . . . . . . . . . . . . . . . . 37
V
variables vs. properties . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
\void. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13, 20