lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Lyric separator


From: Thomas Morley
Subject: Re: Lyric separator
Date: Fri, 20 Sep 2013 02:44:40 +0200

Hi Kieran, David


2013/9/20 Kieren MacMillan <address@hidden>
Hi David,

Could it be a question of version?

Certainly could.
I'm running 2.17.26-1.

Here's what I get when I add a verse (with v2 and v4 ostensibly 'lined'):

Curiouser and curiouser!
 
Actually not.
 
The functions as it stands, reads out a grob at first position in a line, filtering _all_ LyricText-grobs of the system. Though, this might be the grob of the actual context, _or_ _not_.
Comparing this grob with the grob of the context where the function applies, may return #f _or_ #t !!

I come up with some coding below, strongly feeling it could be done better, easier, more straight forward, etc
Please regard it as first step, only.
At least it seems to work.


\version "2.17.25"

%% Ofcourse: Thanks to David Nalesnik
#(define (sort-by-X-coord sys grob-lst)
"Arranges a list of grobs in ascending order by their X-coordinates"
   (let* ((X-coord (lambda (x) (ly:grob-relative-coordinate x sys X)))
          (comparator (lambda (p q) (< (X-coord p) (X-coord q)) )))
     (sort grob-lst comparator)))

#(define (my-callback grob)
   (let* ((text (ly:grob-property-data grob 'text))
          (refp (ly:grob-system grob))
          ; This returns all grobs in a line.
          (all-grobs (ly:grob-array->list
                      (ly:grob-object refp 'all-elements)))
          ; We're only interested in LyricText grobs.
          (just-syllables
            (filter
              (lambda (x) (grob::has-interface x 'lyric-syllable-interface))
              all-grobs))
          ; We want the first LyricText grob in the system.  We must locate this
          ; by position, since grobs don't seem to be listed in order in the
          ; 'all-elements grob array.
           ; Arrange them in ascending order by their X-coordinate.
           (sorted-syls (sort-by-X-coord refp just-syllables))
           ; Find the index where the X-coordinates change.
           (coord-change-at
             (list-index
               (lambda (x y)
                 (< (ly:grob-relative-coordinate x refp X)
                    (ly:grob-relative-coordinate y refp X)))
               sorted-syls
               (cdr sorted-syls)))
           ; Only return a list of grobs with lowest but equal X-coordinate.
           (relevant-grobs
              (call-with-values
                (lambda ()
                  (split-at
                    (sort-by-X-coord refp just-syllables)
                    (+ 1 coord-change-at)))
                (lambda (a b) a))))
               

     ; If our LyricText grob is the first on the line, override its stencil.
     (if (member grob relevant-grobs)
         (begin
           (ly:grob-set-property! grob 'text
             #{
               \markup \combine
                         #text
                         \translate #'(1.6 . -0.5) \draw-line #'(-4 . 0)
             #})
           (ly:grob-set-property! grob 'stencil (lyric-text::print grob))))))

melody = \repeat unfold 16 g'4
lyr = \lyricmode {
  \repeat unfold 16 sol
}
\score {
  \new Staff
  <<
    \new Voice = "voice" {
      \melody
    }
    \new Lyrics \lyricsto "voice" \lyr
    \new Lyrics \with {
      \override LyricText #'after-line-breaking = #my-callback
    } \lyricsto "voice" \lyr
    \new Lyrics \lyricsto "voice" \lyr
    \new Lyrics \with {
      \override LyricText #'after-line-breaking = #my-callback
    } \lyricsto "voice" \lyr
    \new Lyrics \lyricsto "voice" \lyr
   >>
}
\paper {
  indent = 0
  line-width = 5.5\cm
}

HTH,
  Harm

reply via email to

[Prev in Thread] Current Thread [Next in Thread]