;;; texi2latex.el --- convert a texi file into a LaTeX file. ;; Copyright (C) 1996 Lars Magne Ingebrigtsen (require 'cl) (defun latexi-discard-until (string) (let ((beg (match-beginning 0))) (unless (re-search-forward (concat "^@end +" string "[ \t]*\n") nil t) (error "No end: %s" string)) (delete-region beg (match-end 0)))) (defun latexi-strip-line () (delete-region (progn (beginning-of-line) (point)) (progn (forward-line 1) (point)))) (defun latexi-switch-line (command arg) (latexi-strip-line) (insert (format "\\%s{%s}\n" command arg))) (defun latexi-index-command (command arg) (latexi-strip-line) (insert (format "\\gnus%sindex{%s}\n" (if (equal command "kindex") "k" "") arg))) (defun latexi-begin-command (command) (latexi-strip-line) (insert (format "\\begin{%s}\n" command))) (defun latexi-exchange-command (command arg) (delete-region (match-beginning 0) (match-end 0)) (insert (format "\\%s{%s}" command arg))) (defun latexi-translate () "Translate." (interactive) (latexi-translate-file "gnus") (latexi-translate-file "gnus-faq")) (defun latexi-translate-file (file) "Translate file a LaTeX file." (let ((item-string "") (item-stack nil) (list-stack nil) (latexi-buffer (get-buffer-create "*LaTeXi*")) verbatim (regexp (concat "@\\([^{} \t\n]+\\)" "\\(\\( +\\(.*$\\)\\|[ \t]*$\\)\\|{\\([^}]*\\)}\\)")) (cur (find-file-noselect (concat file ".texi"))) (times 3) (chapter 0) command arg) (pop-to-buffer latexi-buffer) (buffer-disable-undo) (erase-buffer) (insert-buffer-substring cur) (goto-char (point-min)) (latexi-strip-line) (latexi-translate-string "%@{" "\\gnuspercent{}\\gnusbraceleft{}") (latexi-translate-string "%@}" "\\gnuspercent{}\\gnusbraceright{}") (latexi-translate-string "%1@{" "\\gnuspercent{}1\\gnusbraceright{}") ; (while (re-search-forward "{\"[^\"]*\\(\\\\\\)[^\"]*\"}\\\\" nil t) ; (replace-match "\\verb+\\\\+ " t t)) (while (not (zerop (decf times))) (goto-char (point-min)) (while (re-search-forward regexp nil t) (setq command (match-string 1)) (if (match-beginning 3) (progn (setq arg (or (match-string 4) "")) (save-match-data (when (string-match "[ \t]+$" arg) (setq arg (substring arg 0 (match-beginning 0))))) (cond ((member command '("c" "comment")) (if (string-match "@icon" (or arg "")) (progn (beginning-of-line) (delete-region (point) (+ (point) 4)) (insert "\\gnus")) (delete-region (match-beginning 0) (progn (end-of-line) (point)))) (if (equal arg "@head") (insert "\\gnusinteresting"))) ((member command '("setfilename" "synindex" "setchapternewpage" "summarycontents" "bye" "top" "iftex" "cartouche" "iflatex" "finalout" "vskip")) (latexi-strip-line)) ((member command '("menu" "tex" "ifinfo" "ignore")) (latexi-discard-until command)) ((member command '("subsection" "subsubsection")) (latexi-switch-line command arg)) ((member command '("chapter")) (latexi-switch-line (format "gnus%s{\\epsfig{figure=tmp/new-herd-%d.ps,scale=.5}}" command (incf chapter)) arg)) ((member command '("section")) (latexi-switch-line (format "gnus%s" command) arg)) ((member command '("cindex" "findex" "kindex" "vindex")) (latexi-index-command command arg)) ((member command '("*")) (delete-char -2) (insert "\\\\")) ((equal command "sp") (replace-match "" t t)) ((equal command "node") (latexi-strip-line) (insert (format "\\label{%s}\n" arg))) ((equal command "contents") (latexi-strip-line) ;;(insert (format "\\tableofcontents\n" arg)) ) ((member command '("titlepage")) (latexi-begin-command command)) ((member command '("lisp" "example")) (latexi-strip-line) (insert (format "\\begin{verbatim}\n")) (setq verbatim (point))) ((member command '("center")) (latexi-strip-line) (insert (format "\\begin{%s}%s\\end{%s}\n" command arg command))) ((member command '("end")) (cond ((member arg '("titlepage")) (latexi-strip-line) (insert (format "\\end{%s}\n" arg))) ((equal arg "quotation") (latexi-strip-line) (insert (format "\\end{verse}\n"))) ((member arg '("lisp" "example")) (latexi-strip-line) (save-excursion (save-restriction (narrow-to-region verbatim (point)) (goto-char (point-min)) (while (search-forward "@{" nil t) (replace-match "{" t t)) (goto-char (point-min)) (while (search-forward "@}" nil t) (replace-match "}" t t)))) (setq verbatim nil) (insert "\\end{verbatim}\n")) ((member arg '("table")) (setq item-string (pop item-stack)) (latexi-strip-line) (insert (format "\\end{%slist}\n" (pop list-stack)))) ((member arg '("itemize" "enumerate")) (setq item-string (pop item-stack)) (latexi-strip-line) (insert (format "\\end{%s}\n" arg))) ((member arg '("iflatex" "iftex" "cartouche")) (latexi-strip-line)) (t (error "Unknown end arg: %s" arg)))) ((member command '("table")) (push item-string item-stack) (push (substring arg 1) list-stack) (setq item-string (format "[@%s{%%s}]" (car list-stack))) (latexi-strip-line) (insert (format "\\begin{%slist}\n" (car list-stack)))) ((member command '("itemize" "enumerate")) (push item-string item-stack) (cond ((member arg '("@bullet")) (setq item-string "[\\gnusbullet]")) (t (setq item-string ""))) (latexi-strip-line) (insert (format "\\begin{%s}\n" command))) ((member command '("item")) (latexi-strip-line) (insert (format "\\%s%s\n" command (format item-string arg)))) ((equal command "itemx") (latexi-strip-line) (insert (format "\\gnusitemx{%s}\n" (format item-string arg)))) ((eq (aref command 0) ?@) (goto-char (match-beginning 0)) (delete-char 2) (insert "duppat{}")) ((equal command "settitle") (latexi-strip-line) (insert (format "\\newcommand{\\gnustitlename}{%s}\n" arg))) ((equal command "title") (latexi-strip-line) (insert (format "\\gnustitlename{%s}\n" arg))) ((equal command "author") (latexi-strip-line) (insert (format "\\gnusauthor{%s}\n" arg))) ((equal command "quotation") (latexi-begin-command "verse")) ((equal command "page") (latexi-strip-line) (insert (format "\\newpage\n" arg))) ((equal command "'s") (goto-char (match-beginning 0)) (delete-char 1)) ((equal command "include") (latexi-strip-line) (insert "\\input{gnus-faq.latexi}\n")) ((equal command "printindex") (latexi-strip-line) ;;(insert ;; (format ;; "\\begin{theindex}\\input{gnus.%s}\\end{theindex}\n" arg)) ) (t (error "Unknown command: %s" command)))) ;; These are commands with {}. (setq arg (match-string 5)) (cond ((member command '("xref" "pxref")) (latexi-exchange-command (concat "gnus" command) arg)) ((member command '("sc" "file" "dfn" "emph" "kbd" "code" "samp" "var" "strong" "i")) (goto-char (match-beginning 0)) (delete-char 1) (insert "\\gnus")) ((member command '("copyright")) (goto-char (match-beginning 0)) (delete-char 1) (insert "\\")) ((eq (aref command 0) ?@) (goto-char (match-beginning 0)) (delete-char 2) (insert "duppat{}")) (t (error "Unknown command: %s" command)))))) (latexi-translate-string "$" "\\gnusdollar{}") (latexi-translate-string "&" "\\gnusampersand{}") (latexi-translate-string "%" "\\gnuspercent{}") (latexi-translate-string "#" "\\gnushash{}") (latexi-translate-string "^" "\\gnushat{}") (latexi-translate-string "~" "\\gnustilde{}") (latexi-translate-string "_" "\\gnusunderline{}") (latexi-translate-string "¬" "\\gnusnot{}") (goto-char (point-min)) (while (search-forward "duppat{}" nil t) (replace-match "@" t t)) (latexi-translate-string "@@" "@") (latexi-translate-string "<" "\\gnusless{}") (latexi-translate-string ">" "\\gnusgreater{}") (goto-char (point-min)) (search-forward "label{Top}" nil t) (while (re-search-forward "\\\\[ntr]\\b" nil t) (when (save-match-data (or (not (save-excursion (search-backward "begin{verbatim}" nil t))) (> (save-excursion (search-backward "end{verbatim")) (save-excursion (search-backward "begin{verbatim}"))))) (goto-char (match-beginning 0)) (delete-char 1) (insert "\\gnusbackslash{}"))) (latexi-translate-string "\\\\" "\\gnusbackslash{}") (goto-char (point-min)) (while (re-search-forward "\\\\[][{}]" nil t) (goto-char (match-beginning 0)) (delete-char 1)) (latexi-contributors) (write-region (point-min) (point-max) (concat file ".latexi")))) (defun latexi-translate-string (in out) (let (yes) (goto-char (point-min)) (search-forward "label{Top}" nil t) (while (search-forward in nil t) (when (save-match-data (or (not (save-excursion (search-backward "begin{verbatim}" nil t))) (> (save-excursion (re-search-backward "end{verbatim}\\|end{verse}")) (save-excursion (re-search-backward "begin{verbatim}\\|begin{verse}"))))) (replace-match out t t))))) (defun latexi-contributors () (goto-char (point-min)) (when (re-search-forward "^Also thanks to the following" nil t) (forward-line 2) (narrow-to-region (point) (1- (search-forward "\n\n"))) (when (re-search-backward "^and" nil t) (latexi-strip-line)) (goto-char (point-min)) (while (re-search-forward "[.,] *$" nil t) (replace-match "" t t)) (goto-char (point-min)) (let (names) (while (not (eobp)) (push (buffer-substring (point) (progn (end-of-line) (point))) names) (forward-line 1)) (delete-region (point-min) (point-max)) (insert "\\begin{tabular}{lll}\n") (setq names (nreverse (delete "" names))) (while names (insert (pop names) " & " (or (pop names) "\\mbox{}") " & " (or (pop names) "\\mbox{}") "\\\\\n")) (insert "\\end{tabular}\n") (widen))))