[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: text block as spanner
From: |
Thomas Morley |
Subject: |
Re: text block as spanner |
Date: |
Sat, 2 Feb 2019 21:09:42 +0100 |
Am Do., 31. Jan. 2019 um 10:27 Uhr schrieb Leo Correia de Verdier
<address@hidden>:
>
> Dear List!
>
> I’m still learning lilypond and working on a piece with long text
> instructions that appear over a note or group of notes. So far I have managed
> to achieve this by hacking off the stencils from text spanners and replacing
> them with the line wrapped markup, but I feel there should be a neater
> solution out there that I just haven’t thought or learned about. This hack
> has also reached it’s limits because it has created the need for multiple
> simultaneous text spanners (not in the example). While I could go further
> down the hack road by placing additional spanners in separate voices with
> spacer rests or starting to destroy trill spanners too, that would just
> increase the mess. Could you please point me towards a tidier path? :)
>
> Thanks a lot!
>
> /Leo
>
> \version "2.19.80"
>
> longTextInstr =
> #(define-music-function (alongtext)
> (string?)
> #{
> \once \override Staff.TextSpanner.stencil =
> #(lambda (grob)
> (let* ((grob-X (interval-length
> (ly:stencil-extent (ly:line-spanner::print grob) X)))
> (layout (ly:grob-layout grob))
> (props (ly:grob-alist-chain grob
> (ly:output-def-lookup layout
> 'text-font-defaults))))
>
> (ly:text-interface::interpret-markup layout props
> #{ \markup {
> \override #(cons 'line-width grob-X)
> \wordwrap-string #alongtext }
> #})
> ))
> #}
> )
>
> \relative {
> c'1 \longTextInstr "this is a long text instruction to be printed
> line-wrapped over a group of notes"
> d \startTextSpan
> e f
> e \stopTextSpan
> d
> }
Hi Leo,
you're code is fine. It does exactly what it is supposed to do.
You could consider, making it a tweak and you could use
'grob-interpret-markup' to avoid finding 'layout' 'props' yourself.
Though, it's a kown limitation that you can't use more than one
TextSpanner per Voice.
You already found the usual workaround: Additional Voices.
A bold workaround is to define the whole infrastructure for
TextSpanners with new/renamed events (class and type), grobs,
engravers and
start/stop-commands.
\version "2.19.82"
\include "multiple-spanner-grobs-engravers.ly"
\createSpannersAndEngravers #'(X Y Z)
\layout {
\context {
\Global
\grobdescriptions #all-grob-descriptions
}
\context {
\Voice
\consists \XTextSpannerEngraver
\consists \YTextSpannerEngraver
\consists \ZTextSpannerEngraver
}
}
#(define (text-spanner->text text)
(lambda (grob)
(let* ((grob-X
(interval-length
(ly:stencil-extent (ly:line-spanner::print grob) X))))
(grob-interpret-markup grob
#{
\markup \override #(cons 'line-width grob-X) \wordwrap-string #text
#}))))
txtI =
"this is a long text instruction to be printed line-wrapped over a group of
notes"
txtII =
"this is another long text instruction to be printed line-wrapped below a group
of notes"
\relative {
c'1
d
-\tweak stencil #(text-spanner->text txtI)
\startTextSpan
-\tweak stencil #(text-spanner->text txtII)
_\x-start
e f
e \stopTextSpan
d \x-stop
}
HTH,
Harm
multiple-spanner-grobs-engravers.ly
Description: Text Data
- Re: text block as spanner,
Thomas Morley <=