Jan 20, 2015

Advanced Staff Grouping

Man, I love the LSR! There are so many interesting snippets there. I had to write a quick post about this one, too:

To be honest, the big orchestral brace looks a bit ugly to me (no offense to the original creators). It uses postscript code (and that's probably the point of the snippet) and requires a bunch of unnecessary \overrides. Let's clean it (and the code) up a bit!

In this snippet, a handful of useful new contexts are created to assist in grouping things together. The main contexts that already exist are: Score, GrandStaff, StaffGroup, Staff, Voice, etc. We can create new contexts by aliasing the appropriate default contexts. For example, if we want to create a "ViolinGroup", because we'd like to give a staff to the 1st and 2nd violin groups, we can do so like this:
\layout {
  \context {
    \StaffGroup
    \name ViolinGroup
    \alias StaffGroup
    systemStartDelimiter = #'SystemStartBrace
  }
}
The ViolinGroup now behaves like a StaffGroup, but with a system brace as its group indicator. The snippet goes on to similarly create a WindGroup, but uses the default system bracket as the group indicator, inheriting from StaffGroup.

Going further, we now create a StringGroup, intended for including the ViolinGroup as well as the normal Staff for the violas, cellos, and contrabasses:
\layout {
  \context {
    \StaffGroup
    \name StringGroup
    \alias StaffGroup
    \accepts ViolinGroup
    systemStartDelimiter = #'SystemStartBracket
  }
}
Since StaffGroup already \accepts the Staff context, there is no need to repeat that here, but we do need to explicitly say "\accepts ViolinGroup" since that's a custom context. The StringGroup would then need to be accepted by the context containing it (if necessary, which it is here):
\layout {
  \context {
    \StaffGroup
    \name OrchestraGroup
    \accepts WindGroup
    \accepts StringGroup
    \remove "System_start_delimiter_engraver"
  }
}
We remove the "System_start_delimiter_engraver" because we don't want it to show up right by the system itself, so we will customize this in the instrumentName variable. For this, we're going to rotate the text "Orchestra" vertically and add a large brace to show the correct grouping:
\markup { 
  \lower #0.75 \rotate #90 "Orchestra" \hspace #1
  \left-brace #175 \hspace #5
}
The extra "\hspace" commands are just to give each element a good amount of space. The last little bit of \override-ing we need to do is for the regular instrument names:
\layout {
  \context {
    \Staff
    \override InstrumentName.font-size = #-1
    \override InstrumentName.extra-offset = #'(6 . 0)
  }
}
If we didn't do these, they will show up too far-away to the system (depending on the value of "indent", of course) and to help with spacing we decrease the font-size slightly.

Those are the main building blocks we need. Here's the full updated snippet:
\version "2.18.2"
%% http://lsr.di.unimi.it/LSR/Item?id=906

% by Kieren MacMillan and P.P.Schneider.
% => http://lists.gnu.org/archive/html/lilypond-user/2013-03/msg00260.html

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% LSR workaround:
#(set! paper-alist (cons '("snippet" . (cons (* 90 mm) (* 120 mm))) paper-alist))
\paper {
  #(set-paper-size "snippet")
  tagline = ##f
}

\markup \vspace #1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%here starts the snippet:

someMusic = { 
  \tempo "Andante."
  \time 3/4
  \key c \minor
  c'2. r8 
}

\paper { 
  indent = 40 
}

\layout {
  \context {
    \Staff
    \override InstrumentName.font-size = #-1
    \override InstrumentName.extra-offset = #'(6 . 0)
  }
  \context {
    \StaffGroup
    \name ViolinGroup
    \alias StaffGroup
    systemStartDelimiter = #'SystemStartBrace
  }
  \context {
    \StaffGroup
    \name WindGroup
    \alias StaffGroup
    systemStartDelimiter = #'SystemStartBracket
    \override SystemStartBracket.collapse-height = #1
  }
  \context {
    \StaffGroup
    \name StringGroup
    \alias StaffGroup
    \accepts ViolinGroup
    systemStartDelimiter = #'SystemStartBracket
  }
  \context {
    \StaffGroup
    \name OrchestraGroup
    \accepts WindGroup
    \accepts StringGroup
    \remove "System_start_delimiter_engraver"
    instrumentName = \markup { 
      \lower #0.75 \rotate #90 "Orchestra" \hspace #1
      \left-brace #175 \hspace #5
    }
  }
  \context {
    \GrandStaff
    \remove "System_start_delimiter_engraver"
    \accepts OrchestraGroup
    \accepts StaffGroup
    \accepts VocalGroup
  }
  \context {
    \StaffGroup
    \name VocalGroup
    \alias StaffGroup
    systemStartDelimiter = #'SystemStartBracket
  }
}

\score {
  \new GrandStaff <<
    \new OrchestraGroup <<
      \new WindGroup <<
        \new Staff \with { 
          instrumentName = "Oboe" 
        } \someMusic
      >>
      \new StringGroup <<
        \new ViolinGroup <<
          \new Staff \with { 
            instrumentName = "Violino I" 
          } \someMusic
          \new Staff \with { 
            instrumentName = "Violino II" 
          } \someMusic
        >>
        \new Staff \with { 
            instrumentName = "Viola" 
          } { \clef C \someMusic }
      >>
    >>
    \new VocalGroup <<
      \new Staff \with { 
       instrumentName = "Soprano" 
      } \someMusic
      \new Staff \with { 
       instrumentName = "Alto" 
      } { \clef C \someMusic }
    >>
  >>
}
What do you think? Let me know in the comments. What other contexts have you used/created before? How have you shown grouped instruments? I'd love to hear your experiences.

No comments:

Post a Comment