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