*** empty log message ***
[gnus] / texi / texi2latex.el
1 ;;; texi2latex.el --- convert a texi file into a LaTeX file.
2 ;; Copyright (C) 1996 Lars Magne Ingebrigtsen
3
4 (require 'cl)
5
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))))
11
12 (defun latexi-strip-line ()
13   (delete-region (progn (beginning-of-line) (point))
14                  (progn (forward-line 1) (point))))
15
16 (defun latexi-switch-line (command arg)
17   (latexi-strip-line)
18   (insert (format "\\%s{%s}\n" command arg)))
19
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)))
25
26 (defun latexi-begin-command (command)
27   (latexi-strip-line)
28   (insert (format "\\begin{%s}\n" command)))
29
30 (defun latexi-exchange-command (command arg)
31   (delete-region (match-beginning 0) (match-end 0))
32   (insert (format "\\%s{%s}" command arg)))
33
34 (defun latexi-translate ()
35   "Translate."
36   (interactive)
37   (latexi-translate-file "gnus")
38   (latexi-translate-file "gnus-faq"))
39
40 (defun latexi-translate-file (file)
41   "Translate file a LaTeX file."
42   (let ((item-string "")
43         (item-stack nil)
44         (list-stack nil)
45         (latexi-buffer (get-buffer-create "*LaTeXi*"))
46         verbatim
47         (regexp 
48          (concat 
49             "@\\([^{} \t\n]+\\)"
50             "\\(\\( +\\(.*$\\)\\|[ \t]*$\\)\\|{\\([^}]*\\)}\\)"))
51         (cur (find-file-noselect (concat file ".texi")))
52         (times 3)
53         (chapter 0)
54         command arg)
55     (pop-to-buffer latexi-buffer)
56     (buffer-disable-undo)
57     (erase-buffer)
58     (insert-buffer-substring cur)
59     (goto-char (point-min))
60     (latexi-strip-line)
61     (latexi-translate-string "%@{" "\\gnuspercent{}\\gnusbraceleft{}")
62     (latexi-translate-string "%@}" "\\gnuspercent{}\\gnusbraceright{}")
63     (latexi-translate-string "%1@{" "\\gnuspercent{}1\\gnusbraceright{}")
64 ;    (while (re-search-forward "{\"[^\"]*\\(\\\\\\)[^\"]*\"}\\\\" nil t)
65 ;      (replace-match "\\verb+\\\\+ " t t))
66     (while (not (zerop (decf times)))
67       (goto-char (point-min))
68       (while (re-search-forward regexp nil t)
69         (setq command (match-string 1))
70         (if (match-beginning 3)
71             (progn
72               (setq arg (or (match-string 4) ""))
73               (save-match-data
74                 (when (string-match "[ \t]+$" arg)
75                   (setq arg (substring arg 0 (match-beginning 0)))))
76               (cond 
77                ((member command '("c" "comment"))
78                 (if (string-match "@icon" (or arg ""))
79                     (progn
80                       (beginning-of-line)
81                       (delete-region (point) (+ (point) 4))
82                       (insert "\\gnus"))
83                   (delete-region (match-beginning 0) 
84                                  (progn (end-of-line) (point))))
85                 (if (equal arg "@head")
86                     (insert "\\gnusinteresting")))
87                ((member command '("setfilename" 
88                                   "synindex" "setchapternewpage"
89                                   "summarycontents" "bye"
90                                   "top" "iftex" "cartouche" 
91                                   "iflatex" "finalout" "vskip"))
92                 (latexi-strip-line))
93                ((member command '("menu" "tex" "ifinfo" "ignore"))
94                 (latexi-discard-until command))
95                ((member command '("subsection" "subsubsection"))
96                 (latexi-switch-line command arg))
97                ((member command '("chapter"))
98                 (latexi-switch-line 
99                  (format 
100                   "gnus%s{\\epsfig{figure=tmp/new-herd-%d.ps,scale=.5}}"
101                    command (incf chapter))
102                  arg))
103                ((member command '("section"))
104                 (latexi-switch-line (format "gnus%s" command) arg))
105                ((member command '("cindex" "findex" "kindex" "vindex"))
106                 (latexi-index-command command arg))
107                ((member command '("*"))
108                 (delete-char -2)
109                 (insert "\\\\"))
110                ((equal command "sp")
111                 (replace-match "" t t))
112                ((equal command "node")
113                 (latexi-strip-line)
114                 (insert (format "\\label{%s}\n" arg)))
115                ((equal command "contents")
116                 (latexi-strip-line)
117                 ;;(insert (format "\\tableofcontents\n" arg))
118                 )
119                ((member command '("titlepage"))
120                 (latexi-begin-command command))
121                ((member command '("lisp" "example"))
122                 (latexi-strip-line)
123                 (insert (format "\\begin{verbatim}\n"))
124                 (setq verbatim (point)))
125                ((member command '("center"))
126                 (latexi-strip-line)
127                 (insert (format "\\begin{%s}%s\\end{%s}\n"
128                                 command arg command)))
129                ((member command '("end"))
130                 (cond
131                  ((member arg '("titlepage"))
132                   (latexi-strip-line)
133                   (insert (format "\\end{%s}\n" arg)))
134                  ((equal arg "quotation")
135                   (latexi-strip-line)
136                   (insert (format "\\end{verse}\n")))
137                  ((member arg '("lisp" "example"))
138                   (latexi-strip-line)
139                   (save-excursion
140                     (save-restriction
141                       (narrow-to-region verbatim (point))
142                       (goto-char (point-min))
143                       (while (search-forward "@{" nil t)
144                         (replace-match "{" t t))
145                       (goto-char (point-min))
146                       (while (search-forward "@}" nil t)
147                         (replace-match "}" t t))))
148                   (setq verbatim nil)
149                   (insert "\\end{verbatim}\n"))
150                  ((member arg '("table"))
151                   (setq item-string (pop item-stack))
152                   (latexi-strip-line)
153                   (insert (format "\\end{%slist}\n" (pop list-stack))))
154                  ((member arg '("itemize" "enumerate"))
155                   (setq item-string (pop item-stack))
156                   (latexi-strip-line)
157                   (insert (format "\\end{%s}\n" arg)))
158                  ((member arg '("iflatex" "iftex" "cartouche"))
159                   (latexi-strip-line))
160                  (t
161                   (error "Unknown end arg: %s" arg))))
162                ((member command '("table"))
163                 (push item-string item-stack)
164                 (push (substring arg 1) list-stack)
165                 (setq item-string 
166                       (format "[@%s{%%s}]" (car list-stack)))
167                 (latexi-strip-line)
168                 (insert (format "\\begin{%slist}\n" (car list-stack))))
169                ((member command '("itemize" "enumerate"))
170                 (push item-string item-stack)
171                 (cond 
172                  ((member arg '("@bullet"))
173                   (setq item-string "[\\gnusbullet]"))
174                  (t
175                   (setq item-string "")))
176                 (latexi-strip-line)
177                 (insert (format "\\begin{%s}\n" command)))
178                ((member command '("item"))
179                 (latexi-strip-line)
180                 (insert (format "\\%s%s\n" command (format item-string arg))))
181                ((equal command "itemx")
182                 (latexi-strip-line)
183                 (insert (format "\\gnusitemx{%s}\n" (format item-string arg))))
184                ((eq (aref command 0) ?@)
185                 (goto-char (match-beginning 0))
186                 (delete-char 2)
187                 (insert "duppat{}"))
188                ((equal command "settitle")
189                 (latexi-strip-line)
190                 (insert (format "\\newcommand{\\gnustitlename}{%s}\n" arg)))
191                ((equal command "title")
192                 (latexi-strip-line)
193                 (insert (format "\\gnustitlename{%s}\n" arg)))
194                ((equal command "author")
195                 (latexi-strip-line)
196                 (insert (format "\\gnusauthor{%s}\n" arg)))
197                ((equal command "quotation")
198                 (latexi-begin-command "verse"))
199                ((equal command "page")
200                 (latexi-strip-line)
201                 (insert (format "\\newpage\n" arg)))
202                ((equal command "'s")
203                 (goto-char (match-beginning 0))
204                 (delete-char 1))
205                ((equal command "include")
206                 (latexi-strip-line)
207                 (insert "\\input{gnus-faq.latexi}\n"))
208                ((equal command "printindex")
209                 (latexi-strip-line)
210                 ;;(insert 
211                 ;; (format 
212                 ;;  "\\begin{theindex}\\input{gnus.%s}\\end{theindex}\n" arg))
213                 )
214                (t
215                 (error "Unknown command: %s" command))))
216           ;; These are commands with {}.
217           (setq arg (match-string 5))
218           (cond 
219            ((member command '("xref" "pxref"))
220             (latexi-exchange-command (concat "gnus" command) arg))
221            ((member command '("sc" "file" "dfn" "emph" "kbd" 
222                               "code" "samp" "var" "strong" "i"))
223             (goto-char (match-beginning 0))
224             (delete-char 1)
225             (insert "\\gnus"))
226            ((member command '("copyright"))
227             (goto-char (match-beginning 0))
228             (delete-char 1)
229             (insert "\\"))
230            ((eq (aref command 0) ?@)
231             (goto-char (match-beginning 0))
232             (delete-char 2)
233             (insert "duppat{}"))
234            (t
235             (error "Unknown command: %s" command))))))
236     (latexi-translate-string "$" "\\gnusdollar{}")
237     (latexi-translate-string "&" "\\gnusampersand{}")
238     (latexi-translate-string "%" "\\gnuspercent{}")
239     (latexi-translate-string "#" "\\gnushash{}")
240     (latexi-translate-string "^" "\\gnushat{}")
241     (latexi-translate-string "~" "\\gnustilde{}")
242     (latexi-translate-string "_" "\\gnusunderline{}")
243     (latexi-translate-string "¬" "\\gnusnot{}")
244     (goto-char (point-min))
245     (while (search-forward "duppat{}" nil t)
246       (replace-match "@" t t))
247     (latexi-translate-string "@@" "@")
248     (latexi-translate-string "<" "\\gnusless{}")
249     (latexi-translate-string ">" "\\gnusgreater{}")
250     (goto-char (point-min))
251     (search-forward "label{Top}" nil t)
252     (while (re-search-forward "\\\\[ntr]\\b" nil t)
253       (when (save-match-data
254               (or (not (save-excursion
255                          (search-backward "begin{verbatim}" nil t)))
256                   (> (save-excursion
257                        (search-backward "end{verbatim"))
258                      (save-excursion
259                        (search-backward "begin{verbatim}")))))
260         (goto-char (match-beginning 0))
261         (delete-char 1)
262         (insert "\\gnusbackslash{}")))
263     (latexi-translate-string "\\\\" "\\gnusbackslash{}")
264     (goto-char (point-min))
265     (while (re-search-forward "\\\\[][{}]" nil t)
266       (goto-char (match-beginning 0))
267       (delete-char 1))
268     (latexi-contributors)
269     (write-region (point-min) (point-max) (concat file ".latexi"))))
270
271 (defun latexi-translate-string (in out)
272   (let (yes)
273     (goto-char (point-min))
274     (search-forward "label{Top}" nil t)
275     (while (search-forward in nil t)
276       (when (save-match-data
277               (or (not (save-excursion
278                          (search-backward "begin{verbatim}" nil t)))
279                   (> (save-excursion
280                        (re-search-backward "end{verbatim}\\|end{verse}"))
281                      (save-excursion
282                        (re-search-backward
283                         "begin{verbatim}\\|begin{verse}")))))
284         (replace-match out t t)))))
285
286 (defun latexi-contributors ()
287   (goto-char (point-min))
288   (when (re-search-forward "^Also thanks to the following" nil t)
289     (forward-line 2)
290     (narrow-to-region
291      (point)
292      (1- (search-forward "\n\n")))
293     (when (re-search-backward "^and" nil t)
294       (latexi-strip-line))
295     (goto-char (point-min))
296     (while (re-search-forward "[.,] *$" nil t)
297       (replace-match "" t t))
298     (goto-char (point-min))
299     (let (names)
300       (while (not (eobp))
301         (push (buffer-substring (point) (progn (end-of-line) (point)))
302               names)
303         (forward-line 1))
304       (delete-region (point-min) (point-max))
305       (insert "\\begin{tabular}{lll}\n")
306       (setq names (nreverse (delete "" names)))
307       (while names
308         (insert (pop names) " & " (or (pop names) "\\mbox{}") 
309                 " & " (or (pop names) "\\mbox{}") 
310                 "\\\\\n"))
311       (insert "\\end{tabular}\n")
312       (widen))))
313