lilypond-devel
[Top][All Lists]

## Re: TimeSignature with note in denominator

 From: Lukas-Fabian Moser Subject: Re: TimeSignature with note in denominator Date: Sat, 13 Nov 2021 15:44:02 +0100 User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0

Hi Kieren,

You’re not extrapolating the concept, as I have been asking people to, so I’ll
once again make it more explicit for you:

I want the user to be able to say

\tweak style #'note-denom \time 3/4.
or
\tweak style #'note-denom \time #'(3 . "4.")
or
\tweak style #'note-denom \time #'(3 . {4.})

or basically any other intuitive input that would allow a dotted duration for
the denominator, which would pass through the parser to the TimeSignature
formatting function(s) without “loss” (as per Aaron described it).

It's probable that I'm missing a point (since I only skimmed the discussion so far), but:

Currently, \time is defined (in ly/music-functions-init.ly) with the signature

#(define-music-function (beat-structure fraction)
((number-list? '()) fraction?)

Now the predicate fraction? is defined (in scm/c++.scm) as

(define-public (fraction? x)
(and (pair? x)
(index? (car x)) (index? (cdr x))))

to wit, a pair of non-negative exact integers.

Now the lexer turns 3/4 into such a pair: See lily/lexer.ll, by virtue of the lines

N        [0-9]
FRACTION    {N}+\/{N}+

which translate as "a fraction consists of one or more digits, followed by /, followed by one or more digits"; and the call to the procedure scan_fraction; just search for it in lexer.ll. (I'm deliberately giving you more information than you probably need, to help you navigate the source and see how everything fits together.)

So, \time 3/4 is converted to \time #'(3 . 4) already while lexing, which is very early and very "basic". It's no problem at all to make \time accept more general pairs: Just replace fraction? by (e.g.) pair? in the definition of \time, or define a suitable predicate of your own accepting only the "right" kind of pairs.

So, of your three examples, only the first one (\time 3/4.) definitely would require changes to the lexer/parser. The others are not hard to implement (provided I don't miss something). But: I think it would be desirable to be able to enter durations in LilyPond syntax, in order to, for example, be able to enter complicated constructs like "8.~8" from Werner's example. But if you want to include LilyPond syntax in an explicit pair argument, you need #{ #} which certainly works but makes for horrible syntax:

test =
#(define-void-function (test) (pair?)
(display-scheme-music test))

\test #`(3 . ,#{ 8~8. #})
% or not much better:
\test #(cons 3 #{ 8~8. #})

Wouldn't it be easier to define an independent \kierenTime function that expects an integer (index?) numerator and a music (ly:music?) denominator? Then we could just write

\version "2.22"

kierenTime =
#(define-void-function (num den) (index? ly:music?)
(format #t "~a\n" num)
(display-lily-music den))

\kierenTime 3 { 8~8. }
\kierenTime 3 4.  % the dot is important :-)

I provided a very silly simple example along these lines in my mail replying to Werner's example. I'm not sure if you saw this, as you reported that only part of the discussion came through to your end.

Lukas