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