Hi all, your intention here seems to be to have the stanza number printed for each system. Maybe try the attached file, which should achieve this effect automatically by using a modified spanner.
> However, I believe that your code is setting the stanza to the same > variable, which means that Lilypond does not recognize it as a different > value. correct, the issue here is that the parser turns the Lilypond code into a scheme data structure, by which point this string is a pointer to some string object. Reusing this data structure will use the same pointer, so you get object-equality. Arguably this is not a good design by the way, since it is hard to understand and relies on specific behaviour of the scheme interpreter. E.g. if you do `#(eq? "abc" "abc")` in guile this will be `#f`. If you do it in say Racket this will be `#t`. What is the difference? Well, Racket allocates string literals only once. So the first time the code has an `"abc"` an object is created and all other occasions simply point to that object. So if guile were to do this suddenly `\set verse = #"1" bla bla \set verse = #"1"` would not work anymore. And `\set verse = "1" bla bla \set verse = "1"` would depend on the parser, I guess. I think it would make sense to include a property similar to force-clef which can be used to reprint the stanza number. Best regards, Tina
% Defines an engraver that creates a Text Span to act like continuations of Stanza Numbers
#(define (stanza-span-engraver context)
(let ((span #f) (syllables '()))
(make-engraver
(acknowledgers
; If a now stanza number was created, create a new spanner
((stanza-number-interface engraver grob source)
(set! span (ly:engraver-make-spanner engraver 'TextSpanner '()))
(let* ((bound-det (ly:grob-property span 'bound-details))
(lb (ly:assoc-get 'left-broken bound-det '())))
(ly:grob-set-property!
span
'bound-details
(acons 'left-broken
(acons 'text
(ly:grob-property grob 'text)
lb)
bound-det))))
; Record syllables, hyphens and extenders for placement like stanza numbers
((lyric-syllable-interface engraver grob source)
(set! syllables (cons grob syllables)))
((lyric-interface engraver grob source)
(set! syllables (cons grob syllables)))
((lyric-space-interface engraver grob source)
(set! syllables (cons grob syllables))))
; Set Lyrics stuff as side support
((process-acknowledged engraver)
(if (and span (not (null? syllables)))
(let* ((elts (ly:grob-object span 'side-support-elements))
(elts-list (if (null? elts) elts (ly:grob-array->list elts))))
(ly:grob-set-object!
span 'side-support-elements
(ly:grob-list->grob-array (append syllables elts-list)))))
(set! syllables '()))
; Set spanner bounds
((stop-translation-timestep engraver)
(if span
(let ((col (ly:context-property context 'currentMusicalColumn)))
(if (null? (ly:spanner-bound span LEFT))
(ly:spanner-set-bound! span LEFT col))
(ly:spanner-set-bound! span RIGHT col)))))))
\layout {
\context {
\Lyrics
\consists #stanza-span-engraver
\consists Text_spanner_engraver
% Custom printing procedure for Spanner: Do not print line, just broken bound text
\override TextSpanner.stencil =
#(lambda (grob)
(let ((text (ly:assoc-get 'text (ly:grob-property grob 'left-bound-info))))
(if (markup? text)
(grob-interpret-markup grob (ly:assoc-get 'text (ly:grob-property grob 'left-bound-info)))
(ly:grob-suicide! grob))))
% Change placement to act like a stanza number
\override TextSpanner.outside-staff-priority = ##f % This is just to avoid warning about direction
\override TextSpanner.Y-offset = 0
\override TextSpanner.side-axis = #X
\override TextSpanner.direction = #LEFT
\override TextSpanner.padding = #1
\override TextSpanner.X-offset = #ly:side-position-interface::x-aligned-side
% Change font properties to look like a stanza number
\override TextSpanner.font-series = #'bold
\override TextSpanner.font-shape = #'upright
}
}
text = \lyricmode {
\set stanza = "1"
One two three
}
notes = { c' d' \break e' }
<<
\new Voice = "tune" { \notes }
\new Lyrics { \lyricsto "tune" \text }
>>
signature.asc
Description: This is a digitally signed message part.
