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 }
>>

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to