[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