5.1.6 Defining new contexts

Context definition overview

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 that provide this functionality, plus the engraver that groups notes, stems, and rests occurring 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 should look like a slash without a 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 are of type Engraver_group. Some special contexts 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. Doing

\layout {
  …
  \inherit-acceptability to from
}

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

\layout {
  …
  \inherit-acceptability ImproVoice Voice
}

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

See also

Internals Reference: Contexts, Engravers and Performers.

New contexts in MIDI

In MIDI output, the syntax for defining new context types is the same, except that the \context block should be placed inside a \midi block, and the \type should normally be Performer_group rather than Engraver_group. The term engraver refers to a context plug-in that creates visual output. A performer, on the other hand, is relevant in MIDI output only. When plug-ins have “translator” in their name rather than “engraver” or “performer”, they are relevant for both graphical and audio output. Thus, when adapting a context definition for the \midi block, you need to

Please note that, in order to maintain consistent interpretation between graphical and MIDI output, it is recommended to copy any custom context definition in a \midi block. It should at the minimum include those commands that specify the context hierarchy, such as \accepts, \defaultchild, and \inherit-acceptability. Copying aliases is advised as well.

Thus, to complete the example above, the following can be added:

\midi {
  \context {
    \name ImproVoice
    \type Performer_group
    \alias Voice
    \consists Note_performer
    \consists Beam_performer
    \consists Dynamic_performer
    \consists Tie_performer
    \consists Slur_performer
  }
  \context {
    \Staff
    \accepts ImproVoice
  }
}

This makes the ImproVoice context also work in MIDI output.

Replacing the Score context

In order to write a context MyScore that acts as the topmost context, as the Score context usually does, use \inherit-acceptability MyScore Score. The following example defines a ProportionalScore context where proportional notation is enabled (see Proportional notation).

\layout {
  \context {
    \Score
    \name ProportionalScore
    \alias Score
    proportionalNotationDuration = \musicLength 8
  }
  \inherit-acceptability ProportionalScore Score
}

music = { c'1 2 4 8 16 16 }

\new Score \music
\new ProportionalScore \music

[image of music]

Since the topmost context needs to contain a number of fundamental engravers, inheriting settings with \Score is easiest in most cases. If you nevertheless define a score-level context from scratch without inheriting the Score definition, the argument to \type should be Score_engraver (or Score_performer in \midi) rather than Engraver_group. Furthermore, giving the topmost context the Score alias is strongly recommended given that a number of engravers need to access the topmost context using its alias.


LilyPond Notation Reference v2.25.22 (development-branch).