X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scm%2Flily-library.scm;h=6e30cf6ae541780e331d2e5602c1d01379665dbe;hb=e28484ea68c8cbcdaa5edfe7211b11f0d1779ff9;hp=85bf5db019dbe36baf5f627ed9d8dce96469551a;hpb=2e538595214c8c70f863a43859faad5ff9b1ac31;p=lilypond.git diff --git a/scm/lily-library.scm b/scm/lily-library.scm index 85bf5db019..6e30cf6ae5 100644 --- a/scm/lily-library.scm +++ b/scm/lily-library.scm @@ -1,9 +1,10 @@ +;;;; ;;;; lily-library.scm -- utilities ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 1998--2005 Jan Nieuwenhuizen -;;;; Han-Wen Nienhuys +;;;; (c) 1998--2006 Jan Nieuwenhuizen +;;;; Han-Wen Nienhuys (define-public X 0) @@ -43,34 +44,82 @@ ;; parser stuff. (define-public (print-music-as-book parser music) - (let* ((head (ly:parser-lookup parser '$globalheader)) - (book (ly:make-book (ly:parser-lookup parser $defaultpaper) - head score))) - (ly:parser-print-book parser book))) + (let* ((head (ly:parser-lookup parser '$defaultheader)) + (book (ly:make-book (ly:parser-lookup parser '$defaultpaper) + head (scorify-music music parser)))) + (print-book-with-defaults parser book))) (define-public (print-score-as-book parser score) - (let* ((head (ly:parser-lookup parser '$globalheader)) - (book (ly:make-book (ly:parser-lookup parser $defaultpaper) + (let* ((head (ly:parser-lookup parser '$defaultheader)) + (book (ly:make-book (ly:parser-lookup parser '$defaultpaper) head score))) - (ly:parser-print-book parser book))) + (print-book-with-defaults parser book))) (define-public (print-score parser score) - (let* ((head (ly:parser-lookup parser '$globalheader)) - (book (ly:make-book (ly:parser-lookup parser $defaultpaper) + (let* ((head (ly:parser-lookup parser '$defaultheader)) + (book (ly:make-book (ly:parser-lookup parser '$defaultpaper) head score))) (ly:parser-print-score parser book))) -(define-public (collect-scores-for-book parser score) - (let* ((oldval (ly:parser-lookup parser 'toplevel-scores))) - (ly:parser-define parser 'toplevel-scores (cons score oldval)))) +(define-public (collect-scores-for-book parser score) + (ly:parser-define! + parser 'toplevel-scores + (cons score (ly:parser-lookup parser 'toplevel-scores)))) + + +(define-public (scorify-music music parser) + + (for-each (lambda (func) + (set! music (func music parser))) + toplevel-music-functions) + + (ly:make-score music)) (define-public (collect-music-for-book parser music) - (collect-scores-for-book parser (ly:music-scorify music parser))) + ;; discard music if its 'void property is true. + (let ((void-music (ly:music-property music 'void))) + (if (or (null? void-music) (not void-music)) + (collect-scores-for-book parser (scorify-music music parser))))) + + +(define-public (print-book-with-defaults parser book) + (let* + ((paper (ly:parser-lookup parser '$defaultpaper)) + (layout (ly:parser-lookup parser '$defaultlayout)) + (count (ly:parser-lookup parser 'output-count)) + (base (ly:parser-output-name parser))) + + (if (not (integer? count)) + (set! count 0)) + + (if (> count 0) + (set! base (format #f "~a-~a" base count))) + + (ly:parser-define! parser 'output-count (1+ count)) + (ly:book-process book paper layout base) + )) + +(define-public (print-score-with-defaults parser score) + (let* + ((paper (ly:parser-lookup parser '$defaultpaper)) + (layout (ly:parser-lookup parser '$defaultlayout)) + (header (ly:parser-lookup parser '$defaultheader)) + (count (ly:parser-lookup parser 'output-count)) + (base (ly:parser-output-name parser))) + + (if (not (integer? count)) + (set! count 0)) + + (if (> count 0) + (set! base (format #f "~a-~a" base count))) + + (ly:parser-define! parser 'output-count (1+ count)) + (ly:score-process score header paper layout base) + )) - ;;;;;;;;;;;;;;;; -; alist +;; alist (define-public assoc-get ly:assoc-get) (define-public (uniqued-alist alist acc) @@ -119,7 +168,28 @@ found." '() (cons (cons (func (caar list)) (cdar list)) (map-alist-keys func (cdr list))))) - + +(define-public (first-member members lst) + "Return first successful MEMBER of member from MEMBERS in LST." + (if (null? members) + #f + (let ((m (member (car members) lst))) + (if m m (first-member (cdr members) lst))))) + +(define-public (first-assoc keys lst) + "Return first successful ASSOC of key from KEYS in LST." + (if (null? keys) + #f + (let ((k (assoc (car keys) lst))) + (if k k (first-assoc (cdr keys) lst))))) + +(define-public (flatten-alist alist) + (if (null? alist) + '() + (cons (caar alist) + (cons (cdar alist) + (flatten-alist (cdr alist)))))) + ;;;;;;;;;;;;;;;; ;; vector (define-public (vector-for-each proc vec) @@ -134,7 +204,12 @@ found." (if (not (defined? 'hash-table?)) ;; guile 1.6 compat (begin (define hash-table? vector?) - + (define-public (hash-for-each proc tab) + (hash-fold (lambda (k v prior) + (proc k v) + #f) + #f + tab)) (define-public (hash-table->alist t) "Convert table t to list" (apply append (vector->list t)))) @@ -153,7 +228,34 @@ found." m)) ;;;;;;;;;;;;;;;; -; list +;; list + + +(define-public (count-list lst) + "Given lst (E1 E2 .. ) return ((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))) + +(define-public (list-join lst intermediate) + "put INTERMEDIATE between all elts of LST." + + (fold-right + (lambda (elem prev) + (if (pair? prev) + (cons elem (cons intermediate prev)) + (list elem))) + '() lst)) + +(define-public (filtered-map proc lst) + (filter + (lambda (x) x) + (map proc lst))) + (define (flatten-list lst) "Unnest LST" @@ -235,18 +337,59 @@ found." (define-public (offset-flip-y o) (cons (car o) (- (cdr o)))) +(define-public (offset-scale o scale) + (cons (* (car o) scale) + (* (cdr o) scale))) + (define-public (ly:list->offsets accum coords) (if (null? coords) accum (cons (cons (car coords) (cadr coords)) (ly:list->offsets accum (cddr coords))))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; numbers + +(if (not (defined? 'nan?)) ;; guile 1.6 compat + (define-public (nan? x) (not (or (< 0.0 x) + (> 0.0 x) + (= 0.0 x))))) + +(if (not (defined? 'inf?)) + (define-public (inf? x) (= (/ 1.0 x) 0.0))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; intervals + (define-public (interval-length x) "Length of the number-pair X, when an interval" (max 0 (- (cdr x) (car x)))) +(define-public interval-start car) +(define-public (ordered-cons a b) + (cons (min a b) + (max a b))) + +(define-public interval-end cdr) + +(define-public (interval-index interval dir) + "Interpolate INTERVAL between between left (DIR=-1) and right (DIR=+1)" + + (* (+ (interval-start interval) (interval-end interval) + (* dir (- (interval-end interval) (interval-start interval)))) + 0.5)) + +(define-public (interval-center x) + "Center the number-pair X, when an interval" + (if (interval-empty? x) + 0.0 + (/ (+ (car x) (cdr x)) 2))) + (define-public interval-start car) (define-public interval-end cdr) +(define-public (interval-translate iv amount) + (cons (+ amount (car iv)) + (+ amount (cdr iv)))) (define (other-axis a) (remainder (+ a 1) 2)) @@ -255,10 +398,55 @@ found." (cons (- (car iv) amount) (+ (cdr iv) amount))) + +(define-public (interval-empty? iv) + (> (car iv) (cdr iv))) + (define-public (interval-union i1 i2) (cons (min (car i1) (car i2)) (max (cdr i1) (cdr i2)))) +(define-public (interval-sane? i) + (not (or (nan? (car i)) + (inf? (car i)) + (nan? (cdr i)) + (inf? (cdr i)) + (> (car i) (cdr i))))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; + + +(define-public (string-encode-integer i) + (cond + ((= i 0) "o") + ((< i 0) (string-append "n" (string-encode-integer (- i)))) + (else (string-append + (make-string 1 (integer->char (+ 65 (modulo i 26)))) + (string-encode-integer (quotient i 26)))))) + +(define-public (ly:numbers->string lst) + (string-join (map ly:number->string lst) " ")) + +(define (number->octal-string x) + (let* ((n (inexact->exact x)) + (n64 (quotient n 64)) + (n8 (quotient (- n (* n64 64)) 8))) + (string-append + (number->string n64) + (number->string n8) + (number->string (remainder (- n (+ (* n64 64) (* n8 8))) 8))))) + +(define-public (ly:inexact->string x radix) + (let ((n (inexact->exact x))) + (number->string n radix))) + +(define-public (ly:number-pair->string c) + (string-append (ly:number->string (car c)) " " + (ly:number->string (cdr c)))) + + (define-public (write-me message x) "Return X. Display MESSAGE and write X. Handy for debugging, possibly turned off." @@ -269,6 +457,10 @@ possibly turned off." (apply format (cons (current-error-port) (cons string rest))) (force-output (current-error-port))) +(define-public (debugf string . rest) + (if #f + (apply stderr (cons string rest)))) + (define (index-cell cell dir) (if (equal? dir 1) (cdr cell) @@ -286,6 +478,29 @@ possibly turned off." (cons x (cons between y)))) (fold-right conc #f lst)) +(define-public (string-regexp-substitute a b str) + (regexp-substitute/global #f a str 'pre b 'post)) + +(define (regexp-split str regex) + (define matches '()) + (define end-of-prev-match 0) + (define (notice match) + + (set! matches (cons (substring (match:string match) + end-of-prev-match + (match:start match)) + matches)) + (set! end-of-prev-match (match:end match))) + + (regexp-substitute/global #f regex str notice 'post) + + (if (< end-of-prev-match (string-length str)) + (set! + matches + (cons (substring str end-of-prev-match (string-length str)) matches))) + + (reverse matches)) + ;;;;;;;;;;;;;;;; ; other (define (sign x) @@ -293,71 +508,69 @@ possibly turned off." 0 (if (< x 0) -1 1))) +(define-public (car< a b) (< (car a) (car b))) + (define-public (symbolstring lst) (symbol->string r))) +(define-public (symbol-keystring (car lst)) (symbol->string (car r)))) + +;; +;; don't confuse users with # syntax. +;; +(define-public (scm->string val) + (if (and (procedure? val) (symbol? (procedure-name val))) + (symbol->string (procedure-name val)) + (string-append + (if (self-evaluating? val) "" "'") + (call-with-output-string (lambda (port) (display val port)))))) + (define-public (!= lst r) (not (= lst r))) -(define-public scale-to-unit +(define-public lily-unit->bigpoint-factor (cond ((equal? (ly:unit) "mm") (/ 72.0 25.4)) ((equal? (ly:unit) "pt") (/ 72.0 72.27)) - (else (error "unknown unit" (ly:unit))))) + (else (ly:error (_ "unknown unit: ~S") (ly:unit))))) -;;; font +(define-public lily-unit->mm-factor + (* 25.4 (/ lily-unit->bigpoint-factor 72))) + +;;; FONT may be font smob, or pango font string... (define-public (font-name-style font) - ;; FIXME: ughr, (ly:font-name) sometimes also has Style appended. - (let* ((font-name (ly:font-name font)) - (full-name (if font-name font-name (ly:font-file-name font))) - (name-style (string-split full-name #\-))) - ;; FIXME: ughr, barf: feta-alphabet is actually emmentaler - (if (string-prefix? "feta-alphabet" full-name) - (list "emmentaler" - (substring full-name (string-length "feta-alphabet"))) - (if (not (null? (cdr name-style))) + ;; FIXME: ughr, (ly:font-name) sometimes also has Style appended. + (let* ((font-name (ly:font-name font)) + (full-name (if font-name font-name (ly:font-file-name font))) + (name-style (string-split full-name #\-))) + ;; FIXME: ughr, barf: feta-alphabet is actually emmentaler + (if (string-prefix? "feta-alphabet" full-name) + (list "emmentaler" + (substring full-name (string-length "feta-alphabet"))) + (if (not (null? (cdr name-style))) name-style (append name-style '("Regular")))))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(define-public (ps-embed-cff body font-set-name version) - (let* ((binary-data - (string-append - (format "/~a ~s StartData " font-set-name (string-length body)) - body)) - - (header - (format - "%%BeginResource: font ~a -%!PS-Adobe-3.0 Resource-FontSet -%%DocumentNeededResources: ProcSet (FontSetInit) -%%Title: (FontSet/~a) -%%Version: ~s -%%EndComments -%%IncludeResource: ProcSet (FontSetInit) -%%BeginResource: FontSet (~a) -/FontSetInit /ProcSet findresource begin -%%BeginData: ~s Binary Bytes -" - font-set-name font-set-name version font-set-name - (string-length binary-data))) - (footer "\n%%EndData -%%EndResource -%%EOF -%%EndResource\n")) - - (string-append - header - binary-data - footer))) - -(define-public (version-not-seen-message) - (ly:warn +(define-public (modified-font-metric-font-scaling font) + (let* ((designsize (ly:font-design-size font)) + (magnification (* (ly:font-magnification font))) + (scaling (* magnification designsize))) + (debugf "scaling:~S\n" scaling) + (debugf "magnification:~S\n" magnification) + (debugf "design:~S\n" designsize) + scaling)) + +(define-public (version-not-seen-message input-file-name) + (ly:message + (string-append + input-file-name ": 0: " (_ "warning: ") (format #f - (_ "No \\version statement found. Please add~afor future compatibility.") - (format #f "\n\n\\version ~s\n\n" (lilypond-version)))) - (newline (current-error-port))) - - + (_ "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:message + (string-append + input-file-name ": 0: " (_ "warning: ") + (_ "old relative compatibility not used"))))