lilypond-user
[Top][All Lists]
Advanced

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

Re: Make shortVocalName attach to lyrics like stanza


From: Jean Abou Samra
Subject: Re: Make shortVocalName attach to lyrics like stanza
Date: Mon, 4 Apr 2022 17:51:04 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.7.0



Le 04/04/2022 à 05:07, Dinh Hoang Tu a écrit :
Hi Jean,

Thanks a lot for your updated code.
This seems to solve the issue with stanza of verses. It's really great. Thanks again for this!

But it also prints chorus stanza on each line which is not really expected I think.

\version "2.22.2"

sopranoMusic = \relative c'' {
   \time 2/4
   % chorus music
   \repeat unfold 10 { c } \break
   \repeat unfold 10 { c } \break
   \repeat unfold 10 { c } \break
   % verse music
   \repeat unfold 10 { c } \break
   \repeat unfold 10 { c }
}

sopranoLyrics = \lyrics {
   \set stanza = "CH:"
   \repeat unfold 29 { aaaaa }
   <<
     {
       \set stanza = "1."
       \repeat unfold 21 { aaa }
     }
     \new Lyrics = "lyr2" {

       \set stanza = "2."
       \repeat unfold 21 { aaaa }
     }
   >>
}

#(define (add-grob-definition grob-name grob-entry)
    (set! all-grob-descriptions
          (cons ((@@ (lily) completize-grob-entry)
                 (cons grob-name grob-entry))
                all-grob-descriptions)))

#(add-grob-definition
   'StanzaNumberSpanner
   `((direction . ,LEFT)
     (font-series . bold)
     (padding . 1.0)
     (side-axis . ,X)
     (stencil . ,ly:text-interface::print)
     (X-offset . ,ly:side-position-interface::x-aligned-side)
     (Y-extent . ,grob::always-Y-extent-from-stencil)
     (meta . ((class . Spanner)
              (interfaces . (font-interface
                             side-position-interface
                             stanza-number-interface
                             text-interface))))))

\layout {
   \context {
     \Global
     \grobdescriptions #all-grob-descriptions
   }
   \context {
     \Score
     \remove Stanza_number_align_engraver
     \consists
       #(lambda (context)
          (let ((texts '())
                (syllables '()))
            (make-engraver
             (acknowledgers
              ((stanza-number-interface engraver grob source-engraver)
                 (set! texts (cons grob texts)))
              ((lyric-syllable-interface engraver grob source-engraver)
                 (set! syllables (cons grob syllables))))
             ((stop-translation-timestep engraver)
                (for-each
                 (lambda (text)
                   (for-each
                    (lambda (syllable)
                      (ly:pointer-group-interface::add-grob text
'side-support-elements syllable))
                    syllables))
                 texts)
                (set! syllables '())))))
   }
   \context {
     \Lyrics
     \remove Stanza_number_engraver
     \consists
       #(lambda (context)
          (let ((text #f)
                (last-stanza #f))
            (make-engraver
             ((process-music engraver)
                (let ((stanza (ly:context-property context 'stanza #f)))
                  (if (and stanza (not (equal? stanza last-stanza)))
                      (let ((column (ly:context-property context
'currentCommandColumn)))
                        (set! last-stanza stanza)
                        (if text
                            (ly:spanner-set-bound! text RIGHT column))


                        (set! text (ly:engraver-make-grob engraver
'StanzaNumberSpanner '()))
                        (ly:grob-set-property! text 'text stanza)
                        (ly:spanner-set-bound! text LEFT column)))))
             ((finalize engraver)
                (if text
                    (let ((column (ly:context-property context
'currentCommandColumn)))
                      (ly:spanner-set-bound! text RIGHT column)))))))
     \override StanzaNumberSpanner.horizon-padding = 10000
   }
}

\score {
   \new ChoirStaff <<
     \new Staff <<
       \new Voice = soprano \sopranoMusic
       \new Lyrics \lyricsto soprano \sopranoLyrics
       >>
   >>
   \layout {
     indent = 0
   }
}

I guess it can be a bit better if we create a new element for this kind of stanza, for ex. longStanza. Just in same way as vocalName/shortVocalName, instrumentName/shortInstrumentName

My temporary workaround is to make chorus stanza as a markup. It's not beautiful, but at least it's acceptable for my usage:

\version "2.22.2"

sopranoMusic = \relative c'' {
   \time 2/4
   % chorus music
   <> \tweak extra-offset #'(-7.5 . -1.7) _\markup { \bold "CH:" }
   \repeat unfold 10 { c } \break
   \repeat unfold 10 { c } \break
   \repeat unfold 10 { c } \break
   % verse music
   \repeat unfold 10 { c } \break
   \repeat unfold 10 { c }
}

sopranoLyrics = \lyrics {
   %\set stanza = "CH:"
   \repeat unfold 29 { aaaaa }
   <<
     {
       \set stanza = "1."
       \repeat unfold 21 { aaa }
     }
     \new Lyrics = "lyr2" {

       \set stanza = "2."
       \repeat unfold 21 { aaaa }
     }
   >>
}

#(define (add-grob-definition grob-name grob-entry)
    (set! all-grob-descriptions
          (cons ((@@ (lily) completize-grob-entry)
                 (cons grob-name grob-entry))
                all-grob-descriptions)))

#(add-grob-definition
   'StanzaNumberSpanner
   `((direction . ,LEFT)
     (font-series . bold)
     (padding . 1.0)
     (side-axis . ,X)
     (stencil . ,ly:text-interface::print)
     (X-offset . ,ly:side-position-interface::x-aligned-side)
     (Y-extent . ,grob::always-Y-extent-from-stencil)
     (meta . ((class . Spanner)
              (interfaces . (font-interface
                             side-position-interface
                             stanza-number-interface
                             text-interface))))))

\layout {
   \context {
     \Global
     \grobdescriptions #all-grob-descriptions
   }
   \context {
     \Score
     \remove Stanza_number_align_engraver
     \consists
       #(lambda (context)
          (let ((texts '())
                (syllables '()))
            (make-engraver
             (acknowledgers
              ((stanza-number-interface engraver grob source-engraver)
                 (set! texts (cons grob texts)))
              ((lyric-syllable-interface engraver grob source-engraver)
                 (set! syllables (cons grob syllables))))
             ((stop-translation-timestep engraver)
                (for-each
                 (lambda (text)
                   (for-each
                    (lambda (syllable)
                      (ly:pointer-group-interface::add-grob text
'side-support-elements syllable))
                    syllables))
                 texts)
                (set! syllables '())))))
   }
   \context {
     \Lyrics
     \remove Stanza_number_engraver
     \consists
       #(lambda (context)
          (let ((text #f)
                (last-stanza #f))
            (make-engraver
             ((process-music engraver)
                (let ((stanza (ly:context-property context 'stanza #f)))
                  (if (and stanza (not (equal? stanza last-stanza)))
                      (let ((column (ly:context-property context
'currentCommandColumn)))
                        (set! last-stanza stanza)
                        (if text
                            (ly:spanner-set-bound! text RIGHT column))


                        (set! text (ly:engraver-make-grob engraver
'StanzaNumberSpanner '()))
                        (ly:grob-set-property! text 'text stanza)
                        (ly:spanner-set-bound! text LEFT column)))))
             ((finalize engraver)
                (if text
                    (let ((column (ly:context-property context
'currentCommandColumn)))
                      (ly:spanner-set-bound! text RIGHT column)))))))
     \override StanzaNumberSpanner.horizon-padding = 10000
   }
}

\score {
   \new ChoirStaff <<
     \new Staff <<
       \new Voice = soprano \sopranoMusic
       \new Lyrics \lyricsto soprano \sopranoLyrics
       >>
   >>
   \layout {
     indent = 0
   }
}



OK, try:

\version "2.22.2"

#(define (add-grob-definition grob-name grob-entry)
    (set! all-grob-descriptions
          (cons ((@@ (lily) completize-grob-entry)
                 (cons grob-name grob-entry))
                all-grob-descriptions)))

#(add-grob-definition
   'StanzaNumberSpanner
   `((direction . ,LEFT)
     (font-series . bold)
     (padding . 1.0)
     (side-axis . ,X)
     (stencil . ,ly:text-interface::print)
     (X-offset . ,ly:side-position-interface::x-aligned-side)
     (Y-extent . ,grob::always-Y-extent-from-stencil)
     (meta . ((class . Spanner)
              (interfaces . (font-interface
                             side-position-interface
                             stanza-number-interface
                             text-interface))))))

\layout {
   \context {
     \Global
     \grobdescriptions #all-grob-descriptions
   }
   \context {
     \Score
     \remove Stanza_number_align_engraver
     \consists
       #(lambda (context)
          (let ((texts '())
                (syllables '()))
            (make-engraver
             (acknowledgers
              ((stanza-number-interface engraver grob source-engraver)
                 (set! texts (cons grob texts)))
              ((lyric-syllable-interface engraver grob source-engraver)
                 (set! syllables (cons grob syllables))))
             ((stop-translation-timestep engraver)
                (for-each
                 (lambda (text)
                   (for-each
                    (lambda (syllable)
                      (ly:pointer-group-interface::add-grob
                       text
                       'side-support-elements
                       syllable))
                    syllables))
                 texts)
                (set! syllables '())))))
   }
   \context {
     \Lyrics
     \remove Stanza_number_engraver
     \consists
       #(lambda (context)
          (let ((text #f)
                (last-stanza #f))
            (make-engraver
             ((process-music engraver)
                (let ((stanza (ly:context-property context 'stanza #f)))
                  (if (and stanza (not (equal? stanza last-stanza)))
                      (let ((column (ly:context-property context 'currentCommandColumn)))
                        (set! last-stanza stanza)
                        (if text
                            (ly:spanner-set-bound! text RIGHT column))
                        (set! text (ly:engraver-make-grob engraver 'StanzaNumberSpanner '()))
                        (ly:grob-set-property! text 'text stanza)
                        (ly:spanner-set-bound! text LEFT column)))))
             ((finalize engraver)
                (if text
                    (let ((column (ly:context-property context 'currentCommandColumn)))
                      (ly:spanner-set-bound! text RIGHT column)))))))
     \override StanzaNumberSpanner.horizon-padding = 10000
   }
}

stanzaReminderOff =
\temporary \override StanzaNumberSpanner.after-line-breaking =
  #(lambda (grob)
     ;; Can be replaced with (not (first-broken-spanner? grob)) in 2.23.
     (if (let ((siblings (ly:spanner-broken-into (ly:grob-original grob))))
           (and (pair? siblings)
                (not (eq? grob (car siblings)))))
         (ly:grob-suicide! grob)))

stanzaReminderOn =
\undo \stanzaReminderOff


sopranoMusic = \relative c'' {
   \time 2/4
   % chorus music
   \repeat unfold 10 { c } \break
   \repeat unfold 10 { c } \break
   \repeat unfold 10 { c } \break
   % verse music
   \repeat unfold 10 { c } \break
   \repeat unfold 10 { c }
}

sopranoLyrics = \lyrics {
   \set stanza = "CH:"
   \stanzaReminderOff
   \repeat unfold 29 { aaaaa }
   <<
     {
       \set stanza = "1."
       \stanzaReminderOn
       \repeat unfold 21 { aaa }
     }
     \new Lyrics = "lyr2" {

       \set stanza = "2."
       \repeat unfold 21 { aaaa }
     }
   >>
}



\score {
   \new ChoirStaff <<
     \new Staff <<
       \new Voice = soprano \sopranoMusic
       \new Lyrics \lyricsto soprano \sopranoLyrics
       >>
   >>
   \layout {
     indent = 0
   }
}

Jean



reply via email to

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