;;;; 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))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(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
(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}."
"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))
(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
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))))
(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")))