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