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