]> git.donarmstrong.com Git - lilypond.git/blobdiff - scm/define-music-display-methods.scm
Doc-es: various updates.
[lilypond.git] / scm / define-music-display-methods.scm
index e429c92b6fcf0e3b641e321d0319b4dd9b143305..a61c2e8b18e9895d7c0d9613f309427cb91d4768 100644 (file)
@@ -1,7 +1,7 @@
 ;;; define-music-display-methods.scm -- data for displaying music
 ;;; expressions using LilyPond notation.
 ;;;
-;;; Copyright (C) 2005--2012 Nicolas Sceaux  <nicolas.sceaux@free.fr>
+;;; Copyright (C) 2005--2015 Nicolas Sceaux  <nicolas.sceaux@free.fr>
 ;;;
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   (cond ((or (number? scm-arg)
              (string? scm-arg)
              (boolean? scm-arg))
-        (format #f "~s" scm-arg))
-       ((or (symbol? scm-arg)
-            (list? scm-arg))
-        (format #f "'~s" scm-arg))
-       ((procedure? scm-arg)
-        (format #f "~a"
-                (or (procedure-name scm-arg)
-                    (with-output-to-string
-                      (lambda ()
-                        (pretty-print (procedure-source scm-arg)))))))
-       (else
-        (format #f "~a"
-                (with-output-to-string
-                  (lambda ()
-                    (display-scheme-music scm-arg)))))))
+         (format #f "~s" scm-arg))
+        ((or (symbol? scm-arg)
+             (list? scm-arg))
+         (format #f "'~s" scm-arg))
+        ((procedure? scm-arg)
+         (format #f "~a"
+                 (or (procedure-name scm-arg)
+                     (with-output-to-string
+                       (lambda ()
+                         (pretty-print (procedure-source scm-arg)))))))
+        (else
+         (format #f "~a"
+                 (with-output-to-string
+                   (lambda ()
+                     (display-scheme-music scm-arg)))))))
 ;;;
 ;;; Markups
 ;;;
@@ -43,33 +43,33 @@ expression."
   (define (proc->command proc)
     (let ((cmd-markup (symbol->string (procedure-name proc))))
       (substring cmd-markup 0 (- (string-length cmd-markup)
-                                (string-length "-markup")))))
+                                 (string-length "-markup")))))
   (define (arg->string arg)
     (cond ((string? arg)
-          (format #f "~s" arg))
-         ((markup? arg) ;; a markup
-          (markup->lily-string-aux arg))
-         ((and (pair? arg) (every markup? arg)) ;; a markup list
-          (format #f "{~{ ~a~}}" (map-in-order markup->lily-string-aux arg)))
-         (else          ;; a scheme argument
-          (format #f "#~a" (scheme-expr->lily-string arg)))))
+           (format #f "~s" arg))
+          ((markup? arg) ;; a markup
+           (markup->lily-string-aux arg))
+          ((and (pair? arg) (every markup? arg)) ;; a markup list
+           (format #f "{~{ ~a~}}" (map-in-order markup->lily-string-aux arg)))
+          (else          ;; a scheme argument
+           (format #f "#~a" (scheme-expr->lily-string arg)))))
   (define (markup->lily-string-aux expr)
     (if (string? expr)
-       (format #f "~s" expr)
-       (let ((cmd (car expr))
-             (args (cdr expr)))
-         (if (eqv? cmd simple-markup) ;; a simple markup
-             (format #f "~s" (car args))
-             (format #f "\\~a~{ ~a~}"
-                     (proc->command cmd)
-                     (map-in-order arg->string args))))))
+        (format #f "~s" expr)
+        (let ((cmd (car expr))
+              (args (cdr expr)))
+          (if (eqv? cmd simple-markup) ;; a simple markup
+              (format #f "~s" (car args))
+              (format #f "\\~a~{ ~a~}"
+                      (proc->command cmd)
+                      (map-in-order arg->string args))))))
   (cond ((string? markup-expr)
-        (format #f "~s" markup-expr))
-       ((eqv? (car markup-expr) simple-markup)
-        (format #f "~s" (second markup-expr)))
-       (else
-        (format #f "\\markup ~a"
-                (markup->lily-string-aux markup-expr)))))
+         (format #f "~s" markup-expr))
+        ((eqv? (car markup-expr) simple-markup)
+         (format #f "~s" (second markup-expr)))
+        (else
+         (format #f "\\markup ~a"
+                 (markup->lily-string-aux markup-expr)))))
 
 ;;;
 ;;; pitch names
@@ -81,795 +81,778 @@ expression."
        (result #f result))
       ((or result (null? alist)) result)
     (if (and (car alist) (test item (cdar alist)))
-       (set! result (car alist)))))
+        (set! result (car alist)))))
 
-(define-public (note-name->lily-string ly-pitch parser)
+(define-public (note-name->lily-string ly-pitch)
   ;; 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=)))
-    (if result
-       (car result)
-       #f)))
+         (= (ly:pitch-alteration pitch1) (ly:pitch-alteration pitch2))))
+  (let* ((result (rassoc ly-pitch pitchnames pitch=)))
+    (and result (car result))))
 
 (define-public (octave->lily-string pitch)
   (let ((octave (ly:pitch-octave pitch)))
     (cond ((>= octave 0)
-          (make-string (1+ octave) #\'))
-         ((< octave -1)
-          (make-string (1- (* -1 octave)) #\,))
-         (else ""))))
+           (make-string (1+ octave) #\'))
+          ((< octave -1)
+           (make-string (1- (* -1 octave)) #\,))
+          (else ""))))
 
 ;;;
 ;;; durations
 ;;;
-(define*-public (duration->lily-string ly-duration #:key (prev-duration (*previous-duration*))
-                       (force-duration (*force-duration*))
-                       (time-scale (*time-scale*))
-                       remember)
-  (if remember (*previous-duration* ly-duration))
-  (let ((log2   (ly:duration-log ly-duration))
-       (dots    (ly:duration-dot-count ly-duration))
-       (scale (ly:duration-scale ly-duration)))
-    (if (or force-duration (not prev-duration) (not (equal? ly-duration prev-duration)))
-       (string-append (case log2
-                        ((-1) "\\breve")
-                        ((-2) "\\longa")
-                        ((-3) "\\maxima")
-                        (else (number->string (expt 2 log2))))
-                      (make-string dots #\.)
-                      (let ((end-scale (/ scale time-scale)))
-                        (if (= end-scale 1) ""
-                            (format #f "*~a" end-scale))))
-       "")))
+(define*-public (duration->lily-string ly-duration #:key
+                                       (force-duration #f)
+                                       (time-scale (*time-scale*)))
+  (let ((log2    (ly:duration-log ly-duration))
+        (dots    (ly:duration-dot-count ly-duration))
+        (scale (ly:duration-scale ly-duration)))
+    (if (or force-duration (not (*omit-duration*)))
+        (string-append (case log2
+                         ((-1) "\\breve")
+                         ((-2) "\\longa")
+                         ((-3) "\\maxima")
+                         (else (number->string (expt 2 log2))))
+                       (make-string dots #\.)
+                       (let ((end-scale (/ scale time-scale)))
+                         (if (= end-scale 1) ""
+                             (format #f "*~a" end-scale))))
+        "")))
 
 ;;;
 ;;; post events
 ;;;
 
-(define (post-event? m)
-  (music-is-of-type? m 'post-event))
+(define post-event? (music-type-predicate 'post-event))
 
 (define* (event-direction->lily-string event #:optional (required #t))
   (let ((direction (ly:music-property event 'direction)))
     (cond ((or (not direction) (null? direction) (= CENTER direction))
-          (if required "-" ""))
-         ((= UP direction) "^")
-         ((= DOWN direction) "_")
-         (else ""))))
+           (if required "-" ""))
+          ((= UP direction) "^")
+          ((= DOWN direction) "_")
+          (else ""))))
 
 (define-macro (define-post-event-display-method type vars direction-required str)
   `(define-display-method ,type ,vars
      (format #f "~a~a"
-            (event-direction->lily-string ,(car vars) ,direction-required)
-            ,str)))
+             (event-direction->lily-string ,(car vars) ,direction-required)
+             ,str)))
 
 (define-macro (define-span-event-display-method type vars direction-required str-start str-stop)
   `(define-display-method ,type ,vars
      (format #f "~a~a"
-            (event-direction->lily-string ,(car vars) ,direction-required)
-            (if (= START (ly:music-property ,(car vars) 'span-direction))
-                ,str-start
-                ,str-stop))))
+             (event-direction->lily-string ,(car vars) ,direction-required)
+             (if (= START (ly:music-property ,(car vars) 'span-direction))
+                 ,str-start
+                 ,str-stop))))
 
-(define-display-method HyphenEvent (event parser)
+(define-display-method HyphenEvent (event)
   " --")
-(define-display-method ExtenderEvent (event parser)
+(define-display-method ExtenderEvent (event)
   " __")
-(define-display-method TieEvent (event parser)
+(define-display-method TieEvent (event)
   " ~")
-(define-display-method BeamForbidEvent (event parser)
+(define-display-method BeamForbidEvent (event)
   "\\noBeam")
-(define-display-method StringNumberEvent (event parser)
+(define-display-method StringNumberEvent (event)
   (format #f "\\~a" (ly:music-property event 'string-number)))
 
 
-(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-display-method TremoloEvent (event)
+  (let ((tremolo-type (ly:music-property event 'tremolo-type 8)))
+    (format #f ":~a" tremolo-type)))
 
-(define-display-method ArticulationEvent (event parser) #t
+(define-display-method ArticulationEvent (event) #t
   (let* ((articulation  (ly:music-property event 'articulation-type))
-        (shorthand
-         (case (string->symbol articulation)
-           ((marcato) "^")
-           ((stopped) "+")
-           ((tenuto)    "-")
-           ((staccatissimo) "|")
-           ((accent) ">")
-           ((staccato) ".")
-           ((portato) "_")
-           (else #f))))
+         (shorthand
+          (case (string->symbol articulation)
+            ((marcato) "^")
+            ((stopped) "+")
+            ((tenuto)    "-")
+            ((staccatissimo) "!")
+            ((accent) ">")
+            ((staccato) ".")
+            ((portato) "_")
+            (else #f))))
     (format #f "~a~:[\\~;~]~a"
-           (event-direction->lily-string event shorthand)
-           shorthand
-           (or shorthand articulation))))
+            (event-direction->lily-string event shorthand)
+            shorthand
+            (or shorthand articulation))))
 
-(define-post-event-display-method FingeringEvent (event parser) #t
+(define-post-event-display-method FingeringEvent (event) #t
   (ly:music-property event 'digit))
 
-(define-post-event-display-method TextScriptEvent (event parser) #t
+(define-post-event-display-method TextScriptEvent (event) #t
   (markup->lily-string (ly:music-property event 'text)))
 
-(define-post-event-display-method MultiMeasureTextEvent (event parser) #t
+(define-post-event-display-method MultiMeasureTextEvent (event) #t
   (markup->lily-string (ly:music-property event 'text)))
 
-(define-post-event-display-method BendAfterEvent (event parser) #f
-  (format #f "\\bendAfter #~a" (ly:music-property event 'delta-step)))
+(define-post-event-display-method BendAfterEvent (event) #f
+  (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) #f "\\glissando")
-(define-post-event-display-method ArpeggioEvent (event parser) #f "\\arpeggio")
-(define-post-event-display-method AbsoluteDynamicEvent (event parser) #f
+(define-post-event-display-method HarmonicEvent (event) #f "\\harmonic")
+(define-post-event-display-method GlissandoEvent (event) #f "\\glissando")
+(define-post-event-display-method ArpeggioEvent (event) #f "\\arpeggio")
+(define-post-event-display-method AbsoluteDynamicEvent (event) #f
   (format #f "\\~a" (ly:music-property event 'text)))
 
-(define-post-event-display-method StrokeFingerEvent (event parser) #f
-  (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")
+(define-post-event-display-method StrokeFingerEvent (event) #f
+  (format #f "\\rightHandFinger #~a " (ly:music-property event 'digit)))
+
+(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 EpisemaEvent (event) #f "\\episemInitium" "\\episemFinis")
+(define-span-event-display-method PhrasingSlurEvent (event) #f "\\(" "\\)")
+(define-span-event-display-method SustainEvent (event) #f "\\sustainOn" "\\sustainOff")
+(define-span-event-display-method SostenutoEvent (event) #f "\\sostenutoOn" "\\sostenutoOff")
+(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")
 
 ;;;
 ;;; Graces
 ;;;
 
-(define-display-method GraceMusic (expr parser)
+(define-display-method GraceMusic (expr)
   (format #f "\\grace ~a"
-         (music->lily-string (ly:music-property expr 'element) parser)))
+          (music->lily-string (ly:music-property expr 'element))))
 
 ;; \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 parser)
+(define-extra-display-method GraceMusic (expr)
   "Display method for appoggiatura."
   (with-music-match (expr (music
-                          'GraceMusic
-                          element (music
-                                   'SequentialMusic
-                                   elements (?start
-                                             ?music
-                                             ?stop))))
-    ;; we check whether ?start and ?stop look like
-    ;; startAppoggiaturaMusic stopAppoggiaturaMusic
-    (and (with-music-match (?start (music
-                                   'SequentialMusic
-                                   elements ((music
-                                              'EventChord
-                                              elements
-                                              ((music
-                                                'SlurEvent
-                                                span-direction START))))))
-           #t)
-        (with-music-match (?stop (music
-                                  'SequentialMusic
-                                  elements ((music
-                                             'EventChord
-                                             elements
-                                             ((music
-                                               'SlurEvent
-                                               span-direction STOP))))))
-           (format #f "\\appoggiatura ~a" (music->lily-string ?music parser))))))
-
-
-(define-extra-display-method GraceMusic (expr parser)
+                           'GraceMusic
+                           element (music
+                                    'SequentialMusic
+                                    elements (?start
+                                              ?music
+                                              ?stop))))
+                    ;; we check whether ?start and ?stop look like
+                    ;; startAppoggiaturaMusic stopAppoggiaturaMusic
+                    (and (with-music-match (?start (music
+                                                    'SequentialMusic
+                                                    elements ((music
+                                                               'EventChord
+                                                               elements
+                                                               ((music
+                                                                 'SlurEvent
+                                                                 span-direction START))))))
+                                           #t)
+                         (with-music-match (?stop (music
+                                                   'SequentialMusic
+                                                   elements ((music
+                                                              'EventChord
+                                                              elements
+                                                              ((music
+                                                                'SlurEvent
+                                                                span-direction STOP))))))
+                                           (format #f "\\appoggiatura ~a" (music->lily-string ?music))))))
+
+
+(define-extra-display-method GraceMusic (expr)
   "Display method for acciaccatura."
   (with-music-match (expr (music
-                          'GraceMusic
-                          element (music
-                                   'SequentialMusic
-                                   elements (?start
-                                             ?music
-                                             ?stop))))
-    ;; we check whether ?start and ?stop look like
-    ;; startAcciaccaturaMusic stopAcciaccaturaMusic
-    (and (with-music-match (?start (music
-                                   'SequentialMusic
-                                   elements ((music
-                                              'EventChord
-                                              elements
-                                              ((music
-                                                'SlurEvent
-                                                span-direction START)))
-                                             (music
-                                              'ContextSpeccedMusic
-                                              element (music
-                                                       'OverrideProperty
-                                                       grob-property-path '(stroke-style)
-                                                       grob-value "grace"
-                                                       symbol 'Flag)))))
-          #t)
-        (with-music-match (?stop (music
-                                  'SequentialMusic
-                                  elements ((music
-                                             'ContextSpeccedMusic
-                                             element (music
-                                                      'RevertProperty
-                                                      grob-property-path '(stroke-style)
-                                                      symbol 'Flag))
-
-                                            (music
-                                             'EventChord
-                                             elements
-                                             ((music
-                                               'SlurEvent
-                                               span-direction STOP))))))
-          (format #f "\\acciaccatura ~a" (music->lily-string ?music parser))))))
-
-(define-extra-display-method GraceMusic (expr parser)
+                           'GraceMusic
+                           element (music
+                                    'SequentialMusic
+                                    elements (?start
+                                              ?music
+                                              ?stop))))
+                    ;; we check whether ?start and ?stop look like
+                    ;; startAcciaccaturaMusic stopAcciaccaturaMusic
+                    (and (with-music-match (?start (music
+                                                    'SequentialMusic
+                                                    elements ((music
+                                                               'EventChord
+                                                               elements
+                                                               ((music
+                                                                 'SlurEvent
+                                                                 span-direction START)))
+                                                              (music
+                                                               'ContextSpeccedMusic
+                                                               element (music
+                                                                        'OverrideProperty
+                                                                        grob-property-path '(stroke-style)
+                                                                        grob-value "grace"
+                                                                        symbol 'Flag)))))
+                                           #t)
+                         (with-music-match (?stop (music
+                                                   'SequentialMusic
+                                                   elements ((music
+                                                              'ContextSpeccedMusic
+                                                              element (music
+                                                                       'RevertProperty
+                                                                       grob-property-path '(stroke-style)
+                                                                       symbol 'Flag))
+
+                                                             (music
+                                                              'EventChord
+                                                              elements
+                                                              ((music
+                                                                'SlurEvent
+                                                                span-direction STOP))))))
+                                           (format #f "\\acciaccatura ~a" (music->lily-string ?music))))))
+
+(define-extra-display-method GraceMusic (expr)
   "Display method for grace."
   (with-music-match (expr (music
-                          'GraceMusic
-                          element (music
-                                   'SequentialMusic
-                                   elements (?start
-                                             ?music
-                                             ?stop))))
-    ;; we check whether ?start and ?stop look like
-    ;; startGraceMusic stopGraceMusic
-    (and (null? (ly:music-property ?start 'elements))
-        (null? (ly:music-property ?stop 'elements))
-        (format #f "\\grace ~a" (music->lily-string ?music parser)))))
+                           'GraceMusic
+                           element (music
+                                    'SequentialMusic
+                                    elements (?start
+                                              ?music
+                                              ?stop))))
+                    ;; we check whether ?start and ?stop look like
+                    ;; startGraceMusic stopGraceMusic
+                    (and (null? (ly:music-property ?start 'elements))
+                         (null? (ly:music-property ?stop 'elements))
+                         (format #f "\\grace ~a" (music->lily-string ?music)))))
 
 ;;;
 ;;; Music sequences
 ;;;
 
-(define-display-method SequentialMusic (seq parser)
+(define-display-method SequentialMusic (seq)
   (let ((force-line-break (and (*force-line-break*)
-                              ;; 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)))
+                               ;; 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_}"
-           (if (any (lambda (e)
-                      (or (cluster? e)
-                          (and (chord? e)
-                               (any cluster? (ly:music-property e 'elements)))))
-                    elements)
-               "\\makeClusters "
-               "")
-           (if (*explicit-mode*)
-               ;; if the sequence contains EventChord which contains figures ==> figuremode
-               ;; if the sequence contains EventChord which contains lyrics ==> lyricmode
-               ;; if the sequence contains EventChord which contains drum notes ==> drummode
-               (cond ((any (lambda (chord)
-                             (any (make-music-type-predicate 'BassFigureEvent)
-                                  (ly:music-property chord 'elements)))
-                           (filter chord? elements))
-                      "\\figuremode ")
-                     ((any (lambda (chord)
-                             (any (make-music-type-predicate 'LyricEvent)
-                                  (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)))))
-                                  (cons chord
-                                        (ly:music-property chord 'elements))))
-                           (filter note-or-chord? elements))
-                      "\\drummode ")
-                     (else ;; TODO: other modes?
-                      ""))
-               "")
-           (if force-line-break 1 0)
-           (if force-line-break (+ 2 (*indent*)) 1)
-           (parameterize ((*indent* (+ 2 (*indent*))))
-                         (map-in-order (lambda (music)
-                                         (music->lily-string music parser))
-                                       elements))
-           (if force-line-break 1 0)
-           (if force-line-break (*indent*) 1))))
-
-(define-display-method SimultaneousMusic (sim parser)
+            (if (any (lambda (e)
+                       (or (cluster? e)
+                           (and (chord? e)
+                                (any cluster? (ly:music-property e 'elements)))))
+                     elements)
+                "\\makeClusters "
+                "")
+            (if (*explicit-mode*)
+                ;; if the sequence contains EventChord which contains figures ==> figuremode
+                ;; if the sequence contains EventChord which contains lyrics ==> lyricmode
+                ;; if the sequence contains EventChord which contains drum notes ==> drummode
+                (cond ((any (lambda (chord)
+                              (any (make-music-type-predicate 'BassFigureEvent)
+                                   (ly:music-property chord 'elements)))
+                            (filter chord? elements))
+                       "\\figuremode ")
+                      ((any (lambda (chord)
+                              (any (make-music-type-predicate 'LyricEvent)
+                                   (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)))))
+                                   (cons chord
+                                         (ly:music-property chord 'elements))))
+                            (filter note-or-chord? elements))
+                       "\\drummode ")
+                      (else ;; TODO: other modes?
+                       ""))
+                "")
+            (if force-line-break 1 0)
+            (if force-line-break (+ 2 (*indent*)) 1)
+            (parameterize ((*indent* (+ 2 (*indent*))))
+                          (map-in-order (lambda (music)
+                                          (music->lily-string music))
+                                        elements))
+            (if force-line-break 1 0)
+            (if force-line-break (*indent*) 1))))
+
+(define-display-method SimultaneousMusic (sim)
   (parameterize ((*indent* (+ 3 (*indent*))))
-    (format #f "<< ~{~a ~}>>"
-           (map-in-order (lambda (music)
-                           (music->lily-string music parser))
-                         (ly:music-property sim 'elements)))))
-
-(define-extra-display-method SimultaneousMusic (expr parser)
-  "If `sim' is an \afterGrace expression, return \"\\afterGrace ...\".
-Otherwise, return #f."
-  ;; TODO: do something with afterGraceFraction?
-  (with-music-match (expr (music 'SimultaneousMusic
-                                elements (?before-grace
-                                          (music 'SequentialMusic
-                                                 elements ((music 'SkipMusic)
-                                                           (music 'GraceMusic
-                                                                  element ?grace))))))
-    (format #f "\\afterGrace ~a ~a"
-           (music->lily-string ?before-grace parser)
-           (music->lily-string ?grace parser))))
+                (format #f "<< ~{~a ~}>>"
+                        (map-in-order (lambda (music)
+                                        (music->lily-string music))
+                                      (ly:music-property sim 'elements)))))
 
 ;;;
 ;;; Chords
 ;;;
 
-(define-display-method EventChord (chord parser)
+(define-display-method EventChord (chord)
   ;; event_chord : command_element
-  ;;              | note_chord_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 (append (ly:music-property chord 'elements)
-                          (ly:music-property chord 'articulations)))
-        (chord-repeat (ly:music-property chord 'duration)))
+                           (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 ()
+          (partition (music-type-predicate '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)
+        (cond ((pair? chord-elements)
+               ;; note_chord_element :
+               ;; '<' (notepitch | drumpitch)* '>" duration post_events
+               (let ((duration (duration->lily-string (ly:music-property
+                                                       (car chord-elements)
+                                                       'duration))))
+                 ;; Format duration first so that it does not appear on
+                 ;; chord elements
+                 (format #f "< ~{~a ~}>~a~:{~:[-~;~]~a~^ ~}"
+                         (parameterize ((*omit-duration* #t))
+                                       (map-in-order
+                                        (lambda (music)
+                                          (music->lily-string music))
+                                        chord-elements))
+                         duration
+                         (map-in-order (lambda (music)
+                                         (list
+                                          (post-event? music)
+                                          (music->lily-string music)))
+                                       other-elements))))
+              ((ly:duration? chord-repeat)
+               (let ((duration (duration->lily-string chord-repeat)))
+                 (format #f "q~a~:{~:[-~;~]~a~^ ~}"
+                         duration
+                         (map-in-order (lambda (music)
+                                         (list
+                                          (post-event? music)
+                                          (music->lily-string music)))
+                                       other-elements))))
+
+              ((and (= 1 (length other-elements))
+                    (not (post-event? (car other-elements))))
+               (format #f (music->lily-string (car other-elements))))
+              (else
+               (format #f "< >~:{~:[-~;~]~a~^ ~}"
+                       (map-in-order (lambda (music)
+                                       (list
+                                        (post-event? music)
+                                        (music->lily-string music)))
+                                     other-elements))))))))
+
+(define-display-method MultiMeasureRestMusic (mmrest)
   (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))))
+          (duration->lily-string (ly:music-property mmrest 'duration))
+          (map-in-order (lambda (music)
+                          (music->lily-string music))
+                        (ly:music-property mmrest 'articulations))))
 
-(define-display-method SkipMusic (skip parser)
+(define-display-method SkipMusic (skip)
   (format #f "\\skip ~a" (duration->lily-string (ly:music-property skip 'duration) #:force-duration #t)))
 
-(define-display-method OttavaMusic (ottava parser)
+(define-display-method OttavaMusic (ottava)
   (format #f "\\ottava #~a" (ly:music-property ottava 'ottava-number)))
 
 ;;;
 ;;; Notes, rests, skips...
 ;;;
 
-(define (simple-note->lily-string event parser)
+(define (simple-note->lily-string event)
   (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)))
-           (cond ((and (not (null? forced))
-                       forced
-                       (not (null? cautionary))
-                       cautionary)
-                  "?")
-                 ((and (not (null? forced)) forced) "!")
-                 (else "")))
-         (let ((octave-check (ly:music-property event 'absolute-octave)))
-           (if (not (null? octave-check))
-               (format #f "=~a" (cond ((>= octave-check 0)
-                                       (make-string (1+ octave-check) #\'))
-                                      ((< octave-check -1)
-                                       (make-string (1- (* -1 octave-check)) #\,))
-                                      (else "")))
-               ""))
-         (duration->lily-string (ly:music-property event 'duration)
-                                #:remember #t)
-         (if ((make-music-type-predicate 'RestEvent) event)
-             "\\rest" "")
-         (map-in-order (lambda (event)
-                         (list
-                          (post-event? event)
-                          (music->lily-string event parser)))
-                       (ly:music-property event 'articulations))))
-
-(define-display-method NoteEvent (note parser)
+          (note-name->lily-string (ly:music-property event 'pitch))
+          (octave->lily-string (ly:music-property event 'pitch))
+          (let ((forced (ly:music-property event 'force-accidental))
+                (cautionary (ly:music-property event 'cautionary)))
+            (cond ((and (not (null? forced))
+                        forced
+                        (not (null? cautionary))
+                        cautionary)
+                   "?")
+                  ((and (not (null? forced)) forced) "!")
+                  (else "")))
+          (let ((octave-check (ly:music-property event 'absolute-octave)))
+            (if (not (null? octave-check))
+                (format #f "=~a" (cond ((>= octave-check 0)
+                                        (make-string (1+ octave-check) #\'))
+                                       ((< octave-check -1)
+                                        (make-string (1- (* -1 octave-check)) #\,))
+                                       (else "")))
+                ""))
+          (duration->lily-string (ly:music-property event 'duration))
+          (if ((make-music-type-predicate 'RestEvent) event)
+              "\\rest" "")
+          (map-in-order (lambda (event)
+                          (list
+                           (post-event? event)
+                           (music->lily-string event)))
+                        (ly:music-property event 'articulations))))
+
+(define-display-method NoteEvent (note)
   (cond ((not (null? (ly:music-property note 'pitch))) ;; note
-        (simple-note->lily-string note parser))
-       ((not (null? (ly:music-property note 'drum-type))) ;; drum
-        (format #f "~a~a~{~a~}" (ly:music-property note 'drum-type)
-                (duration->lily-string (ly:music-property note 'duration)
-                                       #:remember #t)
-                (map-in-order (lambda (event)
-                                (music->lily-string event parser))
-                              (ly:music-property note 'articulations))))
-       (else ;; unknown?
-        "")))
-
-(define-display-method ClusterNoteEvent (note parser)
-  (simple-note->lily-string note parser))
-
-(define-display-method RestEvent (rest parser)
+         (simple-note->lily-string note))
+        ((not (null? (ly:music-property note 'drum-type))) ;; drum
+         (format #f "~a~a~{~a~}" (ly:music-property note 'drum-type)
+                 (duration->lily-string (ly:music-property note 'duration))
+                 (map-in-order (lambda (event)
+                                 (music->lily-string event))
+                               (ly:music-property note 'articulations))))
+        (else
+         ;; pure duration
+         (format #f "~a~{~a~}"
+                 (duration->lily-string (ly:music-property note 'duration)
+                                        #:force-duration #t)
+                 (map-in-order (lambda (event)
+                                 (music->lily-string event))
+                               (ly:music-property note 'articulations))))))
+
+(define-display-method ClusterNoteEvent (note)
+  (simple-note->lily-string note))
+
+(define-display-method RestEvent (rest)
   (if (not (null? (ly:music-property rest 'pitch)))
-      (simple-note->lily-string rest parser)
+      (simple-note->lily-string rest)
       (format #f "r~a~{~a~}"
-             (duration->lily-string (ly:music-property rest 'duration)
-                                    #:remember #t)
-             (map-in-order (lambda (event)
-                             (music->lily-string event parser))
-                           (ly:music-property rest 'articulations)))))
+              (duration->lily-string (ly:music-property rest 'duration))
+              (map-in-order (lambda (event)
+                              (music->lily-string event))
+                            (ly:music-property rest 'articulations)))))
 
-(define-display-method MultiMeasureRestEvent (rest parser)
-  (string-append "R" (duration->lily-string (ly:music-property rest 'duration)
-                                           #:remember #t)))
+(define-display-method MultiMeasureRestEvent (rest)
+  (string-append "R" (duration->lily-string (ly:music-property rest 'duration))))
 
-(define-display-method SkipEvent (rest parser)
+(define-display-method SkipEvent (rest)
   (format #f "s~a~{~a~}"
-         (duration->lily-string (ly:music-property rest 'duration)
-                                #:remember #t)
-         (map-in-order (lambda (event)
-                         (music->lily-string event parser))
-                       (ly:music-property rest 'articulations))))
-
-(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 KeyChangeEvent (key parser)
+          (duration->lily-string (ly:music-property rest 'duration))
+          (map-in-order (lambda (event)
+                          (music->lily-string event))
+                        (ly:music-property rest 'articulations))))
+
+(define-display-method RepeatedChord (chord)
+  (music->lily-string (ly:music-property chord 'element)))
+
+(define-display-method MarkEvent (mark)
+  (let ((label (ly:music-property mark 'label #f)))
+    (string-append "\\mark "
+                   (if label (value->lily-string label) "\\default"))))
+
+(define-display-method KeyChangeEvent (key)
   (let ((pitch-alist (ly:music-property key 'pitch-alist))
-       (tonic (ly:music-property key 'tonic)))
+        (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
-                                                    (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) parser)
-                 (any (lambda (mode)
-                        (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 parser)
+            (null? tonic))
+        "\\key \\default"
+        (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))
+                  (any (lambda (mode)
+                         (and (equal? (ly:parser-lookup mode) c-pitch-alist)
+                              (symbol->string mode)))
+                       '(major minor ionian locrian aeolian mixolydian lydian phrygian dorian))
+                  (new-line->lily-string))))))
+
+(define-display-method RelativeOctaveCheck (octave)
   (let ((pitch (ly:music-property octave 'pitch)))
     (format #f "\\octaveCheck ~a~a"
-           (note-name->lily-string pitch parser)
-           (octave->lily-string pitch))))
+            (note-name->lily-string pitch)
+            (octave->lily-string pitch))))
 
-(define-display-method VoiceSeparator (sep parser)
+(define-display-method VoiceSeparator (sep)
   "\\\\")
 
-(define-display-method LigatureEvent (ligature parser)
+(define-display-method LigatureEvent (ligature)
   (if (= START (ly:music-property ligature 'span-direction))
       "\\["
       "\\]"))
 
-(define-display-method BarCheck (check parser)
+(define-display-method BarCheck (check)
   (format #f "|~a" (new-line->lily-string)))
 
-(define-display-method PesOrFlexaEvent (expr parser)
+(define-display-method PesOrFlexaEvent (expr)
   "\\~")
 
-(define-display-method BassFigureEvent (figure parser)
+(define-display-method BassFigureEvent (figure)
   (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)))
+        (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) "_")
-                 ((markup? fig) (second fig)) ;; fig: (<number-markup> "number")
-                 (else fig))
-           (if (null? alteration)
-               ""
-               (cond
-                 ((= alteration DOUBLE-FLAT) "--")
-                 ((= alteration FLAT) "-")
-                 ((= alteration NATURAL) "!")
-                 ((= alteration SHARP) "+")
-                 ((= alteration DOUBLE-SHARP) "++")
-                 (else "")))
-           (if (null? bracket-stop) "" "]"))))
-
-(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)
+            (if (null? bracket-start) "" "[")
+            (cond ((null? fig) "_")
+                  ((markup? fig) (second fig)) ;; fig: (<number-markup> "number")
+                  (else fig))
+            (if (null? alteration)
+                ""
+                (cond
+                 ((= alteration DOUBLE-FLAT) "--")
+                 ((= alteration FLAT) "-")
+                 ((= alteration NATURAL) "!")
+                 ((= alteration SHARP) "+")
+                 ((= alteration DOUBLE-SHARP) "++")
+                 (else "")))
+            (if (null? bracket-stop) "" "]"))))
+
+(define-display-method LyricEvent (lyric)
+  (format #f "~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 music->lily-string
+                        (ly:music-property lyric 'articulations))))
+
+(define-display-method BreathingEvent (event)
   "\\breathe")
 
 ;;;
 ;;; Staff switches
 ;;;
 
-(define-display-method AutoChangeMusic (m parser)
+(define-display-method AutoChangeMusic (m)
   (format #f "\\autochange ~a"
-         (music->lily-string (ly:music-property m 'element) parser)))
+          (music->lily-string
+           (ly:music-property (ly:music-property m 'element) 'element))))
 
-(define-display-method ContextChange (m parser)
+(define-display-method ContextChange (m)
   (format #f "\\change ~a = \"~a\""
-         (ly:music-property m 'change-to-type)
-         (ly:music-property m 'change-to-id)))
+          (ly:music-property m 'change-to-type)
+          (ly:music-property m 'change-to-id)))
 
 ;;;
 
-(define-display-method TimeScaledMusic (times parser)
+(define-display-method TimeScaledMusic (times)
   (let* ((num (ly:music-property times 'numerator))
-        (den (ly:music-property times 'denominator))
-        (scale (/ num den))
-        (dur (*previous-duration*))
-        (time-scale (*time-scale*)))
-
-    (parameterize ((*force-line-break* #f)
-                  (*previous-duration*
-                   (ly:make-duration (ly:duration-log dur)
-                                     (ly:duration-dot-count dur)
-                                     (* (ly:duration-scale dur)
-                                        scale)))
-                  (*time-scale* (* time-scale scale)))
-      (format #f "\\times ~a/~a ~a"
-             num
-             den
-             (music->lily-string (ly:music-property times 'element) parser)))))
-
-(define-display-method RelativeOctaveMusic (m parser)
-  (music->lily-string (ly:music-property m 'element) parser))
-
-(define-display-method TransposedMusic (m parser)
-  (music->lily-string (ly:music-property m 'element) parser))
+         (den (ly:music-property times 'denominator))
+         (span (ly:music-property times 'duration #f))
+         ;; need to format before changing time scale
+         (formatted-span
+          (and span (duration->lily-string span #:force-duration #t)))
+         (scale (/ num den))
+         (time-scale (*time-scale*)))
+    (let ((result
+           (parameterize ((*force-line-break* #f)
+                          (*time-scale* (* time-scale scale)))
+                         (format #f "\\tuplet ~a/~a ~@[~a ~]~a"
+                                 den
+                                 num
+                                 formatted-span
+                                 (music->lily-string (ly:music-property times 'element))))))
+      result)))
+
+(define-display-method RelativeOctaveMusic (m)
+  (music->lily-string (ly:music-property m 'element)))
+
+(define-display-method TransposedMusic (m)
+  (music->lily-string (ly:music-property m 'element)))
 
 ;;;
 ;;; Repeats
 ;;;
 
-(define-display-method AlternativeEvent (alternative parser) "")
+(define-display-method AlternativeEvent (alternative) "")
 
-(define (repeat->lily-string expr repeat-type parser)
-  (let* ((main (music->lily-string (ly:music-property expr 'element) parser)))
+(define (repeat->lily-string expr repeat-type)
+  (let* ((main (music->lily-string (ly:music-property expr 'element))))
     (format #f "\\repeat ~a ~a ~a ~a"
-           repeat-type
-           (ly:music-property expr 'repeat-count)
-           main
-           (let ((alternatives (ly:music-property expr 'elements)))
-             (if (null? alternatives)
-                 ""
-                 (format #f "\\alternative { ~{~a ~}}"
-                         (map-in-order (lambda (music)
-                                         (music->lily-string music parser))
-                                       alternatives)))))))
-
-(define-display-method VoltaRepeatedMusic (expr parser)
-  (repeat->lily-string expr "volta" parser))
-
-(define-display-method UnfoldedRepeatedMusic (expr parser)
-  (repeat->lily-string expr "unfold" parser))
-
-(define-display-method PercentRepeatedMusic (expr parser)
-  (repeat->lily-string expr "percent" parser))
-
-(define-display-method TremoloRepeatedMusic (expr parser)
-  (let* ((main (ly:music-property expr 'element))
-        (children (if (music-is-of-type? main 'sequential-music)
-                      ;; \repeat tremolo n { ... }
-                      (length (extract-named-music main '(EventChord
-                                                          NoteEvent)))
-                      ;; \repeat tremolo n c4
-                      1))
-        (times (ly:music-property expr 'repeat-count))
-
-        ;; # of dots is equal to the 1 in bitwise representation (minus 1)!
-        (dots (1- (logcount (* times children))))
-        ;; The remaining missing multiplicator to scale the notes by
-        ;; times * children
-        (mult (/ (* times children (ash 1 dots)) (1- (ash 2 dots))))
-        (shift (- (ly:intlog2 (floor mult)))))
-    (set! main (ly:music-deep-copy main))
-    ;; Adjust the time of the notes
-    (ly:music-compress main (ly:make-moment children 1))
-    ;; Adjust the displayed note durations
-    (shift-duration-log main (- shift) (- dots))
-    (format #f "\\repeat tremolo ~a ~a"
-           times
-           (music->lily-string main parser))))
+            repeat-type
+            (ly:music-property expr 'repeat-count)
+            main
+            (let ((alternatives (ly:music-property expr 'elements)))
+              (if (null? alternatives)
+                  ""
+                  (format #f "\\alternative { ~{~a ~}}"
+                          (map-in-order (lambda (music)
+                                          (music->lily-string music))
+                                        alternatives)))))))
+
+(define-display-method VoltaRepeatedMusic (expr)
+  (repeat->lily-string expr "volta"))
+
+(define-display-method UnfoldedRepeatedMusic (expr)
+  (repeat->lily-string expr "unfold"))
+
+(define-display-method PercentRepeatedMusic (expr)
+  (repeat->lily-string expr "percent"))
+
+(define-display-method TremoloRepeatedMusic (expr)
+  (repeat->lily-string expr "tremolo"))
 
 ;;;
 ;;; Contexts
 ;;;
 
-(define-display-method ContextSpeccedMusic (expr parser)
+(define-display-method ContextSpeccedMusic (expr)
   (let ((id    (ly:music-property expr 'context-id))
-       (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)))
+        (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)))
     (format #f "~a ~a~a~a ~a"
-           (if (and (not (null? create-new)) create-new)
-               "\\new"
-               "\\context")
-           ctype
-           (if (null? id)
-               ""
-               (format #f " = ~s" id))
-           (if (null? operations)
-               ""
-               (format #f " \\with {~{~a~}~%~v_}"
-                       (parameterize ((*indent* (+ (*indent*) 2)))
-                         (map (lambda (op)
-                                (format #f "~%~v_\\~a ~s"
-                                        (*indent*)
-                                        (first op)
-                                        (second op)))
-                              operations))
-                       (*indent*)))
-           (parameterize ((*current-context* ctype))
-             (music->lily-string music parser)))))
+            (if (and (not (null? create-new)) create-new)
+                "\\new"
+                "\\context")
+            ctype
+            (if (null? id)
+                ""
+                (format #f " = ~s" id))
+            (if (null? operations)
+                ""
+                (format #f " \\with {~{~a~}~%~v_}"
+                        (parameterize ((*indent* (+ (*indent*) 2)))
+                                      (map (lambda (op)
+                                             (format #f "~%~v_\\~a ~s"
+                                                     (*indent*)
+                                                     (first op)
+                                                     (second op)))
+                                           operations))
+                        (*indent*)))
+            (parameterize ((*current-context* ctype))
+                          (music->lily-string music)))))
+
+;; \afterGrace
+(define-extra-display-method ContextSpeccedMusic (expr)
+  "If `sim' is an \afterGrace expression, return \"\\afterGrace ...\".
+Otherwise, return #f."
+  ;; TODO: do something with afterGraceFraction?
+  (with-music-match
+   (expr (music 'ContextSpeccedMusic
+                context-type 'Bottom
+                element
+                (music 'SimultaneousMusic
+                       elements (?before-grace
+                                 (music 'SequentialMusic
+                                        elements ((music 'SkipMusic)
+                                                  (music 'GraceMusic
+                                                         element ?grace)))))))
+   (format #f "\\afterGrace ~a ~a"
+           (music->lily-string ?before-grace)
+            (music->lily-string ?grace))))
+
 
 ;; special cases: \figures \lyrics \drums
-(define-extra-display-method ContextSpeccedMusic (expr parser)
+(define-extra-display-method ContextSpeccedMusic (expr)
   (with-music-match (expr (music 'ContextSpeccedMusic
-                                create-new #t
-                                property-operations ?op
-                                context-type ?context-type
-                                element ?sequence))
-    (if (null? ?op)
-       (parameterize ((*explicit-mode* #f))
-         (case ?context-type
-           ((FiguredBass)
-            (format #f "\\figures ~a" (music->lily-string ?sequence parser)))
-           ((Lyrics)
-            (format #f "\\lyrics ~a" (music->lily-string ?sequence parser)))
-           ((DrumStaff)
-            (format #f "\\drums ~a" (music->lily-string ?sequence parser)))
-           (else
-            #f)))
-       #f)))
+                                 create-new #t
+                                 property-operations ?op
+                                 context-type ?context-type
+                                 element ?sequence))
+                    (if (null? ?op)
+                        (parameterize ((*explicit-mode* #f))
+                                      (case ?context-type
+                                        ((FiguredBass)
+                                         (format #f "\\figures ~a" (music->lily-string ?sequence)))
+                                        ((Lyrics)
+                                         (format #f "\\lyrics ~a" (music->lily-string ?sequence)))
+                                        ((DrumStaff)
+                                         (format #f "\\drums ~a" (music->lily-string ?sequence)))
+                                        (else
+                                         #f)))
+                        #f)))
 
 ;;; Context properties
 
-(define-extra-display-method ContextSpeccedMusic (expr parser)
+(define-extra-display-method ContextSpeccedMusic (expr)
   (let ((element (ly:music-property expr 'element))
-       (property-tuning? (make-music-type-predicate 'PropertySet
-                                                    'PropertyUnset
-                                                    'OverrideProperty
-                                                    'RevertProperty))
-       (sequence? (make-music-type-predicate 'SequentialMusic)))
+        (property-tuning? (make-music-type-predicate 'PropertySet
+                                                     'PropertyUnset
+                                                     'OverrideProperty
+                                                     'RevertProperty))
+        (sequence? (make-music-type-predicate 'SequentialMusic)))
     (if (and (ly:music? element)
-            (or (property-tuning? element)
-                (and (sequence? element)
-                     (every property-tuning? (ly:music-property element 'elements)))))
-       (parameterize ((*current-context* (ly:music-property expr 'context-type)))
-         (music->lily-string element parser))
-       #f)))
-
-(define (property-value->lily-string arg parser)
+             (or (property-tuning? element)
+                 (and (sequence? element)
+                      (every property-tuning? (ly:music-property element 'elements)))))
+        (parameterize ((*current-context* (ly:music-property expr 'context-type)))
+                      (music->lily-string element))
+        #f)))
+
+(define-public (value->lily-string arg)
   (cond ((ly:music? arg)
-        (music->lily-string arg parser))
-       ((string? arg)
-        (format #f "#~s" arg))
-       ((markup? arg)
-        (markup->lily-string arg))
-       (else
-        (format #f "#~a" (scheme-expr->lily-string arg)))))
-
-(define-display-method PropertySet (expr parser)
+         (music->lily-string arg))
+        ((markup? arg)
+         (markup->lily-string arg))
+        ((ly:duration? arg)
+         (format #f "##{ ~a #}" (duration->lily-string arg #:force-duration #t)))
+        ((ly:pitch? arg)
+         (format #f "~a~a"
+                 (note-name->lily-string arg)
+                 (octave->lily-string arg)))
+        (else
+         (format #f "#~a" (scheme-expr->lily-string arg)))))
+
+(define-display-method PropertySet (expr)
   (let ((property (ly:music-property expr 'symbol))
-       (value (ly:music-property expr 'value))
-       (once (ly:music-property expr 'once)))
+        (value (ly:music-property expr 'value))
+        (once (ly:music-property expr 'once)))
     (format #f "~a\\set ~a~a = ~a~a"
-           (if (and (not (null? once)))
-               "\\once "
-               "")
-           (if (eqv? (*current-context*) 'Bottom)
-               ""
-               (format #f "~a . " (*current-context*)))
-           property
-           (property-value->lily-string value parser)
-           (new-line->lily-string))))
-
-(define-display-method PropertyUnset (expr parser)
-  (format #f "\\unset ~a~a~a"
-         (if (eqv? (*current-context*) 'Bottom)
-             ""
-             (format #f "~a . " (*current-context*)))
-         (ly:music-property expr 'symbol)
-         (new-line->lily-string)))
+            (if (and (not (null? once)))
+                "\\once "
+                "")
+            (if (eq? (*current-context*) 'Bottom)
+                ""
+                (format #f "~a." (*current-context*)))
+            property
+            (value->lily-string value)
+            (new-line->lily-string))))
+
+(define-display-method PropertyUnset (expr)
+  (format #f "~a\\unset ~a~a~a"
+          (if (ly:music-property expr 'once #f) "\\once " "")
+          (if (eq? (*current-context*) 'Bottom)
+              ""
+              (format #f "~a." (*current-context*)))
+          (ly:music-property expr 'symbol)
+          (new-line->lily-string)))
 
 ;;; Layout properties
 
-(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)))
+(define-display-method OverrideProperty (expr)
+  (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"
-           (if (or (null? once)
-                   (not once))
-               ""
-               "\\once ")
+            (if (or (null? once)
+                    (not once))
+                ""
+                "\\once ")
             (if (eqv? (*current-context*) 'Bottom)
                 (cons symbol properties)
                 (cons* (*current-context*) symbol properties))
-            (property-value->lily-string value parser)
-           (new-line->lily-string))))
+            (value->lily-string value)
+            (new-line->lily-string))))
 
-(define-display-method RevertProperty (expr parser)
+(define-display-method RevertProperty (expr)
   (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"
+                                        (list (ly:music-property expr
+                                                                 'grob-property))))
+         (once (ly:music-property expr 'once #f)))
+    (format #f "~a\\revert ~{~a~^.~}~a"
+            (if once "\\once " "")
             (if (eqv? (*current-context*) 'Bottom)
                 (cons symbol properties)
                 (cons* (*current-context*) symbol properties))
-           (new-line->lily-string))))
+            (new-line->lily-string))))
 
-(define-display-method TimeSignatureMusic (expr parser)
+(define-display-method TimeSignatureMusic (expr)
   (let* ((num (ly:music-property expr 'numerator))
          (den (ly:music-property expr 'denominator))
          (structure (ly:music-property expr 'beat-structure)))
@@ -879,51 +862,55 @@ Otherwise, return #f."
                 num den
                 (new-line->lily-string))
         (format #f
-                "\\time #'~a ~a/~a~a" 
+                ;; This is silly but the latter will also work for #f
+                ;; and other
+                (if (key-list? structure)
+                    "\\time ~{~a~^,~} ~a/~a~a"
+                    "\\time #'~a ~a/~a~a")
                 structure num den
                 (new-line->lily-string)))))
 
 ;;; \melisma and \melismaEnd
-(define-extra-display-method ContextSpeccedMusic (expr parser)
+(define-extra-display-method ContextSpeccedMusic (expr)
   "If expr is a melisma, return \"\\melisma\", otherwise, return #f."
   (with-music-match (expr (music 'ContextSpeccedMusic
-                                element (music 'PropertySet
-                                               value #t
-                                               symbol 'melismaBusy)))
-    "\\melisma"))
+                                 element (music 'PropertySet
+                                                value #t
+                                                symbol 'melismaBusy)))
+                    "\\melisma"))
 
-(define-extra-display-method ContextSpeccedMusic (expr parser)
+(define-extra-display-method ContextSpeccedMusic (expr)
   "If expr is a melisma end, return \"\\melismaEnd\", otherwise, return #f."
   (with-music-match (expr (music 'ContextSpeccedMusic
-                                element (music 'PropertyUnset
-                                               symbol 'melismaBusy)))
-    "\\melismaEnd"))
+                                 element (music 'PropertyUnset
+                                                symbol 'melismaBusy)))
+                    "\\melismaEnd"))
 
 ;;; \tempo
-(define-extra-display-method SequentialMusic (expr parser)
+(define-extra-display-method SequentialMusic (expr)
   (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)
+                                 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)
   (let ((text (ly:music-property expr 'text)))
     (format #f "\\tempo ~a~a"
-           (markup->lily-string text)
-           (new-line->lily-string))))
+            (markup->lily-string text)
+            (new-line->lily-string))))
 
 ;;; \clef
 (define clef-name-alist #f)
@@ -936,200 +923,246 @@ Otherwise, return #f."
                          (car name+vals)))
                  clefs))))
 
-(define-extra-display-method ContextSpeccedMusic (expr parser)
+(define-extra-display-method ContextSpeccedMusic (expr)
   "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
-                                               elements ((music 'PropertySet
-                                                                value ?clef-glyph
-                                                                symbol 'clefGlyph)
-                                                         (music 'PropertySet
-                                                                symbol 'middleCClefPosition)
-                                                         (music 'PropertySet
-                                                                value ?clef-position
-                                                                symbol 'clefPosition)
-                                                         (music 'PropertySet
-                                                                value ?clef-octavation
-                                                                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"
-                 clef-name
-                 (cond ((= 0 ?clef-octavation)
-                        (list "" ""))
-                       ((> ?clef-octavation 0)
-                        (list "^" (1+ ?clef-octavation)))
-                       (else
-                        (list "_" (- 1 ?clef-octavation))))
-                 (new-line->lily-string))
-         #f))))
+                                 context-type 'Staff
+                                 element (music 'SequentialMusic
+                                                elements ((music 'PropertySet
+                                                                 value ?clef-glyph
+                                                                 symbol 'clefGlyph)
+                                                          (music 'PropertySet
+                                                                 symbol 'middleCClefPosition)
+                                                          (music 'PropertySet
+                                                                 value ?clef-position
+                                                                 symbol 'clefPosition)
+                                                          (music 'PropertySet
+                                                                 value ?clef-transposition
+                                                                 symbol 'clefTransposition)
+                                                          (music 'PropertySet
+                                                                 value ?clef-transposition-style
+                                                                 symbol 'clefTranspositionStyle)
+                                                          (music 'ApplyContext
+                                                                 procedure ly:set-middle-C!)))))
+                    (let ((clef-name (assoc-get (list ?clef-glyph ?clef-position 0)
+                                                clef-name-alist)))
+                      (and clef-name
+                           (format #f "\\clef \"~a~?\"~a"
+                                   clef-name
+                                   (case ?clef-transposition-style
+                                     ((parenthesized) "~a(~a)")
+                                     ((bracketed) "~a[~a]")
+                                     (else "~a~a"))
+                                   (cond ((zero? ?clef-transposition)
+                                          (list "" ""))
+                                         ((positive? ?clef-transposition)
+                                          (list "^" (1+ ?clef-transposition)))
+                                         (else (list "_" (- 1 ?clef-transposition))))
+                                   (new-line->lily-string))))))
 
 ;;; \bar
-(define-extra-display-method ContextSpeccedMusic (expr parser)
+(define-extra-display-method ContextSpeccedMusic (expr)
   "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-extra-display-method ContextSpeccedMusic (expr parser)
+(define-extra-display-method ContextSpeccedMusic (expr)
   "If `expr' is a partial measure, return \"\\partial ...\".
 Otherwise, return #f."
   (with-music-match (expr (music
-                          'ContextSpeccedMusic
-                          element (music
-                                   'ContextSpeccedMusic
-                                   context-type 'Timing
-                                   element (music
-                                            'PartialSet
-                                            partial-duration ?duration))))
-
-    (and ?duration
-        (format #f "\\partial ~a"
-                (duration->lily-string ?duration #:force-duration #t)))))
+                           'ContextSpeccedMusic
+                           element (music
+                                    'ContextSpeccedMusic
+                                    context-type 'Timing
+                                    element (music
+                                             'PartialSet
+                                             duration ?duration))))
+
+                    (and ?duration
+                         (format #f "\\partial ~a"
+                                 (duration->lily-string ?duration #:force-duration #t)))))
 
 ;;;
 ;;;
 
-(define-display-method ApplyOutputEvent (applyoutput parser)
+(define-display-method ApplyOutputEvent (applyoutput)
   (let ((proc (ly:music-property applyoutput 'procedure))
-       (ctx  (ly:music-property applyoutput 'context-type)))
-    (format #f "\\applyOutput #'~a #~a"
-           ctx
-           (or (procedure-name proc)
-               (with-output-to-string
-                 (lambda ()
-                   (pretty-print (procedure-source proc))))))))
-
-(define-display-method ApplyContext (applycontext parser)
+        (ctx  (ly:music-property applyoutput 'context-type))
+        (grob (ly:music-property applyoutput 'symbol)))
+    (format #f "\\applyOutput ~a~@[.~a~] #~a"
+            ctx
+            (and (symbol? grob) grob)
+            (or (procedure-name proc)
+                (with-output-to-string
+                  (lambda ()
+                    (pretty-print (procedure-source proc))))))))
+
+(define-display-method ApplyContext (applycontext)
   (let ((proc (ly:music-property applycontext 'procedure)))
     (format #f "\\applyContext #~a"
-           (or (procedure-name proc)
-               (with-output-to-string
-                 (lambda ()
-                   (pretty-print (procedure-source proc))))))))
+            (or (procedure-name proc)
+                (with-output-to-string
+                  (lambda ()
+                    (pretty-print (procedure-source proc))))))))
 
 ;;; \partcombine
-(define-display-method PartCombineMusic (expr parser)
-  (format #f "\\partcombine ~{~a ~}"
-         (map-in-order (lambda (music)
-                         (music->lily-string music parser))
-                       (ly:music-property expr 'elements))))
-
-(define-extra-display-method PartCombineMusic (expr parser)
-  (with-music-match (expr (music 'PartCombineMusic
-                                elements ((music 'UnrelativableMusic
-                                                 element (music 'ContextSpeccedMusic
-                                                                context-id "one"
-                                                                context-type 'Voice
-                                                                element ?sequence1))
-                                          (music 'UnrelativableMusic
-                                                 element (music 'ContextSpeccedMusic
-                                                                context-id "two"
-                                                                context-type 'Voice
-                                                                element ?sequence2)))))
-    (format #f "\\partcombine ~a~a~a"
-           (music->lily-string ?sequence1 parser)
-           (new-line->lily-string)
-           (music->lily-string ?sequence2 parser))))
-
-(define-display-method UnrelativableMusic (expr parser)
-  (music->lily-string (ly:music-property expr 'element) parser))
+(define-display-method PartCombineMusic (expr)
+  (let ((dir (ly:music-property expr 'direction)))
+    (format #f "\\partcombine~a ~a~a~a"
+            (cond ((equal? dir UP) "Up")
+                  ((equal? dir DOWN) "Down")
+                  (else ""))
+            (music->lily-string (car (ly:music-property expr 'elements)))
+            (new-line->lily-string)
+            (music->lily-string (cadr (ly:music-property expr 'elements))))))
+
+(define-display-method PartCombinePartMusic (expr)
+  (with-music-match ((ly:music-property expr 'element)
+                     (music 'ContextSpeccedMusic element ?part))
+                    (format #f "~a" (music->lily-string ?part))))
+
+(define-extra-display-method ContextSpeccedMusic (expr)
+  "If `expr' is a \\partcombine expression, return \"\\partcombine ...\".
+Otherwise, return #f."
+  (with-music-match
+   (expr (music 'ContextSpeccedMusic
+                context-type 'Staff
+                element (music 'SimultaneousMusic
+                               elements ((music 'ContextSpeccedMusic
+                                                context-id "one"
+                                                context-type 'Voice)
+                                         (music 'ContextSpeccedMusic
+                                                context-id "two"
+                                                context-type 'Voice)
+                                         (music 'ContextSpeccedMusic
+                                                context-id "shared"
+                                                context-type 'Voice)
+                                         (music 'ContextSpeccedMusic
+                                                context-id "solo"
+                                                context-type 'Voice)
+                                         (music 'ContextSpeccedMusic
+                                                context-id "null"
+                                                context-type 'NullVoice)
+                                         ?pc-music
+                                         ?pc-marks))))
+   (with-music-match
+    (?pc-music (music 'PartCombineMusic))
+    (format #f "~a" (music->lily-string ?pc-music)))))
+
+(define-display-method UnrelativableMusic (expr)
+  (music->lily-string (ly:music-property expr 'element)))
 
 ;;; Cue notes
-(define-display-method QuoteMusic (expr parser)
+(define-display-method QuoteMusic (expr)
   (or (with-music-match (expr (music
-                              'QuoteMusic
-                              quoted-voice-direction ?quoted-voice-direction
-                              quoted-music-name ?quoted-music-name
-                              quoted-context-id "cue"
-                              quoted-context-type 'Voice
-                              element ?music))
-       (format #f "\\cueDuring #~s #~a ~a"
-               ?quoted-music-name
-               ?quoted-voice-direction
-               (music->lily-string ?music parser)))
+                               'QuoteMusic
+                               quoted-voice-direction ?quoted-voice-direction
+                               quoted-music-name ?quoted-music-name
+                               quoted-context-id "cue"
+                               quoted-context-type 'CueVoice
+                               element ?music))
+                        (format #f "\\cueDuring #~s #~a ~a"
+                                ?quoted-music-name
+                                ?quoted-voice-direction
+                                (music->lily-string ?music)))
       (format #f "\\quoteDuring #~s ~a"
-             (ly:music-property expr 'quoted-music-name)
-             (music->lily-string (ly:music-property expr 'element) parser))))
+              (ly:music-property expr 'quoted-music-name)
+              (music->lily-string (ly:music-property expr 'element)))))
 
 ;;;
 ;;; Breaks
 ;;;
-(define-display-method LineBreakEvent (expr parser)
+(define-display-method LineBreakEvent (expr)
   (if (null? (ly:music-property expr 'break-permission))
       "\\noBreak"
       "\\break"))
 
-(define-display-method PageBreakEvent (expr parser)
+(define-display-method PageBreakEvent (expr)
   (if (null? (ly:music-property expr 'break-permission))
       "\\noPageBreak"
       "\\pageBreak"))
 
-(define-display-method PageTurnEvent (expr parser)
+(define-display-method PageTurnEvent (expr)
   (if (null? (ly:music-property expr 'break-permission))
       "\\noPageTurn"
       "\\pageTurn"))
 
-(define-extra-display-method EventChord (expr parser)
+(define-extra-display-method EventChord (expr)
   (with-music-match (expr (music 'EventChord
-                           elements ((music 'LineBreakEvent
-                                            break-permission 'force)
-                                     (music 'PageBreakEvent
-                                            break-permission 'force))))
-    "\\pageBreak"))
+                                 elements ((music 'LineBreakEvent
+                                                  break-permission 'force)
+                                           (music 'PageBreakEvent
+                                                  break-permission 'force))))
+                    "\\pageBreak"))
 
-(define-extra-display-method EventChord (expr parser)
+(define-extra-display-method EventChord (expr)
   (with-music-match (expr (music 'EventChord
-                           elements ((music 'LineBreakEvent
-                                            break-permission 'force)
-                                     (music 'PageBreakEvent
-                                            break-permission 'force)
-                                     (music 'PageTurnEvent
-                                            break-permission 'force))))
-    "\\pageTurn"))
+                                 elements ((music 'LineBreakEvent
+                                                  break-permission 'force)
+                                           (music 'PageBreakEvent
+                                                  break-permission 'force)
+                                           (music 'PageTurnEvent
+                                                  break-permission 'force))))
+                    "\\pageTurn"))
 
 ;;;
 ;;; Lyrics
 ;;;
 
 ;;; \lyricsto
-(define-display-method LyricCombineMusic (expr parser)
+(define-display-method LyricCombineMusic (expr)
   (format #f "\\lyricsto ~s ~a"
-         (ly:music-property expr 'associated-context)
-         (parameterize ((*explicit-mode* #f))
-           (music->lily-string (ly:music-property expr 'element) parser))))
+          (ly:music-property expr 'associated-context)
+          (parameterize ((*explicit-mode* #f)
+                         (*omit-duration* #t))
+                        (music->lily-string (ly:music-property expr 'element)))))
+
+;; \autochange
+(define-extra-display-method SimultaneousMusic (expr)
+  (with-music-match (expr (music 'SimultaneousMusic
+                                 elements ((music 'ContextSpeccedMusic
+                                                  context-id "up"
+                                                  context-type 'Staff
+                                                  element ?ac-music)
+                                           (music 'ContextSpeccedMusic
+                                                  context-id "up"
+                                                  context-type 'Staff)
+                                           (music 'ContextSpeccedMusic
+                                                  context-id "down"
+                                                  context-type 'Staff))))
+                    (with-music-match (?ac-music (music 'AutoChangeMusic))
+                                      (format #f "~a"
+                                              (music->lily-string ?ac-music)))))
 
 ;; \addlyrics
-(define-extra-display-method SimultaneousMusic (expr parser)
+(define-extra-display-method SimultaneousMusic (expr)
   (with-music-match (expr (music 'SimultaneousMusic
-                                elements ((music 'ContextSpeccedMusic
-                                                 context-id ?id
-                                                 context-type 'Voice
-                                                 element ?note-sequence)
-                                          (music 'ContextSpeccedMusic
-                                                 context-type 'Lyrics
-                                                 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 parser)
-               (new-line->lily-string)
-               (parameterize ((*explicit-mode* #f))
-                 (music->lily-string ?lyric-sequence parser)))
-       #f)))
+                                 elements ((music 'ContextSpeccedMusic
+                                                  context-id ?id
+                                                  context-type 'Voice
+                                                  element ?note-sequence)
+                                           (music 'ContextSpeccedMusic
+                                                  context-type 'Lyrics
+                                                  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)
+                                (new-line->lily-string)
+                                (parameterize ((*explicit-mode* #f)
+                                               (*omit-duration* #t))
+                                              (music->lily-string ?lyric-sequence)))
+                        #f)))
 
 ;; Silence internal event sent at end of each lyrics block
-(define-display-method CompletizeExtenderEvent (expr parser)
+(define-display-method CompletizeExtenderEvent (expr)
   "")