lilypond-user
[Top][All Lists]
Advanced

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

Rather involved TextSpanner edge-text Scheme markup question


From: Trevor Bača
Subject: Rather involved TextSpanner edge-text Scheme markup question
Date: Mon, 18 Sep 2006 01:13:41 -0500

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.



--
Trevor Bača
address@hidden

reply via email to

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