Initial release of Maemo 5 port of gnuplot
[gnuplot] / docs / doc2texi.el
1 ;;;; doc2texi.el -- generate a texinfo file from the gnuplot doc file
2
3 ;; Copyright (C) 1999 Bruce Ravel
4
5 ;; Author:     Bruce Ravel <ravel@phys.washington.edu>
6 ;; Maintainer: Bruce Ravel <ravel@phys.washington.edu>
7 ;; Created:    March 23 1999
8 ;; Updated:    May 28 1999
9 ;; Version:    0.2
10 ;; Keywords:   gnuplot, document, info
11
12 ;; This file is not part of GNU Emacs.
13
14 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15 ;; This lisp script is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 ;;
19 ;; Permission is granted to distribute copies of this lisp script
20 ;; provided the copyright notice and this permission are preserved in
21 ;; all copies.
22 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
23 ;; send bug reports to the author (ravel@phys.washington.edu)
24 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25 ;;; Commentary:
26 ;;
27 ;; I suppose the most immediate question to ask is "Why do this in
28 ;; emacs lisp???"  While it is true that the gnuplot.doc file lends
29 ;; itself to processing by a 1 pass filter, there are some aspects of
30 ;; texinfo files that are a bit tricky and would require 2 or perhaps
31 ;; three passes.  Specifically, getting all of the cross references
32 ;; made correctly is a lot of work.  Fortunately, texinfo-mode has
33 ;; functions for building menus and updating nodes.  This saves a lot
34 ;; of sweat and is the principle reason why I decided to write this in
35 ;; emacs lisp.
36 ;;
37 ;; Everything else in gnuplot is written in C for the sake of
38 ;; portability.  Emacs lisp, of course, requires that you have emacs.
39 ;; For many gnuplot users, that is not a good assumption.  However,
40 ;; the likelihood of needing info files in the absence of emacs is
41 ;; very, very slim.  I think it is safe to say that someone who needs
42 ;; info files has emacs installed and thus will be able to use this
43 ;; program.
44 ;;
45 ;; Since this is emacs, I am not treating the gnuplot.doc file as a
46 ;; text stream.  It seems much more efficient in this context to treat
47 ;; it as a buffer.  All of the work is done by the function
48 ;; `d2t-doc-to-texi'.  Each of the conversion chores is handled by an
49 ;; individual function.  Each of thse functions is very similar in
50 ;; structure.  They start at the top of the buffer, search forward for
51 ;; a line matching the text element being converted, perform the
52 ;; replacement in place, and move on until the end of the buffer.
53 ;; These text manipulations are actually quite speedy.  The slow part
54 ;; of the process is using the texinfo-mode function to update the
55 ;; nodes and menus.  However, using these slow functions has one
56 ;; advantage -- the texinfo-mode functions for doing menus and nodes
57 ;; are certain to do the job correctly.  Although rather slow, this
58 ;; approach doesn't totally suck compared to the time cost of
59 ;; compiling and running a C program.  And the output from this is
60 ;; much more useful than the output from the doc2info program.
61 ;;
62 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
63 ;;; Use:
64 ;;
65 ;; Customize the variables at the start of the executable code.  Then
66 ;; I intend that this be used from the command line or from a Makefile
67 ;; like so:
68 ;;
69 ;;      emacs -batch -l doc2texi.el -f d2t-doc-to-texi
70 ;;
71 ;; or
72 ;;
73 ;;      emacs -batch -l doc2texi.el -f d2t-doc-to-texi-verbosely
74 ;;
75 ;; This will start emacs in batch mode, load this file, run the
76 ;; converter, then quit.  This takes about 30 seconds my 133 MHz
77 ;; Pentium.  It also sends a large number of mesages to stderr, so you
78 ;; may want to redirect stderr to /dev/null or to a file.
79 ;;
80 ;; Then you can do
81 ;;
82 ;;      makeinfo gnuplot.info
83 ;;
84 ;; You may want to use the --no-split option.
85 ;;
86 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
87 ;;; History:
88 ;;
89 ;;  0.1  Mar 23 1999 <BR> Initial version
90 ;;  0.2  May 28 1999 <BR>
91 ;;  0.3  Jun  2 1999 <BR> Added terminal information, fixed uref problem.
92 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
93 ;;; Acknowledgements:
94 ;;
95 ;; Lars Hecking asked me to look into the doc -> info problem.  Silly
96 ;; me, I said "ok."  This is what I came up with.
97 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
98 ;;; To do:
99 ;;
100 ;;  -- internal cross-references: these are not perfect due to
101 ;;     inconsistencies in the use of `` and case inconsistencies in
102 ;;     the text.  The latter can be fixed.  Also I need a way to not
103 ;;     make the @ref if point is currently in that region.
104 ;;  -- catch errors gracefully, particularly when looking for files.
105 ;;  -- are guesses about OS specific terminal information correct?
106 ;;  -- turn the lists in the "What's New" and "xlabel" sections into
107 ;;     proper lists.  "^\\([0-9]\\)+\." finds the list items.  If
108 ;;     (match-string 1) is "1" then insert "@enumerate\n@item\n", else
109 ;;     insert "@item\n".  also use (replace-match "").  need to find
110 ;;     the end somehow.
111 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
112 ;;; Code:
113
114 ;;; You may need to customize these variables:
115 (defvar d2t-doc-file-name "gnuplot.doc"
116   "Name of the gnuplot.doc file.")
117 (defvar d2t-terminal-directory (expand-file-name "../term/")
118   "Location of .trm files in gnuplot source tree.")
119
120
121 ;;; You should not need to touch anything below here ;;;;;;;;;;;;;;;;;;;;;
122
123 (require 'cl)
124 (eval-and-compile                       ; need split-string to do xrefs
125   (if (fboundp 'split-string)
126       ()
127     (defun split-string (string &optional pattern)
128       "Return a list of substrings of STRING which are separated by PATTERN.
129 If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"."
130       (or pattern
131           (setq pattern "[ \f\t\n\r\v]+"))
132       (let (parts (start 0))
133         (while (string-match pattern string start)
134           (setq parts (cons (substring string start (match-beginning 0)) parts)
135                 start (match-end 0)))
136         (nreverse (cons (substring string start) parts)))) ))
137
138 (defconst d2t-work-buffer-name "*doc2texi*"
139   "Name of scratch buffer where the doc file will be converted into a
140   texi file.")
141 (defconst d2t-scratch-buffer-name "*doc2texi-output*")
142 (defconst d2t-terminal-buffer-name "*doc2texi-terminal*")
143 (defvar d2t-verbose nil)
144 (defconst d2t-texi-filename "gnuplot.texi")
145
146 (defconst d2t-texi-header
147   "\\input texinfo   @c -*-texinfo-*-
148
149 @c %**start of header
150 @setfilename gnuplot.info
151 @settitle Gnuplot: An Interactive Plotting Program
152 @setchapternewpage odd
153 @c %**end of header
154
155 @c define the command and options indeces
156 @defindex cm
157 @defindex op
158 @defindex tm
159
160 @dircategory Math
161 @direntry
162 * GNUPLOT: (gnuplot).             An Interactive Plotting Program
163 @end direntry
164
165 @ifnottex
166 @node Top, gnuplot, (dir), (dir)
167 @top Master Menu
168 @end ifnottex
169
170 @example
171                        GNUPLOT
172
173             An Interactive Plotting Program
174              Thomas Williams & Colin Kelley
175           Version 4.2 organized by: Hans-Bernhard Broeker
176
177  Copyright (C) 1986 - 1993, 1998, 2004   Thomas Williams, Colin Kelley
178
179        Mailing list for comments: gnuplot-info@@lists.sourceforge.net
180      Mailing list for bug reports: gnuplot-bugs@@lists.sourceforge.net
181
182          This manual was originally prepared by Dick Crawford
183                    Version 4.2 - 1 Oct 2006
184
185
186 Major contributors (alphabetic order):
187 @end example
188
189 "
190   "Texinfo header.")
191
192 (defconst d2t-main-menu
193   "@menu
194 @end menu"
195   "Main menu.")
196
197 (defconst d2t-texi-footer
198   "@node Concept_Index, Command_Index, Bugs, Top
199 @unnumbered Concept Index
200 @printindex cp
201
202 @node Command_Index, Option_Index, Concept_Index, Top
203 @unnumbered Command Index
204 @printindex cm
205
206 @node Options_Index, Function_Index, Command_Index, Top
207 @unnumbered Options Index
208 @printindex op
209
210 @node Function_Index, Terminal_Index, Options_Index, Top
211 @unnumbered Function Index
212 @printindex fn
213
214 @node Terminal_Index, , Options_Index, Top
215 @unnumbered Terminal Index
216 @printindex tm
217
218 @c @shortcontents
219 @contents
220 @bye
221 "
222   "Texinfo file terminator.")
223
224 (defvar d2t-level-1-alist nil
225   "Alist of level 1 tags and markers.")
226 (defvar d2t-level-2-alist nil
227   "Alist of level 2 tags and markers.")
228 (defvar d2t-level-3-alist nil
229   "Alist of level 3 tags and markers.")
230 (defvar d2t-level-4-alist nil
231   "Alist of level 4 tags and markers.")
232 (defvar d2t-level-5-alist nil
233   "Alist of level 5 tags and markers.")
234 (defvar d2t-commands-alist nil
235   "Alist of commands and markers.")
236 (defvar d2t-set-show-alist nil
237   "Alist of options and markers.")
238 (defvar d2t-functions-alist nil
239   "Alist of functions and markers.")
240 (defvar d2t-terminals-alist nil
241   "Alist of terminal types and markers.")
242 (defvar d2t-node-list nil
243   "List of nodes.")
244
245 (defvar d2t-terminal-list ())
246 (setq d2t-terminal-list
247       '("aed"
248         "ai"
249         "amiga"
250         "apollo"
251         "aquaterm"
252         "atariaes"
253         "atarivdi"
254         "be"
255         "cgi"
256         "cgm"
257         "corel"
258         "debug"
259         "djsvga"
260         "dumb"
261         "dxf"
262         "dxy"
263         "eepic"
264         "emf"
265         "emxvga"
266         "epslatex"
267         "epson"
268         "excl"
269         "fg"
270         "fig"
271         "gd"
272         "ggi"
273         "gif"
274         "gnugraph"
275         "gpic"
276         "gpr"
277         "grass"
278         "hp26"
279         "hp2648"
280         "hp500c"
281         "hpgl"
282         "hpljii"
283         "hppj"
284         "imagen"
285         "iris4d"
286         "jpeg"
287         "kyo"
288         "latex"
289         "linux"
290         "mac"
291         "metafont"
292         "metapost"
293         "mgr"
294         "mif"
295         "multitos"
296         "next"
297         "openstep"
298         "pbm"
299         "pc"
300         "pdf"
301         "png"
302         "post"
303         "pslatex"
304         "pstricks"
305         "qms"
306         "regis"
307         "rgip"
308         "sun"
309         "svg"
310         "t410x"
311         "table"
312         "tek"
313         "texdraw"
314         "tgif"
315         "tkcanvas"
316         "tpic"
317         "unixpc"
318         "unixplot"
319         "v384"
320         "vgagl"
321         "vws"
322         "win"
323         "x11"
324         "xlib"))
325
326 (defun d2t-doc-to-texi-verbosely ()
327   "Run `d2t-doc-to-texi' noisily"
328   (interactive)
329   (setq d2t-verbose t)
330   (d2t-doc-to-texi))
331
332 (defun d2t-doc-to-texi ()
333   "This is the doc to texi converter function.
334 It calls a bunch of other functions, each of which handles one
335 particular conversion chore."
336   (interactive)
337   (setq d2t-level-1-alist   nil ;; initialize variables
338         d2t-level-2-alist   nil
339         d2t-level-3-alist   nil
340         d2t-level-4-alist   nil
341         d2t-level-5-alist   nil
342         d2t-commands-alist  nil
343         d2t-set-show-alist  nil
344         d2t-functions-alist nil
345         d2t-terminals-alist nil
346         d2t-node-list       nil)
347   ;; open the doc file and get some data about its contents
348   (d2t-prepare-workspace)
349   (message "Inserting help for terminals ...")
350   (d2t-get-terminals)
351   (message "Analyzing doc file ...")
352   (d2t-get-levels)
353   (d2t-get-commands)
354   (d2t-get-set-show)
355   (d2t-get-functions)
356   ;; convert the buffer from doc to texi, one element at a time
357   (message "Converting to texinfo ...")
358   (d2t-braces-atsigns)   ;; this must be the first conversion function
359   (d2t-comments)         ;; delete comments
360   (d2t-sectioning)       ;; chapters, sections, etc
361   (d2t-indexing)         ;; index markup
362   (d2t-tables)           ;; fix up tables
363   (d2t-handle-html)      ;; fix up html markup
364   (d2t-first-column)     ;; left justify normal text
365   (d2t-enclose-examples) ;; turn indented text into @examples
366   (message "Menus, nodes, xrefs ...")
367   (d2t-make-refs)
368   ;(d2t-make-menus)
369   ;(d2t-set-nodes)
370   (save-excursion        ;; fix a few more things explicitly
371     (goto-char (point-min))
372     (insert d2t-texi-header)
373     (search-forward "@node")
374     ;; (beginning-of-line)
375     ;; (insert "\n\n" d2t-main-menu "\n\n")
376     (search-forward "@node Bugs")       ; `texinfo-all-menus-update' seems
377     (beginning-of-line)                 ; to miss this one.  how odd.
378     (insert "@menu\n* Bugs::\t\t\t\n@end menu\n\n")
379     (goto-char (point-max))
380     (insert d2t-texi-footer))
381   (load-library "texinfo") ;; now do the hard stuff with texinfo-mode
382   (texinfo-mode)
383   (let ((message-log-max 0)
384         (standard-output (get-buffer-create d2t-scratch-buffer-name)))
385     (message "Making texinfo nodes ...\n")
386     (texinfo-every-node-update)
387     (message "Making texinfo menus ...\n")
388     (texinfo-all-menus-update))
389   (write-file d2t-texi-filename) )  ; save it and done!
390
391 (defun d2t-prepare-workspace ()
392   "Create a scratch buffer and populate it with gnuplot.doc."
393   (and d2t-verbose (message "  Doing d2t-prepare-workspace ..."))
394   (if (get-buffer d2t-work-buffer-name)
395       (kill-buffer d2t-work-buffer-name))
396   (if (get-buffer d2t-texi-filename)
397       (kill-buffer d2t-texi-filename))
398   (if (get-buffer d2t-terminal-buffer-name)
399       (kill-buffer d2t-terminal-buffer-name))
400   (get-buffer-create d2t-terminal-buffer-name)
401   (set-buffer (get-buffer-create d2t-work-buffer-name))
402   (insert-file-contents d2t-doc-file-name)
403   (goto-char (point-min)))
404
405
406 (defun d2t-get-terminals ()
407   "Insert all appropriate terminal help."
408   (let ((case-fold-search t))
409     (if (string-match "linux" system-configuration)
410         (setq d2t-terminal-list (append d2t-terminal-list
411                                         '("linux"))))
412     (if (string-match "amiga" system-configuration)
413         (setq d2t-terminal-list (append d2t-terminal-list
414                                         '("amiga"))))
415     (if (string-match "atari" system-configuration)
416         (setq d2t-terminal-list (append d2t-terminal-list
417                                         '("atarivdi" "multitos" "atariaes"))))
418     (if (string-match "mac" system-configuration)
419         (setq d2t-terminal-list (append d2t-terminal-list
420                                         '("mac" "openstep"))))
421     (if (string-match "beos" system-configuration)
422         (setq d2t-terminal-list (append d2t-terminal-list
423                                         '("be"))))
424     (if (string-match "dos" system-configuration)
425         (setq d2t-terminal-list (append d2t-terminal-list
426                                         '("emxvga" "djsvga" "fg" "pc"))))
427     (if (string-match "windows" (format "%s" system-type))
428         (setq d2t-terminal-list (append d2t-terminal-list
429                                         '("win"))))
430     (if (string-match "next" system-configuration)
431         (setq d2t-terminal-list (append d2t-terminal-list
432                                         '("next"))))
433     (if (string-match "os2" system-configuration)
434         (setq d2t-terminal-list (append d2t-terminal-list
435                                         '("pm" "emxvga"))))
436     (if (string-match "irix" system-configuration)
437         (setq d2t-terminal-list (append d2t-terminal-list
438                                         '("iris4d"))))
439     (if (string-match "sco" system-configuration)
440         (setq d2t-terminal-list (append d2t-terminal-list
441                                         '("cgi"))))
442     (if (string-match "sun" system-configuration)
443         (setq d2t-terminal-list (append d2t-terminal-list
444                                         '("sun"))))
445     (if (string-match "vms" system-configuration)
446         (setq d2t-terminal-list (append d2t-terminal-list
447                                         '("vws"))))
448     (unless (member* system-configuration '("dos" "windows" "atari" "amiga")
449                      :test 'string-match)
450       (setq d2t-terminal-list
451             (append d2t-terminal-list
452                     '("x11" "tgif" "gpic" "regis" "t410x" "tex" "xlib")))) )
453   (setq d2t-terminal-list (sort d2t-terminal-list 'string<))
454   (let ((list d2t-terminal-list) file node marker)
455     (save-excursion
456       (when (re-search-forward "^<3" (point-max) t)
457         (beginning-of-line)
458         (insert "@c ")
459         (forward-line 1)
460         (while list
461           (and d2t-verbose (message "    %s ..." (car list)))
462           (setq file (concat d2t-terminal-directory (car list) ".trm"))
463           (when (file-exists-p file)
464             (set-buffer d2t-terminal-buffer-name)
465             (erase-buffer)
466             (insert-file-contents file)
467             ;; find the terminal help
468             (when (search-forward "START_HELP" (point-max) "to_end")
469               (forward-line 1)
470               (delete-region (point-min) (point-marker))
471               (search-forward "END_HELP" (point-max) "to_end")
472               (beginning-of-line)
473               (delete-region (point-marker) (point-max))
474               ;; tidy up the terminal help content
475               (goto-char (point-min))
476               (while (re-search-forward "\",[ \t]*$" nil t)
477                 (replace-match "" nil nil))
478               (goto-char (point-min))
479               (while (re-search-forward "^\"" nil t)
480                 (replace-match "" nil nil))
481               (goto-char (point-min))
482               (while (re-search-forward "\\\\\"" nil t)
483                 (replace-match "\"" nil nil))
484               (goto-char (point-min))
485               (while (re-search-forward "^1[ \t]+\\(.+\\)$" nil t)
486                 (setq node   (match-string 1)
487                       marker (point-marker))
488                 (replace-match (concat "4  " node) nil nil))
489               (goto-char (point-min))
490               (while (re-search-forward "^2" nil t)
491                 (replace-match "5 " nil nil))
492               (goto-char (point-min))
493               ;; set up terminals index
494               (while (re-search-forward "^\?\\([^ ]+\\)$" nil t)
495                 (let ((word (match-string 1)))
496                   (unless (string-match "_\\|command-line-options" word)
497                     (setq d2t-terminals-alist
498                           (append d2t-terminals-alist
499                                   (list (cons word (point-marker))))))))
500               ;; and cram it into the doc buffer
501               (set-buffer d2t-work-buffer-name)
502               (insert-buffer-substring d2t-terminal-buffer-name)
503               ))
504           (setq list (cdr list))
505           )))))
506
507 ;;; functions for obtaining lists of nodes in the document
508
509 (defun d2t-get-levels ()
510   "Find positions of all nodes in the doc."
511   (and d2t-verbose (message "  Doing d2t-get-levels ..."))
512   (let ((list '("1" "2" "3" "4" "5")) str)
513     (while list
514       (setq str (concat "d2t-level-" (car list) "-alist"))
515       (and d2t-verbose (message "    %s ..." str))
516       (save-excursion
517         (while (not (eobp))
518           (when (re-search-forward (concat "^" (car list) " \\(.+\\)$")
519                                    (point-max) "to_end")
520             (beginning-of-line)
521             (set (intern str)
522                  (append (eval (intern str))
523                          (list (cons (match-string 1) (point-marker)))))
524             (forward-line 1))))
525       (setq list (cdr list)))))
526
527
528 (defun d2t-get-commands ()
529   "Find all commands in the doc."
530   (and d2t-verbose (message "  Doing d2t-get-commands ..."))
531   (save-excursion
532     (let ((alist d2t-level-1-alist) start end)
533       (while alist
534         (if (string= (caar alist) "Commands")
535             (setq start (cdar  alist) ;; location of "1 Commands"
536                   end   (cdadr alist) ;; location of next level 1 heading
537                   alist nil)
538           (setq alist (cdr alist))))
539       ;;(message "%S %S" start end)
540       (goto-char start)
541       (while (< (point) end)
542         (when (re-search-forward "^2 \\(.+\\)$" (point-max) "to_end")
543           (beginning-of-line)
544           (unless (> (point) end)
545             (setq d2t-commands-alist
546                   (append d2t-commands-alist
547                           (list (cons (match-string 1) (point-marker))))))
548           (forward-line 1))) )))
549
550 (defun d2t-get-set-show ()
551   "Find all set-show options in the doc."
552   (and d2t-verbose (message "  Doing d2t-get-set-show ..."))
553   (save-excursion
554     (let ((alist d2t-commands-alist) start end)
555       (while alist
556         (if (string= (caar alist) "set-show")
557             (setq start (cdar  alist) ;; location of "1 set-show"
558                   end   (cdadr alist) ;; location of next level 2 heading
559                   alist nil)
560           (setq alist (cdr alist))))
561       ;;(message "%S %S" start end)
562       (goto-char start)
563       (while (< (point) end)
564         (when (re-search-forward "^3 \\(.+\\)$" (point-max) "to_end")
565           (beginning-of-line)
566           (unless (> (point) end)
567             (setq d2t-set-show-alist
568                   (append d2t-set-show-alist
569                           (list (cons (match-string 1) (point-marker))))))
570           (forward-line 1))) )))
571
572
573 (defun d2t-get-functions ()
574   "Find all functions in the doc."
575   (and d2t-verbose (message "  Doing d2t-get-functions ..."))
576   (let (begin end)
577     (save-excursion                     ; determine bounds of functions
578       (when (re-search-forward "^3 Functions" (point-max) "to_end")
579           (beginning-of-line)
580           (setq begin (point-marker))
581           (forward-line 1)
582           (when (re-search-forward "^3 " (point-max) "to_end")
583             (beginning-of-line)
584             (setq end (point-marker))))
585       (goto-char begin)
586       (while (< (point) end)
587         (when (re-search-forward "^4 \\(.+\\)$" (point-max) "to_end")
588           (beginning-of-line)
589           (unless (> (point) end)
590             (setq d2t-functions-alist
591                   (append d2t-functions-alist
592                           (list (cons (match-string 1) (point-marker))))))
593           (forward-line 1))) )))
594
595 ;; buffer manipulation functions
596
597 ;; this can probably be made faster using a let-scoped alist rather
598 ;; than the big cons block
599 (defun d2t-sectioning ()
600   "Find all lines starting with a number.
601 These are chapters, sections, etc.  Delete these lines and insert the
602 appropriate sectioning and @node commands."
603   (and d2t-verbose (message "  Doing d2t-sectioning ..."))
604   (save-excursion
605     (while (not (eobp))
606       (re-search-forward "^\\([1-9]\\) +\\(.+\\)$" (point-max) "to_end")
607       (unless (eobp)
608         (let* ((number (match-string 1))
609                (word (match-string 2))
610                (node (substitute ?_ ?  word :test 'char-equal))
611                (eol  (save-excursion (end-of-line) (point-marker))))
612           ;; some node names appear twice.  make the second one unique.
613           ;; this will fail to work if a third pops up in the future!
614           (if (member* node d2t-node-list :test 'string=)
615               (setq node (concat node "_")))
616           (setq d2t-node-list (append d2t-node-list (list node)))
617           (beginning-of-line)
618           (delete-region (point-marker) eol)
619           (if (string-match "[1-4]" number) (insert "\n@node " node "\n"))
620           (cond ((string= number "1")
621                  (insert "@chapter " word "\n"))
622                 ((string= number "2")
623                  (insert "@section " word "\n"))
624                 ((string= number "3")
625                  (insert "@subsection " word "\n"))
626                 ((string= number "4")
627                  (insert "@subsubsection " word "\n"))
628                 (t
629                  (insert "\n\n@noindent --- " (upcase word) " ---\n")) ) )))))
630
631 (defun d2t-indexing ()
632   "Find all lines starting with a question mark.
633 These are index references.  Delete these lines and insert the
634 appropriate indexing commands.  Only index one word ? entries,
635 comment out the multi-word ? entries."
636   (and d2t-verbose (message "  Doing d2t-indexing ..."))
637   (save-excursion
638     (while (not (eobp))
639       (re-search-forward "^\\(\\\?\\([^ \n]+\\)\\|=\\([^\n]+\\)\\) *$" 
640                          (point-max) "to_end")
641       (unless (eobp)
642         (let ((word (or (match-string 2) (match-string 3)))
643               (eol  (save-excursion (end-of-line) (point-marker))))
644           (beginning-of-line)
645           (delete-region (point-marker) eol)
646           (insert "@cindex " word "\n")
647           (cond ((assoc word d2t-commands-alist)
648                  (insert "@cmindex " word "\n\n"))
649                 ((assoc word d2t-set-show-alist)
650                  (insert "@opindex " word "\n\n"))
651                 ((assoc word d2t-terminals-alist)
652                  (insert "@tmindex " word "\n\n"))
653                 ((assoc word d2t-functions-alist)
654                  (insert "@findex " word "\n\n"))) )))
655     (goto-char (point-min))
656     (while (not (eobp))
657       (re-search-forward "^\\\?" (point-max) "to_end")
658       (unless (eobp)
659         (if (looking-at "functions? \\(tm_\\w+\\)")
660             (progn
661               (beginning-of-line)
662               (insert "@findex " (match-string 1) "\n@c "))
663           (beginning-of-line)
664           (insert "@c ")))) ))
665
666 (defun d2t-comments ()
667   "Delete comments and lines beginning with # or %.
668 # and % lines are used in converting tables into various formats."
669   (and d2t-verbose (message "  Doing d2t-comments ..."))
670   (save-excursion
671     (while (not (eobp))
672       (re-search-forward "^[C#%]" (point-max) "to_end")
673       (unless (eobp)
674         (let ((eol  (save-excursion (end-of-line)
675                                     (forward-char 1)
676                                     (point-marker))))
677           (beginning-of-line)
678           (delete-region (point-marker) eol) )))))
679
680 (defun d2t-first-column ()
681   "Justify normal text to the 0th column.
682 This must be run before `d2t-enclose-examples'.
683 This is rather slow since there are almost 9000 lines of text."
684   (and d2t-verbose (message "  Doing d2t-first-column ..."))
685   (save-excursion
686     (while (not (eobp))
687       (and (char-equal (char-after (point)) ? )
688            (delete-char 1))
689       (forward-line))))
690
691 (defun d2t-braces-atsigns ()
692   "Prepend @ to @, {, or } everywhere in the doc.
693 This MUST be the first conversion function called in
694 `d2t-doc-to-texi'."
695   (and d2t-verbose (message "  Doing d2t-braces-atsigns ..."))
696   (save-excursion
697     (while (not (eobp))
698       (re-search-forward "[@{}]" (point-max) "to_end")
699       (unless (eobp)
700         (backward-char 1)
701         (insert "@")
702         (forward-char 1)))))
703
704 (defun d2t-tables ()
705   "Remove @start table and @end table tags.
706 These will be made into @example's by `d2t-enclose-examples'.
707 Thus, the plain text formatting already in the doc is used."
708   (and d2t-verbose (message "  Doing d2t-tables ..."))
709   (save-excursion
710     (while (not (eobp))
711       (re-search-forward "^ *@+start table" (point-max) "to_end")
712       (unless (eobp)
713         (let ((eol  (save-excursion (end-of-line) (point-marker))))
714           (beginning-of-line)
715           (delete-region (point-marker) eol))))
716           ;;(insert "@example")
717     (goto-char (point-min))
718     (while (not (eobp))
719       (re-search-forward "^ *@+end table" (point-max) "to_end")
720       (unless (eobp)
721         (let ((eol  (save-excursion (end-of-line) (point-marker))))
722           (beginning-of-line)
723           (delete-region (point-marker) eol))))))
724           ;;(insert "@end example")
725
726
727 (defun d2t-enclose-examples ()
728   "Turn indented text in the doc into @examples.
729 This must be run after `d2t-first-column'."
730   (and d2t-verbose (message "  Doing d2t-enclose-examples ..."))
731   (save-excursion
732     (while (not (eobp))
733       (re-search-forward "^ +[^ \n]" (point-max) "to_end")
734       (unless (eobp)
735         (beginning-of-line)
736         (insert "@example\n")
737         (forward-line 1)
738         (re-search-forward "^[^ ]" (point-max) "to_end")
739         (beginning-of-line)
740         (insert "@end example\n\n") ))))
741
742 (defun d2t-handle-html ()
743   "Deal with all of the html markup in the doc."
744   (and d2t-verbose (message "  Doing d2t-handle-html ..."))
745   (save-excursion
746     (while (not (eobp))
747       (let ((rx (concat "^" (regexp-quote "^")
748                         " *\\(<?\\)\\([^ \n]+\\)" )))
749         (re-search-forward rx (point-max) "to_end")
750         (unless (eobp)
751           (let ((bracket (match-string 1))
752                 (tag (match-string 2))
753                 (eol  (save-excursion (end-of-line) (point-marker))))
754             (beginning-of-line)
755             (cond
756              ;; comment out images
757              ((and (string= bracket "<") (string= tag "img"))
758               (insert "@c "))
759              ;; tyepset anchors
760              ((and (string= bracket "<") (string-match "^/?a" tag))
761               ;(insert "@c fix me!!  ")
762               (beginning-of-line)
763               (if (looking-at (concat "\\^\\s-*<a\\s-+href=" ; opening tag
764                                       "\"\\([^\"]+\\)\">\\s-*\n*\\s-*" ; url
765                                       "\\([^<]+\\)" ; text
766                                       "[ \t]*\\^?</a>" ; closing tag
767                                       ))
768                   (replace-match (concat "@uref{"
769                                          (match-string 1)
770                                          ","
771                                          (remove* ?^ (match-string 2)
772                                                   :test 'char-equal)
773                                          "}"))
774                   (insert "@c ")))
775              ;; translate <ul> </ul> to @itemize environment
776              ((and (string= bracket "<") (string-match "^ul" tag))
777               (delete-region (point) eol)
778               (insert "\n@itemize @bullet"))
779              ((and (string= bracket "<") (string-match "/ul" tag))
780               (delete-region (point) eol)
781               (insert "@end itemize\n"))
782              ;; list items
783              ((and (string= bracket "<") (string-match "^li" tag))
784               (delete-char 5)
785               (delete-horizontal-space)
786               (insert "@item\n"))
787              ;; fix up a few miscellaneous things
788              (t ;;(looking-at ".*Terminal Types")
789               (insert "@c ")) )
790             (forward-line))) ))))
791
792
793 (defvar d2t-dont-make-ref
794   "^fit f\(x\)\\|gnuplot\\|help\\s-+plotting")
795 (defun d2t-make-refs ()
796   "Make cross-references in the text."
797   (and d2t-verbose (message "  Doing d2t-make-refs ..."))
798   (let ((big-alist (append d2t-level-1-alist
799                            d2t-level-2-alist
800                            d2t-level-3-alist
801                            d2t-level-4-alist)))
802     (save-excursion
803       (while (not (eobp))
804         (re-search-forward "\\(`\\([^`]+\\)`\\)" (point-max) "to_end")
805         (unless (eobp)
806           (let* ((b (match-beginning 1))
807                  (e (match-end 1))
808                  (list (split-string (match-string 2)))
809                  (last (car (reverse list)))
810                  (text (concat "@ref{" last "}")))
811             ;;(message "%s %s" (match-string 1) last)
812             (when (and (equal t (try-completion last big-alist))
813                        (not (string= last "gnuplot")))
814               (delete-region b e)
815               (insert text))))
816         ))))
817
818 ;;; doc2texi.el ends here