* mml-sec.el (mml-secure-cust-record-keys):
[gnus.git] / texi / texi2latex.el
blob91ccda6e27c2b66f88032d3c922315a9e1787768
1 ;;; texi2latex.el --- convert a texi file into a LaTeX file.
2 ;; Copyright (C) 1996, 2004, 2008 Lars Magne Ingebrigtsen
4 (require 'cl)
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)
17 (latexi-strip-line)
18 (insert (format "\\%s{%s}\n" command arg)))
20 (defun latexi-index-command (command arg)
21 (latexi-strip-line)
22 (insert (format "\\gnus%sindex{%s}\n"
23 (if (equal command "kindex") "k" "")
24 arg)))
26 (defun latexi-begin-command (command)
27 (latexi-strip-line)
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 ()
35 "Translate."
36 (interactive)
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)
44 (latexi-translate-file "gnus-news" t))
46 (defun latexi-translate-file (file &optional as-a-chapter)
47 "Translate file a LaTeX file."
48 (let ((item-string "")
49 (item-stack nil)
50 (list-stack nil)
51 (latexi-buffer (get-buffer-create "*LaTeXi*"))
52 verbatim
53 (regexp
54 (concat
55 "@\\([^{} \t\n]+\\)"
56 "\\(\\( +\\(.*$\\)\\|[ \t]*$\\)\\|{\\([^}]*\\)}\\)"))
57 (cur (find-file-noselect (concat (or (getenv "srcdir") ".")
58 "/" file ".texi")))
59 (times 3)
60 (chapter 0)
61 command arg)
62 (pop-to-buffer latexi-buffer)
63 (buffer-disable-undo)
64 (erase-buffer)
65 (insert-buffer-substring cur)
66 (goto-char (point-min))
67 (when (search-forward "@copying" nil t)
68 (latexi-copying))
69 (while (search-forward "@insertcopying" nil t)
70 (delete-region (match-beginning 0) (match-end 0))
71 (latexi-insertcopying))
72 (goto-char (point-min))
73 (latexi-strip-line)
74 (latexi-translate-string "@'e" "\\'{e}")
75 (latexi-translate-string "@`a" "\\`{a}")
76 (latexi-translate-string "@,{c}" "\\c{c}")
77 (latexi-translate-string "@aa{}" "{\\aa}")
78 (latexi-translate-string "@\"{@dotless{i}}" "ï")
79 (latexi-translate-string "%@{" "\\gnuspercent{}\\gnusbraceleft{}")
80 (latexi-translate-string "%@}" "\\gnuspercent{}\\gnusbraceright{}")
81 (latexi-translate-string "%1@{" "\\gnuspercent{}1\\gnusbraceright{}")
82 (latexi-translate-string "@*" "\\newline{}")
83 (latexi-translate-string "S@{" "S\\gnusbraceleft{}")
84 (latexi-translate-string "@code{\\222}" "@code{\\gnusbackslash{}222}")
85 (latexi-translate-string "@code{\\264}" "@code{\\gnusbackslash{}264}")
86 (latexi-translate-string "@samp{\\Deleted}" "@samp{\\gnusbackslash{}Deleted}")
87 (latexi-translate-string "@samp{\\Seen}" "@samp{\\gnusbackslash{}Seen}")
88 (latexi-translate-string "@file{c:\\myhome}" "@file{c:\\gnusbackslash{}myhome}")
89 ; (while (re-search-forward "{\"[^\"]*\\(\\\\\\)[^\"]*\"}\\\\" nil t)
90 ; (replace-match "\\verb+\\\\+ " t t))
91 (while (not (zerop (decf times)))
92 (goto-char (point-min))
93 (while (re-search-forward regexp nil t)
94 (setq command (match-string 1))
95 (if (match-beginning 3)
96 (progn
97 (setq arg (or (match-string 4) ""))
98 (save-match-data
99 (when (string-match "[ \t]+$" arg)
100 (setq arg (substring arg 0 (match-beginning 0)))))
101 (cond
102 ((member command '("c" "comment"))
103 (if (string-match "@icon" (or arg ""))
104 (progn
105 (beginning-of-line)
106 (delete-region (point) (+ (point) 4))
107 (insert "\\gnus"))
108 (delete-region (match-beginning 0)
109 (progn (end-of-line) (point))))
110 (if (equal arg "@head")
111 (insert "\\gnusinteresting")))
112 ((member command '("setfilename" "set"
113 "synindex" "setchapternewpage"
114 "summarycontents" "bye"
115 "top" "iftex" "cartouche"
116 "iflatex" "finalout" "vskip"
117 "dircategory" "group" "syncodeindex"
118 "documentencoding"))
119 (latexi-strip-line))
120 ((member command '("menu" "tex" "ifinfo" "ignore"
121 "ifnottex" "direntry"))
122 (latexi-discard-until command))
123 ((member command '("subsection" "subsubsection"))
124 (if as-a-chapter
125 (latexi-switch-line (format "sub%s" command) arg)
126 (latexi-switch-line command arg)))
127 ((member command '("heading"))
128 (if as-a-chapter
129 (latexi-switch-line "subsection*" arg)
130 (latexi-switch-line "section*" arg)))
131 ((member command '("subheading"))
132 (if as-a-chapter
133 (latexi-switch-line "subsubsection*" arg)
134 (latexi-switch-line "subsection*" arg)))
135 ((member command '("subsubheading"))
136 (if as-a-chapter
137 (latexi-switch-line "subsubsubsection*" arg)
138 (latexi-switch-line "subsubsection*" arg)))
139 ((member command '("chapter"))
140 (if (string-match "Index" arg)
141 (latexi-strip-line)
142 (if as-a-chapter
143 (latexi-switch-line "gnussection" arg)
144 (latexi-switch-line
145 (format
146 "gnus%s{%s}" command
147 (format "\\epsfig{figure=ps/new-herd-%d,scale=.5}"
148 (if (> (incf chapter) 9) 9 chapter)))
149 arg))))
150 ((member command '("section"))
151 (if as-a-chapter
152 (latexi-switch-line "subsection" arg)
153 (latexi-switch-line (format "gnus%s" command) arg)))
154 ((member command '("cindex" "findex" "kindex" "vindex"))
155 (latexi-index-command command arg))
156 ((member command '("*"))
157 (delete-char -2)
158 (insert "\\\\"))
159 ((equal command "sp")
160 (replace-match "" t t))
161 ((equal command ":")
162 (replace-match "" t t))
163 ((member command '("deffn" "defvar" "defun"))
164 (replace-match "" t t))
165 ((equal command "node")
166 (latexi-strip-line)
167 (unless (string-match "Index" arg)
168 (insert (format "\\label{%s}\n" arg))))
169 ((equal command "contents")
170 (latexi-strip-line)
171 ;;(insert (format "\\tableofcontents\n" arg))
173 ((member command '("titlepage"))
174 (latexi-begin-command command))
175 ((member command '("lisp" "example" "smallexample" "display"))
176 (latexi-strip-line)
177 (insert (format "\\begin{verbatim}\n"))
178 (setq verbatim (point)))
179 ((member command '("center"))
180 (latexi-strip-line)
181 (insert (format "\\begin{%s}%s\\end{%s}\n"
182 command arg command)))
183 ((member command '("end"))
184 (cond
185 ((member arg '("titlepage"))
186 (latexi-strip-line)
187 (insert (format "\\end{%s}\n" arg)))
188 ((equal arg "quotation")
189 (latexi-strip-line)
190 (insert (format "\\end{verse}\n")))
191 ((member arg '("lisp" "example" "smallexample" "display"))
192 (latexi-strip-line)
193 (save-excursion
194 (save-restriction
195 (narrow-to-region verbatim (point))
196 (goto-char (point-min))
197 (while (search-forward "@{" nil t)
198 (replace-match "{" t t))
199 (goto-char (point-min))
200 (while (search-forward "@}" nil t)
201 (replace-match "}" t t))))
202 (setq verbatim nil)
203 (insert "\\end{verbatim}\n"))
204 ((member arg '("table"))
205 (setq item-string (pop item-stack))
206 (latexi-strip-line)
207 (insert (format "\\end{%slist}\n" (pop list-stack))))
208 ((member arg '("itemize" "enumerate"))
209 (setq item-string (pop item-stack))
210 (latexi-strip-line)
211 (insert (format "\\end{%s}\n" arg)))
212 ((member arg '("iflatex" "iftex" "cartouche" "group"))
213 (latexi-strip-line))
214 ((member arg '("deffn" "defvar" "defun"))
215 (latexi-strip-line))
217 (error "Unknown end arg: %s" arg))))
218 ((member command '("table"))
219 (push item-string item-stack)
220 (push (substring arg 1) list-stack)
221 (setq item-string
222 (format "[@%s{%%s}]" (car list-stack)))
223 (latexi-strip-line)
224 (insert (format "\\begin{%slist}\n" (car list-stack))))
225 ((member command '("itemize" "enumerate"))
226 (push item-string item-stack)
227 (cond
228 ((member arg '("@bullet"))
229 (setq item-string "[\\gnusbullet]"))
231 (setq item-string "")))
232 (latexi-strip-line)
233 (insert (format "\\begin{%s}\n" command)))
234 ((member command '("item"))
235 (latexi-strip-line)
236 (insert (format "\\%s%s\n" command (format item-string arg))))
237 ((equal command "itemx")
238 (latexi-strip-line)
239 (insert (format "\\gnusitemx{%s}\n" (format item-string arg))))
240 ((eq (aref command 0) ?@)
241 (goto-char (match-beginning 0))
242 (delete-char 2)
243 (insert "duppat{}"))
244 ((equal command "settitle")
245 (latexi-strip-line)
246 (if (not as-a-chapter)
247 (insert
248 (format "\\newcommand{\\gnustitlename}{%s}\n" arg))))
249 ((equal command "title")
250 (latexi-strip-line)
251 (insert (format "\\gnustitlename{%s}\n" arg)))
252 ((equal command "author")
253 (latexi-strip-line)
254 (insert (format "\\gnusauthor{%s}\n" arg)))
255 ((equal command "quotation")
256 (latexi-begin-command "verse"))
257 ((equal command "page")
258 (latexi-strip-line)
259 (insert "\\newpage\n"))
260 ((equal command "'s")
261 (goto-char (match-beginning 0))
262 (delete-char 1))
263 ((equal command "include")
264 (latexi-strip-line)
265 (string-match "\\.texi" arg)
266 (insert (format "\\input{%s.latexi}\n"
267 (substring arg 0 (match-beginning 0)))))
268 ((equal command "noindent")
269 (latexi-strip-line)
270 (insert "\\noindent\n"))
271 ((equal command "printindex")
272 (latexi-strip-line)
273 ;;(insert
274 ;; (format
275 ;; "\\begin{theindex}\\input{gnus.%s}\\end{theindex}\n" arg))
278 (error "Unknown command (file %s line %d): %s"
279 file
280 (save-excursion
281 (widen)
282 (1+ (count-lines (point-min) (progn
283 (beginning-of-line)
284 (point)))))
285 command))))
286 ;; These are commands with {}.
287 (setq arg (match-string 5))
288 (cond
289 ((member command '("anchor"))
290 (latexi-strip-line))
291 ((member command '("ref" "xref" "pxref"))
292 (latexi-exchange-command (concat "gnus" command) arg))
293 ((member command '("sc" "file" "dfn" "emph" "kbd" "key" "uref"
294 "code" "samp" "var" "strong" "i"
295 "result" "email" "env" "r" "command" "asis"
296 "url"))
297 (goto-char (match-beginning 0))
298 (delete-char 1)
299 (insert "\\gnus"))
300 ((member command '("acronym"))
301 (latexi-exchange-command (concat "gnus" command) (downcase arg)))
302 ((member command '("copyright" "footnote" "TeX"))
303 (goto-char (match-beginning 0))
304 (delete-char 1)
305 (insert "\\"))
306 ((member command '("dots"))
307 (goto-char (match-beginning 0))
308 (delete-region (match-beginning 0) (match-end 0))
309 (insert "..."))
310 ((eq (aref command 0) ?@)
311 (goto-char (match-beginning 0))
312 (delete-char 2)
313 (insert "duppat{}"))
315 (error "Unknown command (file %s line %d): %s"
316 file
317 (save-excursion
318 (widen)
319 (1+ (count-lines (point-min) (progn
320 (beginning-of-line)
321 (point)))))
322 command))))))
323 (latexi-translate-string "$" "\\gnusdollar{}")
324 (latexi-translate-string "&" "\\gnusampersand{}")
325 (latexi-translate-string "%" "\\gnuspercent{}")
326 (latexi-translate-string "#" "\\gnushash{}")
327 (latexi-translate-string "^" "\\gnushat{}")
328 (latexi-translate-string "~" "\\gnustilde{}")
329 (latexi-translate-string "_" "\\gnusunderline{}")
330 (latexi-translate-string "¬" "\\gnusnot{}")
331 (goto-char (point-min))
332 (while (search-forward "duppat{}" nil t)
333 (replace-match "@" t t))
334 (latexi-translate-string "@@" "@")
335 (latexi-translate-string "<" "\\gnusless{}")
336 (latexi-translate-string ">" "\\gnusgreater{}")
337 (goto-char (point-min))
338 (search-forward "label{Top}" nil t)
339 (while (re-search-forward "\\\\[ntr]\\b" nil t)
340 (when (save-match-data
341 (or (not (save-excursion
342 (search-backward "begin{verbatim}" nil t)))
343 (> (save-excursion
344 (search-backward "end{verbatim"))
345 (save-excursion
346 (search-backward "begin{verbatim}")))))
347 (goto-char (match-beginning 0))
348 (delete-char 1)
349 (insert "\\gnusbackslash{}")))
350 (latexi-translate-string "\\\\" "\\gnusbackslash{}")
351 (goto-char (point-min))
352 (while (re-search-forward "\\\\[][{}]" nil t)
353 (goto-char (match-beginning 0))
354 (delete-char 1))
355 (latexi-contributors)
356 (let ((coding-system-for-write 'iso-8859-1))
357 (write-region (point-min) (point-max) (concat file ".latexi")))))
359 (defun latexi-translate-string (in out)
360 (let (yes)
361 (goto-char (point-min))
362 (search-forward "label{Top}" nil t)
363 (while (search-forward in nil t)
364 (when (save-match-data
365 (or (not (save-excursion
366 (search-backward "begin{verbatim}" nil t)))
367 (> (save-excursion
368 (re-search-backward "end{verbatim}\\|end{verse}"))
369 (save-excursion
370 (re-search-backward
371 "begin{verbatim}\\|begin{verse}")))))
372 (replace-match out t t)))))
374 (defun latexi-contributors ()
375 (goto-char (point-min))
376 (when (re-search-forward "^Also thanks to the following" nil t)
377 (forward-line 2)
378 (narrow-to-region
379 (point)
380 (1- (search-forward "\n\n")))
381 (when (re-search-backward "^and" nil t)
382 (latexi-strip-line))
383 (goto-char (point-min))
384 (while (re-search-forward "[.,] *$" nil t)
385 (replace-match "" t t))
386 (goto-char (point-min))
387 (let (names)
388 (while (not (eobp))
389 (push (buffer-substring (point) (progn (end-of-line) (point)))
390 names)
391 (forward-line 1))
392 (delete-region (point-min) (point-max))
393 (insert "\\begin{tabular}{lll}\n")
394 (setq names (nreverse (delete "" names)))
395 (while names
396 (insert (pop names) " & " (or (pop names) "\\mbox{}")
397 " & " (or (pop names) "\\mbox{}")
398 "\\\\\n"))
399 (insert "\\end{tabular}\n")
400 (widen))))
402 (defvar latexi-copying-text ""
403 "Text of the copyright notice and copying permissions.")
405 (defun latexi-copying ()
406 "Copy the copyright notice and copying permissions from the Texinfo file,
407 as indicated by the @copying ... @end copying command;
408 insert the text with the @insertcopying command."
409 (let ((beg (progn (beginning-of-line) (point)))
410 (end (progn (re-search-forward "^@end copying[ \t]*\n") (point))))
411 (setq latexi-copying-text
412 (buffer-substring-no-properties
413 (save-excursion (goto-char beg) (forward-line 1) (point))
414 (save-excursion (goto-char end) (forward-line -1) (point))))
415 (delete-region beg end)))
417 (defun latexi-insertcopying ()
418 "Insert the copyright notice and copying permissions from the Texinfo file,
419 which are indicated by the @copying ... @end copying command."
420 (insert (concat "\n" latexi-copying-text)))