I achieved a working solution after I found out about lambda*.
I would like to improve on this, but at least I achieved the expected result.
The example:
\version "2.19.52"
%Useful definitions
#(define characters.thinSpace (ly:wide-char->utf-8 #x2009))
#(define characters.longDash (ly:wide-char->utf-8 #x2013))
#(define characters.curvyEqual "≈")
%Properties of the customMark
#(define customMark.parenthesized #t)
#(define customMark.tempoEqText "= ca.")
#(define customMark.separator (string-append characters.thinSpace characters.longDash characters.thinSpace))
#(define (ly:duration-or-false? obj)
(if (or (ly:duration? obj) (and (boolean? obj) (not obj)))
#t
#f))
#(define (number-or-false? obj)
(if (or (number? obj) (and (boolean? obj) (not obj)))
#t
#f))
createCustomMark =
#(define-music-function
(text dur val1 val2)
(markup? ly:duration-or-false? number-or-false? (number-or-false? #f))
#{
\mark \markup { \line { \upright { \fontsize #-2 {
\larger { \bold { #text } }
#(if (or dur val1 val2)
#{
\markup \concat { %\markup needed to avoid "unknown escaped string: `\concat'"
#(if customMark.parenthesized "(")
#(if dur
#{
\markup \fontsize #-3 { \general-align #Y #DOWN { \note #(ly:duration->string dur) #1 } }
#}
"") %needed to avoid "not a markup" error when dur is #f
" "
#customMark.tempoEqText
#characters.thinSpace
#(if val1
(number->string val1)
"") %needed to avoid "not a markup" error when val1 is #f
#(if val2
(string-append customMark.separator (number->string val2))
"") %needed to avoid "not a markup" error when val2 is #f
#(if customMark.parenthesized ")")
}
#}
"") %needed to avoid "not a markup" error when tempo is #f
} } } }
#})
customMark =
#(lambda* (text #:optional (dur #f) (val1 #f) (val2 #f))
(createCustomMark text dur val1 val2))
allegro = #(customMark "Allegro." #{ 4 #} 120 125)
ceder = #(customMark "ceder...")
metromark = #(customMark "" #{ 4 #} 120)
\relative c' {
\allegro c4 d e \ceder f \metromark
}