1 Commits

Author SHA1 Message Date
tux
0338f1329b new engraver for spacing in chordlyrics 2025-11-03 10:59:53 +01:00

View File

@@ -255,85 +255,110 @@
Chord_lyrics_spacing_engraver = Chord_lyrics_spacing_engraver =
#(lambda (ctx) #(lambda (ctx)
(let ((last-lyric-syllable #f) (let ((last-note-head #f)
(note-head-extended #f)
(last-lyric-syllable-width 0) (last-lyric-syllable-width 0)
(lyric-width-since-last-chord 0) (lyric-width-since-last-chord 0)
(last-printed-chord #f) (notes-on-syllable-count 0)
(chord-width-since-last-lyric 0) (last-chord-name #f)
(lyrics-seen-since-break #f) (remaining-chord-width 0)
(have-a-rest #f)) (last-rest #f)
(rest-count 0)
(multi-measure-rest-count 0)
(stanza-shift 0))
(make-engraver (make-engraver
(listeners (listeners
((multi-measure-rest-event engraver event) ((multi-measure-rest-event engraver event)
(set! have-a-rest #t) (set! multi-measure-rest-count (+ multi-measure-rest-count 1))
)
((rest-event engraver event)
(set! have-a-rest #t)
)
((lyric-event engraver event)
(set! have-a-rest #f)
) )
((break-event engraver event) ((break-event engraver event)
(set! last-lyric-syllable #f) (set! last-note-head #f)
(set! note-head-extended #f)
(set! last-lyric-syllable-width 0) (set! last-lyric-syllable-width 0)
(set! lyric-width-since-last-chord 0) (set! lyric-width-since-last-chord 0)
(set! last-printed-chord #f) (set! notes-on-syllable-count 0)
(set! chord-width-since-last-lyric 0) (set! last-chord-name #f)
(set! lyrics-seen-since-break #f) (set! remaining-chord-width 0)
(set! last-rest #f)
(set! rest-count 0)
(set! multi-measure-rest-count 0)
(set! stanza-shift 0)
)) ))
(acknowledgers (acknowledgers
((note-head-interface this-engraver grob source-engraver)
(if (and (> rest-count 0) (not last-note-head))
(let ((rest-spacing-on-line-start 1.2))
(ly:grob-set-property! grob 'minimum-X-extent (cons (- rest-spacing-on-line-start) 0))
(set! stanza-shift rest-spacing-on-line-start)
))
(set! notes-on-syllable-count (+ 1 notes-on-syllable-count))
(set! last-note-head grob)
(set! note-head-extended #f)
(set! last-rest #f)
(set! rest-count 0)
(set! multi-measure-rest-count 0)
)
((lyric-syllable-interface this-engraver grob source-engraver) ((lyric-syllable-interface this-engraver grob source-engraver)
(let ((syllable-width (interval-length (ly:grob-extent grob grob X)))) (set! remaining-chord-width (max 0 (- remaining-chord-width lyric-width-since-last-chord)))
(set! lyric-width-since-last-chord (+ lyric-width-since-last-chord syllable-width)) (set! last-lyric-syllable-width (- (cdr (ly:grob-extent grob grob X)) 0.2))
(set! last-lyric-syllable-width syllable-width) (set! lyric-width-since-last-chord (+ lyric-width-since-last-chord last-lyric-syllable-width))
) (if last-note-head (set! notes-on-syllable-count 1))
(if (> chord-width-since-last-lyric 0)
(if lyrics-seen-since-break
(ly:grob-set-property! grob 'extra-spacing-width
(cons (- chord-width-since-last-lyric) (cdr (ly:grob-property grob 'extra-spacing-width '(0 . 0)))))
(if last-printed-chord
(let ((last-printed-chord-width (interval-length (ly:grob-extent last-printed-chord last-printed-chord X))))
(ly:grob-set-parent! grob X last-printed-chord)
(ly:grob-set-property! grob 'X-offset last-printed-chord-width)
)))
)
(set! last-lyric-syllable grob)
(set! chord-width-since-last-lyric 0)
(set! lyrics-seen-since-break #t)
) )
((chord-name-interface this-engraver grob source-engraver) ((chord-name-interface this-engraver grob source-engraver)
(if (not (and (if (not (and
(boolean? (ly:grob-property grob 'begin-of-line-visible)) (boolean? (ly:grob-property grob 'begin-of-line-visible))
(ly:grob-property grob 'begin-of-line-visible))) (ly:grob-property grob 'begin-of-line-visible)))
(let* ((last-printed-chord-width (if last-printed-chord (interval-length (ly:grob-extent last-printed-chord last-printed-chord X)) 0)) (let ((on-a-rest (> rest-count 0)))
(chord-overwidth (- last-printed-chord-width lyric-width-since-last-chord)) (if (not on-a-rest)
(chord-gap 0.5)) (set! notes-on-syllable-count (- notes-on-syllable-count 1)))
(if have-a-rest (if (and last-chord-name (= multi-measure-rest-count 1) (> lyric-width-since-last-chord remaining-chord-width))
(let ((chord-width (interval-length (ly:grob-extent grob grob X)))) (ly:grob-set-property! last-chord-name 'extra-spacing-width (cons -0.1 (+ 0.1 (- lyric-width-since-last-chord remaining-chord-width)))))
(if last-lyric-syllable (if last-note-head
(let* ((last-note-min-x-extent (ly:grob-property last-note-head 'minimum-X-extent))
(last-note-min-x-lower (if (pair? last-note-min-x-extent) (car last-note-min-x-extent) 0))
(last-note-min-x-upper (if (pair? last-note-min-x-extent) (cdr last-note-min-x-extent) 0)))
(if on-a-rest
(begin (begin
(ly:grob-set-parent! grob X last-lyric-syllable) (if (not note-head-extended)
(ly:grob-set-property! grob 'X-offset last-lyric-syllable-width)
)
(if last-printed-chord
(begin (begin
(ly:grob-set-parent! grob X last-printed-chord) (ly:grob-set-property! last-note-head 'minimum-X-extent
(ly:grob-set-property! grob 'X-offset (+ chord-gap last-printed-chord-width)) (cons last-note-min-x-lower (- last-lyric-syllable-width -2 (* 2.2 rest-count))))
))) (set! note-head-extended #t)
(set! chord-width-since-last-lyric (+ chord-width-since-last-lyric chord-width chord-gap))
)) ))
(if (and last-lyric-syllable last-printed-chord (> chord-overwidth 0)) (ly:grob-set-property! last-rest 'minimum-X-extent (cons 0 2))
(ly:grob-set-property! last-lyric-syllable 'extra-spacing-width
(cons (car (ly:grob-property last-lyric-syllable 'extra-spacing-width '(0 . 0))) (+ chord-gap chord-overwidth)))
)
(set! last-printed-chord grob)
(set! last-lyric-syllable #f)
(set! lyric-width-since-last-chord 0)
) )
(if (and (> lyric-width-since-last-chord 0)
(> remaining-chord-width lyric-width-since-last-chord))
(ly:grob-set-property! last-note-head 'minimum-X-extent
(cons (- -1.2 (- remaining-chord-width lyric-width-since-last-chord)) last-note-min-x-upper))
(let* ((width-per-note-head 0.5)
(note-width-since-last-chord (* width-per-note-head notes-on-syllable-count)))
(if (> remaining-chord-width note-width-since-last-chord)
(ly:grob-set-property! last-note-head 'minimum-X-extent
(cons (- note-width-since-last-chord remaining-chord-width) last-note-min-x-upper))
) )
) )
) )
))) )))
(set! last-chord-name grob)
(set! remaining-chord-width
(if (and on-a-rest (equal? (ly:prob-property (ly:grob-property grob 'cause) 'duration) (ly:prob-property (ly:grob-property last-rest 'cause) 'duration)))
0
(cdr (ly:grob-extent grob grob X))))
(set! lyric-width-since-last-chord 0)
(set! notes-on-syllable-count (if on-a-rest 0 1))
))
)
((rest-interface this-engraver grob source-engraver)
(set! rest-count (+ 1 rest-count))
(set! last-rest grob)
(set! multi-measure-rest-count 0)
)
((stanza-number-interface this-engraver grob source-engraver)
(ly:grob-set-property! grob 'padding (+ 1 stanza-shift)))
))))
%#(ly:set-option 'debug-skylines #t)
#(define-markup-command (chordlyrics layout props lyrics) (ly:music?) #(define-markup-command (chordlyrics layout props lyrics) (ly:music?)
#:properties ((verse-chords #{#}) #:properties ((verse-chords #{#})
@@ -412,6 +437,15 @@ Chord_lyrics_spacing_engraver =
\remove Note_heads_engraver \remove Note_heads_engraver
\remove Script_engraver \remove Script_engraver
} }
\context {
\NullVoice
\consists Rest_engraver
\omit Rest
\override Rest.X-extent = #'(0 . 0)
\undo \omit NoteHead
\hide NoteHead
\override NoteHead.X-extent = #'(0 . 0.5)
}
} }
} }
} }