Manipulating music expressions - GNU LilyPond
Description: GNU LilyPond

Next: Displaying music expressions, Previous: Extending music syntax, Up: Programmer interfaces for input

#### 11.1.4 Manipulating music expressions

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, 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 (eg. `input/no-notation/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`.

This page is for LilyPond-2.8.8 (stable-branch).

Other languages: English.
Using automatic language selection.