]> git.donarmstrong.com Git - lilypond.git/blobdiff - scm/translation-functions.scm
Merge master into nested-bookparts
[lilypond.git] / scm / translation-functions.scm
index f3bd6163828558557a9f30d5c581e28d98eaf690..3767a18be2be9de99549f3541ef00ea2b494dd66 100644 (file)
@@ -2,31 +2,39 @@
 ;;;;
 ;;;;  source file of the GNU LilyPond music typesetter
 ;;;; 
-;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+;;;; (c) 1998--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
 ;;;;                Jan Nieuwenhuizen <janneke@gnu.org>
 
-(define-public (denominator-tuplet-formatter mus)
-  (number->string (ly:music-property mus 'denominator)))
-
-(define-public (fraction-tuplet-formatter mus)
-  (string-append
-   (number->string (ly:music-property mus 'denominator))
-   ":"
-   (number->string (ly:music-property mus 'numerator))))
-
 ;; metronome marks
-(define-public (format-metronome-markup event context)
-  (let* ((dur (ly:music-property event 'tempo-unit))
-       (count (ly:music-property event 'metronome-count))
-       (note-mark (make-smaller-markup
-                  (make-note-by-number-markup (ly:duration-log dur)
-                                              (ly:duration-dot-count dur)
-                                              1))))  
-    (make-line-markup
-     (list
-      (make-general-align-markup Y DOWN note-mark)
-      (make-simple-markup  "=")
-      (make-simple-markup (number->string count))))))
+(define-public (format-metronome-markup text dur count context)
+  (let* ((hide-note (eq? #t (ly:context-property context 'tempoHideNote)))
+        (note-mark (if (and (not hide-note) (ly:duration? dur))
+                      (make-smaller-markup
+                      (make-note-by-number-markup (ly:duration-log dur)
+                                                  (ly:duration-dot-count dur)
+                                                  1))
+                     (make-null-markup)))
+         (note-markup (if (and (not hide-note) (number? count) (> count 0) )
+                        (make-concat-markup (list
+                          (make-general-align-markup Y DOWN note-mark)
+                          (make-simple-markup " ")
+                          (make-simple-markup  "=")
+                          (make-simple-markup " ")
+                          (make-simple-markup (number->string count))))
+                      #f))
+         (text-markup (if (not (null? text))
+                        (make-bold-markup text)
+                        #f)))
+    (if text-markup
+      (if (and note-markup (not hide-note))
+        (make-line-markup (list text-markup
+          (make-concat-markup (list (make-simple-markup "(")
+                                    note-markup
+                                    (make-simple-markup ")")))))
+        (make-line-markup (list text-markup)))
+      (if note-markup
+        (make-line-markup (list note-markup))
+        (make-null-markup)))))
 
 (define-public (format-mark-alphabet mark context)
   (make-bold-markup (make-markalphabet-markup (1- mark))))
@@ -72,7 +80,7 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (define-public (format-bass-figure figure event context)
-  (let* ((fig (ly:music-property event 'figure))
+  (let* ((fig (ly:event-property event 'figure))
         (fig-markup (if (number? figure)
 
                         ;; this is not very elegant, but center-aligning all digits
                              (lambda (y) (make-translate-scaled-markup (cons -0.7 0) y))
                              identity)
 
-                         (if (eq? #t (ly:music-property event 'diminished))
-                             (markup #:slashed-digit figure)
-                             (markup #:number (number->string figure 10))))
+                         (cond
+                               ((eq? #t (ly:event-property event 'diminished))
+                                        (markup #:slashed-digit figure))
+                               ((eq? #t (ly:event-property event 'augmented-slash))
+                                        (markup #:backslashed-digit figure))
+                               (else (markup #:number (number->string figure 10)))))
                         #f
                         ))
-        (alt (ly:music-property event 'alteration))
+        (alt (ly:event-property event 'alteration))
         (alt-markup
          (if (number? alt)
              (markup
               (alteration->text-accidental-markup alt))
              
              #f))
-        (plus-markup (if (eq? #t (ly:music-property event 'augmented))
+        (plus-markup (if (eq? #t (ly:event-property event 'augmented))
                          (markup #:number "+")
                          #f))
 
     ;;    (if (markup? fig-markup)
     ;; (set!
     ;;  fig-markup (markup #:translate (cons 1.0 0)
-    ;;                     #:hcenter fig-markup)))
+    ;;                     #:center-align fig-markup)))
 
     (if alt-markup
        (set! fig-markup
              (markup #:put-adjacent
-                     fig-markup X
-                     (if (number? alt-dir)
-                         alt-dir
-                         LEFT)
+                     X (if (number? alt-dir)
+                           alt-dir
+                           LEFT)
+                     fig-markup
                      #:pad-x 0.2 alt-markup
                      )))
 
        (set! fig-markup
              (if fig-markup
                  (markup #:put-adjacent
-                         fig-markup
                          X (if (number? plus-dir)
                                plus-dir
                                LEFT)
+                         fig-markup
                          #:pad-x 0.2 plus-markup)
                  plus-markup)))
     
 
     ))
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; fret diagrams
+
+(define-public (determine-frets context grob notes string-numbers)
+  
+  (define (ensure-number a b)
+    (if (number? a)
+       a
+       b))
+
+  (define (string-frets->dot-placement string-frets string-count)
+    (let*
+      ((desc (list->vector
+              (map (lambda (x) (list 'mute  (1+ x)))
+                   (iota string-count)))))
+
+       (for-each (lambda (sf)
+                   (let*
+                       ((string (car sf))
+                        (fret (cadr sf))
+                        (finger (caddr sf)))
+
+                       (vector-set! 
+                         desc (1- string)
+                         (if (= 0 fret)
+                             (list 'open string)
+                             (if finger
+                                 (list 'place-fret string fret finger)
+                                 (list 'place-fret string fret))
+                                      ))
+                     ))
+                 string-frets)
+       (vector->list desc)))
+
+;; body.
+  (let*
+      ((tunings (ly:context-property context 'stringTunings))
+       (my-string-count (length tunings))
+       (details (ly:grob-property grob 'fret-diagram-details))
+       (predefined-frets
+         (ly:context-property context 'predefinedDiagramTable)) 
+       (minimum-fret (ensure-number
+                     (ly:context-property context 'minimumFret) 0))
+       (max-stretch (ensure-number
+                     (ly:context-property context 'maximumFretStretch) 4))
+       (string-frets (determine-frets-mf notes string-numbers
+                                        minimum-fret max-stretch
+                                        tunings))
+       (pitches (map (lambda (x) (ly:event-property x 'pitch)) notes)))
+
+    (set! (ly:grob-property grob 'fret-diagram-details)
+
+          (if (null? details)
+              (acons 'string-count (length tunings) '())
+              (acons 'string-count (length tunings) details)))
+    (set! (ly:grob-property grob 'dot-placement-list)
+        (if predefined-frets
+            (let ((hash-handle 
+                    (hash-get-handle
+                      predefined-frets
+                      (cons tunings pitches))))
+              (if hash-handle 
+                  (cdr hash-handle)  ;found default diagram
+                  (string-frets->dot-placement 
+                        string-frets my-string-count)))
+            (string-frets->dot-placement string-frets my-string-count)))))
+
+(define-public (determine-frets-mf notes string-numbers
+                                  minimum-fret max-stretch
+                                  tunings)
+
+  (define (calc-fret pitch string tuning)
+    (- (ly:pitch-semitones pitch) (list-ref tuning (1- string))))
+
+  (define (note-pitch a)
+    (ly:event-property a 'pitch))
+
+  (define (note-pitch<? a b)
+    (ly:pitch<? (note-pitch a)
+               (note-pitch b)))
+
+  (define (note-finger ev)
+    (let* ((articulations (ly:event-property ev 'articulations))
+          (finger-found #f))
+
+      (map (lambda (art)
+            (let*
+                ((num (ly:event-property art 'digit)))
+
+              (if (and (eq? 'fingering-event (ly:event-property art 'class))
+                       (number? num))
+                  (set! finger-found num))))
+          articulations)
+
+      finger-found))
+  
+  (define (note-string ev)
+    (let* ((articulations (ly:event-property ev 'articulations))
+          (string-found #f))
+
+      (map (lambda (art)
+            (let*
+                ((num (ly:event-property art 'string-number)))
+
+              (if (number? num)
+                  (set! string-found num))))
+          articulations)
+
+      string-found))
+
+  (define (del-string string)
+                     (if (number? string)
+                         (set! free-strings
+                               (delete string free-strings))))
+  (define specified-frets '())
+  (define free-strings '())
+  
+  (define (close-enough fret)
+                      (reduce
+                       (lambda (x y)
+                         (and x y))
+                       #t
+                       (map (lambda (specced-fret)
+                              (> max-stretch (abs (- fret specced-fret))))
+                            specified-frets)
+                       ))
+  
+  (define (string-qualifies string pitch)
+    (let*
+       ((fret (calc-fret pitch string tunings)))
+        
+        (and (>= fret minimum-fret)
+             (close-enough fret))
+        
+        ))
+                          
+  (define string-fret-fingering-tuples '())
+  (define (set-fret note string)
+                   (set! string-fret-fingering-tuples
+                         (cons (list string
+                                     (calc-fret (ly:event-property note 'pitch)
+                                                string tunings)
+                                     (note-finger note))
+                               string-fret-fingering-tuples))
+                   (del-string string))
+       
+
+  ;;; body.
+  (set! specified-frets
+       (filter identity (map
+                     (lambda (note)
+                       (if (note-string note)
+                           (calc-fret (note-pitch note)
+                                      (note-string note) tunings)
+                           #f))
+                     notes)))
+
+
+  (set! free-strings (map 1+ (iota (length tunings))))
+    
+  (for-each (lambda (note)
+             (del-string (note-string note)))
+           notes)
+  
+  
+  (for-each
+   (lambda (note)
+     (if (note-string note)
+        (set-fret note (note-string note))
+        (let*
+            ((fit-string (find (lambda (string) 
+                               (string-qualifies string (note-pitch note)))
+                           free-strings)))
+          (if fit-string
+              (set-fret note fit-string)
+              (ly:warning "No string for pitch ~a (given frets ~a)" 
+                           (note-pitch note)
+                          specified-frets))
+                          
+              )))
+   (sort notes note-pitch<?))
+
+  string-fret-fingering-tuples)