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)
13 (srfi srfi-13) ;strings
17 ;; debugging evaluator is slower.
20 ;(debug-enable 'backtrace)
21 (read-enable 'positions)
24 (define-public (line-column-location line col file)
25 "Print an input location, including column number ."
26 (string-append (number->string line) ":"
27 (number->string col) " " file)
30 (define-public (line-location line col file)
31 "Print an input location, without column number ."
32 (string-append (number->string line) " " file)
35 (define-public point-and-click #f)
37 ;; cpp hack to get useful error message
38 (define ifdef "First run this through cpp.")
39 (define ifndef "First run this through cpp.")
43 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
47 (define-public START -1)
48 (define-public STOP 1)
49 (define-public LEFT -1)
50 (define-public RIGHT 1)
52 (define-public DOWN -1)
53 (define-public CENTER 0)
55 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
56 ;; lily specific variables.
57 (define-public default-script-alist '())
59 (define-public security-paranoia #f)
61 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
62 ;;; Unassorted utility functions.
67 (define (uniqued-alist alist acc)
69 (if (assoc (caar alist) acc)
70 (uniqued-alist (cdr alist) acc)
71 (uniqued-alist (cdr alist) (cons (car alist) acc)))))
74 (define (assoc-get key alist)
75 "Return value if KEY in ALIST, else #f."
76 (let ((entry (assoc key alist)))
77 (if entry (cdr entry) #f)))
79 (define (assoc-get-default key alist default)
80 "Return value if KEY in ALIST, else DEFAULT."
81 (let ((entry (assoc key alist)))
82 (if entry (cdr entry) default)))
85 (define-public (uniqued-alist alist acc)
87 (if (assoc (caar alist) acc)
88 (uniqued-alist (cdr alist) acc)
89 (uniqued-alist (cdr alist) (cons (car alist) acc)))))
91 (define-public (alist<? x y)
92 (string<? (symbol->string (car x))
93 (symbol->string (car y))))
97 (define (chain-assoc x alist-list)
98 (if (null? alist-list)
100 (let* ((handle (assoc x (car alist-list))))
103 (chain-assoc x (cdr alist-list))))))
108 (define (flatten-list lst)
112 (if (pair? (car lst))
113 (append (flatten-list (car lst)) (flatten-list (cdr lst)))
114 (cons (car lst) (flatten-list (cdr lst))))
117 (define (list-minus a b)
118 "Return list of elements in A that are not in B."
119 (lset-difference eq? a b))
122 ;; TODO: use the srfi-1 partition function.
123 (define-public (uniq-list list)
124 "Uniq LIST, assuming that it is sorted"
126 (if (null? (cdr list))
128 (if (equal? (car list) (cadr list))
129 (uniq-list (cdr list))
130 (cons (car list) (uniq-list (cdr list)))))))
132 (define (split-at-predicate predicate l)
133 "Split L = (a_1 a_2 ... a_k b_1 ... b_k)
134 into L1 = (a_1 ... a_k ) and L2 =(b_1 .. b_k)
135 Such that (PREDICATE a_i a_{i+1}) and not (PREDICATE a_k b_1).
136 L1 is copied, L2 not.
138 (split-at-predicate (lambda (x y) (= (- y x) 2)) '(1 3 5 9 11) (cons '() '()))"
143 (define (inner-split predicate l acc)
147 (set-car! acc (cons (car l) (car acc)))
149 ((predicate (car l) (cadr l))
150 (set-car! acc (cons (car l) (car acc)))
151 (inner-split predicate (cdr l) acc))
153 (set-car! acc (cons (car l) (car acc)))
154 (set-cdr! acc (cdr l))
161 (inner-split predicate l c)
162 (set-car! c (reverse! (car c)))
167 (define-public (split-list l sep?)
169 (display (split-list '(a b c / d e f / g) (lambda (x) (equal? x '/))) )
171 ((a b c) (d e f) (g))
176 (define (split-one sep? l acc)
177 "Split off the first parts before separator and return both parts."
182 (split-one sep? (cdr l) (cons (car l) acc))
188 (let* ((c (split-one sep? l '())))
189 (cons (reverse! (car c) '()) (split-list (cdr c) sep?))
193 (define-public (interval-length x)
194 "Length of the number-pair X, when an interval"
195 (max 0 (- (cdr x) (car x)))
199 (define (other-axis a)
200 (remainder (+ a 1) 2))
203 (define-public (widen-interval iv amount)
204 (cons (- (car iv) amount)
208 (define-public (write-me message x)
209 "Return X. Display MESSAGE and write X. Handy for debugging, possibly turned off."
210 (display message) (write x) (newline) x)
213 (define (index-cell cell dir)
218 (define (cons-map f x)
219 "map F to contents of X"
220 (cons (f (car x)) (f (cdr x))))
223 (define-public (list-insert-separator lst between)
224 "Create new list, inserting BETWEEN between elements of LIST"
228 (cons x (cons between y))
230 (fold-right conc #f lst))
239 (define-public (!= l r)
242 (define-public (ly:load x)
244 (fn (%search-load-path x))
248 (format (current-error-port) "[~A]" fn))
249 (primitive-load fn)))
252 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
254 (use-modules (scm output-tex)
256 (scm output-ascii-script)
258 (scm output-sodipodi)
264 ("tex" . ("TeX output. The default output form." ,tex-output-expression))
265 ("ps" . ("Direct postscript. Requires setting GS_LIB and GS_FONTPATH" ,ps-output-expression))
266 ("scm" . ("Scheme dump: debug scheme molecule expressions" ,write))
267 ("as" . ("Asci-script. Postprocess with as2txt to get ascii art" ,as-output-expression))
268 ("sketch" . ("Bare bones Sketch output." ,sketch-output-expression))
269 ("sodipodi" . ("Bare bones Sodipodi output." ,sodipodi-output-expression))
270 ("pdftex" . ("PDFTeX output. Was last seen nonfunctioning." ,pdftex-output-expression))
274 (define (document-format-dumpers)
277 (display (string-append (pad-string-to 5 (car x)) (cadr x) "\n"))
281 (define-public (find-dumper format )
283 ((d (assoc format output-alist)))
287 (scm-error "Could not find dumper for format ~s" format))
290 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
295 '("define-music-types.scm"
298 "chord-ignatzek-names.scm"
300 "chord-generic-names.scm"
304 "music-functions.scm"
305 "define-music-properties.scm"
309 "define-translator-properties.scm"
310 "translation-functions.scm"
320 "define-grob-properties.scm"
322 "define-grob-interfaces.scm"
329 (set! type-p-name-alist
331 (,ly:dir? . "direction")
332 (,scheme? . "any type")
333 (,number-pair? . "pair of numbers")
334 (,ly:input-location? . "input location")
335 (,ly:grob? . "grob (GRaphical OBject)")
336 (,grob-list? . "list of grobs")
337 (,ly:duration? . "duration")
339 (,integer? . "integer")
341 (,symbol? . "symbol")
342 (,string? . "string")
343 (,boolean? . "boolean")
344 (,ly:pitch? . "pitch")
345 (,ly:moment? . "moment")
346 (,ly:dimension? . "dimension, in staff space")
347 (,ly:input-location? . "input location")
348 (,music-list? . "list of music")
349 (,ly:music? . "music")
350 (,number? . "number")
352 (,input-port? . "input port")
353 (,output-port? . "output port")
354 (,vector? . "vector")
355 (,procedure? . "procedure")
356 (,boolean-or-symbol? . "boolean or symbol")
357 (,number-or-string? . "number or string")
358 (,markup? . "markup")
359 (,markup-list? . "list of markups")
360 (,number-or-grob? . "number or grob")