GNU LilyPond – Extension des fonctionnalités: 2.6.1 Évaluation d'un contexte

### 2.6.1 Évaluation d’un contexte

Un contexte peut être modifié, au moment même de son interprétation, par du code Scheme. La syntaxe consacrée au sein d’un bloc LilyPond est

>     \applyContext fonction

et, dans le cadre d’un code Scheme :

>     (make-apply-context fonction)

`fonction` est constitué d’une fonction Scheme comportant un unique argument : le contexte au sein duquel la commande `\applyContext` est appelée. Cette fonction peut accéder aussi bien aux propriétés de grob (y compris modifiées par `\override` ou `\set`) qu’aux propriétés de contexte. Toute action entreprise par la fonction et qui dépendrait de l’état du contexte sera limitée à l’état de ce contexte au moment de l’appel à la fonction. Par ailleurs, les adaptations résultant d’un appel à `\applyContext` seront effectives jusqu’à ce qu’elles soient à nouveau directement modifiées ou bien annulées, quand bien même les conditions initiales dont elles dépendent auraient changé.

Voici quelques fonctions Scheme utiles avec `\applyContext` :

`ly:context-property`

  recherche la valeur d’une propriété de contexte,

`ly:context-set-property!`

  détermine une propriété de contexte,

`ly:context-grob-definition`
`ly:assoc-get`

  recherche la valeur d’une propriété de grob,

`ly:context-pushpop-property`

  réalise un `\temporary \override` ou un `\revert` sur une propriété de grob.

L’exemple suivant recherche la valeur en cours de `fontSize` puis la double :

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

L’exemple suivant recherche la couleur des objets `NoteHead`, `Stem` et `Beam`, puis diminue pour chacun d’eux le degré de saturation.

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

Ceci pourrait tout à fait s’implémenter sous la forme d’une fonction musicale, afin d’en réduire les effets à un seul bloc de musique. Notez comment `ly:context-pushpop-property` est utilisé à la fois pour un `\temporary \override` et pour un `\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
>     }

#### LilyPond — Extension des fonctionnalités v2.22.2 (branche stable).