comparison lisp/w3/w3-latex.el @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children ac2d302a0011
comparison
equal deleted inserted replaced
-1:000000000000 0:376386a54a3c
1 ;;; w3-latex.el,v --- Emacs-W3 printing via LaTeX
2 ;; Author: wmperry
3 ;; Created: 1996/06/06 15:00:18
4 ;; Version: 1.4
5 ;; Keywords: hypermedia, printing, typesetting
6
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 ;;; Copyright (c) 1996 by Stephen Peters <speters%samsun@us.oracle.com>
9 ;;;
10 ;;; This file is not part of GNU Emacs, but the same permissions apply.
11 ;;;
12 ;;; GNU Emacs is free software; you can redistribute it and/or modify
13 ;;; it under the terms of the GNU General Public License as published by
14 ;;; the Free Software Foundation; either version 2, or (at your option)
15 ;;; any later version.
16 ;;;
17 ;;; GNU Emacs is distributed in the hope that it will be useful,
18 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;;; GNU General Public License for more details.
21 ;;;
22 ;;; You should have received a copy of the GNU General Public License
23 ;;; along with GNU Emacs; see the file COPYING. If not, write to
24 ;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26 ;;; Elisp code to convert a W3 parse tree into a LaTeX buffer.
27 ;;;
28 ;;; Heavily hacked upon by William Perry <wmperry@spry.com> to add more
29 ;;; bells and whistles.
30 ;;;
31 ;;; KNOWN BUGS:
32 ;;; 1) This does not use stylesheets to get the formatting information
33 ;;; 2) This means that the new drawing routines need to be abstracted
34 ;;; further so that the same main engine can be used for either
35 ;;; text-output (standard stuff in w3-draw), LaTeX output (this file),
36 ;;; Postscript (to-be-implemented), etc., etc.
37 ;;; 3) This still doesn't handle tables.
38 ;;;
39 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
40 (require 'w3-print)
41
42 (defvar w3-latex-print-links nil
43 "*If non-nil, prints the URLs of hypertext links as footnotes on a page.")
44
45 (defvar w3-latex-use-latex2e nil
46 "*If non-nil, configures LaTeX parser to use LaTeX2e syntax. A `nil'
47 value indicates that LaTeX 2.0.9 compatibility will be used instead.")
48
49 (defvar w3-latex-packages nil
50 "*List of LaTeX packages to include. Currently this is only used if
51 `w3-latex-use-latex2e' is non-nil.")
52
53 (defvar w3-latex-use-maketitle nil
54 "*Non-nil makes the LaTeX parser use real LaTeX title pages for
55 document titles.")
56
57 ;; Internal variables - do not touch!
58 (defvar w3-latex-current-url nil "What URL we are formatting")
59 (defvar w3-latex-verbatim nil "Whether we are in a {verbatim} block or not")
60
61 (defvar w3-latex-entities
62 '((nbsp . "~")
63 (iexcl . "!`")
64 ; (cent . "")
65 (pound . "\\pounds ")
66 ; (curren . "")
67 ; (yen . "")
68 (brvbar . "|")
69 (sect . "\\S")
70 (uml . "\\\"{ }")
71 (copy . "\\copyright ")
72 ; (ordf . "")
73 (laquo . "$\\ll$")
74 (not . "\\neg")
75 (shy . "-")
76 (reg . "(R)")
77 (macr . "\\={ }")
78 (deg . "$\\deg$")
79 (plusmn . "$\\pm$")
80 (sup2 . "$^{2}$")
81 (sup3 . "$^{3}$")
82 (acute . "\\'{ }")
83 (micro . "$\\mu$")
84 (para . "\\P ")
85 (middot . "$\\cdot$")
86 (cedil . "\\c{ }")
87 (sup1 . "$^{1}")
88 ; (ordm . "")
89 (raquo . "$\\gg$")
90 (frac14 . "$\frac{1}{4}$")
91 (frac12 . "$\frac{1}{2}$")
92 (frac34 . "$\frac{3}{4}$")
93 (iquest . "?`")
94 (Agrave . "\\`{A}")
95 (Aacute . "\\'{A}")
96 (Acirc . "\\^{A}")
97 (Atilde . "\\~{A}")
98 (Auml . "\\\"{A}")
99 (Aring . "\\AA ")
100 (AElig . "\\AE ")
101 (Ccedil . "\\c{C}")
102 (Egrave . "\\`{E}")
103 (Eacute . "\\'{E}")
104 (Ecirc . "\\^{E}")
105 (Euml . "\\\"{E}")
106 (Igrave . "\\`{I}")
107 (Iacute . "\\'{I}")
108 (Icirc . "\\^{I}")
109 (Iuml . "\\\"{I}")
110 ; (ETH . "")
111 (Ntilde . "\\~{N}")
112 (Ograve . "\\`{O}")
113 (Oacute . "\\'{O}")
114 (Ocirc . "\\^{O}")
115 (Otilde . "\\~{O}")
116 (Ouml . "\\\"{O}")
117 (times . "$\\times$")
118 (Oslash . "\\O")
119 (Ugrave . "\\`{U}")
120 (Uacute . "\\'{U}")
121 (Ucirc . "\\^{U}")
122 (Uuml . "\\\"{U}")
123 (Yacute . "\\'{Y}")
124 ; (THORN . "")
125 (szlig . "\\ss ")
126 (agrave . "\\`{a}")
127 (aacute . "\\'{a}")
128 (acirc . "\\^{a}")
129 (atilde . "\\~{a}")
130 (auml . "\\\"{a}")
131 (aring . "\\aa ")
132 (aelig . "\\ae ")
133 (ccedil . "\\c{c}")
134 (egrave . "\\`{e}")
135 (eacute . "\\'{e}")
136 (ecirc . "\\^{e}")
137 (euml . "\\\"{e}")
138 (igrave . "\\`{i}")
139 (iacute . "\\'{i}")
140 (icirc . "\\^{i}")
141 (iuml . "\\\"{i}")
142 ; (eth . "")
143 (ntilde . "\\~{n}")
144 (ograve . "\\`{o}")
145 (oacute . "\\'{o}")
146 (ocirc . "\\^{o}")
147 (otilde . "\\~{o}")
148 (ouml . "\\\"{o}")
149 (divide . "$\\div$")
150 (oslash . "\\o")
151 (ugrave . "\\`{u}")
152 (uacute . "\\'{u}")
153 (ucirc . "\\^{u}")
154 (uuml . "\\\"{u}")
155 (yacute . "\\'{y}")
156 ; (thorn . "")
157 (yuml . "\\\"{y}"))
158 "Defines mappings between `w3-html-entities' and LaTeX characters.")
159
160 (defun w3-latex-replace-entities (str)
161 (let ((start 0))
162 (while (string-match "[\200-\377]" str start)
163 ; get the character code, and then search for a match in
164 ; w3-html-entities. If one is found, use it to perform a lookup
165 ; in w3-latex-entities, and use the resulting match to replace
166 ; the character.
167 (let* ((match (rassq (aref str (match-beginning 0))
168 w3-html-entities))
169 (replace (and match
170 (assq (car match) w3-latex-entities))))
171 (if replace
172 (setq str (replace-match (cdr replace) t t str)))
173 (setq start (match-end 0))))
174 str))
175
176 (defun w3-latex-insert-string (str)
177 ;;; convert string to a LaTeX-compatible one.
178 (let ((todo (list (cons "\\\\" "\\BaCkSlAsH")
179 (cons "[%&#_{}$]" "\\\\\\&")
180 (cons "[~^]" "\\\\\\&{ }")
181 (cons "[*]" "{\\&}")
182 (cons "[><|]" "$\\&$")
183 (cons "\\\\BaCkSlAsH" "$\\backslash$")
184 (cons "\n" (if w3-latex-verbatim
185 "\\\\newline\n"
186 " ")))))
187 (if w3-latex-verbatim
188 (setq todo (append todo '((" " . "\\\\ ")))))
189 (save-excursion
190 (set-buffer (get-buffer-create " *w3-latex-munging*"))
191 (erase-buffer)
192 (insert str)
193 (while todo
194 (goto-char (point-min))
195 (while (re-search-forward (caar todo) nil t)
196 (replace-match (cdar todo)))
197 (setq todo (cdr todo)))
198 (setq str (w3-latex-replace-entities (buffer-string))))
199 (insert str)))
200
201 (defun w3-latex-contents (tree)
202 ;;; passes contents of subtree through to the latex-subtree
203 (let ((contents (car (cdr (cdr tree)))))
204 (while contents
205 (w3-latex-subtree (car contents))
206 (setq contents (cdr contents)))))
207
208 (defun w3-latex-html (tree)
209 (insert "% This document automatically generated by Emacs-W3 v"
210 w3-version-number "\n")
211 (if w3-latex-current-url
212 (insert "% from <URL:" w3-latex-current-url ">\n"))
213 (insert "%\n"
214 "\\begin{document}\n")
215 (w3-latex-contents tree)
216 (insert "\\end{document}\n"))
217
218 (defun w3-latex-title (tree)
219 (if w3-latex-use-maketitle
220 (insert "\\title{")
221 (insert "\\section*{\\centering "))
222 (w3-latex-contents tree)
223 (insert "}\n")
224 (if w3-latex-use-maketitle
225 (insert "\\author{}\\date{}\n\\maketitle")))
226
227 (defun w3-latex-heading (tree)
228 ;; look through the additional markup to see if an align=right or
229 ;; align=center is in here...
230 (let ((align (assq 'align (car (cdr tree))))
231 (sym (car tree)))
232 (insert "\n\n")
233 (cond ((and align (string-equal (cdr align) "center"))
234 (insert "\\begin{center}\n"))
235 ((and align (string-equal (cdr align) "right"))
236 (insert "\\begin{flushright}\n")))
237 (cond ((eq sym 'h1) (insert "\\section*{"))
238 ((eq sym 'h2) (insert "\\subsection*{"))
239 ((eq sym 'h3) (insert "\\subsubsection*{"))
240 ((eq sym 'h4) (insert "\\subsubsection*{"))
241 ((eq sym 'h5) (insert "\\paragraph*{"))
242 ((eq sym 'h6) (insert "\\subparagraph*{")))
243 (w3-latex-contents tree)
244 (insert "}\n")
245 (cond ((and align (string-equal (cdr align) "center"))
246 (insert "\\end{center}\n"))
247 ((and align (string-equal (cdr align) "right"))
248 (insert "\\end{flushright}\n")))))
249
250 (defun w3-latex-bold (tree)
251 (insert "{\\bf ")
252 (w3-latex-contents tree)
253 (insert "}"))
254 (defun w3-latex-italic (tree)
255 (insert "{\\em ")
256 (w3-latex-contents tree)
257 (insert "}"))
258 (defun w3-latex-typewriter (tree)
259 (insert "{\\tt ")
260 (w3-latex-contents tree)
261 (insert "}"))
262
263 (defun w3-latex-list (tree)
264 (let* ((sym (car tree))
265 (list-type (cond ((eq sym 'ol) "enumerate")
266 ((eq sym 'dl) "description")
267 (t "itemize"))))
268 (insert (concat "\n\\begin{" list-type "}\n"))
269 (w3-latex-contents tree)
270 (insert (concat "\n\\end{" list-type "}\n"))))
271
272 (defun w3-latex-list-item (tree)
273 (let ((sym (car tree)))
274 (cond ((eq sym 'dt)
275 (insert "\n\\item["))
276 ((eq sym 'dd)
277 ;; don't do anything for dd -- the item is handled by dt.
278 nil)
279 (t (insert "\n\\item")))
280 (w3-latex-contents tree)
281 (if (eq sym 'dt)
282 (insert "]"))))
283
284 (defun w3-latex-center (tree)
285 (insert "\\begin{center}")
286 (w3-latex-contents tree)
287 (insert "\\end{center}"))
288
289 (defun w3-latex-rule (tree)
290 ; use \par to make paragraph division clear.
291 (insert "\n\\par\\noindent\\rule{\\textwidth}{.01in}\n"))
292
293 (defun w3-latex-para (tree)
294 ;; look through the additional markup to see if an align=right or
295 ;; align=center is in here...
296 (let ((align (assq 'align (car (cdr tree)))))
297 (cond ((and align
298 (string-equal (cdr align) "center"))
299 (w3-latex-center tree))
300 ((and align
301 (string-equal (cdr align) "right"))
302 (insert "\\begin{flushright}")
303 (w3-latex-contents tree)
304 (insert "\\end{flushright}"))
305 (t (insert "\\par ")
306 (w3-latex-contents tree)))))
307
308 (defun w3-latex-quote (tree)
309 (insert "\\begin{quote}\n")
310 (w3-latex-contents tree)
311 (insert "\\end{quote}\n"))
312
313 (defun w3-latex-break (tree)
314 ;; no content allowed
315 (insert "\\linebreak"))
316
317 (defun w3-latex-href (tree)
318 (let ((href (cdr-safe (assq 'href (cadr tree)))))
319 (cond
320 ((not w3-latex-print-links) ; No special treatment
321 (w3-latex-contents tree))
322 (href ; Special treatment requested
323 (insert "\\underline{") ; and we have a URL - underline
324 (w3-latex-contents tree) ; it and prepare a footnote.
325 (insert "}\\footnote{" href "}"))
326 (t ; Special treatment requested, but
327 (w3-latex-contents tree))))) ; no URL - do nothing.
328
329 (defun w3-latex-preformatted (tree)
330 (let ((w3-latex-verbatim t))
331 (insert "\\tt{")
332 (w3-latex-contents tree)
333 (insert "}")
334 ))
335
336 (defun w3-latex-xmp (tree)
337 (insert "\\begin{verbatim}")
338 (w3-latex-contents tree)
339 (insert "\\end{verbatim}"))
340
341 (let ((todo '((title . w3-latex-title)
342 (html . w3-latex-html)
343 (pre . w3-latex-preformatted)
344 (xmp . w3-latex-xmp)
345 (h1 . w3-latex-heading)
346 (h2 . w3-latex-heading)
347 (h3 . w3-latex-heading)
348 (h4 . w3-latex-heading)
349 (h5 . w3-latex-heading)
350 (h6 . w3-latex-heading)
351 (a . w3-latex-href)
352 (strong . w3-latex-bold)
353 (b . w3-latex-bold)
354 (dfn . w3-latex-bold)
355 (em . w3-latex-italic)
356 (i . w3-latex-italic)
357 (address . w3-latex-italic)
358 (code . w3-latex-typewriter)
359 (samp . w3-latex-typewriter)
360 (tt . w3-latex-typewriter)
361 (kbd . w3-latex-typewriter)
362 (var . w3-latex-typewriter)
363 (ol . w3-latex-list)
364 (dl . w3-latex-list)
365 (ul . w3-latex-list)
366 (menu . w3-latex-list)
367 (dir . w3-latex-list)
368 (li . w3-latex-list-item)
369 (dt . w3-latex-list-item)
370 (dd . w3-latex-list-item)
371 (center . w3-latex-center)
372 (hr . w3-latex-rule)
373 (p . w3-latex-para)
374 (br . w3-latex-break)
375 (blockquote . w3-latex-quote))))
376 (while todo
377 (put (caar todo) 'w3-latex-formatter (cdar todo))
378 (setq todo (cdr todo))))
379
380 (defun w3-latex-subtree (tree)
381 (cond
382 ((stringp tree)
383 (w3-latex-insert-string tree))
384 ((stringp (car-safe tree))
385 (while tree
386 (w3-latex-insert-string (car tree))
387 (setq tree (cdr tree))))
388 ((symbolp (car tree))
389 (let ((proc (get (car tree) 'w3-latex-formatter)))
390 (if (and proc (fboundp proc))
391 (funcall proc tree)
392 ;; anything else gets passed through unchanged
393 (w3-latex-contents tree))))
394 (t
395 (w3-latex-contents tree))))
396
397 (defun w3-parse-tree-to-latex (tree &optional url)
398 ; assumes that url-working-buffer exists.
399 (set-buffer (get-buffer-create url-working-buffer))
400 (setq w3-latex-current-url url)
401 (erase-buffer)
402 (goto-char (point-min))
403 (if w3-latex-use-latex2e
404 (insert (concat "\\documentclass" w3-latex-docstyle "\n"))
405 (insert (concat "\\documentstyle" w3-latex-docstyle "\n")))
406 (if (and w3-latex-use-latex2e
407 w3-latex-packages)
408 (insert (apply 'concat
409 (mapcar (lambda (x) (concat "\\usepackage{" x "}\n"))
410 w3-latex-packages))))
411 (while tree
412 (w3-latex-subtree (car tree))
413 (setq tree (cdr tree))))
414
415 (defun w3-show-dvi ()
416 "Uses xdvi to show DVI file created from `w3-parse-tree-to-latex'."
417 (interactive)
418 (w3-parse-tree-to-latex w3-current-parse)
419 (save-window-excursion
420 (set-buffer url-working-buffer)
421 (write-region (point-min) (point-max)
422 (expand-file-name "w3-tmp.latex"
423 w3-temporary-directory) nil 5)
424 (shell-command
425 (format
426 "(cd %s ; latex w3-tmp.latex ; xdvi w3-tmp.dvi ; rm -f w3-tmp*) &"
427 w3-temporary-directory))))
428
429 (provide 'w3-latex)