]> git.donarmstrong.com Git - lilypond.git/blob - scm/output-tex.scm
* scm/output-tex.scm (font-command): use ly: functions to
[lilypond.git] / scm / output-tex.scm
1 ;;;; tex.scm -- implement Scheme output routines for TeX
2 ;;;;
3 ;;;;  source file of the GNU LilyPond music typesetter
4 ;;;; 
5 ;;;; (c)  1998--2004 Jan Nieuwenhuizen <janneke@gnu.org>
6 ;;;;                  Han-Wen Nienhuys <hanwen@cs.uu.nl>
7
8
9 ;; (debug-enable 'backtrace)
10 (define-module (scm output-tex)
11   #:re-export (quote)
12   #:export (define-fonts
13              font-command
14              fontify
15              unknown
16              output-paper-def
17              output-scopes
18              blank
19              dot
20              beam
21              bracket
22              dashed-slur
23              char
24              dashed-line
25              zigzag-line
26              symmetric-x-triangle
27              ez-ball
28              comment
29              end-output
30              experimental-on
31              repeat-slash
32              header-end
33              header
34              placebox
35              bezier-sandwich
36              start-system
37              stop-system
38              stop-last-system
39              horizontal-line
40              filledbox
41              round-filled-box
42              text
43              tuplet
44              polygon
45              draw-line
46              between-system-string
47              define-origin
48              no-origin
49              start-page
50              stop-page
51              )
52 )
53
54 (use-modules (ice-9 regex)
55              (ice-9 string-fun)
56              (ice-9 format)
57              (guile)
58              (srfi srfi-13)
59              (lily))
60
61 ;;;;;;;;
62 ;;;;;;;; DOCUMENT ME!
63 ;;;;;;;;
64
65 (define (font-command font)
66   (string-append
67    "magfont"
68    (string-encode-integer
69     (hashq (ly:font-name font) 1000000))
70    "m"
71    (string-encode-integer
72     (inexact->exact (round (* 1000 (ly:font-magnification font)))))))
73
74 (define (define-fonts paper font-list)
75   (apply string-append
76          (map (lambda (x)
77                 (font-load-command paper x))
78               font-list)
79          ))
80
81 ;;
82 ;; urg, how can exp be #unspecified?  -- in sketch output
83 ;;
84 ;; set! returns #<unspecified>  --hwn
85 ;;
86 (define (fontify font exp)
87   (string-append "\\" (font-command font)
88                  exp))
89
90 (define (unknown) 
91   "%\n\\unknown\n")
92
93 (define (symbol->tex-key sym)
94   (regexp-substitute/global
95    #f "_" (output-tex-string (symbol->string sym)) 'pre "X" 'post) )
96
97 (define (tex-string-def prefix key str)
98   (if (equal? "" (sans-surrounding-whitespace (output-tex-string str)))
99       (string-append "\\let\\" prefix (symbol->tex-key key) "\\undefined%\n")
100       (string-append "\\def\\" prefix (symbol->tex-key key) "{"  (output-tex-string str) "}%\n")
101       ))
102
103 (define (tex-number-def prefix key number)
104   (string-append "\\def\\" prefix (symbol->tex-key key) "{" number "}%\n"))
105
106 (define (output-paper-def pd)
107   (apply
108    string-append
109    (module-map
110     (lambda (sym var)
111       (let ((val (variable-ref var))
112             (key (symbol->tex-key sym)))
113
114         (cond
115          ((string? val)
116           (tex-string-def "lilypondpaper" sym val))
117          ((number? val)
118           (tex-number-def "lilypondpaper" sym
119                           (if (integer? val)
120                               (number->string val)
121                               (number->string (exact->inexact val)))))
122          (else ""))))
123       
124     (ly:output-def-scope pd))))
125
126 (define (output-scopes paper scopes fields basename)
127   (define (output-scope scope)
128     (apply
129      string-append
130      (module-map
131      (lambda (sym var)
132        (let ((val (variable-ref var))
133              ;;(val (if (variable-bound? var) (variable-ref var) '""))
134              (tex-key (symbol->string sym)))
135          
136          (if (and (memq sym fields) (string? val))
137              (header-to-file basename sym val))
138
139          (cond
140           ((string? val)
141            (tex-string-def "lilypond" sym val))
142           ((number? val)
143            (tex-number-def "lilypond" sym
144                            (if (integer? val)
145                                (number->string val)
146                                (number->string (exact->inexact val)))))
147           (else ""))))
148      scope)))
149   
150   (apply string-append
151          (map output-scope scopes)))
152
153 (define (blank)
154   "")
155
156 (define (dot x y radius)
157   (embedded-ps (list 'dot x y radius)))
158
159 (define (beam width slope thick blot)
160   (embedded-ps (list 'beam  width slope thick blot)))
161
162 (define (bracket arch_angle arch_width arch_height height arch_thick thick)
163   (embedded-ps (list 'bracket  arch_angle arch_width arch_height height arch_thick thick)))
164
165 (define (dashed-slur thick dash l)
166   (embedded-ps (list 'dashed-slur thick dash `(quote ,l))))
167
168 (define (char i)
169   (string-append "\\char" (ly:inexact->string i 10) " "))
170
171 (define (dashed-line thick on off dx dy)
172   (embedded-ps (list 'dashed-line  thick on off dx dy)))
173
174 (define (zigzag-line centre? zzw zzh thick dx dy)
175   (embedded-ps (list 'zigzag-line centre? zzw zzh thick dx dy)))
176
177 (define (symmetric-x-triangle t w h)
178   (embedded-ps (list 'symmetric-x-triangle t w h)))
179
180 (define (font-load-command paper font)
181   (string-append
182    "\\font\\" (font-command font) "="
183    (ly:font-name font)
184    " scaled "
185    (ly:number->string (inexact->exact
186                        (round (* 1000
187                           (ly:font-magnification font)
188                           (ly:paper-lookup paper 'outputscale)))))
189    "\n"))
190
191 (define (ez-ball c l b)
192   (embedded-ps (list 'ez-ball  c  l b)))
193
194 (define (header-to-file fn key val)
195   (set! key (symbol->string key))
196   (if (not (equal? "-" fn))
197       (set! fn (string-append fn "." key))
198       )
199   (display
200    (format "writing header field `~a' to `~a'..."
201            key
202            (if (equal? "-" fn) "<stdout>" fn)
203            )
204    (current-error-port))
205   (if (equal? fn "-")
206       (display val)
207       (display val (open-file fn "w"))
208   )
209   (display "\n" (current-error-port))
210   ""
211   )
212
213 (define (embedded-ps expr)
214   (let ((ps-string
215          (with-output-to-string
216            (lambda () (ps-output-expression expr (current-output-port))))))
217     (string-append "\\embeddedps{" ps-string "}")))
218   
219 (define (comment s)
220   (string-append "% " s "\n"))
221
222 (define (end-output) 
223   (begin
224     ;; uncomment for some stats about lily memory         
225     ;; (display (gc-stats))
226     (string-append
227      "\\lilypondend\n"
228      ;; Put GC stats here.
229      )))
230
231 (define (experimental-on)
232   "")
233
234 (define (repeat-slash w a t)
235   (embedded-ps (list 'repeat-slash  w a t)))
236
237 (define (header-end)
238   (string-append
239    "\\def\\scaletounit{ "
240    (number->string (cond
241                      ((equal? (ly:unit) "mm") (/ 72.0  25.4))
242                      ((equal? (ly:unit) "pt") (/ 72.0  72.27))
243                      (else (error "unknown unit" (ly:unit)))
244                      ))
245    " mul }%\n"
246    "\\ifx\\lilypondstart\\undefined\n"
247    "  \\input lilyponddefs\n"
248    "\\fi\n"
249    "\\outputscale = \\lilypondpaperoutputscale\\lilypondpaperunit\n"
250    "\\lilypondstart\n"
251    "\\lilypondspecial\n"
252    "\\lilypondpostscript\n"))
253
254 (define (header creator time-stamp page-count)
255   (string-append
256    "% Generated by " creator "\n"
257    "% at " time-stamp "\n"
258    ;; FIXME: duplicated in every backend
259    "\\def\\lilypondtagline{Engraved by LilyPond (version "
260    (lilypond-version)")}\n"))
261
262 (define (invoke-char s i)
263   (string-append 
264    "\n\\" s "{" (ly:inexact->string i 10) "}" ))
265
266 ;; FIXME: explain ploblem: need to do something to make this really safe.  
267 (define (output-tex-string s)
268   (if safe-mode?
269       (regexp-substitute/global #f "\\\\" s 'pre "$\\backslash$" 'post)
270       s))
271
272 (define (lily-def key val)
273   (let ((tex-key
274          (regexp-substitute/global
275               #f "_" (output-tex-string key) 'pre "X" 'post))
276          
277         (tex-val (output-tex-string val)))
278     (if (equal? (sans-surrounding-whitespace tex-val) "")
279         (string-append "\\let\\" tex-key "\\undefined\n")
280         (string-append "\\def\\" tex-key "{" tex-val "}%\n"))))
281
282 (define (number->dim x)
283   (string-append
284    ;;ugh ly:* in backend needs compatibility func for standalone output
285    (ly:number->string x) " \\outputscale "))
286
287 (define (placebox x y s) 
288   (string-append "\\lyitem{"
289                  (ly:number->string y) "}{"
290                  (ly:number->string x) "}{"
291                  s "}%\n"))
292
293 (define (bezier-sandwich l thick)
294   (embedded-ps (list 'bezier-sandwich  `(quote ,l) thick)))
295
296 (define (start-system wd ht)
297   (string-append "\\leavevmode\n"
298                  "\\scoreshift = " (number->dim (* ht 0.5)) "\n"
299                  "\\lilypondifundefined{lilypondscoreshift}%\n"
300                  "  {}%\n"
301                  "  {\\advance\\scoreshift by -\\lilypondscoreshift}%\n"
302                  "\\lybox{"
303                  (ly:number->string wd) "}{"
304                  (ly:number->string ht) "}{%\n"))
305
306 (define (stop-system) 
307   "}%\n%\n\\interscoreline\n%\n")
308 (define (stop-last-system)
309   "}%\n")
310
311 (define (horizontal-line x1 x2 th)
312   (filledbox (- x1)  (- x2 x1) (* .5 th)  (* .5 th )))
313
314 (define (filledbox breapth width depth height)
315   (if (and #f (defined? 'ps-testing))
316       (embedded-ps
317        (string-append (ly:numbers->string (list breapth width depth height))
318                       " draw_box" ))
319       (string-append "\\lyvrule{"
320                      (ly:number->string (- breapth)) "}{"
321                      (ly:number->string (+ breapth width)) "}{"
322                      (ly:number->string depth) "}{"
323                      (ly:number->string height) "}")))
324
325 (define (round-filled-box x y width height blotdiam)
326   (embedded-ps (list 'round-filled-box  x y width height blotdiam)))
327
328 (define (text s)
329   (string-append "\\hbox{" (output-tex-string s) "}"))
330
331 (define (tuplet ht gapx dx dy thick dir)
332   (embedded-ps (list 'tuplet  ht gapx dx dy thick dir)))
333
334 (define (polygon points blotdiameter)
335   (embedded-ps (list 'polygon `(quote ,points) blotdiameter)))
336
337 (define (draw-line thick fx fy tx ty)
338   (embedded-ps (list 'draw-line thick fx fy tx ty)))
339
340 ;; TODO: this should be a default, which is overriden in PS
341 (define (between-system-string string)
342   string
343   )
344 (define (define-origin file line col)
345   (if (procedure? point-and-click)
346       (string-append "\\special{src:" ;;; \\string ? 
347                      (point-and-click line col file)
348                      "}" )
349       "")
350   )
351
352 ;; no-origin not yet supported by Xdvi
353 (define (no-origin) "")
354
355 (define (start-page)
356   "\n%\\vbox{\n")
357
358 (define (stop-page last?)
359   (if last?
360       "\n%}\n"
361       "\n%}\n\\newpage\n"))