1 ;;; texi2latex.el --- convert a texi file into a LaTeX file.
2 ;; Copyright (C) 1996, 2004, 2008 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
)
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 "")
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))
67 (when (search-forward "@copying" nil t
)
69 (while (search-forward "@insertcopying" nil t
)
70 (delete-region (match-beginning 0) (match-end 0))
71 (latexi-insertcopying))
72 (goto-char (point-min))
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)
97 (setq arg
(or (match-string 4) ""))
99 (when (string-match "[ \t]+$" arg
)
100 (setq arg
(substring arg
0 (match-beginning 0)))))
102 ((member command
'("c" "comment"))
103 (if (string-match "@icon" (or arg
""))
106 (delete-region (point) (+ (point) 4))
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"
120 ((member command
'("menu" "tex" "ifinfo" "ignore"
121 "ifnottex" "direntry"))
122 (latexi-discard-until command
))
123 ((member command
'("subsection" "subsubsection"))
125 (latexi-switch-line (format "sub%s" command
) arg
)
126 (latexi-switch-line command arg
)))
127 ((member command
'("heading"))
129 (latexi-switch-line "subsection*" arg
)
130 (latexi-switch-line "section*" arg
)))
131 ((member command
'("subheading"))
133 (latexi-switch-line "subsubsection*" arg
)
134 (latexi-switch-line "subsection*" arg
)))
135 ((member command
'("subsubheading"))
137 (latexi-switch-line "subsubsubsection*" arg
)
138 (latexi-switch-line "subsubsection*" arg
)))
139 ((member command
'("chapter"))
140 (if (string-match "Index" arg
)
143 (latexi-switch-line "gnussection" arg
)
147 (format "\\epsfig{figure=ps/new-herd-%d,scale=.5}"
148 (if (> (incf chapter
) 9) 9 chapter
)))
150 ((member command
'("section"))
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
'("*"))
159 ((equal command
"sp")
160 (replace-match "" t t
))
162 (replace-match "" t t
))
163 ((member command
'("deffn" "defvar" "defun"))
164 (replace-match "" t t
))
165 ((equal command
"node")
167 (unless (string-match "Index" arg
)
168 (insert (format "\\label{%s}\n" arg
))))
169 ((equal command
"contents")
171 ;;(insert (format "\\tableofcontents\n" arg))
173 ((member command
'("titlepage"))
174 (latexi-begin-command command
))
175 ((member command
'("lisp" "example" "smallexample" "display"))
177 (insert (format "\\begin{verbatim}\n"))
178 (setq verbatim
(point)))
179 ((member command
'("center"))
181 (insert (format "\\begin{%s}%s\\end{%s}\n"
182 command arg command
)))
183 ((member command
'("end"))
185 ((member arg
'("titlepage"))
187 (insert (format "\\end{%s}\n" arg
)))
188 ((equal arg
"quotation")
190 (insert (format "\\end{verse}\n")))
191 ((member arg
'("lisp" "example" "smallexample" "display"))
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
))))
203 (insert "\\end{verbatim}\n"))
204 ((member arg
'("table"))
205 (setq item-string
(pop item-stack
))
207 (insert (format "\\end{%slist}\n" (pop list-stack
))))
208 ((member arg
'("itemize" "enumerate"))
209 (setq item-string
(pop item-stack
))
211 (insert (format "\\end{%s}\n" arg
)))
212 ((member arg
'("iflatex" "iftex" "cartouche" "group"))
214 ((member arg
'("deffn" "defvar" "defun"))
217 (error "Unknown end arg: %s" arg
))))
218 ((member command
'("table"))
219 (push item-string item-stack
)
220 (push (substring arg
1) list-stack
)
222 (format "[@%s{%%s}]" (car list-stack
)))
224 (insert (format "\\begin{%slist}\n" (car list-stack
))))
225 ((member command
'("itemize" "enumerate"))
226 (push item-string item-stack
)
228 ((member arg
'("@bullet"))
229 (setq item-string
"[\\gnusbullet]"))
231 (setq item-string
"")))
233 (insert (format "\\begin{%s}\n" command
)))
234 ((member command
'("item"))
236 (insert (format "\\%s%s\n" command
(format item-string arg
))))
237 ((equal command
"itemx")
239 (insert (format "\\gnusitemx{%s}\n" (format item-string arg
))))
240 ((eq (aref command
0) ?
@)
241 (goto-char (match-beginning 0))
244 ((equal command
"settitle")
246 (if (not as-a-chapter
)
248 (format "\\newcommand{\\gnustitlename}{%s}\n" arg
))))
249 ((equal command
"title")
251 (insert (format "\\gnustitlename{%s}\n" arg
)))
252 ((equal command
"author")
254 (insert (format "\\gnusauthor{%s}\n" arg
)))
255 ((equal command
"quotation")
256 (latexi-begin-command "verse"))
257 ((equal command
"page")
259 (insert "\\newpage\n"))
260 ((equal command
"'s")
261 (goto-char (match-beginning 0))
263 ((equal command
"include")
265 (string-match "\\.texi" arg
)
266 (insert (format "\\input{%s.latexi}\n"
267 (substring arg
0 (match-beginning 0)))))
268 ((equal command
"noindent")
270 (insert "\\noindent\n"))
271 ((equal command
"printindex")
275 ;; "\\begin{theindex}\\input{gnus.%s}\\end{theindex}\n" arg))
278 (error "Unknown command (file %s line %d): %s"
282 (1+ (count-lines (point-min) (progn
286 ;; These are commands with {}.
287 (setq arg
(match-string 5))
289 ((member command
'("anchor"))
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"
297 (goto-char (match-beginning 0))
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))
306 ((member command
'("dots"))
307 (goto-char (match-beginning 0))
308 (delete-region (match-beginning 0) (match-end 0))
310 ((eq (aref command
0) ?
@)
311 (goto-char (match-beginning 0))
315 (error "Unknown command (file %s line %d): %s"
319 (1+ (count-lines (point-min) (progn
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
)))
344 (search-backward "end{verbatim"))
346 (search-backward "begin{verbatim}")))))
347 (goto-char (match-beginning 0))
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))
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
)
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
)))
368 (re-search-backward "end{verbatim}\\|end{verse}"))
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
)
380 (1- (search-forward "\n\n")))
381 (when (re-search-backward "^and" nil t
)
383 (goto-char (point-min))
384 (while (re-search-forward "[.,] *$" nil t
)
385 (replace-match "" t t
))
386 (goto-char (point-min))
389 (push (buffer-substring (point) (progn (end-of-line) (point)))
392 (delete-region (point-min) (point-max))
393 (insert "\\begin{tabular}{lll}\n")
394 (setq names
(nreverse (delete "" names
)))
396 (insert (pop names
) " & " (or (pop names
) "\\mbox{}")
397 " & " (or (pop names
) "\\mbox{}")
399 (insert "\\end{tabular}\n")
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
)))