lilypond-user
[Top][All Lists]
Advanced

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

Re: vowel aligned lyrics - want to improve it


From: Wolf Alight
Subject: Re: vowel aligned lyrics - want to improve it
Date: Wed, 17 Feb 2010 11:32:53 +0100


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
    >>  
}  


 




reply via email to

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