Merge from emacs--rel--22
[bpt/emacs.git] / lisp / textmodes / texinfmt.el
1 ;;; texinfmt.el --- format Texinfo files into Info files
2
3 ;; Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993,
4 ;; 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003,
5 ;; 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
6
7 ;; Maintainer: Robert J. Chassell <bug-texinfo@gnu.org>
8 ;; Keywords: maint, tex, docs
9
10 ;; This file is part of GNU Emacs.
11
12 ;; GNU Emacs is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; any later version.
16
17 ;; GNU Emacs is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the
24 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02110-1301, USA.
26
27 ;;; Commentary:
28
29 ;;; Code:
30
31 ;;; Emacs lisp functions to convert Texinfo files to Info files.
32
33 (or (fboundp 'defgroup)
34 (defmacro defgroup (&rest ignore) nil))
35
36 (or (fboundp 'defcustom)
37 (defmacro defcustom (var value doc &rest ignore)
38 `(defvar ,var ,value ,doc)))
39
40 (defvar texinfmt-version "2.42 of 7 Jul 2006")
41
42 (defun texinfmt-version (&optional here)
43 "Show the version of texinfmt.el in the minibuffer.
44 If optional argument HERE is non-nil, insert info at point."
45 (interactive "P")
46 (let ((version-string
47 (format "Version of \`texinfmt.el\': %s" texinfmt-version)))
48 (if here
49 (insert version-string)
50 (if (interactive-p)
51 (message "%s" version-string)
52 version-string))))
53
54 \f
55 ;;; Variable definitions
56
57 (require 'texinfo) ; So `texinfo-footnote-style' is defined.
58 (require 'texnfo-upd) ; So `texinfo-section-types-regexp' is defined.
59
60 (defvar texinfo-vindex)
61 (defvar texinfo-findex)
62 (defvar texinfo-cindex)
63 (defvar texinfo-pindex)
64 (defvar texinfo-tindex)
65 (defvar texinfo-kindex)
66 (defvar texinfo-last-node)
67 (defvar texinfo-node-names)
68 (defvar texinfo-enclosure-list)
69 (defvar texinfo-alias-list)
70 (defvar texinfo-fold-nodename-case nil)
71
72 (defvar texinfo-command-start)
73 (defvar texinfo-command-end)
74 (defvar texinfo-command-name)
75 (defvar texinfo-defun-type)
76 (defvar texinfo-last-node-pos)
77 (defvar texinfo-stack)
78 (defvar texinfo-short-index-cmds-alist)
79 (defvar texinfo-short-index-format-cmds-alist)
80 (defvar texinfo-format-filename)
81 (defvar texinfo-footnote-number)
82
83 (defvar texinfo-raisesections-alist
84 '((@chapter . @chapter) ; Cannot go higher
85 (@unnumbered . @unnumbered)
86 (@centerchap . @unnumbered)
87
88 (@majorheading . @majorheading)
89 (@chapheading . @chapheading)
90 (@appendix . @appendix)
91
92 (@section . @chapter)
93 (@unnumberedsec . @unnumbered)
94 (@heading . @chapheading)
95 (@appendixsec . @appendix)
96
97 (@subsection . @section)
98 (@unnumberedsubsec . @unnumberedsec)
99 (@subheading . @heading)
100 (@appendixsubsec . @appendixsec)
101
102 (@subsubsection . @subsection)
103 (@unnumberedsubsubsec . @unnumberedsubsec)
104 (@subsubheading . @subheading)
105 (@appendixsubsubsec . @appendixsubsec))
106 "*An alist of next higher levels for chapters, sections, etc...
107 For example, section to chapter, subsection to section.
108 Used by `texinfo-raise-lower-sections'.
109 The keys specify types of section; the values correspond to the next
110 higher types.")
111
112 (defvar texinfo-lowersections-alist
113 '((@chapter . @section)
114 (@unnumbered . @unnumberedsec)
115 (@centerchap . @unnumberedsec)
116 (@majorheading . @heading)
117 (@chapheading . @heading)
118 (@appendix . @appendixsec)
119
120 (@section . @subsection)
121 (@unnumberedsec . @unnumberedsubsec)
122 (@heading . @subheading)
123 (@appendixsec . @appendixsubsec)
124
125 (@subsection . @subsubsection)
126 (@unnumberedsubsec . @unnumberedsubsubsec)
127 (@subheading . @subsubheading)
128 (@appendixsubsec . @appendixsubsubsec)
129
130 (@subsubsection . @subsubsection) ; Cannot go lower.
131 (@unnumberedsubsubsec . @unnumberedsubsubsec)
132 (@subsubheading . @subsubheading)
133 (@appendixsubsubsec . @appendixsubsubsec))
134 "*An alist of next lower levels for chapters, sections, etc...
135 For example, chapter to section, section to subsection.
136 Used by `texinfo-raise-lower-sections'.
137 The keys specify types of section; the values correspond to the next
138 lower types.")
139 \f
140 ;;; Syntax table
141
142 (defvar texinfo-format-syntax-table
143 (let ((st (make-syntax-table)))
144 (modify-syntax-entry ?\" " " st)
145 (modify-syntax-entry ?\\ " " st)
146 (modify-syntax-entry ?@ "\\" st)
147 (modify-syntax-entry ?\^q "\\" st)
148 (modify-syntax-entry ?\[ "." st)
149 (modify-syntax-entry ?\] "." st)
150 (modify-syntax-entry ?\( "." st)
151 (modify-syntax-entry ?\) "." st)
152 (modify-syntax-entry ?{ "(}" st)
153 (modify-syntax-entry ?} "){" st)
154 (modify-syntax-entry ?\' "." st)
155 st))
156
157 \f
158 ;;; Top level buffer and region formatting functions
159
160 ;;;###autoload
161 (defun texinfo-format-buffer (&optional nosplit)
162 "Process the current buffer as texinfo code, into an Info file.
163 The Info file output is generated in a buffer visiting the Info file
164 name specified in the @setfilename command.
165
166 Non-nil argument (prefix, if interactive) means don't make tag table
167 and don't split the file if large. You can use `Info-tagify' and
168 `Info-split' to do these manually."
169 (interactive "P")
170 (let ((lastmessage "Formatting Info file...")
171 (coding-system-for-write buffer-file-coding-system))
172 (message lastmessage)
173 (widen)
174 (texinfo-format-buffer-1)
175 (Info-tagify)
176 (if nosplit
177 nil
178 (if (> (buffer-size) 100000)
179 (progn
180 (message (setq lastmessage "Splitting Info file..."))
181 (Info-split))))
182 (message (concat lastmessage
183 (if (interactive-p) "done. Now save it." "done.")))))
184
185 (defvar texinfo-region-buffer-name "*Info Region*"
186 "*Name of the temporary buffer used by \\[texinfo-format-region].")
187
188 (defvar texinfo-pre-format-hook nil
189 "Hook called before the conversion of the Texinfo file to Info format.
190 The functions on this hook are called with argument BUFFER, the buffer
191 containing the Texinfo file.")
192
193 ;; These come from tex-mode.el.
194 (defvar tex-start-of-header)
195 (defvar tex-end-of-header)
196
197 ;;;###autoload
198 (defun texinfo-format-region (region-beginning region-end)
199 "Convert the current region of the Texinfo file to Info format.
200 This lets you see what that part of the file will look like in Info.
201 The command is bound to \\[texinfo-format-region]. The text that is
202 converted to Info is stored in a temporary buffer."
203 (interactive "r")
204 (message "Converting region to Info format...")
205 (let (texinfo-command-start
206 texinfo-command-end
207 texinfo-command-name
208 texinfo-vindex
209 texinfo-findex
210 texinfo-cindex
211 texinfo-pindex
212 texinfo-tindex
213 texinfo-kindex
214 texinfo-stack
215 (texinfo-format-filename "")
216 texinfo-example-start
217 texinfo-last-node-pos
218 texinfo-last-node
219 texinfo-node-names
220 (texinfo-footnote-number 0)
221 last-input-buffer
222 (fill-column-for-info fill-column)
223 (input-buffer (current-buffer))
224 (input-directory default-directory)
225 (header-text "")
226 (header-beginning 1)
227 (header-end 1))
228
229 ;;; Copy lines between beginning and end of header lines,
230 ;;; if any, or else copy the `@setfilename' line, if any.
231 (save-excursion
232 (save-restriction
233 (widen)
234 (goto-char (point-min))
235 (let ((search-end (save-excursion (forward-line 100) (point))))
236 (if (or
237 ;; Either copy header text.
238 (and
239 (prog1
240 (search-forward tex-start-of-header search-end t)
241 (forward-line 1)
242 ;; Mark beginning of header.
243 (setq header-beginning (point)))
244 (prog1
245 (search-forward tex-end-of-header nil t)
246 (beginning-of-line)
247 ;; Mark end of header
248 (setq header-end (point))))
249 ;; Or copy @filename line.
250 (prog2
251 (goto-char (point-min))
252 (search-forward "@setfilename" search-end t)
253 (beginning-of-line)
254 (setq header-beginning (point))
255 (forward-line 1)
256 (setq header-end (point))))
257
258 ;; Copy header
259 (setq header-text
260 (buffer-substring-no-properties
261 (min header-beginning region-beginning)
262 header-end))))))
263
264 ;;; Find a buffer to use.
265 (switch-to-buffer (get-buffer-create texinfo-region-buffer-name))
266 (setq buffer-read-only t)
267 (let ((inhibit-read-only t))
268 (erase-buffer)
269 ;; Insert the header into the buffer.
270 (insert header-text)
271 ;; Insert the region into the buffer.
272 (insert-buffer-substring
273 input-buffer
274 (max region-beginning header-end)
275 region-end)
276 (run-hook-with-args 'texinfo-pre-format-hook input-buffer)
277 ;; Make sure region ends in a newline.
278 (or (= (preceding-char) ?\n)
279 (insert "\n"))
280
281 (goto-char (point-min))
282 (texinfo-mode)
283 (message "Converting region to Info format...")
284 (setq fill-column fill-column-for-info)
285 ;; Install a syntax table useful for scanning command operands.
286 (set-syntax-table texinfo-format-syntax-table)
287
288 ;; Insert @include files so `texinfo-raise-lower-sections' can
289 ;; work on them without losing track of multiple
290 ;; @raise/@lowersections commands.
291 (while (re-search-forward "^@include" nil t)
292 (setq texinfo-command-end (point))
293 (let ((filename (concat input-directory
294 (texinfo-parse-line-arg))))
295 (re-search-backward "^@include")
296 (delete-region (point) (save-excursion (forward-line 1) (point)))
297 (message "Reading included file: %s" filename)
298 (save-excursion
299 (save-restriction
300 (narrow-to-region
301 (point)
302 (+ (point) (car (cdr (insert-file-contents filename)))))
303 (goto-char (point-min))
304 ;; Remove `@setfilename' line from included file, if any,
305 ;; so @setfilename command not duplicated.
306 (if (re-search-forward "^@setfilename" (line-end-position 100) t)
307 (delete-region (line-beginning-position 1)
308 (line-beginning-position 2)))))))
309
310 ;; Raise or lower level of each section, if necessary.
311 (goto-char (point-min))
312 (texinfo-raise-lower-sections)
313 ;; Append @refill to appropriate paragraphs for filling.
314 (goto-char (point-min))
315 (texinfo-append-refill)
316 ;; If the region includes the effective end of the data,
317 ;; discard everything after that.
318 (goto-char (point-max))
319 (if (re-search-backward "^@bye" nil t)
320 (delete-region (point) (point-max)))
321 ;; Make sure buffer ends in a newline.
322 (or (= (preceding-char) ?\n)
323 (insert "\n"))
324 ;; Don't use a previous value of texinfo-enclosure-list.
325 (setq texinfo-enclosure-list nil)
326 (setq texinfo-alias-list nil)
327
328 (goto-char (point-min))
329 (if (looking-at "\\\\input[ \t]+texinfo")
330 (delete-region (point) (line-beginning-position 2)))
331
332 ;; Insert Info region title text.
333 (goto-char (point-min))
334 (if (search-forward
335 "@setfilename" (save-excursion (forward-line 100) (point)) t)
336 (progn
337 (setq texinfo-command-end (point))
338 (beginning-of-line)
339 (setq texinfo-command-start (point))
340 (let ((arg (texinfo-parse-arg-discard)))
341 (insert " "
342 texinfo-region-buffer-name
343 " buffer for: `")
344 (insert (file-name-nondirectory (expand-file-name arg)))
345 (insert "', -*-Text-*-\n")))
346 ;; Else no `@setfilename' line
347 (insert " "
348 texinfo-region-buffer-name
349 " buffer -*-Text-*-\n"))
350 (insert "produced by `texinfo-format-region'\n"
351 "from a region in: "
352 (if (buffer-file-name input-buffer)
353 (concat "`"
354 (file-name-sans-versions
355 (file-name-nondirectory
356 (buffer-file-name input-buffer)))
357 "'")
358 (concat "buffer `" (buffer-name input-buffer) "'"))
359 "\nusing `texinfmt.el' version "
360 texinfmt-version
361 ".\n\n")
362
363 ;; Now convert for real.
364 (goto-char (point-min))
365 (texinfo-format-scan)
366 (goto-char (point-min))
367 (Info-tagify input-buffer)
368 (goto-char (point-min))
369 (message "Done."))))
370
371 ;;;###autoload
372 (defun texi2info (&optional nosplit)
373 "Convert the current buffer (written in Texinfo code) into an Info file.
374 The Info file output is generated in a buffer visiting the Info file
375 names specified in the @setfilename command.
376
377 This function automatically updates all node pointers and menus, and
378 creates a master menu. This work is done on a temporary buffer that
379 is automatically removed when the Info file is created. The original
380 Texinfo source buffer is not changed.
381
382 Non-nil argument (prefix, if interactive) means don't split the file
383 if large. You can use `Info-split' to do this manually."
384 (interactive "P")
385 (let ((temp-buffer (concat "*--" (buffer-name) "--temporary-buffer*" )))
386 (message "First updating nodes and menus, then creating Info file.")
387 ;; (sit-for 2)
388 (copy-to-buffer temp-buffer (point-min) (point-max))
389 (switch-to-buffer temp-buffer)
390 (texinfo-master-menu t)
391 (message "Now creating Info file.")
392 (sit-for 2)
393 (texinfo-format-buffer nosplit)
394 (save-buffer)
395 (kill-buffer temp-buffer)))
396
397 \f
398 ;;; Primary internal formatting function for the whole buffer.
399
400 (defun texinfo-format-buffer-1 ()
401 (let (texinfo-format-filename
402 texinfo-example-start
403 texinfo-command-start
404 texinfo-command-end
405 texinfo-command-name
406 texinfo-last-node
407 texinfo-last-node-pos
408 texinfo-vindex
409 texinfo-findex
410 texinfo-cindex
411 texinfo-pindex
412 texinfo-tindex
413 texinfo-kindex
414 texinfo-stack
415 texinfo-node-names
416 (texinfo-footnote-number 0)
417 last-input-buffer
418 outfile
419 (fill-column-for-info fill-column)
420 (input-buffer (current-buffer))
421 (input-directory default-directory))
422 (setq texinfo-enclosure-list nil)
423 (setq texinfo-alias-list nil)
424 (save-excursion
425 (goto-char (point-min))
426 (or (search-forward "@setfilename" nil t)
427 (error "Texinfo file needs an `@setfilename FILENAME' line"))
428 (setq texinfo-command-end (point))
429 (setq outfile (texinfo-parse-line-arg)))
430
431 (find-file outfile)
432 (texinfo-mode)
433 (erase-buffer)
434 (buffer-disable-undo)
435
436 (message "Formatting Info file: %s" outfile)
437 (setq texinfo-format-filename
438 (file-name-nondirectory (expand-file-name outfile)))
439
440 (setq fill-column fill-column-for-info)
441 (set-syntax-table texinfo-format-syntax-table)
442
443 (insert-buffer-substring input-buffer)
444 (run-hook-with-args 'texinfo-pre-format-hook input-buffer)
445 (message "Converting %s to Info format..." (buffer-name input-buffer))
446
447 ;; Insert @include files so `texinfo-raise-lower-sections' can
448 ;; work on them without losing track of multiple
449 ;; @raise/@lowersections commands.
450 (goto-char (point-min))
451 (while (re-search-forward "^@include" nil t)
452 (setq texinfo-command-end (point))
453 (let ((filename (concat input-directory
454 (texinfo-parse-line-arg))))
455 (re-search-backward "^@include")
456 (delete-region (point) (line-beginning-position 2))
457 (message "Reading included file: %s" filename)
458 (save-excursion
459 (save-restriction
460 (narrow-to-region
461 (point)
462 (+ (point) (car (cdr (insert-file-contents filename)))))
463 (goto-char (point-min))
464 ;; Remove `@setfilename' line from included file, if any,
465 ;; so @setfilename command not duplicated.
466 (if (re-search-forward "^@setfilename" (line-end-position 100) t)
467 (delete-region (line-beginning-position 1)
468 (line-beginning-position 2)))))))
469 ;; Raise or lower level of each section, if necessary.
470 (goto-char (point-min))
471 (texinfo-raise-lower-sections)
472 ;; Append @refill to appropriate paragraphs
473 (goto-char (point-min))
474 (texinfo-append-refill)
475 (goto-char (point-min))
476 (search-forward "@setfilename")
477 (beginning-of-line)
478 (delete-region (point-min) (point))
479 ;; Remove @bye at end of file, if it is there.
480 (goto-char (point-max))
481 (if (search-backward "@bye" nil t)
482 (delete-region (point) (point-max)))
483 ;; Make sure buffer ends in a newline.
484 (or (= (preceding-char) ?\n)
485 (insert "\n"))
486 ;; Scan the whole buffer, converting to Info format.
487 (texinfo-format-scan)
488 (goto-char (point-min))
489 ;; Insert info about how this file was made.
490 (insert "Info file: "
491 texinfo-format-filename ", -*-Text-*-\n"
492 "produced by `texinfo-format-buffer'\n"
493 ;; Date string removed so that regression testing is easier.
494 ;; "on "
495 ;; (insert (format-time-string "%e %b %Y")) " "
496 "from file"
497 (if (buffer-file-name input-buffer)
498 (concat " `"
499 (file-name-sans-versions
500 (file-name-nondirectory
501 (buffer-file-name input-buffer)))
502 "'")
503 (concat "buffer `" (buffer-name input-buffer) "'"))
504 "\nusing `texinfmt.el' version "
505 texinfmt-version
506 ".\n\n")
507 ;; Return data for indices.
508 (list outfile
509 texinfo-vindex texinfo-findex texinfo-cindex
510 texinfo-pindex texinfo-tindex texinfo-kindex)))
511
512 \f
513 ;;; Perform non-@-command file conversions: quotes and hyphens
514
515 (defun texinfo-format-convert (min max)
516 ;; Convert left and right quotes to typewriter font quotes.
517 (goto-char min)
518 (while (search-forward "``" max t)
519 (replace-match "\""))
520 (goto-char min)
521 (while (search-forward "''" max t)
522 (replace-match "\""))
523 ;; Convert three hyphens in a row to two.
524 (goto-char min)
525 (while (re-search-forward "\\( \\|\\w\\)\\(---\\)\\( \\|\\w\\)" max t)
526 (delete-region (1+ (match-beginning 2)) (+ 2 (match-beginning 2)))))
527
528 \f
529 ;;; Handle paragraph filling
530
531 ;; Keep as concatinated lists for ease of maintenance
532
533 (defvar texinfo-no-refill-regexp
534 (concat
535 "^@"
536 "\\("
537 ;; add "itemize\\|" (from experiment of 2001 Nov 28)
538 ;; because of a problem with @end itemize@refill
539 ;; I don't know if this causes other problems.
540 ;; I suspect itemized lists don't get filled properly and a
541 ;; more precise fix is required. Bob
542 ;; commented out on 2005 Feb 28 by Bob
543 ;; "itemize\\|"
544 "direntry\\|"
545 "lisp\\|"
546 "smalllisp\\|"
547 "example\\|"
548 "smallexample\\|"
549 "display\\|"
550 "smalldisplay\\|"
551 "format\\|"
552 "smallformat\\|"
553 "flushleft\\|"
554 "flushright\\|"
555 "menu\\|"
556 "multitable\\|"
557 "titlepage\\|"
558 "iftex\\|"
559 "ifhtml\\|"
560 "tex\\|"
561 "html"
562 "\\)")
563 "Regexp specifying environments in which paragraphs are not filled.")
564
565 (defvar texinfo-accent-commands
566 (concat
567 "@^\\|"
568 "@`\\|"
569 "@'\\|"
570 "@\"\\|"
571 "@,\\|"
572 "@=\\|"
573 "@~\\|"
574 "@OE{\\|"
575 "@oe{\\|"
576 "@AA{\\|"
577 "@aa{\\|"
578 "@AE{\\|"
579 "@ae{\\|"
580 "@ss{\\|"
581 "@questiondown{\\|"
582 "@exclamdown{\\|"
583 "@L{\\|"
584 "@l{\\|"
585 "@O{\\|"
586 "@o{\\|"
587 "@dotaccent{\\|"
588 "@ubaraccent{\\|"
589 "@d{\\|"
590 "@H{\\|"
591 "@ringaccent{\\|"
592 "@tieaccent{\\|"
593 "@u{\\|"
594 "@v{\\|"
595 "@dotless{"
596 ))
597
598 (defvar texinfo-part-of-para-regexp
599 (concat
600 "^@"
601 "\\("
602 "b{\\|"
603 "bullet{\\|"
604 "cite{\\|"
605 "code{\\|"
606 "email{\\|"
607 "emph{\\|"
608 "equiv{\\|"
609 "error{\\|"
610 "expansion{\\|"
611 "file{\\|"
612 "i{\\|"
613 "inforef{\\|"
614 "kbd{\\|"
615 "key{\\|"
616 "lisp{\\|"
617 "minus{\\|"
618 "point{\\|"
619 "print{\\|"
620 "pxref{\\|"
621 "r{\\|"
622 "ref{\\|"
623 "result{\\|"
624 "samp{\\|"
625 "sc{\\|"
626 "t{\\|"
627 "TeX{\\|"
628 "today{\\|"
629 "url{\\|"
630 "var{\\|"
631 "w{\\|"
632 "xref{\\|"
633 "@-\\|" ; @- is a descretionary hyphen (not an accent) (a noop).
634 texinfo-accent-commands
635 "\\)"
636 )
637 "Regexp specifying @-commands found within paragraphs.")
638
639 (defun texinfo-append-refill ()
640 "Append @refill at end of each paragraph that should be filled.
641 Do not append @refill to paragraphs within @example and similar environments.
642 Do not append @refill to paragraphs containing @w{TEXT} or @*."
643
644 ;; It is necessary to append @refill before other processing because
645 ;; the other processing removes information that tells Texinfo
646 ;; whether the text should or should not be filled.
647
648 (while (< (point) (point-max))
649 (let ((refill-blank-lines "^[ \t\n]*$")
650 (case-fold-search nil)) ; Don't confuse @TeX and @tex....
651 (beginning-of-line)
652 ;; 1. Skip over blank lines;
653 ;; skip over lines beginning with @-commands,
654 ;; but do not skip over lines
655 ;; that are no-refill environments such as @example or
656 ;; that begin with within-paragraph @-commands such as @code.
657 (while (and (looking-at (concat "^@\\|^\\\\\\|" refill-blank-lines))
658 (not (looking-at
659 (concat
660 "\\("
661 texinfo-no-refill-regexp
662 "\\|"
663 texinfo-part-of-para-regexp
664 "\\)")))
665 (< (point) (point-max)))
666 (forward-line 1))
667 ;; 2. Skip over @example and similar no-refill environments.
668 (if (looking-at texinfo-no-refill-regexp)
669 (let ((environment (match-string-no-properties 1)))
670 (progn (re-search-forward (concat "^@end " environment) nil t)
671 (forward-line 1)))
672 ;; Else
673 ;; 3. Do not refill a paragraph containing @w or @*, or ending
674 ;; with @<newline> followed by a newline.
675 (if (or (>= (point) (point-max))
676 (re-search-forward
677 "@w{\\|@\\*\\|@\n\n"
678 (save-excursion (forward-paragraph) (forward-line 1) (point))
679 t))
680 ;; Go to end of paragraph and do nothing.
681 (forward-paragraph)
682 ;; 4. Else go to end of paragraph and insert @refill
683 (forward-paragraph)
684 (forward-line -1)
685 (let ((line-beg (point)))
686 (end-of-line)
687 (delete-region
688 (point)
689 (save-excursion (skip-chars-backward " \t") (point)))
690 (forward-char 1)
691 (unless (re-search-backward "@c[ \t\n]\\|@comment[ \t\n]" line-beg t)
692 (forward-char -1))
693 (unless (re-search-backward "@refill\\|^[ \t]*@" line-beg t)
694 (insert "@refill")))
695 (forward-line 1))))))
696
697 \f
698 ;;; Handle `@raisesections' and `@lowersections' commands
699
700 ;; These commands change the hierarchical level of chapter structuring
701 ;; commands.
702 ;;
703 ;; @raisesections changes @subsection to @section,
704 ;; @section to @chapter,
705 ;; etc.
706 ;;
707 ;; @lowersections changes @chapter to @section
708 ;; @subsection to @subsubsection,
709 ;; etc.
710 ;;
711 ;; An @raisesections/@lowersections command changes only those
712 ;; structuring commands that follow the @raisesections/@lowersections
713 ;; command.
714 ;;
715 ;; Repeated @raisesections/@lowersections continue to raise or lower
716 ;; the heading level.
717 ;;
718 ;; An @lowersections command cancels an @raisesections command, and
719 ;; vice versa.
720 ;;
721 ;; You cannot raise or lower "beyond" chapters or subsubsections, but
722 ;; trying to do so does not elicit an error---you just get more
723 ;; headings that mean the same thing as you keep raising or lowering
724 ;; (for example, after a single @raisesections, both @chapter and
725 ;; @section produce chapter headings).
726
727 (defun texinfo-raise-lower-sections ()
728 "Raise or lower the hierarchical level of chapters, sections, etc.
729
730 This function acts according to `@raisesections' and `@lowersections'
731 commands in the Texinfo file.
732
733 For example, an `@lowersections' command is useful if you wish to
734 include what is written as an outer or standalone Texinfo file in
735 another Texinfo file as an inner, included file. The `@lowersections'
736 command changes chapters to sections, sections to subsections and so
737 on.
738
739 @raisesections changes @subsection to @section,
740 @section to @chapter,
741 @heading to @chapheading,
742 etc.
743
744 @lowersections changes @chapter to @section,
745 @subsection to @subsubsection,
746 @heading to @subheading,
747 etc.
748
749 An `@raisesections' or `@lowersections' command changes only those
750 structuring commands that follow the `@raisesections' or
751 `@lowersections' command.
752
753 An `@lowersections' command cancels an `@raisesections' command, and
754 vice versa.
755
756 Repeated use of the commands continue to raise or lower the hierarchical
757 level a step at a time.
758
759 An attempt to raise above `chapters' reproduces chapter commands; an
760 attempt to lower below subsubsections reproduces subsubsection
761 commands."
762
763 ;; `texinfo-section-types-regexp' is defined in `texnfo-upd.el';
764 ;; it is a regexp matching chapter, section, other headings
765 ;; (but not the top node).
766
767 (let (type (level 0))
768 (while
769 (re-search-forward
770 (concat
771 "\\(\\(^@\\(raise\\|lower\\)sections\\)\\|\\("
772 texinfo-section-types-regexp
773 "\\)\\)")
774 nil t)
775 (beginning-of-line)
776 (save-excursion (setq type (read (current-buffer))))
777 (cond
778
779 ;; 1. Increment level
780 ((eq type '@raisesections)
781 (setq level (1+ level))
782 (delete-region
783 (point) (save-excursion (forward-line 1) (point))))
784
785 ;; 2. Decrement level
786 ((eq type '@lowersections)
787 (setq level (1- level))
788 (delete-region
789 (point) (save-excursion (forward-line 1) (point))))
790
791 ;; Now handle structuring commands
792 ((cond
793
794 ;; 3. Raise level when positive
795 ((> level 0)
796 (let ((count level)
797 (new-level type))
798 (while (> count 0)
799 (setq new-level
800 (cdr (assq new-level texinfo-raisesections-alist)))
801 (setq count (1- count)))
802 (kill-word 1)
803 (insert (symbol-name new-level))))
804
805 ;; 4. Do nothing except move point when level is zero
806 ((= level 0) (forward-line 1))
807
808 ;; 5. Lower level when positive
809 ((< level 0)
810 (let ((count level)
811 (new-level type))
812 (while (< count 0)
813 (setq new-level
814 (cdr (assq new-level texinfo-lowersections-alist)))
815 (setq count (1+ count)))
816 (kill-word 1)
817 (insert (symbol-name new-level))))))))))
818 \f
819 ;;; Perform those texinfo-to-info conversions that apply to the whole input
820 ;;; uniformly.
821
822 (defun texinfo-format-scan ()
823 (texinfo-format-convert (point-min) (point-max))
824 ;; Search for @copying, which has to be first since the
825 ;; @insertcopying command then inserts the text elsewhere.
826 (goto-char (point-min))
827 (when (search-forward "@copying" nil t)
828 (texinfo-copying))
829 (while (search-forward "@insertcopying" nil t)
830 (delete-region (match-beginning 0) (match-end 0))
831
832 (texinfo-insertcopying))
833 ;; Scan for other @-commands.
834 (goto-char (point-min))
835 (while (search-forward "@" nil t)
836 ;;
837 ;; These are the single-character accent commands: @^ @` @' @" @= @~
838 ;; In Info, they are simply quoted and the @ deleted.
839 ;; Other single-character commands:
840 ;; @* forces a line break,
841 ;; @- is a discretionary hyphenation point; does nothing in Info.
842 ;; @<space>, @<tab>, @<newline> each produce a single space,
843 ;; unless followed by a newline.
844 ;;
845 ;; Old version 2.34 expression: (looking-at "[@{}^'` *\"?!]")
846 (if (looking-at "[@{}^'`\"=~ \t\n*?!-]")
847 ;; @*, causes a line break.
848 (cond
849 ;; @*, a line break
850 ((= (following-char) ?*)
851 ;; remove command
852 (delete-region (1- (point)) (1+ (point)))
853 ;; insert return if not at end of line;
854 ;; else line is already broken.
855 (if (not (= (following-char) ?\n))
856 (insert ?\n)))
857 ;; @-, deleted
858 ((= (following-char) ?-)
859 (delete-region (1- (point)) (1+ (point))))
860 ;; @<space>, @<tab>, @<newline>: produce a single space,
861 ;; unless followed by a newline.
862 ((= (following-char) ? )
863 (delete-region (1- (point)) (1+ (point)))
864 ;; insert single space if not at end of line;
865 ;; else line is already broken.
866 (if (not (= (following-char) ?\n))
867 (insert ? )))
868 ((= (following-char) ?\t)
869 (delete-region (1- (point)) (1+ (point)))
870 ;; insert single space if not at end of line;
871 ;; else line is already broken.
872 (if (not (= (following-char) ?\n))
873 (insert ? )))
874 ;; following char is a carriage return
875 ((= (following-char) ?\n)
876 ;; remove command
877 (delete-region (1- (point)) (1+ (point)))
878 ;; insert single space if not at end of line;
879 ;; else line is already broken.
880 (if (not (= (following-char) ?\n))
881 (insert ? )))
882 ;; Otherwise: the other characters are simply quoted. Delete the @.
883 (t
884 (delete-char -1)
885 ;; Be compatible with makeinfo: if @' and its ilk are
886 ;; followed by a @ without a brace, barf.
887 (if (looking-at "[\"'^`~=]")
888 (progn
889 (if (= (char-after (1+ (point))) ?@)
890 (error "Use braces to give a command as an argument to @%c"
891 (following-char)))
892 (forward-char 1)
893 ;; @' etc. can optionally accept their argument in
894 ;; braces (makeinfo supports that).
895 (when (looking-at "{")
896 (let ((start (point)))
897 (forward-list 1)
898 (delete-char -1)
899 (goto-char start)
900 (delete-char 1))))
901 (forward-char 1))))
902 ;; @ is followed by a command-word; find the end of the word.
903 (setq texinfo-command-start (1- (point)))
904 (if (= (char-syntax (following-char)) ?w)
905 (forward-word 1)
906 (forward-char 1))
907 (setq texinfo-command-end (point))
908 ;; Detect the case of two @-commands in a row;
909 ;; process just the first one.
910 (goto-char (1+ texinfo-command-start))
911 (skip-chars-forward "^@" texinfo-command-end)
912 (setq texinfo-command-end (point))
913 ;; Handle let aliasing
914 (setq texinfo-command-name
915 (let (trial
916 (cmdname
917 (buffer-substring-no-properties
918 (1+ texinfo-command-start) texinfo-command-end)))
919 (while (setq trial (assoc cmdname texinfo-alias-list))
920 (setq cmdname (cdr trial)))
921 (intern cmdname)))
922 ;; Call the handler for this command.
923 (let ((enclosure-type
924 (assoc
925 (symbol-name texinfo-command-name)
926 texinfo-enclosure-list)))
927 (if enclosure-type
928 (progn
929 (insert
930 (car (car (cdr enclosure-type)))
931 (texinfo-parse-arg-discard)
932 (car (cdr (car (cdr enclosure-type)))))
933 (goto-char texinfo-command-start))
934 (let ((cmd (get texinfo-command-name 'texinfo-format)))
935 (if cmd (funcall cmd) (texinfo-unsupported)))))))
936
937 (cond (texinfo-stack
938 (goto-char (nth 2 (car texinfo-stack)))
939 (error "Unterminated @%s" (car (car texinfo-stack)))))
940
941 ;; Remove excess whitespace
942 (let ((whitespace-silent t))
943 (whitespace-cleanup)))
944
945 (defvar texinfo-copying-text ""
946 "Text of the copyright notice and copying permissions.")
947
948 (defun texinfo-copying ()
949 "Copy the copyright notice and copying permissions from the Texinfo file,
950 as indicated by the @copying ... @end copying command;
951 insert the text with the @insertcopying command."
952 (let ((beg (progn (beginning-of-line) (point)))
953 (end (progn (re-search-forward "^@end copying[ \t]*\n") (point))))
954 (setq texinfo-copying-text
955 (buffer-substring-no-properties
956 (save-excursion (goto-char beg) (forward-line 1) (point))
957 (save-excursion (goto-char end) (forward-line -1) (point))))
958 (delete-region beg end)))
959
960 (defun texinfo-insertcopying ()
961 "Insert the copyright notice and copying permissions from the Texinfo file,
962 which are indicated by the @copying ... @end copying command."
963 (insert (concat "\n" texinfo-copying-text)))
964
965 (put 'begin 'texinfo-format 'texinfo-format-begin)
966 (defun texinfo-format-begin ()
967 (texinfo-format-begin-end 'texinfo-format))
968
969 (put 'end 'texinfo-format 'texinfo-format-end)
970 (defun texinfo-format-end ()
971 (texinfo-format-begin-end 'texinfo-end))
972
973 (defun texinfo-format-begin-end (prop)
974 (setq texinfo-command-name (intern (texinfo-parse-line-arg)))
975 (let ((cmd (get texinfo-command-name prop)))
976 (if cmd (funcall cmd)
977 (texinfo-unsupported))))
978 \f
979 ;;; Parsing functions
980
981 (defun texinfo-parse-line-arg ()
982 "Return argument of @-command as string.
983 Argument is separated from command either by a space or by a brace.
984 If a space, return rest of line, with beginning and ending white
985 space removed. If a brace, return string between braces.
986 Leave point after argument."
987 (goto-char texinfo-command-end)
988 (let ((start (point)))
989 (cond ((looking-at " ")
990 (skip-chars-forward " ")
991 (setq start (point))
992 (end-of-line)
993 (skip-chars-backward " ")
994 (delete-region (point) (progn (end-of-line) (point)))
995 (setq texinfo-command-end (1+ (point))))
996 ((looking-at "{")
997 (setq start (1+ (point)))
998 (forward-list 1)
999 (setq texinfo-command-end (point))
1000 (forward-char -1))
1001 (t
1002 (error "Invalid texinfo command arg format")))
1003 (prog1 (buffer-substring-no-properties start (point))
1004 (if (eolp) (forward-char 1)))))
1005
1006 (defun texinfo-parse-expanded-arg ()
1007 (goto-char texinfo-command-end)
1008 (let ((start (point))
1009 marker)
1010 (cond ((looking-at " ")
1011 (skip-chars-forward " ")
1012 (setq start (point))
1013 (end-of-line)
1014 (setq texinfo-command-end (1+ (point))))
1015 ((looking-at "{")
1016 (setq start (1+ (point)))
1017 (forward-list 1)
1018 (setq texinfo-command-end (point))
1019 (forward-char -1))
1020 (t
1021 (error "Invalid texinfo command arg format")))
1022 (setq marker (move-marker (make-marker) texinfo-command-end))
1023 (texinfo-format-expand-region start (point))
1024 (setq texinfo-command-end (marker-position marker))
1025 (move-marker marker nil)
1026 (prog1 (buffer-substring-no-properties start (point))
1027 (if (eolp) (forward-char 1)))))
1028
1029 (defun texinfo-format-expand-region (start end)
1030 (save-restriction
1031 (narrow-to-region start end)
1032 (let (texinfo-command-start
1033 texinfo-command-end
1034 texinfo-command-name
1035 texinfo-stack)
1036 (texinfo-format-scan))
1037 (goto-char (point-max))))
1038
1039 (defun texinfo-parse-arg-discard ()
1040 "Delete command and argument; return argument of command."
1041 (prog1 (texinfo-parse-line-arg)
1042 (texinfo-discard-command)))
1043
1044 (defun texinfo-discard-command ()
1045 (delete-region texinfo-command-start texinfo-command-end))
1046
1047 (defun texinfo-optional-braces-discard ()
1048 "Discard braces following command, if any."
1049 (goto-char texinfo-command-end)
1050 (let ((start (point)))
1051 (cond ((looking-at "[ \t]*\n")) ; do nothing
1052 ((looking-at "{") ; remove braces, if any
1053 (forward-list 1)
1054 (setq texinfo-command-end (point)))
1055 (t
1056 (error
1057 "Invalid `texinfo-optional-braces-discard' format \(need braces?\)")))
1058 (delete-region texinfo-command-start texinfo-command-end)))
1059
1060 (defun texinfo-format-parse-line-args ()
1061 (let ((start (1- (point)))
1062 next beg end
1063 args)
1064 (skip-chars-forward " ")
1065 (while (not (eolp))
1066 (setq beg (point))
1067 (re-search-forward "[\n,]")
1068 (setq next (point))
1069 (if (bolp) (setq next (1- next)))
1070 (forward-char -1)
1071 (skip-chars-backward " ")
1072 (setq end (point))
1073 (push (if (> end beg) (buffer-substring-no-properties beg end))
1074 args)
1075 (goto-char next)
1076 (skip-chars-forward " "))
1077 (if (eolp) (forward-char 1))
1078 (setq texinfo-command-end (point))
1079 (nreverse args)))
1080
1081 (defun texinfo-format-parse-args ()
1082 (let ((start (1- (point)))
1083 next beg end
1084 args)
1085 (search-forward "{")
1086 (save-excursion
1087 (texinfo-format-expand-region
1088 (point)
1089 (save-excursion (up-list 1) (1- (point)))))
1090 ;; The following does not handle cross references of the form:
1091 ;; `@xref{bullet, , @code{@@bullet}@{@}}.' because the
1092 ;; re-search-forward finds the first right brace after the second
1093 ;; comma.
1094 (while (/= (preceding-char) ?\})
1095 (skip-chars-forward " \t\n")
1096 (setq beg (point))
1097 (re-search-forward "[},]")
1098 (setq next (point))
1099 (forward-char -1)
1100 (skip-chars-backward " \t\n")
1101 (setq end (point))
1102 (cond ((< beg end)
1103 (goto-char beg)
1104 (while (search-forward "\n" end t)
1105 (replace-match " "))))
1106 (push (if (> end beg) (buffer-substring-no-properties beg end))
1107 args)
1108 (goto-char next))
1109 ;;(if (eolp) (forward-char 1))
1110 (setq texinfo-command-end (point))
1111 (nreverse args)))
1112
1113 (defun texinfo-format-parse-defun-args ()
1114 (goto-char texinfo-command-end)
1115 (let ((start (point)))
1116 (end-of-line)
1117 (setq texinfo-command-end (1+ (point)))
1118 (let ((marker (move-marker (make-marker) texinfo-command-end)))
1119 (texinfo-format-expand-region start (point))
1120 (setq texinfo-command-end (marker-position marker))
1121 (move-marker marker nil))
1122 (goto-char start)
1123 (let ((args '())
1124 beg end)
1125 (skip-chars-forward " ")
1126 (while (not (eolp))
1127 (cond ((looking-at "{")
1128 (setq beg (1+ (point)))
1129 (forward-list 1)
1130 (setq end (1- (point))))
1131 (t
1132 (setq beg (point))
1133 (re-search-forward "[\n ]")
1134 (forward-char -1)
1135 (setq end (point))))
1136 (push (buffer-substring-no-properties beg end) args)
1137 (skip-chars-forward " "))
1138 (forward-char 1)
1139 (nreverse args))))
1140
1141 (defun texinfo-discard-line ()
1142 (goto-char texinfo-command-end)
1143 (skip-chars-forward " \t")
1144 (or (eolp)
1145 (error "Extraneous text at end of command line"))
1146 (goto-char texinfo-command-start)
1147 (or (bolp)
1148 (error "Extraneous text at beginning of command line"))
1149 (delete-region (point) (progn (forward-line 1) (point))))
1150
1151 (defun texinfo-discard-line-with-args ()
1152 (goto-char texinfo-command-start)
1153 (delete-region (point) (progn (forward-line 1) (point))))
1154
1155 \f
1156 ;;; @setfilename
1157
1158 ;; Only `texinfo-format-buffer' handles @setfilename with this
1159 ;; definition; `texinfo-format-region' handles @setfilename, if any,
1160 ;; specially.
1161 (put 'setfilename 'texinfo-format 'texinfo-format-setfilename)
1162 (defun texinfo-format-setfilename ()
1163 (texinfo-parse-arg-discard))
1164 \f
1165 ;;; @node, @menu, @detailmenu
1166
1167 (put 'node 'texinfo-format 'texinfo-format-node)
1168 (put 'nwnode 'texinfo-format 'texinfo-format-node)
1169 (defun texinfo-format-node ()
1170 (let* ((args (texinfo-format-parse-line-args))
1171 (name (nth 0 args))
1172 (next (nth 1 args))
1173 (prev (nth 2 args))
1174 (up (nth 3 args)))
1175 (texinfo-discard-command)
1176 (setq texinfo-last-node name)
1177 (let ((tem (if texinfo-fold-nodename-case (downcase name) name)))
1178 (if (assoc tem texinfo-node-names)
1179 (error "Duplicate node name: %s" name)
1180 (push (list tem) texinfo-node-names)))
1181 (setq texinfo-footnote-number 0)
1182 ;; insert "\n\^_" unconditionally since this is what info is looking for
1183 (insert "\n\^_\nFile: " texinfo-format-filename
1184 ", Node: " name)
1185 (if next
1186 (insert ", Next: " next))
1187 (if prev
1188 (insert ", Prev: " prev))
1189 (if up
1190 (insert ", Up: " up))
1191 (insert ?\n)
1192 (setq texinfo-last-node-pos (point))))
1193
1194 (put 'anchor 'texinfo-format 'texinfo-anchor)
1195 (defun texinfo-anchor ()
1196 (let (anchor-string
1197 (here (- (point) 7)) ; save location of beginning of `@anchor'
1198 (arg (texinfo-parse-arg-discard)))
1199 (if (looking-at " ") ; since a space may be left after -discard
1200 (delete-char 1))
1201 (forward-paragraph)
1202 (let ((end (point)))
1203 (if (save-excursion
1204 (backward-word 1)
1205 (search-forward "@refill" end t))
1206 (setq anchor-string "@anchor-yes-refill")
1207 (setq anchor-string "@anchor-no-refill")))
1208 (goto-char here)
1209 (insert anchor-string "{" arg "}")))
1210
1211 (put 'menu 'texinfo-format 'texinfo-format-menu)
1212 (defun texinfo-format-menu ()
1213 (texinfo-discard-line)
1214 (insert "* Menu:\n\n"))
1215
1216 (put 'menu 'texinfo-end 'texinfo-discard-command)
1217
1218 ;; The @detailmenu should be removed eventually.
1219
1220 ;; According to Karl Berry, 31 August 1996:
1221 ;;
1222 ;; You don't like, I don't like it. I agree, it would be better just to
1223 ;; fix the bug [in `makeinfo']. .. At this point, since inserting those
1224 ;; two commands in the Elisp fn is trivial, I don't especially want to
1225 ;; expend more effort...
1226 ;;
1227 ;; I added a couple sentences of documentation to the manual (putting the
1228 ;; blame on makeinfo where it belongs :-().
1229
1230 (put 'detailmenu 'texinfo-format 'texinfo-discard-line)
1231 (put 'detailmenu 'texinfo-end 'texinfo-discard-command)
1232
1233 ;; (Also see `texnfo-upd.el')
1234
1235 \f
1236 ;;; Cross references
1237
1238 ;; @xref {NODE, FNAME, NAME, FILE, DOCUMENT}
1239 ;; -> *Note FNAME: (FILE)NODE
1240 ;; If FILE is missing,
1241 ;; *Note FNAME: NODE
1242 ;; If FNAME is empty and NAME is present
1243 ;; *Note NAME: Node
1244 ;; If both NAME and FNAME are missing
1245 ;; *Note NODE::
1246 ;; texinfo ignores the DOCUMENT argument.
1247 ;; -> See section <xref to NODE> [NAME, else NODE], page <xref to NODE>
1248 ;; If FILE is specified, (FILE)NODE is used for xrefs.
1249 ;; If fifth argument DOCUMENT is specified, produces
1250 ;; See section <xref to NODE> [NAME, else NODE], page <xref to NODE>
1251 ;; of DOCUMENT
1252
1253 ;; @ref a reference that does not put `See' or `see' in
1254 ;; the hardcopy and is the same as @xref in Info
1255 (put 'ref 'texinfo-format 'texinfo-format-xref)
1256
1257 (put 'xref 'texinfo-format 'texinfo-format-xref)
1258 (defun texinfo-format-xref ()
1259 (let ((args (texinfo-format-parse-args)))
1260 (texinfo-discard-command)
1261 (insert "*Note ")
1262 (let ((fname (or (nth 1 args) (nth 2 args))))
1263 (if (null (or fname (nth 3 args)))
1264 (insert (car args) "::")
1265 (insert (or fname (car args)) ": ")
1266 (if (nth 3 args)
1267 (insert "(" (nth 3 args) ")"))
1268 (and (car args) (insert (car args)))))))
1269
1270 (put 'pxref 'texinfo-format 'texinfo-format-pxref)
1271 (defun texinfo-format-pxref ()
1272 (texinfo-format-xref)
1273 (or (save-excursion
1274 (forward-char -2)
1275 (looking-at "::"))
1276 (insert ".")))
1277
1278 ;; @inforef{NODE, FNAME, FILE}
1279 ;; Like @xref{NODE, FNAME,,FILE} in texinfo.
1280 ;; In Tex, generates "See Info file FILE, node NODE"
1281 (put 'inforef 'texinfo-format 'texinfo-format-inforef)
1282 (defun texinfo-format-inforef ()
1283 (let ((args (texinfo-format-parse-args)))
1284 (texinfo-discard-command)
1285 (if (nth 1 args)
1286 (insert "*Note " (nth 1 args) ": (" (nth 2 args) ")" (car args))
1287 (insert "*Note " "(" (nth 2 args) ")" (car args) "::"))))
1288
1289 \f
1290 ;;; URL Reference: @uref
1291
1292 ;; @uref produces a reference to a uniform resource locator (URL).
1293 ;; It takes one mandatory argument, the URL, and one optional argument,
1294 ;; the text to display (the default is the URL itself).
1295
1296 (put 'uref 'texinfo-format 'texinfo-format-uref)
1297 (defun texinfo-format-uref ()
1298 "Format URL and optional URL-TITLE.
1299 Insert ` ... ' around URL if no URL-TITLE argument;
1300 otherwise, insert URL-TITLE followed by URL in parentheses."
1301 (let ((args (texinfo-format-parse-args)))
1302 (texinfo-discard-command)
1303 ;; if url-title
1304 (if (nth 1 args)
1305 (insert (nth 1 args) " (" (nth 0 args) ")")
1306 (insert "`" (nth 0 args) "'"))
1307 (goto-char texinfo-command-start)))
1308
1309 \f
1310 ;;; Section headings
1311
1312 (put 'majorheading 'texinfo-format 'texinfo-format-chapter)
1313 (put 'chapheading 'texinfo-format 'texinfo-format-chapter)
1314 (put 'ichapter 'texinfo-format 'texinfo-format-chapter)
1315 (put 'chapter 'texinfo-format 'texinfo-format-chapter)
1316 (put 'iappendix 'texinfo-format 'texinfo-format-chapter)
1317 (put 'appendix 'texinfo-format 'texinfo-format-chapter)
1318 (put 'iunnumbered 'texinfo-format 'texinfo-format-chapter)
1319 (put 'top 'texinfo-format 'texinfo-format-chapter)
1320 (put 'unnumbered 'texinfo-format 'texinfo-format-chapter)
1321 (put 'centerchap 'texinfo-format 'texinfo-format-chapter)
1322 (defun texinfo-format-chapter ()
1323 (texinfo-format-chapter-1 ?*))
1324
1325 (put 'heading 'texinfo-format 'texinfo-format-section)
1326 (put 'isection 'texinfo-format 'texinfo-format-section)
1327 (put 'section 'texinfo-format 'texinfo-format-section)
1328 (put 'iappendixsection 'texinfo-format 'texinfo-format-section)
1329 (put 'appendixsection 'texinfo-format 'texinfo-format-section)
1330 (put 'iappendixsec 'texinfo-format 'texinfo-format-section)
1331 (put 'appendixsec 'texinfo-format 'texinfo-format-section)
1332 (put 'iunnumberedsec 'texinfo-format 'texinfo-format-section)
1333 (put 'unnumberedsec 'texinfo-format 'texinfo-format-section)
1334 (defun texinfo-format-section ()
1335 (texinfo-format-chapter-1 ?=))
1336
1337 (put 'subheading 'texinfo-format 'texinfo-format-subsection)
1338 (put 'isubsection 'texinfo-format 'texinfo-format-subsection)
1339 (put 'subsection 'texinfo-format 'texinfo-format-subsection)
1340 (put 'iappendixsubsec 'texinfo-format 'texinfo-format-subsection)
1341 (put 'appendixsubsec 'texinfo-format 'texinfo-format-subsection)
1342 (put 'iunnumberedsubsec 'texinfo-format 'texinfo-format-subsection)
1343 (put 'unnumberedsubsec 'texinfo-format 'texinfo-format-subsection)
1344 (defun texinfo-format-subsection ()
1345 (texinfo-format-chapter-1 ?-))
1346
1347 (put 'subsubheading 'texinfo-format 'texinfo-format-subsubsection)
1348 (put 'isubsubsection 'texinfo-format 'texinfo-format-subsubsection)
1349 (put 'subsubsection 'texinfo-format 'texinfo-format-subsubsection)
1350 (put 'iappendixsubsubsec 'texinfo-format 'texinfo-format-subsubsection)
1351 (put 'appendixsubsubsec 'texinfo-format 'texinfo-format-subsubsection)
1352 (put 'iunnumberedsubsubsec 'texinfo-format 'texinfo-format-subsubsection)
1353 (put 'unnumberedsubsubsec 'texinfo-format 'texinfo-format-subsubsection)
1354 (defun texinfo-format-subsubsection ()
1355 (texinfo-format-chapter-1 ?.))
1356
1357 (defun texinfo-format-chapter-1 (belowchar)
1358 (let ((arg (texinfo-parse-arg-discard)))
1359 (message "Formatting: %s ... " arg) ; So we can see where we are.
1360 (insert ?\n arg ?\n "@SectionPAD " belowchar ?\n)
1361 (forward-line -2)))
1362
1363 (put 'SectionPAD 'texinfo-format 'texinfo-format-sectionpad)
1364 (defun texinfo-format-sectionpad ()
1365 (let ((str (texinfo-parse-arg-discard)))
1366 (forward-char -1)
1367 (let ((column (current-column)))
1368 (forward-char 1)
1369 (while (> column 0)
1370 (insert str)
1371 (setq column (1- column))))
1372 (insert ?\n)))
1373
1374 \f
1375 ;;; Space controlling commands: @. and @:, and the soft hyphen.
1376
1377 (put '\. 'texinfo-format 'texinfo-format-\.)
1378 (defun texinfo-format-\. ()
1379 (texinfo-discard-command)
1380 (insert "."))
1381
1382 (put '\: 'texinfo-format 'texinfo-format-\:)
1383 (defun texinfo-format-\: ()
1384 (texinfo-discard-command))
1385
1386 (put '\- 'texinfo-format 'texinfo-format-soft-hyphen)
1387 (defun texinfo-format-soft-hyphen ()
1388 (texinfo-discard-command))
1389
1390 \f
1391 ;;; @kbdinputstyle, @vskip, headings & footings
1392 ;; These commands for not for Info and should never
1393 ;; appear in an Info environment; but if they do,
1394 ;; this causes them to be discarded.
1395
1396 ;; @kbdinputstyle
1397 (put 'kbdinputstyle 'texinfo-format 'texinfo-discard-line-with-args)
1398
1399 ;; @vskip
1400 (put 'vskip 'texinfo-format 'texinfo-discard-line-with-args)
1401
1402 ;; headings & footings
1403 (put 'evenfooting 'texinfo-format 'texinfo-discard-line-with-args)
1404 (put 'evenheading 'texinfo-format 'texinfo-discard-line-with-args)
1405 (put 'oddfooting 'texinfo-format 'texinfo-discard-line-with-args)
1406 (put 'oddheading 'texinfo-format 'texinfo-discard-line-with-args)
1407 (put 'everyfooting 'texinfo-format 'texinfo-discard-line-with-args)
1408 (put 'everyheading 'texinfo-format 'texinfo-discard-line-with-args)
1409
1410 \f
1411 ;;; @documentdescription ... @end documentdescription
1412 ;; This command is for HTML output and should never
1413 ;; appear in an Info environment; but if it does,
1414 ;; this causes it to be discarded.
1415
1416 (put 'documentdescription 'texinfo-format 'texinfo-format-documentdescription)
1417 (defun texinfo-format-documentdescription ()
1418 (delete-region texinfo-command-start
1419 (progn (re-search-forward "^@end documentdescription[ \t]*\n")
1420 (point))))
1421
1422
1423 \f
1424 ;;; @center, @sp, and @br
1425
1426 (put 'center 'texinfo-format 'texinfo-format-center)
1427 (defun texinfo-format-center ()
1428 (let ((arg (texinfo-parse-expanded-arg)))
1429 (texinfo-discard-command)
1430 (insert arg)
1431 (insert ?\n)
1432 (save-restriction
1433 (goto-char (1- (point)))
1434 (let ((indent-tabs-mode nil))
1435 (center-line)))))
1436
1437 (put 'sp 'texinfo-format 'texinfo-format-sp)
1438 (defun texinfo-format-sp ()
1439 (let* ((arg (texinfo-parse-arg-discard))
1440 (num (read arg)))
1441 (insert-char ?\n num)))
1442
1443 (put 'br 'texinfo-format 'texinfo-format-paragraph-break)
1444 (defun texinfo-format-paragraph-break ()
1445 "Force a paragraph break.
1446 If used within a line, follow `@br' with braces."
1447 (texinfo-optional-braces-discard)
1448 ;; insert one return if at end of line;
1449 ;; else insert two returns, to generate a blank line.
1450 (if (= (following-char) ?\n)
1451 (insert ?\n)
1452 (insert-char ?\n 2)))
1453
1454 \f
1455 ;;; @footnote and @footnotestyle
1456
1457 ;; In Texinfo, footnotes are created with the `@footnote' command.
1458 ;; This command is followed immediately by a left brace, then by the text of
1459 ;; the footnote, and then by a terminating right brace. The
1460 ;; template for a footnote is:
1461 ;;
1462 ;; @footnote{TEXT}
1463 ;;
1464 ;; Info has two footnote styles:
1465 ;;
1466 ;; * In the End of node style, all the footnotes for a single node
1467 ;; are placed at the end of that node. The footnotes are
1468 ;; separated from the rest of the node by a line of dashes with
1469 ;; the word `Footnotes' within it.
1470 ;;
1471 ;; * In the Separate node style, all the footnotes for a single node
1472 ;; are placed in an automatically constructed node of their own.
1473
1474 ;; Footnote style is specified by the @footnotestyle command, either
1475 ;; @footnotestyle separate
1476 ;; or
1477 ;; @footnotestyle end
1478 ;;
1479 ;; The default is separate
1480
1481 (defvar texinfo-footnote-style "separate"
1482 "Footnote style, either separate or end.")
1483
1484 (put 'footnotestyle 'texinfo-format 'texinfo-footnotestyle)
1485 (defun texinfo-footnotestyle ()
1486 "Specify whether footnotes are at end of node or in separate nodes.
1487 Argument is either end or separate."
1488 (setq texinfo-footnote-style (texinfo-parse-arg-discard)))
1489
1490 (put 'footnote 'texinfo-format 'texinfo-format-footnote)
1491 (defun texinfo-format-footnote ()
1492 "Format a footnote in either end of node or separate node style.
1493 The texinfo-footnote-style variable controls which style is used."
1494 (setq texinfo-footnote-number (1+ texinfo-footnote-number))
1495 (cond ((string= texinfo-footnote-style "end")
1496 (texinfo-format-end-node))
1497 ((string= texinfo-footnote-style "separate")
1498 (texinfo-format-separate-node))))
1499
1500 (defun texinfo-format-separate-node ()
1501 "Format footnote in Separate node style, with notes in own node.
1502 The node is constructed automatically."
1503 (let* (start
1504 (arg (texinfo-parse-line-arg))
1505 (node-name-beginning
1506 (save-excursion
1507 (re-search-backward
1508 "^File: \\w+\\(\\w\\|\\s_\\|\\.\\|,\\)*[ \t]+Node:")
1509 (match-end 0)))
1510 (node-name
1511 (save-excursion
1512 (buffer-substring-no-properties
1513 (progn (goto-char node-name-beginning) ; skip over node command
1514 (skip-chars-forward " \t") ; and over spaces
1515 (point))
1516 (if (search-forward
1517 ","
1518 (save-excursion (end-of-line) (point)) t) ; bound search
1519 (1- (point))
1520 (end-of-line) (point))))))
1521 (texinfo-discard-command) ; remove or insert whitespace, as needed
1522 (delete-region (save-excursion (skip-chars-backward " \t\n") (point))
1523 (point))
1524 (insert (format " (%d) (*Note %s-Footnotes::)"
1525 texinfo-footnote-number node-name))
1526 (fill-paragraph nil)
1527 (save-excursion
1528 (if (re-search-forward "^@node" nil 'move)
1529 (forward-line -1))
1530
1531 ;; two cases: for the first footnote, we must insert a node header;
1532 ;; for the second and subsequent footnotes, we need only insert
1533 ;; the text of the footnote.
1534
1535 (if (save-excursion
1536 (search-backward
1537 (concat node-name "-Footnotes, Up: ")
1538 node-name-beginning
1539 t))
1540 (progn ; already at least one footnote
1541 (setq start (point))
1542 (insert (format "\n(%d) %s\n" texinfo-footnote-number arg))
1543 (fill-region start (point)))
1544 ;; else not yet a footnote
1545 (insert "\n\^_\nFile: " texinfo-format-filename
1546 " Node: " node-name "-Footnotes, Up: " node-name "\n")
1547 (setq start (point))
1548 (insert (format "\n(%d) %s\n" texinfo-footnote-number arg))
1549 (narrow-to-region (save-excursion (goto-char start) (point)) (point))
1550 (fill-region (point-min) (point-max))
1551 (widen)))))
1552
1553 (defun texinfo-format-end-node ()
1554 "Format footnote in the End of node style, with notes at end of node."
1555 (let (start
1556 (arg (texinfo-parse-line-arg)))
1557 (texinfo-discard-command) ; remove or insert whitespace, as needed
1558 (delete-region (save-excursion (skip-chars-backward " \t\n") (point))
1559 (point))
1560 (insert (format " (%d) " texinfo-footnote-number))
1561 (fill-paragraph nil)
1562 (save-excursion
1563 (if (search-forward "\n--------- Footnotes ---------\n" nil t)
1564 (progn ; already have footnote, put new one before end of node
1565 (if (re-search-forward "^@node" nil 'move)
1566 (forward-line -1))
1567 (setq start (point))
1568 (insert (format "\n(%d) %s\n" texinfo-footnote-number arg))
1569 (fill-region start (point)))
1570 ;; else no prior footnote
1571 (if (re-search-forward "^@node" nil 'move)
1572 (forward-line -1))
1573 (insert "\n--------- Footnotes ---------\n")
1574 (setq start (point))
1575 (insert (format "\n(%d) %s\n" texinfo-footnote-number arg))))))
1576
1577 \f
1578 ;;; @itemize, @enumerate, and similar commands
1579
1580 ;; @itemize pushes (itemize "COMMANDS" STARTPOS) on texinfo-stack.
1581 ;; @enumerate pushes (enumerate 0 STARTPOS).
1582 ;; @item dispatches to the texinfo-item prop of the first elt of the list.
1583 ;; For itemize, this puts in and rescans the COMMANDS.
1584 ;; For enumerate, this increments the number and puts it in.
1585 ;; In either case, it puts a Backspace at the front of the line
1586 ;; which marks it not to be indented later.
1587 ;; All other lines get indented by 5 when the @end is reached.
1588
1589 (defvar texinfo-stack-depth 0
1590 "Count of number of unpopped texinfo-push-stack calls.
1591 Used by @refill indenting command to avoid indenting within lists, etc.")
1592
1593 (defun texinfo-push-stack (check arg)
1594 (setq texinfo-stack-depth (1+ texinfo-stack-depth))
1595 (push (list check arg texinfo-command-start)
1596 texinfo-stack))
1597
1598 (defun texinfo-pop-stack (check)
1599 (setq texinfo-stack-depth (1- texinfo-stack-depth))
1600 (if (null texinfo-stack)
1601 (error "Unmatched @end %s" check))
1602 (if (not (eq (car (car texinfo-stack)) check))
1603 (error "@end %s matches @%s"
1604 check (car (car texinfo-stack))))
1605 (prog1 (cdr (car texinfo-stack))
1606 (setq texinfo-stack (cdr texinfo-stack))))
1607
1608 (put 'itemize 'texinfo-format 'texinfo-itemize)
1609 (defun texinfo-itemize ()
1610 (texinfo-push-stack
1611 'itemize
1612 (progn (skip-chars-forward " \t")
1613 (if (eolp)
1614 "@bullet"
1615 (texinfo-parse-line-arg))))
1616 (texinfo-discard-line-with-args)
1617 (setq fill-column (- fill-column 5)))
1618
1619 (put 'itemize 'texinfo-end 'texinfo-end-itemize)
1620 (defun texinfo-end-itemize ()
1621 (setq fill-column (+ fill-column 5))
1622 (texinfo-discard-command)
1623 (let ((stacktop
1624 (texinfo-pop-stack 'itemize)))
1625 (texinfo-do-itemize (nth 1 stacktop))))
1626
1627 (put 'enumerate 'texinfo-format 'texinfo-enumerate)
1628 (defun texinfo-enumerate ()
1629 (texinfo-push-stack
1630 'enumerate
1631 (progn (skip-chars-forward " \t")
1632 (if (eolp)
1633 1
1634 (read (current-buffer)))))
1635 (if (and (symbolp (car (cdr (car texinfo-stack))))
1636 (> 1 (length (symbol-name (car (cdr (car texinfo-stack)))))))
1637 (error
1638 "@enumerate: Use a number or letter, eg: 1, A, a, 3, B, or d." ))
1639 (texinfo-discard-line-with-args)
1640 (setq fill-column (- fill-column 5)))
1641
1642 (put 'enumerate 'texinfo-end 'texinfo-end-enumerate)
1643 (defun texinfo-end-enumerate ()
1644 (setq fill-column (+ fill-column 5))
1645 (texinfo-discard-command)
1646 (let ((stacktop
1647 (texinfo-pop-stack 'enumerate)))
1648 (texinfo-do-itemize (nth 1 stacktop))))
1649
1650 ;; @alphaenumerate never became a standard part of Texinfo
1651 (put 'alphaenumerate 'texinfo-format 'texinfo-alphaenumerate)
1652 (defun texinfo-alphaenumerate ()
1653 (texinfo-push-stack 'alphaenumerate (1- ?a))
1654 (setq fill-column (- fill-column 5))
1655 (texinfo-discard-line))
1656
1657 (put 'alphaenumerate 'texinfo-end 'texinfo-end-alphaenumerate)
1658 (defun texinfo-end-alphaenumerate ()
1659 (setq fill-column (+ fill-column 5))
1660 (texinfo-discard-command)
1661 (let ((stacktop
1662 (texinfo-pop-stack 'alphaenumerate)))
1663 (texinfo-do-itemize (nth 1 stacktop))))
1664
1665 ;; @capsenumerate never became a standard part of Texinfo
1666 (put 'capsenumerate 'texinfo-format 'texinfo-capsenumerate)
1667 (defun texinfo-capsenumerate ()
1668 (texinfo-push-stack 'capsenumerate (1- ?A))
1669 (setq fill-column (- fill-column 5))
1670 (texinfo-discard-line))
1671
1672 (put 'capsenumerate 'texinfo-end 'texinfo-end-capsenumerate)
1673 (defun texinfo-end-capsenumerate ()
1674 (setq fill-column (+ fill-column 5))
1675 (texinfo-discard-command)
1676 (let ((stacktop
1677 (texinfo-pop-stack 'capsenumerate)))
1678 (texinfo-do-itemize (nth 1 stacktop))))
1679
1680 ;; At the @end, indent all the lines within the construct
1681 ;; except those marked with backspace. FROM says where
1682 ;; construct started.
1683 (defun texinfo-do-itemize (from)
1684 (save-excursion
1685 (while (progn (forward-line -1)
1686 (>= (point) from))
1687 (if (= (following-char) ?\b)
1688 (save-excursion
1689 (delete-char 1)
1690 (end-of-line)
1691 (delete-char 6))
1692 (if (not (looking-at "[ \t]*$"))
1693 (save-excursion (insert " ")))))))
1694
1695 (put 'item 'texinfo-format 'texinfo-item)
1696 (put 'itemx 'texinfo-format 'texinfo-item)
1697 (defun texinfo-item ()
1698 (funcall (get (car (car texinfo-stack)) 'texinfo-item)))
1699
1700 (put 'itemize 'texinfo-item 'texinfo-itemize-item)
1701 (defun texinfo-itemize-item ()
1702 ;; (texinfo-discard-line) ; Did not handle text on same line as @item.
1703 (delete-region (1+ (point)) (save-excursion (beginning-of-line) (point)))
1704 (if (looking-at "[ \t]*[^ \t\n]+")
1705 ;; Text on same line as @item command.
1706 (insert "\b " (nth 1 (car texinfo-stack)) " \n")
1707 ;; Else text on next line.
1708 (insert "\b " (nth 1 (car texinfo-stack)) " "))
1709 (forward-line -1))
1710
1711 (put 'enumerate 'texinfo-item 'texinfo-enumerate-item)
1712 (defun texinfo-enumerate-item ()
1713 (texinfo-discard-line)
1714 (let (enumerating-symbol)
1715 (cond ((integerp (car (cdr (car texinfo-stack))))
1716 (setq enumerating-symbol (car (cdr (car texinfo-stack))))
1717 (insert ?\b (format "%3d. " enumerating-symbol) ?\n)
1718 (setcar (cdr (car texinfo-stack)) (1+ enumerating-symbol)))
1719 ((symbolp (car (cdr (car texinfo-stack))))
1720 (setq enumerating-symbol
1721 (symbol-name (car (cdr (car texinfo-stack)))))
1722 (if (or (equal ?\[ (string-to-char enumerating-symbol))
1723 (equal ?\{ (string-to-char enumerating-symbol)))
1724 (error
1725 "Too many items in enumerated list; alphabet ends at Z."))
1726 (insert ?\b (format "%3s. " enumerating-symbol) ?\n)
1727 (setcar (cdr (car texinfo-stack))
1728 (make-symbol
1729 (char-to-string
1730 (1+
1731 (string-to-char enumerating-symbol))))))
1732 (t
1733 (error
1734 "@enumerate: Use a number or letter, eg: 1, A, a, 3, B or d." )))
1735 (forward-line -1)))
1736
1737 (put 'alphaenumerate 'texinfo-item 'texinfo-alphaenumerate-item)
1738 (defun texinfo-alphaenumerate-item ()
1739 (texinfo-discard-line)
1740 (let ((next (1+ (car (cdr (car texinfo-stack))))))
1741 (if (> next ?z)
1742 (error "More than 26 items in @alphaenumerate; get a bigger alphabet"))
1743 (setcar (cdr (car texinfo-stack)) next)
1744 (insert "\b " next ". \n"))
1745 (forward-line -1))
1746
1747 (put 'capsenumerate 'texinfo-item 'texinfo-capsenumerate-item)
1748 (defun texinfo-capsenumerate-item ()
1749 (texinfo-discard-line)
1750 (let ((next (1+ (car (cdr (car texinfo-stack))))))
1751 (if (> next ?Z)
1752 (error "More than 26 items in @capsenumerate; get a bigger alphabet"))
1753 (setcar (cdr (car texinfo-stack)) next)
1754 (insert "\b " next ". \n"))
1755 (forward-line -1))
1756
1757 \f
1758 ;;; @table
1759
1760 ;; The `@table' command produces two-column tables.
1761
1762 (put 'table 'texinfo-format 'texinfo-table)
1763 (defun texinfo-table ()
1764 (texinfo-push-stack
1765 'table
1766 (progn (skip-chars-forward " \t")
1767 (if (eolp)
1768 "@asis"
1769 (texinfo-parse-line-arg))))
1770 (texinfo-discard-line-with-args)
1771 (setq fill-column (- fill-column 5)))
1772
1773 (put 'table 'texinfo-item 'texinfo-table-item)
1774 (defun texinfo-table-item ()
1775 (let ((arg (texinfo-parse-arg-discard))
1776 (itemfont (car (cdr (car texinfo-stack)))))
1777 (insert ?\b itemfont ?\{ arg "}\n \n"))
1778 (forward-line -2))
1779
1780 (put 'table 'texinfo-end 'texinfo-end-table)
1781 (defun texinfo-end-table ()
1782 (setq fill-column (+ fill-column 5))
1783 (texinfo-discard-command)
1784 (let ((stacktop
1785 (texinfo-pop-stack 'table)))
1786 (texinfo-do-itemize (nth 1 stacktop))))
1787
1788 ;; @description appears to be an undocumented variant on @table that
1789 ;; does not require an arg. It fails in texinfo.tex 2.58 and is not
1790 ;; part of makeinfo.c The command appears to be a relic of the past.
1791 (put 'description 'texinfo-end 'texinfo-end-table)
1792 (put 'description 'texinfo-format 'texinfo-description)
1793 (defun texinfo-description ()
1794 (texinfo-push-stack 'table "@asis")
1795 (setq fill-column (- fill-column 5))
1796 (texinfo-discard-line))
1797
1798 \f
1799 ;;; @ftable, @vtable
1800
1801 ;; The `@ftable' and `@vtable' commands are like the `@table' command
1802 ;; but they also insert each entry in the first column of the table
1803 ;; into the function or variable index.
1804
1805 ;; Handle the @ftable and @vtable commands:
1806
1807 (put 'ftable 'texinfo-format 'texinfo-ftable)
1808 (put 'vtable 'texinfo-format 'texinfo-vtable)
1809
1810 (defun texinfo-ftable () (texinfo-indextable 'ftable))
1811 (defun texinfo-vtable () (texinfo-indextable 'vtable))
1812
1813 (defun texinfo-indextable (table-type)
1814 (texinfo-push-stack table-type (texinfo-parse-arg-discard))
1815 (setq fill-column (- fill-column 5)))
1816
1817 ;; Handle the @item commands within ftable and vtable:
1818
1819 (put 'ftable 'texinfo-item 'texinfo-ftable-item)
1820 (put 'vtable 'texinfo-item 'texinfo-vtable-item)
1821
1822 (defun texinfo-ftable-item () (texinfo-indextable-item 'texinfo-findex))
1823 (defun texinfo-vtable-item () (texinfo-indextable-item 'texinfo-vindex))
1824
1825 (defun texinfo-indextable-item (index-type)
1826 (let ((item (texinfo-parse-arg-discard))
1827 (itemfont (car (cdr (car texinfo-stack))))
1828 (indexvar index-type))
1829 (insert ?\b itemfont ?\{ item "}\n \n")
1830 (set indexvar
1831 (cons
1832 (list item texinfo-last-node)
1833 (symbol-value indexvar)))
1834 (forward-line -2)))
1835
1836 ;; Handle @end ftable, @end vtable
1837
1838 (put 'ftable 'texinfo-end 'texinfo-end-ftable)
1839 (put 'vtable 'texinfo-end 'texinfo-end-vtable)
1840
1841 (defun texinfo-end-ftable () (texinfo-end-indextable 'ftable))
1842 (defun texinfo-end-vtable () (texinfo-end-indextable 'vtable))
1843
1844 (defun texinfo-end-indextable (table-type)
1845 (setq fill-column (+ fill-column 5))
1846 (texinfo-discard-command)
1847 (let ((stacktop
1848 (texinfo-pop-stack table-type)))
1849 (texinfo-do-itemize (nth 1 stacktop))))
1850
1851 \f
1852 ;;; @multitable ... @end multitable
1853
1854 ;; Produce a multi-column table, with as many columns as desired.
1855 ;;
1856 ;; A multi-column table has this template:
1857 ;;
1858 ;; @multitable {A1} {A2} {A3}
1859 ;; @item A1 @tab A2 @tab A3
1860 ;; @item B1 @tab B2 @tab B3
1861 ;; @item C1 @tab C2 @tab C3
1862 ;; @end multitable
1863 ;;
1864 ;; where the width of the text in brackets specifies the width of the
1865 ;; respective column.
1866 ;;
1867 ;; Or else:
1868 ;;
1869 ;; @multitable @columnfractions .25 .3 .45
1870 ;; @item A1 @tab A2 @tab A3
1871 ;; @item B1 @tab B2 @tab B3
1872 ;; @end multitable
1873 ;;
1874 ;; where the fractions specify the width of each column as a percent
1875 ;; of the current width of the text (i.e., of the fill-column).
1876 ;;
1877 ;; Long lines of text are filled within columns.
1878 ;;
1879 ;; Using the Emacs Lisp formatter, texinfmt.el,
1880 ;; the whitespace between columns can be increased by setting
1881 ;; `texinfo-extra-inter-column-width' to a value greater than 0. By default,
1882 ;; there is at least one blank space between columns.
1883 ;;
1884 ;; The Emacs Lisp formatter, texinfmt.el, ignores the following four
1885 ;; commands that are defined in texinfo.tex for printed output.
1886 ;;
1887 ;; @multitableparskip,
1888 ;; @multitableparindent,
1889 ;; @multitablecolmargin,
1890 ;; @multitablelinespace.
1891
1892 ;; How @multitable works.
1893 ;; =====================
1894 ;;
1895 ;; `texinfo-multitable' reads the @multitable line and determines from it
1896 ;; how wide each column should be.
1897 ;;
1898 ;; Also, it pushes this information, along with an identifying symbol,
1899 ;; onto the `texinfo-stack'. At the @end multitable command, the stack
1900 ;; is checked for its matching @multitable command, and then popped, or
1901 ;; else an error is signaled. Also, this command pushes the location of
1902 ;; the start of the table onto the stack.
1903 ;;
1904 ;; `texinfo-end-multitable' checks the `texinfo-stack' that the @end
1905 ;; multitable truly is ending a corresponding beginning, and if it is,
1906 ;; pops the stack.
1907 ;;
1908 ;; `texinfo-multitable-widths' is called by `texinfo-multitable'.
1909 ;; The function returns a list of the widths of each column in a
1910 ;; multi-column table, based on the information supplied by the arguments
1911 ;; to the @multitable command (by arguments, I mean the text on the rest
1912 ;; of the @multitable line, not the remainder of the multi-column table
1913 ;; environment).
1914 ;;
1915 ;; `texinfo-multitable-item' formats a row within a multicolumn table.
1916 ;; This command is executed when texinfmt sees @item inside @multitable.
1917 ;; Cells in row are separated by `@tab's. Widths of cells are specified
1918 ;; by the arguments in the @multitable line. Cells are filled. All cells
1919 ;; are made to be the same height by padding their bottoms, as needed,
1920 ;; with blanks.
1921 ;;
1922 ;; `texinfo-multitable-extract-row' is called by `texinfo-multitable-item'.
1923 ;; This function returns the text in a multitable row, as a string.
1924 ;; The start of a row is marked by an @item and the end of row is the
1925 ;; beginning of next @item or beginning of the @end multitable line.
1926 ;; Cells within a row are separated by @tab.
1927 ;;
1928 ;; Note that @tab, the cell separators, are not treated as independent
1929 ;; Texinfo commands.
1930
1931 (defvar texinfo-extra-inter-column-width 0
1932 "*Number of extra spaces between entries (columns) in @multitable.")
1933
1934 (defvar texinfo-multitable-buffer-name "*multitable-temporary-buffer*")
1935 (defvar texinfo-multitable-rectangle-name "texinfo-multitable-temp-")
1936
1937 ;; These commands are defined in texinfo.tex for printed output.
1938 (put 'multitableparskip 'texinfo-format 'texinfo-discard-line-with-args)
1939 (put 'multitableparindent 'texinfo-format 'texinfo-discard-line-with-args)
1940 (put 'multitablecolmargin 'texinfo-format 'texinfo-discard-line-with-args)
1941 (put 'multitablelinespace 'texinfo-format 'texinfo-discard-line-with-args)
1942
1943 (put 'multitable 'texinfo-format 'texinfo-multitable)
1944
1945 (defun texinfo-multitable ()
1946 "Produce multi-column tables.
1947
1948 A multi-column table has this template:
1949
1950 @multitable {A1} {A2} {A3}
1951 @item A1 @tab A2 @tab A3
1952 @item B1 @tab B2 @tab B3
1953 @item C1 @tab C2 @tab C3
1954 @end multitable
1955
1956 where the width of the text in brackets specifies the width of the
1957 respective column.
1958
1959 Or else:
1960
1961 @multitable @columnfractions .25 .3 .45
1962 @item A1 @tab A2 @tab A3
1963 @item B1 @tab B2 @tab B3
1964 @end multitable
1965
1966 where the fractions specify the width of each column as a percent
1967 of the current width of the text (i.e., of the `fill-column').
1968
1969 Long lines of text are filled within columns.
1970
1971 Using the Emacs Lisp formatter, texinfmt.el,
1972 the whitespace between columns can be increased by setting
1973 `texinfo-extra-inter-column-width' to a value greater than 0. By default,
1974 there is at least one blank space between columns.
1975
1976 The Emacs Lisp formatter, texinfmt.el, ignores the following four
1977 commands that are defined in texinfo.tex for printed output.
1978
1979 @multitableparskip,
1980 @multitableparindent,
1981 @multitablecolmargin,
1982 @multitablelinespace."
1983
1984 ;; This function pushes information onto the `texinfo-stack'.
1985 ;; A stack element consists of:
1986 ;; - type-of-command, i.e., multitable
1987 ;; - the information about column widths, and
1988 ;; - the position of texinfo-command-start.
1989 ;; e.g., ('multitable (1 2 3 4) 123)
1990 ;; The command line is then deleted.
1991 (texinfo-push-stack
1992 'multitable
1993 ;; push width information on stack
1994 (texinfo-multitable-widths))
1995 (texinfo-discard-line-with-args))
1996
1997 (put 'multitable 'texinfo-end 'texinfo-end-multitable)
1998 (defun texinfo-end-multitable ()
1999 "Discard the @end multitable line and pop the stack of multitable."
2000 (texinfo-discard-command)
2001 (texinfo-pop-stack 'multitable))
2002
2003 (defun texinfo-multitable-widths ()
2004 "Return list of widths of each column in a multi-column table."
2005 (let (texinfo-multitable-width-list)
2006 ;; Fractions format:
2007 ;; @multitable @columnfractions .25 .3 .45
2008 ;;
2009 ;; Template format:
2010 ;; @multitable {Column 1 template} {Column 2} {Column 3 example}
2011 ;; Place point before first argument
2012 (skip-chars-forward " \t")
2013 (cond
2014 ;; Check for common misspelling
2015 ((looking-at "@columnfraction ")
2016 (error "In @multitable, @columnfractions misspelled"))
2017 ;; Case 1: @columnfractions .25 .3 .45
2018 ((looking-at "@columnfractions")
2019 (forward-word 1)
2020 (while (not (eolp))
2021 (push (truncate
2022 (1-
2023 (* fill-column (read (get-buffer (current-buffer))))))
2024 texinfo-multitable-width-list)))
2025 ;;
2026 ;; Case 2: {Column 1 template} {Column 2} {Column 3 example}
2027 ((looking-at "{")
2028 (let ((start-of-templates (point)))
2029 (while (not (eolp))
2030 (skip-chars-forward " \t")
2031 (let* ((start-of-template (1+ (point)))
2032 (end-of-template
2033 ;; forward-sexp works with braces in Texinfo mode
2034 (progn (forward-sexp 1) (1- (point)))))
2035 (push (- end-of-template start-of-template)
2036 texinfo-multitable-width-list)
2037 ;; Remove carriage return from within a template, if any.
2038 ;; This helps those those who want to use more than
2039 ;; one line's worth of words in @multitable line.
2040 (narrow-to-region start-of-template end-of-template)
2041 (goto-char (point-min))
2042 (while (search-forward "
2043 " nil t)
2044 (delete-char -1))
2045 (goto-char (point-max))
2046 (widen)
2047 (forward-char 1)))))
2048 ;;
2049 ;; Case 3: Trouble
2050 (t
2051 (error
2052 "You probably need to specify column widths for @multitable correctly.")))
2053 ;; Check whether columns fit on page.
2054 (let ((desired-columns
2055 (+
2056 ;; between column spaces
2057 (length texinfo-multitable-width-list)
2058 ;; additional between column spaces, if any
2059 texinfo-extra-inter-column-width
2060 ;; sum of spaces for each entry
2061 (apply '+ texinfo-multitable-width-list))))
2062 (if (> desired-columns fill-column)
2063 (error
2064 (format
2065 "Multi-column table width, %d chars, is greater than page width, %d chars."
2066 desired-columns fill-column))))
2067 texinfo-multitable-width-list))
2068
2069 ;; @item A1 @tab A2 @tab A3
2070 (defun texinfo-multitable-extract-row ()
2071 "Return multitable row, as a string.
2072 End of row is beginning of next @item or beginning of @end.
2073 Cells within rows are separated by @tab."
2074 (skip-chars-forward " \t")
2075 (let* ((start (point))
2076 (end (progn
2077 (re-search-forward "@item\\|@end")
2078 (match-beginning 0)))
2079 (row (progn (goto-char end)
2080 (skip-chars-backward " ")
2081 ;; remove whitespace at end of argument
2082 (delete-region (point) end)
2083 (buffer-substring-no-properties start (point)))))
2084 (delete-region texinfo-command-start end)
2085 row))
2086
2087 (put 'multitable 'texinfo-item 'texinfo-multitable-item)
2088 (defun texinfo-multitable-item ()
2089 "Format a row within a multicolumn table.
2090 Cells in row are separated by @tab.
2091 Widths of cells are specified by the arguments in the @multitable line.
2092 All cells are made to be the same height.
2093 This command is executed when texinfmt sees @item inside @multitable."
2094 (let ((original-buffer (current-buffer))
2095 (table-widths (reverse (car (cdr (car texinfo-stack)))))
2096 (existing-fill-column fill-column)
2097 start
2098 end
2099 (table-column 0)
2100 (table-entry-height 0)
2101 ;; unformatted row looks like: A1 @tab A2 @tab A3
2102 ;; extract-row command deletes the source line in the table.
2103 (unformated-row (texinfo-multitable-extract-row)))
2104 ;; Use a temporary buffer
2105 (set-buffer (get-buffer-create texinfo-multitable-buffer-name))
2106 (delete-region (point-min) (point-max))
2107 (insert unformated-row)
2108 (goto-char (point-min))
2109 ;; 1. Check for correct number of @tab in line.
2110 (let ((tab-number 1)) ; one @tab between two columns
2111 (while (search-forward "@tab" nil t)
2112 (setq tab-number (1+ tab-number)))
2113 (let ((needed-tabs (- (length table-widths) tab-number)))
2114 (when (> needed-tabs 0)
2115 (goto-char (point-min))
2116 (end-of-line)
2117 (while (> needed-tabs 0)
2118 (insert "@w{ }\n@tab")
2119 (setq needed-tabs (1- needed-tabs))
2120 (message
2121 "Added @tabs and empty spaces to a @multitable row")))))
2122 (goto-char (point-min))
2123 ;; 2. Format each cell, and copy to a rectangle
2124 ;; buffer looks like this: A1 @tab A2 @tab A3
2125 ;; Cell #1: format up to @tab
2126 ;; Cell #2: format up to @tab
2127 ;; Cell #3: format up to eob
2128 (while (not (eobp))
2129 (setq start (point))
2130 (setq end (save-excursion
2131 (if (search-forward "@tab" nil 'move)
2132 ;; Delete the @tab command, including the @-sign
2133 (delete-region
2134 (point)
2135 (progn (forward-word -1) (1- (point)))))
2136 (point)))
2137 ;; Set fill-column *wider* than needed to produce inter-column space
2138 (setq fill-column (+ 1
2139 texinfo-extra-inter-column-width
2140 (nth table-column table-widths)))
2141 (narrow-to-region start end)
2142 ;; Remove whitespace before and after entry.
2143 (skip-chars-forward " ")
2144 (delete-region (point) (save-excursion (beginning-of-line) (point)))
2145 (goto-char (point-max))
2146 (skip-chars-backward " ")
2147 (delete-region (point) (save-excursion (end-of-line) (point)))
2148 ;; Temporarily set texinfo-stack to nil so texinfo-format-scan
2149 ;; does not see an unterminated @multitable.
2150 (let (texinfo-stack) ; nil
2151 (texinfo-format-scan))
2152 (let (fill-prefix) ; no fill prefix
2153 (fill-region (point-min) (point-max)))
2154 (setq table-entry-height
2155 (max table-entry-height (count-lines (point-min) (point-max))))
2156 ;; 3. Move point to end of bottom line, and pad that line to fill column.
2157 (goto-char (point-min))
2158 (forward-line (1- table-entry-height))
2159 (let* ((beg (point)) ; beginning of line
2160 ;; add one more space for inter-column spacing
2161 (needed-whitespace
2162 (1+
2163 (- fill-column
2164 (-
2165 (progn (end-of-line) (point)) ; end of existing line
2166 beg)))))
2167 (insert (make-string
2168 (if (> needed-whitespace 0) needed-whitespace 1)
2169 ? )))
2170 ;; now, put formatted cell into a rectangle
2171 (set (intern (concat texinfo-multitable-rectangle-name
2172 (int-to-string table-column)))
2173 (extract-rectangle (point-min) (point)))
2174 (delete-region (point-min) (point))
2175 (goto-char (point-max))
2176 (setq table-column (1+ table-column))
2177 (widen))
2178 ;; 4. Add extra lines to rectangles so all are of same height
2179 (let ((total-number-of-columns table-column)
2180 (column-number 0)
2181 here)
2182 (while (> table-column 0)
2183 (let ((this-rectangle (int-to-string table-column)))
2184 (while (< (length this-rectangle) table-entry-height)
2185 (setq this-rectangle (append this-rectangle '("")))))
2186 (setq table-column (1- table-column)))
2187 ;; 5. Insert formatted rectangles in original buffer
2188 (switch-to-buffer original-buffer)
2189 (open-line table-entry-height)
2190 (while (< column-number total-number-of-columns)
2191 (setq here (point))
2192 (insert-rectangle
2193 (eval (intern
2194 (concat texinfo-multitable-rectangle-name
2195 (int-to-string column-number)))))
2196 (goto-char here)
2197 (end-of-line)
2198 (setq column-number (1+ column-number))))
2199 (kill-buffer texinfo-multitable-buffer-name)
2200 (setq fill-column existing-fill-column)))
2201
2202 \f
2203 ;;; @image
2204 ;; Use only the FILENAME argument to the command.
2205 ;; In Info, ignore the other arguments.
2206
2207 (put 'image 'texinfo-format 'texinfo-format-image)
2208 (defun texinfo-format-image ()
2209 "Insert an image from an an file ending in .txt.
2210 Use only the FILENAME arg; for Info, ignore the other arguments to @image."
2211 (let ((args (texinfo-format-parse-args))
2212 filename)
2213 (when (null (nth 0 args))
2214 (error "Invalid image command"))
2215 (texinfo-discard-command)
2216 ;; makeinfo uses FILENAME.txt
2217 (setq filename (format "%s.txt" (nth 0 args)))
2218 (message "Reading included file: %s" filename)
2219 ;; verbatim for Info output
2220 (goto-char (+ (point) (cadr (insert-file-contents filename))))
2221 (message "Reading included file: %s...done" filename)))
2222
2223 \f
2224 ;;; @ifinfo, @iftex, @tex, @ifhtml, @html, @ifplaintext, @ifxml, @xml
2225 ;; @ifnottex, @ifnotinfo, @ifnothtml, @ifnotplaintext, @ifnotxml
2226
2227 (put 'ifinfo 'texinfo-format 'texinfo-discard-line)
2228 (put 'ifinfo 'texinfo-end 'texinfo-discard-command)
2229
2230 (put 'iftex 'texinfo-format 'texinfo-format-iftex)
2231 (defun texinfo-format-iftex ()
2232 (delete-region texinfo-command-start
2233 (re-search-forward "@end iftex[ \t]*\n")))
2234
2235 (put 'ifhtml 'texinfo-format 'texinfo-format-ifhtml)
2236 (defun texinfo-format-ifhtml ()
2237 (delete-region texinfo-command-start
2238 (re-search-forward "@end ifhtml[ \t]*\n")))
2239
2240 (put 'ifplaintext 'texinfo-format 'texinfo-format-ifplaintext)
2241 (defun texinfo-format-ifplaintext ()
2242 (delete-region texinfo-command-start
2243 (re-search-forward "@end ifplaintext[ \t]*\n")))
2244
2245 (put 'ifxml 'texinfo-format 'texinfo-format-ifxml)
2246 (defun texinfo-format-ifxml ()
2247 (delete-region texinfo-command-start
2248 (progn (re-search-forward "^@end ifxml[ \t]*\n")
2249 (point))))
2250
2251 (put 'tex 'texinfo-format 'texinfo-format-tex)
2252 (defun texinfo-format-tex ()
2253 (delete-region texinfo-command-start
2254 (re-search-forward "@end tex[ \t]*\n")))
2255
2256 (put 'html 'texinfo-format 'texinfo-format-html)
2257 (defun texinfo-format-html ()
2258 (delete-region texinfo-command-start
2259 (re-search-forward "@end html[ \t]*\n")))
2260
2261 (put 'xml 'texinfo-format 'texinfo-format-xml)
2262 (defun texinfo-format-xml ()
2263 (delete-region texinfo-command-start
2264 (progn (re-search-forward "^@end xml[ \t]*\n")
2265 (point))))
2266
2267 (put 'ifnotinfo 'texinfo-format 'texinfo-format-ifnotinfo)
2268 (defun texinfo-format-ifnotinfo ()
2269 (delete-region texinfo-command-start
2270 (re-search-forward "@end ifnotinfo[ \t]*\n")))
2271
2272 (put 'ifnotplaintext 'texinfo-format 'texinfo-discard-line)
2273 (put 'ifnotplaintext 'texinfo-end 'texinfo-discard-command)
2274
2275 (put 'ifnottex 'texinfo-format 'texinfo-discard-line)
2276 (put 'ifnottex 'texinfo-end 'texinfo-discard-command)
2277
2278 (put 'ifnothtml 'texinfo-format 'texinfo-discard-line)
2279 (put 'ifnothtml 'texinfo-end 'texinfo-discard-command)
2280
2281 (put 'ifnotxml 'texinfo-format 'texinfo-discard-line)
2282 (put 'ifnotxml 'texinfo-end 'texinfo-discard-command)
2283
2284 \f
2285 ;;; @titlepage
2286
2287 (put 'titlepage 'texinfo-format 'texinfo-format-titlepage)
2288 (defun texinfo-format-titlepage ()
2289 (delete-region texinfo-command-start
2290 (re-search-forward "@end titlepage[ \t]*\n")))
2291
2292 (put 'endtitlepage 'texinfo-format 'texinfo-discard-line)
2293
2294 ;; @titlespec an alternative titling command; ignored by Info
2295
2296 (put 'titlespec 'texinfo-format 'texinfo-format-titlespec)
2297 (defun texinfo-format-titlespec ()
2298 (delete-region texinfo-command-start
2299 (re-search-forward "@end titlespec[ \t]*\n")))
2300
2301 (put 'endtitlespec 'texinfo-format 'texinfo-discard-line)
2302
2303 \f
2304 ;;; @today
2305
2306 (put 'today 'texinfo-format 'texinfo-format-today)
2307
2308 ;; Produces Day Month Year style of output. eg `1 Jan 1900'
2309 ;; The `@today{}' command requires a pair of braces, like `@dots{}'.
2310 (defun texinfo-format-today ()
2311 (texinfo-parse-arg-discard)
2312 (insert (format-time-string "%e %b %Y")))
2313
2314 \f
2315 ;;; @timestamp{}
2316 ;; Produce `Day Month Year Hour:Min' style of output.
2317 ;; eg `1 Jan 1900 13:52'
2318
2319 (put 'timestamp 'texinfo-format 'texinfo-format-timestamp)
2320
2321 ;; The `@timestamp{}' command requires a pair of braces, like `@dots{}'.
2322 (defun texinfo-format-timestamp ()
2323 "Insert the current local time and date."
2324 (texinfo-parse-arg-discard)
2325 ;; For seconds and time zone, replace format string with "%e %b %Y %T %Z"
2326 (insert (format-time-string "%e %b %Y %R")))
2327
2328 \f
2329 ;;; @ignore
2330
2331 (put 'ignore 'texinfo-format 'texinfo-format-ignore)
2332 (defun texinfo-format-ignore ()
2333 (delete-region texinfo-command-start
2334 (re-search-forward "@end ignore[ \t]*\n")))
2335
2336 (put 'endignore 'texinfo-format 'texinfo-discard-line)
2337
2338 \f
2339 ;;; Define the Info enclosure command: @definfoenclose
2340
2341 ;; A `@definfoenclose' command may be used to define a highlighting
2342 ;; command for Info, but not for TeX. A command defined using
2343 ;; `@definfoenclose' marks text by enclosing it in strings that precede
2344 ;; and follow the text.
2345 ;;
2346 ;; Presumably, if you define a command with `@definfoenclose` for Info,
2347 ;; you will also define the same command in the TeX definitions file,
2348 ;; `texinfo.tex' in a manner appropriate for typesetting.
2349 ;;
2350 ;; Write a `@definfoenclose' command on a line and follow it with three
2351 ;; arguments separated by commas (commas are used as separators in an
2352 ;; `@node' line in the same way). The first argument to
2353 ;; `@definfoenclose' is the @-command name \(without the `@'\); the
2354 ;; second argument is the Info start delimiter string; and the third
2355 ;; argument is the Info end delimiter string. The latter two arguments
2356 ;; enclose the highlighted text in the Info file. A delimiter string
2357 ;; may contain spaces. Neither the start nor end delimiter is
2358 ;; required. However, if you do not provide a start delimiter, you
2359 ;; must follow the command name with two commas in a row; otherwise,
2360 ;; the Info formatting commands will misinterpret the end delimiter
2361 ;; string as a start delimiter string.
2362 ;;
2363 ;; If you do a @definfoenclose{} on the name of a pre-defined macro (such
2364 ;; as @emph{}, @strong{}, @tt{}, or @i{}) the enclosure definition will
2365 ;; override the built-in definition.
2366 ;;
2367 ;; An enclosure command defined this way takes one argument in braces.
2368 ;;
2369 ;; For example, you can write:
2370 ;;
2371 ;; @ifinfo
2372 ;; @definfoenclose phoo, //, \\
2373 ;; @end ifinfo
2374 ;;
2375 ;; near the beginning of a Texinfo file at the beginning of the lines
2376 ;; to define `@phoo' as an Info formatting command that inserts `//'
2377 ;; before and `\\' after the argument to `@phoo'. You can then write
2378 ;; `@phoo{bar}' wherever you want `//bar\\' highlighted in Info.
2379 ;;
2380 ;; Also, for TeX formatting, you could write
2381 ;;
2382 ;; @iftex
2383 ;; @global@let@phoo=@i
2384 ;; @end iftex
2385 ;;
2386 ;; to define `@phoo' as a command that causes TeX to typeset
2387 ;; the argument to `@phoo' in italics.
2388 ;;
2389 ;; Note that each definition applies to its own formatter: one for TeX,
2390 ;; the other for texinfo-format-buffer or texinfo-format-region.
2391 ;;
2392 ;; Here is another example: write
2393 ;;
2394 ;; @definfoenclose headword, , :
2395 ;;
2396 ;; near the beginning of the file, to define `@headword' as an Info
2397 ;; formatting command that inserts nothing before and a colon after the
2398 ;; argument to `@headword'.
2399
2400 (put 'definfoenclose 'texinfo-format 'texinfo-define-info-enclosure)
2401 (defun texinfo-define-info-enclosure ()
2402 (let* ((args (texinfo-format-parse-line-args))
2403 (command-name (nth 0 args))
2404 (beginning-delimiter (or (nth 1 args) ""))
2405 (end-delimiter (or (nth 2 args) "")))
2406 (texinfo-discard-command)
2407 (push (list command-name
2408 (list
2409 beginning-delimiter
2410 end-delimiter))
2411 texinfo-enclosure-list)))
2412
2413 \f
2414 ;;; @alias
2415
2416 (put 'alias 'texinfo-format 'texinfo-alias)
2417 (defun texinfo-alias ()
2418 (let ((start (1- (point)))
2419 args)
2420 (skip-chars-forward " ")
2421 (save-excursion (end-of-line) (setq texinfo-command-end (point)))
2422 (if (not (looking-at "\\([^=]+\\)=\\(.*\\)"))
2423 (error "Invalid alias command")
2424 (push (cons
2425 (match-string-no-properties 1)
2426 (match-string-no-properties 2))
2427 texinfo-alias-list)
2428 (texinfo-discard-command))
2429 )
2430 )
2431
2432 \f
2433 ;;; @var, @code and the like
2434
2435 (put 'var 'texinfo-format 'texinfo-format-var)
2436 ;; @sc a small caps font for TeX; formatted as `var' in Info
2437 (put 'sc 'texinfo-format 'texinfo-format-var)
2438 ;; @acronym for abbreviations in all caps, such as `NASA'.
2439 ;; Convert all letters to uppercase if they are not already.
2440 (put 'acronym 'texinfo-format 'texinfo-format-var)
2441 (defun texinfo-format-var ()
2442 (let ((arg (texinfo-parse-expanded-arg)))
2443 (texinfo-discard-command)
2444 (insert (upcase arg))))
2445
2446 (put 'cite 'texinfo-format 'texinfo-format-code)
2447 (put 'code 'texinfo-format 'texinfo-format-code)
2448 ;; @command (for command names)
2449 (put 'command 'texinfo-format 'texinfo-format-code)
2450 ;; @env (for environment variables)
2451 (put 'env 'texinfo-format 'texinfo-format-code)
2452 (put 'file 'texinfo-format 'texinfo-format-code)
2453 (put 'samp 'texinfo-format 'texinfo-format-code)
2454 (put 'url 'texinfo-format 'texinfo-format-code)
2455 (defun texinfo-format-code ()
2456 (insert "`" (texinfo-parse-arg-discard) "'")
2457 (goto-char texinfo-command-start))
2458
2459 ;; @option (for command-line options) must be different from @code
2460 ;; because of its special formatting in @table; namely that it does
2461 ;; not lead to inserted ` ... ' in a table, but does elsewhere.
2462 (put 'option 'texinfo-format 'texinfo-format-option)
2463 (defun texinfo-format-option ()
2464 "Insert ` ... ' around arg unless inside a table; in that case, no quotes."
2465 ;; `looking-at-backward' not available in v. 18.57, 20.2
2466 (if (not (search-backward "\b" ; searched-for character is a control-H
2467 (save-excursion (beginning-of-line) (point))
2468 t))
2469 (insert "`" (texinfo-parse-arg-discard) "'")
2470 (insert (texinfo-parse-arg-discard)))
2471 (goto-char texinfo-command-start))
2472
2473 (put 'emph 'texinfo-format 'texinfo-format-emph)
2474 (put 'strong 'texinfo-format 'texinfo-format-emph)
2475 (defun texinfo-format-emph ()
2476 (insert "*" (texinfo-parse-arg-discard) "*")
2477 (goto-char texinfo-command-start))
2478
2479 (put 'dfn 'texinfo-format 'texinfo-format-defn)
2480 (put 'defn 'texinfo-format 'texinfo-format-defn)
2481 (defun texinfo-format-defn ()
2482 (insert "\"" (texinfo-parse-arg-discard) "\"")
2483 (goto-char texinfo-command-start))
2484
2485 (put 'email 'texinfo-format 'texinfo-format-email)
2486 (defun texinfo-format-email ()
2487 "Format email address and optional following full name.
2488 Insert full name, if present, followed by email address
2489 surrounded by in angle brackets."
2490 (let ((args (texinfo-format-parse-args)))
2491 (texinfo-discard-command)
2492 ;; if full-name
2493 (if (nth 1 args)
2494 (insert (nth 1 args) " "))
2495 (insert "<" (nth 0 args) ">")))
2496
2497 (put 'key 'texinfo-format 'texinfo-format-key)
2498 ;; I've decided not want to have angle brackets around these -- rms.
2499 (defun texinfo-format-key ()
2500 (insert (texinfo-parse-arg-discard))
2501 (goto-char texinfo-command-start))
2502
2503 ;; @verb{<char>TEXT<char>} (in `makeinfo' 4.1 and later)
2504 (put 'verb 'texinfo-format 'texinfo-format-verb)
2505 (defun texinfo-format-verb ()
2506 "Format text between non-quoted unique delimiter characters verbatim.
2507 Enclose the verbatim text, including the delimiters, in braces. Print
2508 text exactly as written (but not the delimiters) in a fixed-width.
2509
2510 For example, @verb\{|@|\} results in @ and
2511 @verb\{+@'e?`!`+} results in @'e?`!`."
2512
2513 (let ((delimiter (buffer-substring-no-properties
2514 (1+ texinfo-command-end) (+ 2 texinfo-command-end))))
2515 (unless (looking-at "{")
2516 (error "Not found: @verb start brace"))
2517 (delete-region texinfo-command-start (+ 2 texinfo-command-end))
2518 (search-forward delimiter))
2519 (delete-backward-char 1)
2520 (unless (looking-at "}")
2521 (error "Not found: @verb end brace"))
2522 (delete-char 1))
2523
2524 ;; as of 2002 Dec 10
2525 ;; see (texinfo)Block Enclosing Commands
2526 ;; need: @verbatim
2527
2528 ;; as of 2002 Dec 10
2529 ;; see (texinfo)verbatiminclude
2530 ;; need: @verbatiminclude FILENAME
2531
2532 (put 'bullet 'texinfo-format 'texinfo-format-bullet)
2533 (defun texinfo-format-bullet ()
2534 "Insert an asterisk.
2535 If used within a line, follow `@bullet' with braces."
2536 (texinfo-optional-braces-discard)
2537 (insert "*"))
2538
2539 \f
2540 ;;; @kbd
2541
2542 ;; Inside of @example ... @end example and similar environments,
2543 ;; @kbd does nothing; but outside of such environments, it places
2544 ;; single quotation marks around its argument.
2545
2546 (defvar texinfo-format-kbd-regexp
2547 (concat
2548 "^@"
2549 "\\("
2550 "display\\|"
2551 "example\\|"
2552 "smallexample\\|"
2553 "lisp\\|"
2554 "smalllisp"
2555 "\\)")
2556 "Regexp matching environments in which @kbd does not put `...' around arg.")
2557
2558 (defvar texinfo-format-kbd-end-regexp
2559 (concat
2560 "^@end "
2561 "\\("
2562 "display\\|"
2563 "example\\|"
2564 "smallexample\\|"
2565 "lisp\\|"
2566 "smalllisp"
2567 "\\)")
2568 "Regexp specifying end of environments in which @kbd does not put `...'
2569 around argument. (See `texinfo-format-kbd-regexp')")
2570
2571 (put 'kbd 'texinfo-format 'texinfo-format-kbd)
2572 (defun texinfo-format-kbd ()
2573 "Place single quote marks around arg, except in @example and similar."
2574 ;; Search forward for @end example closer than an @example.
2575 ;; Can stop search at nearest @node or texinfo-section-types-regexp
2576 (let* ((stop
2577 (save-excursion
2578 (re-search-forward
2579 (concat "^@node\\|\\(" texinfo-section-types-regexp "\\)")
2580 nil
2581 'move-to-end) ; if necessary, return point at end of buffer
2582 (point)))
2583 (example-location
2584 (save-excursion
2585 (re-search-forward texinfo-format-kbd-regexp stop 'move-to-end)
2586 (point)))
2587 (end-example-location
2588 (save-excursion
2589 (re-search-forward texinfo-format-kbd-end-regexp stop 'move-to-end)
2590 (point))))
2591 ;; If inside @example, @end example will be closer than @example
2592 ;; or end of search i.e., end-example-location less than example-location
2593 (if (>= end-example-location example-location)
2594 ;; outside an @example or equivalent
2595 (insert "`" (texinfo-parse-arg-discard) "'")
2596 ;; else, in @example; do not surround with `...'
2597 (insert (texinfo-parse-arg-discard)))
2598 (goto-char texinfo-command-start)))
2599
2600 \f
2601 ;;; @example, @lisp, @quotation, @display, @smalllisp, @smallexample,
2602 ;; @smalldisplay
2603
2604 (put 'display 'texinfo-format 'texinfo-format-example)
2605 (put 'smalldisplay 'texinfo-format 'texinfo-format-example)
2606 (put 'example 'texinfo-format 'texinfo-format-example)
2607 (put 'lisp 'texinfo-format 'texinfo-format-example)
2608 (put 'quotation 'texinfo-format 'texinfo-format-example)
2609 (put 'smallexample 'texinfo-format 'texinfo-format-example)
2610 (put 'smalllisp 'texinfo-format 'texinfo-format-example)
2611 (defun texinfo-format-example ()
2612 (texinfo-push-stack 'example nil)
2613 (setq fill-column (- fill-column 5))
2614 (texinfo-discard-line))
2615
2616 (put 'example 'texinfo-end 'texinfo-end-example)
2617 (put 'display 'texinfo-end 'texinfo-end-example)
2618 (put 'smalldisplay 'texinfo-end 'texinfo-end-example)
2619 (put 'lisp 'texinfo-end 'texinfo-end-example)
2620 (put 'quotation 'texinfo-end 'texinfo-end-example)
2621 (put 'smallexample 'texinfo-end 'texinfo-end-example)
2622 (put 'smalllisp 'texinfo-end 'texinfo-end-example)
2623 (defun texinfo-end-example ()
2624 (setq fill-column (+ fill-column 5))
2625 (texinfo-discard-command)
2626 (let ((stacktop
2627 (texinfo-pop-stack 'example)))
2628 (texinfo-do-itemize (nth 1 stacktop))))
2629
2630 (put 'exdent 'texinfo-format 'texinfo-format-exdent)
2631 (defun texinfo-format-exdent ()
2632 (texinfo-discard-command)
2633 (delete-region (point)
2634 (progn
2635 (skip-chars-forward " ")
2636 (point)))
2637 (insert ?\b)
2638 ;; Cancel out the deletion that texinfo-do-itemize
2639 ;; is going to do at the end of this line.
2640 (save-excursion
2641 (end-of-line)
2642 (insert "\n ")))
2643
2644 \f
2645 ;; @direntry and @dircategory
2646
2647 (put 'direntry 'texinfo-format 'texinfo-format-direntry)
2648 (defun texinfo-format-direntry ()
2649 (texinfo-push-stack 'direntry nil)
2650 (texinfo-discard-line)
2651 (insert "START-INFO-DIR-ENTRY\n"))
2652
2653 (put 'direntry 'texinfo-end 'texinfo-end-direntry)
2654 (defun texinfo-end-direntry ()
2655 (texinfo-discard-command)
2656 (insert "END-INFO-DIR-ENTRY\n\n")
2657 (texinfo-pop-stack 'direntry))
2658
2659 (put 'dircategory 'texinfo-format 'texinfo-format-dircategory)
2660 (defun texinfo-format-dircategory ()
2661 (let ((str (texinfo-parse-arg-discard)))
2662 (delete-region (point)
2663 (progn
2664 (skip-chars-forward " ")
2665 (point)))
2666 (insert "INFO-DIR-SECTION " str "\n")))
2667 \f
2668 ;;; @cartouche
2669
2670 ;; The @cartouche command is a noop in Info; in a printed manual,
2671 ;; it makes a box with rounded corners.
2672
2673 (put 'cartouche 'texinfo-format 'texinfo-discard-line)
2674 (put 'cartouche 'texinfo-end 'texinfo-discard-command)
2675
2676 \f
2677 ;;; @flushleft and @format
2678
2679 ;; The @flushleft command left justifies every line but leaves the
2680 ;; right end ragged. As far as Info is concerned, @flushleft is a
2681 ;; `do-nothing' command
2682
2683 ;; The @format command is similar to @example except that it does not
2684 ;; indent; this means that in Info, @format is similar to @flushleft.
2685
2686 (put 'format 'texinfo-format 'texinfo-format-flushleft)
2687 (put 'smallformat 'texinfo-format 'texinfo-format-flushleft)
2688 (put 'flushleft 'texinfo-format 'texinfo-format-flushleft)
2689 (defun texinfo-format-flushleft ()
2690 (texinfo-discard-line))
2691
2692 (put 'format 'texinfo-end 'texinfo-end-flushleft)
2693 (put 'smallformat 'texinfo-end 'texinfo-end-flushleft)
2694 (put 'flushleft 'texinfo-end 'texinfo-end-flushleft)
2695 (defun texinfo-end-flushleft ()
2696 (texinfo-discard-command))
2697
2698 \f
2699 ;;; @flushright
2700
2701 ;; The @flushright command right justifies every line but leaves the
2702 ;; left end ragged. Spaces and tabs at the right ends of lines are
2703 ;; removed so that visible text lines up on the right side.
2704
2705 (put 'flushright 'texinfo-format 'texinfo-format-flushright)
2706 (defun texinfo-format-flushright ()
2707 (texinfo-push-stack 'flushright nil)
2708 (texinfo-discard-line))
2709
2710 (put 'flushright 'texinfo-end 'texinfo-end-flushright)
2711 (defun texinfo-end-flushright ()
2712 (texinfo-discard-command)
2713
2714 (let ((stacktop
2715 (texinfo-pop-stack 'flushright)))
2716
2717 (texinfo-do-flushright (nth 1 stacktop))))
2718
2719 (defun texinfo-do-flushright (from)
2720 (save-excursion
2721 (while (progn (forward-line -1)
2722 (>= (point) from))
2723
2724 (beginning-of-line)
2725 (insert
2726 (make-string
2727 (- fill-column
2728 (save-excursion
2729 (end-of-line)
2730 (skip-chars-backward " \t")
2731 (delete-region (point) (progn (end-of-line) (point)))
2732 (current-column)))
2733 ? )))))
2734
2735 \f
2736 ;;; @ctrl, @TeX, @copyright, @minus, @dots, @enddots, @pounds
2737
2738 (put 'ctrl 'texinfo-format 'texinfo-format-ctrl)
2739 (defun texinfo-format-ctrl ()
2740 (let ((str (texinfo-parse-arg-discard)))
2741 (insert (logand 31 (aref str 0)))))
2742
2743 (put 'TeX 'texinfo-format 'texinfo-format-TeX)
2744 (defun texinfo-format-TeX ()
2745 (texinfo-parse-arg-discard)
2746 (insert "TeX"))
2747
2748 (put 'copyright 'texinfo-format 'texinfo-format-copyright)
2749 (defun texinfo-format-copyright ()
2750 (texinfo-parse-arg-discard)
2751 (insert "(C)"))
2752
2753 (put 'minus 'texinfo-format 'texinfo-format-minus)
2754 (defun texinfo-format-minus ()
2755 "Insert a minus sign.
2756 If used within a line, follow `@minus' with braces."
2757 (texinfo-optional-braces-discard)
2758 (insert "-"))
2759
2760 (put 'dots 'texinfo-format 'texinfo-format-dots)
2761 (defun texinfo-format-dots ()
2762 (texinfo-parse-arg-discard)
2763 (insert "..."))
2764
2765 (put 'enddots 'texinfo-format 'texinfo-format-enddots)
2766 (defun texinfo-format-enddots ()
2767 (texinfo-parse-arg-discard)
2768 (insert "...."))
2769
2770 (put 'pounds 'texinfo-format 'texinfo-format-pounds)
2771 (defun texinfo-format-pounds ()
2772 (texinfo-parse-arg-discard)
2773 (insert "#"))
2774
2775 \f
2776 ;;; Refilling and indenting: @refill, @paragraphindent, @noindent
2777
2778 ;; Indent only those paragraphs that are refilled as a result of an
2779 ;; @refill command.
2780
2781 ;; * If the value is `asis', do not change the existing indentation at
2782 ;; the starts of paragraphs.
2783
2784 ;; * If the value zero, delete any existing indentation.
2785
2786 ;; * If the value is greater than zero, indent each paragraph by that
2787 ;; number of spaces.
2788
2789 ;; But do not refill paragraphs with an @refill command that are
2790 ;; preceded by @noindent or are part of a table, list, or deffn.
2791
2792 (defvar texinfo-paragraph-indent "asis"
2793 "Number of spaces for @refill to indent a paragraph; else to leave as is.")
2794
2795 (put 'paragraphindent 'texinfo-format 'texinfo-paragraphindent)
2796
2797 (defun texinfo-paragraphindent ()
2798 "Specify the number of spaces for @refill to indent a paragraph.
2799 Default is to leave the number of spaces as is."
2800 (let ((arg (texinfo-parse-arg-discard)))
2801 (if (string= "asis" arg)
2802 (setq texinfo-paragraph-indent "asis")
2803 (setq texinfo-paragraph-indent (string-to-number arg)))))
2804
2805 (put 'refill 'texinfo-format 'texinfo-format-refill)
2806 (defun texinfo-format-refill ()
2807 "Refill paragraph. Also, indent first line as set by @paragraphindent.
2808 Default is to leave paragraph indentation as is."
2809 (texinfo-discard-command)
2810 (let ((position (point-marker)))
2811 (forward-paragraph -1)
2812 (if (looking-at "[ \t\n]*$") (forward-line 1))
2813 ;; Do not indent if an entry in a list, table, or deffn,
2814 ;; or if paragraph is preceded by @noindent.
2815 ;; Otherwise, indent
2816 (cond
2817 ;; delete a @noindent line and do not indent paragraph
2818 ((save-excursion (forward-line -1)
2819 (looking-at "^@noindent"))
2820 (forward-line -1)
2821 (delete-region (point) (progn (forward-line 1) (point))))
2822 ;; do nothing if "asis"
2823 ((equal texinfo-paragraph-indent "asis"))
2824 ;; do no indenting in list, etc.
2825 ((> texinfo-stack-depth 0))
2826 ;; otherwise delete existing whitespace and indent
2827 (t
2828 (delete-region (point) (progn (skip-chars-forward " \t") (point)))
2829 (insert (make-string texinfo-paragraph-indent ? ))))
2830 (forward-paragraph 1)
2831 (forward-line -1)
2832 (end-of-line)
2833 ;; Do not fill a section title line with asterisks, hyphens, etc. that
2834 ;; are used to underline it. This could occur if the line following
2835 ;; the underlining is not an index entry and has text within it.
2836 (let* ((previous-paragraph-separate paragraph-separate)
2837 (paragraph-separate
2838 (concat paragraph-separate "\\|[-=.]+\\|\\*\\*+"))
2839 (previous-paragraph-start paragraph-start)
2840 (paragraph-start
2841 (concat paragraph-start "\\|[-=.]+\\|\\*\\*+")))
2842 (unwind-protect
2843 (fill-paragraph nil)
2844 (setq paragraph-separate previous-paragraph-separate)
2845 (setq paragraph-start previous-paragraph-start)))
2846 (goto-char position)))
2847
2848 (put 'noindent 'texinfo-format 'texinfo-noindent)
2849 (defun texinfo-noindent ()
2850 (save-excursion
2851 (forward-paragraph 1)
2852 (if (search-backward "@refill"
2853 (save-excursion (forward-line -1) (point)) t)
2854 () ; leave @noindent command so @refill command knows not to indent
2855 ;; else
2856 (texinfo-discard-line))))
2857
2858 \f
2859 ;;; Index generation
2860
2861 (put 'vindex 'texinfo-format 'texinfo-format-vindex)
2862 (defun texinfo-format-vindex ()
2863 (texinfo-index 'texinfo-vindex))
2864
2865 (put 'cindex 'texinfo-format 'texinfo-format-cindex)
2866 (defun texinfo-format-cindex ()
2867 (texinfo-index 'texinfo-cindex))
2868
2869 (put 'findex 'texinfo-format 'texinfo-format-findex)
2870 (defun texinfo-format-findex ()
2871 (texinfo-index 'texinfo-findex))
2872
2873 (put 'pindex 'texinfo-format 'texinfo-format-pindex)
2874 (defun texinfo-format-pindex ()
2875 (texinfo-index 'texinfo-pindex))
2876
2877 (put 'tindex 'texinfo-format 'texinfo-format-tindex)
2878 (defun texinfo-format-tindex ()
2879 (texinfo-index 'texinfo-tindex))
2880
2881 (put 'kindex 'texinfo-format 'texinfo-format-kindex)
2882 (defun texinfo-format-kindex ()
2883 (texinfo-index 'texinfo-kindex))
2884
2885 (defun texinfo-index (indexvar)
2886 (let ((arg (texinfo-parse-expanded-arg)))
2887 (texinfo-discard-command)
2888 (set indexvar
2889 (cons (list arg
2890 texinfo-last-node
2891 ;; Region formatting may not provide last node position.
2892 (if texinfo-last-node-pos
2893 (1+ (count-lines texinfo-last-node-pos (point)))
2894 1))
2895 (symbol-value indexvar)))))
2896
2897 (defvar texinfo-indexvar-alist
2898 '(("cp" . texinfo-cindex)
2899 ("fn" . texinfo-findex)
2900 ("vr" . texinfo-vindex)
2901 ("tp" . texinfo-tindex)
2902 ("pg" . texinfo-pindex)
2903 ("ky" . texinfo-kindex)))
2904
2905 \f
2906 ;;; @defindex @defcodeindex
2907 (put 'defindex 'texinfo-format 'texinfo-format-defindex)
2908 (put 'defcodeindex 'texinfo-format 'texinfo-format-defindex)
2909
2910 (defun texinfo-format-defindex ()
2911 (let* ((index-name (texinfo-parse-arg-discard)) ; eg: `aa'
2912 (indexing-command (intern (concat index-name "index")))
2913 (index-formatting-command ; eg: `texinfo-format-aaindex'
2914 (intern (concat "texinfo-format-" index-name "index")))
2915 (index-alist-name ; eg: `texinfo-aaindex'
2916 (intern (concat "texinfo-" index-name "index"))))
2917
2918 (set index-alist-name nil)
2919
2920 (put indexing-command ; eg, aaindex
2921 'texinfo-format
2922 index-formatting-command) ; eg, texinfo-format-aaindex
2923
2924 ;; eg: "aa" . texinfo-aaindex
2925 (or (assoc index-name texinfo-indexvar-alist)
2926 (push (cons index-name
2927 index-alist-name)
2928 texinfo-indexvar-alist))
2929
2930 (fset index-formatting-command
2931 (list 'lambda 'nil
2932 (list 'texinfo-index
2933 (list 'quote index-alist-name))))))
2934
2935 \f
2936 ;;; @synindex @syncodeindex
2937
2938 (put 'synindex 'texinfo-format 'texinfo-format-synindex)
2939 (put 'syncodeindex 'texinfo-format 'texinfo-format-synindex)
2940
2941 (defun texinfo-format-synindex ()
2942 (let* ((args (texinfo-parse-arg-discard))
2943 (second (cdr (read-from-string args)))
2944 (joiner (symbol-name (car (read-from-string args))))
2945 (joined (symbol-name (car (read-from-string args second)))))
2946
2947 (if (assoc joiner texinfo-short-index-cmds-alist)
2948 (put
2949 (cdr (assoc joiner texinfo-short-index-cmds-alist))
2950 'texinfo-format
2951 (or (cdr (assoc joined texinfo-short-index-format-cmds-alist))
2952 (intern (concat "texinfo-format-" joined "index"))))
2953 (put
2954 (intern (concat joiner "index"))
2955 'texinfo-format
2956 (or (cdr(assoc joined texinfo-short-index-format-cmds-alist))
2957 (intern (concat "texinfo-format-" joined "index")))))))
2958
2959 (defconst texinfo-short-index-cmds-alist
2960 '(("cp" . cindex)
2961 ("fn" . findex)
2962 ("vr" . vindex)
2963 ("tp" . tindex)
2964 ("pg" . pindex)
2965 ("ky" . kindex)))
2966
2967 (defconst texinfo-short-index-format-cmds-alist
2968 '(("cp" . texinfo-format-cindex)
2969 ("fn" . texinfo-format-findex)
2970 ("vr" . texinfo-format-vindex)
2971 ("tp" . texinfo-format-tindex)
2972 ("pg" . texinfo-format-pindex)
2973 ("ky" . texinfo-format-kindex)))
2974
2975 \f
2976 ;;; Sort and index (for VMS)
2977
2978 ;; Sort an index which is in the current buffer between START and END.
2979 ;; Used on VMS, where the `sort' utility is not available.
2980 (defun texinfo-sort-region (start end)
2981 (require 'sort)
2982 (save-restriction
2983 (narrow-to-region start end)
2984 (goto-char (point-min))
2985 (sort-subr nil 'forward-line 'end-of-line 'texinfo-sort-startkeyfun)))
2986
2987 ;; Subroutine for sorting an index.
2988 ;; At start of a line, return a string to sort the line under.
2989 (defun texinfo-sort-startkeyfun ()
2990 (let ((line (buffer-substring-no-properties (point) (line-end-position))))
2991 ;; Canonicalize whitespace and eliminate funny chars.
2992 (while (string-match "[ \t][ \t]+\\|[^a-z0-9 ]+" line)
2993 (setq line (concat (substring line 0 (match-beginning 0))
2994 " "
2995 (substring line (match-end 0)))))
2996 line))
2997
2998 \f
2999 ;;; @printindex
3000
3001 (put 'printindex 'texinfo-format 'texinfo-format-printindex)
3002
3003 (defun texinfo-format-printindex ()
3004 (let ((indexelts (symbol-value
3005 (cdr (assoc (texinfo-parse-arg-discard)
3006 texinfo-indexvar-alist))))
3007 opoint)
3008 (insert "\n* Menu:\n\n")
3009 (setq opoint (point))
3010 (texinfo-print-index nil indexelts)
3011
3012 (if (memq system-type '(vax-vms windows-nt ms-dos))
3013 (texinfo-sort-region opoint (point))
3014 (shell-command-on-region opoint (point) "sort -fd" 1))))
3015
3016 (defun texinfo-print-index (file indexelts)
3017 (while indexelts
3018 (if (stringp (car (car indexelts)))
3019 (progn
3020 (insert "* " (car (car indexelts)) ": " )
3021 (indent-to 32)
3022 (insert
3023 (if file (concat "(" file ")") "")
3024 (nth 1 (car indexelts)) ".")
3025 (indent-to 54)
3026 (insert
3027 (if (nth 2 (car indexelts))
3028 (format " (line %3d)" (1+ (nth 2 (car indexelts))))
3029 "")
3030 "\n"))
3031 ;; index entries from @include'd file
3032 (texinfo-print-index (nth 1 (car indexelts))
3033 (nth 2 (car indexelts))))
3034 (setq indexelts (cdr indexelts))))
3035
3036 \f
3037 ;;; Glyphs: @equiv, @error, etc
3038
3039 ;; @equiv to show that two expressions are equivalent
3040 ;; @error to show an error message
3041 ;; @expansion to show what a macro expands to
3042 ;; @point to show the location of point in an example
3043 ;; @print to show what an evaluated expression prints
3044 ;; @result to indicate the value returned by an expression
3045
3046 (put 'equiv 'texinfo-format 'texinfo-format-equiv)
3047 (defun texinfo-format-equiv ()
3048 (texinfo-parse-arg-discard)
3049 (insert "=="))
3050
3051 (put 'error 'texinfo-format 'texinfo-format-error)
3052 (defun texinfo-format-error ()
3053 (texinfo-parse-arg-discard)
3054 (insert "error-->"))
3055
3056 (put 'expansion 'texinfo-format 'texinfo-format-expansion)
3057 (defun texinfo-format-expansion ()
3058 (texinfo-parse-arg-discard)
3059 (insert "==>"))
3060
3061 (put 'point 'texinfo-format 'texinfo-format-point)
3062 (defun texinfo-format-point ()
3063 (texinfo-parse-arg-discard)
3064 (insert "-!-"))
3065
3066 (put 'print 'texinfo-format 'texinfo-format-print)
3067 (defun texinfo-format-print ()
3068 (texinfo-parse-arg-discard)
3069 (insert "-|"))
3070
3071 (put 'result 'texinfo-format 'texinfo-format-result)
3072 (defun texinfo-format-result ()
3073 (texinfo-parse-arg-discard)
3074 (insert "=>"))
3075
3076 \f
3077 ;;; Accent commands
3078
3079 ;; Info presumes a plain ASCII output, so the accented characters do
3080 ;; not look as they would if typeset, or output with a different
3081 ;; character set.
3082
3083 ;; See the `texinfo-accent-commands' variable
3084 ;; in the section for `texinfo-append-refill'.
3085 ;; Also, see the defun for `texinfo-format-scan'
3086 ;; for single-character accent commands.
3087
3088 ;; Command Info output Name
3089
3090 ;; These do not have braces:
3091 ;; @^ ==> ^ circumflex accent
3092 ;; @` ==> ` grave accent
3093 ;; @' ==> ' acute accent
3094 ;; @" ==> " umlaut accent
3095 ;; @= ==> = overbar accent
3096 ;; @~ ==> ~ tilde accent
3097
3098 ;; These have braces, but take no argument:
3099 ;; @OE{} ==> OE French-OE-ligature
3100 ;; @oe{} ==> oe
3101 ;; @AA{} ==> AA Scandinavian-A-with-circle
3102 ;; @aa{} ==> aa
3103 ;; @AE{} ==> AE Latin-Scandinavian-AE
3104 ;; @ae{} ==> ae
3105 ;; @ss{} ==> ss German-sharp-S
3106
3107 ;; @questiondown{} ==> ? upside-down-question-mark
3108 ;; @exclamdown{} ==> ! upside-down-exclamation-mark
3109 ;; @L{} ==> L/ Polish suppressed-L (Lslash)
3110 ;; @l{} ==> l/ Polish suppressed-L (Lslash) (lower case)
3111 ;; @O{} ==> O/ Scandinavian O-with-slash
3112 ;; @o{} ==> o/ Scandinavian O-with-slash (lower case)
3113
3114 ;; These have braces, and take an argument:
3115 ;; @,{c} ==> c, cedilla accent
3116 ;; @dotaccent{o} ==> .o overdot-accent
3117 ;; @ubaraccent{o} ==> _o underbar-accent
3118 ;; @udotaccent{o} ==> o-. underdot-accent
3119 ;; @H{o} ==> ""o long Hungarian umlaut
3120 ;; @ringaccent{o} ==> *o ring accent
3121 ;; @tieaccent{oo} ==> [oo tie after accent
3122 ;; @u{o} ==> (o breve accent
3123 ;; @v{o} ==> <o hacek accent
3124 ;; @dotless{i} ==> i dotless i and dotless j
3125
3126 ;; ==========
3127
3128 ;; Note: The defun texinfo-format-scan
3129 ;; looks at "[@{}^'`\",=~ *?!-]"
3130 ;; In the case of @*, a line break is inserted;
3131 ;; in the other cases, the characters are simply quoted and the @ is deleted.
3132 ;; Thus, `texinfo-format-scan' handles the following
3133 ;; single-character accent commands: @^ @` @' @" @, @- @= @~
3134
3135 ;; @^ ==> ^ circumflex accent
3136 ;; (put '^ 'texinfo-format 'texinfo-format-circumflex-accent)
3137 ;; (defun texinfo-format-circumflex-accent ()
3138 ;; (texinfo-discard-command)
3139 ;; (insert "^"))
3140 ;;
3141 ;; @` ==> ` grave accent
3142 ;; (put '\` 'texinfo-format 'texinfo-format-grave-accent)
3143 ;; (defun texinfo-format-grave-accent ()
3144 ;; (texinfo-discard-command)
3145 ;; (insert "\`"))
3146 ;;
3147 ;; @' ==> ' acute accent
3148 ;; (put '\' 'texinfo-format 'texinfo-format-acute-accent)
3149 ;; (defun texinfo-format-acute-accent ()
3150 ;; (texinfo-discard-command)
3151 ;; (insert "'"))
3152 ;;
3153 ;; @" ==> " umlaut accent
3154 ;; (put '\" 'texinfo-format 'texinfo-format-umlaut-accent)
3155 ;; (defun texinfo-format-umlaut-accent ()
3156 ;; (texinfo-discard-command)
3157 ;; (insert "\""))
3158 ;;
3159 ;; @= ==> = overbar accent
3160 ;; (put '= 'texinfo-format 'texinfo-format-overbar-accent)
3161 ;; (defun texinfo-format-overbar-accent ()
3162 ;; (texinfo-discard-command)
3163 ;; (insert "="))
3164 ;;
3165 ;; @~ ==> ~ tilde accent
3166 ;; (put '~ 'texinfo-format 'texinfo-format-tilde-accent)
3167 ;; (defun texinfo-format-tilde-accent ()
3168 ;; (texinfo-discard-command)
3169 ;; (insert "~"))
3170
3171 ;; @OE{} ==> OE French-OE-ligature
3172 (put 'OE 'texinfo-format 'texinfo-format-French-OE-ligature)
3173 (defun texinfo-format-French-OE-ligature ()
3174 (insert "OE" (texinfo-parse-arg-discard))
3175 (goto-char texinfo-command-start))
3176
3177 ;; @oe{} ==> oe
3178 (put 'oe 'texinfo-format 'texinfo-format-French-oe-ligature)
3179 (defun texinfo-format-French-oe-ligature () ; lower case
3180 (insert "oe" (texinfo-parse-arg-discard))
3181 (goto-char texinfo-command-start))
3182
3183 ;; @AA{} ==> AA Scandinavian-A-with-circle
3184 (put 'AA 'texinfo-format 'texinfo-format-Scandinavian-A-with-circle)
3185 (defun texinfo-format-Scandinavian-A-with-circle ()
3186 (insert "AA" (texinfo-parse-arg-discard))
3187 (goto-char texinfo-command-start))
3188
3189 ;; @aa{} ==> aa
3190 (put 'aa 'texinfo-format 'texinfo-format-Scandinavian-a-with-circle)
3191 (defun texinfo-format-Scandinavian-a-with-circle () ; lower case
3192 (insert "aa" (texinfo-parse-arg-discard))
3193 (goto-char texinfo-command-start))
3194
3195 ;; @AE{} ==> AE Latin-Scandinavian-AE
3196 (put 'AE 'texinfo-format 'texinfo-format-Latin-Scandinavian-AE)
3197 (defun texinfo-format-Latin-Scandinavian-AE ()
3198 (insert "AE" (texinfo-parse-arg-discard))
3199 (goto-char texinfo-command-start))
3200
3201 ;; @ae{} ==> ae
3202 (put 'ae 'texinfo-format 'texinfo-format-Latin-Scandinavian-ae)
3203 (defun texinfo-format-Latin-Scandinavian-ae () ; lower case
3204 (insert "ae" (texinfo-parse-arg-discard))
3205 (goto-char texinfo-command-start))
3206
3207 ;; @ss{} ==> ss German-sharp-S
3208 (put 'ss 'texinfo-format 'texinfo-format-German-sharp-S)
3209 (defun texinfo-format-German-sharp-S ()
3210 (insert "ss" (texinfo-parse-arg-discard))
3211 (goto-char texinfo-command-start))
3212
3213 ;; @questiondown{} ==> ? upside-down-question-mark
3214 (put 'questiondown 'texinfo-format 'texinfo-format-upside-down-question-mark)
3215 (defun texinfo-format-upside-down-question-mark ()
3216 (insert "?" (texinfo-parse-arg-discard))
3217 (goto-char texinfo-command-start))
3218
3219 ;; @exclamdown{} ==> ! upside-down-exclamation-mark
3220 (put 'exclamdown 'texinfo-format 'texinfo-format-upside-down-exclamation-mark)
3221 (defun texinfo-format-upside-down-exclamation-mark ()
3222 (insert "!" (texinfo-parse-arg-discard))
3223 (goto-char texinfo-command-start))
3224
3225 ;; @L{} ==> L/ Polish suppressed-L (Lslash)
3226 (put 'L 'texinfo-format 'texinfo-format-Polish-suppressed-L)
3227 (defun texinfo-format-Polish-suppressed-L ()
3228 (insert (texinfo-parse-arg-discard) "/L")
3229 (goto-char texinfo-command-start))
3230
3231 ;; @l{} ==> l/ Polish suppressed-L (Lslash) (lower case)
3232 (put 'l 'texinfo-format 'texinfo-format-Polish-suppressed-l-lower-case)
3233 (defun texinfo-format-Polish-suppressed-l-lower-case ()
3234 (insert (texinfo-parse-arg-discard) "/l")
3235 (goto-char texinfo-command-start))
3236
3237
3238 ;; @O{} ==> O/ Scandinavian O-with-slash
3239 (put 'O 'texinfo-format 'texinfo-format-Scandinavian-O-with-slash)
3240 (defun texinfo-format-Scandinavian-O-with-slash ()
3241 (insert (texinfo-parse-arg-discard) "O/")
3242 (goto-char texinfo-command-start))
3243
3244 ;; @o{} ==> o/ Scandinavian O-with-slash (lower case)
3245 (put 'o 'texinfo-format 'texinfo-format-Scandinavian-o-with-slash-lower-case)
3246 (defun texinfo-format-Scandinavian-o-with-slash-lower-case ()
3247 (insert (texinfo-parse-arg-discard) "o/")
3248 (goto-char texinfo-command-start))
3249
3250 ;; Take arguments
3251
3252 ;; @,{c} ==> c, cedilla accent
3253 (put ', 'texinfo-format 'texinfo-format-cedilla-accent)
3254 (defun texinfo-format-cedilla-accent ()
3255 (insert (texinfo-parse-arg-discard) ",")
3256 (goto-char texinfo-command-start))
3257
3258
3259 ;; @dotaccent{o} ==> .o overdot-accent
3260 (put 'dotaccent 'texinfo-format 'texinfo-format-overdot-accent)
3261 (defun texinfo-format-overdot-accent ()
3262 (insert "." (texinfo-parse-arg-discard))
3263 (goto-char texinfo-command-start))
3264
3265 ;; @ubaraccent{o} ==> _o underbar-accent
3266 (put 'ubaraccent 'texinfo-format 'texinfo-format-underbar-accent)
3267 (defun texinfo-format-underbar-accent ()
3268 (insert "_" (texinfo-parse-arg-discard))
3269 (goto-char texinfo-command-start))
3270
3271 ;; @udotaccent{o} ==> o-. underdot-accent
3272 (put 'udotaccent 'texinfo-format 'texinfo-format-underdot-accent)
3273 (defun texinfo-format-underdot-accent ()
3274 (insert (texinfo-parse-arg-discard) "-.")
3275 (goto-char texinfo-command-start))
3276
3277 ;; @H{o} ==> ""o long Hungarian umlaut
3278 (put 'H 'texinfo-format 'texinfo-format-long-Hungarian-umlaut)
3279 (defun texinfo-format-long-Hungarian-umlaut ()
3280 (insert "\"\"" (texinfo-parse-arg-discard))
3281 (goto-char texinfo-command-start))
3282
3283 ;; @ringaccent{o} ==> *o ring accent
3284 (put 'ringaccent 'texinfo-format 'texinfo-format-ring-accent)
3285 (defun texinfo-format-ring-accent ()
3286 (insert "*" (texinfo-parse-arg-discard))
3287 (goto-char texinfo-command-start))
3288
3289 ;; @tieaccent{oo} ==> [oo tie after accent
3290 (put 'tieaccent 'texinfo-format 'texinfo-format-tie-after-accent)
3291 (defun texinfo-format-tie-after-accent ()
3292 (insert "[" (texinfo-parse-arg-discard))
3293 (goto-char texinfo-command-start))
3294
3295
3296 ;; @u{o} ==> (o breve accent
3297 (put 'u 'texinfo-format 'texinfo-format-breve-accent)
3298 (defun texinfo-format-breve-accent ()
3299 (insert "(" (texinfo-parse-arg-discard))
3300 (goto-char texinfo-command-start))
3301
3302 ;; @v{o} ==> <o hacek accent
3303 (put 'v 'texinfo-format 'texinfo-format-hacek-accent)
3304 (defun texinfo-format-hacek-accent ()
3305 (insert "<" (texinfo-parse-arg-discard))
3306 (goto-char texinfo-command-start))
3307
3308
3309 ;; @dotless{i} ==> i dotless i and dotless j
3310 (put 'dotless 'texinfo-format 'texinfo-format-dotless)
3311 (defun texinfo-format-dotless ()
3312 (insert (texinfo-parse-arg-discard))
3313 (goto-char texinfo-command-start))
3314
3315 \f
3316 ;;; Definition formatting: @deffn, @defun, etc
3317
3318 ;; What definition formatting produces:
3319 ;;
3320 ;; @deffn category name args...
3321 ;; In Info, `Category: name ARGS'
3322 ;; In index: name: node. line#.
3323 ;;
3324 ;; @defvr category name
3325 ;; In Info, `Category: name'
3326 ;; In index: name: node. line#.
3327 ;;
3328 ;; @deftp category name attributes...
3329 ;; `category name attributes...' Note: @deftp args in lower case.
3330 ;; In index: name: node. line#.
3331 ;;
3332 ;; Specialized function-like or variable-like entity:
3333 ;;
3334 ;; @defun, @defmac, @defspec, @defvar, @defopt
3335 ;;
3336 ;; @defun name args In Info, `Function: name ARGS'
3337 ;; @defmac name args In Info, `Macro: name ARGS'
3338 ;; @defvar name In Info, `Variable: name'
3339 ;; etc.
3340 ;; In index: name: node. line#.
3341 ;;
3342 ;; Generalized typed-function-like or typed-variable-like entity:
3343 ;; @deftypefn category data-type name args...
3344 ;; In Info, `Category: data-type name args...'
3345 ;; @deftypevr category data-type name
3346 ;; In Info, `Category: data-type name'
3347 ;; In index: name: node. line#.
3348 ;;
3349 ;; Specialized typed-function-like or typed-variable-like entity:
3350 ;; @deftypefun data-type name args...
3351 ;; In Info, `Function: data-type name ARGS'
3352 ;; In index: name: node. line#.
3353 ;;
3354 ;; @deftypevar data-type name
3355 ;; In Info, `Variable: data-type name'
3356 ;; In index: name: node. line#. but include args after name!?
3357 ;;
3358 ;; Generalized object oriented entity:
3359 ;; @defop category class name args...
3360 ;; In Info, `Category on class: name ARG'
3361 ;; In index: name on class: node. line#.
3362 ;;
3363 ;; @defcv category class name
3364 ;; In Info, `Category of class: name'
3365 ;; In index: name of class: node. line#.
3366 ;;
3367 ;; Specialized object oriented entity:
3368 ;; @defmethod class name args...
3369 ;; In Info, `Method on class: name ARGS'
3370 ;; In index: name on class: node. line#.
3371 ;;
3372 ;; @defivar class name
3373 ;; In Info, `Instance variable of class: name'
3374 ;; In index: name of class: node. line#.
3375
3376 \f
3377 ;;; The definition formatting functions
3378
3379 (defun texinfo-format-defun ()
3380 (texinfo-push-stack 'defun nil)
3381 (setq fill-column (- fill-column 5))
3382 (texinfo-format-defun-1 t))
3383
3384 (defun texinfo-end-defun ()
3385 (setq fill-column (+ fill-column 5))
3386 (texinfo-discard-command)
3387 (let ((start (nth 1 (texinfo-pop-stack 'defun))))
3388 (texinfo-do-itemize start)
3389 ;; Delete extra newline inserted after header.
3390 (save-excursion
3391 (goto-char start)
3392 (delete-char -1))))
3393
3394 (defun texinfo-format-defunx ()
3395 (texinfo-format-defun-1 nil))
3396
3397 (defun texinfo-format-defun-1 (first-p)
3398 (let ((parse-args (texinfo-format-parse-defun-args))
3399 (texinfo-defun-type (get texinfo-command-name 'texinfo-defun-type)))
3400 (texinfo-discard-command)
3401 ;; Delete extra newline inserted after previous header line.
3402 (if (not first-p)
3403 (delete-char -1))
3404 (funcall
3405 (get texinfo-command-name 'texinfo-deffn-formatting-property) parse-args)
3406 ;; Insert extra newline so that paragraph filling does not mess
3407 ;; with header line.
3408 (insert "\n\n")
3409 (rplaca (cdr (cdr (car texinfo-stack))) (point))
3410 (funcall
3411 (get texinfo-command-name 'texinfo-defun-indexing-property) parse-args)))
3412
3413 ;;; Formatting the first line of a definition
3414
3415 ;; @deffn, @defvr, @deftp
3416 (put 'deffn 'texinfo-deffn-formatting-property 'texinfo-format-deffn)
3417 (put 'deffnx 'texinfo-deffn-formatting-property 'texinfo-format-deffn)
3418 (put 'defvr 'texinfo-deffn-formatting-property 'texinfo-format-deffn)
3419 (put 'defvrx 'texinfo-deffn-formatting-property 'texinfo-format-deffn)
3420 (put 'deftp 'texinfo-deffn-formatting-property 'texinfo-format-deffn)
3421 (put 'deftpx 'texinfo-deffn-formatting-property 'texinfo-format-deffn)
3422 (defun texinfo-format-deffn (parsed-args)
3423 ;; Generalized function-like, variable-like, or generic data-type entity:
3424 ;; @deffn category name args...
3425 ;; In Info, `Category: name ARGS'
3426 ;; @deftp category name attributes...
3427 ;; `category name attributes...' Note: @deftp args in lower case.
3428 (let ((category (car parsed-args))
3429 (name (car (cdr parsed-args)))
3430 (args (cdr (cdr parsed-args))))
3431 (insert " -- " category ": " name)
3432 (while args
3433 (insert " "
3434 (if (or (= ?& (aref (car args) 0))
3435 (eq (eval (car texinfo-defun-type)) 'deftp-type))
3436 (car args)
3437 (upcase (car args))))
3438 (setq args (cdr args)))))
3439
3440 ;; @defun, @defmac, @defspec, @defvar, @defopt: Specialized, simple
3441 (put 'defun 'texinfo-deffn-formatting-property
3442 'texinfo-format-specialized-defun)
3443 (put 'defunx 'texinfo-deffn-formatting-property
3444 'texinfo-format-specialized-defun)
3445 (put 'defmac 'texinfo-deffn-formatting-property
3446 'texinfo-format-specialized-defun)
3447 (put 'defmacx 'texinfo-deffn-formatting-property
3448 'texinfo-format-specialized-defun)
3449 (put 'defspec 'texinfo-deffn-formatting-property
3450 'texinfo-format-specialized-defun)
3451 (put 'defspecx 'texinfo-deffn-formatting-property
3452 'texinfo-format-specialized-defun)
3453 (put 'defvar 'texinfo-deffn-formatting-property
3454 'texinfo-format-specialized-defun)
3455 (put 'defvarx 'texinfo-deffn-formatting-property
3456 'texinfo-format-specialized-defun)
3457 (put 'defopt 'texinfo-deffn-formatting-property
3458 'texinfo-format-specialized-defun)
3459 (put 'defoptx 'texinfo-deffn-formatting-property
3460 'texinfo-format-specialized-defun)
3461 (defun texinfo-format-specialized-defun (parsed-args)
3462 ;; Specialized function-like or variable-like entity:
3463 ;; @defun name args In Info, `Function: Name ARGS'
3464 ;; @defmac name args In Info, `Macro: Name ARGS'
3465 ;; @defvar name In Info, `Variable: Name'
3466 ;; Use cdr of texinfo-defun-type to determine category:
3467 (let ((category (car (cdr texinfo-defun-type)))
3468 (name (car parsed-args))
3469 (args (cdr parsed-args)))
3470 (insert " -- " category ": " name)
3471 (while args
3472 (insert " "
3473 (if (= ?& (aref (car args) 0))
3474 (car args)
3475 (upcase (car args))))
3476 (setq args (cdr args)))))
3477
3478 ;; @deftypefn, @deftypevr: Generalized typed
3479 (put 'deftypefn 'texinfo-deffn-formatting-property 'texinfo-format-deftypefn)
3480 (put 'deftypefnx 'texinfo-deffn-formatting-property 'texinfo-format-deftypefn)
3481 (put 'deftypevr 'texinfo-deffn-formatting-property 'texinfo-format-deftypefn)
3482 (put 'deftypevrx 'texinfo-deffn-formatting-property 'texinfo-format-deftypefn)
3483 (defun texinfo-format-deftypefn (parsed-args)
3484 ;; Generalized typed-function-like or typed-variable-like entity:
3485 ;; @deftypefn category data-type name args...
3486 ;; In Info, `Category: data-type name args...'
3487 ;; @deftypevr category data-type name
3488 ;; In Info, `Category: data-type name'
3489 ;; Note: args in lower case, unless modified in command line.
3490 (let ((category (car parsed-args))
3491 (data-type (car (cdr parsed-args)))
3492 (name (car (cdr (cdr parsed-args))))
3493 (args (cdr (cdr (cdr parsed-args)))))
3494 (insert " -- " category ": " data-type " " name)
3495 (while args
3496 (insert " " (car args))
3497 (setq args (cdr args)))))
3498
3499 ;; @deftypefun, @deftypevar: Specialized typed
3500 (put 'deftypefun 'texinfo-deffn-formatting-property 'texinfo-format-deftypefun)
3501 (put 'deftypefunx 'texinfo-deffn-formatting-property
3502 'texinfo-format-deftypefun)
3503 (put 'deftypevar 'texinfo-deffn-formatting-property 'texinfo-format-deftypefun)
3504 (put 'deftypevarx 'texinfo-deffn-formatting-property
3505 'texinfo-format-deftypefun)
3506 (defun texinfo-format-deftypefun (parsed-args)
3507 ;; Specialized typed-function-like or typed-variable-like entity:
3508 ;; @deftypefun data-type name args...
3509 ;; In Info, `Function: data-type name ARGS'
3510 ;; @deftypevar data-type name
3511 ;; In Info, `Variable: data-type name'
3512 ;; Note: args in lower case, unless modified in command line.
3513 ;; Use cdr of texinfo-defun-type to determine category:
3514 (let ((category (car (cdr texinfo-defun-type)))
3515 (data-type (car parsed-args))
3516 (name (car (cdr parsed-args)))
3517 (args (cdr (cdr parsed-args))))
3518 (insert " -- " category ": " data-type " " name)
3519 (while args
3520 (insert " " (car args))
3521 (setq args (cdr args)))))
3522
3523 ;; @defop: Generalized object-oriented
3524 (put 'defop 'texinfo-deffn-formatting-property 'texinfo-format-defop)
3525 (put 'defopx 'texinfo-deffn-formatting-property 'texinfo-format-defop)
3526 (defun texinfo-format-defop (parsed-args)
3527 ;; Generalized object oriented entity:
3528 ;; @defop category class name args...
3529 ;; In Info, `Category on class: name ARG'
3530 ;; Note: args in upper case; use of `on'
3531 (let ((category (car parsed-args))
3532 (class (car (cdr parsed-args)))
3533 (name (car (cdr (cdr parsed-args))))
3534 (args (cdr (cdr (cdr parsed-args)))))
3535 (insert " -- " category " on " class ": " name)
3536 (while args
3537 (insert " " (upcase (car args)))
3538 (setq args (cdr args)))))
3539
3540 ;; @defcv: Generalized object-oriented
3541 (put 'defcv 'texinfo-deffn-formatting-property 'texinfo-format-defcv)
3542 (put 'defcvx 'texinfo-deffn-formatting-property 'texinfo-format-defcv)
3543 (defun texinfo-format-defcv (parsed-args)
3544 ;; Generalized object oriented entity:
3545 ;; @defcv category class name
3546 ;; In Info, `Category of class: name'
3547 ;; Note: args in upper case; use of `of'
3548 (let ((category (car parsed-args))
3549 (class (car (cdr parsed-args)))
3550 (name (car (cdr (cdr parsed-args))))
3551 (args (cdr (cdr (cdr parsed-args)))))
3552 (insert " -- " category " of " class ": " name)
3553 (while args
3554 (insert " " (upcase (car args)))
3555 (setq args (cdr args)))))
3556
3557 ;; @defmethod: Specialized object-oriented
3558 (put 'defmethod 'texinfo-deffn-formatting-property 'texinfo-format-defmethod)
3559 (put 'defmethodx 'texinfo-deffn-formatting-property 'texinfo-format-defmethod)
3560 (defun texinfo-format-defmethod (parsed-args)
3561 ;; Specialized object oriented entity:
3562 ;; @defmethod class name args...
3563 ;; In Info, `Method on class: name ARGS'
3564 ;; Note: args in upper case; use of `on'
3565 ;; Use cdr of texinfo-defun-type to determine category:
3566 (let ((category (car (cdr texinfo-defun-type)))
3567 (class (car parsed-args))
3568 (name (car (cdr parsed-args)))
3569 (args (cdr (cdr parsed-args))))
3570 (insert " -- " category " on " class ": " name)
3571 (while args
3572 (insert " " (upcase (car args)))
3573 (setq args (cdr args)))))
3574
3575 ;; @defivar: Specialized object-oriented
3576 (put 'defivar 'texinfo-deffn-formatting-property 'texinfo-format-defivar)
3577 (put 'defivarx 'texinfo-deffn-formatting-property 'texinfo-format-defivar)
3578 (defun texinfo-format-defivar (parsed-args)
3579 ;; Specialized object oriented entity:
3580 ;; @defivar class name
3581 ;; In Info, `Instance variable of class: name'
3582 ;; Note: args in upper case; use of `of'
3583 ;; Use cdr of texinfo-defun-type to determine category:
3584 (let ((category (car (cdr texinfo-defun-type)))
3585 (class (car parsed-args))
3586 (name (car (cdr parsed-args)))
3587 (args (cdr (cdr parsed-args))))
3588 (insert " -- " category " of " class ": " name)
3589 (while args
3590 (insert " " (upcase (car args)))
3591 (setq args (cdr args)))))
3592
3593 \f
3594 ;;; Indexing for definitions
3595
3596 ;; An index entry has three parts: the `entry proper', the node name, and the
3597 ;; line number. Depending on the which command is used, the entry is
3598 ;; formatted differently:
3599 ;;
3600 ;; @defun,
3601 ;; @defmac,
3602 ;; @defspec,
3603 ;; @defvar,
3604 ;; @defopt all use their 1st argument as the entry-proper
3605 ;;
3606 ;; @deffn,
3607 ;; @defvr,
3608 ;; @deftp
3609 ;; @deftypefun
3610 ;; @deftypevar all use their 2nd argument as the entry-proper
3611 ;;
3612 ;; @deftypefn,
3613 ;; @deftypevr both use their 3rd argument as the entry-proper
3614 ;;
3615 ;; @defmethod uses its 2nd and 1st arguments as an entry-proper
3616 ;; formatted: NAME on CLASS
3617
3618 ;; @defop uses its 3rd and 2nd arguments as an entry-proper
3619 ;; formatted: NAME on CLASS
3620 ;;
3621 ;; @defivar uses its 2nd and 1st arguments as an entry-proper
3622 ;; formatted: NAME of CLASS
3623 ;;
3624 ;; @defcv uses its 3rd and 2nd argument as an entry-proper
3625 ;; formatted: NAME of CLASS
3626
3627 (put 'defun 'texinfo-defun-indexing-property 'texinfo-index-defun)
3628 (put 'defunx 'texinfo-defun-indexing-property 'texinfo-index-defun)
3629 (put 'defmac 'texinfo-defun-indexing-property 'texinfo-index-defun)
3630 (put 'defmacx 'texinfo-defun-indexing-property 'texinfo-index-defun)
3631 (put 'defspec 'texinfo-defun-indexing-property 'texinfo-index-defun)
3632 (put 'defspecx 'texinfo-defun-indexing-property 'texinfo-index-defun)
3633 (put 'defvar 'texinfo-defun-indexing-property 'texinfo-index-defun)
3634 (put 'defvarx 'texinfo-defun-indexing-property 'texinfo-index-defun)
3635 (put 'defopt 'texinfo-defun-indexing-property 'texinfo-index-defun)
3636 (put 'defoptx 'texinfo-defun-indexing-property 'texinfo-index-defun)
3637 (defun texinfo-index-defun (parsed-args)
3638 ;; use 1st parsed-arg as entry-proper
3639 ;; `index-list' will be texinfo-findex or the like
3640 (let ((index-list (get texinfo-command-name 'texinfo-defun-index)))
3641 (set index-list
3642 (cons
3643 ;; Three elements: entry-proper, node-name, line-number
3644 (list
3645 (car parsed-args)
3646 texinfo-last-node
3647 ;; Region formatting may not provide last node position.
3648 (if texinfo-last-node-pos
3649 (1+ (count-lines texinfo-last-node-pos (point)))
3650 1))
3651 (symbol-value index-list)))))
3652
3653 (put 'deffn 'texinfo-defun-indexing-property 'texinfo-index-deffn)
3654 (put 'deffnx 'texinfo-defun-indexing-property 'texinfo-index-deffn)
3655 (put 'defvr 'texinfo-defun-indexing-property 'texinfo-index-deffn)
3656 (put 'defvrx 'texinfo-defun-indexing-property 'texinfo-index-deffn)
3657 (put 'deftp 'texinfo-defun-indexing-property 'texinfo-index-deffn)
3658 (put 'deftpx 'texinfo-defun-indexing-property 'texinfo-index-deffn)
3659 (put 'deftypefun 'texinfo-defun-indexing-property 'texinfo-index-deffn)
3660 (put 'deftypefunx 'texinfo-defun-indexing-property 'texinfo-index-deffn)
3661 (put 'deftypevar 'texinfo-defun-indexing-property 'texinfo-index-deffn)
3662 (put 'deftypevarx 'texinfo-defun-indexing-property 'texinfo-index-deffn)
3663 (defun texinfo-index-deffn (parsed-args)
3664 ;; use 2nd parsed-arg as entry-proper
3665 ;; `index-list' will be texinfo-findex or the like
3666 (let ((index-list (get texinfo-command-name 'texinfo-defun-index)))
3667 (set index-list
3668 (cons
3669 ;; Three elements: entry-proper, node-name, line-number
3670 (list
3671 (car (cdr parsed-args))
3672 texinfo-last-node
3673 ;; Region formatting may not provide last node position.
3674 (if texinfo-last-node-pos
3675 (1+ (count-lines texinfo-last-node-pos (point)))
3676 1))
3677 (symbol-value index-list)))))
3678
3679 (put 'deftypefn 'texinfo-defun-indexing-property 'texinfo-index-deftypefn)
3680 (put 'deftypefnx 'texinfo-defun-indexing-property 'texinfo-index-deftypefn)
3681 (put 'deftypevr 'texinfo-defun-indexing-property 'texinfo-index-deftypefn)
3682 (put 'deftypevrx 'texinfo-defun-indexing-property 'texinfo-index-deftypefn)
3683 (defun texinfo-index-deftypefn (parsed-args)
3684 ;; use 3rd parsed-arg as entry-proper
3685 ;; `index-list' will be texinfo-findex or the like
3686 (let ((index-list (get texinfo-command-name 'texinfo-defun-index)))
3687 (set index-list
3688 (cons
3689 ;; Three elements: entry-proper, node-name, line-number
3690 (list
3691 (car (cdr (cdr parsed-args)))
3692 texinfo-last-node
3693 ;; Region formatting may not provide last node position.
3694 (if texinfo-last-node-pos
3695 (1+ (count-lines texinfo-last-node-pos (point)))
3696 1))
3697 (symbol-value index-list)))))
3698
3699 (put 'defmethod 'texinfo-defun-indexing-property 'texinfo-index-defmethod)
3700 (put 'defmethodx 'texinfo-defun-indexing-property 'texinfo-index-defmethod)
3701 (defun texinfo-index-defmethod (parsed-args)
3702 ;; use 2nd on 1st parsed-arg as entry-proper
3703 ;; `index-list' will be texinfo-findex or the like
3704 (let ((index-list (get texinfo-command-name 'texinfo-defun-index)))
3705 (set index-list
3706 (cons
3707 ;; Three elements: entry-proper, node-name, line-number
3708 (list
3709 (format "%s on %s"
3710 (car (cdr parsed-args))
3711 (car parsed-args))
3712 texinfo-last-node
3713 ;; Region formatting may not provide last node position.
3714 (if texinfo-last-node-pos
3715 (1+ (count-lines texinfo-last-node-pos (point)))
3716 1))
3717 (symbol-value index-list)))))
3718
3719 (put 'defop 'texinfo-defun-indexing-property 'texinfo-index-defop)
3720 (put 'defopx 'texinfo-defun-indexing-property 'texinfo-index-defop)
3721 (defun texinfo-index-defop (parsed-args)
3722 ;; use 3rd on 2nd parsed-arg as entry-proper
3723 ;; `index-list' will be texinfo-findex or the like
3724 (let ((index-list (get texinfo-command-name 'texinfo-defun-index)))
3725 (set index-list
3726 (cons
3727 ;; Three elements: entry-proper, node-name, line-number
3728 (list
3729 (format "%s on %s"
3730 (car (cdr (cdr parsed-args)))
3731 (car (cdr parsed-args)))
3732 texinfo-last-node
3733 ;; Region formatting may not provide last node position.
3734 (if texinfo-last-node-pos
3735 (1+ (count-lines texinfo-last-node-pos (point)))
3736 1))
3737 (symbol-value index-list)))))
3738
3739 (put 'defivar 'texinfo-defun-indexing-property 'texinfo-index-defivar)
3740 (put 'defivarx 'texinfo-defun-indexing-property 'texinfo-index-defivar)
3741 (defun texinfo-index-defivar (parsed-args)
3742 ;; use 2nd of 1st parsed-arg as entry-proper
3743 ;; `index-list' will be texinfo-findex or the like
3744 (let ((index-list (get texinfo-command-name 'texinfo-defun-index)))
3745 (set index-list
3746 (cons
3747 ;; Three elements: entry-proper, node-name, line-number
3748 (list
3749 (format "%s of %s"
3750 (car (cdr parsed-args))
3751 (car parsed-args))
3752 texinfo-last-node
3753 ;; Region formatting may not provide last node position.
3754 (if texinfo-last-node-pos
3755 (1+ (count-lines texinfo-last-node-pos (point)))
3756 1))
3757 (symbol-value index-list)))))
3758
3759 (put 'defcv 'texinfo-defun-indexing-property 'texinfo-index-defcv)
3760 (put 'defcvx 'texinfo-defun-indexing-property 'texinfo-index-defcv)
3761 (defun texinfo-index-defcv (parsed-args)
3762 ;; use 3rd of 2nd parsed-arg as entry-proper
3763 ;; `index-list' will be texinfo-findex or the like
3764 (let ((index-list (get texinfo-command-name 'texinfo-defun-index)))
3765 (set index-list
3766 (cons
3767 ;; Three elements: entry-proper, node-name, line-number
3768 (list
3769 (format "%s of %s"
3770 (car (cdr (cdr parsed-args)))
3771 (car (cdr parsed-args)))
3772 texinfo-last-node
3773 ;; Region formatting may not provide last node position.
3774 (if texinfo-last-node-pos
3775 (1+ (count-lines texinfo-last-node-pos (point)))
3776 1))
3777 (symbol-value index-list)))))
3778
3779 \f
3780 ;;; Properties for definitions
3781
3782 ;; Each definition command has six properties:
3783 ;;
3784 ;; 1. texinfo-deffn-formatting-property to format definition line
3785 ;; 2. texinfo-defun-indexing-property to create index entry
3786 ;; 3. texinfo-format formatting command
3787 ;; 4. texinfo-end end formatting command
3788 ;; 5. texinfo-defun-type type of deffn to format
3789 ;; 6. texinfo-defun-index type of index to use
3790 ;;
3791 ;; The `x' forms of each definition command are used for the second
3792 ;; and subsequent header lines.
3793
3794 ;; The texinfo-deffn-formatting-property and texinfo-defun-indexing-property
3795 ;; are listed just before the appropriate formatting and indexing commands.
3796
3797 (put 'deffn 'texinfo-format 'texinfo-format-defun)
3798 (put 'deffnx 'texinfo-format 'texinfo-format-defunx)
3799 (put 'deffn 'texinfo-end 'texinfo-end-defun)
3800 (put 'deffn 'texinfo-defun-type '('deffn-type nil))
3801 (put 'deffnx 'texinfo-defun-type '('deffn-type nil))
3802 (put 'deffn 'texinfo-defun-index 'texinfo-findex)
3803 (put 'deffnx 'texinfo-defun-index 'texinfo-findex)
3804
3805 (put 'defun 'texinfo-format 'texinfo-format-defun)
3806 (put 'defunx 'texinfo-format 'texinfo-format-defunx)
3807 (put 'defun 'texinfo-end 'texinfo-end-defun)
3808 (put 'defun 'texinfo-defun-type '('defun-type "Function"))
3809 (put 'defunx 'texinfo-defun-type '('defun-type "Function"))
3810 (put 'defun 'texinfo-defun-index 'texinfo-findex)
3811 (put 'defunx 'texinfo-defun-index 'texinfo-findex)
3812
3813 (put 'defmac 'texinfo-format 'texinfo-format-defun)
3814 (put 'defmacx 'texinfo-format 'texinfo-format-defunx)
3815 (put 'defmac 'texinfo-end 'texinfo-end-defun)
3816 (put 'defmac 'texinfo-defun-type '('defun-type "Macro"))
3817 (put 'defmacx 'texinfo-defun-type '('defun-type "Macro"))
3818 (put 'defmac 'texinfo-defun-index 'texinfo-findex)
3819 (put 'defmacx 'texinfo-defun-index 'texinfo-findex)
3820
3821 (put 'defspec 'texinfo-format 'texinfo-format-defun)
3822 (put 'defspecx 'texinfo-format 'texinfo-format-defunx)
3823 (put 'defspec 'texinfo-end 'texinfo-end-defun)
3824 (put 'defspec 'texinfo-defun-type '('defun-type "Special form"))
3825 (put 'defspecx 'texinfo-defun-type '('defun-type "Special form"))
3826 (put 'defspec 'texinfo-defun-index 'texinfo-findex)
3827 (put 'defspecx 'texinfo-defun-index 'texinfo-findex)
3828
3829 (put 'defvr 'texinfo-format 'texinfo-format-defun)
3830 (put 'defvrx 'texinfo-format 'texinfo-format-defunx)
3831 (put 'defvr 'texinfo-end 'texinfo-end-defun)
3832 (put 'defvr 'texinfo-defun-type '('deffn-type nil))
3833 (put 'defvrx 'texinfo-defun-type '('deffn-type nil))
3834 (put 'defvr 'texinfo-defun-index 'texinfo-vindex)
3835 (put 'defvrx 'texinfo-defun-index 'texinfo-vindex)
3836
3837 (put 'defvar 'texinfo-format 'texinfo-format-defun)
3838 (put 'defvarx 'texinfo-format 'texinfo-format-defunx)
3839 (put 'defvar 'texinfo-end 'texinfo-end-defun)
3840 (put 'defvar 'texinfo-defun-type '('defun-type "Variable"))
3841 (put 'defvarx 'texinfo-defun-type '('defun-type "Variable"))
3842 (put 'defvar 'texinfo-defun-index 'texinfo-vindex)
3843 (put 'defvarx 'texinfo-defun-index 'texinfo-vindex)
3844
3845 (put 'defconst 'texinfo-format 'texinfo-format-defun)
3846 (put 'defconstx 'texinfo-format 'texinfo-format-defunx)
3847 (put 'defconst 'texinfo-end 'texinfo-end-defun)
3848 (put 'defconst 'texinfo-defun-type '('defun-type "Constant"))
3849 (put 'defconstx 'texinfo-defun-type '('defun-type "Constant"))
3850 (put 'defconst 'texinfo-defun-index 'texinfo-vindex)
3851 (put 'defconstx 'texinfo-defun-index 'texinfo-vindex)
3852
3853 (put 'defcmd 'texinfo-format 'texinfo-format-defun)
3854 (put 'defcmdx 'texinfo-format 'texinfo-format-defunx)
3855 (put 'defcmd 'texinfo-end 'texinfo-end-defun)
3856 (put 'defcmd 'texinfo-defun-type '('defun-type "Command"))
3857 (put 'defcmdx 'texinfo-defun-type '('defun-type "Command"))
3858 (put 'defcmd 'texinfo-defun-index 'texinfo-findex)
3859 (put 'defcmdx 'texinfo-defun-index 'texinfo-findex)
3860
3861 (put 'defopt 'texinfo-format 'texinfo-format-defun)
3862 (put 'defoptx 'texinfo-format 'texinfo-format-defunx)
3863 (put 'defopt 'texinfo-end 'texinfo-end-defun)
3864 (put 'defopt 'texinfo-defun-type '('defun-type "User Option"))
3865 (put 'defoptx 'texinfo-defun-type '('defun-type "User Option"))
3866 (put 'defopt 'texinfo-defun-index 'texinfo-vindex)
3867 (put 'defoptx 'texinfo-defun-index 'texinfo-vindex)
3868
3869 (put 'deftp 'texinfo-format 'texinfo-format-defun)
3870 (put 'deftpx 'texinfo-format 'texinfo-format-defunx)
3871 (put 'deftp 'texinfo-end 'texinfo-end-defun)
3872 (put 'deftp 'texinfo-defun-type '('deftp-type nil))
3873 (put 'deftpx 'texinfo-defun-type '('deftp-type nil))
3874 (put 'deftp 'texinfo-defun-index 'texinfo-tindex)
3875 (put 'deftpx 'texinfo-defun-index 'texinfo-tindex)
3876
3877 ;;; Object-oriented stuff is a little hairier.
3878
3879 (put 'defop 'texinfo-format 'texinfo-format-defun)
3880 (put 'defopx 'texinfo-format 'texinfo-format-defunx)
3881 (put 'defop 'texinfo-end 'texinfo-end-defun)
3882 (put 'defop 'texinfo-defun-type '('defop-type nil))
3883 (put 'defopx 'texinfo-defun-type '('defop-type nil))
3884 (put 'defop 'texinfo-defun-index 'texinfo-findex)
3885 (put 'defopx 'texinfo-defun-index 'texinfo-findex)
3886
3887 (put 'defmethod 'texinfo-format 'texinfo-format-defun)
3888 (put 'defmethodx 'texinfo-format 'texinfo-format-defunx)
3889 (put 'defmethod 'texinfo-end 'texinfo-end-defun)
3890 (put 'defmethod 'texinfo-defun-type '('defmethod-type "Method"))
3891 (put 'defmethodx 'texinfo-defun-type '('defmethod-type "Method"))
3892 (put 'defmethod 'texinfo-defun-index 'texinfo-findex)
3893 (put 'defmethodx 'texinfo-defun-index 'texinfo-findex)
3894
3895 (put 'defcv 'texinfo-format 'texinfo-format-defun)
3896 (put 'defcvx 'texinfo-format 'texinfo-format-defunx)
3897 (put 'defcv 'texinfo-end 'texinfo-end-defun)
3898 (put 'defcv 'texinfo-defun-type '('defop-type nil))
3899 (put 'defcvx 'texinfo-defun-type '('defop-type nil))
3900 (put 'defcv 'texinfo-defun-index 'texinfo-vindex)
3901 (put 'defcvx 'texinfo-defun-index 'texinfo-vindex)
3902
3903 (put 'defivar 'texinfo-format 'texinfo-format-defun)
3904 (put 'defivarx 'texinfo-format 'texinfo-format-defunx)
3905 (put 'defivar 'texinfo-end 'texinfo-end-defun)
3906 (put 'defivar 'texinfo-defun-type '('defmethod-type "Instance variable"))
3907 (put 'defivarx 'texinfo-defun-type '('defmethod-type "Instance variable"))
3908 (put 'defivar 'texinfo-defun-index 'texinfo-vindex)
3909 (put 'defivarx 'texinfo-defun-index 'texinfo-vindex)
3910
3911 ;;; Typed functions and variables
3912
3913 (put 'deftypefn 'texinfo-format 'texinfo-format-defun)
3914 (put 'deftypefnx 'texinfo-format 'texinfo-format-defunx)
3915 (put 'deftypefn 'texinfo-end 'texinfo-end-defun)
3916 (put 'deftypefn 'texinfo-defun-type '('deftypefn-type nil))
3917 (put 'deftypefnx 'texinfo-defun-type '('deftypefn-type nil))
3918 (put 'deftypefn 'texinfo-defun-index 'texinfo-findex)
3919 (put 'deftypefnx 'texinfo-defun-index 'texinfo-findex)
3920
3921 (put 'deftypefun 'texinfo-format 'texinfo-format-defun)
3922 (put 'deftypefunx 'texinfo-format 'texinfo-format-defunx)
3923 (put 'deftypefun 'texinfo-end 'texinfo-end-defun)
3924 (put 'deftypefun 'texinfo-defun-type '('deftypefun-type "Function"))
3925 (put 'deftypefunx 'texinfo-defun-type '('deftypefun-type "Function"))
3926 (put 'deftypefun 'texinfo-defun-index 'texinfo-findex)
3927 (put 'deftypefunx 'texinfo-defun-index 'texinfo-findex)
3928
3929 (put 'deftypevr 'texinfo-format 'texinfo-format-defun)
3930 (put 'deftypevrx 'texinfo-format 'texinfo-format-defunx)
3931 (put 'deftypevr 'texinfo-end 'texinfo-end-defun)
3932 (put 'deftypevr 'texinfo-defun-type '('deftypefn-type nil))
3933 (put 'deftypevrx 'texinfo-defun-type '('deftypefn-type nil))
3934 (put 'deftypevr 'texinfo-defun-index 'texinfo-vindex)
3935 (put 'deftypevrx 'texinfo-defun-index 'texinfo-vindex)
3936
3937 (put 'deftypevar 'texinfo-format 'texinfo-format-defun)
3938 (put 'deftypevarx 'texinfo-format 'texinfo-format-defunx)
3939 (put 'deftypevar 'texinfo-end 'texinfo-end-defun)
3940 (put 'deftypevar 'texinfo-defun-type '('deftypevar-type "Variable"))
3941 (put 'deftypevarx 'texinfo-defun-type '('deftypevar-type "Variable"))
3942 (put 'deftypevar 'texinfo-defun-index 'texinfo-vindex)
3943 (put 'deftypevarx 'texinfo-defun-index 'texinfo-vindex)
3944
3945 \f
3946 ;;; @set, @clear, @ifset, @ifclear
3947
3948 ;; If a flag is set with @set FLAG, then text between @ifset and @end
3949 ;; ifset is formatted normally, but if the flag is is cleared with
3950 ;; @clear FLAG, then the text is not formatted; it is ignored.
3951
3952 ;; If a flag is cleared with @clear FLAG, then text between @ifclear
3953 ;; and @end ifclear is formatted normally, but if the flag is is set with
3954 ;; @set FLAG, then the text is not formatted; it is ignored. @ifclear
3955 ;; is the opposite of @ifset.
3956
3957 ;; If a flag is set to a string with @set FLAG,
3958 ;; replace @value{FLAG} with the string.
3959 ;; If a flag with a value is cleared,
3960 ;; @value{FLAG} is invalid,
3961 ;; as if there had never been any @set FLAG previously.
3962
3963 (put 'clear 'texinfo-format 'texinfo-clear)
3964 (defun texinfo-clear ()
3965 "Clear the value of the flag."
3966 (let* ((arg (texinfo-parse-arg-discard))
3967 (flag (car (read-from-string arg)))
3968 (value (substring arg (cdr (read-from-string arg)))))
3969 (put flag 'texinfo-whether-setp 'flag-cleared)
3970 (put flag 'texinfo-set-value "")))
3971
3972 (put 'set 'texinfo-format 'texinfo-set)
3973 (defun texinfo-set ()
3974 "Set the value of the flag, optionally to a string.
3975 The command `@set foo This is a string.'
3976 sets flag foo to the value: `This is a string.'
3977 The command `@value{foo}' expands to the value."
3978 (let* ((arg (texinfo-parse-arg-discard))
3979 (flag (car (read-from-string arg)))
3980 (value (substring arg (cdr (read-from-string arg)))))
3981 (if (string-match "^[ \t]+" value)
3982 (setq value (substring value (match-end 0))))
3983 (put flag 'texinfo-whether-setp 'flag-set)
3984 (put flag 'texinfo-set-value value)))
3985
3986 (put 'value 'texinfo-format 'texinfo-value)
3987 (defun texinfo-value ()
3988 "Insert the string to which the flag is set.
3989 The command `@set foo This is a string.'
3990 sets flag foo to the value: `This is a string.'
3991 The command `@value{foo}' expands to the value."
3992 (let ((arg (texinfo-parse-arg-discard)))
3993 (cond ((and
3994 (eq (get (car (read-from-string arg)) 'texinfo-whether-setp)
3995 'flag-set)
3996 (get (car (read-from-string arg)) 'texinfo-set-value))
3997 (insert (get (car (read-from-string arg)) 'texinfo-set-value)))
3998 ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp)
3999 'flag-cleared)
4000 (insert (format "{No value for \"%s\"}" arg)))
4001 ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp) nil)
4002 (insert (format "{No value for \"%s\"}" arg))))))
4003
4004 (put 'ifset 'texinfo-end 'texinfo-discard-command)
4005 (put 'ifset 'texinfo-format 'texinfo-if-set)
4006 (defun texinfo-if-set ()
4007 "If set, continue formatting; else do not format region up to @end ifset."
4008 (let ((arg (texinfo-parse-arg-discard)))
4009 (cond
4010 ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp)
4011 'flag-set)
4012 ;; Format the text (i.e., do not remove it); do nothing here.
4013 ())
4014 ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp)
4015 'flag-cleared)
4016 ;; Clear region (i.e., cause the text to be ignored).
4017 (delete-region texinfo-command-start
4018 (re-search-forward "@end ifset[ \t]*\n")))
4019 ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp)
4020 nil)
4021 ;; In this case flag is neither set nor cleared.
4022 ;; Act as if set, i.e. do nothing.
4023 ()))))
4024
4025 (put 'ifclear 'texinfo-end 'texinfo-discard-command)
4026 (put 'ifclear 'texinfo-format 'texinfo-if-clear)
4027 (defun texinfo-if-clear ()
4028 "If clear, continue formatting; if set, do not format up to @end ifset."
4029 (let ((arg (texinfo-parse-arg-discard)))
4030 (cond
4031 ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp)
4032 'flag-set)
4033 ;; Clear region (i.e., cause the text to be ignored).
4034 (delete-region texinfo-command-start
4035 (re-search-forward "@end ifclear[ \t]*\n")))
4036 ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp)
4037 'flag-cleared)
4038 ;; Format the text (i.e., do not remove it); do nothing here.
4039 ())
4040 ((eq (get (car (read-from-string arg)) 'texinfo-whether-setp)
4041 nil)
4042 ;; In this case flag is neither set nor cleared.
4043 ;; Act as if clear, i.e. do nothing.
4044 ()))))
4045 \f
4046 ;;; @ifeq
4047
4048 (put 'ifeq 'texinfo-format 'texinfo-format-ifeq)
4049 (defun texinfo-format-ifeq ()
4050 "If ARG1 and ARG2 caselessly string compare to same string, perform COMMAND.
4051 Otherwise produces no output.
4052
4053 Thus:
4054 @ifeq{ arg1 , arg1 , @code{foo}} bar
4055
4056 ==> `foo' bar.
4057 but
4058 @ifeq{ arg1 , arg2 , @code{foo}} bar
4059
4060 ==> bar
4061
4062 Note that the Texinfo command and its arguments must be arguments to
4063 the @ifeq command."
4064 ;; compare-buffer-substrings does not exist in version 18; don't use
4065 (goto-char texinfo-command-end)
4066 (let* ((case-fold-search t)
4067 (stop (save-excursion (forward-sexp 1) (point)))
4068 start end
4069 ;; @ifeq{arg1, arg2, @command{optional-args}}
4070 (arg1
4071 (progn
4072 (forward-char 1)
4073 (skip-chars-forward " ")
4074 (setq start (point))
4075 (search-forward "," stop t)
4076 (skip-chars-backward ", ")
4077 (buffer-substring-no-properties start (point))))
4078 (arg2
4079 (progn
4080 (search-forward "," stop t)
4081 (skip-chars-forward " ")
4082 (setq start (point))
4083 (search-forward "," stop t)
4084 (skip-chars-backward ", ")
4085 (buffer-substring-no-properties start (point))))
4086 (texinfo-command
4087 (progn
4088 (search-forward "," stop t)
4089 (skip-chars-forward " ")
4090 (setq start (point))
4091 (goto-char (1- stop))
4092 (skip-chars-backward " ")
4093 (buffer-substring-no-properties start (point)))))
4094 (delete-region texinfo-command-start stop)
4095 (if (equal arg1 arg2)
4096 (insert texinfo-command))
4097 (goto-char texinfo-command-start)))
4098
4099 \f
4100 ;;; Process included files: `@include' command
4101
4102 ;; Updated 19 October 1990
4103 ;; In the original version, include files were ignored by Info but
4104 ;; incorporated in to the printed manual. To make references to the
4105 ;; included file, the Texinfo source file has to refer to the included
4106 ;; files using the `(filename)nodename' format for referring to other
4107 ;; Info files. Also, the included files had to be formatted on their
4108 ;; own. It was just like they were another file.
4109
4110 ;; Currently, include files are inserted into the buffer that is
4111 ;; formatted for Info. If large, the resulting info file is split and
4112 ;; tagified. For current include files to work, the master menu must
4113 ;; refer to all the nodes, and the highest level nodes in the include
4114 ;; files must have the correct next, prev, and up pointers.
4115
4116 ;; The included file may have an @setfilename and even an @settitle,
4117 ;; but not an `\input texinfo' line.
4118
4119 ;; Updated 24 March 1993
4120 ;; In order for @raisesections and @lowersections to work, included
4121 ;; files must be inserted into the buffer holding the outer file
4122 ;; before other Info formatting takes place. So @include is no longer
4123 ;; is treated like other @-commands.
4124 (put 'include 'texinfo-format 'texinfo-format-noop)
4125
4126 ;; Original definition:
4127 ;; (defun texinfo-format-include ()
4128 ;; (let ((filename (texinfo-parse-arg-discard))
4129 ;; (default-directory input-directory)
4130 ;; subindex)
4131 ;; (setq subindex
4132 ;; (save-excursion
4133 ;; (progn (find-file
4134 ;; (cond ((file-readable-p (concat filename ".texinfo"))
4135 ;; (concat filename ".texinfo"))
4136 ;; ((file-readable-p (concat filename ".texi"))
4137 ;; (concat filename ".texi"))
4138 ;; ((file-readable-p (concat filename ".tex"))
4139 ;; (concat filename ".tex"))
4140 ;; ((file-readable-p filename)
4141 ;; filename)
4142 ;; (t (error "@include'd file %s not found"
4143 ;; filename))))
4144 ;; (texinfo-format-buffer-1))))
4145 ;; (texinfo-subindex 'texinfo-vindex (car subindex) (nth 1 subindex))
4146 ;; (texinfo-subindex 'texinfo-findex (car subindex) (nth 2 subindex))
4147 ;; (texinfo-subindex 'texinfo-cindex (car subindex) (nth 3 subindex))
4148 ;; (texinfo-subindex 'texinfo-pindex (car subindex) (nth 4 subindex))
4149 ;; (texinfo-subindex 'texinfo-tindex (car subindex) (nth 5 subindex))
4150 ;; (texinfo-subindex 'texinfo-kindex (car subindex) (nth 6 subindex))))
4151 ;;
4152 ;;(defun texinfo-subindex (indexvar file content)
4153 ;; (set indexvar (cons (list 'recurse file content)
4154 ;; (symbol-value indexvar))))
4155
4156 ;; Second definition:
4157 ;; (put 'include 'texinfo-format 'texinfo-format-include)
4158 ;; (defun texinfo-format-include ()
4159 ;; (let ((filename (concat input-directory
4160 ;; (texinfo-parse-arg-discard)))
4161 ;; (default-directory input-directory))
4162 ;; (message "Reading: %s" filename)
4163 ;; (save-excursion
4164 ;; (save-restriction
4165 ;; (narrow-to-region
4166 ;; (point)
4167 ;; (+ (point) (car (cdr (insert-file-contents filename)))))
4168 ;; (goto-char (point-min))
4169 ;; (texinfo-append-refill)
4170 ;; (texinfo-format-convert (point-min) (point-max))))
4171 ;; (setq last-input-buffer input-buffer) ; to bypass setfilename
4172 ;; ))
4173
4174 \f
4175 ;;; Numerous commands do nothing in Info
4176 ;; These commands are defined in texinfo.tex for printed output.
4177
4178 \f
4179 ;;; various noops, such as @b{foo}, that take arguments in braces
4180
4181 (put 'b 'texinfo-format 'texinfo-format-noop)
4182 (put 'i 'texinfo-format 'texinfo-format-noop)
4183 (put 'r 'texinfo-format 'texinfo-format-noop)
4184 (put 't 'texinfo-format 'texinfo-format-noop)
4185 (put 'w 'texinfo-format 'texinfo-format-noop)
4186 (put 'asis 'texinfo-format 'texinfo-format-noop)
4187 (put 'dmn 'texinfo-format 'texinfo-format-noop)
4188 (put 'math 'texinfo-format 'texinfo-format-noop)
4189 (put 'titlefont 'texinfo-format 'texinfo-format-noop)
4190 (defun texinfo-format-noop ()
4191 (insert (texinfo-parse-arg-discard))
4192 (goto-char texinfo-command-start))
4193
4194 ;; @hyphenation command discards an argument within braces
4195 (put 'hyphenation 'texinfo-format 'texinfo-discard-command-and-arg)
4196 (defun texinfo-discard-command-and-arg ()
4197 "Discard both @-command and its argument in braces."
4198 (goto-char texinfo-command-end)
4199 (forward-list 1)
4200 (setq texinfo-command-end (point))
4201 (delete-region texinfo-command-start texinfo-command-end))
4202
4203 \f
4204 ;;; Do nothing commands, such as @smallbook, that have no args and no braces
4205 ;; These must appear on a line of their own
4206
4207 (put 'bye 'texinfo-format 'texinfo-discard-line)
4208 (put 'smallbook 'texinfo-format 'texinfo-discard-line)
4209 (put 'finalout 'texinfo-format 'texinfo-discard-line)
4210 (put 'overfullrule 'texinfo-format 'texinfo-discard-line)
4211 (put 'smallbreak 'texinfo-format 'texinfo-discard-line)
4212 (put 'medbreak 'texinfo-format 'texinfo-discard-line)
4213 (put 'bigbreak 'texinfo-format 'texinfo-discard-line)
4214 (put 'afourpaper 'texinfo-format 'texinfo-discard-line)
4215 (put 'afivepaper 'texinfo-format 'texinfo-discard-line)
4216 (put 'afourlatex 'texinfo-format 'texinfo-discard-line)
4217 (put 'afourwide 'texinfo-format 'texinfo-discard-line)
4218
4219 \f
4220 ;;; These noop commands discard the rest of the line.
4221
4222 (put 'c 'texinfo-format 'texinfo-discard-line-with-args)
4223 (put 'comment 'texinfo-format 'texinfo-discard-line-with-args)
4224 (put 'contents 'texinfo-format 'texinfo-discard-line-with-args)
4225 (put 'group 'texinfo-end 'texinfo-discard-line-with-args)
4226 (put 'group 'texinfo-format 'texinfo-discard-line-with-args)
4227 (put 'headings 'texinfo-format 'texinfo-discard-line-with-args)
4228 (put 'setchapterstyle 'texinfo-format 'texinfo-discard-line-with-args)
4229 (put 'hsize 'texinfo-format 'texinfo-discard-line-with-args)
4230 (put 'itemindent 'texinfo-format 'texinfo-discard-line-with-args)
4231 (put 'lispnarrowing 'texinfo-format 'texinfo-discard-line-with-args)
4232 (put 'need 'texinfo-format 'texinfo-discard-line-with-args)
4233 (put 'nopara 'texinfo-format 'texinfo-discard-line-with-args)
4234
4235 ;; @novalidate suppresses cross-reference checking and auxiliary file
4236 ;; creation with TeX. The Info-validate command checks that every
4237 ;; node pointer points to an existing node. Since this Info command
4238 ;; is not invoked automatically, the @novalidate command is irrelevant
4239 ;; and not supported by texinfmt.el
4240 (put 'novalidate 'texinfo-format 'texinfo-discard-line-with-args)
4241
4242 (put 'page 'texinfo-format 'texinfo-discard-line-with-args)
4243 (put 'pagesizes 'texinfo-format 'texinfo-discard-line-with-args)
4244 (put 'parindent 'texinfo-format 'texinfo-discard-line-with-args)
4245 (put 'setchapternewpage 'texinfo-format 'texinfo-discard-line-with-args)
4246 (put 'setq 'texinfo-format 'texinfo-discard-line-with-args)
4247
4248 (put 'setcontentsaftertitlepage
4249 'texinfo-format 'texinfo-discard-line-with-args)
4250 (put 'setshortcontentsaftertitlepage
4251 'texinfo-format 'texinfo-discard-line-with-args)
4252
4253 (put 'settitle 'texinfo-format 'texinfo-discard-line-with-args)
4254 (put 'setx 'texinfo-format 'texinfo-discard-line-with-args)
4255 (put 'shortcontents 'texinfo-format 'texinfo-discard-line-with-args)
4256 (put 'shorttitlepage 'texinfo-format 'texinfo-discard-line-with-args)
4257 (put 'summarycontents 'texinfo-format 'texinfo-discard-line-with-args)
4258 (put 'input 'texinfo-format 'texinfo-discard-line-with-args)
4259
4260 (put 'documentlanguage 'texinfo-format 'texinfo-discard-line-with-args)
4261 (put 'documentencoding 'texinfo-format 'texinfo-discard-line-with-args)
4262
4263
4264 \f
4265 ;;; Some commands cannot be handled
4266
4267 (defun texinfo-unsupported ()
4268 (error "%s is not handled by texinfo"
4269 (buffer-substring-no-properties texinfo-command-start texinfo-command-end)))
4270 \f
4271 ;;; Batch formatting
4272
4273 (defun batch-texinfo-format ()
4274 "Run `texinfo-format-buffer' on the files remaining on the command line.
4275 Must be used only with -batch, and kills Emacs on completion.
4276 Each file will be processed even if an error occurred previously.
4277 For example, invoke
4278 \"emacs -batch -funcall batch-texinfo-format $docs/ ~/*.texinfo\"."
4279 (if (not noninteractive)
4280 (error "batch-texinfo-format may only be used -batch"))
4281 (let ((version-control t)
4282 (auto-save-default nil)
4283 (find-file-run-dired nil)
4284 (kept-old-versions 259259)
4285 (kept-new-versions 259259))
4286 (let ((error 0)
4287 file
4288 (files ()))
4289 (while command-line-args-left
4290 (setq file (expand-file-name (car command-line-args-left)))
4291 (cond ((not (file-exists-p file))
4292 (message ">> %s does not exist!" file)
4293 (setq error 1
4294 command-line-args-left (cdr command-line-args-left)))
4295 ((file-directory-p file)
4296 (setq command-line-args-left
4297 (nconc (directory-files file)
4298 (cdr command-line-args-left))))
4299 (t
4300 (push file files)
4301 (setq command-line-args-left (cdr command-line-args-left)))))
4302 (while files
4303 (setq file (car files)
4304 files (cdr files))
4305 (condition-case err
4306 (progn
4307 (if buffer-file-name (kill-buffer (current-buffer)))
4308 (find-file file)
4309 (buffer-disable-undo (current-buffer))
4310 (set-buffer-modified-p nil)
4311 (texinfo-mode)
4312 (message "texinfo formatting %s..." file)
4313 (texinfo-format-buffer nil)
4314 (if (buffer-modified-p)
4315 (progn (message "Saving modified %s" (buffer-file-name))
4316 (save-buffer))))
4317 (error
4318 (message ">> Error: %s" (prin1-to-string err))
4319 (message ">> point at")
4320 (let ((s (buffer-substring-no-properties (point)
4321 (min (+ (point) 100)
4322 (point-max))))
4323 (tem 0))
4324 (while (setq tem (string-match "\n+" s tem))
4325 (setq s (concat (substring s 0 (match-beginning 0))
4326 "\n>> "
4327 (substring s (match-end 0)))
4328 tem (1+ tem)))
4329 (message ">> %s" s))
4330 (setq error 1))))
4331 (kill-emacs error))))
4332
4333 \f
4334 ;;; Place `provide' at end of file.
4335 (provide 'texinfmt)
4336
4337 ;; arch-tag: 1e8d9a2d-bca0-40a0-ac6c-dab01bc6f725
4338 ;;; texinfmt.el ends here