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