]> git.donarmstrong.com Git - lilypond.git/blob - scm/lily.scm
release: 1.3.38
[lilypond.git] / scm / lily.scm
1 ; lily.scm -- implement Scheme output routines for TeX and PostScript
2 ;
3 ;  source file of the GNU LilyPond music typesetter
4
5 ; (c) 1998 Jan Nieuwenhuizen <janneke@gnu.org>
6
7
8 ;
9 ; This file contains various routines in Scheme that are easier to 
10 ; do here than in C++.  At present it is a unorganised mess. Sorry. 
11 ;
12
13
14 ;(debug-enable 'backtrace)
15
16 ;;; library funtions
17
18 (use-modules (ice-9 regex))
19
20 ;; do nothing in .scm output
21 (define (comment s) "")
22
23 (define (mm-to-pt x)
24   (* (/ 72.27 25.40) x)
25   )
26
27 (define (cons-map f x)
28   (cons (f (car x)) (f (cdr x))))
29
30 (define (reduce operator list)
31       (if (null? (cdr list)) (car list)
32           (operator (car list) (reduce operator (cdr list)))
33           )
34       )
35
36
37 (define (numbers->string l)
38   (apply string-append (map ly-number->string l)))
39
40 ; (define (chop-decimal x) (if (< (abs x) 0.001) 0.0 x))
41
42 (define (number->octal-string x)
43   (let* ((n (inexact->exact x))
44          (n64 (quotient n 64))
45          (n8 (quotient (- n (* n64 64)) 8)))
46     (string-append
47      (number->string n64)
48      (number->string n8)
49      (number->string (remainder (- n (+ (* n64 64) (* n8 8))) 8)))))
50
51 (define (inexact->string x radix)
52   (let ((n (inexact->exact x)))
53     (number->string n radix)))
54
55
56 (define (control->string c)
57   (string-append (number->string (car c)) " "
58                  (number->string (cdr c)) " "))
59
60
61 (define (font i)
62   (string-append
63    "font"
64    (make-string 1 (integer->char (+ (char->integer #\A) i)))
65    ))
66
67
68
69 (define (scm-scm action-name)
70   1)
71
72 (define security-paranoia #f)
73
74
75 ;; See documentation of Item::visibility_lambda_
76 (define (begin-of-line-visible d) (if (= d 1) '(#f . #f) '(#t . #t)))
77 (define (spanbar-begin-of-line-invisible d) (if (= d -1) '(#t . #t) '(#f . #f)))
78 (define (all-visible d) '(#f . #f))
79 (define (begin-of-line-invisible d) (if (= d 1) '(#t . #t) '(#f . #f)))
80 (define (end-of-line-invisible d) (if (= d -1) '(#t . #t) '(#f . #f)))
81
82
83 ;; Score_span_bars are only visible at start of line
84 ;; i.e. if break_dir == RIGHT == 1
85 (define Span_bar_engraver-visibility begin-of-line-invisible)
86 (define Base_span_bar_engraver-visibility begin-of-line-invisible)
87 (define mark-visibility end-of-line-invisible)
88 (define Span_score_bar_engraver-visibility begin-of-line-visible)
89 (define Piano_bar_engraver-visibility begin-of-line-visible)
90 (define Staff_group_bar_engraver-visibility begin-of-line-visible)
91
92 ;; Spacing constants for prefatory matter.
93 ;;
94 ;; rules for this spacing are much more complicated than this. See [Wanske] page 126 -- 134, [Ross] pg 143 -- 147
95 ;;
96 ;;
97
98 ;; (Measured in staff space)
99 (define space-alist
100  '(
101    (("" "Left_edge_item") . (extra-space -15.0))
102    (("" "Clef_item") . (minimum-space 1.0))
103    (("" "Staff_bar") . (minimum-space 0.0))
104    (("" "Clef_item") . (minimum-space 1.0))
105    (("" "Key_item") . (minimum-space 0.5))
106    (("" "Span_bar") . (extra-space 0.0))
107    (("" "Time_signature") . (extra-space 0.0))
108    (("" "begin-of-note") . (minimum-space 1.5))
109    (("Clef_item" "Key_item") . (minimum-space 4.0))
110    (("Key_item" "Time_signature") . (extra-space 1.0))
111    (("Clef_item"  "Time_signature") . (minimum-space 3.5))
112    (("Staff_bar" "Clef_item") .   (minimum-space 1.0))
113    (("Clef_item"  "Staff_bar") .  (minimum-space 3.7))
114    (("Time_signature" "Staff_bar") .  (minimum-space 2.0))
115    (("Key_item"  "Staff_bar") .  (extra-space 1.0))
116    (("Span_bar" "Clef_item") .   (extra-space 1.0))
117    (("Clef_item"  "Span_bar") . (minimum-space 3.7))
118    (("Time_signature" "Span_bar") . (minimum-space 2.0))
119    (("Key_item"  "Span_bar") . (minimum-space 2.5))
120    (("Staff_bar" "Time_signature") . (minimum-space 1.5)) ;double check this.
121    (("Time_signature" "begin-of-note") . (extra-space 2.0)) ;double check this.
122    (("Key_item" "begin-of-note") . (extra-space 2.5))
123    (("Staff_bar" "begin-of-note") . (extra-space 1.0))
124    (("Clef_item" "begin-of-note") . (minimum-space 5.0))
125    (("" "Breathing_sign") . (minimum-space 0.0))
126    (("Breathing_sign" "Key_item") . (minimum-space 1.5))
127    (("Breathing_sign" "begin-of-note") . (minimum-space 1.0))
128    (("Breathing_sign" "Staff_bar") . (minimum-space 1.5))
129    (("Breathing_sign" "Clef_item") . (minimum-space 2.0))
130    )
131 )
132  
133 (define (break-align-spacer this next)
134   (let ((entry (assoc `(,this ,next) space-alist)))
135     (if entry
136         (cdr entry)
137         (begin (ly-warn (string-append "Unknown spacing pair `" this "', `" next "'"))
138                '(minimum-space 0.0)))))
139   
140
141
142 ;;;;;;;; TeX
143
144 ;; this is silly, can't we use something like
145 ;; roman-0, roman-1 roman+1 ?
146 (define cmr-alist 
147   '(("bold" . "cmbx") 
148     ("brace" . "feta-braces")
149     ("default" . "cmr10")
150     ("dynamic" . "feta-din") 
151     ("feta" . "feta") 
152     ("feta-1" . "feta") 
153     ("feta-2" . "feta") 
154     ("finger" . "feta-nummer") 
155     ("typewriter" . "cmtt") 
156     ("italic" . "cmti") 
157     ("roman" . "cmr") 
158     ("script" . "cmr") 
159     ("large" . "cmbx") 
160     ("Large" . "cmbx") 
161     ("mark" . "feta-nummer") 
162     ("number" . "feta-nummer") 
163     ("volta" . "feta-nummer"))
164 )
165
166 (define (string-encode-integer i)
167   (cond
168    ((= i  0) "o")
169    ((< i 0)   (string-append "n" (string-encode-integer (- i))))
170    (else (string-append
171           (make-string 1 (integer->char (+ 65 (modulo i 26))))
172           (string-encode-integer (quotient i 26))
173          )
174    )
175   )
176   )
177
178 (define (magstep i)
179   (cdr (assoc i '((-4 . 482)
180                   (-3 . 579)
181                   (-2 . 694)
182                   (-1 . 833)
183                   (0 . 1000)
184                   (1 . 1200) 
185                   (2 . 1440)
186                   (3 . 1728)
187                   (4 . 2074))
188               )
189        )
190   )
191              
192 (define script-alist '())
193 (define (articulation-to-scriptdef a)
194   (assoc a script-alist)
195   )
196
197 ;; Map style names to TeX font names.  Return false if 
198 ;; no font name found. 
199 (define (style-to-cmr s)
200   (assoc s cmr-alist )
201   )
202             
203
204
205 (define font-name-alist  '())
206 (define (font-command name-mag)
207     (cons name-mag
208           (string-append  "magfont"
209                           (string-encode-integer (hashq (car name-mag) 1000000))
210                           "m"
211                           (string-encode-integer (cdr name-mag)))
212
213           )
214     )
215 (define (define-fonts names)
216   (set! font-name-alist (map font-command names))
217   (apply string-append
218          (map (lambda (x)
219                 (font-load-command (car x) (cdr x))) font-name-alist)
220   ))
221
222 (define (fontify name exp)
223   (string-append (select-font name)
224                  exp)
225   )
226
227 ;;;;;;;;;;;;;;;;;;;;
228
229
230 ; Make a function that checks score element for being of a specific type. 
231 (define (make-type-checker name)
232   (lambda (elt)
233     (not (not (memq name (ly-get-elt-property elt 'interfaces))))))
234
235         
236 ;;;;;;;;;;;;;;;;;;; TeX output
237 (define (tex-scm action-name)
238   (define (unknown) 
239     "%\n\\unknown%\n")
240
241
242   (define (select-font font-name-symbol)
243     (let*
244         (
245          (c (assoc font-name-symbol font-name-alist))
246          )
247
248       (if (eq? c #f)
249           (begin
250             (ly-warn (string-append
251                       "Programming error: No such font known " (car font-name-symbol)))
252             "")                         ; issue no command
253           (string-append "\\" (cdr c)))
254       
255       
256       ))
257   
258   (define (beam width slope thick)
259     (embedded-ps ((ps-scm 'beam) width slope thick)))
260
261   (define (bracket arch_angle arch_width arch_height width height arch_thick thick)
262     (embedded-ps ((ps-scm 'bracket) arch_angle arch_width arch_height width height arch_thick thick)))
263
264   (define (dashed-slur thick dash l)
265     (embedded-ps ((ps-scm 'dashed-slur)  thick dash l)))
266
267   (define (crescendo thick w h cont)
268     (embedded-ps ((ps-scm 'crescendo) thick w h cont)))
269
270   (define (char i)
271     (string-append "\\char" (inexact->string i 10) " "))
272   
273   (define (dashed-line thick dash w)
274     (embedded-ps ((ps-scm 'dashed-line) thick dash w)))
275
276   (define (decrescendo thick w h cont)
277     (embedded-ps ((ps-scm 'decrescendo) thick w h cont)))
278
279   (define (font-load-command name-mag command)
280     (string-append
281      "\\font\\" command "="
282      (symbol->string (car name-mag))
283      " scaled "
284      (number->string (magstep (cdr name-mag)))
285      "\n"))
286
287   (define (embedded-ps s)
288     (string-append "\\embeddedps{" s "}"))
289
290   (define (comment s)
291     (string-append "% " s))
292   
293   (define (end-output) 
294     "\n\\EndLilyPondOutput")
295   
296   (define (experimental-on)
297     "")
298
299   (define (font-switch i)
300     (string-append
301      "\\" (font i) "\n"))
302
303   (define (font-def i s)
304     (string-append
305      "\\font" (font-switch i) "=" s "\n"))
306
307   (define (header-end)
308     (string-append
309      "\\special{! "
310      ; fixed in 1.3.4
311      ;(ly-gulp-file "lily.ps")
312
313      ;; URG: now we can't use scm output without Lily
314      (regexp-substitute/global #f "\n" (ly-gulp-file "lily.ps") 'pre " %\n" 'post)
315      "}"
316      "\\input lilyponddefs \\turnOnPostScript"))
317
318   (define (header creator generate) 
319     (string-append
320      "%created by: " creator generate "\n"))
321
322   (define (invoke-char s i)
323     (string-append 
324      "\n\\" s "{" (inexact->string i 10) "}" ))
325
326   (define (invoke-dim1 s d)
327     (string-append
328      "\n\\" s "{" (number->dim d) "}"))
329   (define (pt->sp x)
330     (* 65536 x))
331   
332   ;;
333   ;; need to do something to make this really safe.
334   ;;
335   (define (output-tex-string s)
336       (if security-paranoia
337           (regexp-substitute/global #f "\\\\" s 'pre "$\\backslash$" 'post)
338           s))
339       
340   (define (lily-def key val)
341     (string-append
342      "\\def\\"
343      ; fixed in 1.3.4
344      (regexp-substitute/global #f "_" (output-tex-string key) 'pre "X" 'post)
345      ;(output-tex-string key)
346      "{" (output-tex-string val) "}\n"))
347
348   (define (number->dim x)
349     (string-append 
350      (ly-number->string x) " pt "))
351
352   (define (placebox x y s) 
353     (string-append 
354      "\\placebox{"
355      (number->dim y) "}{" (number->dim x) "}{" s "}\n"))
356
357   (define (bezier-sandwich l thick)
358     (embedded-ps ((ps-scm 'bezier-sandwich) l thick)))
359
360   (define (start-line ht)
361       (string-append"\\vbox to " (number->dim ht) "{\\hbox{%\n"))
362
363   (define (stop-line) 
364     "}\\vss}\\interscoreline")
365   (define (stop-last-line)
366     "}\\vss}")
367   (define (filledbox breapth width depth height) 
368     (string-append 
369      "\\kern" (number->dim (- breapth))
370      "\\vrule width " (number->dim (+ breapth width))
371      "depth " (number->dim depth)
372      "height " (number->dim height) " "))
373
374   (define (text s)
375     (string-append "\\hbox{" (output-tex-string s) "}"))
376   
377   (define (tuplet ht gapx dx dy thick dir)
378     (embedded-ps ((ps-scm 'tuplet) ht gapx dx dy thick dir)))
379
380   (define (volta h w thick vert_start vert_end)
381     (embedded-ps ((ps-scm 'volta) h w thick vert_start vert_end)))
382
383   ;; TeX
384   ;; The procedures listed below form the public interface of TeX-scm.
385   ;; (should merge the 2 lists)
386   (cond ((eq? action-name 'all-definitions)
387          `(begin
388             (define font-load-command ,font-load-command)
389             (define beam ,beam)
390             (define bezier-sandwich ,bezier-sandwich)
391             (define bracket ,bracket)
392             (define char ,char)
393             (define crescendo ,crescendo)
394             (define dashed-line ,dashed-line) 
395             (define dashed-slur ,dashed-slur) 
396             (define decrescendo ,decrescendo) 
397             (define end-output ,end-output)
398             (define experimental-on ,experimental-on)
399             (define filledbox ,filledbox)
400             (define font-def ,font-def)
401             (define font-switch ,font-switch)
402             (define header-end ,header-end)
403             (define lily-def ,lily-def)
404             (define header ,header) 
405             (define invoke-char ,invoke-char) 
406             (define invoke-dim1 ,invoke-dim1)
407             (define placebox ,placebox)
408             (define select-font ,select-font)
409             (define start-line ,start-line)
410             (define stop-line ,stop-line)
411             (define stop-last-line ,stop-last-line)
412             (define text ,text)
413             (define tuplet ,tuplet)
414             (define volta ,volta)
415             ))
416
417         ((eq? action-name 'beam) beam)
418         ((eq? action-name 'tuplet) tuplet)
419         ((eq? action-name 'bracket) bracket)
420         ((eq? action-name 'crescendo) crescendo)
421         ((eq? action-name 'dashed-line) dashed-line) 
422         ((eq? action-name 'dashed-slur) dashed-slur) 
423         ((eq? action-name 'decrescendo) decrescendo) 
424         ((eq? action-name 'end-output) end-output)
425         ((eq? action-name 'experimental-on) experimental-on)
426         ((eq? action-name 'font-def) font-def)
427         ((eq? action-name 'font-switch) font-switch)
428         ((eq? action-name 'header-end) header-end)
429         ((eq? action-name 'lily-def) lily-def)
430         ((eq? action-name 'header) header) 
431         ((eq? action-name 'invoke-char) invoke-char) 
432         ((eq? action-name 'invoke-dim1) invoke-dim1)
433         ((eq? action-name 'placebox) placebox)
434         ((eq? action-name 'bezier-sandwich) bezier-sandwich)
435         ((eq? action-name 'start-line) start-line)
436         ((eq? action-name 'stem) stem)
437         ((eq? action-name 'stop-line) stop-line)
438         ((eq? action-name 'stop-last-line) stop-last-line)
439         ((eq? action-name 'volta) volta)
440         (else (error "unknown tag -- PS-TEX " action-name))
441         )
442   )
443
444
445 ;;;;;;;;;;;; PS
446 (define (ps-scm action-name)
447
448   ;; alist containing fontname -> fontcommand assoc (both strings)
449   (define font-alist '())
450   (define font-count 0)
451   (define current-font "")
452
453   
454   (define (cached-fontname i)
455     (string-append
456      "lilyfont"
457      (make-string 1 (integer->char (+ 65 i)))))
458     
459   (define (mag-to-size m)
460     (number->string (case m 
461                       (0 12)
462                       (1 12)
463                       (2 14) ; really: 14.400
464                       (3 17) ; really: 17.280
465                       (4 21) ; really: 20.736
466                       (5 24) ; really: 24.888
467                       (6 30) ; really: 29.856
468                       )))
469   
470   
471   (define (select-font font-name-symbol)
472     (let*
473         (
474          (c (assoc font-name-symbol font-name-alist))
475          )
476
477       (if (eq? c #f)
478           (begin
479             (ly-warn (string-append
480                       "Programming error: No such font known " (car font-name-symbol)))
481             "")                         ; issue no command
482           (string-append " " (cdr c) " "))
483       
484       
485       ))
486
487     (define (font-load-command name-mag command)
488       (string-append
489        "/" command
490        " { /"
491        (symbol->string (car name-mag))
492        " findfont "
493        (number->string (magstep (cdr name-mag)))
494        " 1000 div 12 mul  scalefont setfont } bind def "
495        "\n"))
496
497
498   (define (beam width slope thick)
499     (string-append
500      (numbers->string (list width slope thick)) " draw_beam" ))
501
502   (define (comment s)
503     (string-append "% " s))
504
505   (define (bracket arch_angle arch_width arch_height width height arch_thick thick)
506     (string-append
507      (numbers->string (list arch_angle arch_width arch_height width height arch_thick thick)) " draw_bracket" ))
508
509   (define (char i)
510     (invoke-char " show" i))
511
512   (define (crescendo thick w h cont )
513     (string-append 
514      (numbers->string (list w h (inexact->exact cont) thick))
515      " draw_crescendo"))
516
517   ;; what the heck is this interface ?
518   (define (dashed-slur thick dash l)
519     (string-append 
520      (apply string-append (map control->string l)) 
521      (number->string thick) 
522      " [ "
523      (number->string dash)
524      " "
525      (number->string (* 10 thick))      ;UGH.  10 ?
526      " ] 0 draw_dashed_slur"))
527
528   (define (dashed-line thick dash width)
529     (string-append 
530      (number->string width) 
531      " "
532      (number->string thick) 
533      " [ "
534      (number->string dash)
535      " "
536      (number->string dash)
537      " ] 0 draw_dashed_line"))
538
539   (define (decrescendo thick w h cont)
540     (string-append 
541      (numbers->string (list w h (inexact->exact cont) thick))
542      " draw_decrescendo"))
543
544
545   (define (end-output)
546     "\nshowpage\n")
547   
548   (define (experimental-on) "")
549   
550   (define (filledbox breapth width depth height) 
551     (string-append (numbers->string (list breapth width depth height))
552                    " draw_box" ))
553
554   ;; obsolete?
555   (define (font-def i s)
556     (string-append
557      "\n/" (font i) " {/" 
558      (substring s 0 (- (string-length s) 4))
559      " findfont 12 scalefont setfont} bind def \n"))
560
561   (define (font-switch i)
562     (string-append (font i) " "))
563
564   (define (header-end)
565     (string-append
566      ;; URG: now we can't use scm output without Lily
567      (ly-gulp-file "lilyponddefs.ps")
568      " {exch pop //systemdict /run get exec} "
569      (ly-gulp-file "lily.ps")
570      "{ exch pop //systemdict /run get exec } "
571     ))
572   
573   (define (lily-def key val)
574
575      (if (string=? (substring key 0 (min (string-length "mudelapaper") (string-length key))) "mudelapaper")
576          (string-append "/" key " {" val "} bind def\n")
577          (string-append "/" key " (" val ") def\n")
578          )
579      )
580
581   (define (header creator generate) 
582     (string-append
583      "%!PS-Adobe-3.0\n"
584      "%%Creator: " creator generate "\n"))
585   
586   (define (invoke-char s i)
587     (string-append 
588      "(\\" (inexact->string i 8) ") " s " " ))
589   
590   (define (invoke-dim1 s d) 
591     (string-append
592      (number->string (* d  (/ 72.27 72))) " " s ))
593
594   (define (placebox x y s) 
595     (string-append 
596      (number->string x) " " (number->string y) " {" s "} placebox "))
597
598   (define (bezier-sandwich l thick)
599     (string-append 
600      (apply string-append (map control->string l))
601      (number->string  thick)
602      " draw_bezier_sandwich"))
603
604   (define (start-line height)
605           "\nstart_line {\n")
606   
607   (define (stem breapth width depth height) 
608     (string-append (numbers->string (list breapth width depth height))
609                    " draw_box" ))
610
611   (define (stop-line)
612       "}\nstop_line\n")
613
614   (define (text s)
615     (string-append "(" s ") show  "))
616
617
618   (define (volta h w thick vert_start vert_end)
619     (string-append 
620      (numbers->string (list h w thick (inexact->exact vert_start) (inexact->exact vert_end)))
621      " draw_volta"))
622
623   (define (tuplet ht gap dx dy thick dir)
624     (string-append 
625      (numbers->string (list ht gap dx dy thick (inexact->exact dir)))
626      " draw_tuplet"))
627
628
629   (define (unknown) 
630     "\n unknown\n")
631
632
633   ;; PS
634   (cond ((eq? action-name 'all-definitions)
635          `(begin
636             (define beam ,beam)
637             (define tuplet ,tuplet)
638             (define bracket ,bracket)
639             (define char ,char)
640             (define crescendo ,crescendo)
641             (define volta ,volta)
642             (define bezier-sandwich ,bezier-sandwich)
643             (define dashed-line ,dashed-line) 
644             (define dashed-slur ,dashed-slur) 
645             (define decrescendo ,decrescendo) 
646             (define end-output ,end-output)
647             (define experimental-on ,experimental-on)
648             (define filledbox ,filledbox)
649             (define font-def ,font-def)
650             (define font-switch ,font-switch)
651             (define header-end ,header-end)
652             (define lily-def ,lily-def)
653             (define font-load-command ,font-load-command)
654             (define header ,header) 
655             (define invoke-char ,invoke-char) 
656             (define invoke-dim1 ,invoke-dim1)
657             (define placebox ,placebox)
658             (define select-font ,select-font)
659             (define start-line ,start-line)
660             (define stem ,stem)
661             (define stop-line ,stop-line)
662             (define stop-last-line ,stop-line)
663             (define text ,text)
664             ))
665         ((eq? action-name 'tuplet) tuplet)
666         ((eq? action-name 'beam) beam)
667         ((eq? action-name 'bezier-sandwich) bezier-sandwich)
668         ((eq? action-name 'bracket) bracket)
669         ((eq? action-name 'char) char)
670         ((eq? action-name 'crescendo) crescendo)
671         ((eq? action-name 'dashed-line) dashed-line) 
672         ((eq? action-name 'dashed-slur) dashed-slur) 
673         ((eq? action-name 'decrescendo) decrescendo)
674         ((eq? action-name 'experimental-on) experimental-on)
675         ((eq? action-name 'filledbox) filledbox)
676         ((eq? action-name 'select-font) select-font)
677         ((eq? action-name 'volta) volta)
678         (else (error "unknown tag -- PS-SCM " action-name))
679         )
680   )
681
682
683 (define (arg->string arg)
684   (cond ((number? arg) (inexact->string arg 10))
685         ((string? arg) (string-append "\"" arg "\""))
686         ((symbol? arg) (string-append "\"" (symbol->string arg) "\""))))
687
688 (define (func name . args)
689   (string-append 
690    "(" name 
691    (if (null? args) 
692        ""
693        (apply string-append 
694               (map (lambda (x) (string-append " " (arg->string x))) args)))
695    ")\n"))
696
697 (define (sign x)
698   (if (= x 0)
699       1
700       (inexact->exact (/ x (abs x)))))
701
702 ;;;; AsciiScript as
703 (define (as-scm action-name)
704
705   (define (beam width slope thick)
706           (string-append
707            (func "set-line-char" "#")
708            (func "rline-to" width (* width slope))
709            ))
710
711   ; simple flat slurs
712   (define (bezier-sandwich l thick)
713           (let (
714                 (c0 (cadddr l))
715                 (c1 (cadr l))
716                 (c3 (caddr l)))
717                (let* ((x (car c0))
718                       (dx (- (car c3) x))
719                       (dy (- (cdr c3) (cdr c0)))
720                       (rc (/ dy dx))
721                       (c1-dx (- (car c1) x))
722                       (c1-line-y (+ (cdr c0) (* c1-dx rc)))
723                       (dir (if (< c1-line-y (cdr c1)) 1 -1))
724                       (y (+ -1 (* dir (max (* dir (cdr c0)) (* dir (cdr c3)))))))
725                      (string-append
726                       (func "rmove-to" x y)
727                       (func "put" (if (< 0 dir) "/" "\\\\"))
728                       (func "rmove-to" 1 (if (< 0 dir) 1 0))
729                       (func "set-line-char" "_")
730                       (func "h-line" (- dx 1))
731                       (func "rmove-to" (- dx 1) (if (< 0 dir) -1 0))
732                       (func "put" (if (< 0 dir) "\\\\" "/"))))))
733
734   (define (bracket arch_angle arch_width arch_height width height arch_thick thick)
735           (string-append
736            (func "rmove-to" (+ width 1) (- (/ height -2) 1))
737            (func "put" "\\\\")
738            (func "set-line-char" "|")
739            (func "rmove-to" 0 1)
740            (func "v-line" (+ height 1))
741            (func "rmove-to" 0 (+ height 1))
742            (func "put" "/")
743            ))
744
745   (define (char i)
746     (func "char" i))
747
748   (define (end-output) 
749     (func "end-output"))
750   
751   (define (experimental-on)
752           "")
753
754   (define (filledbox breapth width depth height)
755           (let ((dx (+ width breapth))
756                 (dy (+ depth height)))
757                (string-append 
758                 (func "rmove-to" (* -1 breapth) (* -1 depth))
759                 (if (< dx dy)
760                     (string-append
761                      (func "set-line-char" 
762                            (if (<= dx 1) "|" "#"))
763                      (func "v-line" dy))
764                     (string-append
765                      (func "set-line-char" 
766                            (if (<= dy 1) "-" "="))
767                     (func "h-line" dx))))))
768
769   (define (font-load-command name-mag command)
770     (func "load-font" (car name-mag) (magstep (cdr name-mag))))
771
772   (define (header creator generate) 
773     (func "header" creator generate))
774
775   (define (header-end) 
776     (func "header-end"))
777
778   ;; urg: this is good for half of as2text's execution time
779   (define (xlily-def key val)
780           (string-append "(define " key " " (arg->string val) ")\n"))
781
782   (define (lily-def key val)
783           (if 
784            (or (equal? key "mudelapaperlinewidth")
785                (equal? key "mudelapaperstaffheight"))
786            (string-append "(define " key " " (arg->string val) ")\n")
787            ""))
788
789   (define (placebox x y s) 
790     (let ((ey (inexact->exact y)))
791           (string-append "(move-to " (number->string (inexact->exact x)) " "
792                          (if (= 0.5 (- (abs y) (abs ey)))
793                              (number->string y)
794                              (number->string ey))
795                          ")\n" s)))
796                        
797   (define (select-font font-name-symbol)
798     (let* ((c (assoc font-name-symbol font-name-alist)))
799       (if (eq? c #f)
800           (begin
801             (ly-warn 
802              (string-append 
803               "Programming error: No such font known " 
804               (car font-name-symbol)))
805             "")                         ; issue no command
806           (func "select-font" (car font-name-symbol)))))
807
808   (define (start-line height)
809           (func "start-line" height))
810
811   (define (stop-line)
812           (func "stop-line"))
813
814   (define (text s)
815           (func "text" s))
816
817   (define (volta h w thick vert-start vert-end)
818           ;; urg
819           (string-append
820            (func "set-line-char" "|")
821            (func "rmove-to" 0 -4)
822            ;; definition strange-way around
823            (if (= 0 vert-start)
824               (func "v-line" h)
825                "")
826            (func "rmove-to" 1 h)
827            (func "set-line-char" "_")
828            (func "h-line" (- w 1))
829            (func "set-line-char" "|")
830            (if (= 0 vert-end)
831                (string-append
832                 (func "rmove-to" (- w 1) (* -1 h))
833                 (func "v-line" (* -1 h)))
834                "")))
835
836   (cond ((eq? action-name 'all-definitions)
837          `(begin
838             (define beam ,beam)
839             (define bracket ,bracket)
840             (define char ,char)
841             ;;(define crescendo ,crescendo)
842             (define bezier-sandwich ,bezier-sandwich)
843             ;;(define dashed-slur ,dashed-slur) 
844             ;;(define decrescendo ,decrescendo) 
845             (define end-output ,end-output)
846             (define experimental-on ,experimental-on)
847             (define filledbox ,filledbox)
848             ;;(define font-def ,font-def)
849             (define font-load-command ,font-load-command)
850             ;;(define font-switch ,font-switch)
851             (define header ,header) 
852             (define header-end ,header-end)
853             (define lily-def ,lily-def)
854             ;;(define invoke-char ,invoke-char) 
855             ;;(define invoke-dim1 ,invoke-dim1)
856             (define placebox ,placebox)
857             (define select-font ,select-font)
858             (define start-line ,start-line)
859             ;;(define stem ,stem)
860             (define stop-line ,stop-line)
861             (define stop-last-line ,stop-line)
862             (define text ,text)
863             ;;(define tuplet ,tuplet)
864             (define volta ,volta)
865             ))
866         ;;((eq? action-name 'tuplet) tuplet)
867         ;;((eq? action-name 'beam) beam)
868         ;;((eq? action-name 'bezier-sandwich) bezier-sandwich)
869         ;;((eq? action-name 'bracket) bracket)
870         ((eq? action-name 'char) char)
871         ;;((eq? action-name 'crescendo) crescendo)
872         ;;((eq? action-name 'dashed-slur) dashed-slur) 
873         ;;((eq? action-name 'decrescendo) decrescendo)
874         ;;((eq? action-name 'experimental-on) experimental-on)
875         ((eq? action-name 'filledbox) filledbox)
876         ((eq? action-name 'select-font) select-font)
877         ;;((eq? action-name 'volta) volta)
878         (else (error "unknown tag -- MUSA-SCM " action-name))
879         )
880   )
881
882
883 (define (gulp-file name)
884   (let* ((port (open-file name "r"))
885          (content (let loop ((text ""))
886                        (let ((line (read-line port)))
887                             (if (or (eof-object? line)
888                                     (not line)) 
889                                 text
890                                 (loop (string-append text line "\n")))))))
891         (close port)
892         content))
893
894 ;; urg: Use when standalone, do:
895 ;; (define (ly-gulp-file name) (scm-gulp-file name))
896 (define (scm-gulp-file name)
897   (set! %load-path 
898         (cons (string-append (getenv 'LILYPONDPREFIX) "/ly")
899               (cons (string-append (getenv 'LILYPONDPREFIX) "/ps")
900                     %load-path)))
901   (let ((path (%search-load-path name)))
902        (if path
903            (gulp-file path)
904            (gulp-file name))))
905
906 (define (scm-tex-output)
907   (eval (tex-scm 'all-definitions)))
908                                 
909 (define (scm-ps-output)
910   (eval (ps-scm 'all-definitions)))
911
912 (define (scm-as-output)
913   (eval (as-scm 'all-definitions)))
914                                 
915 ; Russ McManus, <mcmanus@IDT.NET>  
916
917 ; I use the following, which should definitely be provided somewhere
918 ; in guile, but isn't, AFAIK:
919
920
921
922 (define (hash-table-for-each fn ht)
923   (do ((i 0 (+ 1 i)))
924       ((= i (vector-length ht)))
925     (do ((alist (vector-ref ht i) (cdr alist)))
926         ((null? alist) #t)
927       (fn (car (car alist)) (cdr (car alist))))))
928
929 (define (hash-table-map fn ht)
930   (do ((i 0 (+ 1 i))
931        (ret-ls '()))
932       ((= i (vector-length ht)) (reverse ret-ls))
933     (do ((alist (vector-ref ht i) (cdr alist)))
934         ((null? alist) #t)
935       (set! ret-ls (cons (fn (car (car alist)) (cdr (car alist))) ret-ls)))))
936
937
938
939 (define (index-cell cell dir)
940   (if (equal? dir 1)
941       (cdr cell)
942       (car cell)))
943
944 ;
945 ; How should a  bar line behave at a break? 
946 ;
947 (define (break-barline glyph dir)
948    (let ((result (assoc glyph 
949                         '((":|:" . (":|" . "|:"))
950                           ("|" . ("|" . ""))
951                           ("|s" . (nil . "|"))
952                           ("|:" . ("|" . "|:"))
953                           ("|." . ("|." . nil))
954                           (":|" . (":|" . nil))
955                           ("||" . ("||" . nil))
956                           (".|." . (".|." . nil))
957                           ("scorebar" . (nil . "scorepostbreak"))
958                           ("brace" . (nil . "brace"))
959                           ("bracket" . (nil . "bracket"))  
960                           )
961                         )))
962
963      (if (equal? result #f)
964          (ly-warn (string-append "Unknown bar glyph: `" glyph "'"))
965          (index-cell (cdr result) dir))
966      )
967    )
968      
969
970 (define (slur-ugly ind ht)
971   (if (and
972 ;       (< ht 4.0)
973        (< ht (* 4 ind))
974        (> ht (* 0.4 ind))
975        (> ht (+ (* 2 ind) -4))
976        (< ht (+ (* -2 ind) 8)))
977       #f
978       (cons ind  ht)
979   ))