Mercurial > hg > xemacs-beta
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) |