Hello Asher,
A somewhat long response ahead; sorry!
After some days of traveling and working on it intermittently, here is what I
have, though it doesn’t unfortunately address all your issues:
%%%BEGIN%%%
metricModedit =
#(define-music-function (ratio bpm) (list? number?)
#{
\textMark \markup {
\hspace #-4.5
\rhythm {
\override TupletBracket.bracket-visibility = ##t
\override TupletNumber.text = #tuplet-number::calc-fraction-text
\override TupletBracket.shorten-pair = #(cons -2.5 -2.5)
\override TupletBracket.edge-height = #'(0 . 0.7)
\override TupletBracket.X-offset = #0
#(if (= (length ratio) 2) #{
\tuplet #(cadr ratio) { \tuplet #(car ratio) { 4 } }
#} )
#(if (= (length ratio) 1) #{
\tuplet #(car ratio) { 4 }
#} )
}
}
\tweak self-alignment-X #CENTER
\tweak Y-offset #2.9
\textMark \markup { "="}
\tweak self-alignment-X #LEFT
\textMark \markup {
\hspace #1.5 \rhythm { { 4 } }
% \hspace #(+ 2)
"="
#(number->string bpm)
}
\once \set Score.tempoHideNote = ##t
\tempo 4 = #bpm
#}
)
{
c'2
c'2 |
c'2
c'2 |
c'2
c'2 |
\metricModedit #'((2 . 3) (5 . 2)) 50
c'2
c'2
}
%%%END%%%
Your queries and my observations:
> * I have a separate command for a nested tuplet, mainly because I don't know
> the Scheme interface well enough to generate a tree of tuplets from a list of
> ratios. (This is a skill issue and I can figure it out eventually.)
>
My version addresses this by embedding (if) constructions. I also decided to
opt to indicate ratio differently, in that it’s now a list of pair of numbers.
You can have either one ratio or two ratios.
> * The spacing is not great. I would prefer the first “=” to be centered
> between the tuplet note and the normal note, and I want the normal note to be
> in the same position as the usual “\tempo 4 = n” command would produce
> (aligned with the left edge of the measure—here I just approximated it).
> Because the spacing is hard-coded it doesn't scale with the markup (if I
> decide to make these markings smaller, for example).
My idea here was to create three \textMark instances, each of which is set
differently in terms of the self-alignment-X; here, the most important thing
was the first “=“ sign was centered and aligned exactly above the barline, and
to add things before and after the sign. So what you see in the function is
three separate components put into one function. The idea is to try to simplify
the adjustments that may be needed to refine the metric modulation sign.
> * The logic to unsquish the bracket is imperfect, sometimes looking OK and
> sometimes ugly. Ideally the span of the bracket beyond the numbers remains
> constant, and the whole bracket+numbers assembly would be moved to the left
> if it takes up too much room, even if the number is no longer centered above
> the note, but I couldn't figure out how to do that.
I think that, if you can use the (if ) function to determine how many digits
there are (something like: (if (> (car (car ratio)) 9) (+ 0.5)) ), you could
probably make a modular version of the bracket according to the number of total
digits.
When I do metric modulation, for the initial note, I put the hook of the
bracket on the right aligned to the stem. I don’t particularly like the bracket
to be reaching out to the equal sign, and if you want to try to avoid that,
you’d have to move the initial note to the left or something, which could cause
the sign to look unbalanced.
> * If the marking appears at the beginning of a line, it protrudes into the
> left margin. It seems the common practice is to keep the equation of notes on
> the previous line, and leave the numeric metronome marking at the start of
> the new line, but I don't know how to accomplish this in Lilypond.
Perhaps the solution for that is to make a function of the equation separate
from the tempo marking. As there are different ways of indicating metric
modulations in terms of format, I tried to be respectful of the code you
provided, but in my own practice, I would delete the lines:
\once \set Score.tempoHideNote = ##t
\tempo 4 = #bpm
And just use the \tempo function for the new measure. The equation, then, would
be applied to the end of the previous barline, which the current code doesn’t
accomplish. It’s an issue of how to align text in relation to a bar. I should
perhaps look into it, as I am sure I will have to do something similar myself
in my pieces soon.
(Also, the reason I tend to separate the equation from the new tempo is that
sometimes it is possible that the right side of the equation may carry a note
value different from the tempo. For example, 16th = 8th triplet, but the tempo
marking would be qn = [number]. This implies that this code could be even more
modular, and depending on the note value being used, you could adjust X-offset
value so that characters do not collide to each other.)
Sorry that my response doesn’t address all the issues, but I hope it might give
you some hints, particularly regarding how you could put two functions into
one.
All the best,
Yoshi