%% http://lsr.di.unimi.it/LSR/Item?id=744 #(define linebreakindicator "\\") % \nl command that inserts the placeholder event into a lyrics nl = #(make-music 'LineBreakEvent) %% Function to extract strings from lyrics. % #(define (lyrics->list lyrics) "Return only syllables and hyphens from @code{lyrics}." (if (ly:music? lyrics) (cond ((music-is-of-type? lyrics 'lyric-event) (let* ((art (ly:music-property lyrics 'articulations)) (hyphen? (not (null? (filter (lambda (m) (music-is-of-type? m 'hyphen-event)) art)))) (text (ly:music-property lyrics 'text))) (if hyphen? (list text hyphen?) (list text)))) ((music-is-of-type? lyrics 'line-break-event) (list linebreakindicator)) (else (let ((elt (ly:music-property lyrics 'element)) (elts (ly:music-property lyrics 'elements))) (if (ly:music? elt) (lyrics->list elt) (if (null? elts) '() (map (lambda(x) (lyrics->list x)) elts)))))) '())) #(define (flatten-nonmarkup-list x) "Unnest list one level, but don't flatten markup constructs!" ;; The check for markup? is likely not needed ;; We let it in for clarity (append-map (lambda (e) (if (markup? e) e `(,@e))) x)) #(define (reduce-hyphens text) (if (not (null? text)) (let eat ((wd (car text)) (wds (cdr text))) (cond ((null? wds) (list wd)) ((and (boolean? (car wds)) (not (null? (cdr wds)))) (eat (markup #:concat (wd (cadr wds))) (cddr wds))) (else (cons wd (eat (car wds) (cdr wds)))))) '())) #(define-markup-command (verse layout props lyrics) (ly:music?) #:properties ((display-nl #f) (make-line make-justify-markup)) "Verse command that marks up a column of \\nl-separated lines" (let* ((unnested-lyr-ls (reduce-hyphens (flatten-nonmarkup-list (lyrics->list lyrics)))) (split-cond? (lambda (a) (and (not display-nl) (equal? a linebreakindicator)))) (list-of-lines (map (lambda (l) (make-line l)) (split-list-by-separator unnested-lyr-ls split-cond?)))) (if (null? unnested-lyr-ls) (begin (ly:warning "lyrics is empty, returning empty-stencil") empty-stencil) (interpret-markup layout props (make-column-markup list-of-lines))))) %%%%%%%%%%%%%%%% \header { tagline = ##f } mus = \relative c'' { \partial 4. g8 a g e c r4 r8 g' a g | f[ d] } words = \lyricmode { \override LyricHyphen.minimum-distance = #1.2 Du lil -- le \markup \italic fis -- \markup \italic ker \nl Du \markup \italic lil -- \markup \italic le fis -- ker } %{ << \new Voice = "mel" \mus \new Lyrics \lyricsto "mel" \words >> %} \mus \addlyrics { \words } \markup \line \bold { With line breaks (no overrides) } \markup { \verse #words } \markup \vspace #1 \markup \line \bold { With visible line break character } \markup { \override #'(display-nl . #t) \verse #words } %{ %% To have left-aligned word-wrapping with %% long lines, use \markup { \override #`(make-line . ,make-wordwrap-markup) \verse #words } %% (the default is make-justify-markup) %}