Hi Jean and all,
I ran into cases when chorus and first verse are continued on first line.
Then with this solution, stanza cannot be changed from chorus to verse 1,
or vice versa.
I would appreciate it if it can be archived somehow.
\version "2.22.1"
sopranoMusic = \relative c'' {
\time 2/4
% verse music
\repeat unfold 10 { c } \break
% chorus music
\repeat unfold 10 { c } \break
\repeat unfold 10 { c }
}
sopranoLyrics = \lyrics {
\set stanza = "CH:"
\repeat unfold 10 { aaaaa }
<<
{
\set stanza = "1." % cannot reset stanza to new value
\repeat unfold 20 { aaa }
}
\new Lyrics {
\set stanza = "2."
\repeat unfold 20 { 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))
(make-engraver
((process-music engraver)
(if (not text)
(let ((stanza (ly:context-property context 'stanza #f)))
(if stanza
(begin
(set! text (ly:engraver-make-grob engraver
'StanzaNumberSpanner '()))
(let ((column (ly:context-property context
'currentCommandColumn)))
(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
}
}
Thanks a lot for any help.
Tu DINH
On Thu, 31 Mar 2022 at 15:50, Dinh Hoang Tu <[email protected]> wrote:
> Ça marche parfaitement.
> Merci bcp pour ton "un peu de technique" 😅
>
> It works like a charm!
> Thanks a lot for your "little" code 😊
>
> Cordialement,
> Regards,
>
> Tu DINH
>
> On Wed, 30 Mar 2022 at 21:43, Jean Abou Samra <[email protected]> wrote:
>
>>
>>
>> Le 30/03/2022 à 16:38, Dinh Hoang Tu a écrit :
>> > Hello Lilypond team and users,
>> >
>> > I'm engraving songs with many verses, and I would like to have stanza
>> > numbers in front of each line instead of only first line.
>> > I found vocalName and shortVocalName seems suitable for this purpose,
>> > but their positions do not adhere to verses like stanza does.
>> >
>> > Is there any way to make vocalName/shortVocalName attach to verse like
>> > stanza, or any other way to achieve this?
>>
>> I posted a snippet for that on the French-speaking list recently.
>>
>> https://lists.gnu.org/archive/html/lilypond-user-fr/2022-03/msg00012.html
>>
>> Hope that helps,
>> Jean
>>
>>
\version "2.22.1"
sopranoMusic = \relative c'' {
\time 2/4
% verse music
\repeat unfold 10 { c } \break
% chorus music
\repeat unfold 10 { c } \break
\repeat unfold 10 { c }
}
sopranoLyrics = \lyrics {
\set stanza = "CH:"
\repeat unfold 10 { aaaaa }
<<
{
\set stanza = "1." % cannot reset stanza to new value
\repeat unfold 20 { aaa }
}
\new Lyrics {
\set stanza = "2."
\repeat unfold 20 { 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))
(make-engraver
((process-music engraver)
(if (not text)
(let ((stanza (ly:context-property context 'stanza #f)))
(if stanza
(begin
(set! text (ly:engraver-make-grob engraver 'StanzaNumberSpanner '()))
(let ((column (ly:context-property context 'currentCommandColumn)))
(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
}
}
\version "2.22.1"
sopranoMusic = \relative c'' {
\time 2/4
% verse music
\repeat unfold 10 { c } \break
\repeat unfold 10 { c } \break
% chorus music
\repeat unfold 10 { c }
}
sopranoLyrics = \lyrics {
<<
{
\set stanza = "1."
\repeat unfold 20 { aaa }
}
\new Lyrics {
\set stanza = "2."
\repeat unfold 20 { aaaa }
}
>>
\set stanza = "CH:" % cannot reset stanza to new value
\repeat unfold 10 { aaaaa }
}
#(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))
(make-engraver
((process-music engraver)
(if (not text)
(let ((stanza (ly:context-property context 'stanza #f)))
(if stanza
(begin
(set! text (ly:engraver-make-grob engraver 'StanzaNumberSpanner '()))
(let ((column (ly:context-property context 'currentCommandColumn)))
(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
}
}