--- /dev/null
+\version "2.19.12"
+
+\header {
+ lsrtags = "devel, scheme-language, tweaks-and-overrides"
+
+ texidoc = "
+When working with grob callbacks, it can be helpful to understand a
+grob's @qq{ancestry}. Most grobs have @qq{parents} which influence the
+positioning of the grob. X- and Y-parents influence the horizontal and
+vertical positions for the grob, respectively. Additionally, each
+parent may have parents of its own.
+
+
+Unfortunately, there are several aspects of a grob's ancestry that can
+lead to confusion:
+
+* The types of parents a grob has may depend on context. * For some
+grobs, the X- and Y-parents are the same. * A particular @qq{ancestor}
+may be related to a grob in multiple ways. * The concept of
+@qq{generations} is misleading.
+
+
+For example, the @code{System} grob can be both parent (on the Y-side)
+and grandparent (twice on the X-side) to a @code{VerticalAlignment}
+grob.
+
+
+This macro prints (to the console) a textual representation of a grob's
+ancestry.
+
+
+When called this way
+
+
+@{
+ \\once \\override NoteHead.before-line-breaking = #display-ancestry
+ c @}
+
+
+The following output is generated:
+
+
+------------------------------------
+
+NoteHead X,Y: NoteColumn
+ X: PaperColumn
+ X,Y: System
+ Y: VerticalAxisGroup
+ X: NonMusicalPaperColumn
+ X,Y: System
+ Y: VerticalAlignment
+ X: NonMusicalPaperColumn
+ X,Y: System
+ Y: System
+
+
+
+"
+ doctitle = "Displaying grob ancestry"
+}
+%% http://lsr.di.unimi.it/LSR/Item?id=622
+%% see also http://www.lilypond.org/doc/v2.18/Documentation/snippets/tweaks-and-overrides#tweaks-and-overrides-displaying-grob-ancestry
+
+#(define (grob-name grob)
+ (if (ly:grob? grob)
+ (assoc-ref (ly:grob-property grob 'meta) 'name)
+ #f))
+
+#(define (get-ancestry grob)
+ (if (not (null? (ly:grob-parent grob X)))
+ (list (grob-name grob)
+ (get-ancestry (ly:grob-parent grob X))
+ (get-ancestry (ly:grob-parent grob Y)))
+ (grob-name grob)))
+
+#(define (format-ancestry lst padding)
+ (string-append
+ (symbol->string (car lst))
+ "\n"
+ (let ((X-ancestry
+ (if (list? (cadr lst))
+ (format-ancestry (cadr lst) (+ padding 3))
+ (symbol->string (cadr lst))))
+ (Y-ancestry
+ (if (list? (caddr lst))
+ (format-ancestry (caddr lst) (+ padding 3))
+ (symbol->string (caddr lst)))))
+ (if (equal? X-ancestry Y-ancestry)
+ (string-append
+ (format #f "~&")
+ (make-string padding #\space)
+ "X,Y: "
+ (if (list? (cadr lst))
+ (format-ancestry (cadr lst) (+ padding 5))
+ (symbol->string (cadr lst))))
+ (string-append
+ (format #f "~&")
+ (make-string padding #\space)
+ "X: " X-ancestry
+ "\n"
+ (make-string padding #\space)
+ "Y: " Y-ancestry
+ (format #f "~&"))))
+ (format #f "~&")))
+
+#(define (display-ancestry grob)
+ (format (current-error-port)
+ "~3&~a~2%~a~&"
+ (make-string 36 #\-)
+ (format-ancestry (get-ancestry grob) 0)))
+
+\relative c' {
+ \once \override NoteHead.before-line-breaking = #display-ancestry
+ f4
+ \once \override Accidental.before-line-breaking = #display-ancestry
+ \once \override Arpeggio.before-line-breaking = #display-ancestry
+ <f as c>4\arpeggio
+}
--- /dev/null
+\version "2.19.12"
+
+\header {
+ lsrtags = "automatic-notation, keyboards, template, vocal-music"
+
+ texidoc = "
+This template adds an automatic piano reduction to the standard SATB
+vocal score demonstrated in @qq{Vocal ensemble template}. This
+demonstrates one of the strengths of LilyPond – you can use a music
+definition more than once. If any changes are made to the vocal notes
+(say, @code{tenorMusic}), then the changes will also apply to the piano
+reduction.
+
+"
+ doctitle = "Vocal ensemble template with automatic piano reduction"
+}
+\paper {
+ top-system-spacing.basic-distance = #10
+ score-system-spacing.basic-distance = #20
+ system-system-spacing.basic-distance = #20
+ last-bottom-spacing.basic-distance = #10
+}
+
+global = {
+ \key c \major
+ \time 4/4
+}
+
+sopMusic = \relative c'' {
+ c4 c c8[( b)] c4
+}
+sopWords = \lyricmode {
+ hi hi hi hi
+}
+
+altoMusic = \relative c' {
+ e4 f d e
+}
+altoWords =\lyricmode {
+ ha ha ha ha
+}
+
+tenorMusic = \relative c' {
+ g4 a f g
+}
+tenorWords = \lyricmode {
+ hu hu hu hu
+}
+
+bassMusic = \relative c {
+ c4 c g c
+}
+bassWords = \lyricmode {
+ ho ho ho ho
+}
+
+\score {
+ <<
+ \new ChoirStaff <<
+ \new Lyrics = "sopranos" \with {
+ % This is needed for lyrics above a staff
+ \override VerticalAxisGroup.staff-affinity = #DOWN
+ }
+ \new Staff = "women" <<
+ \new Voice = "sopranos" { \voiceOne << \global \sopMusic >> }
+ \new Voice = "altos" { \voiceTwo << \global \altoMusic >> }
+ >>
+ \new Lyrics = "altos"
+ \new Lyrics = "tenors" \with {
+ % This is needed for lyrics above a staff
+ \override VerticalAxisGroup.staff-affinity = #DOWN
+ }
+
+ \new Staff = "men" <<
+ \clef bass
+ \new Voice = "tenors" { \voiceOne << \global \tenorMusic >> }
+ \new Voice = "basses" { \voiceTwo << \global \bassMusic >> }
+ >>
+ \new Lyrics = "basses"
+ \context Lyrics = "sopranos" \lyricsto "sopranos" \sopWords
+ \context Lyrics = "altos" \lyricsto "altos" \altoWords
+ \context Lyrics = "tenors" \lyricsto "tenors" \tenorWords
+ \context Lyrics = "basses" \lyricsto "basses" \bassWords
+ >>
+ \new PianoStaff <<
+ \new Staff <<
+ \set Staff.printPartCombineTexts = ##f
+ \partcombine
+ << \global \sopMusic >>
+ << \global \altoMusic >>
+ >>
+ \new Staff <<
+ \clef bass
+ \set Staff.printPartCombineTexts = ##f
+ \partcombine
+ << \global \tenorMusic >>
+ << \global \bassMusic >>
+ >>
+ >>
+ >>
+}
--- /dev/null
+\version "2.19.12"
+
+\header {
+ lsrtags = "really-simple, template, vocal-music"
+
+ texidoc = "
+Here is a standard four-part SATB vocal score. With larger ensembles,
+it is often useful to include a section which is included in all parts.
+For example, the time signature and key signature are almost always the
+same for all parts. Like in the @qq{Hymn} template, the four voices are
+regrouped on only two staves.
+
+"
+ doctitle = "Vocal ensemble template"
+}
+\paper {
+ top-system-spacing.basic-distance = #10
+ score-system-spacing.basic-distance = #20
+ system-system-spacing.basic-distance = #20
+ last-bottom-spacing.basic-distance = #10
+}
+
+global = {
+ \key c \major
+ \time 4/4
+}
+
+sopMusic = \relative c'' {
+ c4 c c8[( b)] c4
+}
+sopWords = \lyricmode {
+ hi hi hi hi
+}
+
+altoMusic = \relative c' {
+ e4 f d e
+}
+altoWords = \lyricmode {
+ ha ha ha ha
+}
+
+tenorMusic = \relative c' {
+ g4 a f g
+}
+tenorWords = \lyricmode {
+ hu hu hu hu
+}
+
+bassMusic = \relative c {
+ c4 c g c
+}
+bassWords = \lyricmode {
+ ho ho ho ho
+}
+
+\score {
+ \new ChoirStaff <<
+ \new Lyrics = "sopranos" \with {
+ % this is needed for lyrics above a staff
+ \override VerticalAxisGroup.staff-affinity = #DOWN
+ }
+ \new Staff = "women" <<
+ \new Voice = "sopranos" {
+ \voiceOne
+ << \global \sopMusic >>
+ }
+ \new Voice = "altos" {
+ \voiceTwo
+ << \global \altoMusic >>
+ }
+ >>
+ \new Lyrics = "altos"
+ \new Lyrics = "tenors" \with {
+ % this is needed for lyrics above a staff
+ \override VerticalAxisGroup.staff-affinity = #DOWN
+ }
+ \new Staff = "men" <<
+ \clef bass
+ \new Voice = "tenors" {
+ \voiceOne
+ << \global \tenorMusic >>
+ }
+ \new Voice = "basses" {
+ \voiceTwo << \global \bassMusic >>
+ }
+ >>
+ \new Lyrics = "basses"
+ \context Lyrics = "sopranos" \lyricsto "sopranos" \sopWords
+ \context Lyrics = "altos" \lyricsto "altos" \altoWords
+ \context Lyrics = "tenors" \lyricsto "tenors" \tenorWords
+ \context Lyrics = "basses" \lyricsto "basses" \bassWords
+ >>
+}