Dear all,

On 2016-12-10 00:12, Alexander Kobel wrote:
[...]
AFAICS, everything works beautifully as expected, with one strange
exception: in a chord with two equal notes, the default algorithm
chooses the right one as reference, your method chooses the reference
point depending on the stem direction. That's something I can perfectly
live with.
In particular because I took the liberty to add a second variant that
centers on chords; starting from your code, I found out how to do that.
Please find the file attached.

One little flaw in my last post: I forgot to remove some debug console output. Attached is a slightly revised version, including the original example from the LSR and a slightly cleaned-up new one comparing the default, center-on-word and center-on-word-on-chords strategies.

I think this one should be suitable for a revision of LSR 888; please test and let me know if any issues still remain.


Thanks,
Alexander
\version "2.19.50"  %% and higher

%% 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 (make-center-on-word-callback grob center-on-chords)
   (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))
               '()))
          (full-column-width 
           (interval-length (ly:relative-group-extent nh-ls note-column X)))
          (note-column-width
           (interval-length
            (ly:relative-group-extent
             (remove-suspended-note-heads stem nh-ls) note-column X))))
     (-
      (*
       (/ (if center-on-chords
              (if (positive? stem-dir)
                  (- full-column-width word-width)
                  (- (* 2 note-column-width) full-column-width word-width))
              (- note-column-width word-width))
         2)
       (1+ (ly:grob-property-data grob 'self-alignment-X)))
      preword-width)))

#(define (center-on-word grob) (make-center-on-word-callback grob #f))
#(define (center-on-word-on-chords grob) (make-center-on-word-callback grob #t))
\version "2.19.50"  %% and higher

\include "center-on-words.ily"

\paper { ragged-last = ##f }

melody = \relative c' { 
  c4 
  d e f | 
  c d 
  e( f) 
  g1 \bar"|." 
}

lyr = \lyricmode {
  \set stanza = "1. "
  Do, ““Re, Mi, Fa, Do, Re, 
  %\once \set Score.lyricMelismaAlignment = #4.5
  "...mimifa,"
  \markup \bold Sol—
}

lyrA = \lyricmode {
  \set stanza = "2. "
  “Do Re, Mi, Fa, Do, Re, 
  mimifa... 
  Sol!”
}

lyrControl = \lyricmode{ 
  \set stanza = "Control: "
  \revert LyricText.X-offset
  Do Re Mi Fa Do Re mimifa Sol
}

\score {
  \new Staff <<
    \new Voice = "voice" \melody
    \new Lyrics = "testI" 
      \with { \override LyricText.X-offset = #center-on-word }
      \lyricsto "voice" \lyr
    \new Lyrics = "testII" 
      \with { \override LyricText.X-offset = #center-on-word }
      \lyricsto "voice" \lyrA
    %% The control-voice omits the override
    \new Lyrics = "control" 
      \lyricsto "voice" \lyrControl
  >>
  \layout {
    \context {
      \Score
      lyricMelismaAlignment = #-0.6
    }
  }
}

\markup \vspace #3

melodyII = \relative c'' {
  \override NoteHead.color = #black
  \autoBeamOff
  g8 a b c
  << { \voiceTwo c } \new Voice { \voiceOne d } >>
  << { \voiceOne c } \new Voice { \voiceTwo <d e> } >>
  << { \voiceTwo <c d> } \new Voice { \voiceOne e } >>
  << { \voiceOne c } \new Voice { \voiceTwo e } >>
  \oneVoice
  <c b> <b a> <a b e> <a g> <g f> <f e> <e d> <c c>
}

lyr = \lyricmode { \repeat unfold 16 "^" }

\score {
  <<
    \new Staff \with { instrumentName = \markup \center-column { center- on-word } } \melodyII
    \addlyrics \with { \override LyricText.X-offset = #center-on-word } \lyr

    \new Staff \with { instrumentName = "default" } \melodyII
    \addlyrics \lyr

    \new Staff \with { instrumentName = \markup \center-column { center- on-word- on-chords } } \melodyII
    \addlyrics \with { \override LyricText.X-offset = #center-on-word-on-chords } \lyr
  >>
  \layout {
    \context {
      \Score
      % just for easier comparison
      proportionalNotationDuration = #(ly:make-moment 1 16)
      \override SpacingSpanner.strict-note-spacing = ##t
    }
    \context {
      \Voice
      \override NoteHead.color = #grey
    }
  }
}

Attachment: center-on-words-example.pdf
Description: Adobe PDF document

_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to