\version "2.19.44" #(define create-stanza-number-grob-engraver ;; puts out a StanzaNumber for every LyricText-grob (lambda (context) (let ((stanza (ly:context-property context 'stanza))) `((acknowledgers (lyric-syllable-interface . ,(lambda (engraver grob source-engraver) (let ((new-stanza-grob (ly:engraver-make-grob engraver 'StanzaNumber '()))) ;; set 'id to select them later (ly:grob-set-property! new-stanza-grob 'id (markup->string stanza)) (ly:grob-set-property! new-stanza-grob 'text stanza))))))))) #(define (delete-adjacent-duplicates lst) "Delete all duplicates in a list of strings." (if (and (not (null? lst)) (every string? lst)) (fold-right (lambda (elem ret) (if (equal? elem (first ret)) ret (cons elem ret))) (list (last lst)) (sort lst stringlist (ly:grob-object sys 'all-elements))) ;; get all StanzaNumbers (stanzas (filter (lambda (e) (grob::has-interface e 'stanza-number-interface)) all-elts)) ;; get all stanza-ids, without duplicates (stanza-ids (delete-adjacent-duplicates (filter string? (map (lambda (x) (ly:grob-property x 'id)) stanzas)))) ;; put StanzaNumbers into sub-lists according to the 'id (id-selected-stanzas (map (lambda (val) (filter (lambda (x) (equal? (ly:grob-property x 'id) val)) stanzas)) stanza-ids))) ;; keep only the first StanzaNumber of every line ;; all other's stencil is set #f ;; TODO there may be a StanzaNumber not catchable this way (for-each (lambda (lst) (if (not (null? (cdr lst))) (for-each (lambda (stz) (ly:grob-set-property! stz 'stencil #f)) (cdr lst)))) id-selected-stanzas))))) keepLineStartStanzaNumbers = \layout { \context { \Score \override NonMusicalPaperColumn.after-line-breaking = #keep-stanza-number-at-line-begin } } numberLyrics = #(define-scheme-function (nmbr)(number?) "Return a context-modification setting @code{stanza} and consisting @code{create-stanza-number-grob-engraver}." #{ \with { stanza = \markup \italic #(format #f "~a." nmbr) \consists #create-stanza-number-grob-engraver } #}) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXAMPLE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \paper { ragged-last-bottom = ##f } \score { << \new Staff { \key cis \major \repeat unfold 6 { c''4 d'' e'' } } \new Lyrics \with \numberLyrics 1 \lyricmode { \repeat unfold 6 { foo -- bar -- buzz } } \new Lyrics \with \numberLyrics 2 \lyricmode { \repeat unfold 6 { very-very-long-syllable bur -- buuuzz } } \new Lyrics \with \numberLyrics 3 \lyricmode { \repeat unfold 6 { fuu -- bla -- blibbb } } >> \header { piece = \markup \rounded-box \fill-line { "Using StanzaNumber" } } \layout { \keepLineStartStanzaNumbers } } \score { << \new Staff { \key cis \major \repeat unfold 6 { c''4 d'' e'' } } \new Lyrics \with { instrumentName = "1." shortInstrumentName = "1." } \lyricmode { \repeat unfold 6 { foo -- bar -- buzz } } \new Lyrics \with { instrumentName = "2." shortInstrumentName = "2." } \lyricmode { \repeat unfold 6 { very-very-long-syllable bur -- buuuzz } } \new Lyrics \with { instrumentName = "3." shortInstrumentName = "3." } \lyricmode { \repeat unfold 6 { fuu -- bla -- blibbb } } >> \header { piece = \markup \rounded-box \fill-line { "Using InstrumentName" } } \layout { \context { \Score \override InstrumentName.X-offset = #'() \override InstrumentName.font-series = #'bold \override InstrumentName.font-shape = #'italic } \context { \Lyrics \revert InstrumentName.font-size } } }