Thank you very much, Aaron! The \markup \null construction is something
that I will have to study carefully in the next few days to fully grasp it.
I made some adjustments to the formatting, so that it matches the default
\tempo formatting of Lilypond, especially when using a tempo range
(Lilypond uses – instead of -, and leaves a space before and after the
hyphen, so your added \concat is not required here ;-)), and I made all
\tempo text bold by default (as Lilypond does). However, your example made
me compare it with Lilypond's formatting and there's still one issue even
after fixing the other small details: When the user writes \tempo "Adagio"
4 = 70, he expects the tempo unit and metronome count in parenthesis after
the given text. Here I'm absolutely limited by my Scheme ignorance on how
to achieve that (somehow combining several conditions and adding \markup
{#text  \concat { "(" #tempo-unit } = \concat { #metronome-count ")" } ?).

This is not going to be easy to solve.  You need to know when then
> \stopTextSpan occurs so that the \tempo command applies at that moment.
> However that information is entirely unknown at the time of
> \tempoTextSpan.
>

Oh! Right! Then I guess one solution would be to name the function
\tempoSpan instead, with a "dummy" variable (for the sake of syntax)
startTempoSpan = \startTextSpan and a variable stopTempoSpan, that would
have to call the previous obtained values of tempoSpan (that I can't re-use
because they're a markup and not a number anymore? Or because I don't know
how to call information obtained in other variables? Or both? GUILLE
complains of an Unbound variable: tempo-unit and Unbound variable:
metronome-count) and would add something like stopTempoSpan = \stopTextSpan
\once \omit Score.MetronomeMark \tempo #tempo-unit = #metronome-count.
Simulating a rit. and accel. is probably too much to ask. I don't even know
how to do that independently of this script.

Anyways, this script is already quite awesome! :-) Thank you!

Here the progress of the script with the small formatting fixes and the new
name \tempoSpan in the hope that a \stopTempoSpan as described above can be
successfully created:

tempoSpan =
#(define-scheme-function
    (leftmarkup tempo lefthalign righthalign)
    (markup? tempo? number? number?)
    (set! tempo (first (extract-typed-music tempo 'tempo-change-event)))
    (let ((tempo-unit (ly:prob-property tempo 'tempo-unit #f))
          (metronome-count (ly:prob-property tempo 'metronome-count #f))
          (text (ly:prob-property tempo 'text #f))
          )
      (set! tempo-unit
        (if (ly:duration? tempo-unit)
            #{ \markup {
              \note #(ly:duration->string tempo-unit) #UP
                } #}
            #{ \markup \null #} ))
      (set! metronome-count
        (cond ((number-pair? metronome-count)
               #{ \markup { =
                  #(format #f "~d" (car metronome-count)) –
                  #(format #f "~d" (cdr metronome-count)) } #})
              ((number? metronome-count)
               #{ \markup { =
                  #(format #f "~d" metronome-count) } #})
              (else #{ \markup \null #})))
      (set! text
        (if (markup? text)
            #{ \markup \bold \abs-fontsize #11 \upright #text #}
            #{ \markup \null #}))
      #{
\once \override TextSpanner.bound-details.left-broken.text = ##f
\once \override TextSpanner.bound-details.right-broken.text = ##f
\once \override TextSpanner #'(bound-details left text) =  \markup \halign
#lefthalign \abs-fontsize #11 #leftmarkup
\once \override TextSpanner #'(bound-details right text) = \markup \halign
#righthalign \line { #text \abs-fontsize #10 \general-align #Y #DOWN
#tempo-unit
\abs-fontsize #11 \upright #metronome-count }
      #}))

Best regards,
Martín.

Am Fr., 18. Sept. 2020 um 12:16 Uhr schrieb Aaron Hill <
[email protected]>:

> On 2020-09-18 2:01 am, Martín Rincón Botero wrote:
> > [ . . . ] The thing I couldn't adapt from your script
> > is the Text part, when the user writes a new tempo with a construction
> > like
> > \tempo "Allegro". I suppose I have to somehow put my \once \override
> > TextSpanner #'(bound-details right text) in some sort of conditional so
> > that when the user puts a text, it displays a text, when it's a
> > metronome,
> > a metronome :-), but I couldn't figure out how to adapt what you
> > already
> > had.
>
> You could do things with conditionals, but it might make better sense to
> simply use a null markup when an element is not present.  Consider:
>
> %%%%
> \version "2.20.0"
>
> #(define (tempo? arg)
>     (and (ly:music? arg)
>          (not (null? (extract-typed-music arg 'tempo-change-event)))))
>
> tempoTextSpan =
> #(define-scheme-function
>     (leftmarkup tempo lefthalign righthalign)
>     (markup? tempo? number? number?)
>     (set! tempo (first (extract-typed-music tempo 'tempo-change-event)))
>     (let ((tempo-unit (ly:prob-property tempo 'tempo-unit #f))
>           (metronome-count (ly:prob-property tempo 'metronome-count #f))
>           (text (ly:prob-property tempo 'text #f))
>           )
>       (set! tempo-unit
>         (if (ly:duration? tempo-unit)
>             #{ \markup {
>               \note #(ly:duration->string tempo-unit) #UP
>                 } #}
>             #{ \markup \null #} ))
>       (set! metronome-count
>         (cond ((number-pair? metronome-count)
>                #{ \markup { = \concat {
>                   #(format #f "~d" (car metronome-count)) -
>                   #(format #f "~d" (cdr metronome-count)) } } #})
>               ((number? metronome-count)
>                #{ \markup { =
>                   #(format #f "~d" metronome-count) } #})
>               (else #{ \markup \null #})))
>       (set! text
>         (if (markup? text)
>             #{ \markup \abs-fontsize #11 \upright #text #}
>             #{ \markup \null #}))
>       #{
> \once \override TextSpanner.bound-details.left-broken.text = ##f
> \once \override TextSpanner.bound-details.right-broken.text = ##f
> \once \override TextSpanner #'(bound-details left text) =  \markup
> \halign
> #lefthalign \abs-fontsize #11 #leftmarkup
> \once \override TextSpanner #'(bound-details right text) = \markup
> \halign
> #righthalign \line { #text \abs-fontsize #10 \general-align #Y #DOWN
> #tempo-unit
> \abs-fontsize #11 \upright #metronome-count }
>       #}))
>
> {
>    \tempoTextSpan "accel." \tempo 4 = 80 #LEFT #RIGHT
>    c'4\startTextSpan 4 4 4 2 2 d'1\stopTextSpan R1
>    \tempoTextSpan "rall." \tempo "Adagio" 4 = 65-70 #LEFT #CENTER
>    d'4\startTextSpan 4 4 4 2 2 e'1\stopTextSpan R1
>    \tempoTextSpan "rit." \tempo \markup \box "Grave" #LEFT #LEFT
>    e'4\startTextSpan 4 4 4 2 2 f'1\stopTextSpan R1 \bar "|."
> }
> %%%%
>
> The advantage of the above approach is that the final markup is really
> nothing more than a concatenation of the elements.
>
>
> > I also wasn't successful in adding \once \omit Score.MetronomeMark
> > \tempo #tempo-unit = #metronome-count, so that the MIDI can pick up the
> > new
> > tempo mark, if a metronome is given (probably because the new tempo is
> > converted to a markup and can't be used as a "real" tempo definition
> > anymore?).
>
> This is not going to be easy to solve.  You need to know when then
> \stopTextSpan occurs so that the \tempo command applies at that moment.
> However that information is entirely unknown at the time of
> \tempoTextSpan.
>
> I would suggest handling MIDI tempo manually, that way you can issue as
> many \tempo commands as needed to properly simulate the accel, rall, and
> rit instructions.
>
> Otherwise, this whole thing really looks like a job for a custom
> engraver/performer.
>
>
> -- Aaron Hill



-- 
www.martinrinconbotero.com

Reply via email to