Next: Using LilyPond syntax inside Scheme, Previous: Extending music syntax, Up: Programmer interfaces for input
Music objects and their properties can be accessed and manipulated
directly, through the \applymusic
mechanism.
The syntax for \applymusic
is
\applymusic #func music
This means that the Scheme function func is called with
music as its argument. The return value of func is the
result of the entire expression. func may read and write music
properties using the functions ly:music-property
and
ly:music-set-property!
.
An example is a function that reverses the order of elements in its argument,
#(define (rev-music-1 m) (ly:music-set-property! m 'elements (reverse (ly:music-property m 'elements))) m) \applymusic #rev-music-1 { c'4 d'4 }
The use of such a function is very limited. The effect of this function is void when applied to an argument that does not have multiple children. The following function application has no effect
\applymusic #rev-music-1 \grace { c4 d4 }
In this case, \grace
is stored as
GraceMusic (lilypond-internals)
, which
has no elements
, only a single element
. Every generally
applicable function for \applymusic
must – like music expressions
themselves – be recursive.
The following example is such a recursive function: It first extracts
the elements
of an expression, reverses them and puts them
back. Then it recurses, both on elements
and element
children.
#(define (reverse-music music) (let* ((elements (ly:music-property music 'elements)) (child (ly:music-property music 'element)) (reversed (reverse elements))) ; set children (ly:music-set-property! music 'elements reversed) ; recurse (if (ly:music? child) (reverse-music child)) (map reverse-music reversed) music))
A slightly more elaborate example is in input/test/reverse-music.ly.
Some of the input syntax is also implemented as recursive music functions. For example, the syntax for polyphony
<<a \\ b>>
is actually implemented as a recursive function that replaces the above by the internal equivalent of
<< \context Voice = "1" { \voiceOne a } \context Voice = "2" { \voiceTwo b } >>
Other applications of \applymusic
are writing out repeats
automatically (input/test/unfold-all-repeats.ly),
saving keystrokes (input/test/music-box.ly) and
exporting LilyPond input to other formats
(input/no-notation/to-xml.ly).
When writing a music function, it is often instructive to inspect how
a music expression is stored internally. This can be done with the
music function \displayMusic
.
scm/music-functions.scm, scm/music-types.scm, input/test/add-staccato.ly, input/test/unfold-all-repeats.ly, and input/test/music-box.ly.
This page is for LilyPond-2.5.11 (development-branch).