0
|
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)
|