X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scm%2Fdefine-music-display-methods.scm;h=c0041ba2a98344efe4fdef5fe097a9e0f832e0cb;hb=refs%2Fheads%2Fdon%2Fdep5_copyright;hp=3212e5f0b8be0f7ade9cdce5c361bded2510773d;hpb=88755cdba14fe06fbe7f434841e193c5474c5a6b;p=lilypond.git diff --git a/scm/define-music-display-methods.scm b/scm/define-music-display-methods.scm index 3212e5f0b8..c0041ba2a9 100644 --- a/scm/define-music-display-methods.scm +++ b/scm/define-music-display-methods.scm @@ -1,7 +1,7 @@ ;;; define-music-display-methods.scm -- data for displaying music ;;; expressions using LilyPond notation. ;;; -;;; (c) 2005--2006 Nicolas Sceaux +;;; Copyright (C) 2005--2011 Nicolas Sceaux ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -16,7 +16,8 @@ ;;; (define (scheme-expr->lily-string scm-arg) (cond ((or (number? scm-arg) - (string? scm-arg)) + (string? scm-arg) + (boolean? scm-arg)) (format #f "~s" scm-arg)) ((or (symbol? scm-arg) (list? scm-arg)) @@ -37,7 +38,8 @@ ;;; (define-public (markup->lily-string markup-expr) - "Return a string describing, in LilyPond syntax, the given markup expression." + "Return a string describing, in LilyPond syntax, the given markup +expression." (define (proc->command proc) (let ((cmd-markup (symbol->string (procedure-name proc)))) (substring cmd-markup 0 (- (string-length cmd-markup) @@ -58,7 +60,7 @@ (args (cdr expr))) (if (eqv? cmd simple-markup) ;; a simple markup (format #f "~s" (car args)) - (format #f "\\~a~{ ~a~}" + (format #f "\\~a~{ ~a~}" (proc->command cmd) (map-in-order arg->string args)))))) (cond ((string? markup-expr) @@ -81,7 +83,7 @@ (if (and (car alist) (test item (cdar alist))) (set! result (car alist))))) -(define (note-name->lily-string ly-pitch parser) +(define-public (note-name->lily-string ly-pitch parser) ;; here we define a custom pitch= function, since we do not want to ;; test whether octaves are also equal. (otherwise, we would be using equal?) (define (pitch= pitch1 pitch2) @@ -92,7 +94,7 @@ (car result) #f))) -(define (octave->lily-string pitch) +(define-public (octave->lily-string pitch) (let ((octave (ly:pitch-octave pitch))) (cond ((>= octave 0) (make-string (1+ octave) #\')) @@ -103,7 +105,7 @@ ;;; ;;; durations ;;; -(define* (duration->lily-string ly-duration #:key (prev-duration (*previous-duration*)) +(define*-public (duration->lily-string ly-duration #:key (prev-duration (*previous-duration*)) (force-duration (*force-duration*)) (time-factor-numerator (*time-factor-numerator*)) (time-factor-denominator (*time-factor-denominator*))) @@ -134,33 +136,37 @@ ;;; post events ;;; -(define post-event? (make-music-type-predicate - 'StringNumberEvent - 'ArticulationEvent - 'FingeringEvent - 'TextScriptEvent - 'MultiMeasureTextEvent - 'HyphenEvent - 'ExtenderEvent - 'BeamEvent - 'SlurEvent - 'TieEvent - 'CrescendoEvent - 'DecrescendoEvent - 'PhrasingSlurEvent - 'TremoloEvent - 'SustainEvent - 'SostenutoEvent - 'TextSpanEvent - 'HarmonicEvent - 'BeamForbidEvent - 'AbsoluteDynamicEvent - 'TupletSpanEvent - 'TrillSpanEvent - 'GlissandoEvent - 'ArpeggioEvent - 'NoteGroupingEvent - 'UnaCordaEvent)) +(define post-event? + (make-music-type-predicate + 'AbsoluteDynamicEvent + 'ArpeggioEvent + 'ArticulationEvent + 'BeamEvent + 'BeamForbidEvent + 'BendAfterEvent + 'CrescendoEvent + 'DecrescendoEvent + 'EpisemaEvent + 'ExtenderEvent + 'FingeringEvent + 'GlissandoEvent + 'HarmonicEvent + 'HyphenEvent + 'MultiMeasureTextEvent + 'NoteGroupingEvent + 'PhrasingSlurEvent + 'SlurEvent + 'SostenutoEvent + 'StringNumberEvent + 'StrokeFingerEvent + 'SustainEvent + 'TextScriptEvent + 'TextSpanEvent + 'TieEvent + 'TremoloEvent + 'TrillSpanEvent + 'TupletSpanEvent + 'UnaCordaEvent)) (define* (event-direction->lily-string event #:optional (required #t)) (let ((direction (ly:music-property event 'direction))) @@ -223,19 +229,26 @@ (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 BendAfterEvent (event parser) #t + (format #f "\\bendAfter #~a" (ly:music-property event 'delta-step))) + +(define-post-event-display-method HarmonicEvent (event parser) #f "\\harmonic") (define-post-event-display-method GlissandoEvent (event parser) #t "\\glissando") (define-post-event-display-method ArpeggioEvent (event parser) #t "\\arpeggio") (define-post-event-display-method AbsoluteDynamicEvent (event parser) #f (format #f "\\~a" (ly:music-property event 'text))) +(define-post-event-display-method StrokeFingerEvent (event parser) #t + (format #f "\\rightHandFinger #~a" (ly:music-property event 'digit))) + (define-span-event-display-method BeamEvent (event parser) #f "[" "]") (define-span-event-display-method SlurEvent (event parser) #f "(" ")") (define-span-event-display-method CrescendoEvent (event parser) #f "\\<" "\\!") (define-span-event-display-method DecrescendoEvent (event parser) #f "\\>" "\\!") +(define-span-event-display-method EpisemaEvent (event parser) #f "\\episemInitium" "\\episemFinis") (define-span-event-display-method PhrasingSlurEvent (event parser) #f "\\(" "\\)") -(define-span-event-display-method SustainEvent (event parser) #f "\\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") @@ -247,7 +260,7 @@ ;;; (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 @@ -265,7 +278,7 @@ ?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 @@ -275,8 +288,8 @@ (music 'SlurEvent span-direction START)))))) - #t) - (with-music-match (?stop (music + #t) + (with-music-match (?stop (music 'SequentialMusic elements ((music 'EventChord @@ -300,7 +313,7 @@ ?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 @@ -317,8 +330,8 @@ grob-property-path '(stroke-style) grob-value "grace" symbol 'Stem))))) - #t) - (with-music-match (?stop (music + #t) + (with-music-match (?stop (music 'SequentialMusic elements ((music 'ContextSpeccedMusic @@ -357,7 +370,7 @@ (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)) @@ -424,7 +437,7 @@ Otherwise, return #f." (format #f "\\afterGrace ~a ~a" (music->lily-string ?before-grace parser) (music->lily-string ?grace parser)))) - + ;;; ;;; Chords ;;; @@ -439,7 +452,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))) @@ -448,7 +461,15 @@ 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 any post_events in + ;; its 'articulations list, it should be interpreted instead + ;; as a note_chord_element to prevent spurious output, e.g., + ;; \displayLilyMusic < c-1\4 >8 -> c-1\48 + (null? (filter post-event? + (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 (ly:music-property simple-element 'duration)) @@ -475,7 +496,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)))) @@ -499,6 +520,9 @@ Otherwise, return #f." (define-display-method SkipMusic (skip parser) (format #f "\\skip ~a" (duration->lily-string (ly:music-property skip 'duration) #:force-duration #t))) +(define-display-method OttavaMusic (ottava parser) + (format #f "\\ottava #~a" (ly:music-property ottava 'ottava-number))) + ;;; ;;; Notes, rests, skips... ;;; @@ -550,6 +574,9 @@ Otherwise, return #f." (define-display-method SkipEvent (rest parser) "s") +(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) @@ -562,7 +589,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) @@ -576,7 +603,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)))) @@ -607,7 +634,7 @@ Otherwise, return #f." (else fig)) (if (null? alteration) "" - (cond + (cond ((= alteration DOUBLE-FLAT) "--") ((= alteration FLAT) "-") ((= alteration NATURAL) "!") @@ -655,7 +682,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))))) @@ -689,9 +716,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)) @@ -728,7 +752,7 @@ Otherwise, return #f." ;;; ;;; Contexts -;;; +;;; (define-display-method ContextSpeccedMusic (expr parser) (let ((id (ly:music-property expr 'context-id)) @@ -745,15 +769,15 @@ Otherwise, return #f." "" (format #f " = ~s" id)) (if (null? operations) - "" - (format #f " \\with {~{~a~}~%~v_}" + "" + (format #f " \\with {~{~a~}~%~v_}" (parameterize ((*indent* (+ (*indent*) 2))) (map (lambda (op) (format #f "~%~v_\\~a ~s" (*indent*) (first op) (second op))) - (reverse operations))) + operations)) (*indent*))) (parameterize ((*current-context* ctype)) (music->lily-string music parser))))) @@ -813,8 +837,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) @@ -822,8 +846,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))) @@ -844,8 +868,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)) @@ -853,13 +877,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)) @@ -867,6 +891,20 @@ Otherwise, return #f." properties) (new-line->lily-string)))) +(define-display-method TimeSignatureMusic (expr parser) + (let* ((num (ly:music-property expr 'numerator)) + (den (ly:music-property expr 'denominator)) + (structure (ly:music-property expr 'beat-structure))) + (if (null? structure) + (format #f + "\\time ~a/~a~a" + num den + (new-line->lily-string)) + (format #f + "#(set-time-signature ~a ~a '~a)~a" + num den structure + (new-line->lily-string))))) + ;;; \melisma and \melismaEnd (define-extra-display-method ContextSpeccedMusic (expr parser) "If expr is a melisma, return \"\\melisma\", otherwise, return #f." @@ -884,26 +922,35 @@ Otherwise, return #f." "\\melismaEnd")) ;;; \tempo -(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 - 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-extra-display-method SequentialMusic (expr parser) + (with-music-match (expr (music 'SequentialMusic + elements ((music 'TempoChangeEvent + text ?text + tempo-unit ?unit + metronome-count ?count) + (music 'ContextSpeccedMusic + element (music 'PropertySet + symbol 'tempoWholesPerMinute))))) + (format #f "\\tempo ~{~a~a~}~a = ~a~a" + (if (markup? ?text) + (list (markup->lily-string ?text) " ") + '()) + (duration->lily-string ?unit #:force-duration #t) + (if (pair? ?count) + (format #f "~a ~~ ~a" (car ?count) (cdr ?count)) + ?count) + (new-line->lily-string)))) + +(define-display-method TempoChangeEvent (expr parser) + (let ((text (ly:music-property expr 'text))) + (format #f "\\tempo ~a~a" + (markup->lily-string text) + (new-line->lily-string)))) + +;;; \clef (define clef-name-alist #f) (define-public (memoize-clef-names clefs) - "Initialize `clef-name-alist', if not already set." + "Initialize @code{clef-name-alist}, if not already set." (if (not clef-name-alist) (set! clef-name-alist (map (lambda (name+vals) @@ -912,8 +959,8 @@ Otherwise, return #f." clefs)))) (define-extra-display-method ContextSpeccedMusic (expr parser) - "If `expr' is a clef change, return \"\\clef ...\" -Otherwise, return #f." + "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 @@ -921,18 +968,20 @@ Otherwise, return #f." value ?clef-glyph symbol 'clefGlyph) (music 'PropertySet - symbol 'middleCPosition) + symbol 'middleCClefPosition) (music 'PropertySet value ?clef-position symbol 'clefPosition) (music 'PropertySet value ?clef-octavation - symbol 'clefOctavation))))) - (let ((clef-prop+name (assoc (list ?clef-glyph ?clef-position 0) - clef-name-alist))) - (if clef-prop+name + symbol 'clefOctavation) + (music 'ApplyContext + procedure ly:set-middle-C!))))) + (let ((clef-name (assoc-get (list ?clef-glyph ?clef-position 0) + clef-name-alist))) + (if clef-name (format #f "\\clef \"~a~{~a~a~}\"~a" - (cdr clef-prop+name) + clef-name (cond ((= 0 ?clef-octavation) (list "" "")) ((> ?clef-octavation 0) @@ -942,36 +991,6 @@ Otherwise, return #f." (new-line->lily-string)) #f)))) -;;; \time -(define-extra-display-method ContextSpeccedMusic (expr parser) - "If `expr' is a time signature set, return \"\\time ...\". -Otherwise, return #f." - (with-music-match (expr (music - 'ContextSpeccedMusic - element (music - 'ContextSpeccedMusic - context-type 'Timing - element (music - 'SequentialMusic - elements ((music - 'PropertySet - value ?num+den - symbol 'timeSignatureFraction) - (music - 'PropertySet - symbol 'beatLength) - (music - 'PropertySet - symbol 'measureLength) - (music - 'PropertySet - value ?grouping - symbol 'beatGrouping)))))) - (if (null? ?grouping) - (format #f "\\time ~a/~a~a" (car ?num+den) (cdr ?num+den) (new-line->lily-string)) - (format #f "#(set-time-signature ~a ~a '~s)~a" - (car ?num+den) (cdr ?num+den) ?grouping (new-line->lily-string))))) - ;;; \bar (define-extra-display-method ContextSpeccedMusic (expr parser) "If `expr' is a bar, return \"\\bar ...\". @@ -981,34 +1000,9 @@ Otherwise, return #f." element (music 'PropertySet value ?bar-type symbol 'whichBar))) - (format #f "\\bar \"~a\"~a" ?bar-type (new-line->lily-string)))) + (format #f "\\bar \"~a\"~a" ?bar-type (new-line->lily-string)))) ;;; \partial -(define (duration->moment ly-duration) - (let ((log2 (ly:duration-log ly-duration)) - (dots (ly:duration-dot-count ly-duration)) - (num+den (ly:duration-factor ly-duration))) - (let* ((m (expt 2 (- log2))) - (factor (/ (car num+den) (cdr num+den)))) - (/ (do ((i 0 (1+ i)) - (delta (/ m 2) (/ delta 2))) - ((= i dots) m) - (set! m (+ m delta))) - factor)))) -(define moment-duration-alist (map (lambda (duration) - (cons (duration->moment duration) - duration)) - (append-map (lambda (log2) - (map (lambda (dots) - (ly:make-duration log2 dots 1 1)) - (list 0 1 2 3))) - (list 0 1 2 3 4)))) - -(define (moment->duration moment) - (let ((result (assoc (- moment) moment-duration-alist =))) - (and result - (cdr result)))) - (define-extra-display-method ContextSpeccedMusic (expr parser) "If `expr' is a partial measure, return \"\\partial ...\". Otherwise, return #f." @@ -1018,13 +1012,12 @@ Otherwise, return #f." 'ContextSpeccedMusic context-type 'Timing element (music - 'PropertySet - value ?moment - symbol 'measurePosition)))) - (let ((duration (moment->duration (/ (ly:moment-main-numerator ?moment) - (ly:moment-main-denominator ?moment))))) - (and duration (format #f "\\partial ~a" (duration->lily-string duration - #:force-duration #t)))))) + 'PartialSet + partial-duration ?duration)))) + + (and ?duration + (format #f "\\partial ~a" + (duration->lily-string ?duration #:force-duration #t))))) ;;; ;;; @@ -1159,4 +1152,6 @@ Otherwise, return #f." (music->lily-string ?lyric-sequence parser))) #f))) - +;; Silence internal event sent at end of each lyrics block +(define-display-method CompletizeExtenderEvent (expr parser) + "")