2 ;; Copyright (c) 2006, Cyrus Harmon
4 ;; latex.cl - latex output from smarkup
9 (defvar *baseline-skip
* "12pt")
10 (defvar *baseline-stretch
* "1.6")
11 (defvar *par-skip
* "18pt")
12 (defvar *latex-graphics-params
* nil
)
14 (defparameter *document-format-parameters
*
15 '(#+nil
("oddsidemargin" .
"0.5in")
16 #+nil
("textwidth" .
"6.0in")
17 #+nil
("topmargin" .
"0in")
18 #+nil
("headheight" .
"0.1in")
19 #+nil
("headsep" .
"0.0in")
20 #+nil
("textheight" .
"9.6in")
21 #+nil
("footskip" .
"0.4in")
22 #+nil
("parindent" .
"0.5in")))
24 (defvar *section-numbering-depth
* 5)
26 (defparameter *document-class
* "article")
27 (defparameter *document-options
* '("10pt"))
29 (defvar *document-latex-commands
*
30 '("\\newcommand{\\argmax}{\\operatornamewithlimits{argmax}}"
31 "\\newcommand{\\argmin}{\\operatornamewithlimits{argmin}}"))
33 (defparameter *latex-packages
*
34 '("amssymb" "amsmath" "verbatim" "graphicx" "subfigure"
35 "caption" "hyperref" "fancyheadings" "longtable"
36 ("geometry" .
"letterpaper")))
38 (defparameter *thesis-preamble
*
39 "\\DeclareCaptionFont{singlespacing}{\\ssp}
40 \\captionsetup{font={singlespacing,small}}")
42 ;;; \\captionsetup{font={singlespacing,small}}
44 (defparameter *beamer-preamble
*
45 "\\mode<presentation>{
46 \\definecolor{nicegreen}{RGB}{10,100,10}
47 \\setbeamercolor*{normal text}{bg=black,fg=white}
48 \\setbeamercolor{structure}{fg=nicegreen}
53 (defparameter *res-preamble
* "
55 \\evensidemargin -.5in
61 \\textheight=60\\baselineskip
65 \\newenvironment{list1}{
67 \\setlength{\\itemsep}{0in}
68 \\setlength{\\parsep}{0in} \\setlength{\\parskip}{0in}
69 \\setlength{\\topsep}{0in} \\setlength{\\partopsep}{0in}
70 \\setlength{\\leftmargin}{0.17in}}}{\\end{list}}
71 \\newenvironment{list2}{
72 \\begin{list}{$\\bullet$}{%
73 \\setlength{\\itemsep}{0in}
74 \\setlength{\\parsep}{0in} \\setlength{\\parskip}{0in}
75 \\setlength{\\topsep}{0in} \\setlength{\\partopsep}{0in}
76 \\setlength{\\leftmargin}{0.2in}}}{\\end{list}}")
78 (defparameter *llncs-preamble
*
79 "\\bibliographystyle{splncs}
80 \\renewcommand\\floatpagefraction{.9}
81 \\renewcommand\\topfraction{.9}
82 \\renewcommand\\bottomfraction{.9}
83 \\renewcommand\\textfraction{.1}
84 \\setcounter{totalnumber}{50}
85 \\setcounter{topnumber}{50}
86 \\setcounter{bottomnumber}{50}
89 (defparameter *acm-proc-article-preamble
*
90 "\\bibliographystyle{splncs}
91 \\renewcommand\\floatpagefraction{.95}
92 \\renewcommand\\topfraction{.95}
93 \\renewcommand\\bottomfraction{.95}
94 \\renewcommand\\textfraction{.1}
95 \\setcounter{totalnumber}{50}
96 \\setcounter{topnumber}{50}
97 \\setcounter{bottomnumber}{50}
103 (defparameter *article-preamble
*
104 "\\setcounter{topnumber}{2}
105 \\setcounter{bottomnumber}{2}
106 \\setcounter{totalnumber}{4} % 2 may work better
107 \\setcounter{dbltopnumber}{2} % for 2-column pages
108 \\renewcommand{\\dbltopfraction}{0.9} % fit big float above 2-col. text
109 \\renewcommand{\\textfraction}{0.07} % allow minimal text w. figs
110 % Parameters for FLOAT pages (not text pages):
111 \\renewcommand{\\floatpagefraction}{0.7} % require fuller float pages
112 % N.B.: floatpagefraction MUST be less than topfraction !!
113 \\renewcommand{\\dblfloatpagefraction}{0.7} % require fuller float pages
114 \\setlength{\\captionmargin}{10pt}")
116 (defvar *article-headings
* '((:h1 .
"section")
118 (:h3 .
"subsubsection")
119 (:h4 .
"paragraph")))
121 (defvar *thesis-headings
* '((:h1 .
"chapter")
124 (:h4 .
"subsubsection")))
126 (defparameter *thesis-approval-page
* t
)
128 (defun latex-command (command &optional arg
)
129 (format nil
"~&\\~A~@[{~A}~]~%" command arg
))
131 (defgeneric emit-latex
(stream thing
&key newline
))
132 (defgeneric emit-latex-gf
(stream type children
&key newline
))
134 ;;; default is a no-op
135 (defmethod emit-latex (stream thing
&key newline
)
136 (declare (ignore newline
)))
138 (defmethod emit-latex (stream (thing string
) &key newline
)
139 (declare (ignore newline
))
140 (format stream
"~A" thing
))
142 (defmethod emit-latex (stream (thing string
) &key newline
)
143 (format stream
"~A~:[~;~%~]" thing newline
))
145 (defmethod emit-latex (stream (thing character
) &key newline
)
146 (emit-latex stream
(string thing
) :newline newline
))
148 (defmethod emit-latex (stream (thing cons
) &key
(newline nil newline-supplied-p
))
149 (cond ((atom (car thing
))
150 (apply #'emit-latex-gf stream
(car thing
) (cdr thing
)
151 (when newline-supplied-p
`(:newline
,newline
))))
153 (apply #'emit-latex-gf stream
(caar thing
) (cdr thing
)
154 (when newline-supplied-p
`(:newline
,newline
))))))
156 (defmethod emit-latex (stream (thing (eql :nbsp
)) &key
(newline nil
))
157 (emit-latex stream
"~" :newline newline
))
159 (defmethod emit-latex (stream (thing (eql :hr
)) &key
(newline nil
))
160 (declare (ignore newline
))
161 (emit-latex-newline stream
))
163 (defmethod emit-latex (stream (thing (eql :newline
)) &key
(newline nil
))
164 (declare (ignore newline
))
165 (emit-latex stream
"\\\\" :newline t
))
167 (defmethod emit-latex (stream (thing (eql :pause
)) &key
(newline nil
))
168 (emit-latex stream
"\\pause" :newline newline
))
170 (defmethod emit-latex (stream (thing (eql :hfill
)) &key
(newline nil
))
171 (emit-latex stream
"\\hfill" :newline newline
))
173 (defmethod emit-latex (stream (thing (eql :qquad
)) &key
(newline nil
))
174 (emit-latex stream
"\\qquad" :newline newline
))
176 (defmethod emit-latex (stream (thing (eql :quad
)) &key
(newline nil
))
177 (emit-latex stream
"\\quad" :newline newline
))
179 (defun emit-latex-freshline (stream)
180 (format stream
"~&"))
182 (defun emit-latex-newline (stream)
183 (format stream
"~%"))
185 ;;; default is a no-op
186 (defmethod emit-latex-gf (stream type children
&key newline
)
187 (declare (ignore newline
)))
189 (defun emit-children-to-string (children)
190 (cond ((null children
) nil
)
192 (apply #'concatenate
'string
193 (loop for c in children collect
(emit-latex nil c
))))
196 (defmethod emit-latex-gf (stream (type (eql :p
)) children
&key
(newline t
))
197 (emit-latex-freshline stream
)
199 (emit-latex stream c
))
201 (emit-latex-newline stream
)
202 (emit-latex-newline stream
)))
204 (defun emit-latex-command (stream command children
207 (initial-freshline t
)
209 (format stream
"~:[~;~&~]\\~A~@[[~A]~]~@[{~A}~]~:[~;~%~]"
213 (cond ((null children
) nil
)
215 (apply #'concatenate
'string
216 (loop for c in children collect
(emit-latex nil c
))))
220 (defun emit-latex-command-2 (stream command
&key options arg1 arg2
(newline t
))
221 (format stream
"~&\\~A~@[[~A]~]~@[{~A}~]~@[{~A}~]~:[~;~%~]" command options arg1 arg2 newline
))
223 (defun emit-latex-command-3 (stream command section
&key options arg1 arg2
(newline t
))
224 (format stream
"~&\\~A{~A}~@[[~A]~]~@[{~A}~]~@[{~A}~]~:[~;~%~]" command section options arg1 arg2 newline
))
226 (defun emit-latex-command-4 (stream command children
229 (initial-freshline t
)
231 (format stream
"~:[~;~&~]\\~A~@[[~A]~]{"
235 (loop for c in children do
(emit-latex stream c
))
236 (format stream
"}~:[~;~%~]" newline
))
239 ;;; takes options command, options, arg1, arg2 and arg3, e.g.:
240 ;;; (emit-latex-command-5 nil "command" :options "options" :arg1 "arg1" :arg2 "arg2")
241 ;;; produces "\\command[options]{arg1}[arg2]{arg3}"
243 (defun emit-latex-command-5 (stream command
&key options arg1 arg2 arg3
(newline t
))
244 (format stream
"~&\\~A~@[[~A]~]~@[{~A}~]~@[[~A]~]~@[{~A}~]~:[~;~%~]"
245 command options arg1 arg2 arg3 newline
))
247 (defun emit-latex-command-6 (stream command children
250 (initial-freshline t
)
252 (format stream
"~:[~;~&~]\\~A~@[{~A}~]~:[~;{~]"
257 (loop for c in children do
(emit-latex stream c
))
258 (format stream
"~:[~;}~]~:[~;~%~]" children newline
))
260 (defun emit-latex-parameter (stream command children
&key
(newline t
))
261 (format stream
"~&\\~A~@[ ~A~]~:[~;~%~]"
263 (cond ((null children
) nil
)
265 (apply #'concatenate
'string
266 (loop for c in children collect
(emit-latex nil c
))))
270 (defmethod emit-latex-gf (stream (type (eql :div
)) children
&key newline
)
271 (loop for c in children collect
272 (emit-latex stream c
))
273 (when newline
(emit-latex-newline stream
)))
275 (defmethod emit-latex-gf (stream (type (eql :span
)) children
&key newline
)
276 #+nil
(format stream
"~{~A~}~:[~;~%~]"
277 (loop for c in children collect
(emit-latex nil c
))
279 (loop for c in children collect
(emit-latex stream c
)))
281 (defun emit-latex-block (command stream children
&key newline
)
282 (format stream
"{\\~A ~{~A~}}~:[~;~%~]" command
283 (loop for c in children collect
(emit-latex nil c
))
286 (defmacro with-latex-block
(command stream
&rest rest
)
288 (format ,stream
"{\\~A " ,command
)
290 (format ,stream
"}~:[~;~%~]" t
)))
292 (defmethod emit-latex-gf (stream (type (eql :i
)) children
&key newline
)
293 (emit-latex-block "it" stream children
:newline newline
))
295 (defmethod emit-latex-gf (stream (type (eql :b
)) children
&key newline
)
296 (emit-latex-block "bf" stream children
:newline newline
))
298 (defmethod emit-latex-gf (stream (type (eql :sc
)) children
&key newline
)
299 (emit-latex-block "sc" stream children
:newline newline
))
301 (defparameter *document-single-space-count
* 0)
303 (defun single-space (stream)
304 (cond ((equal *document-class
* "ucthesis")
305 (incf *document-single-space-count
*)
306 (emit-latex stream
"\\ssp" :newline t
))
307 ((equal *document-class
* "beamer"))
308 ((equal *document-class
* "llncs"))
309 ((equal *document-class
* "acm_proc_article-sp"))
310 (t (emit-latex stream
(format nil
"\\baselineskip~A" "12pt") :newline t
))))
312 (defun default-space (stream)
313 (cond ((equal *document-class
* "ucthesis")
314 (unless (plusp (decf *document-single-space-count
*))
315 (emit-latex stream
(format nil
"\\dsp") :newline t
)))
316 ((equal *document-class
* "beamer"))
317 ((equal *document-class
* "llncs"))
318 ((equal *document-class
* "acm_proc_article-sp"))
319 (t (emit-latex stream
(format nil
"\\baselineskip~A" *baseline-skip
*) :newline t
))))
321 (defmethod emit-latex-gf (stream (type (eql :pre
)) children
&key
(newline nil
))
322 (declare (ignore newline
))
323 (emit-latex-newline stream
)
324 (single-space stream
)
325 (emit-latex-command stream
"begin" '("verbatim") :newline nil
)
326 (format stream
"~{~A~}"
327 (loop for c in children collect
(emit-latex nil c
)))
328 (emit-latex-command stream
"end" '("verbatim"))
329 (default-space stream
))
332 (defmethod emit-latex-gf (stream (type (eql :code
)) children
&key
(newline nil
))
333 (format stream
"~{~A~}~:[~;~%~]"
334 (loop for c in children collect
(emit-latex nil c
))
337 (defmethod emit-latex-gf (stream (type (eql :pseudocode
)) children
&key
(newline t
))
338 (destructuring-bind (&key name
(parameters " ") label
)
340 (single-space stream
)
341 (when (equal *document-class
* "beamer")
342 (emit-latex stream
"{\\scriptsize"))
343 (emit-latex-command-3 stream
"begin" "pseudocode" :options
"framebox" :arg1 name
:arg2 parameters
:newline nil
)
344 (format stream
"~{~A~}~:[~;~%~]"
345 (loop for c in
(cdr children
)
346 collect
(emit-latex nil c
))
349 (emit-latex-command stream
"label" label
:newline t
))
350 (emit-latex-command stream
"end" "pseudocode" :newline newline
)
351 (when (equal *document-class
* "beamer")
352 (emit-latex stream
"}" :newline t
))
353 (emit-latex-newline stream
)
354 (default-space stream
)))
356 (defmethod emit-latex-gf (stream (type (eql :soutput
)) children
&key
(newline))
357 (declare (ignore newline
))
358 (single-space stream
)
359 (emit-latex stream
"{\\scriptsize")
360 (emit-latex-command stream
"begin" "Soutput")
362 (emit-latex stream c
))
363 (emit-latex-command stream
"end" "Soutput")
364 (emit-latex stream
"}" :newline t
)
365 (default-space stream
))
367 (defmethod emit-latex-gf (stream (type (eql :results
)) children
&key
(newline nil
))
368 (format stream
"~{~A~}~:[~;~%~]"
369 (loop for c in children collect
(emit-latex nil c
))
372 (defmethod emit-latex-gf (stream (type (eql :clearpage
)) children
&key
(newline t
))
373 (emit-latex-command stream
"clearpage" nil
:newline t
))
375 (defun get-headings ()
376 (cond ((equal *document-class
* "ucthesis")
378 (t *article-headings
*)))
380 (defvar *default-font-size
* "10pt")
382 (defun setup-headings ()
383 (cond ((member *document-class
* '("ucthesis") :test
#'equal
)
384 (setf *document-options
* '("11pt")))
385 ((member *document-class
* '("beamer") :test
#'equal
)
386 (setf *document-options
* '("10pt")))
387 ((member *document-class
* '("res") :test
#'equal
)
388 (setf *document-options
* '("margin" "line")))
389 ((member *document-class
* '("acm_proc_article-sp") :test
#'equal
)
390 (setf *document-options
* nil
))
391 ((member *document-class
* '("llncs") :test
#'equal
)
392 (setf *document-options
* '("oribibl")))
393 (t (setf *document-options
* `(,*default-font-size
*)))))
395 (defmethod emit-latex-gf (stream (type (eql :appendices
)) children
&key
(newline t
))
396 (declare (ignore newline
))
397 (single-space stream
)
398 (emit-latex-command stream
"appendix" nil
)
399 (loop for c in children
400 do
(emit-latex stream c
))
401 (default-space stream
))
403 (defparameter *h1-default-clearpage
* t
)
404 (defparameter *h2-default-clearpage
* t
)
406 (defparameter *default-number-sections
* t
)
408 (defmethod emit-latex-gf (stream (type (eql :h1
)) children
&key
(newline t
))
409 (ch-util::with-keyword-args
((label
410 (clearpage *h1-default-clearpage
*)
411 (no-number (not *default-number-sections
*)))
414 (when (and clearpage
(not (eql clearpage
:nil
)))
415 (emit-latex-command stream
"clearpage" nil
:newline t
))
416 (when (equal *document-class
* "ucthesis")
417 (emit-latex stream
"\\pagestyle{fancyplain}" :newline t
)
418 (emit-latex stream
"\\cfoot{}" :newline t
))
419 (emit-latex-command stream
(format nil
"~A~:[~;*~]"
420 (cdr (assoc type
(get-headings)))
422 children
:newline newline
)
424 (emit-latex-command stream
"label" label
:newline newline
))))
427 (defmethod emit-latex-header (stream type children
&key
(newline t
))
428 (ch-util::with-keyword-args
((label
429 (clearpage *h2-default-clearpage
*)
430 (no-number (not *default-number-sections
*))) children
)
432 (when (and clearpage
(not (eql clearpage
:nil
)))
433 (emit-latex-command stream
"clearpage" nil
:newline t
))
434 (single-space stream
)
435 (emit-latex-command stream
(format nil
"~A~:[~;*~]"
436 (cdr (assoc type
(get-headings)))
438 children
:newline newline
)
440 (emit-latex-command stream
"label" label
:newline newline
))
441 (default-space stream
)))
443 (defmethod emit-latex-gf (stream (type (eql :h2
)) children
&key
(newline t
))
445 (emit-latex-header stream type children
:newline newline
)
447 #+nil
(ch-util::with-keyword-args
((label) children
)
450 (emit-latex-command stream
'label label
:newline newline
))))
452 (defmethod emit-latex-gf (stream (type (eql :h3
)) children
&key
(newline t
))
453 #+nil
(when (equal *document-class
* "article")
454 (emit-latex-command stream
"res" '("-14pt")))
456 (emit-latex-header stream type children
:newline newline
))
458 (defmethod emit-latex-gf (stream (type (eql :h4
)) children
&key
(newline t
))
459 #+nil
(when (equal *document-class
* "article")
460 (emit-latex-command stream
"res" '("-14pt")))
461 (emit-latex-header stream type children
:newline newline
))
463 (defmethod emit-latex-gf (stream (type (eql :part
)) children
&key
(newline nil
))
464 (emit-latex-command stream
"part" (format nil
"~{~A~^, ~}" children
) :newline newline
))
466 (defmethod emit-latex-gf (stream (type (eql :bibcite
)) children
&key
(newline nil
))
467 (emit-latex-command stream
"cite" (format nil
"~{~A~^, ~}" children
) :initial-freshline nil
:newline newline
))
469 (defmethod emit-latex-gf (stream (type (eql :caption
)) children
&key
(newline nil
))
470 (ch-util::with-keyword-args
(((figure-label t
)) children
)
472 (let ((label (if figure-label
475 (emit-latex-command stream label children
:newline newline
:initial-freshline nil
))))
477 (defmethod emit-latex-gf (stream (type (eql :label
)) children
&key
(newline nil
))
478 (emit-latex-command stream
"label" children
:newline newline
))
480 (defmethod emit-latex-gf (stream (type (eql :ref
)) children
&key newline
)
481 (declare (ignore newline
))
482 (emit-latex-command stream
"ref" children
:initial-freshline nil
:newline nil
))
484 (defmethod emit-latex-gf (stream (type (eql :nbsp
)) children
&key newline
)
485 (declare (ignore newline children
))
486 (emit-latex stream
"~"))
488 (defmethod emit-latex-gf (stream (type (eql :centering
)) children
&key
(newline nil
))
489 (emit-latex-command-6 stream
"centering" children
:newline newline
))
491 (defmethod emit-latex-gf (stream (type (eql :center2
)) children
&key
(newline nil
))
492 (declare (optimize (debug 3))
494 (emit-latex-newline stream
)
495 (emit-latex-command stream
"begin" '("centering") :newline nil
)
497 (emit-latex stream p
:newline nil
))
498 (emit-latex-command stream
"end" '("centering")))
500 (defparameter *image-copy-path
* nil
)
502 (defparameter *copy-image-files
* nil
)
504 (defmethod emit-latex-gf (stream (type (eql :image
)) children
&key
(newline t
))
505 (destructuring-bind (image-pathname &key
507 (copy *copy-image-files
*)
508 (convert-png-to-eps nil
)
511 (let ((image-file (ch-util:unix-name image-pathname
)))
512 (when (and copy
*image-copy-path
*)
513 (let ((new-file (merge-pathnames (make-pathname :name
(pathname-name image-file
)
514 :type
(pathname-type image-file
)
515 :directory
(cons :relative
(nthcdr 5 (pathname-directory image-file
))))
517 (ensure-directories-exist new-file
)
518 (cond ((and convert-png-to-eps
519 (equal (pathname-type image-file
)
521 (setf new-file
(merge-pathnames (make-pathname :type
"eps")
523 (print (sb-ext::run-program
"/Users/sly/bin/png2eps"
525 :environment
'("PATH=/bobo/bin:/sw/bin:/sw/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/Users/sly/bin:/opt/local/bin:")
526 :if-output-exists
:supersede
529 (cl-fad::copy-file image-file new-file
:overwrite t
)))
533 (setf image-file new-file
)))
534 (apply #'emit-latex-command-2
540 (when width
`(:options
,(format nil
"width=~A" width
))))))))
542 (defparameter *default-figure-placement
* "tbp")
544 (defmethod emit-latex-gf (stream
549 (placement *default-figure-placement
*))
550 (declare (ignorable newline
))
551 (ch-util::with-keyword-args
(((placement placement
)
552 (increment-counter t
)
556 (emit-latex-command-3 stream
"begin" "figure" :options placement
:newline nil
)
557 (when subfigure-start
558 (let ((subfigure-start (if (numberp subfigure-start
)
560 (parse-integer subfigure-start
))))
561 (when (plusp subfigure-start
)
562 (list (emit-latex-command-2 stream
"addtocounter"
564 :arg2 subfigure-start
567 (emit-latex stream p
:newline nil
))
569 (emit-latex-command stream
"label" label
:newline t
))
570 (emit-latex-command stream
"end" "figure")
571 (when (or (not increment-counter
)
572 (eql increment-counter
:nil
))
573 (list (emit-latex-command-2 stream
"addtocounter" :arg1
"figure" :arg2
"-1" :newline nil
)))))
575 (defmethod emit-latex-gf (stream
576 (type (eql :figure
*))
580 (placement *default-figure-placement
*))
581 (declare (ignorable newline
))
582 (ch-util::with-keyword-args
(((placement placement
) label
) children
)
584 (emit-latex-command-3 stream
"begin" "figure*" :options placement
:newline nil
)
586 (emit-latex stream p
:newline nil
))
588 (emit-latex-command stream
"label" label
:newline t
))
589 (emit-latex-command stream
"end" "figure*")))
591 (defmethod emit-latex-gf (stream (type (eql :subfigure
)) children
&key
(newline nil
))
592 (ch-util::with-keyword-args
((caption (increment-counter t
)) children
)
595 (setf caption
(emit-children-to-string caption
)))
596 (apply #'concatenate
'string
597 (apply #'emit-latex-command
601 (when caption
`(:options
,caption
))
602 `(:newline
,newline
)))
603 (unless (or caption increment-counter
)
604 (list (emit-latex-command-2 stream
"addtocounter" :arg1
"subfigure" :arg2
"-1" :newline nil
))))))
606 (defmethod emit-latex-gf (stream (type (eql :document-element
)) children
&key
(newline t
))
607 (destructuring-bind (element &rest rest
) children
608 (emit-latex-command-3 stream
"begin" element
:newline newline
)
610 (emit-latex stream p
:newline nil
))
611 (when (string-equal element
"abstract")
612 (cond ((equal *document-class
* "ucthesis")
613 (emit-latex-command stream
"abstractsignature" nil
))))
614 (emit-latex-command stream
"end" element
)))
616 (defmethod emit-latex-gf (stream (type (eql :document-command
)) children
&key
(newline t
))
617 (destructuring-bind (element &rest rest
) children
618 (emit-latex-command-6 stream element rest
:newline newline
)))
620 ;;; "scicite" "pslatex" "times" "epsfig" "graphs" "newcent"
622 (defun include-contents-of-file-file (stream file
)
623 (emit-latex stream
(ch-util::contents-of-file file
)))
625 (defun latex-document-format (stream)
626 (dolist (package *latex-packages
*)
628 (emit-latex-command-2 stream
"usepackage" :options
(cdr package
) :arg1
(car package
))
629 (emit-latex-command stream
"usepackage" package
)))
630 (loop for
(param . val
) in
*document-format-parameters
*
631 do
(emit-latex-parameter stream param val
))
632 (dolist (command *document-latex-commands
*)
633 (emit-latex stream command
)))
635 (defun latex-document (stream sexp
&key
(options *document-options
*) (class *document-class
*))
636 (emit-latex-command-2 stream
"documentclass"
637 :options
(format nil
"~{~A~^,~}" options
) :arg1 class
:newline t
)
638 (unless (equal *document-class
* "llncs")
639 (emit-latex-command-2 stream
"setcounter"
641 :arg2
*section-numbering-depth
* :newline t
))
642 (latex-document-format stream
)
644 (when *document-title
*
645 (emit-latex-command stream
"title" (list *document-title
*)))
646 (when *document-titlerunning
*
647 (emit-latex-command stream
"titlerunning" (list *document-titlerunning
*)))
648 (when (and *document-subtitle
*
649 (equal *document-class
* "beamer"))
650 (emit-latex-command stream
"subtitle" (list *document-subtitle
*)))
651 (when *document-author
*
652 (emit-latex-command stream
"author" (list *document-author
*)))
653 (when *document-tocauthor
*
654 (emit-latex-command stream
"tocauthor" (list *document-tocauthor
*)))
655 (when *document-authorrunning
*
656 (emit-latex-command stream
"authorrunning" (list *document-authorrunning
*)))
657 (when *document-address
*
658 (emit-latex-command stream
"address" (list *document-address
*)))
659 (when *document-institute
*
660 (emit-latex-command stream
"institute" (list *document-institute
*)))
661 (when *document-date
*
662 (emit-latex-command stream
"date" (list *document-date
*)))
663 (when (equal *document-class
* "ucthesis")
664 (when *document-degree-year
*
665 (emit-latex-command stream
"degreeyear" (list *document-degree-year
*)))
666 (when *document-degree-semester
*
667 (emit-latex-command stream
"degreesemester" (list *document-degree-semester
*)))
668 (when *document-degree
*
669 (emit-latex-command stream
"degree" (list *document-degree
*)))
670 (when *document-chair
*
671 (emit-latex-command stream
"chair" (list *document-chair
*)))
672 (when *document-other-members
*
673 (emit-latex-command stream
"othermembers" (list *document-other-members
*)))
674 (when *document-number-of-members
*
675 (emit-latex-command stream
"numberofmembers" (list *document-number-of-members
*)))
676 (when *document-prev-degrees
*
677 (emit-latex-command stream
"prevdegrees" (list *document-prev-degrees
*)))
678 (when *document-field
*
679 (emit-latex-command stream
"field" (list *document-field
*)))
680 (when *document-campus
*
681 (emit-latex-command stream
"campus" (list *document-campus
*))))
683 (cond ((equal *document-class
* "ucthesis")
686 "\\def\\dsp{\\def\\baselinestretch{~A}\\large\\normalsize}"
689 (emit-latex stream
"\\dsp" :newline t
)
691 (emit-latex stream
"\\addtolength{\\headheight}{\\baselineskip}" :newline t
)
694 (emit-latex stream
"\\lhead[\\fancyplain{}\\sl\\thepage]{\\fancyplain{}\\sl\\rightmark}" :newline t
)
695 (emit-latex stream
"\\rhead[\\fancyplain{}\\sl\\leftmark]{\\fancyplain{}\\sl\\thepage}" :newline t
)
696 (emit-latex stream
"\\lhead[\\fancyplain{}\\bfseries\\thepage]{\\fancyplain{}\\bfseries\\rightmark}" :newline t
)
697 (emit-latex stream
"\\rhead[\\fancyplain{}\\bfseries\\leftmark]{\\fancyplain{}\\bfseries\\thepage}" :newline t
))
698 (progn (emit-latex stream
"\\lhead[\\fancyplain{}{}]{\\fancyplain{}{\\bfseries\\leftmark}}" :newline t
)
699 (emit-latex stream
"\\rhead[\\fancyplain{}{}]{\\fancyplain{\\bfseries\\thepage}{\\bfseries\\thepage}}" :newline t
))
700 (emit-latex stream
"\\hyphenpenalty=1000" :newline t
)
701 (emit-latex stream
"\\clubpenalty=500" :newline t
)
702 (emit-latex stream
"\\widowpenalty=500" :newline t
)
703 (princ *thesis-preamble
* stream
))
704 ((equal *document-class
* "beamer")
705 (princ *beamer-preamble
* stream
))
706 ((equal *document-class
* "res")
707 (princ *res-preamble
* stream
))
708 ((equal *document-class
* "llncs")
709 (princ *llncs-preamble
* stream
))
710 ((equal *document-class
* "acm_proc_article-sp")
711 (princ *acm-proc-article-preamble
* stream
))
713 (emit-latex stream
"\\geometry{verbose,tmargin=1in,bmargin=1in,lmargin=1in,rmargin=1in}" :newline t
)
714 (princ *article-preamble
* stream
)))
716 (emit-latex-command stream
"begin" "document")
717 (emit-latex-freshline stream
)
719 (cond ((equal *document-class
* "beamer"))
720 ((equal *document-class
* "res"))
721 ((equal *document-class
* "acm_proc_article-sp"))
723 (when *document-titlepage
*
724 (emit-latex stream
"\\maketitle" :newline t
))))
726 (cond ((equal *document-class
* "llncs"))
727 ((equal *document-class
* "acm_proc_article-sp"))
729 (emit-latex stream
"\\let\\mypdfximage\\pdfximage" :newline t
)
730 (emit-latex stream
"\\def\\pdfximage{\\immediate\\mypdfximage}" :newline t
)))
732 (cond ((equal *document-class
* "ucthesis")
734 (when *thesis-approval-page
*
735 (emit-latex stream
"\\approvalpage" :newline t
))
736 (emit-latex stream
"\\copyrightpage" :newline t
)))
737 ((equal *document-class
* "beamer"))
738 ((equal *document-class
* "llncs"))
739 ((equal *document-class
* "acm_proc_article-sp"))
741 (emit-latex stream
(format nil
"\\baselineskip~A" *baseline-skip
*) :newline t
)))
744 (emit-latex stream p
))
746 (emit-latex-command stream
"end" "document"))
748 (defun latex-use-package (stream package
)
749 (emit-latex-command stream
"usepackage" package
))
751 (defun latex-use-packages (stream &rest packages
)
752 (mapcar #'(lambda (x) (latex-use-package stream x
)) packages
))
754 ;;; Bibliography stuff
756 (defun latex-cite (stream ref
)
757 (emit-latex-command stream
"cite" ref
))
759 (defun latex-bibliography-style (stream style
)
760 (emit-latex-command stream
"bibliographystyle" style
))
762 (defun latex-bibliography (stream bib
)
763 (emit-latex-command stream
"bibliography" bib
))
765 ;;; The main entry point to this stuff
767 (defmethod render-as ((type (eql :latex
)) sexp file
)
768 (let ((*document-class
* *document-class
*)
769 (*document-degree-year
* *document-degree-year
*)
770 (*document-degree-semester
* *document-degree-semester
*)
771 (*document-degree
* *document-degree
*)
772 (*document-chair
* *document-chair
*)
773 (*document-other-members
* *document-other-members
*)
774 (*document-number-of-members
* *document-number-of-members
*)
775 (*document-prev-degrees
* *document-prev-degrees
*)
776 (*document-field
* *document-field
*)
777 (*document-campus
* *document-campus
*)
778 (*latex-packages
* *latex-packages
*)
779 (*document-format-parameters
* *document-format-parameters
*))
781 (with-open-file (stream file
:direction
:output
:if-exists
:supersede
)
782 (latex-document stream sexp
)))
785 ;; the intent here is that :bibliography is a tag with no children and
786 ;; that we should output the appropriate latex bibliography here.
787 (defmethod emit-latex-gf (stream (type (eql :bibliography
)) children
&key
(newline t
))
788 (declare (optimize (debug 3)) (ignore newline
))
789 (destructuring-bind (&rest rest
&key
(clearpage t
) &allow-other-keys
)
791 (declare (ignore rest
))
792 (when (and clearpage
(not (eql clearpage
:nil
)))
793 (emit-latex-command stream
"clearpage" nil
:newline t
)))
794 (unless (member *document-class
* '("beamer" "llncs") :test
'equal
)
795 (emit-latex stream
(format nil
"\\baselineskip~A" "11pt") :newline t
))
796 (let ((style-function (bibtex-compiler:find-bibtex-style
*bibtex-style
*))
797 (bibtex-runtime:*cite-keys
* (reverse *cite-keys
*))
798 (bibtex-runtime:*bib-macros
* *bibtex-macros
*)
799 (bibtex-runtime:*bib-database
* *bibtex-database
*)
800 (bibtex-runtime:*bib-files
* nil
)
801 (bibtex-runtime:*bbl-output
* stream
))
802 (funcall style-function
)))
804 (defmethod emit-latex-gf (stream (type (eql :table-of-contents
)) children
&key
(newline t
))
805 (declare (ignore newline
))
806 (emit-latex stream
"\\tableofcontents" :newline t
))
808 (defmethod emit-latex-gf (stream (type (eql :list-of-figures
)) children
&key
(newline t
))
809 (declare (ignore newline
))
810 (emit-latex stream
"\\listoffigures" :newline t
))
812 (defmethod emit-latex-gf (stream (type (eql :table-of-tables
)) children
&key
(newline t
))
813 (declare (ignore newline
))
814 (emit-latex stream
"\\listoftables" :newline t
))
821 (defmethod emit-latex-gf (stream (type (eql :quotation
)) children
&key
(newline t
))
822 (declare (ignorable newline
))
823 (emit-latex-command-3 stream
"begin" "quotation" :newline nil
)
825 (emit-latex stream p
:newline nil
))
826 (emit-latex-command stream
"end" "quotation" :newline t
))
828 (defmethod emit-latex-gf (stream (type (eql :equation
)) children
&key
(newline t
))
829 (declare (ignorable newline
))
830 (emit-latex-command-3 stream
"begin" "equation" :newline nil
)
832 (emit-latex stream p
:newline nil
))
833 (emit-latex-command stream
"end" "equation" :newline t
))
835 (defmethod emit-latex-gf (stream (type (eql :matrix
)) children
&key
(newline t
))
836 (declare (ignorable newline
))
838 (emit-latex-command-3 stream
"begin" "matrix" :newline nil
)
840 (emit-latex stream p
:newline nil
))
841 (emit-latex-command stream
"end" "matrix" :newline nil
)
844 (defmethod emit-latex-gf (stream (type (eql :bmatrix
)) children
&key
(newline t
))
845 (declare (ignorable newline
))
847 (emit-latex-command-3 stream
"begin" "bmatrix" :newline nil
)
849 (emit-latex stream p
:newline nil
))
850 (emit-latex-command stream
"end" "bmatrix" :newline nil
)
855 (defmethod emit-latex-gf (stream (type (eql :table
)) children
&key newline
)
856 (destructuring-bind ((&key cols
857 top-line
) (&rest children
))
858 (apply #'ch-util
::remove-keywordish-args
'(:cols
860 (emit-latex-command-3 stream
"begin" "tabular" :arg1 cols
)
862 (emit-latex stream
(format nil
"\\hline~%")))
863 (loop for c in children collect
864 (emit-latex stream c
))
865 (emit-latex-command-3 stream
"end" "tabular")
866 (when newline
(emit-latex-newline stream
))))
868 (defun emit-table-row (stream children
&key
(newline t
))
869 (emit-latex stream
(format nil
"~{~A~^ & ~}\\\\"
870 (mapcar #'(lambda (x)
872 children
)) :newline newline
))
874 (defmethod emit-latex-gf (stream (type (eql :longtable
)) children
&key newline
)
875 (destructuring-bind ((&key cols
879 (first-heading heading
)
880 (first-caption caption
)
881 (font-size "small")) (&rest children
))
882 (apply #'ch-util
::remove-keywordish-args
'(:cols
888 :font-size
) children
)
890 (single-space stream
)
891 (with-latex-block font-size
893 (emit-latex-command-3 stream
"begin" "longtable" :arg1 cols
)
896 (destructuring-bind (first-caption)
898 (emit-latex-command stream
"caption" first-caption
:newline nil
)
899 (emit-latex stream
"\\\\" :newline t
)))
902 (emit-latex stream
"\\hline" :newline t
))
905 (emit-table-row stream
(car first-heading
))
906 (loop for c in
(cdr first-heading
)
907 do
(emit-latex stream c
)))
908 (emit-latex stream
"\\endfirsthead" :newline t
)
911 (destructuring-bind (caption)
913 (emit-latex-command stream
"caption" caption
:newline nil
)
914 (emit-latex stream
"\\\\" :newline t
)))
917 (emit-latex stream
"\\hline" :newline t
))
920 (emit-table-row stream
(car heading
))
921 (loop for c in
(cdr heading
)
922 do
(emit-latex stream c
)))
923 (emit-latex stream
"\\endhead" :newline t
)
925 (loop for c in children collect
926 (emit-latex stream c
))
927 (emit-latex-command-3 stream
"end" "longtable")
928 (when newline
(emit-latex-newline stream
)))
929 (default-space stream
)))
931 (defmethod emit-latex-gf (stream (type (eql :table-row
)) children
&key
(newline t
))
932 (destructuring-bind ((&key multicolumn
(spec "|c|")) (&rest children
))
933 (apply #'ch-util
::remove-keywordish-args
'(:multicolumn
:spec
) children
)
935 (progn (apply #'emit-latex-command-3 stream
"multicolumn" multicolumn
938 :arg2
(mapcar #'(lambda (x)
941 (emit-latex stream
"\\\\" :newline newline
))
942 (emit-latex stream
(format nil
"~{~A~^ & ~}\\\\"
943 (mapcar #'(lambda (x)
945 children
)) :newline newline
))))
947 (defmethod emit-latex-gf (stream (type (eql :horizontal-line
)) children
&key
(newline t
))
948 (emit-latex stream
"\\hline" :newline newline
))
953 (defmethod emit-latex-gf (stream (type (eql :slide
)) children
&key
(newline t
))
954 (ch-util::with-keyword-args
((slide-title) children
)
956 (emit-latex-command-2 stream
"frame")
958 (when slide-title
(emit-latex-command-2 stream
"frametitle" :arg1 slide-title
))
959 (loop for c in children do
(emit-latex stream c
))
962 (emit-latex-newline stream
))))
964 (defmethod emit-latex-gf (stream (type (eql :title-page
)) children
&key
(newline t
))
965 (declare (ignore newline
))
966 (emit-latex-command-2 stream
"titlepage"))
968 (defmethod emit-latex-gf (stream (type (eql :table-of-contents
)) children
&key
(newline t
))
969 (declare (ignore newline
))
970 (emit-latex-command-2 stream
"tableofcontents"))
972 (defmethod emit-latex-gf (stream (type (eql :list
)) children
&key
(newline t
))
973 (emit-latex-command stream
"begin" '("itemize") :newline newline
)
974 (loop for c in children do
(emit-latex stream c
))
975 (emit-latex-command stream
"end" '("itemize") :newline newline
))
977 (defmethod emit-latex-gf (stream (type (eql :item
)) children
&key
(newline t
))
978 (declare (ignore newline
))
979 (emit-latex-command-2 stream
"item " :newline nil
)
980 (loop for c in children do
(emit-latex stream c
)))
982 (defmethod emit-latex-gf (stream (type (eql :colorbox
)) children
&key
(newline nil
))
983 (ch-util::with-keyword-args
(((color "white")) children
)
985 (emit-latex-command-6 stream
"colorbox" children
:arg color
:newline newline
)))
987 ;;; columns for beamer
988 (defmethod emit-latex-gf (stream (type (eql :columns
)) children
&key
(newline t
))
989 (ch-util::with-keyword-args
((format) children
)
991 (emit-latex-command-5 stream
"begin" :arg1
"columns" :arg2 format
:newline newline
)
992 (loop for c in children do
(emit-latex stream c
))
993 (emit-latex-command stream
"end" '("columns") :newline newline
)))
995 (defmethod emit-latex-gf (stream (type (eql :column
)) children
&key
(newline t
))
996 (ch-util::with-keyword-args
((width) children
)
998 (emit-latex-command-2 stream
"begin" :arg1
"column" :arg2
(format nil
"~A\\textwidth" width
) :newline newline
)
999 (loop for c in children do
(emit-latex stream c
))
1000 (emit-latex-command stream
"end" '("column") :newline newline
)))
1002 ;;; minipage (for use with captions)
1005 (defmethod emit-latex-gf (stream (type (eql :minipage
)) children
&key
(newline t
))
1006 (ch-util::with-keyword-args
(((width "0.5")) children
)
1008 (emit-latex-command-5 stream
"begin" :arg1
"minipage" :arg2
"t"
1009 :arg3
(format nil
"~A\\linewidth" width
) :newline newline
)
1010 (loop for c in children do
(emit-latex stream c
))
1011 (emit-latex-command stream
"end" '("minipage") :newline newline
)))
1016 (defmethod emit-latex-gf (stream (type (eql :name
)) children
&key
(newline nil
))
1017 (emit-latex-command stream
"name" children
:newline newline
))
1019 (defmethod emit-latex-gf (stream (type (eql :employer
)) children
&key
(newline nil
))
1020 (emit-latex-command stream
"employer" children
:newline newline
))
1022 (defmethod emit-latex-gf (stream (type (eql :position-title
)) children
&key
(newline nil
))
1023 (emit-latex-command stream
"title" children
:newline newline
))
1025 (defmethod emit-latex-gf (stream (type (eql :dates
)) children
&key
(newline nil
))
1026 (emit-latex-command stream
"dates" children
:newline newline
))
1028 (defmethod emit-latex-gf (stream (type (eql :location
)) children
&key
(newline nil
))
1029 (emit-latex-command stream
"location" children
:newline newline
))
1031 (defmethod emit-latex-gf (stream (type (eql :position
)) children
&key
(newline t
))
1032 (emit-latex-command stream
"begin" '("position") :newline newline
)
1033 (loop for c in children do
(emit-latex stream c
))
1034 (emit-latex-command stream
"end" '("position") :newline newline
))
1036 (defmethod emit-latex-gf (stream (type (eql :resume
)) children
&key
(newline t
))
1037 (emit-latex-command stream
"begin" '("resume") :newline newline
)
1038 (loop for c in children do
(emit-latex stream c
))
1039 (emit-latex-command stream
"end" '("resume") :newline newline
))
1041 (defmethod emit-latex-gf (stream (type (eql :list1
)) children
&key
(newline t
))
1042 (emit-latex-command stream
"begin" '("list1") :newline newline
)
1043 (loop for c in children do
(emit-latex stream c
))
1044 (emit-latex-command stream
"end" '("list1") :newline newline
))
1046 (defmethod emit-latex-gf (stream (type (eql :list2
)) children
&key
(newline t
))
1047 (emit-latex-command stream
"begin" '("list2") :newline newline
)
1048 (loop for c in children do
(emit-latex stream c
))
1049 (emit-latex-command stream
"end" '("list2") :newline newline
))