lilypond-user
[Top][All Lists]
Advanced

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

Re: Scheme predicative types


From: Martín Rincón Botero
Subject: Re: Scheme predicative types
Date: Fri, 18 Sep 2020 23:08:43 +0200

Sorry, I said "That an \override has to be used for making a basic input (and mostly for actually overriding a property)", I meant "instead of mostly for actually overriding...".

Am Fr., 18. Sept. 2020 um 23:06 Uhr schrieb Martín Rincón Botero <martinrinconbotero@gmail.com>:
Regardless, I will leave you with my final contribution of a "cleaned
up" version with some logic and usage updates.  In particular, I
reordered the arguments to enable default values for the alignments. 
And the main refactoring uses a different approach to assembling the
markup, which makes handling the parentheses simpler.

Wow, thanks a million, Aaron! This works perfectly! This Scheme crash course is leaving me with much to chew for the next few weeks ;-) and your script is a great contribution!

Now, it is as if all
you need is a normal MetronomeMark aligned to the end of a TextSpanner. 
After all, reusing is preferred to reinventing.

That's right. It sounds simple but it isn't. There's an open issue about the subject since at least 2013 https://code.google.com/archive/p/lilypond/issues/3176. 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 opened a thread about it in July https://lists.gnu.org/archive/html/lilypond-user/2020-07/msg00263.html. Right now there is what I consider an abuse of \overrides. An \override should be used to be able to change "sensible" defaults. 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. This interface is what I call \markupSpan in my feature request, a function that I'm also implementing at least for personal use for the moment). That an \override has to be used for making a basic input (and mostly for actually overriding a property) is unsatisfactory. 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). 

So while you could continue to develop the function above, perhaps time
would be better spent solving the underlying issues that necessitated
creating this function in the first place.  Though, that discussion
would likely merit its own thread.

It would be awesome if this thread is the seed for waters to start moving to close the 2013 issue and perhaps to have a proper markup syntax for allowing user input for text spanners (\markupSpan, \textSpan or whatever is adopted, leaving overrides for actual properties). Both issues already have their own threads in the archive.

Best regards,
Martín.

Am Fr., 18. Sept. 2020 um 16:26 Uhr schrieb Aaron Hill <lilypond@hillvisions.com>:
On 2020-09-18 4:40 am, Martín Rincón Botero wrote:
> 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 ")" }
> ?).

Looking at the internal format-metronome-markup function, it uses half
spaces (U+2009) and an en dash (U+2013).

Regardless, I will leave you with my final contribution of a "cleaned
up" version with some logic and usage updates.  In particular, I
reordered the arguments to enable default values for the alignments. 
And the main refactoring uses a different approach to assembling the
markup, which makes handling the parentheses simpler.

%%%%
\version "2.20.0"

tempoTextSpan =
#(define-music-function
   (left-halign left-text right-halign tempo)
   ((number? LEFT) markup? (number? LEFT) ly:music?)

   (define (tempo-property prop)
     (if (ly:prob? tempo)
         (ly:prob-property tempo prop #f)))

   ;; Verify tempo argument contains one tempo-change-event.
   (let ((events (extract-typed-music tempo 'tempo-change-event)))
     (if (eq? 1 (length events))
         (set! tempo (first events))
         (begin
           (ly:music-error tempo
             "Argument must specify a single \\tempo indication.")
           (set! tempo #f))))

   (let ((tempo-text (tempo-property 'text))
         (tempo-unit (tempo-property 'tempo-unit))
         (metronome-count (tempo-property 'metronome-count))
         (tempo-markup #f))

     (if (ly:duration? tempo-unit)
        (set! tempo-markup
          #{
            \markup {
              \general-align #Y #DOWN
              \smaller
              \note #(ly:duration->string tempo-unit) #UP
              =
              #(cond
                ((number-pair? metronome-count)
                 #{
                   \markup \concat {
                     #(format #f "~d" (car metronome-count))
                     \char ##x2009 \char ##x2013 \char ##x2009
                     #(format #f "~d" (cdr metronome-count))
                   }
                 #})
                ((number? metronome-count)
                 #{ \markup #(format #f "~d" metronome-count) #})
                (else (make-null-markup)))
            }
          #}))
     (if (markup? tempo-text)
       (set! tempo-markup
         #{
           \markup {
             \bold #tempo-text
             #(if (markup? tempo-markup)
                  #{ \markup \concat { ( #tempo-markup ) } #}
                  (make-null-markup))
           }
         #}))

     #{
       \once {
         \override TextSpanner.bound-details.left-broken.text = ##f
         \override TextSpanner.bound-details.right-broken.text = ##f
         \override TextSpanner.bound-details.left.text =
           \markup \abs-fontsize #11
                   \halign #left-halign #left-text
         \override TextSpanner.bound-details.right.text =
           \markup \abs-fontsize #11 \normal-text
                   \halign #right-halign #tempo-markup
       }
     #}))

{
   \tempoTextSpan "accel." #RIGHT \tempo 2 = 50-55
   g'4\startTextSpan 4 4 4 | 2 2 | 1\stopTextSpan | R1
   \tempoTextSpan #RIGHT "rall." #CENTER \tempo "Adagio" 4 = 60
   g'4\startTextSpan 4 4 4 | 2 2 | 1\stopTextSpan | R1
   \tempoTextSpan "rit." #-0.5 \tempo \markup \circle \bold "!"
   g'4\startTextSpan 4 4 4 | 2 2 | 1\stopTextSpan \bar "|."
}

%% Uncomment to test argument validation.
% \tempoTextSpan "missing \\tempo" { }
% \tempoTextSpan "too many \\tempos" { \tempo "" \tempo "" }
%%%%


> 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.

You could use context properties to persist the relevant information;
or, if you were feeling more adventurous, you could build a custom
engraver/performer to do the work.

But if I can be honest, this approach is starting to feel awkward and
potentially circuitous.  Initially, I had no idea what you intended to
do with the information from the \tempo command.  Now, it is as if all
you need is a normal MetronomeMark aligned to the end of a TextSpanner. 
After all, reusing is preferred to reinventing.

So while you could continue to develop the function above, perhaps time
would be better spent solving the underlying issues that necessitated
creating this function in the first place.  Though, that discussion
would likely merit its own thread.


-- Aaron Hill


--


--
www.martinrinconbotero.com

reply via email to

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