1 ;;; texi2latex.el --- convert a texi file into a LaTeX file.
2 ;; Copyright (C) 1996, 2004 Lars Magne Ingebrigtsen
6 (defun latexi-discard-until (string)
7 (let ((beg (match-beginning 0)))
8 (unless (re-search-forward (concat "^@end +" string "[ \t]*\n") nil t)
9 (error "No end: %s" string))
10 (delete-region beg (match-end 0))))
12 (defun latexi-strip-line ()
13 (delete-region (progn (beginning-of-line) (point))
14 (progn (forward-line 1) (point))))
16 (defun latexi-switch-line (command arg)
18 (insert (format "\\%s{%s}\n" command arg)))
20 (defun latexi-index-command (command arg)
22 (insert (format "\\gnus%sindex{%s}\n"
23 (if (equal command "kindex") "k" "")
26 (defun latexi-begin-command (command)
28 (insert (format "\\begin{%s}\n" command)))
30 (defun latexi-exchange-command (command arg)
31 (delete-region (match-beginning 0) (match-end 0))
32 (insert (format "\\%s{%s}" command arg)))
34 (defun latexi-translate ()
37 (latexi-translate-file "gnus")
38 (latexi-translate-file "gnus-faq")
39 (latexi-translate-file "message" t)
40 (latexi-translate-file "emacs-mime" t)
41 (latexi-translate-file "sieve" t)
42 ;;(latexi-translate-file "pgg" t)
43 ;;(latexi-translate-file "sasl" t)
46 (defun latexi-translate-file (file &optional as-a-chapter)
47 "Translate file a LaTeX file."
48 (let ((item-string "")
51 (latexi-buffer (get-buffer-create "*LaTeXi*"))
56 "\\(\\( +\\(.*$\\)\\|[ \t]*$\\)\\|{\\([^}]*\\)}\\)"))
57 (cur (find-file-noselect (concat (or (getenv "srcdir") ".")
62 (pop-to-buffer latexi-buffer)
65 (insert-buffer-substring cur)
66 (goto-char (point-min))
68 (latexi-translate-string "%@{" "\\gnuspercent{}\\gnusbraceleft{}")
69 (latexi-translate-string "%@}" "\\gnuspercent{}\\gnusbraceright{}")
70 (latexi-translate-string "%1@{" "\\gnuspercent{}1\\gnusbraceright{}")
71 (latexi-translate-string "@*" "\\newline{}")
72 (latexi-translate-string "S@{" "S\\gnusbraceleft{}")
73 (latexi-translate-string "@code{\\222}" "@code{\\gnusbackslash{}222}")
74 (latexi-translate-string "@code{\\264}" "@code{\\gnusbackslash{}264}")
75 (latexi-translate-string "@samp{\\Deleted}" "@samp{\\gnusbackslash{}Deleted}")
76 (latexi-translate-string "@samp{\\Seen}" "@samp{\\gnusbackslash{}Seen}")
77 (latexi-translate-string "@file{c:\\myhome}" "@file{c:\\gnusbackslash{}myhome}")
78 ; (while (re-search-forward "{\"[^\"]*\\(\\\\\\)[^\"]*\"}\\\\" nil t)
79 ; (replace-match "\\verb+\\\\+ " t t))
80 (while (not (zerop (decf times)))
81 (goto-char (point-min))
82 (while (re-search-forward regexp nil t)
83 (setq command (match-string 1))
84 (if (match-beginning 3)
86 (setq arg (or (match-string 4) ""))
88 (when (string-match "[ \t]+$" arg)
89 (setq arg (substring arg 0 (match-beginning 0)))))
91 ((member command '("c" "comment"))
92 (if (string-match "@icon" (or arg ""))
95 (delete-region (point) (+ (point) 4))
97 (delete-region (match-beginning 0)
98 (progn (end-of-line) (point))))
99 (if (equal arg "@head")
100 (insert "\\gnusinteresting")))
101 ((member command '("setfilename" "set"
102 "synindex" "setchapternewpage"
103 "summarycontents" "bye"
104 "top" "iftex" "cartouche"
105 "iflatex" "finalout" "vskip"
106 "dircategory" "group" "syncodeindex"))
108 ((member command '("menu" "tex" "ifinfo" "ignore"
109 "ifnottex" "direntry"))
110 (latexi-discard-until command))
111 ((member command '("subsection" "subsubsection"))
113 (latexi-switch-line (format "sub%s" command) arg)
114 (latexi-switch-line command arg)))
115 ((member command '("heading"))
117 (latexi-switch-line "subsection*" arg)
118 (latexi-switch-line "section*" arg)))
119 ((member command '("subheading"))
121 (latexi-switch-line "subsubsection*" arg)
122 (latexi-switch-line "subsection*" arg)))
123 ((member command '("subsubheading"))
125 (latexi-switch-line "subsubsubsection*" arg)
126 (latexi-switch-line "subsubsection*" arg)))
127 ((member command '("chapter"))
128 (if (string-match "Index" arg)
131 (latexi-switch-line "gnussection" arg)
135 (format "\\epsfig{figure=ps/new-herd-%d,scale=.5}"
136 (if (> (incf chapter) 9) 9 chapter)))
138 ((member command '("section"))
140 (latexi-switch-line "subsection" arg)
141 (latexi-switch-line (format "gnus%s" command) arg)))
142 ((member command '("cindex" "findex" "kindex" "vindex"))
143 (latexi-index-command command arg))
144 ((member command '("*"))
147 ((equal command "sp")
148 (replace-match "" t t))
150 (replace-match "" t t))
151 ((member command '("deffn" "defvar" "defun"))
152 (replace-match "" t t))
153 ((equal command "node")
155 (unless (string-match "Index" arg)
156 (insert (format "\\label{%s}\n" arg))))
157 ((equal command "contents")
159 ;;(insert (format "\\tableofcontents\n" arg))
161 ((member command '("titlepage"))
162 (latexi-begin-command command))
163 ((member command '("lisp" "example" "smallexample" "display"))
165 (insert (format "\\begin{verbatim}\n"))
166 (setq verbatim (point)))
167 ((member command '("center"))
169 (insert (format "\\begin{%s}%s\\end{%s}\n"
170 command arg command)))
171 ((member command '("end"))
173 ((member arg '("titlepage"))
175 (insert (format "\\end{%s}\n" arg)))
176 ((equal arg "quotation")
178 (insert (format "\\end{verse}\n")))
179 ((member arg '("lisp" "example" "smallexample" "display"))
183 (narrow-to-region verbatim (point))
184 (goto-char (point-min))
185 (while (search-forward "@{" nil t)
186 (replace-match "{" t t))
187 (goto-char (point-min))
188 (while (search-forward "@}" nil t)
189 (replace-match "}" t t))))
191 (insert "\\end{verbatim}\n"))
192 ((member arg '("table"))
193 (setq item-string (pop item-stack))
195 (insert (format "\\end{%slist}\n" (pop list-stack))))
196 ((member arg '("itemize" "enumerate"))
197 (setq item-string (pop item-stack))
199 (insert (format "\\end{%s}\n" arg)))
200 ((member arg '("iflatex" "iftex" "cartouche" "group"))
202 ((member arg '("deffn" "defvar" "defun"))
205 (error "Unknown end arg: %s" arg))))
206 ((member command '("table"))
207 (push item-string item-stack)
208 (push (substring arg 1) list-stack)
210 (format "[@%s{%%s}]" (car list-stack)))
212 (insert (format "\\begin{%slist}\n" (car list-stack))))
213 ((member command '("itemize" "enumerate"))
214 (push item-string item-stack)
216 ((member arg '("@bullet"))
217 (setq item-string "[\\gnusbullet]"))
219 (setq item-string "")))
221 (insert (format "\\begin{%s}\n" command)))
222 ((member command '("item"))
224 (insert (format "\\%s%s\n" command (format item-string arg))))
225 ((equal command "itemx")
227 (insert (format "\\gnusitemx{%s}\n" (format item-string arg))))
228 ((eq (aref command 0) ?@)
229 (goto-char (match-beginning 0))
232 ((equal command "settitle")
234 (if (not as-a-chapter)
236 (format "\\newcommand{\\gnustitlename}{%s}\n" arg))))
237 ((equal command "title")
239 (insert (format "\\gnustitlename{%s}\n" arg)))
240 ((equal command "author")
242 (insert (format "\\gnusauthor{%s}\n" arg)))
243 ((equal command "quotation")
244 (latexi-begin-command "verse"))
245 ((equal command "page")
247 (insert (format "\\newpage\n" arg)))
248 ((equal command "'s")
249 (goto-char (match-beginning 0))
251 ((equal command "include")
253 (string-match "\\.texi" arg)
254 (insert (format "\\input{%s.latexi}\n"
255 (substring arg 0 (match-beginning 0)))))
256 ((equal command "noindent")
258 (insert "\\noindent\n"))
259 ((equal command "printindex")
263 ;; "\\begin{theindex}\\input{gnus.%s}\\end{theindex}\n" arg))
266 (error "Unknown command (file %s line %d): %s"
270 (1+ (count-lines (point-min) (progn
274 ;; These are commands with {}.
275 (setq arg (match-string 5))
277 ((member command '("anchor"))
279 ((member command '("ref" "xref" "pxref"))
280 (latexi-exchange-command (concat "gnus" command) arg))
281 ((member command '("sc" "file" "dfn" "emph" "kbd" "key" "uref"
282 "code" "samp" "var" "strong" "i"
283 "result" "email" "env" "r" "command" "asis"
285 (goto-char (match-beginning 0))
288 ((member command '("acronym"))
289 (latexi-exchange-command (concat "gnus" command) (downcase arg)))
290 ((member command '("copyright" "footnote" "TeX"))
291 (goto-char (match-beginning 0))
294 ((member command '("dots"))
295 (goto-char (match-beginning 0))
296 (delete-region (match-beginning 0) (match-end 0))
298 ((eq (aref command 0) ?@)
299 (goto-char (match-beginning 0))
303 (error "Unknown command (file %s line %d): %s"
307 (1+ (count-lines (point-min) (progn
311 (latexi-translate-string "$" "\\gnusdollar{}")
312 (latexi-translate-string "&" "\\gnusampersand{}")
313 (latexi-translate-string "%" "\\gnuspercent{}")
314 (latexi-translate-string "#" "\\gnushash{}")
315 (latexi-translate-string "^" "\\gnushat{}")
316 (latexi-translate-string "~" "\\gnustilde{}")
317 (latexi-translate-string "_" "\\gnusunderline{}")
318 (latexi-translate-string "¬" "\\gnusnot{}")
319 (goto-char (point-min))
320 (while (search-forward "duppat{}" nil t)
321 (replace-match "@" t t))
322 (latexi-translate-string "@@" "@")
323 (latexi-translate-string "<" "\\gnusless{}")
324 (latexi-translate-string ">" "\\gnusgreater{}")
325 (goto-char (point-min))
326 (search-forward "label{Top}" nil t)
327 (while (re-search-forward "\\\\[ntr]\\b" nil t)
328 (when (save-match-data
329 (or (not (save-excursion
330 (search-backward "begin{verbatim}" nil t)))
332 (search-backward "end{verbatim"))
334 (search-backward "begin{verbatim}")))))
335 (goto-char (match-beginning 0))
337 (insert "\\gnusbackslash{}")))
338 (latexi-translate-string "\\\\" "\\gnusbackslash{}")
339 (goto-char (point-min))
340 (while (re-search-forward "\\\\[][{}]" nil t)
341 (goto-char (match-beginning 0))
343 (latexi-contributors)
344 (let ((coding-system-for-write 'iso-8859-1))
345 (write-region (point-min) (point-max) (concat file ".latexi")))))
347 (defun latexi-translate-string (in out)
349 (goto-char (point-min))
350 (search-forward "label{Top}" nil t)
351 (while (search-forward in nil t)
352 (when (save-match-data
353 (or (not (save-excursion
354 (search-backward "begin{verbatim}" nil t)))
356 (re-search-backward "end{verbatim}\\|end{verse}"))
359 "begin{verbatim}\\|begin{verse}")))))
360 (replace-match out t t)))))
362 (defun latexi-contributors ()
363 (goto-char (point-min))
364 (when (re-search-forward "^Also thanks to the following" nil t)
368 (1- (search-forward "\n\n")))
369 (when (re-search-backward "^and" nil t)
371 (goto-char (point-min))
372 (while (re-search-forward "[.,] *$" nil t)
373 (replace-match "" t t))
374 (goto-char (point-min))
377 (push (buffer-substring (point) (progn (end-of-line) (point)))
380 (delete-region (point-min) (point-max))
381 (insert "\\begin{tabular}{lll}\n")
382 (setq names (nreverse (delete "" names)))
384 (insert (pop names) " & " (or (pop names) "\\mbox{}")
385 " & " (or (pop names) "\\mbox{}")
387 (insert "\\end{tabular}\n")