]> git.donarmstrong.com Git - lilypond.git/blobdiff - scm/translation-functions.scm
Imported Upstream version 2.16.0
[lilypond.git] / scm / translation-functions.scm
index 94862688fdb522ec369130ae485000983bafc582..33acfbc7b42178a6f2c5ca585a989d73d6c27bdf 100644 (file)
@@ -1,6 +1,6 @@
 ;;;; This file is part of LilyPond, the GNU music typesetter.
 ;;;;
-;;;; (c) 1998--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 1998--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
 ;;;;                Jan Nieuwenhuizen <janneke@gnu.org>
 ;;;;
 ;;;; LilyPond is free software: you can redistribute it and/or modify
@@ -276,13 +276,17 @@ dot placement entries."
 along with @var{minimum-fret}, @var{maximum-stretch}, and
 @var{tuning}.  Returns a list of @code{(string fret finger) lists."
 
+
+    (define restrain-open-strings (ly:context-property context
+                                                      'restrainOpenStrings
+                                                      #f))
     (define specified-frets '())
     (define free-strings (iota (length tuning) 1))
 
     (define (calc-fret pitch string tuning)
       "Calculate the fret to play @var{pitch} on @var{string} with
 @var{tuning}."
-      (- (ly:pitch-semitones pitch) (ly:pitch-semitones (list-ref tuning (1- string)))))
+      (* 2  (- (ly:pitch-tones pitch) (ly:pitch-tones (list-ref tuning (1- string))))))
 
     (define (note-pitch note)
       "Get the pitch (in semitones) from @var{note}."
@@ -296,7 +300,7 @@ if no fingering is present."
        (map (lambda (art)
               (let* ((num (ly:event-property art 'digit)))
 
-                (if (and (eq? 'fingering-event (ly:event-property art 'class))
+                (if (and (ly:in-event-class? art 'fingering-event)
                          (number? num)
                          (> num 0))
                   (set! finger-found num))))
@@ -326,6 +330,8 @@ if no string-number is present."
          #t
          (map (lambda (specced-fret)
                 (or (eq? 0 specced-fret)
+                    (and (not restrain-open-strings)
+                    (eq? 0 fret))
                     (>= maximum-stretch (abs (- fret specced-fret)))))
               specified-frets))))
 
@@ -333,7 +339,10 @@ if no string-number is present."
       "Can @var{pitch} be played on @var{string}, given already placed
 notes?"
       (let* ((fret (calc-fret pitch string tuning)))
-       (and (>= fret minimum-fret)
+       (and (or (and (not restrain-open-strings)
+                     (eq? fret 0))
+                (>= fret minimum-fret))
+            (integer? fret)
             (close-enough fret))))
 
     (define (open-string string pitch)
@@ -348,7 +357,10 @@ the current tuning?"
                                  tuning)))
        (if (< this-fret 0)
          (ly:warning (_ "Negative fret for pitch ~a on string ~a")
-                     (car pitch-entry) string))
+                     (car pitch-entry) string)
+         (if (not (integer? this-fret))
+             (ly:warning (_ "Missing fret for pitch ~a on string ~a")
+                         (car pitch-entry) string)))
        (delete-free-string string)
         (set! specified-frets (cons this-fret specified-frets))
         (list-set! string-fret-fingers
@@ -407,7 +419,7 @@ the current tuning?"
                            (ly:context-property context
                                                 'handleNegativeFrets
                                                 'recalculate)))
-                     (cond ((or (>= this-fret 0)
+                     (cond ((or (and (>= this-fret 0) (integer? this-fret))
                                 (eq? handle-negative 'include))
                              (set-fret! pitch-entry string finger))
                            ((eq? handle-negative 'recalculate)
@@ -565,7 +577,7 @@ only ~a fret labels provided")
 (define-public (fret-number-tablature-format
                 context string-number fret-number)
   (make-vcenter-markup
-    (format "~a" fret-number)))
+    (format #f "~a" fret-number)))
 
 ;; The 5-string banjo has got a extra string, the fifth (duh), which
 ;; starts at the fifth fret on the neck.  Frets on the fifth string
@@ -599,10 +611,10 @@ only ~a fret labels provided")
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; bar numbers
 
-(define-public ((every-nth-bar-number-visible n) barnum)
+(define-public ((every-nth-bar-number-visible n) barnum mp)
   (= 0 (modulo barnum n)))
 
-(define-public ((modulo-bar-number-visible n m) barnum)
+(define-public ((modulo-bar-number-visible n m) barnum mp)
   (and (> barnum 1) (= m (modulo barnum n))))
 
 (define-public ((set-bar-number-visibility n) tr)
@@ -610,9 +622,44 @@ only ~a fret labels provided")
     (ly:context-set-property! tr 'barNumberVisibility
                              (modulo-bar-number-visible n (modulo bn n)))))
 
-(define-public (first-bar-number-invisible barnum) (> barnum 1))
-
-(define-public (all-bar-numbers-visible barnum) #t)
+(define-public (first-bar-number-invisible barnum mp)
+  (> barnum 1))
+
+(define-public (first-bar-number-invisible-save-broken-bars barnum mp)
+  (or (> barnum 1)
+      (> (ly:moment-main-numerator mp) 0)))
+
+(define-public (first-bar-number-invisible-and-no-parenthesized-bar-numbers barnum mp)
+  (and (> barnum 1)
+       (= (ly:moment-main-numerator mp) 0)))
+
+(define-public (robust-bar-number-function barnum measure-pos alt-number context)
+  (define (get-number-and-power an pow)
+    (if (<= an alt-number)
+        (get-number-and-power (+ an (expt 26 (1+ pow))) (1+ pow))
+        (cons (+ alt-number (- (expt 26 pow) an)) (1- pow))))
+  (define (make-letter so-far an pow)
+    (if (< pow 0)
+      so-far
+      (let ((pos (modulo (quotient an (expt 26 pow)) 26)))
+        (make-letter (string-append so-far
+                                    (substring "abcdefghijklmnopqrstuvwxyz"
+                                               pos
+                                               (1+ pos)))
+                   an
+                   (1- pow)))))
+  (let* ((number-and-power (get-number-and-power 0 0))
+         (begin-measure (= 0 (ly:moment-main-numerator measure-pos)))
+         (maybe-open-parenthesis (if begin-measure "" "("))
+         (maybe-close-parenthesis (if begin-measure "" ")")))
+    (markup (string-append maybe-open-parenthesis
+                           (number->string barnum)
+                           (make-letter ""
+                                        (car number-and-power)
+                                        (cdr number-and-power))
+                           maybe-close-parenthesis))))
+
+(define-public (all-bar-numbers-visible barnum mp) #t)
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -622,3 +669,39 @@ only ~a fret labels provided")
   (= 0 (modulo count n)))
 
 (define-public (all-repeat-counts-visible count context) #t)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; make-engraver helper macro
+
+(defmacro-public make-engraver forms
+  "Helper macro for creating Scheme engravers.
+
+The usual form for an engraver is an association list (or alist)
+mapping symbols to either anonymous functions or to another such
+alist.
+
+@code{make-engraver} accepts forms where the first element is either
+an argument list starting with the respective symbol, followed by the
+function body (comparable to the way @code{define} is used for
+defining functions), or a single symbol followed by subordinate forms
+in the same manner.  You can also just make an alist pair
+literally (the @samp{car} is quoted automatically) as long as the
+unevaluated @samp{cdr} is not a pair.  This is useful if you already
+have defined your engraver functions separately.
+
+Symbols mapping to a function would be @code{initialize},
+@code{start-translation-timestep}, @code{process-music},
+@code{process-acknowledged}, @code{stop-translation-timestep}, and
+@code{finalize}.  Symbols mapping to another alist specified in the
+same manner are @code{listeners} with the subordinate symbols being
+event classes, and @code{acknowledgers} and @code{end-acknowledgers}
+with the subordinate symbols being interfaces."
+  (let loop ((forms forms))
+    (if (cheap-list? forms)
+       `(list
+         ,@(map (lambda (form)
+                  (if (pair? (car form))
+                      `(cons ',(caar form) (lambda ,(cdar form) ,@(cdr form)))
+                      `(cons ',(car form) ,(loop (cdr form)))))
+                forms))
+       forms)))