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