X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scm%2Flily.scm;h=31a24cd074cc9ab4edadc2f512cb28a5020c3ed6;hb=ed8702ba953fe9dd62927c6312b36b369f022f93;hp=1e6fab4f69b6eba5cd49b2331cfd3e5606cfe43a;hpb=b9c65b122d107a6f7c1a44d3041f6cfeb78fc4a2;p=lilypond.git diff --git a/scm/lily.scm b/scm/lily.scm index 1e6fab4f69..31a24cd074 100644 --- a/scm/lily.scm +++ b/scm/lily.scm @@ -2,104 +2,504 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 1998--2001 Jan Nieuwenhuizen +;;;; (c) 1998--2004 Jan Nieuwenhuizen ;;;; Han-Wen Nienhuys -;;; Library funtions +;;; Library functions -(use-modules (ice-9 regex)) -;;(write standalone (current-error-port)) +(use-modules (ice-9 regex) + (ice-9 safe) + (oop goops) + (srfi srfi-1) ; lists + (srfi srfi-13)) ; strings + +(define-public safe-module (make-safe-module)) + +(define-public (myd k v) (display k) (display ": ") (display v) (display ", ")) ;;; General settings +;;; debugging evaluator is slower. This should +;;; have a more sensible default. -(debug-enable 'backtrace) +(if (ly:get-option 'verbose) + (begin + (debug-enable 'debug) + (debug-enable 'backtrace) + (read-enable 'positions) )) -(define point-and-click #f) -(define security-paranoia #f) -(define midi-debug #f) -(define (line-column-location line col file) +(define-public (line-column-location line col file) "Print an input location, including column number ." (string-append (number->string line) ":" (number->string col) " " file) ) -(define (line-location line col file) +(define-public (line-location line col file) "Print an input location, without column number ." (string-append (number->string line) " " file) ) +(define-public point-and-click #f) + +(define-public (lilypond-version) + (string-join + (map (lambda (x) (if (symbol? x) + (symbol->string x) + (number->string x))) + (ly:version)) + ".")) + + + ;; cpp hack to get useful error message (define ifdef "First run this through cpp.") (define ifndef "First run this through cpp.") + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define-public X 0) +(define-public Y 1) +(define-public START -1) +(define-public STOP 1) +(define-public LEFT -1) +(define-public RIGHT 1) +(define-public UP 1) +(define-public DOWN -1) +(define-public CENTER 0) + +(define-public DOUBLE-FLAT -4) +(define-public THREE-Q-FLAT -3) +(define-public FLAT -2) +(define-public SEMI-FLAT -1) +(define-public NATURAL 0) +(define-public SEMI-SHARP 1) +(define-public SHARP 2) +(define-public THREE-Q-SHARP 3) +(define-public DOUBLE-SHARP 4) +(define-public SEMI-TONE 2) + +(define-public ZERO-MOMENT (ly:make-moment 0 1)) + +(define-public (moment-min a b) + (if (ly:momentstring (car x)) + (symbol->string (car y)))) -;; If you have trouble with regex, define #f -(define use-regex #t) -;;(define use-regex #f) -;;; Un-assorted stuff +(define (chain-assoc x alist-list) + (if (null? alist-list) + #f + (let* ((handle (assoc x (car alist-list)))) + (if (pair? handle) + handle + (chain-assoc x (cdr alist-list)))))) + +(define (chain-assoc-get x alist-list default) + (if (null? alist-list) + default + (let* ((handle (assoc x (car alist-list)))) + (if (pair? handle) + (cdr handle) + (chain-assoc-get x (cdr alist-list) default))))) + + +(define (map-alist-vals func list) + "map FUNC over the vals of LIST, leaving the keys." + (if (null? list) + '() + (cons (cons (caar list) (func (cdar list))) + (map-alist-vals func (cdr list))) + )) + +(define (map-alist-keys func list) + "map FUNC over the keys of an alist LIST, leaving the vals. " + (if (null? list) + '() + (cons (cons (func (caar list)) (cdar list)) + (map-alist-keys func (cdr list))) + )) + +;;;;;;;;;;;;;;;; +;; hash + + + +(if (not (defined? 'hash-table?)) ; guile 1.6 compat + (begin + (define hash-table? vector?) + + (define-public (hash-table->alist t) + "Convert table t to list" + (apply append + (vector->list t) + ))) + + ;; native hashtabs. + (begin + (define-public (hash-table->alist t) + + (hash-fold (lambda (k v acc) (acons k v acc)) + '() t) + ) + )) + +;; todo: code dup with C++. +(define-public (alist->hash-table l) + "Convert alist to table" + (let + ((m (make-hash-table (length l)))) + + (map (lambda (k-v) + (hashq-set! m (car k-v) (cdr k-v))) + l) + + m)) + + + +;;;;;;;;;;;;;;;; +; list + +(define (flatten-list lst) + "Unnest LST" + (if (null? lst) + '() + (if (pair? (car lst)) + (append (flatten-list (car lst)) (flatten-list (cdr lst))) + (cons (car lst) (flatten-list (cdr lst)))) + )) + +(define (list-minus a b) + "Return list of elements in A that are not in B." + (lset-difference eq? a b)) + + +;; TODO: use the srfi-1 partition function. +(define-public (uniq-list l) + + "Uniq LIST, assuming that it is sorted" + (define (helper acc l) + (if (null? l) + acc + (if (null? (cdr l)) + (cons (car l) acc) + (if (equal? (car l) (cadr l)) + (helper acc (cdr l)) + (helper (cons (car l) acc) (cdr l))) + ))) + (reverse! (helper '() l) '())) -;; URG guile-1.3/1.4 compatibility -(define (ly-eval x) (eval2 x #f)) +(define (split-at-predicate predicate l) + "Split L = (a_1 a_2 ... a_k b_1 ... b_k) +into L1 = (a_1 ... a_k ) and L2 =(b_1 .. b_k) +Such that (PREDICATE a_i a_{i+1}) and not (PREDICATE a_k b_1). +L1 is copied, L2 not. + +(split-at-predicate (lambda (x y) (= (- y x) 2)) '(1 3 5 9 11) (cons '() '()))" +;; " + +;; KUT EMACS MODE. + + (define (inner-split predicate l acc) + (cond + ((null? l) acc) + ((null? (cdr l)) + (set-car! acc (cons (car l) (car acc))) + acc) + ((predicate (car l) (cadr l)) + (set-car! acc (cons (car l) (car acc))) + (inner-split predicate (cdr l) acc)) + (else + (set-car! acc (cons (car l) (car acc))) + (set-cdr! acc (cdr l)) + acc) + + )) + (let* + ((c (cons '() '())) + ) + (inner-split predicate l c) + (set-car! c (reverse! (car c))) + c) +) + + +(define-public (split-list l sep?) +" +(display (split-list '(a b c / d e f / g) (lambda (x) (equal? x '/))) ) +=> +((a b c) (d e f) (g)) + +" +;; " KUT EMACS. + +(define (split-one sep? l acc) + "Split off the first parts before separator and return both parts." + (if (null? l) + (cons acc '()) + (if (sep? (car l)) + (cons acc (cdr l)) + (split-one sep? (cdr l) (cons (car l) acc)) + ) + )) + +(if (null? l) + '() + (let* ((c (split-one sep? l '()))) + (cons (reverse! (car c) '()) (split-list (cdr c) sep?)) + ))) + + +(define-public (interval-length x) + "Length of the number-pair X, when an interval" + (max 0 (- (cdr x) (car x))) + ) + + +(define (other-axis a) + (remainder (+ a 1) 2)) + + +(define-public (interval-widen iv amount) + (cons (- (car iv) amount) + (+ (cdr iv) amount))) + +(define-public (interval-union i1 i2) + (cons (min (car i1) (car i2)) + (max (cdr i1) (cdr i2)))) + + +(define-public (write-me message x) + "Return X. Display MESSAGE and write X. Handy for debugging, possibly turned off." + (display message) (write x) (newline) x) +;; x) + +(define (index-cell cell dir) + (if (equal? dir 1) + (cdr cell) + (car cell))) + +(define (cons-map f x) + "map F to contents of X" + (cons (f (car x)) (f (cdr x)))) + + +(define-public (list-insert-separator lst between) + "Create new list, inserting BETWEEN between elements of LIST" + (define (conc x y ) + (if (eq? y #f) + (list x) + (cons x (cons between y)) + )) + (fold-right conc #f lst)) + +;;;;;;;;;;;;;;;; +; other (define (sign x) (if (= x 0) - 1 + 0 (if (< x 0) -1 1))) +(define-public (symbolstring l) (symbol->string r))) + +(define-public (!= l r) + (not (= l r))) + +(define-public (ly:load x) + (let* ( + (fn (%search-load-path x)) + + ) + (if (ly:get-option 'verbose) + (format (current-error-port) "[~A]" fn)) + (primitive-load fn))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; output +(use-modules (scm output-tex) + (scm output-ps) + (scm output-sketch) + (scm output-sodipodi) + (scm output-pdftex) + ) + +(define output-alist + `( + ("tex" . ("TeX output. The default output form." ,tex-output-expression)) + ("ps" . ("Direct postscript. Requires setting GS_LIB and GS_FONTPATH" ,ps-output-expression)) + ("scm" . ("Scheme dump: debug scheme molecule expressions" ,write)) + ("sketch" . ("Bare bones Sketch output." ,sketch-output-expression)) + ("sodipodi" . ("Bare bones Sodipodi output." ,sodipodi-output-expression)) + ("pdftex" . ("PDFTeX output. Was last seen nonfunctioning." ,pdftex-output-expression)) + )) -;;(define major-scale -;; '( -;; (0 . 0) -;; (1 . 0) -;; (2 . 0) -;; (3 . 0) -;; (4 . 0) -;; (5 . 0) -;; (6 . 0) -;; )) +(define (document-format-dumpers) + (map + (lambda (x) + (display (string-append (pad-string-to 5 (car x)) (cadr x) "\n")) + output-alist) + )) -(map (lambda (x) (eval-string (ly-gulp-file x))) - '("output-lib.scm" - "tex.scm" - "ps.scm" - "ascii-script.scm" +(define-public (find-dumper format ) + (let* + ((d (assoc format output-alist))) + + (if (pair? d) + (caddr d) + (scm-error "Could not find dumper for format ~s" format)) + )) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; other files. + +(map ly:load + ; load-from-path + '("define-music-types.scm" + "output-lib.scm" + "c++.scm" + "chord-ignatzek-names.scm" + "chord-entry.scm" + "chord-generic-names.scm" + "molecule.scm" + "new-markup.scm" + "bass-figure.scm" + "music-functions.scm" + "part-combiner.scm" + "define-music-properties.scm" + "auto-beam.scm" + "chord-name.scm" + + "define-translator-properties.scm" + "translation-functions.scm" + "script.scm" + "midi.scm" + + "beam.scm" + "clef.scm" + "slur.scm" + "font.scm" + + "define-markup-commands.scm" + "define-grob-properties.scm" + "define-grobs.scm" + "define-grob-interfaces.scm" + + "paper.scm" )) -(if (not standalone) - (map (lambda (x) (eval-string (ly-gulp-file x))) - '("c++.scm" - "grob-property-description.scm" - "translator-property-description.scm" - "interface-description.scm" - "beam.scm" - "clef.scm" - "slur.scm" - "font.scm" - "music-functions.scm" - "auto-beam.scm" - "generic-property.scm" - "basic-properties.scm" - "chord-name.scm" - "grob-description.scm" - "script.scm" - "drums.scm" - "midi.scm" - ))) +(set! type-p-name-alist + `( + (,boolean-or-symbol? . "boolean or symbol") + (,boolean? . "boolean") + (,char? . "char") + (,grob-list? . "list of grobs") + (,hash-table? . "hash table") + (,input-port? . "input port") + (,integer? . "integer") + (,list? . "list") + (,ly:context? . "context") + (,ly:dimension? . "dimension, in staff space") + (,ly:dir? . "direction") + (,ly:duration? . "duration") + (,ly:grob? . "layout object") + (,ly:input-location? . "input location") + (,ly:input-location? . "input location") + (,ly:moment? . "moment") + (,ly:music? . "music") + (,ly:pitch? . "pitch") + (,ly:translator? . "translator") + (,markup-list? . "list of markups") + (,markup? . "markup") + (,music-list? . "list of music") + (,number-or-grob? . "number or grob") + (,number-or-string? . "number or string") + (,number-pair? . "pair of numbers") + (,number? . "number") + (,output-port? . "output port") + (,pair? . "pair") + (,procedure? . "procedure") + (,scheme? . "any type") + (,string? . "string") + (,symbol? . "symbol") + (,vector? . "vector") + )) + + +;; debug mem leaks + +(define gc-protect-stat-count 0) +(define-public (dump-gc-protects) + (set! gc-protect-stat-count (1+ gc-protect-stat-count) ) + + (display + (map (lambda (y) + (let + ((x (car y)) + (c (cdr y))) + + (string-append + (string-join + (map object->string (list (object-address x) c x)) + " ") + "\n"))) + + (sort + (hash-table->alist (ly:protects)) + (lambda (a b) + (< (object-address (car a)) + (object-address (car b))))) + + ) + (open-file (string-append + "gcstat-" (number->string gc-protect-stat-count) + ".scm" + ) "w")))