[ << Interfaces for programmers ] | [Top][Contents][Index] | [ LilyPond Scheme interfaces >> ] |
[ < Contexts for programmers ] | [ Up : Contexts for programmers ] | [ Running a function on all layout objects > ] |
2.6.1 Context evaluation
Contexts can be modified during interpretation with Scheme code. In a LilyPond code block, the syntax for this is:
\applyContext function
In Scheme code, the syntax is:
(make-apply-context function)
function
should be a Scheme function that takes a
single argument: the context in which the \applyContext
command is being called. The function can access as well as
override/set grob properties and context properties. Any actions
taken by the function that depend on the state of the context are
limited to the state of the context when the function is
called. Also, changes effected by a call to \applyContext
remain in effect until they are directly modified again, or
reverted, even if the initial conditions that they depended on
have changed.
The following Scheme functions are useful when using
\applyContext
:
ly:context-property
look up a context property value
ly:context-set-property!
set a context property
ly:context-grob-definition
ly:assoc-get
look up a grob property value
ly:context-pushpop-property
do a
\temporary \override
or a\revert
on a grob property
The following example looks up the current fontSize
value, and
then doubles it:
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' }
The following example looks up the current colors of the
NoteHead
, Stem
, and Beam
grobs, and then changes
each to a less saturated shade.
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] }
This also could be implemented as a music function, in order to
restrict the modifications to a single music block. Notice how
ly:context-pushpop-property
is used both as a
\temporary \override
and as a \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 }
[ << Interfaces for programmers ] | [Top][Contents][Index] | [ LilyPond Scheme interfaces >> ] |
[ < Contexts for programmers ] | [ Up : Contexts for programmers ] | [ Running a function on all layout objects > ] |