lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Rather involved TextSpanner edge-text Scheme markup question


From: Mats Bengtsson
Subject: Re: Rather involved TextSpanner edge-text Scheme markup question
Date: Mon, 18 Sep 2006 09:04:20 +0200
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.6) Gecko/20060730 SeaMonkey/1.0.4

I expected something like
(markup #:pad-to-box '(0 . 0) '(-2 . 2) "f")
to solve the problem, but apparently it doesn't.

If you want to pursue your current approach, try the \combine markup command
(and try it first without your current #:hcenter commands, they caused me some
confusing results).

  /Mats

Trevor Bača wrote:
Hi,

I'm trying to get the edge text of a series of consecutive
TextSpanners to vertically align according to baseline.

I've pasted in a sequence of ever-closer steps but beware that the
post is long. If you're not interested in markup, skip to the next
thread.

Here's what I'm starting out with, in snippet 1: three different
TextSpanner layers.

%%% EDGE TEXT SNIPPET 1 %%%

\version "2.9.17"

\new Staff \with {
  \override TextSpanner #'dash-fraction = #'()
  \override TextSpanner #'direction = #down
  \override TextSpanner #'bound-padding = #1
} <<
  \time 3/8
  \new Voice {
     c'8 c'8 c'8
  }
  \new Voice \with {
     \override TextSpanner #'staff-padding = #3
  } {
\override TextSpanner #'edge-text = #(cons (markup #:hcenter "a" ) " ")
     s8 \startTextSpan
     \override TextSpanner #'edge-text = #(cons (markup #:hcenter "b"
) (markup #:hcenter "c"))
     s8 \stopTextSpan \startTextSpan
     s8 \stopTextSpan
  }
  \new Voice \with {
     \override TextSpanner #'staff-padding = #5.5
  } {
\override TextSpanner #'edge-text = #(cons (markup (#:hcenter "d")) " ")
     s8 \startTextSpan
     \override TextSpanner #'edge-text = #(cons (markup #:hcenter "e"
) (markup #:hcenter "f"))
     s8 \stopTextSpan \startTextSpan
     s8 \stopTextSpan
  }
  \new Voice \with {
     \override TextSpanner #'staff-padding = #8
  } {
\override TextSpanner #'edge-text = #(cons (markup #:hcenter "g" ) " ")
     s8 \startTextSpan
     \override TextSpanner #'edge-text = #(cons (markup #:hcenter "h"
) (markup #:hcenter "i"))
     s8 \stopTextSpan \startTextSpan
     s8 \stopTextSpan
  }


%%% END EDGE TEXT SNIPPET 1 %%%

This snippet 1 shows Lily's default behavior; it's less than optimal
because all the edge text *top aligns* rather than aligning by
baseline, which results not only in non-ideally aligned text but also
in uneven spanners, which is bad.


I asked a similar question about baseline alignment about TextScript
in this thread ...

  http://lists.gnu.org/archive/html/lilypond-user/2006-09/msg00037.html

... and Kieren helpfully pointed to the workaround of using a fake
character to force alignment.

Here's an example with a fake "l" following edge bit of edge text.
I've left the character visible so that it's easier to see what's
going on. Notice that the results are better, but now there's the
problem that some pieces of edge text *descend* too far.

%%% EDGE TEXT ALIGNMENT SNIPPET 2 %%%

\version "2.9.17"

\new Staff \with {
  \override TextSpanner #'dash-fraction = #'()
  \override TextSpanner #'direction = #down
  \override TextSpanner #'bound-padding = #1
} <<
  \time 3/8
  \new Voice {
     c'8 c'8 c'8
  }
  \new Voice \with {
     \override TextSpanner #'staff-padding = #3
  } {
\override TextSpanner #'edge-text = #(cons (markup #:hcenter "al") " ")
     s8 \startTextSpan
     \override TextSpanner #'edge-text = #(cons (markup #:hcenter
"bl") (markup #:hcenter "cl"))
     s8 \stopTextSpan \startTextSpan
     s8 \stopTextSpan
  }
  \new Voice \with {
     \override TextSpanner #'staff-padding = #5.5
  } {
\override TextSpanner #'edge-text = #(cons (markup (#:hcenter "dl")) " ")
     s8 \startTextSpan
     \override TextSpanner #'edge-text = #(cons (markup #:hcenter
"el") (markup #:hcenter "fl"))
     s8 \stopTextSpan \startTextSpan
     s8 \stopTextSpan
  }
  \new Voice \with {
     \override TextSpanner #'staff-padding = #8
  } {
\override TextSpanner #'edge-text = #(cons (markup #:hcenter "gl") " ")
     s8 \startTextSpan
     \override TextSpanner #'edge-text = #(cons (markup #:hcenter
"hl") (markup #:hcenter "il"))
     s8 \stopTextSpan \startTextSpan
     s8 \stopTextSpan
  }


%%% END EDGE TEXT ALIGNMENT SNIPPET 2 %%%



So, since descenders are the problem (like in the "g"), we can carry
the fake-character workaround a step further and add not only the fake
"l" but also a fake "g" in snippet 3.

%%% BEGIN EDGE TEXT ALIGNMENT SNIPPET 3 %%%

\version "2.9.17"

\new Staff \with {
  \override TextSpanner #'dash-fraction = #'()
  \override TextSpanner #'direction = #down
  \override TextSpanner #'bound-padding = #1
} <<
  \time 3/8
  \new Voice {
     c'8 c'8 c'8
  }
  \new Voice \with {
     \override TextSpanner #'staff-padding = #3
  } {
\override TextSpanner #'edge-text = #(cons (markup #:hcenter "gal") " ")
     s8 \startTextSpan
     \override TextSpanner #'edge-text = #(cons (markup #:hcenter
"gbl") (markup #:hcenter "gcl"))
     s8 \stopTextSpan \startTextSpan
     s8 \stopTextSpan
  }
  \new Voice \with {
     \override TextSpanner #'staff-padding = #5.5
  } {
\override TextSpanner #'edge-text = #(cons (markup (#:hcenter "gdl")) " ")
     s8 \startTextSpan
     \override TextSpanner #'edge-text = #(cons (markup #:hcenter
"gel") (markup #:hcenter "gfl"))
     s8 \stopTextSpan \startTextSpan
     s8 \stopTextSpan
  }
  \new Voice \with {
     \override TextSpanner #'staff-padding = #8
  } {
\override TextSpanner #'edge-text = #(cons (markup #:hcenter "ggl") " ")
     s8 \startTextSpan
     \override TextSpanner #'edge-text = #(cons (markup #:hcenter
"ghl") (markup #:hcenter "gil"))
     s8 \stopTextSpan \startTextSpan
     s8 \stopTextSpan
  }


%%% END EDGE TEXT ALIGNMENT SNIPPET 3 %%%



This snippet #3 finally has the spanners vertically aligned, which is
essential, and we've basically faked baseline alignment. Now two
things remain: the first is to make the fake "g"s and "l"s disappear,
and the second is to see if we can make the fake "g"s and "l"s take up
no (horizontal) space. I was able to figure out how to make the fake
"g"s and "l"s transparent with help from the section 12.4.1 "Markup
construction in Scheme"  in the manual. The code (in snippet 4, below)
looks moderately insane but does in fact work and all the spanners
line up vertically quite nicely.

%%% BEGIN EDGE TEXT ALIGNMENT SNIPPET 4 %%%

\version "2.9.17"

\new Staff \with {
  \override TextSpanner #'dash-fraction = #'()
  \override TextSpanner #'direction = #down
  \override TextSpanner #'bound-padding = #1
} <<
  \time 3/8
  \new Voice {
     c'8 c'8 c'8
  }
  \new Voice \with {
     \override TextSpanner #'staff-padding = #3
  } {
     \override TextSpanner #'edge-text = #(cons (markup #:hcenter
(markup #:transparent "g" "a" #:transparent "l")) " ")
     s8 \startTextSpan
     \override TextSpanner #'edge-text = #(cons
(markup #:hcenter (markup #:transparent "g" "b" #:transparent "l")) (markup #:hcenter (markup #:transparent "g" "c" #:transparent "l")))
     s8 \stopTextSpan \startTextSpan
     s8 \stopTextSpan
  }
  \new Voice \with {
     \override TextSpanner #'staff-padding = #5.5
  } {
     \override TextSpanner #'edge-text = #(cons (markup #:hcenter
(markup #:transparent "g" "d" #:transparent "l")) " ")
     s8 \startTextSpan
     \override TextSpanner #'edge-text = #(cons
(markup #:hcenter (markup #:transparent "g" "e" #:transparent "l")) (markup #:hcenter (markup #:transparent "g" "f" #:transparent "l")))
     s8 \stopTextSpan \startTextSpan
     s8 \stopTextSpan
  }
  \new Voice \with {
     \override TextSpanner #'staff-padding = #8
  } {
     \override TextSpanner #'edge-text = #(cons (markup #:hcenter
(markup #:transparent "g" "g" #:transparent "l")) " ")
     s8 \startTextSpan
     \override TextSpanner #'edge-text = #(cons
(markup #:hcenter (markup #:transparent "g" "h" #:transparent "l")) (markup #:hcenter (markup #:transparent "g" "i" #:transparent "l")))
     s8 \stopTextSpan \startTextSpan
     s8 \stopTextSpan
  }


%%% END EDGE TEXT ALIGNMENT SNIPPET 4 %%%


The problem now is that the transparent, fake "g" and "l" struts take
up horizontal space and cause weird things to happen with the space
around each piece of edge text.

In this post ...

  http://lists.gnu.org/archive/html/lilypond-user/2006-09/msg00127.html

... Mats gives a way of forcing pieces of text together. I'd like to
use Mats's suggestion here, but I'm not able to map the TeX-looking
\markup into Scheme-looking commands; also, what I'd really like to do
is not only make the fake struts *abut* the main visible text, but
actually *disappear* and take no horizontal space.


QUESTION. Can anyone suggest a way of making the "g" and "l" struts
take up no horizontal space?

BETTER QUESTION. Is there a way to explicitly get baseline alignment
of edge text?

EVEN BETTER QUESTION. If I'm wanting different layers of text spanners
like I've got in these examples, is there a better way of doing this?
I've considered using a \new Lyrics context (where you get baseline
alignment for free) but then I don't know how to instantiate the
spanners.



------------------------------------------------------------------------

_______________________________________________
lilypond-user mailing list
address@hidden
http://lists.gnu.org/mailman/listinfo/lilypond-user

--
=============================================
        Mats Bengtsson
        Signal Processing
        Signals, Sensors and Systems
        Royal Institute of Technology
        SE-100 44  STOCKHOLM
        Sweden
        Phone: (+46) 8 790 8463                         
       Fax:   (+46) 8 790 7260
        Email: address@hidden
        WWW: http://www.s3.kth.se/~mabe
=============================================





reply via email to

[Prev in Thread] Current Thread [Next in Thread]