From ece789bf5f661cb8f16b50f87a248dedd6e1d8d5 Mon Sep 17 00:00:00 2001 From: Thomas Morley Date: Thu, 1 Dec 2016 22:38:54 +0100 Subject: [PATCH] Issue 5003 unfoldRepeats can be restricted to certain repeat-types It now takes an additional, optional argument. It's a list of symbols representing the repeat-types which should be unfolded. Possible settings are percent, tremolo and volta. The default is an empty list, for which repeated-music is taken, unfolding all. A new regtest is added to cover the new feature. Changes is extended accordingly. Also correcting two small typos in Documentation/notation/staff.itely --- Documentation/changes.tely | 8 ++++ Documentation/notation/staff.itely | 4 +- input/regression/repeat-unfold-partial.ly | 37 +++++++++++++++++++ ly/articulate.ly | 6 ++- ly/music-functions-init.ly | 13 +++++-- scm/music-functions.scm | 45 ++++++++++++++++------- 6 files changed, 91 insertions(+), 22 deletions(-) create mode 100644 input/regression/repeat-unfold-partial.ly diff --git a/Documentation/changes.tely b/Documentation/changes.tely index 2407b3d018..958ecb109e 100644 --- a/Documentation/changes.tely +++ b/Documentation/changes.tely @@ -61,6 +61,14 @@ which scares away people. @end ignore +@item +The music function @code{\\unfoldRepeats} can now take an +optional argument-list specifying which type(s) of repeated music +should be unfolded. Possible entries are @code{percent}, @code{tremolo}, +@code{volta}. +If the optional argument-list is unspecified, @code{repeated-music} will be +used, unfolding all. + @item A new @code{output-attributes} grob property is now used for svg output instead of the @code{id} grob property. It allows multiple attributes diff --git a/Documentation/notation/staff.itely b/Documentation/notation/staff.itely index a114434664..d097535643 100644 --- a/Documentation/notation/staff.itely +++ b/Documentation/notation/staff.itely @@ -1078,9 +1078,9 @@ oboeNotes = \relative { } @end lilypond -If an @code{\unfoldRepeat} command in a music expression is required to +If an @code{\unfoldRepeats} command in a music expression is required to be printed when using @code{\quoteDuring}, then it too must also contain -its own @code{\unfoldRepeat} command; +its own @code{\unfoldRepeats} command; @lilypond[verbatim,quote] fluteNotes = \relative { diff --git a/input/regression/repeat-unfold-partial.ly b/input/regression/repeat-unfold-partial.ly new file mode 100644 index 0000000000..8023932de7 --- /dev/null +++ b/input/regression/repeat-unfold-partial.ly @@ -0,0 +1,37 @@ +\header { + texidoc = "The music function @code{\\unfoldRepeats} can take an +optional argument-list specifying which type(s) of repeated music has +to be unfolded." +} + +m = + \repeat volta 2 { + \repeat percent 2 { c'1 } + \repeat tremolo 4 { c'16 d' } + f'2 + } + \alternative { + { d'1 } + { e'1 } + } + +\markup "not expanding" +\m + +\markup "expanding all" +\unfoldRepeats \m + +\markup "expanding percent-repeated-music" +\unfoldRepeats percent \m + +\markup "expanding tremolo-repeated-music" +\unfoldRepeats tremolo \m + +\markup "expanding volta-repeated-music" +\unfoldRepeats volta \m + +\markup \column { + "combinations are possible:" + "expanding percent-repeated-music and tremolo-repeated-music" +} +\unfoldRepeats percent,tremolo \m diff --git a/ly/articulate.ly b/ly/articulate.ly index 0f198ffbed..1dc0e5566b 100644 --- a/ly/articulate.ly +++ b/ly/articulate.ly @@ -131,7 +131,9 @@ % how to do lookahead in scheme. % * Also ignore explicit line breaks. % * Add Mordents (reported by Patrick Karl) -% +% * Thomas Morley: extend unfold-repeats to reflect the possibility to +% customize its effect to user-settable repeat-types. Here the most general +% setting is hard-coded, resulting in unchanged behaviour. \version "2.19.22" @@ -538,7 +540,7 @@ (make-music 'BarCheck)))) (else m))) - (unfold-repeats music))) + (unfold-repeats '() music))) % If there's an articulation, use it. % If in a slur, use (1 . 1) instead (unless the note is marked staccato, diff --git a/ly/music-functions-init.ly b/ly/music-functions-init.ly index d96e655370..1f94319bce 100644 --- a/ly/music-functions-init.ly +++ b/ly/music-functions-init.ly @@ -1976,11 +1976,16 @@ unsets already in @var{music} cause a warning. Non-property-related music is ig (else (make-sequential-music lst)))))) unfoldRepeats = -#(define-music-function (music) (ly:music?) - (_i "Force any @code{\\repeat volta}, @code{\\repeat tremolo} or +#(define-music-function (types music) + ((symbol-list-or-symbol? '()) ly:music?) + (_i "Force @code{\\repeat volta}, @code{\\repeat tremolo} or @code{\\repeat percent} commands in @var{music} to be interpreted -as @code{\\repeat unfold}.") - (unfold-repeats music)) +as @code{\\repeat unfold}, if specified in the optional symbol-list @var{types}. +The default for @var{types} is an empty list, which will force any of those +commands in @var{music} to be interpreted as @code{\\repeat unfold}. Possible +entries are @code{volta}, @code{tremolo} or @code{percent}. Multiple entries +are possible.") + (unfold-repeats types music)) void = #(define-void-function (arg) (scheme?) diff --git a/scm/music-functions.scm b/scm/music-functions.scm index 3e9818d009..b1dc2f9c61 100644 --- a/scm/music-functions.scm +++ b/scm/music-functions.scm @@ -390,19 +390,36 @@ beats to be distinguished." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; repeats. -(define-public (unfold-repeats music) - "Replace all repeats with unfolded repeats." - (let ((es (ly:music-property music 'elements)) - (e (ly:music-property music 'element))) - (if (music-is-of-type? music 'repeated-music) - (set! music (make-music 'UnfoldedRepeatedMusic music))) - (if (pair? es) - (set! (ly:music-property music 'elements) - (map unfold-repeats es))) - (if (ly:music? e) - (set! (ly:music-property music 'element) - (unfold-repeats e))) - music)) +(define-public (unfold-repeats types music) + "Replace repeats of the types given by @var{types} with unfolded repeats. +If @var{types} is an empty list, @code{repeated-music} is taken, unfolding all." + (let* ((types-list + (if (or (null? types) (not (list? types))) + (list types) + types)) + (repeat-types-alist + '((volta . volta-repeated-music) + (percent . percent-repeated-music) + (tremolo . tremolo-repeated-music) + (() . repeated-music))) + (repeat-types-hash (alist->hash-table repeat-types-alist))) + (for-each + (lambda (type) + (let ((repeat-type (hashq-ref repeat-types-hash type))) + (if repeat-type + (let ((es (ly:music-property music 'elements)) + (e (ly:music-property music 'element))) + (if (music-is-of-type? music repeat-type) + (set! music (make-music 'UnfoldedRepeatedMusic music))) + (if (pair? es) + (set! (ly:music-property music 'elements) + (map (lambda (x) (unfold-repeats types x)) es))) + (if (ly:music? e) + (set! (ly:music-property music 'element) + (unfold-repeats types e)))) + (ly:warning "unknown repeat-type ~a, ignoring." type)))) + types-list) + music)) (define-public (unfold-repeats-fully music) "Unfolds repeats and expands the resulting @code{unfolded-repeated-music}." @@ -411,7 +428,7 @@ beats to be distinguished." (and (music-is-of-type? m 'unfolded-repeated-music) (make-sequential-music (ly:music-deep-copy (make-unfolded-set m))))) - (unfold-repeats music))) + (unfold-repeats '() music))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; property setting music objs. -- 2.39.2