On 2024-05-04 8:06 am, Fr. Samuel Springuel wrote:
1) Can I establish that shortVocalName should default to vocalName at the top level of the file (effectively placing it where I can transport it over to my format file)?


Yes, you do something like this:

%%%%
\version "2.24.3"

\layout {
  \context {
    \Lyrics
    \override InstrumentName.stencil =
      #(lambda (grob)
        ;; Use long-text for text, as needed.
        (or (markup? (ly:grob-property grob 'text))
          (ly:grob-set-property! grob 'text
            (ly:grob-property grob 'long-text)))
        (system-start-text::print grob))
  }
}
%%%%

If vocalName is set but not shortVocalName, then the value of vocalName (long-text) is copied into the shortVocalName (text). This gives you some flexibility as you can define them independently as needed.


2) Can I automate the numbering so that I don’t have to manually number the verses? I’ve seen http://lsr.di.unimi.it/LSR/Item?id=543, but this has two problems: one, the counter increments each time the markup is printed, which is problematic for verse numbers which should stay the same within a verse, no matter how many times it is printed, and only increment between verses. Two, it introduces a spurious space after the counter that I don’t know how to get rid of.


I would use more helper functions to automate things.  Consider:

%%%%
\version "2.24.3"

\layout {
  \context {
    \Lyrics
    \override InstrumentName.self-alignment-X = #RIGHT
  }
}

stanza =
#(define-scheme-function (stanza) (markup?)
  (let ((markup #{ \markup \italic #stanza #}))
    #{ \with { vocalName = #markup shortVocalName = #markup } #}))

autoStanza =
#(let ((ctr 0))
  (define-scheme-function (fmt) ((string? "~d."))
    (set! ctr (1+ ctr))
    #{ \stanza #(format #f fmt ctr) #}))

\layout { ragged-right = ##t }

music = \relative { f' g a c | \break c a g f | \break f e d c }
verseI = \lyricmode { \repeat unfold 12 a }
verseII = \lyricmode { \repeat unfold 12 b }
verseIII = \lyricmode { \repeat unfold 12 c }
verseIV = \lyricmode { \repeat unfold 12 d }

\new Staff
<<
  \new Voice = "mel" { \music }
  \new Lyrics \with \autoStanza \default \lyricsto "mel" { \verseI }
  \new Lyrics \with \autoStanza "~@(~:r.~)" \lyricsto "mel" { \verseII }
  \new Lyrics \with \autoStanza "~@r." \lyricsto "mel" { \verseIII }
  \new Lyrics \with \autoStanza "~(~:@r.~)" \lyricsto "mel" { \verseIV }

%%%%

Note above that \stanza takes care of setting both vocalName and shortVocalName to the same markup, so the stencil override I showed is not necessary. I am also doing the work within the \with block for each Lyrics context rather than \setting. You could modify this logic to use \set instead if you needed to change the vocalName/shortVocalName. You'd need to use define-music-function rather than define-scheme-function.

The \autoStanza takes care of the counter logic, although it only supports one global counter. For most scores, this is probably sufficient. The formatting string gives you some customization options based on the formatted printing facility within Scheme. If you used this a lot, it probably make sense to define the format strings with sensible naming:

%%%%
ordinal = "~@(~:r.~)"
newRomanUpper = "~@r."
oldRomanLower = "~(~:@r.~)"
%% . . .

  \new Lyrics \with \autoStanza \oldRomanLower \lyricsto "mel" { ... }

%%%%

In fact, you could take automation even further to reduce typing:

%%%%
lyricsWithAutoStanzaOrdinal =
#(define-music-function (lyrics) (ly:music?)
  #{ \new Lyrics \with \autoStanza \ordinal \lyricsto mel $lyrics #})
%% . . .

  \lyricsWithAutoStanzaOrdinal \verseII

%%%%


-- Aaron Hill

Reply via email to