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