David Kastrup <d...@gnu.org> writes: > Jean Abou Samra <j...@abou-samra.fr> writes: > >> Le 27/06/2022 à 20:10, Simon Albrecht a écrit : >>> Hello everyone, >>> >>> I’m trying to encode a piece such that I can switch whether or not >>> durations will be shifted (note values >>> halved/doubled). Unfortunately \tempo isn’t affected by >>> \shiftDurations (that would be a sensible feature request, right?), >> >> Go open an issue. >> >> >>> so I tried this: >>> %%%%%%%%%%%%%%%%%%%%%%%%%%% >>> \version "2.23.9" >>> >>> durationShiftOne = #-1 >>> { >>> \tempo #(ly:make-duration (+ 3 durationShiftOne)) = 152 >>> \shiftDurations \durationShiftOne #0 { 8 } >>> } >>> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% >>> >>> but unfortunately Lily won’t accept that Scheme expression instead >>> of the normal duration. >>> >>> Can I make that work some other way? >>> >>> Should the parser be able to take that Scheme expression there? >> >> >> \version "2.23.9" >> >> durationShiftOne = #-1 >> { >> \tempo $(ly:make-duration (+ 3 durationShiftOne)) = 152 >> \shiftDurations \durationShiftOne #0 { 8 } >> } >> >> >> You just need to use $ instead of #. See these pages about the difference: >> >> https://lilypond.org/doc/v2.23/Documentation/extending/lilypond-scheme-syntax.html >> https://extending-lilypond.readthedocs.io/en/latest/lily-and-scheme.html#hash-vs-dollar >> >> The problem is that \tempo has multiple syntaxes (\tempo <markup>, >> \tempo <duration> = <bpm> and \tempo <markup> <duration> = <bpm>), >> which makes it impossible to accept # here because early evaluation >> is needed to disambiguate, I think. I'm no expert of the parser >> though. > > It's sort of like that. Before looking for a possible following `=` > LilyPond has to have made a decision what type the token/expression > coming before that has. It cannot look at the type of a #... expression > before deciding to look for `=` but it can (and will) look at the type > of a $... expression. > > Now syntax errors are comparatively unhelpful, so one could try to > tentatively accept an #... = ... expression anyway and then barf if the > expression type does not support it. The result would likely not be > worse for the user.
To wit:
>From 56869db10837eac331e89d074efa5952116ce3d6 Mon Sep 17 00:00:00 2001 From: David Kastrup <d...@gnu.org> Date: Tue, 28 Jun 2022 00:06:17 +0200 Subject: [PATCH] Allow \tempo #<Duration> = ... for tempo specifications What doesn't work is specifying \tempo "text" #<Duration> = ... because its implementation would lead to parser conflicts. --- lily/parser.yy | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lily/parser.yy b/lily/parser.yy index 9207e479c8..7fff2fd019 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -1403,6 +1403,16 @@ tempo_event: TEMPO steno_duration '=' tempo_range { $$ = MAKE_SYNTAX (tempo, @$, SCM_EOL, $2, $4); } + | TEMPO embedded_scm_bare '=' tempo_range { + if (unsmob<Duration> ($2)) + { + $$ = MAKE_SYNTAX (tempo, @$, SCM_EOL, $2, $4); + } else { + parser->parser_error (@2, _("duration expected")); + $$ = MAKE_SYNTAX (tempo, @$, + SCM_EOL, Duration (2, 0).smobbed_copy (), $4); + } + } | TEMPO text steno_duration '=' tempo_range { $$ = MAKE_SYNTAX (tempo, @$, $2, $3, $5); } -- 2.34.1
It's debatable whether this partial ability to specify the duration as #... but not in the long form including text is worth the confusion. Anyone who wants to tackle the resulting parser conflicts is welcome to try: Bison appears to do a pretty good job these days proposing productions that may trigger the problem when giving the right options. -- David Kastrup