lilypond-user
[Top][All Lists]
Advanced

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

TextSpanner usability improvements (was Re: Scheme predicative types)


From: Aaron Hill
Subject: TextSpanner usability improvements (was Re: Scheme predicative types)
Date: Fri, 18 Sep 2020 22:01:52 -0700
User-agent: Roundcube Webmail/1.4.2

On 2020-09-18 2:06 pm, Martín Rincón Botero wrote:
[...] There are two
unsatisfactory problems for usability involved from my point of view. One
is the impossibility to use proper markup syntax for text spanners.

I am uncertain what you mean by "proper" markup syntax. Even though they are called "TextSpanners", the text can be any markup? value:

%%%%
{ b'4 -\tweak bound-details.left.text \markup \box ?
      -\tweak bound-details.right.text \markup \circle !
      -\tweak font-series #'bold
      -\tweak font-shape #'upright
      \startTextSpan
  a' g'2 | f'4 g'8 a' g'2 | a'1\stopTextSpan }
%%%%

Your proposed...

%%%%
\markupSpan { "sul pont." \arrow "sul tasto" }
%%%%

...while interesting, is invalid syntax and surely not proper. Perhaps you simply meant something that *looks* like it could be valid LilyPond.


[...] In the case of
text spanners, the default has no musical use: a dashed line with no text on either side. The syntax of a text spanner has the serious omission of starting something without user input (\startTextSpan starts what? The user
should have an "interface" to give an initial input.

Consider a \textSpan function that has you specify the left and right text. What happens when you only need left-side text? Is it satisfactory for a user to have to say \textSpan "left" ""? Next, there are options for padding and whether the side of the spanner terminates in an arrow. What happens when you need to specify the padding on one side and the arrow-type on the other? Including all of these as parameters to a function could make the function unwieldy to use when one only needs to specify a few values. Optional arguments help to some degree, but they aren't perfect especially when there is ambiguity of types.

The existing interface for TextSpanners requires that one manually \override or \tweak properties so that you only specify what you need. This may seem cumbersome when adjusting many things, but it is at least very clear what is going on. You certainly don't have to remember which argument is which. And users of TextSpanners should invest in creating their own wrappers for commonly used items. Consider something like this:

%%%%
startRitSpan =
  -\tweak bound-details.left.text "rit."
  -\tweak to-barline ##t
  \startTextSpan

{ b'4 a' g'2\startRitSpan |
  f'4 g'8 a' g'2 | a'1\stopTextSpan }
%%%%

The result is something that is more succinct to use within the actual music, uncluttered by \overrides and \tweaks. And being reusable assists in keeping the overall score consistent. (It is mildly annoying though to have to use \stopTextSpan, but it is probably better than polluting the namespace with a whole host of \stop*Span aliases that all do the same thing.)

While the above is some defense of the existing interface, there could be ways to improve the experience. For instance, imagine this:

%%%%
{ b'4 a' g'2\startTextSpan \with { left-text = "rit."
                                   to-barline = ##t } |
  f'4 g'8 a' g'2 | a'1\stopTextSpan }
%%%%

I do wonder if my obsession with ly:context-mod? goes too far, but I keep finding that the \with {} construct is a great alternative to variable argument lists. There is never any confusion as properties are well-named; plus, the construct is quite extensible.


[...] The second issue is the mentioned 2013
issue. Lilypond lacks the possibility of using text spanners not only with
a \tempo syntax (which thanks to your script is very well solved now!),
something that makes the "music" in the code more legible (because there is proper markup of musical events) but also to format the whole thing as a
\tempo marking in the score (tempo indications are not attached to the
staff but to the system, and horizontally metronome marks are not attached to the first note of the measure but to the time signature above which they
are centered, that's why I included \halign properties in the script as
workaround).

That would point to TextSpanners not being the right fit/tool for the job. What we perhaps need is something like a MetronomeSpanner and possibly a RehearsalSpanner--connecting MetronomeMarks and RehearsalMarks, respectively. And then we need a way to attach the spanner to \tempos or \marks in an equivalent manner as you attach TextSpanners to notes.

That approach would better preserve the semantics of the underlying elements. Consuming a \tempo command only to produce a \markup that *looks* like a MetronomeMark but is not one leads to issues as you found with MIDI. The Tempo_performer cannot do what it needs to do as it does not understand what the \markup means. That is not to mention that the use of \tempo occurs at the wrong moment in the music. Such a proposed MetronomeSpanner would terminate with an actual \tempo command on either end at the correct moments. And the Tempo_performer could be improved to understand how to interpolate tempos that are connected by spanners.

What is unclear is how this would end up looking in practice. I am not sure something like \(start|stop)TempoSpan looks very good, especially since one might want to terminate a span with an invisible \tempo. (See my example above with \startRitSpan.)

I wonder if the parser's \etc could support defining new functions that borrow the syntax from built-in ones:

%%%%
% What we can do today... %
hideTempo = \once \omit Score.MetronomeMark

{ \hideTempo \tempo 4 = 90 }

% What would be nice to do... %
hiddenTempo = {
  \once \omit Score.MetronomeMark
  \tempo \etc
}

{ \hiddenTempo 4 = 90 }
%%%%

That might be asking too much.


-- Aaron Hill



reply via email to

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