]> git.donarmstrong.com Git - lilypond.git/blobdiff - scm/define-music-display-methods.scm
Really fix #741.
[lilypond.git] / scm / define-music-display-methods.scm
index ea72b1147646fcbd6c81e4b720ac99dfe2467893..9a3a4c10691cfb1bb14ac43910c2fdf562a42895 100644 (file)
@@ -1,7 +1,7 @@
 ;;; define-music-display-methods.scm -- data for displaying music
 ;;; expressions using LilyPond notation.
 ;;;
-;;; (c) 2005--2006 Nicolas Sceaux  <nicolas.sceaux@free.fr>
+;;; (c) 2005--2009 Nicolas Sceaux  <nicolas.sceaux@free.fr>
 ;;;
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -58,7 +58,7 @@
              (args (cdr expr)))
          (if (eqv? cmd simple-markup) ;; a simple markup
              (format #f "~s" (car args))
-             (format #f "\\~a~{ ~a~}" 
+             (format #f "\\~a~{ ~a~}"
                      (proc->command cmd)
                      (map-in-order arg->string args))))))
   (cond ((string? markup-expr)
 ;;; post events
 ;;;
 
-(define post-event? (make-music-type-predicate 
+(define post-event? (make-music-type-predicate
                     'StringNumberEvent
                     'ArticulationEvent
                     'FingeringEvent
                     'HarmonicEvent
                     'BeamForbidEvent
                     'AbsoluteDynamicEvent
+                    'TupletSpanEvent
                     'TrillSpanEvent
                     'GlissandoEvent
                     'ArpeggioEvent
 (define-post-event-display-method MultiMeasureTextEvent (event parser) #t
   (markup->lily-string (ly:music-property event 'text)))
 
-(define-post-event-display-method HarmonicEvent (event parser) #t "\\harmonic")
+(define-post-event-display-method HarmonicEvent (event parser) #f "\\harmonic")
 (define-post-event-display-method GlissandoEvent (event parser) #t "\\glissando")
 (define-post-event-display-method ArpeggioEvent (event parser) #t "\\arpeggio")
 (define-post-event-display-method AbsoluteDynamicEvent (event parser) #f
 (define-span-event-display-method CrescendoEvent (event parser) #f "\\<" "\\!")
 (define-span-event-display-method DecrescendoEvent (event parser) #f "\\>" "\\!")
 (define-span-event-display-method PhrasingSlurEvent (event parser) #f "\\(" "\\)")
-(define-span-event-display-method SustainEvent (event parser) #f "\\sustainDown" "\\sustainUp")
-(define-span-event-display-method SostenutoEvent (event parser) #f "\\sostenutoDown" "\\sostenutoUp")
+(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-display-method GraceMusic (expr parser)
-  (format #f "\\grace ~a" 
+  (format #f "\\grace ~a"
          (music->lily-string (ly:music-property expr 'element) parser)))
 
 ;; \acciaccatura \appoggiatura \grace
                                              ?stop))))
     ;; we check whether ?start and ?stop look like
     ;; startAppoggiaturaMusic stopAppoggiaturaMusic
-    (and (with-music-match (?start (music 
+    (and (with-music-match (?start (music
                                    'SequentialMusic
                                    elements ((music
                                               'EventChord
                                                          'SlurEvent
                                                          span-direction START))))))
                           #t)
-         (with-music-match (?stop (music 
+         (with-music-match (?stop (music
                                    'SequentialMusic
                                    elements ((music
                                               'EventChord
                                              ?stop))))
     ;; we check whether ?start and ?stop look like
     ;; startAcciaccaturaMusic stopAcciaccaturaMusic
-    (and (with-music-match (?start (music 
+    (and (with-music-match (?start (music
                                    'SequentialMusic
                                    elements ((music
                                               'EventChord
                                                        grob-value "grace"
                                                        symbol 'Stem)))))
                           #t)
-        (with-music-match (?stop (music 
+        (with-music-match (?stop (music
                                   'SequentialMusic
                                   elements ((music
                                              'ContextSpeccedMusic
 
 (define-display-method SequentialMusic (seq parser)
   (let ((force-line-break (and (*force-line-break*)
-                              ;; hm 
+                              ;; hm
                               (> (length (ly:music-property seq 'elements))
                                  (*max-element-number-before-break*))))
        (elements (ly:music-property seq 'elements))
@@ -423,7 +424,7 @@ Otherwise, return #f."
     (format #f "\\afterGrace ~a ~a"
            (music->lily-string ?before-grace parser)
            (music->lily-string ?grace parser))))
-  
+
 ;;;
 ;;; Chords
 ;;;
@@ -438,7 +439,7 @@ Otherwise, return #f."
   ;; tagged_post_event: '-' \tag embedded_scm post_event
 
   (let* ((elements (ly:music-property chord 'elements))
-        (simple-elements (filter (make-music-type-predicate 
+        (simple-elements (filter (make-music-type-predicate
                                   'NoteEvent 'ClusterNoteEvent 'RestEvent
                                   'MultiMeasureRestEvent 'SkipEvent 'LyricEvent)
                                  elements)))
@@ -447,7 +448,13 @@ Otherwise, return #f."
        ;; and BreathingEvent (\breathe)
        (music->lily-string (car elements) parser)
        (if (and (not (null? simple-elements))
-                (null? (cdr simple-elements)))
+                (null? (cdr simple-elements))
+                ;; special case: if this simple_element has a HarmonicEvent in its
+                ;; 'articulations list, it should be interpreted instead as a
+                ;; note_chord_element, since \harmonic only works inside chords,
+                ;; even for single notes, e.g., < c\harmonic >
+                (null? (filter (make-music-type-predicate 'HarmonicEvent)
+                               (ly:music-property (car simple-elements) 'articulations))))
            ;; simple_element : note | figure | rest | mmrest | lyric_element | skip
            (let* ((simple-element (car simple-elements))
                   (duration (ly:music-property simple-element 'duration))
@@ -474,7 +481,7 @@ Otherwise, return #f."
                                                             (music->lily-string music parser))
                                                           chord-elements)
                                             (duration->lily-string (ly:music-property (car chord-elements)
-                                                                                    'duration))
+                                                                                      'duration))
                                             (map-in-order (lambda (music)
                                                             (music->lily-string music parser))
                                                           post-events))))
@@ -561,7 +568,7 @@ Otherwise, return #f."
     (if (or (null? pitch-alist)
            (null? tonic))
        "\\key \\default"
-       (let ((c-pitch-alist (ly:transpose-key-alist pitch-alist 
+       (let ((c-pitch-alist (ly:transpose-key-alist pitch-alist
                                                     (ly:pitch-diff (ly:make-pitch 0 0 0) tonic))))
          (format #f "\\key ~a \\~a~a"
                  (note-name->lily-string (ly:music-property key 'tonic) parser)
@@ -575,7 +582,7 @@ Otherwise, return #f."
 
 (define-display-method RelativeOctaveCheck (octave parser)
   (let ((pitch (ly:music-property octave 'pitch)))
-    (format #f "\\octave ~a~a"
+    (format #f "\\octaveCheck ~a~a"
            (note-name->lily-string pitch parser)
            (octave->lily-string pitch))))
 
@@ -606,7 +613,7 @@ Otherwise, return #f."
                  (else fig))
            (if (null? alteration)
                ""
-               (cond 
+               (cond
                  ((= alteration DOUBLE-FLAT) "--")
                  ((= alteration FLAT) "-")
                  ((= alteration NATURAL) "!")
@@ -654,7 +661,7 @@ Otherwise, return #f."
     (parameterize ((*force-line-break* #f)
                   (*time-factor-numerator* (/ num nd-gcd))
                   (*time-factor-denominator* (/ den nd-gcd)))
-      (format #f "\\times ~a/~a ~a" 
+      (format #f "\\times ~a/~a ~a"
              num
              den
              (music->lily-string (ly:music-property times 'element) parser)))))
@@ -688,9 +695,6 @@ Otherwise, return #f."
 (define-display-method UnfoldedRepeatedMusic (expr parser)
   (repeat->lily-string expr "unfold" parser))
 
-(define-display-method FoldedRepeatedMusic (expr parser)
-  (repeat->lily-string expr "fold" parser))
-
 (define-display-method PercentRepeatedMusic (expr parser)
   (repeat->lily-string expr "percent" parser))
 
@@ -727,7 +731,7 @@ Otherwise, return #f."
 
 ;;;
 ;;; Contexts
-;;; 
+;;;
 
 (define-display-method ContextSpeccedMusic (expr parser)
   (let ((id    (ly:music-property expr 'context-id))
@@ -744,8 +748,8 @@ Otherwise, return #f."
                ""
                (format #f " = ~s" id))
            (if (null? operations)
-               "" 
-               (format #f " \\with {~{~a~}~%~v_}" 
+               ""
+               (format #f " \\with {~{~a~}~%~v_}"
                        (parameterize ((*indent* (+ (*indent*) 2)))
                          (map (lambda (op)
                                 (format #f "~%~v_\\~a ~s"
@@ -812,8 +816,8 @@ Otherwise, return #f."
            (if (and (not (null? once)))
                "\\once "
                "")
-           (if (eqv? (*current-context*) 'Bottom) 
-               "" 
+           (if (eqv? (*current-context*) 'Bottom)
+               ""
                (format #f "~a . " (*current-context*)))
            property
            (property-value->lily-string value parser)
@@ -821,8 +825,8 @@ Otherwise, return #f."
 
 (define-display-method PropertyUnset (expr parser)
   (format #f "\\unset ~a~a~a"
-         (if (eqv? (*current-context*) 'Bottom) 
-             "" 
+         (if (eqv? (*current-context*) 'Bottom)
+             ""
              (format #f "~a . " (*current-context*)))
          (ly:music-property expr 'symbol)
          (new-line->lily-string)))
@@ -843,8 +847,8 @@ Otherwise, return #f."
                    (not once))
                ""
                "\\once ")
-           (if (eqv? (*current-context*) 'Bottom) 
-               "" 
+           (if (eqv? (*current-context*) 'Bottom)
+               ""
                (format #f "~a . " (*current-context*)))
            symbol
            (if (null? (cdr properties))
@@ -852,13 +856,13 @@ Otherwise, return #f."
                properties)
            (property-value->lily-string value parser)
            (new-line->lily-string))))
-           
+
 (define-display-method RevertProperty (expr parser)
   (let ((symbol (ly:music-property expr 'symbol))
        (properties (ly:music-property expr 'grob-property-path)))
     (format #f "\\revert ~a~a #'~a~a"
-           (if (eqv? (*current-context*) 'Bottom) 
-               "" 
+           (if (eqv? (*current-context*) 'Bottom)
+               ""
                (format #f "~a . " (*current-context*)))
            symbol
            (if (null? (cdr properties))
@@ -883,27 +887,59 @@ Otherwise, return #f."
     "\\melismaEnd"))
 
 ;;; \tempo
+;;; Check for all three different syntaxes of tempo:
+;;; \tempo string duration=note, \tempo duration=note and \tempo string
 (define-extra-display-method ContextSpeccedMusic (expr parser)
   "If expr is a tempo, return \"\\tempo x = nnn\", otherwise return #f."
-  (with-music-match (expr (music 'ContextSpeccedMusic
+  (or   (with-music-match (expr (music 'ContextSpeccedMusic
+               element (music 'SequentialMusic
+                             elements ((music 'PropertySet
+                                         value ?unit-text
+                                         symbol 'tempoText)
+                                       (music 'PropertySet
+                                         symbol 'tempoWholesPerMinute)
+                                       (music 'PropertySet
+                                         value ?unit-duration
+                                         symbol 'tempoUnitDuration)
+                                       (music 'PropertySet
+                                         value ?unit-count
+                                         symbol 'tempoUnitCount)))))
+               (format #f "\\tempo ~a ~a = ~a"
+                       (scheme-expr->lily-string ?unit-text)
+                       (duration->lily-string ?unit-duration #:force-duration #t)
+                       ?unit-count))
+       (with-music-match (expr (music 'ContextSpeccedMusic
+                   element (music 'SequentialMusic
+                             elements ((music 'PropertyUnset
+                                         symbol 'tempoText)
+                                       (music 'PropertySet
+                                         symbol 'tempoWholesPerMinute)
+                                       (music 'PropertySet
+                                         value ?unit-duration
+                                         symbol 'tempoUnitDuration)
+                                       (music 'PropertySet
+                                         value ?unit-count
+                                         symbol 'tempoUnitCount)))))
+                       (format #f "\\tempo ~a = ~a"
+                               (duration->lily-string ?unit-duration #:force-duration #t)
+                               ?unit-count))
+       (with-music-match (expr (music 'ContextSpeccedMusic
                            element (music 'SequentialMusic
                                      elements ((music 'PropertySet
-                                                 symbol 'tempoWholesPerMinute)
-                                               (music 'PropertySet
-                                                 value ?unit-duration
-                                                 symbol 'tempoUnitDuration)
-                                               (music 'PropertySet
-                                                 value ?unit-count
-                                                 symbol 'tempoUnitCount)))))
-    (format #f "\\tempo ~a = ~a"
-           (duration->lily-string ?unit-duration #:force-duration #t)
-           ?unit-count)))
-
-;;; \clef 
-(define clef-name-alist (map (lambda (name+vals)
-                              (cons (cdr name+vals)
-                                    (car name+vals)))
-                            supported-clefs))
+                                                 value ?tempo-text
+                                                symbol 'tempoText)))))
+                       (format #f "\\tempo ~a" (scheme-expr->lily-string ?tempo-text)))))
+
+;;; \clef
+(define clef-name-alist #f)
+(define-public (memoize-clef-names clefs)
+  "Initialize `clef-name-alist', if not already set."
+  (if (not clef-name-alist)
+      (set! clef-name-alist
+            (map (lambda (name+vals)
+                   (cons (cdr name+vals)
+                         (car name+vals)))
+                 clefs))))
 
 (define-extra-display-method ContextSpeccedMusic (expr parser)
   "If `expr' is a clef change, return \"\\clef ...\"
@@ -915,13 +951,15 @@ Otherwise, return #f."
                                                                 value ?clef-glyph
                                                                 symbol 'clefGlyph)
                                                          (music 'PropertySet
-                                                                symbol 'middleCPosition)
+                                                                symbol 'middleCClefPosition)
                                                          (music 'PropertySet
                                                                 value ?clef-position
                                                                 symbol 'clefPosition)
                                                          (music 'PropertySet
                                                                 value ?clef-octavation
-                                                                symbol 'clefOctavation)))))
+                                                                symbol 'clefOctavation)
+                                                         (music 'ApplyContext
+                                                                procedure ly:set-middle-C!)))))
     (let ((clef-prop+name (assoc (list ?clef-glyph ?clef-position 0)
                                 clef-name-alist)))
       (if clef-prop+name
@@ -940,14 +978,14 @@ Otherwise, return #f."
 (define-extra-display-method ContextSpeccedMusic (expr parser)
   "If `expr' is a time signature set, return \"\\time ...\".
 Otherwise, return #f."
-  (with-music-match (expr (music 
+  (with-music-match (expr (music
                           'ContextSpeccedMusic
-                          element (music 
+                          element (music
                                    'ContextSpeccedMusic
                                    context-type 'Timing
-                                   element (music 
+                                   element (music
                                             'SequentialMusic
-                                            elements ((music 
+                                            elements ((music
                                                        'PropertySet
                                                        value ?num+den
                                                        symbol 'timeSignatureFraction)
@@ -1000,7 +1038,7 @@ Otherwise, return #f."
 
 (define (moment->duration moment)
   (let ((result (assoc (- moment) moment-duration-alist =)))
-    (and result 
+    (and result
         (cdr result))))
 
 (define-extra-display-method ContextSpeccedMusic (expr parser)