(no subject)

From:

Han-Wen Nienhuys

Subject:

(no subject)

Date:

Wed, 6 Mar 2002 23:36:24 +0100

Subject: Re: wrapping long textual markup
In-Reply-To: <address@hidden>
References: <address@hidden>
<address@hidden>
X-Mailer: VM 6.96 under Emacs 20.7.1
FCC: ~/persoonlijk/Mail/sent
address@hidden writes:
> > Of course, a clumsy solution to your problem is to hard-code
> > the line breaks of the music using \break commands and then
> > splitting the sonnet into several text scripts, one for each
> > line. This will of course be more troublesome if you want it
> > typeset both in the score and in the separate parts.
> >
> > In principle, Lilypond has all the knowledge needed to do
> > the requested line breaking, it's just a matter of implementing
> > the mechanism.
>
> I don't mind hacking at it a bit. But since lilypond is mixture
> of 4+ languages, it would be helpful if you could point me in
> the right direction...
ok, I'm taking this to lilypond-devel, which is more appropriate.
Hacking it in shouldn't be too tough:
* Your objective is to make a spanner, similar to TextSpanner (used
for cresc.... ).
* The code will be easiest in C++. (Although, if you prefer Scheme,
I can provide the necessary callbacks.)
* You let the spanner start somewhere manually, and end it somewhere
else, in the input. The line breaking process will break it into
pieces (like slurs that cross line breaks). The tricky part is
then to decide which words go on which broken part; this is done
as follows:
* You have to make an after_line_breaking () callback.
* From this callback, find all of the pieces by examining
dynamic_cast<Spanner*> (spanner->origin_l_)->broken_into_l_arr_
* You can find the length of each piece by examining
common = spanner->get_bound (RIGHT)
->common_refpoint(spanner->get_bound (LEFT));
spanner->get_bound (RIGHT)->relative_coordinate (common, X_AXIS)
- spanner->get_bound (LEFT)->relative_coordinate (common, X_AXIS)
* Then you have to find the dimensions of each word, using
Font_metric::text_dimension(), and do a standard word wrap
insert the appropriate words using set_grob_property ("text",
ly_str02scm (words));
* A simple brew_molecule callback should take care of getting the
text and making it into a molecule.
* For instantiating the stuff, use TextSpanner for now (see the
refman example). You can install your own functions by doing
TextSpanner \override #'after-line-rbeaking-callback =
#Running_text::after_line_breaking()
TextSpanner \override #'molecule-callback =
#Running_text::brew_molecule()
On second thought, it would be rather nice if the code were done in
Scheme, so if you're fluent in Scheme, I'd love to add the appropriate
functions to make this possible.
--
Han-Wen Nienhuys | address@hidden | http://www.cs.uu.nl/~hanwen/