X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;ds=sidebyside;f=scm%2Flily.scm;h=65c861cca745ee99882ecefe109b45d21159ff4a;hb=2086beff8cd9949318c97a2a531edb8f04f45f8c;hp=be6872c6779dd92b43660812b78496e492f19117;hpb=fdb66b65c89bf9e98da8975999815228d5f0449e;p=lilypond.git diff --git a/scm/lily.scm b/scm/lily.scm index be6872c677..65c861cca7 100644 --- a/scm/lily.scm +++ b/scm/lily.scm @@ -1,769 +1,433 @@ ;;; lily.scm -- implement Scheme output routines for TeX and PostScript -;;; -;;; source file of the GNU LilyPond music typesetter -;;; -;;; (c) 1998--2000 Jan Nieuwenhuizen -;;; Han-Wen Nienhuys +;;;; +;;;; source file of the GNU LilyPond music typesetter +;;;; +;;;; (c) 1998--2002 Jan Nieuwenhuizen +;;;; Han-Wen Nienhuys +;;; Library functions -;;; -;;; This file contains various routines in Scheme that are easier to -;;; do here than in C++. At present it is an unorganised mess. Sorry. - - -;;; We should repartition the entire scm side of lily in a -;;; more sane way, using namesspaces/modules? - -(debug-enable 'backtrace) - -;;; library funtions (use-modules (ice-9 regex)) -(define (number-pair? x) - (and (pair? x) (number? (car x)) (number? (cdr x)))) - -(define (object-type obj) - (cond - ((dir? obj) "direction") - ((number-pair? obj) "pair of numbers") - ((ly-input-location? obj) "input location") - ((ly-element? obj) "graphic element") - ((pair? obj) "pair") - ((integer? obj) "integer") - ((list? obj) "list") - ((symbol? obj) "symbol") - ((string? obj) "string") - ((boolean? obj) "boolean") - ((moment? obj) "moment") - ((number? obj) "number") - ((char? obj) "char") - ((input-port? obj) "input port") - ((output-port? obj) "output port") - ((vector? obj) "vector") - ((procedure? obj) "procedure") - (else "unknown type") - )) - - -(define (type-name predicate) - (cond - ((eq? predicate dir?) "direction") - ((eq? predicate number-pair?) "pair of numbers") - ((eq? predicate ly-input-location?) "input location") - ((eq? predicate ly-element?) "graphic element") - ((eq? predicate pair?) "pair") - ((eq? predicate integer?) "integer") - ((eq? predicate list?) "list") - ((eq? predicate symbol?) "symbol") - ((eq? predicate string?) "string") - ((eq? predicate boolean?) "boolean") - ((eq? predicate moment?) "moment") - ((eq? predicate number?) "number") - ((eq? predicate char?) "char") - ((eq? predicate input-port?) "input port") - ((eq? predicate output-port?) "output port") - ((eq? predicate vector?) "vector") - ((eq? predicate procedure?) "procedure") - (else "unknown type") - )) - - -;; The regex module may not be available, or may be broken. -(define use-regex - (let ((os (string-downcase (vector-ref (uname) 0)))) - (not (equal? "cygwin" (substring os 0 (min 6 (string-length os))))))) - -;; If you have trouble with regex, define #f -(define use-regex #t) -;;(define use-regex #f) -;; do nothing in .scm output -(define (comment s) "") +;;; General settings +;; debugging evaluator is slower. -;; URG guile-1.3/1.4 compatibility -(define (ly-eval x) (eval2 x #f)) +(debug-enable 'debug) +;(debug-enable 'backtrace) +(read-enable 'positions) -(define (comment s) "") -(define (mm-to-pt x) - (* (/ 72.27 25.40) x) +(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 (cons-map f x) - (cons (f (car x)) (f (cdr x)))) - -(define (reduce operator list) - (if (null? (cdr list)) (car list) - (operator (car list) (reduce operator (cdr list))) - ) - ) - - -(define (numbers->string l) - (apply string-append (map ly-number->string l))) - -; (define (chop-decimal x) (if (< (abs x) 0.001) 0.0 x)) - -(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 (inexact->string x radix) - (let ((n (inexact->exact x))) - (number->string n radix))) - - -(define (control->string c) - (string-append (number->string (car c)) " " - (number->string (cdr c)) " ")) - -(define (font i) - (string-append - "font" - (make-string 1 (integer->char (+ (char->integer #\A) i))) - )) - -(define (scm-scm action-name) - 1) - -(define security-paranoia #f) - - -;; silly, use alist? -(define (find-notehead-symbol duration style) - (case style - ((cross) "2cross") - ((harmonic) "0mensural") - ((baroque) - (string-append (number->string duration) - (if (< duration 0) "mensural" ""))) - ((default) (number->string duration)) - (else - (string-append (number->string duration) (symbol->string style)))) +(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) -;;;;;;;; TeX +;; cpp hack to get useful error message +(define ifdef "First run this through cpp.") +(define ifndef "First run this through cpp.") -(define (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 default-script-alist '()) -(define font-name-alist '()) -(define (tex-encoded-fontswitch name-mag) - (let* ( - (iname-mag (car name-mag)) - (ename-mag (cdr name-mag)) - ) - (cons iname-mag - (cons ename-mag - (string-append "magfont" - (string-encode-integer - (hashq (car ename-mag) 1000000)) - "m" - (string-encode-integer - (inexact->exact (* 1000 (cdr ename-mag)))) - - ) - ) - ))) - -(define (define-fonts internal-external-name-mag-pairs) - (set! font-name-alist (map tex-encoded-fontswitch - internal-external-name-mag-pairs)) - (apply string-append - (map (lambda (x) - (font-load-command (car x) (cdr x))) - (map cdr font-name-alist) - ))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define (fontify name-mag-pair exp) - (string-append (select-font name-mag-pair) - exp) - ) +(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) -;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; lily specific variables. +(define-public default-script-alist '()) +(define-public security-paranoia #f) -; Make a function that checks score element for being of a specific type. -(define (make-type-checker symbol) - (lambda (elt) - ;;(display symbol) - ;;(eq? #t (ly-get-elt-property elt symbol)) - (not (eq? #f (memq symbol (ly-get-elt-property elt 'interfaces)))) - )) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Unassorted utility functions. -;;;;;;;;;;;;;;;;;;; TeX output -(define (tex-scm action-name) - (define (unknown) - "%\n\\unknown%\n") +;;;;;;;;;;;;;;;; +; alist +(define (uniqued-alist alist acc) + (if (null? alist) acc + (if (assoc (caar alist) acc) + (uniqued-alist (cdr alist) acc) + (uniqued-alist (cdr alist) (cons (car alist) acc))))) - (define (select-font name-mag-pair) - (let* - ( - (c (assoc name-mag-pair font-name-alist)) - ) - (if (eq? c #f) - (begin - (display "FAILED\n") - (display (object-type (car name-mag-pair))) - (display (object-type (caaar font-name-alist))) - - (ly-warn (string-append - "Programming error: No such font known " - (car name-mag-pair) " " - (number->string (cdr name-mag-pair)) - )) - "") ; issue no command - (string-append "\\" (cddr c))) - - - )) +(define (assoc-get key alist) + "Return value if KEY in ALIST, else #f." + (let ((entry (assoc key alist))) + (if entry (cdr entry) #f))) - (define (beam width slope thick) - (embedded-ps ((ps-scm 'beam) width slope thick))) - - (define (bracket arch_angle arch_width arch_height width height arch_thick thick) - (embedded-ps ((ps-scm 'bracket) arch_angle arch_width arch_height width height arch_thick thick))) - - (define (dashed-slur thick dash l) - (embedded-ps ((ps-scm 'dashed-slur) thick dash l))) - - (define (crescendo thick w h cont) - (embedded-ps ((ps-scm 'crescendo) thick w h cont))) +(define (assoc-get-default key alist default) + "Return value if KEY in ALIST, else DEFAULT." + (let ((entry (assoc key alist))) + (if entry (cdr entry) default))) + + +(define-public (uniqued-alist alist acc) + (if (null? alist) acc + (if (assoc (caar alist) acc) + (uniqued-alist (cdr alist) acc) + (uniqued-alist (cdr alist) (cons (car alist) acc))))) + +(define-public (aliststring (car x)) + (symbol->string (car y)))) + +;;;;;;;;;;;;;;;; +; list +(define (tail lst) + "Return tail element of LST." + (car (last-pair lst))) + + +(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 (char i) - (string-append "\\char" (inexact->string i 10) " ")) +(define (list-minus a b) + "Return list of elements in A that are not in B." + (if (pair? a) + (if (pair? b) + (if (member (car a) b) + (list-minus (cdr a) b) + (cons (car a) (list-minus (cdr a) b))) + a) + '())) + +;; why -list suffix (see reduce-list) +(define-public (filter-list pred? list) + "return that part of LIST for which PRED is true. + + TODO: rewrite using accumulator. Now it takes O(n) stack. " + + (if (null? list) '() + (let* ((rest (filter-list pred? (cdr list)))) + (if (pred? (car list)) + (cons (car list) rest) + rest)))) + +(define-public (filter-out-list pred? list) + "return that part of LIST for which PRED is false." + (if (null? list) '() + (let* ((rest (filter-out-list pred? (cdr list)))) + (if (not (pred? (car list))) + (cons (car list) rest) + rest)))) + + +(define (first-n n lst) + "Return first N elements of LST" + (if (and (pair? lst) + (> n 0)) + (cons (car lst) (first-n (- n 1) (cdr lst))) + '())) + +(define-public (uniq-list list) + (if (null? list) '() + (if (null? (cdr list)) + list + (if (equal? (car list) (cadr list)) + (uniq-list (cdr list)) + (cons (car list) (uniq-list (cdr list))))))) + +(define (butfirst-n n lst) + "Return all but first N entries of LST" + (if (pair? lst) + (if (> n 0) + (butfirst-n (- n 1) (cdr lst)) + lst) + '())) - (define (dashed-line thick on off dx dy) - (embedded-ps ((ps-scm 'dashed-line) thick on off dx dy))) +(define (split-at 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. - (define (decrescendo thick w h cont) - (embedded-ps ((ps-scm 'decrescendo) thick w h cont))) +(split-at (lambda (x y) (= (- y x) 2)) '(1 3 5 9 11) (cons '() '()))" +;; " - (define (font-load-command name-mag command) - (string-append - "\\font\\" command "=" - (car name-mag) - " scaled " - (number->string (inexact->exact (* 1000 (cdr name-mag)))) - "\n")) +;; KUT EMACS MODE. - (define (embedded-ps s) - (string-append "\\embeddedps{" s "}")) + (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) - (define (comment s) - (string-append "% " s)) - - (define (end-output) - (begin -; uncomment for some stats about lily memory -; (display (gc-stats)) - (string-append "\n\\EndLilyPondOutput" - ; Put GC stats here. - ))) - - (define (experimental-on) - "") - - (define (font-switch i) - (string-append - "\\" (font i) "\n")) - - (define (font-def i s) - (string-append - "\\font" (font-switch i) "=" s "\n")) - - (define (header-end) - (string-append - "\\special{! " - - ;; URG: ly-gulp-file: now we can't use scm output without Lily - (if use-regex - ;; fixed in 1.3.4 for powerpc -- broken on Windows - (regexp-substitute/global #f "\n" - (ly-gulp-file "lily.ps") 'pre " %\n" 'post) - (ly-gulp-file "lily.ps")) - "}" - "\\input lilyponddefs\\newdimen\\outputscale \\outputscale=\\mudelapaperoutputscale pt\\turnOnPostScript")) - - (define (header creator generate) - (string-append - "%created by: " creator generate "\n")) - - (define (invoke-char s i) - (string-append - "\n\\" s "{" (inexact->string i 10) "}" )) - - (define (invoke-dim1 s d) - (string-append - "\n\\" s "{" (number->dim d) "}")) - (define (pt->sp x) - (* 65536 x)) - - ;; - ;; need to do something to make this really safe. - ;; - (define (output-tex-string s) - (if security-paranoia - (if use-regex - (regexp-substitute/global #f "\\\\" s 'pre "$\\backslash$" 'post) - (begin (display "warning: not paranoid") (newline) s)) - s)) - - (define (lily-def key val) - (string-append - "\\def\\" - (if use-regex - ;; fixed in 1.3.4 for powerpc -- broken on Windows - (regexp-substitute/global #f "_" - (output-tex-string key) 'pre "X" 'post) - (output-tex-string key)) - "{" (output-tex-string val) "}\n")) - - (define (number->dim x) - (string-append - (ly-number->string x) " \\outputscale ")) - - (define (placebox x y s) - (string-append - "\\placebox{" - (number->dim y) "}{" (number->dim x) "}{" s "}\n")) - - (define (bezier-sandwich l thick) - (embedded-ps ((ps-scm 'bezier-sandwich) l thick))) - - (define (start-line ht) - (string-append"\\vbox to " (number->dim ht) "{\\hbox{%\n")) - - (define (stop-line) - "}\\vss}\\interscoreline\n") - (define (stop-last-line) - "}\\vss}") - (define (filledbox breapth width depth height) - (string-append - "\\kern" (number->dim (- breapth)) - "\\vrule width " (number->dim (+ breapth width)) - "depth " (number->dim depth) - "height " (number->dim height) " ")) - - (define (text s) - (string-append "\\hbox{" (output-tex-string s) "}")) - - (define (tuplet ht gapx dx dy thick dir) - (embedded-ps ((ps-scm 'tuplet) ht gapx dx dy thick dir))) - - (define (volta h w thick vert_start vert_end) - (embedded-ps ((ps-scm 'volta) h w thick vert_start vert_end))) - - (define (define-origin file line col) - ; use this for column positions - (string-append "\\special{src:" (number->string line) ":" - (number->string col) " " file "}" - ;; arg, the clueless take over the mailing list... -; "\\special{-****-These-warnings-are-harmless-***}" -; "\\special{-****-PLEASE-read-http://appel.lilypond.org/wiki/index.php3?PostProcessing-****}" - ) - - ; line numbers only: - ;(string-append "\\special{src:" (number->string line) " " file "}") + )) + (let* + ((c (cons '() '())) + ) + (inner-split predicate l c) + (set-car! c (reverse! (car c))) + c) ) - ; no origin info: return empty string - ; "" - ; no-origin not yet supported by Xdvi - (define (no-origin) "") - - ;; TeX - ;; The procedures listed below form the public interface of TeX-scm. - ;; (should merge the 2 lists) - (cond ((eq? action-name 'all-definitions) - `(begin - (define font-load-command ,font-load-command) - (define beam ,beam) - (define bezier-sandwich ,bezier-sandwich) - (define bracket ,bracket) - (define char ,char) - (define crescendo ,crescendo) - (define dashed-line ,dashed-line) - (define dashed-slur ,dashed-slur) - (define decrescendo ,decrescendo) - (define end-output ,end-output) - (define experimental-on ,experimental-on) - (define filledbox ,filledbox) - (define font-def ,font-def) - (define font-switch ,font-switch) - (define header-end ,header-end) - (define lily-def ,lily-def) - (define header ,header) - (define invoke-char ,invoke-char) - (define invoke-dim1 ,invoke-dim1) - (define placebox ,placebox) - (define select-font ,select-font) - (define start-line ,start-line) - (define stop-line ,stop-line) - (define stop-last-line ,stop-last-line) - (define text ,text) - (define tuplet ,tuplet) - (define volta ,volta) - (define define-origin ,define-origin) - (define no-origin ,no-origin) - )) - - ((eq? action-name 'beam) beam) - ((eq? action-name 'tuplet) tuplet) - ((eq? action-name 'bracket) bracket) - ((eq? action-name 'crescendo) crescendo) - ((eq? action-name 'dashed-line) dashed-line) - ((eq? action-name 'dashed-slur) dashed-slur) - ((eq? action-name 'decrescendo) decrescendo) - ((eq? action-name 'end-output) end-output) - ((eq? action-name 'experimental-on) experimental-on) - ((eq? action-name 'font-def) font-def) - ((eq? action-name 'font-switch) font-switch) - ((eq? action-name 'header-end) header-end) - ((eq? action-name 'lily-def) lily-def) - ((eq? action-name 'header) header) - ((eq? action-name 'invoke-char) invoke-char) - ((eq? action-name 'invoke-dim1) invoke-dim1) - ((eq? action-name 'placebox) placebox) - ((eq? action-name 'bezier-sandwich) bezier-sandwich) - ((eq? action-name 'start-line) start-line) - ((eq? action-name 'stem) stem) - ((eq? action-name 'stop-line) stop-line) - ((eq? action-name 'stop-last-line) stop-last-line) - ((eq? action-name 'volta) volta) - (else (error "unknown tag -- PS-TEX " action-name)) - ) - ) -;;;;;;;;;;;; PS -(define (ps-scm action-name) +(define-public (split-list l sep?) + " - ;; alist containing fontname -> fontcommand assoc (both strings) - (define font-alist '()) - (define font-count 0) - (define current-font "") +(display (split-list '(a b c / d e f / g) (lambda (x) (equal? x '/))) ) +=> +((a b c) (d e f) (g)) - - (define (cached-fontname i) - (string-append - "lilyfont" - (make-string 1 (integer->char (+ 65 i))))) - +" - (define (select-font name-mag-pair) - (let* - ( - (c (assoc name-mag-pair font-name-alist)) - ) +(define (split-one sep? l acc) + "Split off the first parts before separator and return both parts. - (if (eq? c #f) - (begin - (display name-mag-pair) - (display font-name-alist) - (ly-warn (string-append - "Programming error: No such font known " (car name-mag-pair)) - (number->string (cdr name-mag-pair)) - ) - - "") ; issue no command - (string-append " " (cdr c) " ")) +" + ;; " KUT EMACS + (if (null? l) + (cons acc '()) + (if (sep? (car l)) + (cons acc (cdr l)) + (split-one sep? (cdr l) (cons (car l) acc)) + ) )) - (define (font-load-command name-mag command) - (string-append - "/" command - " { /" - (symbol->string (car name-mag)) - " findfont " - (number->string (cdr name-mag)) - " 1000 div 12 mul scalefont setfont } bind def " - "\n")) - - - (define (beam width slope thick) - (string-append - (numbers->string (list width slope thick)) " draw_beam" )) - - (define (comment s) - (string-append "% " s)) - - (define (bracket arch_angle arch_width arch_height width height arch_thick thick) - (string-append - (numbers->string (list arch_angle arch_width arch_height width height arch_thick thick)) " draw_bracket" )) - - (define (char i) - (invoke-char " show" i)) - - (define (crescendo thick w h cont ) - (string-append - (numbers->string (list w h (inexact->exact cont) thick)) - " draw_crescendo")) - - ;; what the heck is this interface ? - (define (dashed-slur thick dash l) - (string-append - (apply string-append (map control->string l)) - (number->string thick) - " [ " - (number->string dash) - " " - (number->string (* 10 thick)) ;UGH. 10 ? - " ] 0 draw_dashed_slur")) - - (define (dashed-line thick on off dx dy) - (string-append - (number->string dx) - " " - (number->string dy) - " " - (number->string thick) - " [ " - (number->string on) - " " - (number->string off) - " ] 0 draw_dashed_line")) - - (define (decrescendo thick w h cont) - (string-append - (numbers->string (list w h (inexact->exact cont) thick)) - " draw_decrescendo")) - - - (define (end-output) - "\nshowpage\n") - - (define (experimental-on) "") - - (define (filledbox breapth width depth height) - (string-append (numbers->string (list breapth width depth height)) - " draw_box" )) - - ;; obsolete? - (define (font-def i s) - (string-append - "\n/" (font i) " {/" - (substring s 0 (- (string-length s) 4)) - " findfont 12 scalefont setfont} bind def \n")) - - (define (font-switch i) - (string-append (font i) " ")) - - (define (header-end) - (string-append - ;; URG: now we can't use scm output without Lily - (ly-gulp-file "lilyponddefs.ps") - " {exch pop //systemdict /run get exec} " - (ly-gulp-file "lily.ps") - "{ exch pop //systemdict /run get exec } " - )) - - (define (lily-def key val) +(if (null? l) + '() + (let* ((c (split-one sep? l '()))) + (cons (reverse! (car c) '()) (split-list (cdr c) sep?)) + ) + ) +) - (if (string=? (substring key 0 (min (string-length "mudelapaper") (string-length key))) "mudelapaper") - (string-append "/" key " {" val "} bind def\n") - (string-append "/" key " (" val ") def\n") - ) - ) - (define (header creator generate) - (string-append - "%!PS-Adobe-3.0\n" - "%%Creator: " creator generate "\n")) - - (define (invoke-char s i) - (string-append - "(\\" (inexact->string i 8) ") " s " " )) - - (define (invoke-dim1 s d) - (string-append - (number->string (* d (/ 72.27 72))) " " s )) - - (define (placebox x y s) - (string-append - (number->string x) " " (number->string y) " {" s "} placebox ")) - - (define (bezier-sandwich l thick) - (string-append - (apply string-append (map control->string l)) - (number->string thick) - " draw_bezier_sandwich")) - - (define (start-line height) - "\nstart_line {\n") +(define (other-axis a) + (remainder (+ a 1) 2)) - (define (stem breapth width depth height) - (string-append (numbers->string (list breapth width depth height)) - " draw_box" )) - (define (stop-line) - "}\nstop_line\n") +(define-public (widen-interval iv amount) + (cons (- (car iv) amount) + (+ (cdr iv) amount)) +) - (define (text s) - (string-append "(" s ") show ")) +(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 (volta h w thick vert_start vert_end) - (string-append - (numbers->string (list h w thick (inexact->exact vert_start) (inexact->exact vert_end))) - " draw_volta")) +(define (cons-map f x) + "map F to contents of X" + (cons (f (car x)) (f (cdr x)))) - (define (tuplet ht gap dx dy thick dir) - (string-append - (numbers->string (list ht gap dx dy thick (inexact->exact dir))) - " draw_tuplet")) +;; used where? +(define-public (reduce operator list) + "reduce OP [A, B, C, D, ... ] = + A op (B op (C ... )) +" + (if (null? (cdr list)) (car list) + (operator (car list) (reduce operator (cdr list))))) + +(define (take-from-list-until todo gathered crit?) + "return (G, T), where (reverse G) + T = GATHERED + TODO, and the last of G +is the first to satisfy CRIT + + (take-from-list-until '(1 2 3 4 5) '() (lambda (x) (eq? x 3))) +=> + ((3 2 1) 4 5) + +" + (if (null? todo) + (cons gathered todo) + (if (crit? (car todo)) + (cons (cons (car todo) gathered) (cdr todo)) + (take-from-list-until (cdr todo) (cons (car todo) gathered) crit?) + ) + )) +(define-public (list-insert-separator list between) + "Create new list, inserting BETWEEN between elements of LIST" + (if (null? list) + '() + (if (null? (cdr list)) + list + (cons (car list) + (cons between (list-insert-separator (cdr list) between))) + + ))) - (define (unknown) - "\n unknown\n") +;;;;;;;;;;;;;;;; +; strings. - (define (define-origin a b c ) "") - (define (no-origin) "") +;; TODO : make sep optional. +(define-public (string-join str-list sep) + "append the list of strings in STR-LIST, joining them with SEP" - ;; PS - (cond ((eq? action-name 'all-definitions) - `(begin - (define beam ,beam) - (define tuplet ,tuplet) - (define bracket ,bracket) - (define char ,char) - (define crescendo ,crescendo) - (define volta ,volta) - (define bezier-sandwich ,bezier-sandwich) - (define dashed-line ,dashed-line) - (define dashed-slur ,dashed-slur) - (define decrescendo ,decrescendo) - (define end-output ,end-output) - (define experimental-on ,experimental-on) - (define filledbox ,filledbox) - (define font-def ,font-def) - (define font-switch ,font-switch) - (define header-end ,header-end) - (define lily-def ,lily-def) - (define font-load-command ,font-load-command) - (define header ,header) - (define invoke-char ,invoke-char) - (define invoke-dim1 ,invoke-dim1) - (define placebox ,placebox) - (define select-font ,select-font) - (define start-line ,start-line) - (define stem ,stem) - (define stop-line ,stop-line) - (define stop-last-line ,stop-line) - (define text ,text) - (define no-origin ,no-origin) - (define define-origin ,define-origin) - )) - ((eq? action-name 'tuplet) tuplet) - ((eq? action-name 'beam) beam) - ((eq? action-name 'bezier-sandwich) bezier-sandwich) - ((eq? action-name 'bracket) bracket) - ((eq? action-name 'char) char) - ((eq? action-name 'crescendo) crescendo) - ((eq? action-name 'dashed-line) dashed-line) - ((eq? action-name 'dashed-slur) dashed-slur) - ((eq? action-name 'decrescendo) decrescendo) - ((eq? action-name 'experimental-on) experimental-on) - ((eq? action-name 'filledbox) filledbox) - ((eq? action-name 'select-font) select-font) - ((eq? action-name 'volta) volta) - (else (error "unknown tag -- PS-SCM " action-name)) - ) + (apply string-append (list-insert-separator str-list sep)) ) +(define-public (pad-string-to str wid) + (string-append str (make-string (max (- wid (string-length str)) 0) #\ )) + ) -(define (arg->string arg) - (cond ((number? arg) (inexact->string arg 10)) - ((string? arg) (string-append "\"" arg "\"")) - ((symbol? arg) (string-append "\"" (symbol->string arg) "\"")))) - -; ugh: naming. -(define (func name . args) - (string-append - "(" name - (if (null? args) - "" - (apply string-append - (map (lambda (x) (string-append " " (arg->string x))) args))) - ")\n")) - +;;;;;;;;;;;;;;;; +; other (define (sign x) (if (= x 0) - 1 + 0 (if (< x 0) -1 1))) -(define (gulp-file name) - (let* ((file (open-input-file name)) - (text (read-delimited "" file))) - (close file) - text)) - -;; urg: Use when standalone, do: -;; (define ly-gulp-file scm-gulp-file) -(define (scm-gulp-file name) - (set! %load-path - (cons (string-append (getenv 'LILYPONDPREFIX) "/ly") - (cons (string-append (getenv 'LILYPONDPREFIX) "/ps") - %load-path))) - (let ((path (%search-load-path name))) - (if path - (gulp-file path) - (gulp-file name)))) - -(define (scm-tex-output) - (ly-eval (tex-scm 'all-definitions))) - -(define (scm-ps-output) - (ly-eval (ps-scm 'all-definitions))) - -(define (scm-as-output) - (ly-eval (as-scm 'all-definitions))) - -(define (index-cell cell dir) - (if (equal? dir 1) - (cdr cell) - (car cell))) +(define-public (!= l r) + (not (= l r))) + +(define-public (ly:load x) + (let* ( + (fn (%search-load-path x)) + + ) + (if (ly:verbose) + (format (current-error-port) "[~A]" fn)) + (primitive-load fn))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; output +(use-modules (scm tex) + (scm ps) + (scm pysk) + (scm ascii-script) + (scm sketch) + (scm sodipodi) + (scm 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)) + ("as" . ("Asci-script. Postprocess with as2txt to get ascii art" ,as-output-expression)) + ("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) - ) - ) -(begin - (eval-string (ly-gulp-file "interface.scm")) - (eval-string (ly-gulp-file "beam.scm")) - (eval-string (ly-gulp-file "slur.scm")) - (eval-string (ly-gulp-file "font.scm")) - (eval-string (ly-gulp-file "auto-beam.scm")) - (eval-string (ly-gulp-file "generic-property.scm")) - (eval-string (ly-gulp-file "basic-properties.scm")) - (eval-string (ly-gulp-file "chord-names.scm")) - (eval-string (ly-gulp-file "element-descriptions.scm")) - ) +(define (document-format-dumpers) + (map + (lambda (x) + (display (string-append (pad-string-to 5 (car x)) (cadr x) "\n")) + output-alist) + )) + +(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 + '("music-types.scm" + "output-lib.scm" + "c++.scm" + "chords-ignatzek.scm" + "chord-entry.scm" + "double-plus-new-chord-name.scm" + "molecule.scm" + "new-markup.scm" + "bass-figure.scm" + "music-functions.scm" + "music-property-description.scm" + "auto-beam.scm" + "basic-properties.scm" + "chord-name.scm" + "translator-property-description.scm" + "script.scm" + "drums.scm" + "midi.scm" + + "beam.scm" + "clef.scm" + "slur.scm" + "font.scm" + + "grob-property-description.scm" + "grob-description.scm" + "context-description.scm" + "interface-description.scm" + )) + + + + + +(set! type-p-name-alist + `( + (,ly:dir? . "direction") + (,scheme? . "any type") + (,number-pair? . "pair of numbers") + (,ly:input-location? . "input location") + (,ly:grob? . "grob (GRaphical OBject)") + (,grob-list? . "list of grobs") + (,ly:duration? . "duration") + (,pair? . "pair") + (,integer? . "integer") + (,list? . "list") + (,symbol? . "symbol") + (,string? . "string") + (,boolean? . "boolean") + (,ly:pitch? . "pitch") + (,ly:moment? . "moment") + (,ly:dimension? . "dimension, in staff space") + (,ly:input-location? . "input location") + (,music-list? . "list of music") + (,ly:music? . "music") + (,number? . "number") + (,char? . "char") + (,input-port? . "input port") + (,output-port? . "output port") + (,vector? . "vector") + (,procedure? . "procedure") + (,boolean-or-symbol? . "boolean or symbol") + (,number-or-string? . "number or string") + (,markup? . "markup") + (,markup-list? . "list of markups") + (,number-or-grob? . "number or grob") + ))