]> git.donarmstrong.com Git - lilypond.git/blobdiff - scm/lily-library.scm
Reformat some files to let emacs do its work correctly.
[lilypond.git] / scm / lily-library.scm
index 5519bb8263207d5faa33c5ec77ecdfefd324d2bf..48ee33cf50f20be5dca07da805bfa6e2d7d28dcf 100644 (file)
 ;;;; You should have received a copy of the GNU General Public License
 ;;;; along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 
-; for take, drop, take-while, list-index, and find-tail:
+;; for take, drop, take-while, list-index, and find-tail:
 (use-modules (srfi srfi-1))
 
-; for define-safe-public when byte-compiling using Guile V2
+;; for define-safe-public when byte-compiling using Guile V2
 (use-modules (scm safe-utility-defs))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -57,6 +57,8 @@
 (define-safe-public DOUBLE-SHARP 1)
 (define-safe-public SEMI-TONE 1/2)
 
+(define-safe-public INFINITY-INT 1000000)
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; moments
 
   (cons (ly:moment-main-numerator moment)
         (ly:moment-main-denominator moment)))
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; durations
+
+(define-public (duration-log-factor lognum)
+"Given a logarithmic duration number, return the length of the duration,
+as a number of whole notes."
+  (or (and (exact? lognum) (integer? lognum))
+    (scm-error 'wrong-type-arg "duration-log-factor" "Not an integer: ~S" (list lognum) #f))
+  (if (<= lognum 0)
+    (ash 1 (- lognum))
+    (/ (ash 1 lognum))))
+
+(define-public (duration-dot-factor dotcount)
+"Given a count of the dots used to extend a musical duration, return
+the numeric factor by which they increase the duration."
+  (or (and (exact? dotcount) (integer? dotcount) (>= dotcount 0))
+    (scm-error 'wrong-type-arg "duration-dot-factor" "Not a count: ~S" (list dotcount) #f))
+  (- 2 (/ (ash 1 dotcount))))
+
+(define-public (duration-length dur)
+"Return the overall length of a duration, as a number of whole notes.
+(Not to be confused with ly:duration-length, which returns a less-useful
+moment object.)"
+  (ly:moment-main (ly:duration-length dur)))
+
+(define-public (duration-visual dur)
+"Given a duration object, return the visual part of the duration (base
+note length and dot count), in the form of a duration object with
+non-visual scale factor 1."
+  (ly:make-duration (ly:duration-log dur) (ly:duration-dot-count dur) 1))
+
+(define-public (duration-visual-length dur)
+"Given a duration object, return the length of the visual part of the
+duration (base note length and dot count), as a number of whole notes."
+  (duration-length (duration-visual dur)))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; arithmetic
 (define-public (average x . lst)
 
 (define-public (collect-music-aux score-handler parser music)
   (define (music-property symbol)
-    (let ((value (ly:music-property music symbol)))
-      (if (not (null? value))
-         value
-         #f)))
+    (ly:music-property music symbol #f))
   (cond ((music-property 'page-marker)
         ;; a page marker: set page break/turn permissions or label
-        (begin
-          (let ((label (music-property 'page-label)))
-            (if (symbol? label)
-                (score-handler (ly:make-page-label-marker label))))
-          (for-each (lambda (symbol)
-                      (let ((permission (music-property symbol)))
-                        (if (symbol? permission)
-                            (score-handler
-                             (ly:make-page-permission-marker symbol
-                                                             (if (eqv? 'forbid permission)
-                                                                 '()
-                                                                 permission))))))
-                    (list 'line-break-permission 'page-break-permission
-                          'page-turn-permission))))
-       ((not (music-property 'void))
+         (let ((label (music-property 'page-label)))
+           (if (symbol? label)
+               (score-handler (ly:make-page-label-marker label))))
+         (for-each (lambda (symbol)
+                     (let ((permission (music-property symbol)))
+                       (if (symbol? permission)
+                           (score-handler
+                            (ly:make-page-permission-marker symbol
+                                                            (if (eq? 'forbid permission)
+                                                                '()
+                                                                permission))))))
+                   '(line-break-permission page-break-permission
+                                           page-turn-permission)))
+        ((not (music-property 'void))
         ;; a regular music expression: make a score with this music
         ;; void music is discarded
         (score-handler (scorify-music music parser)))))
 
 (define-public (scorify-music music parser)
   "Preprocess @var{music}."
-
-  (for-each (lambda (func)
-             (set! music (func music parser)))
-           toplevel-music-functions)
-
-  (ly:make-score music))
-
+  (ly:make-score
+   (fold (lambda (f m) (f m parser))
+         music
+         toplevel-music-functions)))
 
 (define (get-current-filename parser book)
   "return any suffix value for output filename allowing for settings by
 calls to bookOutputName function"
-  (let ((book-filename (paper-variable parser book 'output-filename)))
-    (if (not book-filename)
-       (ly:parser-output-name parser)
-       book-filename)))
+  (or (paper-variable parser book 'output-filename)
+      (ly:parser-output-name parser)))
 
 (define (get-current-suffix parser book)
   "return any suffix value for output filename allowing for settings by calls to
@@ -505,19 +534,12 @@ For example:
   (helper lst (make-vector n '()) (1- n)))
 
 (define (list-element-index lst x)
-  (list-index (lambda (m) (equal? m x))))
+  (list-index (lambda (m) (equal? m x)) lst))
 
 (define-public (count-list lst)
   "Given @var{lst} as @code{(E1 E2 .. )}, return
 @code{((E1 . 1) (E2 . 2) ... )}."
-
-  (define (helper l acc count)
-    (if (pair? l)
-       (helper (cdr l) (cons (cons (car l) count) acc) (1+ count))
-       acc))
-
-
-  (reverse (helper lst '() 1)))
+  (map cons lst (iota (length lst) 1)))
 
 (define-public (list-join lst intermediate)
   "Put @var{intermediate} between all elts of @var{lst}."
@@ -562,28 +584,27 @@ for comparisons."
   "Split LST into two lists at the first element that returns #f for
   (PRED previous_element element).  Return the two parts as a pair.
   Example: (split-at-predicate < '(1 2 3 2 1)) ==> ((1 2 3) . (2 1))"
-  (if (null? lst)
-      (list lst)
-      (let ((i (list-index (lambda (x y) (not (pred x y)))
-                          lst
-                          (cdr lst))))
-        (if i
-            (cons (take lst (1+ i)) (drop lst (1+ i)))
-            (list lst)))))
+  (let ((i (and (pair? lst)
+                (list-index (lambda (x y) (not (pred x y)))
+                            lst
+                            (cdr lst)))))
+    (if i
+        (call-with-values
+            (lambda () (split-at lst (1+ i)))
+          cons)
+        (list lst))))
 
 (define-public (split-list-by-separator lst pred)
   "Split @var{lst} at each element that satisfies @var{pred}, and return
 the parts (with the separators removed) as a list of lists.  For example,
 executing @samp{(split-list-by-separator '(a 0 b c 1 d) number?)} returns
 @samp{((a) (b c) (d))}."
-  (let loop ((result '()) (lst lst))
-    (if (and lst (not (null? lst)))
-        (loop
-          (append result
-                  (list (take-while (lambda (x) (not (pred x))) lst)))
-          (let ((tail (find-tail pred lst)))
-            (if tail (cdr tail) #f)))
-       result)))
+  (call-with-values (lambda () (break pred lst))
+    (lambda (head tail)
+      (cons head
+            (if (null? tail)
+                tail
+                (split-list-by-separator (cdr tail) pred))))))
 
 (define-public (offset-add a b)
   (cons (+ (car a) (car b))
@@ -677,15 +698,6 @@ right (@var{dir}=+1)."
 (define-public (reverse-interval iv)
   (cons (cdr iv) (car iv)))
 
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; boolean
-
-(define (lily-and a b)
-  (and a b))
-
-(define (lily-or a b)
-  (or a b))
-
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; coordinates
 
@@ -920,13 +932,10 @@ in module @var{module}.  In that case evaluate, otherwise
 print a warning and set an optional @var{default}."
   (let* ((unavailable? (lambda (sym)
                          (not (module-defined? module sym))))
-        (sym-unavailable (if (pair? symbol)
-                             (filter
-                               unavailable?
-                               (filter symbol? (flatten-list symbol)))
-                             (if (unavailable? symbol)
-                                  #t
-                                  '()))))
+        (sym-unavailable
+          (filter
+           unavailable?
+           (filter symbol? (flatten-list symbol)))))
     (if (null? sym-unavailable)
         (eval symbol module)
         (let* ((def (and (pair? default) (car default))))
@@ -989,8 +998,3 @@ print a warning and set an optional @var{default}."
     (ly:format "~a:1" input-file-name)
     (_ "no \\version statement found, please add~afor future compatibility")
     (format #f "\n\n\\version ~s\n\n" (lilypond-version))))
-
-(define-public (old-relative-not-used-message input-file-name)
-  (ly:warning-located
-    (ly:format "~a:1" input-file-name)
-    (_ "old relative compatibility not used")))