Mercurial > hg > xemacs-beta
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/w3/w3-latex.el Mon Aug 13 08:45:50 2007 +0200 @@ -0,0 +1,429 @@ +;;; w3-latex.el,v --- Emacs-W3 printing via LaTeX +;; Author: wmperry +;; Created: 1996/06/06 15:00:18 +;; Version: 1.4 +;; Keywords: hypermedia, printing, typesetting + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Copyright (c) 1996 by Stephen Peters <speters%samsun@us.oracle.com> +;;; +;;; This file is not part of GNU Emacs, but the same permissions apply. +;;; +;;; GNU Emacs is free software; you can redistribute it and/or modify +;;; it under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 2, or (at your option) +;;; any later version. +;;; +;;; GNU Emacs is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Emacs; see the file COPYING. If not, write to +;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Elisp code to convert a W3 parse tree into a LaTeX buffer. +;;; +;;; Heavily hacked upon by William Perry <wmperry@spry.com> to add more +;;; bells and whistles. +;;; +;;; KNOWN BUGS: +;;; 1) This does not use stylesheets to get the formatting information +;;; 2) This means that the new drawing routines need to be abstracted +;;; further so that the same main engine can be used for either +;;; text-output (standard stuff in w3-draw), LaTeX output (this file), +;;; Postscript (to-be-implemented), etc., etc. +;;; 3) This still doesn't handle tables. +;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(require 'w3-print) + +(defvar w3-latex-print-links nil + "*If non-nil, prints the URLs of hypertext links as footnotes on a page.") + +(defvar w3-latex-use-latex2e nil + "*If non-nil, configures LaTeX parser to use LaTeX2e syntax. A `nil' +value indicates that LaTeX 2.0.9 compatibility will be used instead.") + +(defvar w3-latex-packages nil + "*List of LaTeX packages to include. Currently this is only used if +`w3-latex-use-latex2e' is non-nil.") + +(defvar w3-latex-use-maketitle nil + "*Non-nil makes the LaTeX parser use real LaTeX title pages for +document titles.") + +;; Internal variables - do not touch! +(defvar w3-latex-current-url nil "What URL we are formatting") +(defvar w3-latex-verbatim nil "Whether we are in a {verbatim} block or not") + +(defvar w3-latex-entities + '((nbsp . "~") + (iexcl . "!`") +; (cent . "") + (pound . "\\pounds ") +; (curren . "") +; (yen . "") + (brvbar . "|") + (sect . "\\S") + (uml . "\\\"{ }") + (copy . "\\copyright ") +; (ordf . "") + (laquo . "$\\ll$") + (not . "\\neg") + (shy . "-") + (reg . "(R)") + (macr . "\\={ }") + (deg . "$\\deg$") + (plusmn . "$\\pm$") + (sup2 . "$^{2}$") + (sup3 . "$^{3}$") + (acute . "\\'{ }") + (micro . "$\\mu$") + (para . "\\P ") + (middot . "$\\cdot$") + (cedil . "\\c{ }") + (sup1 . "$^{1}") +; (ordm . "") + (raquo . "$\\gg$") + (frac14 . "$\frac{1}{4}$") + (frac12 . "$\frac{1}{2}$") + (frac34 . "$\frac{3}{4}$") + (iquest . "?`") + (Agrave . "\\`{A}") + (Aacute . "\\'{A}") + (Acirc . "\\^{A}") + (Atilde . "\\~{A}") + (Auml . "\\\"{A}") + (Aring . "\\AA ") + (AElig . "\\AE ") + (Ccedil . "\\c{C}") + (Egrave . "\\`{E}") + (Eacute . "\\'{E}") + (Ecirc . "\\^{E}") + (Euml . "\\\"{E}") + (Igrave . "\\`{I}") + (Iacute . "\\'{I}") + (Icirc . "\\^{I}") + (Iuml . "\\\"{I}") +; (ETH . "") + (Ntilde . "\\~{N}") + (Ograve . "\\`{O}") + (Oacute . "\\'{O}") + (Ocirc . "\\^{O}") + (Otilde . "\\~{O}") + (Ouml . "\\\"{O}") + (times . "$\\times$") + (Oslash . "\\O") + (Ugrave . "\\`{U}") + (Uacute . "\\'{U}") + (Ucirc . "\\^{U}") + (Uuml . "\\\"{U}") + (Yacute . "\\'{Y}") +; (THORN . "") + (szlig . "\\ss ") + (agrave . "\\`{a}") + (aacute . "\\'{a}") + (acirc . "\\^{a}") + (atilde . "\\~{a}") + (auml . "\\\"{a}") + (aring . "\\aa ") + (aelig . "\\ae ") + (ccedil . "\\c{c}") + (egrave . "\\`{e}") + (eacute . "\\'{e}") + (ecirc . "\\^{e}") + (euml . "\\\"{e}") + (igrave . "\\`{i}") + (iacute . "\\'{i}") + (icirc . "\\^{i}") + (iuml . "\\\"{i}") +; (eth . "") + (ntilde . "\\~{n}") + (ograve . "\\`{o}") + (oacute . "\\'{o}") + (ocirc . "\\^{o}") + (otilde . "\\~{o}") + (ouml . "\\\"{o}") + (divide . "$\\div$") + (oslash . "\\o") + (ugrave . "\\`{u}") + (uacute . "\\'{u}") + (ucirc . "\\^{u}") + (uuml . "\\\"{u}") + (yacute . "\\'{y}") +; (thorn . "") + (yuml . "\\\"{y}")) + "Defines mappings between `w3-html-entities' and LaTeX characters.") + +(defun w3-latex-replace-entities (str) + (let ((start 0)) + (while (string-match "[\200-\377]" str start) + ; get the character code, and then search for a match in + ; w3-html-entities. If one is found, use it to perform a lookup + ; in w3-latex-entities, and use the resulting match to replace + ; the character. + (let* ((match (rassq (aref str (match-beginning 0)) + w3-html-entities)) + (replace (and match + (assq (car match) w3-latex-entities)))) + (if replace + (setq str (replace-match (cdr replace) t t str))) + (setq start (match-end 0)))) + str)) + +(defun w3-latex-insert-string (str) + ;;; convert string to a LaTeX-compatible one. + (let ((todo (list (cons "\\\\" "\\BaCkSlAsH") + (cons "[%&#_{}$]" "\\\\\\&") + (cons "[~^]" "\\\\\\&{ }") + (cons "[*]" "{\\&}") + (cons "[><|]" "$\\&$") + (cons "\\\\BaCkSlAsH" "$\\backslash$") + (cons "\n" (if w3-latex-verbatim + "\\\\newline\n" + " "))))) + (if w3-latex-verbatim + (setq todo (append todo '((" " . "\\\\ "))))) + (save-excursion + (set-buffer (get-buffer-create " *w3-latex-munging*")) + (erase-buffer) + (insert str) + (while todo + (goto-char (point-min)) + (while (re-search-forward (caar todo) nil t) + (replace-match (cdar todo))) + (setq todo (cdr todo))) + (setq str (w3-latex-replace-entities (buffer-string)))) + (insert str))) + +(defun w3-latex-contents (tree) + ;;; passes contents of subtree through to the latex-subtree + (let ((contents (car (cdr (cdr tree))))) + (while contents + (w3-latex-subtree (car contents)) + (setq contents (cdr contents))))) + +(defun w3-latex-html (tree) + (insert "% This document automatically generated by Emacs-W3 v" + w3-version-number "\n") + (if w3-latex-current-url + (insert "% from <URL:" w3-latex-current-url ">\n")) + (insert "%\n" + "\\begin{document}\n") + (w3-latex-contents tree) + (insert "\\end{document}\n")) + +(defun w3-latex-title (tree) + (if w3-latex-use-maketitle + (insert "\\title{") + (insert "\\section*{\\centering ")) + (w3-latex-contents tree) + (insert "}\n") + (if w3-latex-use-maketitle + (insert "\\author{}\\date{}\n\\maketitle"))) + +(defun w3-latex-heading (tree) + ;; look through the additional markup to see if an align=right or + ;; align=center is in here... + (let ((align (assq 'align (car (cdr tree)))) + (sym (car tree))) + (insert "\n\n") + (cond ((and align (string-equal (cdr align) "center")) + (insert "\\begin{center}\n")) + ((and align (string-equal (cdr align) "right")) + (insert "\\begin{flushright}\n"))) + (cond ((eq sym 'h1) (insert "\\section*{")) + ((eq sym 'h2) (insert "\\subsection*{")) + ((eq sym 'h3) (insert "\\subsubsection*{")) + ((eq sym 'h4) (insert "\\subsubsection*{")) + ((eq sym 'h5) (insert "\\paragraph*{")) + ((eq sym 'h6) (insert "\\subparagraph*{"))) + (w3-latex-contents tree) + (insert "}\n") + (cond ((and align (string-equal (cdr align) "center")) + (insert "\\end{center}\n")) + ((and align (string-equal (cdr align) "right")) + (insert "\\end{flushright}\n"))))) + +(defun w3-latex-bold (tree) + (insert "{\\bf ") + (w3-latex-contents tree) + (insert "}")) +(defun w3-latex-italic (tree) + (insert "{\\em ") + (w3-latex-contents tree) + (insert "}")) +(defun w3-latex-typewriter (tree) + (insert "{\\tt ") + (w3-latex-contents tree) + (insert "}")) + +(defun w3-latex-list (tree) + (let* ((sym (car tree)) + (list-type (cond ((eq sym 'ol) "enumerate") + ((eq sym 'dl) "description") + (t "itemize")))) + (insert (concat "\n\\begin{" list-type "}\n")) + (w3-latex-contents tree) + (insert (concat "\n\\end{" list-type "}\n")))) + +(defun w3-latex-list-item (tree) + (let ((sym (car tree))) + (cond ((eq sym 'dt) + (insert "\n\\item[")) + ((eq sym 'dd) + ;; don't do anything for dd -- the item is handled by dt. + nil) + (t (insert "\n\\item"))) + (w3-latex-contents tree) + (if (eq sym 'dt) + (insert "]")))) + +(defun w3-latex-center (tree) + (insert "\\begin{center}") + (w3-latex-contents tree) + (insert "\\end{center}")) + +(defun w3-latex-rule (tree) + ; use \par to make paragraph division clear. + (insert "\n\\par\\noindent\\rule{\\textwidth}{.01in}\n")) + +(defun w3-latex-para (tree) + ;; look through the additional markup to see if an align=right or + ;; align=center is in here... + (let ((align (assq 'align (car (cdr tree))))) + (cond ((and align + (string-equal (cdr align) "center")) + (w3-latex-center tree)) + ((and align + (string-equal (cdr align) "right")) + (insert "\\begin{flushright}") + (w3-latex-contents tree) + (insert "\\end{flushright}")) + (t (insert "\\par ") + (w3-latex-contents tree))))) + +(defun w3-latex-quote (tree) + (insert "\\begin{quote}\n") + (w3-latex-contents tree) + (insert "\\end{quote}\n")) + +(defun w3-latex-break (tree) + ;; no content allowed + (insert "\\linebreak")) + +(defun w3-latex-href (tree) + (let ((href (cdr-safe (assq 'href (cadr tree))))) + (cond + ((not w3-latex-print-links) ; No special treatment + (w3-latex-contents tree)) + (href ; Special treatment requested + (insert "\\underline{") ; and we have a URL - underline + (w3-latex-contents tree) ; it and prepare a footnote. + (insert "}\\footnote{" href "}")) + (t ; Special treatment requested, but + (w3-latex-contents tree))))) ; no URL - do nothing. + +(defun w3-latex-preformatted (tree) + (let ((w3-latex-verbatim t)) + (insert "\\tt{") + (w3-latex-contents tree) + (insert "}") + )) + +(defun w3-latex-xmp (tree) + (insert "\\begin{verbatim}") + (w3-latex-contents tree) + (insert "\\end{verbatim}")) + +(let ((todo '((title . w3-latex-title) + (html . w3-latex-html) + (pre . w3-latex-preformatted) + (xmp . w3-latex-xmp) + (h1 . w3-latex-heading) + (h2 . w3-latex-heading) + (h3 . w3-latex-heading) + (h4 . w3-latex-heading) + (h5 . w3-latex-heading) + (h6 . w3-latex-heading) + (a . w3-latex-href) + (strong . w3-latex-bold) + (b . w3-latex-bold) + (dfn . w3-latex-bold) + (em . w3-latex-italic) + (i . w3-latex-italic) + (address . w3-latex-italic) + (code . w3-latex-typewriter) + (samp . w3-latex-typewriter) + (tt . w3-latex-typewriter) + (kbd . w3-latex-typewriter) + (var . w3-latex-typewriter) + (ol . w3-latex-list) + (dl . w3-latex-list) + (ul . w3-latex-list) + (menu . w3-latex-list) + (dir . w3-latex-list) + (li . w3-latex-list-item) + (dt . w3-latex-list-item) + (dd . w3-latex-list-item) + (center . w3-latex-center) + (hr . w3-latex-rule) + (p . w3-latex-para) + (br . w3-latex-break) + (blockquote . w3-latex-quote)))) + (while todo + (put (caar todo) 'w3-latex-formatter (cdar todo)) + (setq todo (cdr todo)))) + +(defun w3-latex-subtree (tree) + (cond + ((stringp tree) + (w3-latex-insert-string tree)) + ((stringp (car-safe tree)) + (while tree + (w3-latex-insert-string (car tree)) + (setq tree (cdr tree)))) + ((symbolp (car tree)) + (let ((proc (get (car tree) 'w3-latex-formatter))) + (if (and proc (fboundp proc)) + (funcall proc tree) + ;; anything else gets passed through unchanged + (w3-latex-contents tree)))) + (t + (w3-latex-contents tree)))) + +(defun w3-parse-tree-to-latex (tree &optional url) + ; assumes that url-working-buffer exists. + (set-buffer (get-buffer-create url-working-buffer)) + (setq w3-latex-current-url url) + (erase-buffer) + (goto-char (point-min)) + (if w3-latex-use-latex2e + (insert (concat "\\documentclass" w3-latex-docstyle "\n")) + (insert (concat "\\documentstyle" w3-latex-docstyle "\n"))) + (if (and w3-latex-use-latex2e + w3-latex-packages) + (insert (apply 'concat + (mapcar (lambda (x) (concat "\\usepackage{" x "}\n")) + w3-latex-packages)))) + (while tree + (w3-latex-subtree (car tree)) + (setq tree (cdr tree)))) + +(defun w3-show-dvi () + "Uses xdvi to show DVI file created from `w3-parse-tree-to-latex'." + (interactive) + (w3-parse-tree-to-latex w3-current-parse) + (save-window-excursion + (set-buffer url-working-buffer) + (write-region (point-min) (point-max) + (expand-file-name "w3-tmp.latex" + w3-temporary-directory) nil 5) + (shell-command + (format + "(cd %s ; latex w3-tmp.latex ; xdvi w3-tmp.dvi ; rm -f w3-tmp*) &" + w3-temporary-directory)))) + +(provide 'w3-latex)