]> git.donarmstrong.com Git - lilypond.git/blobdiff - scm/define-music-display-methods.scm
Issue 2525: Fix a number of display-lily shortcomings
[lilypond.git] / scm / define-music-display-methods.scm
index ac9930e1381ae24b9b36ee57a21382e990f2df43..6d0449edfc5c5ebd0ef9443bdc17ab086d2c8e5c 100644 (file)
@@ -181,17 +181,22 @@ expression."
                         ""
                         tremolo-type))))
 
-(define-post-event-display-method ArticulationEvent (event parser) #t
-  (let ((articulation  (ly:music-property event 'articulation-type)))
-    (case (string->symbol articulation)
-      ((marcato) "^")
-      ((stopped) "+")
-      ((tenuto)         "-")
-      ((staccatissimo) "|")
-      ((accent) ">")
-      ((staccato) ".")
-      ((portato) "_")
-      (else (format #f "\\~a" articulation)))))
+(define-display-method ArticulationEvent (event parser) #t
+  (let* ((articulation  (ly:music-property event 'articulation-type))
+        (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))))
 
 (define-post-event-display-method FingeringEvent (event parser) #t
   (ly:music-property event 'digit))
@@ -202,16 +207,16 @@ expression."
 (define-post-event-display-method MultiMeasureTextEvent (event parser) #t
   (markup->lily-string (ly:music-property event 'text)))
 
-(define-post-event-display-method BendAfterEvent (event parser) #t
+(define-post-event-display-method BendAfterEvent (event parser) #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) #t "\\glissando")
-(define-post-event-display-method ArpeggioEvent (event parser) #t "\\arpeggio")
+(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
   (format #f "\\~a" (ly:music-property event 'text)))
 
-(define-post-event-display-method StrokeFingerEvent (event parser) #t
+(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 "[" "]")
@@ -419,72 +424,69 @@ Otherwise, return #f."
 ;;;
 
 (define-display-method EventChord (chord parser)
-  ;; event_chord : simple_element post_events
-  ;;              | command_element
+  ;; event_chord : command_element
   ;;              | note_chord_element
 
   ;; TODO : tagged post_events
   ;; post_events : ( post_event | tagged_post_event )*
   ;; tagged_post_event: '-' \tag embedded_scm post_event
 
-  (let* ((elements (ly:music-property chord 'elements))
-        (simple-elements (filter (make-music-type-predicate
-                                  'NoteEvent 'ClusterNoteEvent 'RestEvent
-                                  'SkipEvent 'LyricEvent)
-                                 elements)))
-    (if ((make-music-type-predicate 'StaffSpanEvent 'BreathingEvent) (car elements))
-       ;; first, a special case: StaffSpanEvent (\startStaff, \stopStaff)
-       ;; and BreathingEvent (\breathe)
-       (music->lily-string (car elements) parser)
-       (if (and (not (null? simple-elements))
-                (null? (cdr simple-elements))
-                ;; a non-empty articulation list is only possible with
-                ;; chord entry.
-                (null? (ly:music-property (car simple-elements) 'articulations))
-                ;; same for simple_element with \tweak
-                (null? (ly:music-property (car simple-elements) 'tweaks)))
-           ;; simple_element : note | figure | rest | mmrest | lyric_element | skip
-           (let* ((simple-element (car simple-elements))
-                  (duration (duration->lily-string
-                             (ly:music-property simple-element 'duration)
-                             #:remember #t)))
-             (format #f "~a~a~{~a~^ ~}"
-                     (music->lily-string simple-element parser)
-                     duration
-                     (map-in-order (lambda (music)
-                                     (music->lily-string music parser))
-                                   (filter post-event? elements))))
-           (let ((chord-elements (filter (make-music-type-predicate
-                                          'NoteEvent 'ClusterNoteEvent 'BassFigureEvent)
-                                         elements))
-                 (post-events (filter post-event? elements)))
-             (if (not (null? chord-elements))
-                 ;; note_chord_element : '<' (notepitch | drumpitch)* '>" duration post_events
-                 (let* ((duration (duration->lily-string
-                                   (ly:music-property (car chord-elements) 'duration)
-                                   #:remember #t)))
-                   (format #f "< ~{~a ~}>~a~{~a~^ ~}"
-                           (map-in-order (lambda (music)
-                                           (music->lily-string music parser))
-                                         chord-elements)
-                           duration
-                           (map-in-order (lambda (music)
-                                           (music->lily-string music parser))
-                                         post-events)))
-                 ;; command_element
-                 (format #f "~{~a~^ ~}" (map-in-order (lambda (music)
-                                                      (music->lily-string music parser))
-                                                    elements))))))))
+  (let* ((elements (append (ly:music-property chord 'elements)
+                          (ly:music-property chord 'articulations)))
+        (chord-repeat (ly:music-property chord 'duration)))
+    (call-with-values
+       (lambda ()
+         (partition (lambda (m) (music-is-of-type? m 'rhythmic-event))
+                    elements))
+      (lambda (chord-elements other-elements)
+       (cond ((pair? chord-elements)
+              ;; note_chord_element :
+              ;; '<' (notepitch | drumpitch)* '>" duration post_events
+              (let ((duration (duration->lily-string (ly:music-property
+                                                      (car chord-elements)
+                                                      'duration)
+                                                     #:remember #t)))
+                ;; Format duration first so that it does not appear on
+                ;; chord elements
+                (format #f "< ~{~a ~}>~a~:{~:[-~;~]~a~^ ~}"
+                        (map-in-order (lambda (music)
+                                        (music->lily-string music parser))
+                                      chord-elements)
+                        duration
+                        (map-in-order (lambda (music)
+                                        (list
+                                         (post-event? music)
+                                         (music->lily-string music parser)))
+                                      other-elements))))
+             ((ly:duration? chord-repeat)
+              (let ((duration (duration->lily-string chord-repeat
+                                                     #:remember #t)))
+                (format #f "q~a~:{~:[-~;~]~a~^ ~}"
+                        duration
+                        (map-in-order (lambda (music)
+                                        (list
+                                         (post-event? music)
+                                         (music->lily-string music parser)))
+                                      other-elements))))
+
+             ((and (= 1 (length other-elements))
+                   (not (post-event? (car other-elements))))
+              (format #f (music->lily-string (car other-elements) parser)))
+             (else
+              (format #f "< >~:{~:[-~;~]~a~^ ~}"
+                      (map-in-order (lambda (music)
+                                      (list
+                                       (post-event? music)
+                                       (music->lily-string music parser)))
+                                    other-elements))))))))
 
 (define-display-method MultiMeasureRestMusic (mmrest parser)
-  (let* ((dur (ly:music-property mmrest 'duration))
-        (ly (format #f "R~a~{~a~^ ~}"
-                    (duration->lily-string dur)
-                    (map-in-order (lambda (music)
-                                    (music->lily-string music parser))
-                                  (ly:music-property mmrest 'articulations)))))
-    (*previous-duration* dur)
-    ly))
+  (format #f "R~a~{~a~^ ~}"
+         (duration->lily-string (ly:music-property mmrest 'duration)
+                                #:remember #t)
+         (map-in-order (lambda (music)
+                         (music->lily-string music parser))
+                       (ly:music-property mmrest 'articulations))))
 
 (define-display-method SkipMusic (skip parser)
   (format #f "\\skip ~a" (duration->lily-string (ly:music-property skip 'duration) #:force-duration #t)))
@@ -497,7 +499,7 @@ Otherwise, return #f."
 ;;;
 
 (define (simple-note->lily-string event parser)
-  (format #f "~a~a~a~a~a~a~{~a~}" ; pitchname octave !? octave-check duration optional_rest articulations
+  (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))
@@ -522,16 +524,21 @@ Otherwise, return #f."
          (if ((make-music-type-predicate 'RestEvent) event)
              "\\rest" "")
          (map-in-order (lambda (event)
-                         (music->lily-string event parser))
+                         (list
+                          (post-event? event)
+                          (music->lily-string event parser)))
                        (ly:music-property event 'articulations))))
 
 (define-display-method NoteEvent (note parser)
   (cond ((not (null? (ly:music-property note 'pitch))) ;; note
         (simple-note->lily-string note parser))
        ((not (null? (ly:music-property note 'drum-type))) ;; drum
-        (format #f "~a~a" (ly:music-property note 'drum-type)
+        (format #f "~a~a~{~a~}" (ly:music-property note 'drum-type)
                 (duration->lily-string (ly:music-property note 'duration)
-                                       #:remember #t)))
+                                       #:remember #t)
+                (map-in-order (lambda (event)
+                                (music->lily-string event parser))
+                              (ly:music-property note 'articulations))))
        (else ;; unknown?
         "")))
 
@@ -541,16 +548,24 @@ Otherwise, return #f."
 (define-display-method RestEvent (rest parser)
   (if (not (null? (ly:music-property rest 'pitch)))
       (simple-note->lily-string rest parser)
-      (string-append "r" (duration->lily-string (ly:music-property rest 'duration)
-                                               #:remember #t))))
+      (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)))))
 
 (define-display-method MultiMeasureRestEvent (rest parser)
   (string-append "R" (duration->lily-string (ly:music-property rest 'duration)
                                            #:remember #t)))
 
 (define-display-method SkipEvent (rest parser)
-  (string-append "s" (duration->lily-string (ly:music-property rest 'duration)
-                                           #:remember #t)))
+  (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))