[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: bug in magnetic snapping lyrics engraver
From: |
Werner LEMBERG |
Subject: |
Re: bug in magnetic snapping lyrics engraver |
Date: |
Fri, 15 Apr 2022 04:52:29 +0000 (UTC) |
>> How did you do that? Sorry to rain on your parade, but I would not
>> want you to put a lot of work in it if it will not be of mergeable
>> quality.
>
> Attached. In the end the necessary modifications were surprisingly
> minor. Please comment, there is certainly room for improvements.
Attached is another version for testing without the need to patch
LilyPond.
Werner
% magnetic-lyrics.ily
%
% written by
% Jean Abou Samra <jean@abou-samra.fr>
% Werner Lemberg <wl@gnu.org>
%
% Version 2022-Apr-15
\version "2.23.7"
#(define (Left_hyphen_pointer_engraver context)
"Collect syllable-hyphen-syllable occurrences in lyrics and store
them in properties. This engraver only looks to the left. For
example, if the lyrics input is @code{foo -- bar}, it does the
following.
@itemize @bullet
@item
Set the @code{text} property of the @code{LyricHyphen} grob between
@q{foo} and @q{bar} to @code{foo}.
@item
Set the @code{left-hyphen} property of the @code{LyricText} grob with
text @q{foo} to the @code{LyricHyphen} grob between @q{foo} and
@q{bar}.
@end itemize
Use this auxiliary engraver in combination with the
@code{lyric-@/text::@/apply-@/magnetic-@/offset!} hook."
(let ((hyphen #f)
(text #f))
(make-engraver
(acknowledgers
((lyric-syllable-interface engraver grob source-engraver)
(set! text grob)))
(end-acknowledgers
((lyric-hyphen-interface engraver grob source-engraver)
(when (not (grob::has-interface grob 'lyric-space-interface))
(set! hyphen grob))))
((stop-translation-timestep engraver)
(when (and text hyphen)
(ly:grob-set-object! text 'left-hyphen hyphen))
(set! text #f)
(set! hyphen #f)))))
#(define (lyric-text::apply-magnetic-offset! grob)
"If the space between two syllables is less than the value in
property @code{LyricText@/.details@/.squash-threshold}, move the right
syllable to the left so that it gets concatenated with the left
syllable.
Use this function as a hook for
@code{LyricText@/.after-@/line-@/breaking} if the
@code{Left_@/hyphen_@/pointer_@/engraver} is active."
(let ((hyphen (ly:grob-object grob 'left-hyphen #f)))
(when hyphen
(let ((left-text (ly:spanner-bound hyphen LEFT)))
(when (grob::has-interface left-text 'lyric-syllable-interface)
(let* ((common (ly:grob-common-refpoint grob left-text X))
(this-x-ext (ly:grob-extent grob common X))
(left-x-ext
(begin
;; Trigger magnetism for left-text.
(ly:grob-property left-text 'after-line-breaking)
(ly:grob-extent left-text common X)))
;; `delta` is the gap width between two syllables.
(delta (- (interval-start this-x-ext)
(interval-end left-x-ext)))
(details (ly:grob-property grob 'details))
(threshold (assoc-get 'squash-threshold details 0.2)))
(when (< delta threshold)
(let* (;; We have to manipulate the input text so that
;; ligatures crossing syllable boundaries are not
;; disabled. For languages based on the Latin
;; script this is essentially a beautification.
;; However, for non-Western scripts it can be a
;; necessity.
(lt (ly:grob-property left-text 'text))
(rt (ly:grob-property grob 'text))
;; Append new syllable.
(ltrt (if (and (string? lt) (string? rt))
(string-append lt rt)
(make-concat-markup (list lt rt))))
;; Right-align `ltrt` to the right side.
(markup (grob-interpret-markup
grob
(make-translate-markup
(cons (interval-length this-x-ext) 0)
(make-right-align-markup ltrt)))))
(begin
;; Don't print `left-text`.
(ly:grob-set-property! left-text 'stencil #f)
;; Set text and stencil (which holds all collected
;; syllables so far) and shift it to the left.
(ly:grob-set-property! grob 'text ltrt)
(ly:grob-set-property! grob 'stencil markup)
(ly:grob-translate-axis! grob (- delta) X))))))))))
#(define (lyric-hyphen::displace-bounds-first grob)
;; Make very sure this callback isn't triggered too early.
(let ((left (ly:spanner-bound grob LEFT))
(right (ly:spanner-bound grob RIGHT)))
(ly:grob-property left 'after-line-breaking)
(ly:grob-property right 'after-line-breaking)
(ly:lyric-hyphen::print grob)))
\layout {
\context {
\Lyrics
\consists #Left_hyphen_pointer_engraver
\override LyricText.after-line-breaking =
#lyric-text::apply-magnetic-offset!
\override LyricHyphen.stencil = #lyric-hyphen::displace-bounds-first
\override LyricText.details.squash-threshold = 0.4
\override LyricHyphen.minimum-distance = 0
\override LyricHyphen.minimum-length = 0.4
\override LyricSpace.minimum-distance = 1
}
}
- Re: bug in magnetic snapping lyrics engraver, (continued)
- Re: bug in magnetic snapping lyrics engraver, Kieren MacMillan, 2022/04/06
- Re: bug in magnetic snapping lyrics engraver, Jean Abou Samra, 2022/04/06
- Re: bug in magnetic snapping lyrics engraver, Werner LEMBERG, 2022/04/07
- Re: bug in magnetic snapping lyrics engraver, Jean Abou Samra, 2022/04/07
- Re: bug in magnetic snapping lyrics engraver, Werner LEMBERG, 2022/04/13
- Re: bug in magnetic snapping lyrics engraver, Werner LEMBERG, 2022/04/14
- Re: bug in magnetic snapping lyrics engraver, Jean Abou Samra, 2022/04/14
- Re: bug in magnetic snapping lyrics engraver, Werner LEMBERG, 2022/04/14
- Re: bug in magnetic snapping lyrics engraver, Jean Abou Samra, 2022/04/14
- Re: bug in magnetic snapping lyrics engraver, Werner LEMBERG, 2022/04/14
- Re: bug in magnetic snapping lyrics engraver,
Werner LEMBERG <=
- Re: bug in magnetic snapping lyrics engraver, Kieren MacMillan, 2022/04/07
- Re: bug in magnetic snapping lyrics engraver, Carl Sorensen, 2022/04/07
Re: bug in magnetic snapping lyrics engraver, Werner LEMBERG, 2022/04/07
Re: bug in magnetic snapping lyrics engraver, Alexander Kobel, 2022/04/14