>
>
> You could do interpret-markup and get a stencil of an individual character,
> then get its X-extent, I think.  It would involve getting the 'text, then
> going through the text elements one by one and creating a stencil.
>
> Hope this is helpful,
>
> Carl
>
>
Thank you Carl for that needle in the haystack! I have been trying the
stencil function out and with a define-markup-command I can now calculate
the vowel aligned X for a word!

The only challenge is how to pass the alignment value on to the
define-music-function that runs through the music elements?
Is it even possible to call a define-markup-command from
a define-music-function?
Or can I make a function which has access to both the music, layout and
props objects at the same time?

Below is the code so far.
Thanx for any help.
/Tor


\version "2.12.1"

#(define vowel-set (list->char-set (string->list "AEIOUYÅÄÖaeiouyåäö")))
#(define secondary-vowel-set (list->char-set (string->list "")))

#(define-markup-command (centertext layout props text) (markup?)
 (let* ((text-stencil (interpret-markup layout props text))
(text-width (interval-length (ly:stencil-extent text-stencil X)))
                (vowel-count (string-count text vowel-set))
                (vowel-position (string-index text vowel-set))
(prev-text (substring text 0 vowel-position))
(vowel (string-ref text vowel-position))
(postv-text (substring text (+ vowel-position 1) (string-length text)))
(prev-text-stencil (interpret-markup layout props prev-text))
(vowel-stencil (interpret-markup layout props vowel))
(postv-text-stencil (interpret-markup layout props postv-text))
(prev-text-width (interval-length (ly:stencil-extent prev-text-stencil X)))
(vowel-width (interval-length (ly:stencil-extent vowel-stencil X)))
(postv-text-width (interval-length (ly:stencil-extent postv-text-stencil
X)))
(vowel-width-plus-space (+ vowel-width (- text-width (+ prev-text-width
vowel-width postv-text-width))))
(vowel-centered-x (- (* 0.5 text-width) (+ postv-text-width (* 0.5
vowel-width-plus-space))))
(stack-stencil-line 0
(list text-stencil text-stencil text-stencil)) ;INSTEAD I WANT TO RETURN
vowel-centered-x
)))

#(define (vowel-center music)
  "For every EventChord in elements of @var{music}, if elements in
EventChord has a LyricEvent, add an item just before the EventChord
that will provide the appropriate self-alignment-X to allow vowel-centered
lyrics."
  (define (insert-X-align element-list)
     (if (null? element-list)
         '()
         (let* ((element (car element-list))
                (element-name (ly:music-property element 'name))
                (syllable (if (eq? element-name 'EventChord)
                           (let ((sub-element
                                  (car
                                    (ly:music-property element
'elements))))
                            (if (eq? (ly:music-property
                                      sub-element
                                      'name
                                      'LyricEvent))
                                (ly:music-property sub-element 'text)
                                #f))
                            #f)))
             (if syllable
              (cons
                (make-music
                 'ContextSpeccedMusic
                 'context-type 'Bottom
                 'element
                 (make-music
                  'OverrideProperty
                  'pop-first #t
                  'grob-property-path '(self-alignment-X)
                  'grob-value 0 ;HERE I WOULD INSTEAD LIKE TO CALL THE
MARKUP FUNCTION centertext WITH syllable
                  'once #t
                  'symbol 'LyricText))
              (cons
               element
               (insert-X-align (cdr element-list))))
             (cons element (insert-X-align (cdr element-list)))))))
  (set! (ly:music-property music 'elements)
        (insert-X-align (ly:music-property music 'elements)))
  music)

vowelAlignedLyrics =
 #(define-music-function (parser location music) (ly:music?)
   "Set x alignment so each syllable of @var{music} will be
aligned with the first vowel centered on the note."
   (vowel-center music))

chant = \relative c'' { c4 d4 c4 c4 c4 }
words = \lyricmode { aligned words dont come easy }

\score {
  <<
    \new Voice = "melody" \chant
    \new Lyrics \lyricsto "melody" \vowelAlignedLyrics \words
    >>
}
_______________________________________________
lilypond-user mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to