1 ;;; lily.scm -- implement Scheme output routines for TeX and PostScript
3 ;;;; source file of the GNU LilyPond music typesetter
5 ;;;; (c) 1998--2003 Jan Nieuwenhuizen <janneke@gnu.org>
6 ;;;; Han-Wen Nienhuys <hanwen@cs.uu.nl>
11 (use-modules (ice-9 regex)
15 ;; debugging evaluator is slower.
18 ;(debug-enable 'backtrace)
19 (read-enable 'positions)
22 (define-public (line-column-location line col file)
23 "Print an input location, including column number ."
24 (string-append (number->string line) ":"
25 (number->string col) " " file)
28 (define-public (line-location line col file)
29 "Print an input location, without column number ."
30 (string-append (number->string line) " " file)
33 (define-public point-and-click #f)
35 ;; cpp hack to get useful error message
36 (define ifdef "First run this through cpp.")
37 (define ifndef "First run this through cpp.")
41 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
45 (define-public START -1)
46 (define-public STOP 1)
47 (define-public LEFT -1)
48 (define-public RIGHT 1)
50 (define-public DOWN -1)
51 (define-public CENTER 0)
53 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
54 ;; lily specific variables.
55 (define-public default-script-alist '())
57 (define-public security-paranoia #f)
59 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
60 ;;; Unassorted utility functions.
65 (define (uniqued-alist alist acc)
67 (if (assoc (caar alist) acc)
68 (uniqued-alist (cdr alist) acc)
69 (uniqued-alist (cdr alist) (cons (car alist) acc)))))
72 (define (assoc-get key alist)
73 "Return value if KEY in ALIST, else #f."
74 (let ((entry (assoc key alist)))
75 (if entry (cdr entry) #f)))
77 (define (assoc-get-default key alist default)
78 "Return value if KEY in ALIST, else DEFAULT."
79 (let ((entry (assoc key alist)))
80 (if entry (cdr entry) default)))
83 (define-public (uniqued-alist alist acc)
85 (if (assoc (caar alist) acc)
86 (uniqued-alist (cdr alist) acc)
87 (uniqued-alist (cdr alist) (cons (car alist) acc)))))
89 (define-public (alist<? x y)
90 (string<? (symbol->string (car x))
91 (symbol->string (car y))))
95 (define (chain-assoc x alist-list)
96 (if (null? alist-list)
98 (let* ((handle (assoc x (car alist-list))))
101 (chain-assoc x (cdr alist-list))))))
106 (define (flatten-list lst)
110 (if (pair? (car lst))
111 (append (flatten-list (car lst)) (flatten-list (cdr lst)))
112 (cons (car lst) (flatten-list (cdr lst))))
115 (define (list-minus a b)
116 "Return list of elements in A that are not in B."
117 (lset-difference eq? a b))
120 ;; TODO: use the srfi-1 partition function.
121 (define-public (uniq-list list)
123 (if (null? (cdr list))
125 (if (equal? (car list) (cadr list))
126 (uniq-list (cdr list))
127 (cons (car list) (uniq-list (cdr list)))))))
129 (define (split-at-predicate predicate l)
130 "Split L = (a_1 a_2 ... a_k b_1 ... b_k)
131 into L1 = (a_1 ... a_k ) and L2 =(b_1 .. b_k)
132 Such that (PREDICATE a_i a_{i+1}) and not (PREDICATE a_k b_1).
133 L1 is copied, L2 not.
135 (split-at-predicate (lambda (x y) (= (- y x) 2)) '(1 3 5 9 11) (cons '() '()))"
140 (define (inner-split predicate l acc)
144 (set-car! acc (cons (car l) (car acc)))
146 ((predicate (car l) (cadr l))
147 (set-car! acc (cons (car l) (car acc)))
148 (inner-split predicate (cdr l) acc))
150 (set-car! acc (cons (car l) (car acc)))
151 (set-cdr! acc (cdr l))
158 (inner-split predicate l c)
159 (set-car! c (reverse! (car c)))
164 (define-public (split-list l sep?)
166 (display (split-list '(a b c / d e f / g) (lambda (x) (equal? x '/))) )
168 ((a b c) (d e f) (g))
173 (define (split-one sep? l acc)
174 "Split off the first parts before separator and return both parts."
179 (split-one sep? (cdr l) (cons (car l) acc))
185 (let* ((c (split-one sep? l '())))
186 (cons (reverse! (car c) '()) (split-list (cdr c) sep?))
190 (define-public (interval-length x)
191 "Length of the number-pair X, when an interval"
192 (max 0 (- (cdr x) (car x)))
196 (define (other-axis a)
197 (remainder (+ a 1) 2))
200 (define-public (widen-interval iv amount)
201 (cons (- (car iv) amount)
205 (define-public (write-me message x)
206 "Return X. Display MESSAGE and write X. Handy for debugging, possibly turned off."
207 (display message) (write x) (newline) x)
210 (define (index-cell cell dir)
215 (define (cons-map f x)
216 "map F to contents of X"
217 (cons (f (car x)) (f (cdr x))))
220 (define-public (reduce-no-unit operator list)
221 "reduce OP [A, B, C, D, ... ] =
224 (if (null? (cdr list)) (car list)
225 (operator (car list) (reduce-no-unit operator (cdr list)))))
227 (define-public (list-insert-separator list between)
228 "Create new list, inserting BETWEEN between elements of LIST"
231 (if (null? (cdr list))
234 (cons between (list-insert-separator (cdr list) between)))
242 ;; TODO : make sep optional.
243 (define-public (string-join str-list sep)
244 "append the list of strings in STR-LIST, joining them with SEP"
246 (apply string-append (list-insert-separator str-list sep))
249 (define-public (pad-string-to str wid)
250 (string-append str (make-string (max (- wid (string-length str)) 0) #\ ))
260 (define-public (!= l r)
263 (define-public (ly:load x)
265 (fn (%search-load-path x))
269 (format (current-error-port) "[~A]" fn))
270 (primitive-load fn)))
273 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
275 (use-modules (scm output-tex)
277 (scm output-ascii-script)
279 (scm output-sodipodi)
285 ("tex" . ("TeX output. The default output form." ,tex-output-expression))
286 ("ps" . ("Direct postscript. Requires setting GS_LIB and GS_FONTPATH" ,ps-output-expression))
287 ("scm" . ("Scheme dump: debug scheme molecule expressions" ,write))
288 ("as" . ("Asci-script. Postprocess with as2txt to get ascii art" ,as-output-expression))
289 ("sketch" . ("Bare bones Sketch output." ,sketch-output-expression))
290 ("sodipodi" . ("Bare bones Sodipodi output." ,sodipodi-output-expression))
291 ("pdftex" . ("PDFTeX output. Was last seen nonfunctioning." ,pdftex-output-expression))
295 (define (document-format-dumpers)
298 (display (string-append (pad-string-to 5 (car x)) (cadr x) "\n"))
302 (define-public (find-dumper format )
304 ((d (assoc format output-alist)))
308 (scm-error "Could not find dumper for format ~s" format))
311 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
316 '("define-music-types.scm"
319 "chord-ignatzek-names.scm"
321 "chord-generic-names.scm"
325 "music-functions.scm"
326 "define-music-properties.scm"
330 "define-translator-properties.scm"
331 "translation-functions.scm"
341 "define-grob-properties.scm"
343 "define-grob-interfaces.scm"
350 (set! type-p-name-alist
352 (,ly:dir? . "direction")
353 (,scheme? . "any type")
354 (,number-pair? . "pair of numbers")
355 (,ly:input-location? . "input location")
356 (,ly:grob? . "grob (GRaphical OBject)")
357 (,grob-list? . "list of grobs")
358 (,ly:duration? . "duration")
360 (,integer? . "integer")
362 (,symbol? . "symbol")
363 (,string? . "string")
364 (,boolean? . "boolean")
365 (,ly:pitch? . "pitch")
366 (,ly:moment? . "moment")
367 (,ly:dimension? . "dimension, in staff space")
368 (,ly:input-location? . "input location")
369 (,music-list? . "list of music")
370 (,ly:music? . "music")
371 (,number? . "number")
373 (,input-port? . "input port")
374 (,output-port? . "output port")
375 (,vector? . "vector")
376 (,procedure? . "procedure")
377 (,boolean-or-symbol? . "boolean or symbol")
378 (,number-or-string? . "number or string")
379 (,markup? . "markup")
380 (,markup-list? . "list of markups")
381 (,number-or-grob? . "number or grob")