lilypond-user
[Top][All Lists]
Advanced

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

Re: Fixing LSR 888: center-on-words ignoring punctuation


From: Thomas Morley
Subject: Re: Fixing LSR 888: center-on-words ignoring punctuation
Date: Fri, 9 Dec 2016 00:50:18 +0100

2016-12-07 1:07 GMT+01:00 Alexander Kobel <address@hidden>:
> Hi all,
>
> yet another semi-feature request where I'm running out of knowledge...
> I happily used LSR 888 (center lyrics without taking punctuation into
> account) for years and only now found out that the alignment is off under
> certain circumstances: The default algorithm seems to align lyrics on the
> center of the note*head* of the associated voice. Which seems the right
> thing to do. However, center-on-words aligns on the center of the *entire
> note* - in particular, this yields different results on quavers with stems
> up and "outward flags". At least, neither dots nor accidentals are taken
> into account...
>
> Even more ugly, the alignment is totally off on chords with two adjacent
> notes (shifting one note). I know that this should be a forbidden situation
> for vocal music, but sometimes there is a reason for writing such chords
> instead of two separate voices (e.g., soprano and alto notated on a common
> staff in a homorhythmic piece, with one of the voices splitting for a
> cluster on just a few notes).
> In such a rare case, I do not like the default algorithm's choices either
> (and I'd prefer alignment on the center of the noteheads of the chord); but
> center-on-words does even /way/ worse.
>
> I attach a "test case" (including a full copy of the core of
> http://lsr.di.unimi.it/LSR/Snippet?id=888), where one would expect
> center-on-words to do exactly nothing, but you can notice the slight offsets
> on the "nonius scale" of lyrics.
>
> Anyone got an idea where to start to fix that? I think one would have to
> figure how to get the note-column-extent without flags; but I have no clue
> how to approach that.
>
>
> Thanks in advance,
> Alexander



Hi,

how about below?
You need a devel-version, though. Please test thoroughly. I'm too
tired to do more than the included examples.

\version "2.19.52"  %% sic !!

%% http://lsr.di.unimi.it/LSR/Item?id=888

#(define space-set
  (list->char-set
    (string->list "—.?-;,:“†‘’–— */()[]{}|<>!`~&…")))

#(define (width grob text)
  (let* ((X-extent
           (ly:stencil-extent (grob-interpret-markup grob text) X)))
   (if (interval-empty? X-extent)
       0
       (cdr X-extent))))

#(define (remove-suspended-note-heads stem note-heads)
  (let* ((nc (ly:grob-common-refpoint stem (car note-heads) X))
         (stem-coord
           (ly:grob-relative-coordinate stem stem X))
         (half-stem-thick
           (/ (ly:grob-property stem 'thickness) 2))
         (stem-dir (ly:grob-property stem 'direction)))
    (remove
      (lambda (nh)
        (if (positive? stem-dir)
            (> (ly:grob-relative-coordinate nh nc X)
                stem-coord)
            (< (ly:grob-relative-coordinate nh nc X)
               (- stem-coord half-stem-thick))))
      note-heads)))

#(define (center-on-word grob)
  (let* ((text (ly:grob-property-data grob 'text))
         (syllable (markup->string text))
         (word-position
           (if (string-skip syllable space-set)
               (string-skip syllable space-set)
               0))
         (word-end
           (if (string-skip-right syllable space-set)
               (+ (string-skip-right syllable space-set) 1)
               (string-length syllable)))
         (preword (substring syllable 0 word-position))
         (word (substring syllable word-position word-end))
         (preword-width (width grob preword))
         (word-width (width grob (if (string-null? syllable) text word)))
         (note-column (ly:grob-parent grob X))
         (stem (ly:grob-object note-column 'stem))
         (stem-dir (ly:grob-property stem 'direction))
         (sys (ly:grob-system grob))
         (nh-ls
           (if (ly:grob-array? (ly:grob-object note-column 'note-heads))
               (ly:grob-array->list (ly:grob-object note-column 'note-heads))
               '()))
         (note-column-width
           (interval-length
             (ly:relative-group-extent
               (remove-suspended-note-heads stem nh-ls) note-column X))))

  (-
    (*
      (/ (- note-column-width word-width) 2)
      (1+ (ly:grob-property-data grob 'self-alignment-X)))
    preword-width)))

%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLES
%%%%%%%%%%%%%%%%%%%%%%

\layout {
  \context {
    \Lyrics
    \override LyricText.X-offset = #center-on-word
  }
}

<<
    \new Voice { \voiceOne c''8 }
    \addlyrics { word }

    \new Voice { c''8 }
    \addlyrics { ,,,word }

    \new Voice { \voiceOne <c'' d''>8 }
    \addlyrics { word!!! }

    \new Voice { <c'' d''>8 }
    \addlyrics { word }
>>

Cheers,
  Harm



reply via email to

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