lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Tip: defining new contexts ... starting from existing contexts


From: Trevor Bača
Subject: Tip: defining new contexts ... starting from existing contexts
Date: Sat, 21 Jul 2007 11:16:56 -0500

Hi,

The following is a short write-up on how to define new contexts
starting from existing contexts. The tip augments 9.2.7 "Defining new
contexts" which explains how to define new contexts starting from
scratch.

Consider the following red-and-blue score.

%%% EX 1 %%%

  \version "2.11.26"

  \new Score <<
     \new Staff \with {
        \override NoteHead #'color = #red
        \override Stem #'color = #red
      } {
        c'4 c'4 c'4 c'4
      }
     \new Staff \with {
        \override NoteHead #'color = #blue
        \override Stem #'color = #blue
      } {
        c'4 c'4 c'4 c'4
      }
  >>

%%% EX 1 %%%


The red-and-blue score in example 1 instantiates two separate staves,
reddens the with-block of the first staff, and then turns the
with-block of the second staff blue.

This approach works great but mixes formatting directives and note
entry together. Maybe externalizing our overrides will give us a
cleaner inputfile.

9.2.6 "Changing context default settings" tells us how change contexts
globally. But this approach is unavailable to us here.

%%% EX 2 %%%

  \version "2.11.26"

  \layout {
     \context {
        \Staff
        \override NoteHead #'color = #red
        \override Stem #'color = #red
        \override NoteHead #'color = #blue
        \override Stem #'color = #blue
     }
  }

  \new Score <<
     \new Staff {
        c'4 c'4 c'4 c'4
      }
     \new Staff {
        c'4 c'4 c'4 c'4
      }
  >>

%%% EX 2 %%%

We can't override the global staff context to be both red and blue.
When we try, the interpreter overwrites our red overrides with our
blue overrides. Our red-and-blue score comes out only blue.


Instead, we've got two different types of staff. So we define two new contexts.

9.2.7 "Defining new contexts" tells us how to define new contexts from
scratch. But the default staff context does an awful lot of work. And
defining new staff contexts from scratch is a pain.

%%% EX 3 %%%

  \version "2.11.26"

  \layout {
     \context {
        \type "Engraver_group"
        \name "RedStaff"
        \consists "Output_property_engraver"
        \consists "Bar_engraver"
        \consists "Font_size_engraver"
        \consists "Volta_engraver"
        \consists "Separating_line_group_engraver"
        \consists "Dot_column_engraver"
        \consists "Staff_collecting_engraver"
        \consists "Ottava_spanner_engraver"
        \consists "Clef_engraver"
        \consists "Key_engraver"
        \consists "Time_signature_engraver"
        \consists "Ledger_line_engraver"
        \consists "Staff_symbol_engraver"
        \consists "Collision_engraver"
        \consists "Rest_collision_engraver"
        \consists "Accidental_engraver"
        \consists "Piano_pedal_engraver"
        \consists "Piano_pedal_align_engraver"
        \consists "Instrument_name_engraver"
        \consists "String_number_engraver"
        \consists "Axis_group_engraver"
        \consists "Figured_bass_engraver"
        \consists "Figured_bass_position_engraver"
        \consists "Script_row_engraver"
        localKeySignature = #'()
        createSpacing = ##t
        ignoreFiguredBassRest = ##t
        instrumentName = #'()
        shortInstrumentName = #'()
        \defaultchild "Voice"
        \accepts "Voice"
        \accepts "CueVoice"
        \override NoteHead #'color = #red
        \override Stem #'color = #red
     }
     \context {
        \type "Engraver_group"
        \name "BlueStaff"
        \consists "Output_property_engraver"
        \consists "Bar_engraver"
        \consists "Font_size_engraver"
        \consists "Volta_engraver"
        \consists "Separating_line_group_engraver"
        \consists "Dot_column_engraver"
        \consists "Staff_collecting_engraver"
        \consists "Ottava_spanner_engraver"
        \consists "Clef_engraver"
        \consists "Key_engraver"
        \consists "Time_signature_engraver"
        \consists "Ledger_line_engraver"
        \consists "Staff_symbol_engraver"
        \consists "Collision_engraver"
        \consists "Rest_collision_engraver"
        \consists "Accidental_engraver"
        \consists "Piano_pedal_engraver"
        \consists "Piano_pedal_align_engraver"
        \consists "Instrument_name_engraver"
        \consists "String_number_engraver"
        \consists "Axis_group_engraver"
        \consists "Figured_bass_engraver"
        \consists "Figured_bass_position_engraver"
        \consists "Script_row_engraver"
        localKeySignature = #'()
        createSpacing = ##t
        ignoreFiguredBassRest = ##t
        instrumentName = #'()
        shortInstrumentName = #'()
        \defaultchild "Voice"
        \accepts "Voice"
        \accepts "CueVoice"
        \override NoteHead #'color = #blue
        \override Stem #'color = #blue
     }
     \context {
        \Score
        \accepts RedStaff
        \accepts BlueStaff
     }
  }

  \new Score <<
     \new RedStaff {
        c''4 c''4 c''4 c''4
     }
     \new BlueStaff {
        c'4 c'4 c'4 c'4
     }
  >>

%%% EX 3 %%%

Rebuilding the staff context from scratch means copying in 34
definitions behind per context before we can get to the red and blue
heart of the matter.


What we really need is a way to define a new context -- like in 9.2.7
-- but based on an existing context rather than from scratch. Clearly
the lily sources do this sort of thing all the time -- DrumStaff,
GregorianTranscriptionStaff, MensuralStaff, and all the other
staff-like contexts must clearly extend the base staff context in some
way rather than retyping all 34 (or more) context definitions.

And, indeed, engraver-init.ly gives us the following pattern to define
a new context from an existing context.

%%% EX 4 %%%

  \version "2.11.26"

  \layout {
     \context {
        \Staff
        \type "Engraver_group"
        \name RedStaff
        \alias Staff
        \override NoteHead #'color = #red
        \override Stem #'color = #red
     }
     \context {
        \Staff
        \type "Engraver_group"
        \name BlueStaff
        \alias Staff
        \override NoteHead #'color = #blue
        \override Stem #'color = #blue
     }
     \context {
        \Score
        \accepts RedStaff
        \accepts BlueStaff
     }
  }

  \new Score <<
     \new RedStaff {
        c''4 c''4 c''4 c''4
     }
     \new BlueStaff {
        c'4 c'4 c'4 c'4
     }
  >>

%%% EX 4%%%

This gives us exactly what we want. Formatting information lives only
in the layout block. And our red and blue staff contexts define in
terms of the existing global staff context.

* * *

Note when using the pattern in example 4 that the order of the four commands ...

 \Staff
 \type ...
 \name ...
 \alias ...

... matters. Placing the \name command before the \Staff command, for
example, causes explosions. So it's important to follow the recipe in
the order given here.

* * *

CONCLUSION. So the short summary here is that 9.2.7 "Defining new
contexts" does a great job of explaining how to define new contexts
from scratch. If you want to define new contexts based on existing
contexts, then a look at engraver-init.ly gives the pattern shown here
in example 4.




--
Trevor Bača
address@hidden

reply via email to

[Prev in Thread] Current Thread [Next in Thread]