X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scm%2Fdefine-music-display-methods.scm;h=4133fa6443b7ba95277d591be7ffa88ff65efd47;hb=fea33b81da974ff0627843dfc88a00b49cd2323c;hp=2dbb0acb02200a3a516e0e023973751d012e1e5b;hpb=55c7ef27b5382940b8afe785c94b744c24b98473;p=lilypond.git diff --git a/scm/define-music-display-methods.scm b/scm/define-music-display-methods.scm index 2dbb0acb02..6089e25392 100644 --- a/scm/define-music-display-methods.scm +++ b/scm/define-music-display-methods.scm @@ -1,7 +1,7 @@ ;;; define-music-display-methods.scm -- data for displaying music ;;; expressions using LilyPond notation. ;;; -;;; (c) 2005--2006 Nicolas Sceaux +;;; Copyright (C) 2005--2012 Nicolas Sceaux ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -11,18 +11,13 @@ (define-module (scm display-lily)) -;;; `display-lily-init' must be called before using `display-lily-music'. It -;;; takes a parser object as an argument. -(define-public (display-lily-init parser) - (*parser* parser) - #t) - ;;; ;;; Scheme forms ;;; (define (scheme-expr->lily-string scm-arg) (cond ((or (number? scm-arg) - (string? scm-arg)) + (string? scm-arg) + (boolean? scm-arg)) (format #f "~s" scm-arg)) ((or (symbol? scm-arg) (list? scm-arg)) @@ -43,7 +38,8 @@ ;;; (define-public (markup->lily-string markup-expr) - "Return a string describing, in LilyPond syntax, the given markup expression." + "Return a string describing, in LilyPond syntax, the given markup +expression." (define (proc->command proc) (let ((cmd-markup (symbol->string (procedure-name proc)))) (substring cmd-markup 0 (- (string-length cmd-markup) @@ -64,7 +60,7 @@ (args (cdr expr))) (if (eqv? cmd simple-markup) ;; a simple markup (format #f "~s" (car args)) - (format #f "\\~a~{ ~a~}" + (format #f "\\~a~{ ~a~}" (proc->command cmd) (map-in-order arg->string args)))))) (cond ((string? markup-expr) @@ -87,18 +83,18 @@ (if (and (car alist) (test item (cdar alist))) (set! result (car alist))))) -(define (note-name->lily-string ly-pitch) +(define-public (note-name->lily-string ly-pitch parser) ;; here we define a custom pitch= function, since we do not want to ;; test whether octaves are also equal. (otherwise, we would be using equal?) (define (pitch= pitch1 pitch2) (and (= (ly:pitch-notename pitch1) (ly:pitch-notename pitch2)) (= (ly:pitch-alteration pitch1) (ly:pitch-alteration pitch2)))) - (let ((result (rassoc ly-pitch (ly:parser-lookup (*parser*) 'pitchnames) pitch=))) + (let ((result (rassoc ly-pitch (ly:parser-lookup parser 'pitchnames) pitch=))) (if result (car result) #f))) -(define (octave->lily-string pitch) +(define-public (octave->lily-string pitch) (let ((octave (ly:pitch-octave pitch))) (cond ((>= octave 0) (make-string (1+ octave) #\')) @@ -109,10 +105,12 @@ ;;; ;;; durations ;;; -(define* (duration->lily-string ly-duration #:key (prev-duration (*previous-duration*)) +(define*-public (duration->lily-string ly-duration #:key (prev-duration (*previous-duration*)) (force-duration (*force-duration*)) (time-factor-numerator (*time-factor-numerator*)) - (time-factor-denominator (*time-factor-denominator*))) + (time-factor-denominator (*time-factor-denominator*)) + remember) + (if remember (*previous-duration* ly-duration)) (let ((log2 (ly:duration-log ly-duration)) (dots (ly:duration-dot-count ly-duration)) (num+den (ly:duration-factor ly-duration))) @@ -140,33 +138,8 @@ ;;; post events ;;; -(define post-event? (make-music-type-predicate - 'StringNumberEvent - 'ArticulationEvent - 'FingerEvent - 'TextScriptEvent - 'MultiMeasureTextEvent - 'HyphenEvent - 'ExtenderEvent - 'BeamEvent - 'SlurEvent - 'TieEvent - 'CrescendoEvent - 'DecrescendoEvent - 'PhrasingSlurEvent - 'TremoloEvent - 'SustainEvent - 'SostenutoEvent - 'ManualMelismaEvent - 'TextSpanEvent - 'HarmonicEvent - 'BeamForbidEvent - 'AbsoluteDynamicEvent - 'TrillSpanEvent - 'GlissandoEvent - 'ArpeggioEvent - 'NoteGroupingEvent - 'UnaCordaEvent)) +(define (post-event? m) + (music-is-of-type? m 'post-event)) (define* (event-direction->lily-string event #:optional (required #t)) (let ((direction (ly:music-property event 'direction))) @@ -190,25 +163,25 @@ ,str-start ,str-stop)))) -(define-display-method HyphenEvent (event) +(define-display-method HyphenEvent (event parser) " --") -(define-display-method ExtenderEvent (event) +(define-display-method ExtenderEvent (event parser) " __") -(define-display-method TieEvent (event) +(define-display-method TieEvent (event parser) " ~") -(define-display-method BeamForbidEvent (event) +(define-display-method BeamForbidEvent (event parser) "\\noBeam") -(define-display-method StringNumberEvent (event) +(define-display-method StringNumberEvent (event parser) (format #f "\\~a" (ly:music-property event 'string-number))) -(define-display-method TremoloEvent (event) +(define-display-method TremoloEvent (event parser) (let ((tremolo-type (ly:music-property event 'tremolo-type))) (format #f ":~a" (if (= 0 tremolo-type) "" tremolo-type)))) -(define-post-event-display-method ArticulationEvent (event) #t +(define-post-event-display-method ArticulationEvent (event parser) #t (let ((articulation (ly:music-property event 'articulation-type))) (case (string->symbol articulation) ((marcato) "^") @@ -220,48 +193,54 @@ ((portato) "_") (else (format #f "\\~a" articulation))))) -(define-post-event-display-method FingerEvent (event) #t +(define-post-event-display-method FingeringEvent (event parser) #t (ly:music-property event 'digit)) -(define-post-event-display-method TextScriptEvent (event) #t +(define-post-event-display-method TextScriptEvent (event parser) #t (markup->lily-string (ly:music-property event 'text))) -(define-post-event-display-method MultiMeasureTextEvent (event) #t +(define-post-event-display-method MultiMeasureTextEvent (event parser) #t (markup->lily-string (ly:music-property event 'text))) -(define-post-event-display-method HarmonicEvent (event) #t "\\harmonic") -(define-post-event-display-method GlissandoEvent (event) #t "\\glissando") -(define-post-event-display-method ArpeggioEvent (event) #t "\\arpeggio") -(define-post-event-display-method AbsoluteDynamicEvent (event) #f +(define-post-event-display-method BendAfterEvent (event parser) #t + (format #f "\\bendAfter #~a" (ly:music-property event 'delta-step))) + +(define-post-event-display-method HarmonicEvent (event parser) #f "\\harmonic") +(define-post-event-display-method GlissandoEvent (event parser) #t "\\glissando") +(define-post-event-display-method ArpeggioEvent (event parser) #t "\\arpeggio") +(define-post-event-display-method AbsoluteDynamicEvent (event parser) #f (format #f "\\~a" (ly:music-property event 'text))) -(define-span-event-display-method BeamEvent (event) #f "[" "]") -(define-span-event-display-method SlurEvent (event) #f "(" ")") -(define-span-event-display-method CrescendoEvent (event) #f "\\<" "\\!") -(define-span-event-display-method DecrescendoEvent (event) #f "\\>" "\\!") -(define-span-event-display-method PhrasingSlurEvent (event) #f "\\(" "\\)") -(define-span-event-display-method SustainEvent (event) #f "\\sustainDown" "\\sustainUp") -(define-span-event-display-method SostenutoEvent (event) #f "\\sostenutoDown" "\\sostenutoUp") -(define-span-event-display-method ManualMelismaEvent (event) #f "\\melisma" "\\melismaEnd") -(define-span-event-display-method TextSpanEvent (event) #f "\\startTextSpan" "\\stopTextSpan") -(define-span-event-display-method TrillSpanEvent (event) #f "\\startTrillSpan" "\\stopTrillSpan") -(define-span-event-display-method StaffSpanEvent (event) #f "\\startStaff" "\\stopStaff") -(define-span-event-display-method NoteGroupingEvent (event) #f "\\startGroup" "\\stopGroup") -(define-span-event-display-method UnaCordaEvent (event) #f "\\unaCorda" "\\treCorde") +(define-post-event-display-method StrokeFingerEvent (event parser) #t + (format #f "\\rightHandFinger #~a" (ly:music-property event 'digit))) + +(define-span-event-display-method BeamEvent (event parser) #f "[" "]") +(define-span-event-display-method SlurEvent (event parser) #f "(" ")") +(define-span-event-display-method CrescendoEvent (event parser) #f "\\<" "\\!") +(define-span-event-display-method DecrescendoEvent (event parser) #f "\\>" "\\!") +(define-span-event-display-method EpisemaEvent (event parser) #f "\\episemInitium" "\\episemFinis") +(define-span-event-display-method PhrasingSlurEvent (event parser) #f "\\(" "\\)") +(define-span-event-display-method SustainEvent (event parser) #f "\\sustainOn" "\\sustainOff") +(define-span-event-display-method SostenutoEvent (event parser) #f "\\sostenutoOn" "\\sostenutoOff") +(define-span-event-display-method TextSpanEvent (event parser) #f "\\startTextSpan" "\\stopTextSpan") +(define-span-event-display-method TrillSpanEvent (event parser) #f "\\startTrillSpan" "\\stopTrillSpan") +(define-span-event-display-method StaffSpanEvent (event parser) #f "\\startStaff" "\\stopStaff") +(define-span-event-display-method NoteGroupingEvent (event parser) #f "\\startGroup" "\\stopGroup") +(define-span-event-display-method UnaCordaEvent (event parser) #f "\\unaCorda" "\\treCorde") ;;; ;;; Graces ;;; -(define-display-method GraceMusic (expr) - (format #f "\\grace ~a" - (music->lily-string (ly:music-property expr 'element)))) +(define-display-method GraceMusic (expr parser) + (format #f "\\grace ~a" + (music->lily-string (ly:music-property expr 'element) parser))) ;; \acciaccatura \appoggiatura \grace ;; TODO: it would be better to compare ?start and ?stop ;; with startAppoggiaturaMusic and stopAppoggiaturaMusic, ;; using a custom music equality predicate. -(define-extra-display-method GraceMusic (expr) +(define-extra-display-method GraceMusic (expr parser) "Display method for appoggiatura." (with-music-match (expr (music 'GraceMusic @@ -272,31 +251,29 @@ ?stop)))) ;; we check whether ?start and ?stop look like ;; startAppoggiaturaMusic stopAppoggiaturaMusic - (and (with-music-match (?start (music - 'SequentialMusic - elements ((music - 'EventChord - elements ((music - 'SkipEvent - duration (ly:make-duration 0 0 0 1)) - (music - 'SlurEvent - span-direction START)))))) - #t) - (with-music-match (?stop (music + (and (with-music-match (?start (music 'SequentialMusic elements ((music - 'EventChord - elements ((music - 'SkipEvent - duration (ly:make-duration 0 0 0 1)) - (music - 'SlurEvent - span-direction STOP)))))) - (format #f "\\appoggiatura ~a" (music->lily-string ?music)))))) + 'SkipEvent + duration (ly:make-duration 0 0 0 1) + articulations + ((music + 'SlurEvent + span-direction START)))))) + #t) + (with-music-match (?stop (music + 'SequentialMusic + elements ((music + 'SkipEvent + duration (ly:make-duration 0 0 0 1) + articulations + ((music + 'SlurEvent + span-direction STOP)))))) + (format #f "\\appoggiatura ~a" (music->lily-string ?music parser)))))) -(define-extra-display-method GraceMusic (expr) +(define-extra-display-method GraceMusic (expr parser) "Display method for acciaccatura." (with-music-match (expr (music 'GraceMusic @@ -307,43 +284,42 @@ ?stop)))) ;; we check whether ?start and ?stop look like ;; startAcciaccaturaMusic stopAcciaccaturaMusic - (and (with-music-match (?start (music + (and (with-music-match (?start (music 'SequentialMusic elements ((music - 'EventChord - elements ((music - 'SkipEvent - duration (ly:make-duration 0 0 0 1)) - (music - 'SlurEvent - span-direction START))) + 'SkipEvent + duration (ly:make-duration 0 0 0 1) + articulations + ((music + 'SlurEvent + span-direction START))) (music 'ContextSpeccedMusic element (music 'OverrideProperty grob-property-path '(stroke-style) grob-value "grace" - symbol 'Stem))))) - #t) - (with-music-match (?stop (music + symbol 'Flag))))) + #t) + (with-music-match (?stop (music 'SequentialMusic elements ((music 'ContextSpeccedMusic element (music 'RevertProperty grob-property-path '(stroke-style) - symbol 'Stem)) + symbol 'Flag)) + (music - 'EventChord - elements ((music - 'SkipEvent - duration (ly:make-duration 0 0 0 1)) - (music - 'SlurEvent - span-direction STOP)))))) - (format #f "\\acciaccatura ~a" (music->lily-string ?music)))))) - -(define-extra-display-method GraceMusic (expr) + 'SkipEvent + duration (ly:make-duration 0 0 0 1) + articulations + ((music + 'SlurEvent + span-direction STOP)))))) + (format #f "\\acciaccatura ~a" (music->lily-string ?music parser)))))) + +(define-extra-display-method GraceMusic (expr parser) "Display method for grace." (with-music-match (expr (music 'GraceMusic @@ -356,25 +332,29 @@ ;; startGraceMusic stopGraceMusic (and (null? (ly:music-property ?start 'elements)) (null? (ly:music-property ?stop 'elements)) - (format #f "\\grace ~a" (music->lily-string ?music))))) + (format #f "\\grace ~a" (music->lily-string ?music parser))))) ;;; ;;; Music sequences ;;; -(define-display-method SequentialMusic (seq) +(define-display-method SequentialMusic (seq parser) (let ((force-line-break (and (*force-line-break*) - ;; hm + ;; hm (> (length (ly:music-property seq 'elements)) (*max-element-number-before-break*)))) (elements (ly:music-property seq 'elements)) (chord? (make-music-type-predicate 'EventChord)) + (note-or-chord? (make-music-type-predicate 'EventChord 'NoteEvent + 'LyricEvent 'RestEvent + 'ClusterNoteEvent)) (cluster? (make-music-type-predicate 'ClusterNoteEvent)) (note? (make-music-type-predicate 'NoteEvent))) - (format #f "~a~a{~v%~v_~{~a ~}~v%~v_}" + (format #f "~a~a{~v%~v_~{~a~^ ~}~v%~v_}" (if (any (lambda (e) - (and (chord? e) - (any cluster? (ly:music-property e 'elements)))) + (or (cluster? e) + (and (chord? e) + (any cluster? (ly:music-property e 'elements))))) elements) "\\makeClusters " "") @@ -389,15 +369,17 @@ "\\figuremode ") ((any (lambda (chord) (any (make-music-type-predicate 'LyricEvent) - (ly:music-property chord 'elements))) - (filter chord? elements)) + (cons chord + (ly:music-property chord 'elements)))) + (filter note-or-chord? elements)) "\\lyricmode ") ((any (lambda (chord) (any (lambda (event) (and (note? event) (not (null? (ly:music-property event 'drum-type))))) - (ly:music-property chord 'elements))) - (filter chord? elements)) + (cons chord + (ly:music-property chord 'elements)))) + (filter note-or-chord? elements)) "\\drummode ") (else ;; TODO: other modes? "")) @@ -405,16 +387,20 @@ (if force-line-break 1 0) (if force-line-break (+ 2 (*indent*)) 1) (parameterize ((*indent* (+ 2 (*indent*)))) - (map-in-order music->lily-string elements)) + (map-in-order (lambda (music) + (music->lily-string music parser)) + elements)) (if force-line-break 1 0) - (if force-line-break (*indent*) 0)))) + (if force-line-break (*indent*) 1)))) -(define-display-method SimultaneousMusic (sim) +(define-display-method SimultaneousMusic (sim parser) (parameterize ((*indent* (+ 3 (*indent*)))) (format #f "<< ~{~a ~}>>" - (map-in-order music->lily-string (ly:music-property sim 'elements))))) + (map-in-order (lambda (music) + (music->lily-string music parser)) + (ly:music-property sim 'elements))))) -(define-extra-display-method SimultaneousMusic (expr) +(define-extra-display-method SimultaneousMusic (expr parser) "If `sim' is an \afterGrace expression, return \"\\afterGrace ...\". Otherwise, return #f." ;; TODO: do something with afterGraceFraction? @@ -425,81 +411,91 @@ Otherwise, return #f." (music 'GraceMusic element ?grace)))))) (format #f "\\afterGrace ~a ~a" - (music->lily-string ?before-grace) - (music->lily-string ?grace)))) - + (music->lily-string ?before-grace parser) + (music->lily-string ?grace parser)))) + ;;; ;;; Chords ;;; -(define-display-method EventChord (chord) - ;; event_chord : simple_element post_events - ;; | command_element +(define-display-method EventChord (chord parser) + ;; event_chord : command_element ;; | note_chord_element ;; TODO : tagged post_events ;; post_events : ( post_event | tagged_post_event )* ;; tagged_post_event: '-' \tag embedded_scm post_event - (let* ((elements (ly:music-property chord 'elements)) - (simple-elements (filter (make-music-type-predicate - 'NoteEvent 'ClusterNoteEvent 'RestEvent - 'MultiMeasureRestEvent 'SkipEvent 'LyricEvent) - elements))) - (if ((make-music-type-predicate 'StaffSpanEvent 'BreathingSignEvent) (car elements)) - ;; first, a special case: StaffSpanEvent (\startStaff, \stopStaff) - ;; and BreathingSignEvent (\breathe) - (music->lily-string (car elements)) - (if (and (not (null? simple-elements)) - (null? (cdr simple-elements))) - ;; simple_element : note | figure | rest | mmrest | lyric_element | skip - (let* ((simple-element (car simple-elements)) - (duration (ly:music-property simple-element 'duration)) - (lily-string (format #f "~a~a~a~{~a ~}" - (music->lily-string simple-element) - (duration->lily-string duration) - (if (and ((make-music-type-predicate 'RestEvent) simple-element) - (ly:pitch? (ly:music-property simple-element 'pitch))) - "\\rest" - "") - (map-in-order music->lily-string (filter post-event? elements))))) - (*previous-duration* duration) - lily-string) - (let ((chord-elements (filter (make-music-type-predicate - 'NoteEvent 'ClusterNoteEvent 'BassFigureEvent) - elements)) - (post-events (filter post-event? elements))) - (if (not (null? chord-elements)) - ;; note_chord_element : '<' (notepitch | drumpitch)* '>" duration post_events - (let ((lily-string (format #f "< ~{~a ~}>~a~{~a ~}" - (map-in-order music->lily-string chord-elements) - (duration->lily-string (ly:music-property (car chord-elements) - 'duration)) - (map-in-order music->lily-string post-events)))) - (*previous-duration* (ly:music-property (car chord-elements) 'duration)) - lily-string) - ;; command_element - (format #f "~{~a ~}" (map-in-order music->lily-string elements)))))))) - -(define-display-method MultiMeasureRest (mmrest) - (let* ((dur (ly:music-property mmrest 'duration)) - (ly (format #f "R~a~{~a ~}" - (duration->lily-string dur) - (map-in-order music->lily-string - (ly:music-property mmrest 'articulations))))) - (*previous-duration* dur) - ly)) - -(define-display-method SkipMusic (skip) + (let* ((elements (append (ly:music-property chord 'elements) + (ly:music-property chord 'articulations))) + (chord-repeat (ly:music-property chord 'duration))) + (call-with-values + (lambda () + (partition (lambda (m) (music-is-of-type? m 'rhythmic-event)) + elements)) + (lambda (chord-elements other-elements) + (cond ((pair? chord-elements) + ;; note_chord_element : + ;; '<' (notepitch | drumpitch)* '>" duration post_events + (let ((duration (duration->lily-string (ly:music-property + (car chord-elements) + 'duration) + #:remember #t))) + ;; Format duration first so that it does not appear on + ;; chord elements + (format #f "< ~{~a ~}>~a~:{~:[-~;~]~a~^ ~}" + (map-in-order (lambda (music) + (music->lily-string music parser)) + chord-elements) + duration + (map-in-order (lambda (music) + (list + (post-event? music) + (music->lily-string music parser))) + other-elements)))) + ((ly:duration? chord-repeat) + (let ((duration (duration->lily-string chord-repeat + #:remember #t))) + (format #f "q~a~:{~:[-~;~]~a~^ ~}" + duration + (map-in-order (lambda (music) + (list + (post-event? music) + (music->lily-string music parser))) + other-elements)))) + + ((and (= 1 (length other-elements)) + (not (post-event? (car other-elements)))) + (format #f (music->lily-string (car other-elements) parser))) + (else + (format #f "< >~:{~:[-~;~]~a~^ ~}" + (map-in-order (lambda (music) + (list + (post-event? music) + (music->lily-string music parser))) + other-elements)))))))) + +(define-display-method MultiMeasureRestMusic (mmrest parser) + (format #f "R~a~{~a~^ ~}" + (duration->lily-string (ly:music-property mmrest 'duration) + #:remember #t) + (map-in-order (lambda (music) + (music->lily-string music parser)) + (ly:music-property mmrest 'articulations)))) + +(define-display-method SkipMusic (skip parser) (format #f "\\skip ~a" (duration->lily-string (ly:music-property skip 'duration) #:force-duration #t))) +(define-display-method OttavaMusic (ottava parser) + (format #f "\\ottava #~a" (ly:music-property ottava 'ottava-number))) + ;;; ;;; Notes, rests, skips... ;;; -(define (simple-note->lily-string event) - (format #f "~a~a~a~a~{~a~}" ; pitchname octave !? octave-check articulations - (note-name->lily-string (ly:music-property event 'pitch)) +(define (simple-note->lily-string event parser) + (format #f "~a~a~a~a~a~a~{~a~}" ; pitchname octave !? octave-check duration optional_rest articulations + (note-name->lily-string (ly:music-property event 'pitch) parser) (octave->lily-string (ly:music-property event 'pitch)) (let ((forced (ly:music-property event 'force-accidental)) (cautionary (ly:music-property event 'cautionary))) @@ -518,84 +514,94 @@ Otherwise, return #f." (make-string (1- (* -1 octave-check)) #\,)) (else ""))) "")) - (map-in-order music->lily-string (ly:music-property event 'articulations)))) - -(define-display-method NoteEvent (note) + (duration->lily-string (ly:music-property event 'duration) + #:remember #t) + (if ((make-music-type-predicate 'RestEvent) event) + "\\rest" "") + (map-in-order (lambda (event) + (music->lily-string event parser)) + (ly:music-property event 'articulations)))) + +(define-display-method NoteEvent (note parser) (cond ((not (null? (ly:music-property note 'pitch))) ;; note - (simple-note->lily-string note)) + (simple-note->lily-string note parser)) ((not (null? (ly:music-property note 'drum-type))) ;; drum - (format #f "~a" (ly:music-property note 'drum-type))) + (format #f "~a~a" (ly:music-property note 'drum-type) + (duration->lily-string (ly:music-property note 'duration) + #:remember #t))) (else ;; unknown? ""))) -(define-display-method ClusterNoteEvent (note) - (simple-note->lily-string note)) +(define-display-method ClusterNoteEvent (note parser) + (simple-note->lily-string note parser)) -(define-display-method RestEvent (rest) +(define-display-method RestEvent (rest parser) (if (not (null? (ly:music-property rest 'pitch))) - (simple-note->lily-string rest) - "r")) + (simple-note->lily-string rest parser) + (string-append "r" (duration->lily-string (ly:music-property rest 'duration) + #:remember #t)))) -(define-display-method MultiMeasureRestEvent (rest) - "R") +(define-display-method MultiMeasureRestEvent (rest parser) + (string-append "R" (duration->lily-string (ly:music-property rest 'duration) + #:remember #t))) -(define-display-method SkipEvent (rest) - "s") +(define-display-method SkipEvent (rest parser) + (string-append "s" (duration->lily-string (ly:music-property rest 'duration) + #:remember #t))) -(define-display-method MarkEvent (mark) +(define-display-method RepeatedChord (chord parser) + (music->lily-string (ly:music-property chord 'element) parser)) + +(define-display-method MarkEvent (mark parser) (let ((label (ly:music-property mark 'label))) (if (null? label) "\\mark \\default" (format #f "\\mark ~a" (markup->lily-string label))))) -(define-display-method MetronomeChangeEvent (tempo) - (format #f "\\tempo ~a = ~a" - (duration->lily-string (ly:music-property tempo 'tempo-unit) #:force-duration #t #:prev-duration #f) - (ly:music-property tempo 'metronome-count))) - -(define-display-method KeyChangeEvent (key) +(define-display-method KeyChangeEvent (key parser) (let ((pitch-alist (ly:music-property key 'pitch-alist)) (tonic (ly:music-property key 'tonic))) (if (or (null? pitch-alist) (null? tonic)) "\\key \\default" - (let ((c-pitch-alist (ly:transpose-key-alist pitch-alist + (let ((c-pitch-alist (ly:transpose-key-alist pitch-alist (ly:pitch-diff (ly:make-pitch 0 0 0) tonic)))) (format #f "\\key ~a \\~a~a" - (note-name->lily-string (ly:music-property key 'tonic)) + (note-name->lily-string (ly:music-property key 'tonic) parser) (any (lambda (mode) - (if (and (*parser*) - (equal? (ly:parser-lookup (*parser*) mode) c-pitch-alist)) + (if (and parser + (equal? (ly:parser-lookup parser mode) c-pitch-alist)) (symbol->string mode) #f)) '(major minor ionian locrian aeolian mixolydian lydian phrygian dorian)) (new-line->lily-string)))))) -(define-display-method RelativeOctaveCheck (octave) +(define-display-method RelativeOctaveCheck (octave parser) (let ((pitch (ly:music-property octave 'pitch))) - (format #f "\\octave ~a~a" - (note-name->lily-string pitch) + (format #f "\\octaveCheck ~a~a" + (note-name->lily-string pitch parser) (octave->lily-string pitch)))) -(define-display-method VoiceSeparator (sep) +(define-display-method VoiceSeparator (sep parser) "\\\\") -(define-display-method LigatureEvent (ligature) +(define-display-method LigatureEvent (ligature parser) (if (= START (ly:music-property ligature 'span-direction)) "\\[" "\\]")) -(define-display-method BarCheck (check) +(define-display-method BarCheck (check parser) (format #f "|~a" (new-line->lily-string))) -(define-display-method PesOrFlexaEvent (expr) +(define-display-method PesOrFlexaEvent (expr parser) "\\~") -(define-display-method BassFigureEvent (figure) +(define-display-method BassFigureEvent (figure parser) (let ((alteration (ly:music-property figure 'alteration)) (fig (ly:music-property figure 'figure)) (bracket-start (ly:music-property figure 'bracket-start)) (bracket-stop (ly:music-property figure 'bracket-stop))) + (format #f "~a~a~a~a" (if (null? bracket-start) "" "[") (cond ((null? fig) "_") @@ -603,93 +609,97 @@ Otherwise, return #f." (else fig)) (if (null? alteration) "" - (case alteration - ((-4) "--") - ((-2) "-") - ((0) "!") - ((2) "+") - ((4) "++") + (cond + ((= alteration DOUBLE-FLAT) "--") + ((= alteration FLAT) "-") + ((= alteration NATURAL) "!") + ((= alteration SHARP) "+") + ((= alteration DOUBLE-SHARP) "++") (else ""))) (if (null? bracket-stop) "" "]")))) -(define-display-method LyricEvent (lyric) - (let ((text (ly:music-property lyric 'text))) - (if (or (string? text) - (eqv? (first text) simple-markup)) - ;; a string or a simple markup - (let ((string (if (string? text) - text - (second text)))) - (if (string-match "(\"| |[0-9])" string) - ;; TODO check exactly in which cases double quotes should be used - (format #f "~s" string) - string)) - (markup->lily-string text)))) - -(define-display-method BreathingSignEvent (event) +(define-display-method LyricEvent (lyric parser) + (format "~a~{~a~^ ~}" + (let ((text (ly:music-property lyric 'text))) + (if (or (string? text) + (eqv? (first text) simple-markup)) + ;; a string or a simple markup + (let ((string (if (string? text) + text + (second text)))) + (if (string-match "(\"| |[0-9])" string) + ;; TODO check exactly in which cases double quotes should be used + (format #f "~s" string) + string)) + (markup->lily-string text))) + (map-in-order (lambda (m) (music->lily-string m parser)) + (ly:music-property lyric 'articulations)))) + +(define-display-method BreathingEvent (event parser) "\\breathe") ;;; ;;; Staff switches ;;; -(define-display-method AutoChangeMusic (m) +(define-display-method AutoChangeMusic (m parser) (format #f "\\autochange ~a" - (music->lily-string (ly:music-property m 'element)))) + (music->lily-string (ly:music-property m 'element) parser))) -(define-display-method ContextChange (m) +(define-display-method ContextChange (m parser) (format #f "\\change ~a = \"~a\"" (ly:music-property m 'change-to-type) (ly:music-property m 'change-to-id))) ;;; -(define-display-method TimeScaledMusic (times) +(define-display-method TimeScaledMusic (times parser) (let* ((num (ly:music-property times 'numerator)) (den (ly:music-property times 'denominator)) (nd-gcd (gcd num den))) (parameterize ((*force-line-break* #f) (*time-factor-numerator* (/ num nd-gcd)) (*time-factor-denominator* (/ den nd-gcd))) - (format #f "\\times ~a/~a ~a" + (format #f "\\times ~a/~a ~a" num den - (music->lily-string (ly:music-property times 'element)))))) + (music->lily-string (ly:music-property times 'element) parser))))) -(define-display-method RelativeOctaveMusic (m) - (music->lily-string (ly:music-property m 'element))) +(define-display-method RelativeOctaveMusic (m parser) + (music->lily-string (ly:music-property m 'element) parser)) -(define-display-method TransposedMusic (m) - (music->lily-string (ly:music-property m 'element))) +(define-display-method TransposedMusic (m parser) + (music->lily-string (ly:music-property m 'element) parser)) ;;; ;;; Repeats ;;; -(define (repeat->lily-string expr repeat-type) +(define-display-method AlternativeEvent (alternative parser) "") + +(define (repeat->lily-string expr repeat-type parser) (format #f "\\repeat ~a ~a ~a ~a" repeat-type (ly:music-property expr 'repeat-count) - (music->lily-string (ly:music-property expr 'element)) + (music->lily-string (ly:music-property expr 'element) parser) (let ((alternatives (ly:music-property expr 'elements))) (if (null? alternatives) "" (format #f "\\alternative { ~{~a ~}}" - (map-in-order music->lily-string alternatives)))))) - -(define-display-method VoltaRepeatedMusic (expr) - (repeat->lily-string expr "volta")) + (map-in-order (lambda (music) + (music->lily-string music parser)) + alternatives)))))) -(define-display-method UnfoldedRepeatedMusic (expr) - (repeat->lily-string expr "unfold")) +(define-display-method VoltaRepeatedMusic (expr parser) + (repeat->lily-string expr "volta" parser)) -(define-display-method FoldedRepeatedMusic (expr) - (repeat->lily-string expr "fold")) +(define-display-method UnfoldedRepeatedMusic (expr parser) + (repeat->lily-string expr "unfold" parser)) -(define-display-method PercentRepeatedMusic (expr) - (repeat->lily-string expr "percent")) +(define-display-method PercentRepeatedMusic (expr parser) + (repeat->lily-string expr "percent" parser)) -(define-display-method TremoloRepeatedMusic (expr) +(define-display-method TremoloRepeatedMusic (expr parser) (let* ((count (ly:music-property expr 'repeat-count)) (dots (if (= 0 (modulo count 3)) 0 1)) (shift (- (log2 (if (= 0 dots) @@ -718,15 +728,15 @@ Otherwise, return #f." element) (format #f "\\repeat tremolo ~a ~a" count - (music->lily-string element)))) + (music->lily-string element parser)))) ;;; ;;; Contexts -;;; +;;; -(define-display-method ContextSpeccedMusic (expr) +(define-display-method ContextSpeccedMusic (expr parser) (let ((id (ly:music-property expr 'context-id)) - (create-new (ly:music-property expr 'create-new)) + (create-new (ly:music-property expr 'create-new)) (music (ly:music-property expr 'element)) (operations (ly:music-property expr 'property-operations)) (ctype (ly:music-property expr 'context-type))) @@ -739,23 +749,23 @@ Otherwise, return #f." "" (format #f " = ~s" id)) (if (null? operations) - "" - (format #f " \\with {~{~a~}~%~v_}" + "" + (format #f " \\with {~{~a~}~%~v_}" (parameterize ((*indent* (+ (*indent*) 2))) (map (lambda (op) (format #f "~%~v_\\~a ~s" (*indent*) (first op) (second op))) - (reverse operations))) + operations)) (*indent*))) (parameterize ((*current-context* ctype)) - (music->lily-string music))))) + (music->lily-string music parser))))) ;; special cases: \figures \lyrics \drums -(define-extra-display-method ContextSpeccedMusic (expr) +(define-extra-display-method ContextSpeccedMusic (expr parser) (with-music-match (expr (music 'ContextSpeccedMusic - create-new #t + create-new #t property-operations ?op context-type ?context-type element ?sequence)) @@ -763,18 +773,18 @@ Otherwise, return #f." (parameterize ((*explicit-mode* #f)) (case ?context-type ((FiguredBass) - (format #f "\\figures ~a" (music->lily-string ?sequence))) + (format #f "\\figures ~a" (music->lily-string ?sequence parser))) ((Lyrics) - (format #f "\\lyrics ~a" (music->lily-string ?sequence))) + (format #f "\\lyrics ~a" (music->lily-string ?sequence parser))) ((DrumStaff) - (format #f "\\drums ~a" (music->lily-string ?sequence))) + (format #f "\\drums ~a" (music->lily-string ?sequence parser))) (else #f))) #f))) ;;; Context properties -(define-extra-display-method ContextSpeccedMusic (expr) +(define-extra-display-method ContextSpeccedMusic (expr parser) (let ((element (ly:music-property expr 'element)) (property-tuning? (make-music-type-predicate 'PropertySet 'PropertyUnset @@ -786,12 +796,12 @@ Otherwise, return #f." (and (sequence? element) (every property-tuning? (ly:music-property element 'elements))))) (parameterize ((*current-context* (ly:music-property expr 'context-type))) - (music->lily-string element)) + (music->lily-string element parser)) #f))) -(define (property-value->lily-string arg) +(define (property-value->lily-string arg parser) (cond ((ly:music? arg) - (music->lily-string arg)) + (music->lily-string arg parser)) ((string? arg) (format #f "#~s" arg)) ((markup? arg) @@ -799,7 +809,7 @@ Otherwise, return #f." (else (format #f "#~a" (scheme-expr->lily-string arg))))) -(define-display-method PropertySet (expr) +(define-display-method PropertySet (expr parser) (let ((property (ly:music-property expr 'symbol)) (value (ly:music-property expr 'value)) (once (ly:music-property expr 'once))) @@ -807,49 +817,52 @@ Otherwise, return #f." (if (and (not (null? once))) "\\once " "") - (if (eqv? (*current-context*) 'Bottom) - "" + (if (eqv? (*current-context*) 'Bottom) + "" (format #f "~a . " (*current-context*))) property - (property-value->lily-string value) + (property-value->lily-string value parser) (new-line->lily-string)))) -(define-display-method PropertyUnset (expr) +(define-display-method PropertyUnset (expr parser) (format #f "\\unset ~a~a~a" - (if (eqv? (*current-context*) 'Bottom) - "" + (if (eqv? (*current-context*) 'Bottom) + "" (format #f "~a . " (*current-context*))) (ly:music-property expr 'symbol) (new-line->lily-string))) ;;; Layout properties -(define-display-method OverrideProperty (expr) - (let ((symbol (ly:music-property expr 'symbol)) - (properties (ly:music-property expr 'grob-property-path)) - (value (ly:music-property expr 'grob-value)) - (once (ly:music-property expr 'once))) +(define-display-method OverrideProperty (expr parser) + (let* ((symbol (ly:music-property expr 'symbol)) + (properties (ly:music-property expr 'grob-property-path + (list (ly:music-property expr 'grob-property)))) + (value (ly:music-property expr 'grob-value)) + (once (ly:music-property expr 'once))) + (format #f "~a\\override ~a~a #'~a = ~a~a" (if (or (null? once) (not once)) "" "\\once ") - (if (eqv? (*current-context*) 'Bottom) - "" + (if (eqv? (*current-context*) 'Bottom) + "" (format #f "~a . " (*current-context*))) symbol (if (null? (cdr properties)) (car properties) properties) - (property-value->lily-string value) + (property-value->lily-string value parser) (new-line->lily-string)))) - -(define-display-method RevertProperty (expr) - (let ((symbol (ly:music-property expr 'symbol)) - (properties (ly:music-property expr 'grob-property-path))) + +(define-display-method RevertProperty (expr parser) + (let* ((symbol (ly:music-property expr 'symbol)) + (properties (ly:music-property expr 'grob-property-path + (list (ly:music-property expr 'grob-property))))) (format #f "\\revert ~a~a #'~a~a" - (if (eqv? (*current-context*) 'Bottom) - "" + (if (eqv? (*current-context*) 'Bottom) + "" (format #f "~a . " (*current-context*))) symbol (if (null? (cdr properties)) @@ -857,15 +870,76 @@ Otherwise, return #f." properties) (new-line->lily-string)))) -;;; \clef -(define clef-name-alist (map (lambda (name+vals) - (cons (cdr name+vals) - (car name+vals))) - supported-clefs)) +(define-display-method TimeSignatureMusic (expr parser) + (let* ((num (ly:music-property expr 'numerator)) + (den (ly:music-property expr 'denominator)) + (structure (ly:music-property expr 'beat-structure))) + (if (null? structure) + (format #f + "\\time ~a/~a~a" + num den + (new-line->lily-string)) + (format #f + "\\time #'~a ~a/~a~a" + structure num den + (new-line->lily-string))))) + +;;; \melisma and \melismaEnd +(define-extra-display-method ContextSpeccedMusic (expr parser) + "If expr is a melisma, return \"\\melisma\", otherwise, return #f." + (with-music-match (expr (music 'ContextSpeccedMusic + element (music 'PropertySet + value #t + symbol 'melismaBusy))) + "\\melisma")) -(define-extra-display-method ContextSpeccedMusic (expr) - "If `expr' is a clef change, return \"\\clef ...\" -Otherwise, return #f." +(define-extra-display-method ContextSpeccedMusic (expr parser) + "If expr is a melisma end, return \"\\melismaEnd\", otherwise, return #f." + (with-music-match (expr (music 'ContextSpeccedMusic + element (music 'PropertyUnset + symbol 'melismaBusy))) + "\\melismaEnd")) + +;;; \tempo +(define-extra-display-method SequentialMusic (expr parser) + (with-music-match (expr (music 'SequentialMusic + elements ((music 'TempoChangeEvent + text ?text + tempo-unit ?unit + metronome-count ?count) + (music 'ContextSpeccedMusic + element (music 'PropertySet + symbol 'tempoWholesPerMinute))))) + (format #f "\\tempo ~{~a~a~}~a = ~a~a" + (if (markup? ?text) + (list (markup->lily-string ?text) " ") + '()) + (duration->lily-string ?unit #:force-duration #t) + (if (pair? ?count) + (format #f "~a ~~ ~a" (car ?count) (cdr ?count)) + ?count) + (new-line->lily-string)))) + +(define-display-method TempoChangeEvent (expr parser) + (let ((text (ly:music-property expr 'text))) + (format #f "\\tempo ~a~a" + (markup->lily-string text) + (new-line->lily-string)))) + +;;; \clef +(define clef-name-alist #f) +(define-public (memoize-clef-names clefs) + "Initialize @code{clef-name-alist}, if not already set." + (if (not clef-name-alist) + (set! clef-name-alist + (map (lambda (name+vals) + (cons (cdr name+vals) + (car name+vals))) + clefs)))) + +(define-extra-display-method ContextSpeccedMusic (expr parser) + "If @var{expr} is a clef change, return \"\\clef ...\". +Otherwise, return @code{#f}." (with-music-match (expr (music 'ContextSpeccedMusic context-type 'Staff element (music 'SequentialMusic @@ -873,18 +947,20 @@ Otherwise, return #f." value ?clef-glyph symbol 'clefGlyph) (music 'PropertySet - symbol 'middleCPosition) + symbol 'middleCClefPosition) (music 'PropertySet value ?clef-position symbol 'clefPosition) (music 'PropertySet value ?clef-octavation - symbol 'clefOctavation))))) - (let ((clef-prop+name (assoc (list ?clef-glyph ?clef-position 0) - clef-name-alist))) - (if clef-prop+name + symbol 'clefOctavation) + (music 'ApplyContext + procedure ly:set-middle-C!))))) + (let ((clef-name (assoc-get (list ?clef-glyph ?clef-position 0) + clef-name-alist))) + (if clef-name (format #f "\\clef \"~a~{~a~a~}\"~a" - (cdr clef-prop+name) + clef-name (cond ((= 0 ?clef-octavation) (list "" "")) ((> ?clef-octavation 0) @@ -894,74 +970,19 @@ Otherwise, return #f." (new-line->lily-string)) #f)))) -;;; \time -(define-extra-display-method ContextSpeccedMusic (expr) - "If `expr' is a time signature set, return \"\\time ...\". -Otherwise, return #f." - (with-music-match (expr (music - 'ContextSpeccedMusic - element (music - 'ContextSpeccedMusic - context-type 'Timing - element (music - 'SequentialMusic - elements ((music - 'PropertySet - value ?num+den - symbol 'timeSignatureFraction) - (music - 'PropertySet - symbol 'beatLength) - (music - 'PropertySet - symbol 'measureLength) - (music - 'PropertySet - value ?grouping - symbol 'beatGrouping)))))) - (if (null? ?grouping) - (format #f "\\time ~a/~a~a" (car ?num+den) (cdr ?num+den) (new-line->lily-string)) - (format #f "#(set-time-signature ~a ~a '~s)~a" - (car ?num+den) (cdr ?num+den) ?grouping (new-line->lily-string))))) - ;;; \bar -(define-extra-display-method ContextSpeccedMusic (expr) +(define-extra-display-method ContextSpeccedMusic (expr parser) "If `expr' is a bar, return \"\\bar ...\". Otherwise, return #f." (with-music-match (expr (music 'ContextSpeccedMusic - context-type 'Timing - element (music 'PropertySet - value ?bar-type - symbol 'whichBar))) - (format #f "\\bar \"~a\"~a" ?bar-type (new-line->lily-string)))) + context-type 'Timing + element (music 'PropertySet + value ?bar-type + symbol 'whichBar))) + (format #f "\\bar \"~a\"~a" ?bar-type (new-line->lily-string)))) ;;; \partial -(define (duration->moment ly-duration) - (let ((log2 (ly:duration-log ly-duration)) - (dots (ly:duration-dot-count ly-duration)) - (num+den (ly:duration-factor ly-duration))) - (let* ((m (expt 2 (- log2))) - (factor (/ (car num+den) (cdr num+den)))) - (/ (do ((i 0 (1+ i)) - (delta (/ m 2) (/ delta 2))) - ((= i dots) m) - (set! m (+ m delta))) - factor)))) -(define moment-duration-alist (map (lambda (duration) - (cons (duration->moment duration) - duration)) - (append-map (lambda (log2) - (map (lambda (dots) - (ly:make-duration log2 dots 1 1)) - (list 0 1 2 3))) - (list 0 1 2 3 4)))) - -(define (moment->duration moment) - (let ((result (assoc (- moment) moment-duration-alist))) - (and result - (cdr result)))) - -(define-extra-display-method ContextSpeccedMusic (expr) +(define-extra-display-method ContextSpeccedMusic (expr parser) "If `expr' is a partial measure, return \"\\partial ...\". Otherwise, return #f." (with-music-match (expr (music @@ -970,27 +991,27 @@ Otherwise, return #f." 'ContextSpeccedMusic context-type 'Timing element (music - 'PropertySet - value ?moment - symbol 'measurePosition)))) - (let ((duration (moment->duration (/ (ly:moment-main-numerator ?moment) - (ly:moment-main-denominator ?moment))))) - (and duration (format #f "\\partial ~a" (duration->lily-string duration #:force-duration #t)))))) + 'PartialSet + partial-duration ?duration)))) + + (and ?duration + (format #f "\\partial ~a" + (duration->lily-string ?duration #:force-duration #t))))) ;;; ;;; -(define-display-method ApplyOutputEvent (applyoutput) +(define-display-method ApplyOutputEvent (applyoutput parser) (let ((proc (ly:music-property applyoutput 'procedure)) - (ctx (ly:music-property applyoutput 'context-type))) + (ctx (ly:music-property applyoutput 'context-type))) (format #f "\\applyOutput #'~a #~a" - ctx + ctx (or (procedure-name proc) (with-output-to-string (lambda () (pretty-print (procedure-source proc)))))))) -(define-display-method ApplyContext (applycontext) +(define-display-method ApplyContext (applycontext parser) (let ((proc (ly:music-property applycontext 'procedure))) (format #f "\\applyContext #~a" (or (procedure-name proc) @@ -999,11 +1020,13 @@ Otherwise, return #f." (pretty-print (procedure-source proc)))))))) ;;; \partcombine -(define-display-method PartCombineMusic (expr) +(define-display-method PartCombineMusic (expr parser) (format #f "\\partcombine ~{~a ~}" - (map-in-order music->lily-string (ly:music-property expr 'elements)))) + (map-in-order (lambda (music) + (music->lily-string music parser)) + (ly:music-property expr 'elements)))) -(define-extra-display-method PartCombineMusic (expr) +(define-extra-display-method PartCombineMusic (expr parser) (with-music-match (expr (music 'PartCombineMusic elements ((music 'UnrelativableMusic element (music 'ContextSpeccedMusic @@ -1016,15 +1039,15 @@ Otherwise, return #f." context-type 'Voice element ?sequence2))))) (format #f "\\partcombine ~a~a~a" - (music->lily-string ?sequence1) + (music->lily-string ?sequence1 parser) (new-line->lily-string) - (music->lily-string ?sequence2)))) + (music->lily-string ?sequence2 parser)))) -(define-display-method UnrelativableMusic (expr) - (music->lily-string (ly:music-property expr 'element))) +(define-display-method UnrelativableMusic (expr parser) + (music->lily-string (ly:music-property expr 'element) parser)) ;;; Cue notes -(define-display-method QuoteMusic (expr) +(define-display-method QuoteMusic (expr parser) (or (with-music-match (expr (music 'QuoteMusic quoted-voice-direction ?quoted-voice-direction @@ -1035,45 +1058,45 @@ Otherwise, return #f." (format #f "\\cueDuring #~s #~a ~a" ?quoted-music-name ?quoted-voice-direction - (music->lily-string ?music))) + (music->lily-string ?music parser))) (format #f "\\quoteDuring #~s ~a" (ly:music-property expr 'quoted-music-name) - (music->lily-string (ly:music-property expr 'element))))) + (music->lily-string (ly:music-property expr 'element) parser)))) ;;; ;;; Breaks ;;; -(define-display-method LineBreakEvent (expr) +(define-display-method LineBreakEvent (expr parser) (if (null? (ly:music-property expr 'break-permission)) "\\noBreak" "\\break")) -(define-display-method PageBreakEvent (expr) +(define-display-method PageBreakEvent (expr parser) (if (null? (ly:music-property expr 'break-permission)) "\\noPageBreak" "\\pageBreak")) -(define-display-method PageTurnEvent (expr) +(define-display-method PageTurnEvent (expr parser) (if (null? (ly:music-property expr 'break-permission)) "\\noPageTurn" "\\pageTurn")) -(define-extra-display-method EventChord (expr) +(define-extra-display-method EventChord (expr parser) (with-music-match (expr (music 'EventChord - elements ((music 'LineBreakEvent - break-permission 'force) - (music 'PageBreakEvent - break-permission 'force)))) + elements ((music 'LineBreakEvent + break-permission 'force) + (music 'PageBreakEvent + break-permission 'force)))) "\\pageBreak")) -(define-extra-display-method EventChord (expr) +(define-extra-display-method EventChord (expr parser) (with-music-match (expr (music 'EventChord - elements ((music 'LineBreakEvent - break-permission 'force) - (music 'PageBreakEvent - break-permission 'force) - (music 'PageTurnEvent - break-permission 'force)))) + elements ((music 'LineBreakEvent + break-permission 'force) + (music 'PageBreakEvent + break-permission 'force) + (music 'PageTurnEvent + break-permission 'force)))) "\\pageTurn")) ;;; @@ -1081,14 +1104,14 @@ Otherwise, return #f." ;;; ;;; \lyricsto -(define-display-method LyricCombineMusic (expr) +(define-display-method LyricCombineMusic (expr parser) (format #f "\\lyricsto ~s ~a" (ly:music-property expr 'associated-context) (parameterize ((*explicit-mode* #f)) - (music->lily-string (ly:music-property expr 'element))))) + (music->lily-string (ly:music-property expr 'element) parser)))) ;; \addlyrics -(define-extra-display-method SimultaneousMusic (expr) +(define-extra-display-method SimultaneousMusic (expr parser) (with-music-match (expr (music 'SimultaneousMusic elements ((music 'ContextSpeccedMusic context-id ?id @@ -1096,16 +1119,18 @@ Otherwise, return #f." element ?note-sequence) (music 'ContextSpeccedMusic context-type 'Lyrics - create-new #t + create-new #t element (music 'LyricCombineMusic associated-context ?associated-id element ?lyric-sequence))))) (if (string=? ?id ?associated-id) (format #f "~a~a \\addlyrics ~a" - (music->lily-string ?note-sequence) + (music->lily-string ?note-sequence parser) (new-line->lily-string) (parameterize ((*explicit-mode* #f)) - (music->lily-string ?lyric-sequence))) + (music->lily-string ?lyric-sequence parser))) #f))) - +;; Silence internal event sent at end of each lyrics block +(define-display-method CompletizeExtenderEvent (expr parser) + "")