5.1.6 Defining new contexts

Specific contexts, like Staff and Voice, are made from simple building blocks. It is possible to create new types of contexts with different combinations of engraver plug-ins.

The next example shows how to build a different type of Voice context from scratch. It will be similar to Voice, but only prints centered slash note heads. It can be used to indicate improvisation in jazz pieces,

[image of music]

These settings are defined within a \context block inside a \layout block,

\layout {
  \context {
    …
  }
}

In the following discussion, the example input shown should go in place of the … in the previous fragment.

First it is necessary to define a name for the new context:

\name ImproVoice

Since it is similar to the Voice context, we want commands that work in (existing) Voice contexts to continue working. This is achieved by giving the new context an alias of Voice,

\alias Voice

The context will print notes and instructive texts, so we need to add the engravers which provide this functionality, plus the engraver which groups notes, stems and rests which occur at the same musical moment into columns,

\consists "Note_heads_engraver"
\consists "Text_engraver"
\consists "Rhythmic_column_engraver"

The note heads should all be placed on the center line,

\consists "Pitch_squash_engraver"
squashedPosition = #0

The Pitch_squash_engraver modifies note heads (created by the Note_heads_engraver) and sets their vertical position to the value of squashedPosition, in this case 0, the center line.

The notes look like a slash, and have no stem,

\override NoteHead.style = #'slash
\hide Stem

All these plug-ins have to communicate under the control of the context. The mechanisms with which contexts communicate are established by declaring the context \type. Within a \layout block, most contexts will be of type Engraver_group. Some special contexts and contexts in \midi blocks use other context types. Copying and modifying an existing context definition will also fill in the type. Since this example creates a definition from scratch, it needs to be specified explicitly.

\type "Engraver_group"

Put together, we get

\context {
  \name ImproVoice
  \type "Engraver_group"
  \consists "Note_heads_engraver"
  \consists "Text_engraver"
  \consists "Rhythmic_column_engraver"
  \consists "Pitch_squash_engraver"
  squashedPosition = #0
  \override NoteHead.style = #'slash
  \hide Stem
  \alias Voice
}

Contexts form hierarchies. We want to place the ImproVoice context within the Staff context, just like normal Voice contexts. Therefore, we modify the Staff definition with the \accepts command,

\context {
  \Staff
  \accepts ImproVoice
}

Often when reusing an existing context definition, the resulting context can be used anywhere where the original context would have been useful.

\layout {
  …
  \inherit-acceptability to from
}

will arrange to have contexts of type to accepted by all contexts also accepting from. For example, using

\layout {
  …
  \inherit-acceptability "ImproVoice" "Voice"
}

will add an \accepts for ImproVoice to both Staff and RhythmicStaff definitions.

The opposite of \accepts is \denies, which is sometimes needed when reusing existing context definitions.

Arranging the required pieces into a \layout block leaves us with

\layout {
  \context {
    \name ImproVoice
    …
  }
  \inherit-acceptability "ImproVoice" "Voice"
}

Then the output at the start of this subsection can be entered as

\relative {
  a'4 d8 bes8
  \new ImproVoice {
    c4^"ad lib" c
    c4 c^"undress"
    c c_"while playing :)"
  }
  a1
}

To complete this example, changes affecting the context hierarchy should be repeated in a \midi block so that Midi output depends on the same context relations.

Vegeu també

Internals Reference: Note_heads_engraver, Text_engraver, Rhythmic_column_engraver, Pitch_squash_engraver.


Altres idiomes: English, deutsch, español, français, italiano, 日本語.
Quant a la selecció automàtica de la llengua.

LilyPond — Referència de la notació v2.21.0 (branca de desenvolupament).