Previous: Internal music representation, Up: Programmer interfaces for input



C.1.3 Manipulating music expressions

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 } }

[image of music]

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)

See also

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).

Report errors to <bug-lilypond@gnu.org>.