Music objects and their properties can be accessed and manipulated
directly, through the \apply
mechanism.
The syntax for \apply
is
\apply #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) \score { \notes \apply #rev-music-1 { c4 d4 } }
The use of such a function is very limited. The effect of this function is void when applied to an argument which is does not have multiple children. The following function application has no effect:
\apply #rev-music-1 \grace { c4 d4 }
In this case, \grace
is stored as GraceMusic, which has no
elements
, only a single element
. Every generally
applicable function for \apply
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 \apply
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/test/to-xml.ly)
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.
Read comments on this page, or
add one.
This page is for LilyPond-2.2.6 (stable-branch). |