[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.6 Contexts for programmers


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

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

[image of music]

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

[image of music]

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
}

[image of music]


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.6.2 Running a function on all layout objects

The most versatile way of tuning an object is \applyOutput which works by inserting an event into the specified context ( (internals)ApplyOutputEvent section ‘ApplyOutputEvent’ in Internals Reference). Its syntax is either

 
\applyOutput Context proc

or

 
\applyOutput Context.Grob proc

where proc is a Scheme function, taking three arguments.

When interpreted, the function proc is called for every layout object (with grob name Grob if specified) found in the context Context at the current time step, with the following arguments:

In addition, the cause of the layout object, i.e., the music expression or object that was responsible for creating it, is in the object property cause. For example, for a note head, this is a (internals)NoteHead section ‘NoteHead’ in Internals Reference event, and for a stem object, this is a (internals)Stem section ‘Stem’ in Internals Reference object.

Here is a function to use for \applyOutput; it blanks note-heads on the center-line and next to it:

 
#(define (blanker grob grob-origin context)
   (if (< (abs (ly:grob-property grob 'staff-position)) 2)
       (set! (ly:grob-property grob 'transparent) #t)))

\relative {
  a'4 e8 <<\applyOutput Voice.NoteHead #blanker a c d>> b2
}

[image of music]

To have function interpreted at the Score or Staff level use these forms

 
\applyOutput Score…
\applyOutput Staff…

[ < ] [ > ]   [ << ] [ Up ] [ >> ]

This document was generated by gub on July 13, 2020 using texi2html 1.82.

Jiné jazyky: deutsch, español, français.
O automatickém výběru řeči.