| 1 | ;;; texinfo.el --- major mode for editing Texinfo files |
| 2 | |
| 3 | ;; Copyright (C) 1985, '88, '89, '90, '91, '01, |
| 4 | ;; '92, '93, '96, '97, 2000, 2002 Free Software Foundation, Inc. |
| 5 | |
| 6 | ;; Author: Robert J. Chassell |
| 7 | ;; Date: [See date below for texinfo-version] |
| 8 | ;; Maintainer: FSF |
| 9 | ;; Keywords: maint, tex, docs |
| 10 | |
| 11 | ;; This file is part of GNU Emacs. |
| 12 | |
| 13 | ;; GNU Emacs is free software; you can redistribute it and/or modify |
| 14 | ;; it under the terms of the GNU General Public License as published by |
| 15 | ;; the Free Software Foundation; either version 2, or (at your option) |
| 16 | ;; any later version. |
| 17 | |
| 18 | ;; GNU Emacs is distributed in the hope that it will be useful, |
| 19 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 20 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 21 | ;; GNU General Public License for more details. |
| 22 | |
| 23 | ;; You should have received a copy of the GNU General Public License |
| 24 | ;; along with GNU Emacs; see the file COPYING. If not, write to the |
| 25 | ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| 26 | ;; Boston, MA 02111-1307, USA. |
| 27 | |
| 28 | ;;; Todo: |
| 29 | |
| 30 | ;; - facemenu support. |
| 31 | |
| 32 | ;;; Commentary: |
| 33 | |
| 34 | ;;; Code: |
| 35 | |
| 36 | (or (fboundp 'defgroup) |
| 37 | (defmacro defgroup (&rest ignore) nil)) |
| 38 | |
| 39 | (or (fboundp 'defcustom) |
| 40 | (defmacro defcustom (var value doc &rest ignore) |
| 41 | `(defvar ,var ,value ,doc))) |
| 42 | |
| 43 | (eval-when-compile (require 'tex-mode) (require 'cl)) |
| 44 | |
| 45 | (defgroup texinfo nil |
| 46 | "Texinfo Mode" |
| 47 | :group 'docs) |
| 48 | |
| 49 | ;;;###autoload |
| 50 | (defcustom texinfo-open-quote "``" |
| 51 | "*String inserted by typing \\[texinfo-insert-quote] to open a quotation." |
| 52 | :type 'string |
| 53 | :group 'texinfo) |
| 54 | |
| 55 | ;;;###autoload |
| 56 | (defcustom texinfo-close-quote "''" |
| 57 | "*String inserted by typing \\[texinfo-insert-quote] to close a quotation." |
| 58 | :type 'string |
| 59 | :group 'texinfo) |
| 60 | |
| 61 | \f |
| 62 | ;;; Autoloads: |
| 63 | |
| 64 | (autoload 'makeinfo-region |
| 65 | "makeinfo" |
| 66 | "Make Info file from region of current Texinfo file, and switch to it. |
| 67 | |
| 68 | This command does not offer the `next-error' feature since it would |
| 69 | apply to a temporary file, not the original; use the `makeinfo-buffer' |
| 70 | command to gain use of `next-error'." |
| 71 | t nil) |
| 72 | |
| 73 | (autoload 'makeinfo-buffer |
| 74 | "makeinfo" |
| 75 | "Make Info file from current buffer. |
| 76 | |
| 77 | Use the \\[next-error] command to move to the next error |
| 78 | \(if there are errors\)." |
| 79 | t nil) |
| 80 | |
| 81 | (autoload 'kill-compilation |
| 82 | "compile" |
| 83 | "Kill the process made by the \\[compile] command." |
| 84 | t nil) |
| 85 | |
| 86 | (autoload 'makeinfo-recenter-compilation-buffer |
| 87 | "makeinfo" |
| 88 | "Redisplay `*compilation*' buffer so most recent output can be seen. |
| 89 | The last line of the buffer is displayed on |
| 90 | line LINE of the window, or centered if LINE is nil." |
| 91 | t nil) |
| 92 | |
| 93 | (autoload 'texinfo-update-node |
| 94 | "texnfo-upd" |
| 95 | "Without any prefix argument, update the node in which point is located. |
| 96 | Non-nil argument (prefix, if interactive) means update the nodes in the |
| 97 | marked region. |
| 98 | |
| 99 | The functions for creating or updating nodes and menus, and their |
| 100 | keybindings, are: |
| 101 | |
| 102 | `texinfo-update-node' (&optional region-p) \\[texinfo-update-node] |
| 103 | `texinfo-every-node-update' () \\[texinfo-every-node-update] |
| 104 | `texinfo-sequential-node-update' (&optional region-p) |
| 105 | |
| 106 | `texinfo-make-menu' (&optional region-p) \\[texinfo-make-menu] |
| 107 | `texinfo-all-menus-update' () \\[texinfo-all-menus-update] |
| 108 | `texinfo-master-menu' () |
| 109 | |
| 110 | `texinfo-indent-menu-description' (column &optional region-p) |
| 111 | |
| 112 | The `texinfo-column-for-description' variable specifies the column to |
| 113 | which menu descriptions are indented. Its default value is 32." |
| 114 | t nil) |
| 115 | |
| 116 | (autoload 'texinfo-every-node-update |
| 117 | "texnfo-upd" |
| 118 | "Update every node in a Texinfo file." |
| 119 | t nil) |
| 120 | |
| 121 | (autoload 'texinfo-sequential-node-update |
| 122 | "texnfo-upd" |
| 123 | "Update one node (or many) in a Texinfo file with sequential pointers. |
| 124 | |
| 125 | This function causes the `Next' or `Previous' pointer to point to the |
| 126 | immediately preceding or following node, even if it is at a higher or |
| 127 | lower hierarchical level in the document. Continually pressing `n' or |
| 128 | `p' takes you straight through the file. |
| 129 | |
| 130 | Without any prefix argument, update the node in which point is located. |
| 131 | Non-nil argument (prefix, if interactive) means update the nodes in the |
| 132 | marked region. |
| 133 | |
| 134 | This command makes it awkward to navigate among sections and |
| 135 | subsections; it should be used only for those documents that are meant |
| 136 | to be read like a novel rather than a reference, and for which the |
| 137 | Info `g*' command is inadequate." |
| 138 | t nil) |
| 139 | |
| 140 | (autoload 'texinfo-make-menu |
| 141 | "texnfo-upd" |
| 142 | "Without any prefix argument, make or update a menu. |
| 143 | Make the menu for the section enclosing the node found following point. |
| 144 | |
| 145 | Non-nil argument (prefix, if interactive) means make or update menus |
| 146 | for nodes within or part of the marked region. |
| 147 | |
| 148 | Whenever a menu exists, and is being updated, the descriptions that |
| 149 | are associated with node names in the pre-existing menu are |
| 150 | incorporated into the new menu. Otherwise, the nodes' section titles |
| 151 | are inserted as descriptions." |
| 152 | t nil) |
| 153 | |
| 154 | (autoload 'texinfo-all-menus-update |
| 155 | "texnfo-upd" |
| 156 | "Update every regular menu in a Texinfo file. |
| 157 | Remove pre-existing master menu, if there is one. |
| 158 | |
| 159 | If called with a non-nil argument, this function first updates all the |
| 160 | nodes in the buffer before updating the menus." |
| 161 | t nil) |
| 162 | |
| 163 | (autoload 'texinfo-master-menu |
| 164 | "texnfo-upd" |
| 165 | "Make a master menu for a whole Texinfo file. |
| 166 | Non-nil argument (prefix, if interactive) means first update all |
| 167 | existing nodes and menus. Remove pre-existing master menu, if there is one. |
| 168 | |
| 169 | This function creates a master menu that follows the top node. The |
| 170 | master menu includes every entry from all the other menus. It |
| 171 | replaces any existing ordinary menu that follows the top node. |
| 172 | |
| 173 | If called with a non-nil argument, this function first updates all the |
| 174 | menus in the buffer (incorporating descriptions from pre-existing |
| 175 | menus) before it constructs the master menu. |
| 176 | |
| 177 | The function removes the detailed part of an already existing master |
| 178 | menu. This action depends on the pre-existing master menu using the |
| 179 | standard `texinfo-master-menu-header'. |
| 180 | |
| 181 | The master menu has the following format, which is adapted from the |
| 182 | recommendation in the Texinfo Manual: |
| 183 | |
| 184 | * The first part contains the major nodes in the Texinfo file: the |
| 185 | nodes for the chapters, chapter-like sections, and the major |
| 186 | appendices. This includes the indices, so long as they are in |
| 187 | chapter-like sections, such as unnumbered sections. |
| 188 | |
| 189 | * The second and subsequent parts contain a listing of the other, |
| 190 | lower level menus, in order. This way, an inquirer can go |
| 191 | directly to a particular node if he or she is searching for |
| 192 | specific information. |
| 193 | |
| 194 | Each of the menus in the detailed node listing is introduced by the |
| 195 | title of the section containing the menu." |
| 196 | t nil) |
| 197 | |
| 198 | (autoload 'texinfo-indent-menu-description |
| 199 | "texnfo-upd" |
| 200 | "Indent every description in menu following point to COLUMN. |
| 201 | Non-nil argument (prefix, if interactive) means indent every |
| 202 | description in every menu in the region. Does not indent second and |
| 203 | subsequent lines of a multi-line description." |
| 204 | t nil) |
| 205 | |
| 206 | (autoload 'texinfo-insert-node-lines |
| 207 | "texnfo-upd" |
| 208 | "Insert missing `@node' lines in region of Texinfo file. |
| 209 | Non-nil argument (prefix, if interactive) means also to insert the |
| 210 | section titles as node names; and also to insert the section titles as |
| 211 | node names in pre-existing @node lines that lack names." |
| 212 | t nil) |
| 213 | |
| 214 | (autoload 'texinfo-start-menu-description |
| 215 | "texnfo-upd" |
| 216 | "In this menu entry, insert the node's section title as a description. |
| 217 | Position point at beginning of description ready for editing. |
| 218 | Do not insert a title if the line contains an existing description. |
| 219 | |
| 220 | You will need to edit the inserted text since a useful description |
| 221 | complements the node name rather than repeats it as a title does." |
| 222 | t nil) |
| 223 | |
| 224 | (autoload 'texinfo-multiple-files-update |
| 225 | "texnfo-upd" |
| 226 | "Update first node pointers in each file included in OUTER-FILE; |
| 227 | create or update main menu in the outer file that refers to such nodes. |
| 228 | This does not create or update menus or pointers within the included files. |
| 229 | |
| 230 | With optional MAKE-MASTER-MENU argument (prefix arg, if interactive), |
| 231 | insert a master menu in OUTER-FILE. This does not create or update |
| 232 | menus or pointers within the included files. |
| 233 | |
| 234 | With optional UPDATE-EVERYTHING argument (numeric prefix arg, if |
| 235 | interactive), update all the menus and all the `Next', `Previous', and |
| 236 | `Up' pointers of all the files included in OUTER-FILE before inserting |
| 237 | a master menu in OUTER-FILE. |
| 238 | |
| 239 | The command also updates the `Top' level node pointers of OUTER-FILE. |
| 240 | |
| 241 | Notes: |
| 242 | |
| 243 | * this command does NOT save any files--you must save the |
| 244 | outer file and any modified, included files. |
| 245 | |
| 246 | * except for the `Top' node, this command does NOT handle any |
| 247 | pre-existing nodes in the outer file; hence, indices must be |
| 248 | enclosed in an included file. |
| 249 | |
| 250 | Requirements: |
| 251 | |
| 252 | * each of the included files must contain exactly one highest |
| 253 | hierarchical level node, |
| 254 | * this highest node must be the first node in the included file, |
| 255 | * each highest hierarchical level node must be of the same type. |
| 256 | |
| 257 | Thus, normally, each included file contains one, and only one, |
| 258 | chapter." |
| 259 | t nil) |
| 260 | |
| 261 | \f |
| 262 | ;;; Code: |
| 263 | |
| 264 | ;;; Don't you dare insert any `require' calls at top level in this file--rms. |
| 265 | |
| 266 | (defvar texinfo-section-list |
| 267 | '(("top" 1) |
| 268 | ("majorheading" 2) |
| 269 | ("chapter" 2) |
| 270 | ("unnumbered" 2) |
| 271 | ("appendix" 2) |
| 272 | ("chapheading" 2) |
| 273 | ("section" 3) |
| 274 | ("unnumberedsec" 3) |
| 275 | ("appendixsec" 3) |
| 276 | ("heading" 3) |
| 277 | ("subsection" 4) |
| 278 | ("unnumberedsubsec" 4) |
| 279 | ("appendixsubsec" 4) |
| 280 | ("subheading" 4) |
| 281 | ("subsubsection" 5) |
| 282 | ("unnumberedsubsubsec" 5) |
| 283 | ("appendixsubsubsec" 5) |
| 284 | ("subsubheading" 5)) |
| 285 | "Alist of sectioning commands and their relative level.") |
| 286 | |
| 287 | ;;; Syntax table |
| 288 | |
| 289 | (defvar texinfo-mode-syntax-table nil) |
| 290 | |
| 291 | (if texinfo-mode-syntax-table |
| 292 | nil |
| 293 | (setq texinfo-mode-syntax-table (make-syntax-table)) |
| 294 | (modify-syntax-entry ?\" "." texinfo-mode-syntax-table) |
| 295 | (modify-syntax-entry ?\\ "." texinfo-mode-syntax-table) |
| 296 | (modify-syntax-entry ?@ "\\" texinfo-mode-syntax-table) |
| 297 | (modify-syntax-entry ?\^q "\\" texinfo-mode-syntax-table) |
| 298 | (modify-syntax-entry ?\[ "(]" texinfo-mode-syntax-table) |
| 299 | (modify-syntax-entry ?\] ")[" texinfo-mode-syntax-table) |
| 300 | (modify-syntax-entry ?{ "(}" texinfo-mode-syntax-table) |
| 301 | (modify-syntax-entry ?} "){" texinfo-mode-syntax-table) |
| 302 | (modify-syntax-entry ?\n ">" texinfo-mode-syntax-table) |
| 303 | (modify-syntax-entry ?\' "w" texinfo-mode-syntax-table)) |
| 304 | |
| 305 | ;; Written by Wolfgang Bangerth <zcg51122@rpool1.rus.uni-stuttgart.de> |
| 306 | ;; To override this example, set either `imenu-generic-expression' |
| 307 | ;; or `imenu-create-index-function'. |
| 308 | (defvar texinfo-imenu-generic-expression |
| 309 | '((nil "^@\\(node\\|anchor\\)[ \t]+\\([^,\n]*\\)" 2) |
| 310 | ("Chapters" "^@chapter[ \t]+\\(.*\\)$" 1)) |
| 311 | "Imenu generic expression for TexInfo mode. See `imenu-generic-expression'.") |
| 312 | |
| 313 | (defvar texinfo-font-lock-syntactic-keywords |
| 314 | '(("\\(@\\)c\\(omment\\)?\\>" (1 "<")) |
| 315 | ("^\\(@\\)ignore\\>" (1 "< b")) |
| 316 | ("^@end ignore\\(\n\\)" (1 "> b"))) |
| 317 | "Syntactic keywords to catch comment delimiters in `texinfo-mode'.") |
| 318 | |
| 319 | (defconst texinfo-environments |
| 320 | '("cartouche" "defcv" "deffn" "defivar" "defmac" "defmethod" "defop" |
| 321 | "defopt" "defspec" "deftp" "deftypefn" "deftypefun" "deftypevar" |
| 322 | "deftypevr" "defun" "defvar" "defvr" "description" "detailmenu" |
| 323 | "direntry" "display" "enumerate" "example" "flushleft" "flushright" |
| 324 | "format" "ftable" "group" "ifclear" "ifset" "ifhtml" "ifinfo" |
| 325 | "ifnothtml" "ifnotinfo" "ifnottex" "iftex" "ignore" "itemize" "lisp" |
| 326 | "macro" "menu" "multitable" "quotation" "smalldisplay" "smallexample" |
| 327 | "smallformat" "smalllisp" "table" "tex" "titlepage" "vtable") |
| 328 | "List of TeXinfo environments.") |
| 329 | |
| 330 | (defconst texinfo-environment-regexp |
| 331 | (concat "^@" (regexp-opt (cons "end" texinfo-environments) t) "\\>") |
| 332 | "Regexp for environment-like TexInfo list commands. |
| 333 | Subexpression 1 is what goes into the corresponding `@end' statement.") |
| 334 | |
| 335 | (defface texinfo-heading-face |
| 336 | '((t (:inherit font-lock-function-name-face))) |
| 337 | "Face used for section headings in `texinfo-mode'.") |
| 338 | (defvar texinfo-heading-face 'texinfo-heading-face) |
| 339 | |
| 340 | (defvar texinfo-font-lock-keywords |
| 341 | `(;; All but the first had an OVERRIDE of t. |
| 342 | ;; It didn't seem to be any better, and it's slower--simon. |
| 343 | ;; Robert J. Chassell <bob@gnu.org> says remove this line. |
| 344 | ;;("\\$\\([^$]*\\)\\$" 1 font-lock-string-face t) |
| 345 | ("@\\([a-zA-Z]+\\|[^ \t\n]\\)" 1 font-lock-keyword-face) ;commands |
| 346 | ("^\\*\\([^\n:]*\\)" 1 font-lock-function-name-face t) ;menu items |
| 347 | ("@\\(emph\\|i\\|sc\\){\\([^}]+\\)" 2 'italic) |
| 348 | ("@\\(strong\\|b\\){\\([^}]+\\)" 2 'bold) |
| 349 | ("@\\(kbd\\|key\\|url\\|uref\\){\\([^}]+\\)" 2 font-lock-string-face) |
| 350 | ;; The following two groups have an OVERRIDE of `keep' because |
| 351 | ;; their arguments frequently include a @@, and we don't want that |
| 352 | ;; to overwrite the normal fontification of the argument. |
| 353 | ("@\\(file\\|email\\){\\([^}]+\\)" 2 font-lock-string-face keep) |
| 354 | ("@\\(samp\\|code\\|var\\|math\\|env\\|command\\|option\\){\\([^}]+\\)" |
| 355 | 2 font-lock-variable-name-face keep) |
| 356 | ("@\\(cite\\|x?ref\\|pxref\\|dfn\\|inforef\\){\\([^}]+\\)" |
| 357 | 2 font-lock-constant-face) |
| 358 | ("@\\(anchor\\){\\([^}]+\\)" 2 font-lock-type-face) |
| 359 | ("@\\(dmn\\|acronym\\|value\\){\\([^}]+\\)" 2 font-lock-builtin-face) |
| 360 | ("@\\(end\\|itemx?\\) +\\(.+\\)" 2 font-lock-keyword-face keep) |
| 361 | (,texinfo-environment-regexp |
| 362 | 1 (texinfo-clone-environment (match-beginning 1) (match-end 1)) keep) |
| 363 | (,(concat "^@" (regexp-opt (mapcar 'car texinfo-section-list) t) |
| 364 | ".*\n") 0 texinfo-heading-face t)) |
| 365 | "Additional expressions to highlight in TeXinfo mode.") |
| 366 | |
| 367 | (defun texinfo-clone-environment (start end) |
| 368 | (let ((endp nil)) |
| 369 | (save-excursion |
| 370 | (ignore-errors |
| 371 | (goto-char start) |
| 372 | (when (looking-at "end\\Sw+\\(\\sw+\\)") |
| 373 | (setq endp t start (match-beginning 1) end (match-end 1))) |
| 374 | (unless (get-char-property start 'text-clones) |
| 375 | (if endp |
| 376 | (texinfo-last-unended-begin) |
| 377 | (forward-word 1) |
| 378 | (texinfo-next-unmatched-end)) |
| 379 | (skip-syntax-forward "^w") |
| 380 | (when (looking-at (regexp-quote (buffer-substring start end))) |
| 381 | (text-clone-create start end 'spread "\\w*"))))))) |
| 382 | |
| 383 | (defun texinfo-outline-level () |
| 384 | ;; Calculate level of current texinfo outline heading. |
| 385 | (save-excursion |
| 386 | (if (bobp) |
| 387 | 0 |
| 388 | (forward-char 1) |
| 389 | (let* ((word (buffer-substring-no-properties |
| 390 | (point) (progn (forward-word 1) (point)))) |
| 391 | (entry (assoc word texinfo-section-list))) |
| 392 | (if entry |
| 393 | (nth 1 entry) |
| 394 | 5))))) |
| 395 | |
| 396 | \f |
| 397 | ;;; Keybindings |
| 398 | (defvar texinfo-mode-map nil) |
| 399 | |
| 400 | ;;; Keys common both to Texinfo mode and to TeX shell. |
| 401 | |
| 402 | (defun texinfo-define-common-keys (keymap) |
| 403 | "Define the keys both in Texinfo mode and in the texinfo-tex-shell." |
| 404 | (define-key keymap "\C-c\C-t\C-k" 'tex-kill-job) |
| 405 | (define-key keymap "\C-c\C-t\C-x" 'texinfo-quit-job) |
| 406 | (define-key keymap "\C-c\C-t\C-l" 'tex-recenter-output-buffer) |
| 407 | (define-key keymap "\C-c\C-t\C-d" 'texinfo-delete-from-print-queue) |
| 408 | (define-key keymap "\C-c\C-t\C-q" 'tex-show-print-queue) |
| 409 | (define-key keymap "\C-c\C-t\C-p" 'texinfo-tex-print) |
| 410 | (define-key keymap "\C-c\C-t\C-v" 'texinfo-tex-view) |
| 411 | (define-key keymap "\C-c\C-t\C-i" 'texinfo-texindex) |
| 412 | |
| 413 | (define-key keymap "\C-c\C-t\C-r" 'texinfo-tex-region) |
| 414 | (define-key keymap "\C-c\C-t\C-b" 'texinfo-tex-buffer)) |
| 415 | |
| 416 | ;; Mode documentation displays commands in reverse order |
| 417 | ;; from how they are listed in the texinfo-mode-map. |
| 418 | |
| 419 | (if texinfo-mode-map |
| 420 | nil |
| 421 | (setq texinfo-mode-map (make-sparse-keymap)) |
| 422 | |
| 423 | ;; bindings for `texnfo-tex.el' |
| 424 | (texinfo-define-common-keys texinfo-mode-map) |
| 425 | |
| 426 | (define-key texinfo-mode-map "\"" 'texinfo-insert-quote) |
| 427 | |
| 428 | ;; bindings for `makeinfo.el' |
| 429 | (define-key texinfo-mode-map "\C-c\C-m\C-k" 'kill-compilation) |
| 430 | (define-key texinfo-mode-map "\C-c\C-m\C-l" |
| 431 | 'makeinfo-recenter-compilation-buffer) |
| 432 | (define-key texinfo-mode-map "\C-c\C-m\C-r" 'makeinfo-region) |
| 433 | (define-key texinfo-mode-map "\C-c\C-m\C-b" 'makeinfo-buffer) |
| 434 | |
| 435 | ;; bindings for `texinfmt.el' |
| 436 | (define-key texinfo-mode-map "\C-c\C-e\C-r" 'texinfo-format-region) |
| 437 | (define-key texinfo-mode-map "\C-c\C-e\C-b" 'texinfo-format-buffer) |
| 438 | |
| 439 | ;; AUCTeX-like bindings |
| 440 | (define-key texinfo-mode-map "\e\r" 'texinfo-insert-@item) |
| 441 | |
| 442 | ;; bindings for updating nodes and menus |
| 443 | |
| 444 | (define-key texinfo-mode-map "\C-c\C-um" 'texinfo-master-menu) |
| 445 | |
| 446 | (define-key texinfo-mode-map "\C-c\C-u\C-m" 'texinfo-make-menu) |
| 447 | (define-key texinfo-mode-map "\C-c\C-u\C-n" 'texinfo-update-node) |
| 448 | (define-key texinfo-mode-map "\C-c\C-u\C-e" 'texinfo-every-node-update) |
| 449 | (define-key texinfo-mode-map "\C-c\C-u\C-a" 'texinfo-all-menus-update) |
| 450 | |
| 451 | (define-key texinfo-mode-map "\C-c\C-s" 'texinfo-show-structure) |
| 452 | |
| 453 | (define-key texinfo-mode-map "\C-c}" 'up-list) |
| 454 | (define-key texinfo-mode-map "\C-c]" 'up-list) |
| 455 | (define-key texinfo-mode-map "\C-c{" 'texinfo-insert-braces) |
| 456 | |
| 457 | ;; bindings for inserting strings |
| 458 | (define-key texinfo-mode-map "\C-c\C-o" 'texinfo-insert-block) |
| 459 | (define-key texinfo-mode-map "\C-c\C-c\C-d" 'texinfo-start-menu-description) |
| 460 | (define-key texinfo-mode-map "\C-c\C-c\C-s" 'texinfo-insert-@strong) |
| 461 | (define-key texinfo-mode-map "\C-c\C-c\C-e" 'texinfo-insert-@emph) |
| 462 | |
| 463 | (define-key texinfo-mode-map "\C-c\C-cv" 'texinfo-insert-@var) |
| 464 | (define-key texinfo-mode-map "\C-c\C-cu" 'texinfo-insert-@uref) |
| 465 | (define-key texinfo-mode-map "\C-c\C-ct" 'texinfo-insert-@table) |
| 466 | (define-key texinfo-mode-map "\C-c\C-cs" 'texinfo-insert-@samp) |
| 467 | (define-key texinfo-mode-map "\C-c\C-cq" 'texinfo-insert-@quotation) |
| 468 | (define-key texinfo-mode-map "\C-c\C-co" 'texinfo-insert-@noindent) |
| 469 | (define-key texinfo-mode-map "\C-c\C-cn" 'texinfo-insert-@node) |
| 470 | (define-key texinfo-mode-map "\C-c\C-cm" 'texinfo-insert-@email) |
| 471 | (define-key texinfo-mode-map "\C-c\C-ck" 'texinfo-insert-@kbd) |
| 472 | (define-key texinfo-mode-map "\C-c\C-ci" 'texinfo-insert-@item) |
| 473 | (define-key texinfo-mode-map "\C-c\C-cf" 'texinfo-insert-@file) |
| 474 | (define-key texinfo-mode-map "\C-c\C-cx" 'texinfo-insert-@example) |
| 475 | (define-key texinfo-mode-map "\C-c\C-ce" 'texinfo-insert-@end) |
| 476 | (define-key texinfo-mode-map "\C-c\C-cd" 'texinfo-insert-@dfn) |
| 477 | (define-key texinfo-mode-map "\C-c\C-cc" 'texinfo-insert-@code)) |
| 478 | |
| 479 | (easy-menu-define texinfo-mode-menu |
| 480 | texinfo-mode-map |
| 481 | "Menu used for `texinfo-mode'." |
| 482 | '("Texinfo" |
| 483 | ["Insert block" texinfo-insert-block t] |
| 484 | ;; ["Insert node" texinfo-insert-@node t] |
| 485 | "----" |
| 486 | ["Update All" (lambda () (interactive) (texinfo-master-menu t)) |
| 487 | :keys "\\[universal-argument] \\[texinfo-master-menu]"] |
| 488 | ["Update every node" texinfo-every-node-update t] |
| 489 | ["Update node" texinfo-update-node t] |
| 490 | ["Make Master menu" texinfo-master-menu t] |
| 491 | ["Make menu" texinfo-make-menu t] |
| 492 | ["Update all menus" texinfo-all-menus-update t] |
| 493 | "----" |
| 494 | ["Show structure" texinfo-show-structure t] |
| 495 | ["Format region" texinfo-format-region t] |
| 496 | ["Format buffer" texinfo-format-buffer t] |
| 497 | ["Makeinfo region" makeinfo-region t] |
| 498 | ["Makeinfo buffer" makeinfo-buffer t])) |
| 499 | |
| 500 | \f |
| 501 | (defun texinfo-filter (section list) |
| 502 | (let (res) |
| 503 | (dolist (x list) (if (eq section (cadr x)) (push (car x) res))) |
| 504 | res)) |
| 505 | |
| 506 | (defvar texinfo-chapter-level-regexp |
| 507 | (regexp-opt (texinfo-filter 2 texinfo-section-list)) |
| 508 | "Regular expression matching just the Texinfo chapter level headings.") |
| 509 | |
| 510 | ;;; Texinfo mode |
| 511 | |
| 512 | ;;;###autoload |
| 513 | (define-derived-mode texinfo-mode text-mode "Texinfo" |
| 514 | "Major mode for editing Texinfo files. |
| 515 | |
| 516 | It has these extra commands: |
| 517 | \\{texinfo-mode-map} |
| 518 | |
| 519 | These are files that are used as input for TeX to make printed manuals |
| 520 | and also to be turned into Info files with \\[makeinfo-buffer] or |
| 521 | the `makeinfo' program. These files must be written in a very restricted and |
| 522 | modified version of TeX input format. |
| 523 | |
| 524 | Editing commands are like text-mode except that the syntax table is |
| 525 | set up so expression commands skip Texinfo bracket groups. To see |
| 526 | what the Info version of a region of the Texinfo file will look like, |
| 527 | use \\[makeinfo-region], which runs `makeinfo' on the current region. |
| 528 | |
| 529 | You can show the structure of a Texinfo file with \\[texinfo-show-structure]. |
| 530 | This command shows the structure of a Texinfo file by listing the |
| 531 | lines with the @-sign commands for @chapter, @section, and the like. |
| 532 | These lines are displayed in another window called the *Occur* window. |
| 533 | In that window, you can position the cursor over one of the lines and |
| 534 | use \\[occur-mode-goto-occurrence], to jump to the corresponding spot |
| 535 | in the Texinfo file. |
| 536 | |
| 537 | In addition, Texinfo mode provides commands that insert various |
| 538 | frequently used @-sign commands into the buffer. You can use these |
| 539 | commands to save keystrokes. And you can insert balanced braces with |
| 540 | \\[texinfo-insert-braces] and later use the command \\[up-list] to |
| 541 | move forward past the closing brace. |
| 542 | |
| 543 | Also, Texinfo mode provides functions for automatically creating or |
| 544 | updating menus and node pointers. These functions |
| 545 | |
| 546 | * insert the `Next', `Previous' and `Up' pointers of a node, |
| 547 | * insert or update the menu for a section, and |
| 548 | * create a master menu for a Texinfo source file. |
| 549 | |
| 550 | Here are the functions: |
| 551 | |
| 552 | texinfo-update-node \\[texinfo-update-node] |
| 553 | texinfo-every-node-update \\[texinfo-every-node-update] |
| 554 | texinfo-sequential-node-update |
| 555 | |
| 556 | texinfo-make-menu \\[texinfo-make-menu] |
| 557 | texinfo-all-menus-update \\[texinfo-all-menus-update] |
| 558 | texinfo-master-menu |
| 559 | |
| 560 | texinfo-indent-menu-description (column &optional region-p) |
| 561 | |
| 562 | The `texinfo-column-for-description' variable specifies the column to |
| 563 | which menu descriptions are indented. |
| 564 | |
| 565 | Passed an argument (a prefix argument, if interactive), the |
| 566 | `texinfo-update-node' and `texinfo-make-menu' functions do their jobs |
| 567 | in the region. |
| 568 | |
| 569 | To use the updating commands, you must structure your Texinfo file |
| 570 | hierarchically, such that each `@node' line, with the exception of the |
| 571 | Top node, is accompanied by some kind of section line, such as an |
| 572 | `@chapter' or `@section' line. |
| 573 | |
| 574 | If the file has a `top' node, it must be called `top' or `Top' and |
| 575 | be the first node in the file. |
| 576 | |
| 577 | Entering Texinfo mode calls the value of `text-mode-hook', and then the |
| 578 | value of `texinfo-mode-hook'." |
| 579 | (set (make-local-variable 'page-delimiter) |
| 580 | (concat |
| 581 | "^@node [ \t]*[Tt]op\\|^@\\(" |
| 582 | texinfo-chapter-level-regexp |
| 583 | "\\)\\>")) |
| 584 | (make-local-variable 'require-final-newline) |
| 585 | (setq require-final-newline t) |
| 586 | (make-local-variable 'indent-tabs-mode) |
| 587 | (setq indent-tabs-mode nil) |
| 588 | (make-local-variable 'paragraph-separate) |
| 589 | (setq paragraph-separate |
| 590 | (concat "\b\\|@[a-zA-Z]*[ \n]\\|" paragraph-separate)) |
| 591 | (make-local-variable 'paragraph-start) |
| 592 | (setq paragraph-start (concat "\b\\|@[a-zA-Z]*[ \n]\\|" paragraph-start)) |
| 593 | (make-local-variable 'adaptive-fill-mode) |
| 594 | (setq adaptive-fill-mode nil) |
| 595 | (make-local-variable 'fill-column) |
| 596 | (setq fill-column 70) |
| 597 | (make-local-variable 'comment-start) |
| 598 | (setq comment-start "@c ") |
| 599 | (make-local-variable 'comment-start-skip) |
| 600 | (setq comment-start-skip "@c +\\|@comment +") |
| 601 | (make-local-variable 'words-include-escapes) |
| 602 | (setq words-include-escapes t) |
| 603 | (make-local-variable 'imenu-generic-expression) |
| 604 | (setq imenu-generic-expression texinfo-imenu-generic-expression) |
| 605 | (setq imenu-case-fold-search nil) |
| 606 | (make-local-variable 'font-lock-defaults) |
| 607 | (setq font-lock-defaults |
| 608 | '(texinfo-font-lock-keywords nil nil nil backward-paragraph |
| 609 | (font-lock-syntactic-keywords |
| 610 | . texinfo-font-lock-syntactic-keywords))) |
| 611 | (set (make-local-variable 'parse-sexp-lookup-properties) t) |
| 612 | (make-local-variable 'outline-regexp) |
| 613 | (setq outline-regexp |
| 614 | (concat "@" (regexp-opt (mapcar 'car texinfo-section-list) t) "\\>")) |
| 615 | (make-local-variable 'outline-level) |
| 616 | (setq outline-level 'texinfo-outline-level) |
| 617 | (make-local-variable 'tex-start-of-header) |
| 618 | (setq tex-start-of-header "%\\*\\*start") |
| 619 | (make-local-variable 'tex-end-of-header) |
| 620 | (setq tex-end-of-header "%\\*\\*end") |
| 621 | (make-local-variable 'tex-first-line-header-regexp) |
| 622 | (setq tex-first-line-header-regexp "^\\\\input") |
| 623 | (make-local-variable 'tex-trailer) |
| 624 | (setq tex-trailer "@bye\n") |
| 625 | |
| 626 | ;; Prevent filling certain lines, in addition to ones specified |
| 627 | ;; by the user. |
| 628 | (let ((prevent-filling "^@\\(def\\|multitable\\)")) |
| 629 | (set (make-local-variable 'auto-fill-inhibit-regexp) |
| 630 | (if (null auto-fill-inhibit-regexp) |
| 631 | prevent-filling |
| 632 | (concat auto-fill-inhibit-regexp "\\|" prevent-filling))))) |
| 633 | |
| 634 | |
| 635 | \f |
| 636 | ;;; Insert string commands |
| 637 | |
| 638 | (defvar texinfo-block-default "example") |
| 639 | |
| 640 | (define-skeleton texinfo-insert-block |
| 641 | "Create a matching pair @<cmd> .. @end <cmd> at point. |
| 642 | Puts point on a blank line between them." |
| 643 | (setq texinfo-block-default |
| 644 | (completing-read (format "Block name [%s]: " texinfo-block-default) |
| 645 | (mapcar 'list texinfo-environments) |
| 646 | nil nil nil nil texinfo-block-default)) |
| 647 | \n "@" str \n _ \n "@end " str \n) |
| 648 | |
| 649 | (defun texinfo-inside-macro-p (macro &optional bound) |
| 650 | "Non-nil if inside a macro matching the regexp MACRO." |
| 651 | (condition-case nil |
| 652 | (save-excursion |
| 653 | (save-restriction |
| 654 | (narrow-to-region bound (point)) |
| 655 | (while (progn |
| 656 | (up-list -1) |
| 657 | (not (condition-case nil |
| 658 | (save-excursion |
| 659 | (backward-sexp 1) |
| 660 | (looking-at macro)) |
| 661 | (scan-error nil))))) |
| 662 | t)) |
| 663 | (scan-error nil))) |
| 664 | |
| 665 | (defun texinfo-inside-env-p (env &optional bound) |
| 666 | "Non-nil if inside an environment matching the regexp @ENV." |
| 667 | (save-excursion |
| 668 | (and (re-search-backward (concat "@\\(end\\s +\\)?" env) bound t) |
| 669 | (not (match-end 1))))) |
| 670 | |
| 671 | (defun texinfo-insert-quote (&optional arg) |
| 672 | "Insert the appropriate quote mark for TeXinfo. |
| 673 | Usually inserts the value of `texinfo-open-quote' (normally ``) or |
| 674 | `texinfo-close-quote' (normally ''), depending on the context. |
| 675 | With prefix argument or inside @code or @example, inserts a plain \"." |
| 676 | (interactive "*P") |
| 677 | (let ((top (or (save-excursion (re-search-backward "@node\\>" nil t)) |
| 678 | (point-min)))) |
| 679 | (if (or arg |
| 680 | (= (preceding-char) ?\\) |
| 681 | (save-excursion |
| 682 | (backward-char (length texinfo-open-quote)) |
| 683 | (when (or (looking-at texinfo-open-quote) |
| 684 | (looking-at texinfo-close-quote)) |
| 685 | (delete-char (length texinfo-open-quote)) |
| 686 | t)) |
| 687 | (texinfo-inside-macro-p "@\\(code\\|samp\\|kbd\\)\\>" top) |
| 688 | (texinfo-inside-env-p "example\\>" top) |
| 689 | (texinfo-inside-env-p "lisp\\>" top)) |
| 690 | (self-insert-command (prefix-numeric-value arg)) |
| 691 | (insert |
| 692 | (if (memq (char-syntax (preceding-char)) '(?\( ?> ?\ )) |
| 693 | texinfo-open-quote |
| 694 | texinfo-close-quote))))) |
| 695 | |
| 696 | ;; The following texinfo-insert-@end command not only inserts a SPC |
| 697 | ;; after the @end, but tries to find out what belongs there. It is |
| 698 | ;; not very smart: it does not understand nested lists. |
| 699 | |
| 700 | (defun texinfo-last-unended-begin () |
| 701 | (while (and (re-search-backward texinfo-environment-regexp) |
| 702 | (looking-at "@end")) |
| 703 | (texinfo-last-unended-begin))) |
| 704 | |
| 705 | (defun texinfo-next-unmatched-end () |
| 706 | (while (and (re-search-forward texinfo-environment-regexp) |
| 707 | (save-excursion |
| 708 | (goto-char (match-beginning 0)) |
| 709 | (not (looking-at "@end")))) |
| 710 | (texinfo-next-unmatched-end))) |
| 711 | |
| 712 | (defun texinfo-insert-@end () |
| 713 | "Insert the matching `@end' for the last Texinfo command that needs one." |
| 714 | (interactive) |
| 715 | (let ((string |
| 716 | (ignore-errors |
| 717 | (save-excursion |
| 718 | (texinfo-last-unended-begin) |
| 719 | (match-string 1))))) |
| 720 | (insert "@end ") |
| 721 | (if string (insert string "\n")))) |
| 722 | |
| 723 | ;; The following insert commands accept a prefix arg N, which is the |
| 724 | ;; number of words (actually s-exprs) that should be surrounded by |
| 725 | ;; braces. Thus you can first paste a variable name into a .texinfo |
| 726 | ;; buffer, then say C-u 1 C-c C-c v at the beginning of the just |
| 727 | ;; pasted variable name to put @var{...} *around* the variable name. |
| 728 | ;; Operate on previous word or words with negative arg. |
| 729 | |
| 730 | ;; These commands use texinfo-insert-@-with-arg |
| 731 | (defun texinfo-insert-@-with-arg (string &optional arg) |
| 732 | (if arg |
| 733 | (progn |
| 734 | (setq arg (prefix-numeric-value arg)) |
| 735 | (if (< arg 0) |
| 736 | (progn |
| 737 | (skip-chars-backward " \t\n\r\f") |
| 738 | (save-excursion |
| 739 | (forward-sexp arg) |
| 740 | (insert "@" string "{")) |
| 741 | (insert "}")) |
| 742 | (skip-chars-forward " \t\n\r\f") |
| 743 | (insert "@" string "{") |
| 744 | (forward-sexp arg) |
| 745 | (insert "}"))) |
| 746 | (insert "@" string "{}") |
| 747 | (backward-char))) |
| 748 | |
| 749 | (defun texinfo-insert-braces () |
| 750 | "Make a pair of braces and be poised to type inside of them. |
| 751 | Use \\[up-list] to move forward out of the braces." |
| 752 | (interactive) |
| 753 | (insert "{}") |
| 754 | (backward-char)) |
| 755 | |
| 756 | (defun texinfo-insert-@code (&optional arg) |
| 757 | "Insert a `@code{...}' command in a Texinfo buffer. |
| 758 | A numeric argument says how many words the braces should surround. |
| 759 | The default is not to surround any existing words with the braces." |
| 760 | (interactive "P") |
| 761 | (texinfo-insert-@-with-arg "code" arg)) |
| 762 | |
| 763 | (defun texinfo-insert-@dfn (&optional arg) |
| 764 | "Insert a `@dfn{...}' command in a Texinfo buffer. |
| 765 | A numeric argument says how many words the braces should surround. |
| 766 | The default is not to surround any existing words with the braces." |
| 767 | (interactive "P") |
| 768 | (texinfo-insert-@-with-arg "dfn" arg)) |
| 769 | |
| 770 | (defun texinfo-insert-@email (&optional arg) |
| 771 | "Insert a `@email{...}' command in a Texinfo buffer. |
| 772 | A numeric argument says how many words the braces should surround. |
| 773 | The default is not to surround any existing words with the braces." |
| 774 | (interactive "P") |
| 775 | (texinfo-insert-@-with-arg "email" arg)) |
| 776 | |
| 777 | (defun texinfo-insert-@emph (&optional arg) |
| 778 | "Insert a `@emph{...}' command in a Texinfo buffer. |
| 779 | A numeric argument says how many words the braces should surround. |
| 780 | The default is not to surround any existing words with the braces." |
| 781 | (interactive "P") |
| 782 | (texinfo-insert-@-with-arg "emph" arg)) |
| 783 | |
| 784 | (defun texinfo-insert-@example () |
| 785 | "Insert the string `@example' in a Texinfo buffer." |
| 786 | (interactive) |
| 787 | (insert "@example\n")) |
| 788 | |
| 789 | (defun texinfo-insert-@file (&optional arg) |
| 790 | "Insert a `@file{...}' command in a Texinfo buffer. |
| 791 | A numeric argument says how many words the braces should surround. |
| 792 | The default is not to surround any existing words with the braces." |
| 793 | (interactive "P") |
| 794 | (texinfo-insert-@-with-arg "file" arg)) |
| 795 | |
| 796 | (defun texinfo-insert-@item () |
| 797 | "Insert the string `@item' in a Texinfo buffer." |
| 798 | (interactive) |
| 799 | (insert "@item") |
| 800 | (newline)) |
| 801 | |
| 802 | (defun texinfo-insert-@kbd (&optional arg) |
| 803 | "Insert a `@kbd{...}' command in a Texinfo buffer. |
| 804 | A numeric argument says how many words the braces should surround. |
| 805 | The default is not to surround any existing words with the braces." |
| 806 | (interactive "P") |
| 807 | (texinfo-insert-@-with-arg "kbd" arg)) |
| 808 | |
| 809 | (defun texinfo-insert-@node () |
| 810 | "Insert the string `@node' in a Texinfo buffer. |
| 811 | This also inserts on the following line a comment indicating |
| 812 | the order of arguments to @node." |
| 813 | (interactive) |
| 814 | (insert "@node \n@comment node-name, next, previous, up") |
| 815 | (forward-line -1) |
| 816 | (forward-char 6)) |
| 817 | |
| 818 | (defun texinfo-insert-@noindent () |
| 819 | "Insert the string `@noindent' in a Texinfo buffer." |
| 820 | (interactive) |
| 821 | (insert "@noindent\n")) |
| 822 | |
| 823 | (defun texinfo-insert-@quotation () |
| 824 | "Insert the string `@quotation' in a Texinfo buffer." |
| 825 | (interactive) |
| 826 | (insert "@quotation\n")) |
| 827 | |
| 828 | (defun texinfo-insert-@samp (&optional arg) |
| 829 | "Insert a `@samp{...}' command in a Texinfo buffer. |
| 830 | A numeric argument says how many words the braces should surround. |
| 831 | The default is not to surround any existing words with the braces." |
| 832 | (interactive "P") |
| 833 | (texinfo-insert-@-with-arg "samp" arg)) |
| 834 | |
| 835 | (defun texinfo-insert-@strong (&optional arg) |
| 836 | "Insert a `@strong{...}' command in a Texinfo buffer. |
| 837 | A numeric argument says how many words the braces should surround. |
| 838 | The default is not to surround any existing words with the braces." |
| 839 | (interactive "P") |
| 840 | (texinfo-insert-@-with-arg "strong" arg)) |
| 841 | |
| 842 | (defun texinfo-insert-@table (&optional arg) |
| 843 | "Insert the string `@table' in a Texinfo buffer." |
| 844 | (interactive "P") |
| 845 | (insert "@table ")) |
| 846 | |
| 847 | (defun texinfo-insert-@var (&optional arg) |
| 848 | "Insert a `@var{}' command in a Texinfo buffer. |
| 849 | A numeric argument says how many words the braces should surround. |
| 850 | The default is not to surround any existing words with the braces." |
| 851 | (interactive "P") |
| 852 | (texinfo-insert-@-with-arg "var" arg)) |
| 853 | |
| 854 | (defun texinfo-insert-@uref (&optional arg) |
| 855 | "Insert a `@uref{}' command in a Texinfo buffer. |
| 856 | A numeric argument says how many words the braces should surround. |
| 857 | The default is not to surround any existing words with the braces." |
| 858 | (interactive "P") |
| 859 | (texinfo-insert-@-with-arg "uref" arg)) |
| 860 | (defalias 'texinfo-insert-@url 'texinfo-insert-@uref) |
| 861 | \f |
| 862 | ;;; Texinfo file structure |
| 863 | |
| 864 | (defun texinfo-show-structure (&optional nodes-too) |
| 865 | "Show the structure of a Texinfo file. |
| 866 | List the lines in the file that begin with the @-sign commands for |
| 867 | @chapter, @section, and the like. |
| 868 | |
| 869 | With optional argument (prefix if interactive), list both the lines |
| 870 | with @-sign commands for @chapter, @section, and the like, and list |
| 871 | @node lines. |
| 872 | |
| 873 | Lines with structuring commands beginning in them are displayed in |
| 874 | another buffer named `*Occur*'. In that buffer, you can move point to |
| 875 | one of those lines and then use |
| 876 | \\<occur-mode-map>\\[occur-mode-goto-occurrence], |
| 877 | to jump to the corresponding spot in the Texinfo source file." |
| 878 | |
| 879 | (interactive "P") |
| 880 | ;; First, remember current location |
| 881 | (let ((source-buffer (current-buffer)) |
| 882 | current-location) |
| 883 | (save-excursion |
| 884 | (end-of-line) ; so as to find section on current line |
| 885 | (if (re-search-backward |
| 886 | ;; do not require `texinfo-section-types-regexp' in texnfo-upd.el |
| 887 | "^@\\(chapter \\|sect\\|subs\\|subh\\|unnum\\|major\\|chapheading \\|heading \\|appendix\\)" |
| 888 | nil t) |
| 889 | (setq current-location |
| 890 | (progn |
| 891 | (beginning-of-line) |
| 892 | (buffer-substring (point) (progn (end-of-line) (point))))) |
| 893 | ;; else point is located before before any section command |
| 894 | (setq current-location "tex"))) |
| 895 | ;; Second, create and format an *Occur* buffer |
| 896 | (save-excursion |
| 897 | (goto-char (point-min)) |
| 898 | (if nodes-too |
| 899 | (occur (concat "^@node\\>\\|" outline-regexp)) |
| 900 | (occur outline-regexp))) |
| 901 | (pop-to-buffer "*Occur*") |
| 902 | (goto-char (point-min)) |
| 903 | (let ((inhibit-read-only t)) |
| 904 | (flush-lines "-----") |
| 905 | ;; Now format the "*Occur*" buffer to show the structure. |
| 906 | ;; Thanks to ceder@signum.se (Per Cederqvist) |
| 907 | (goto-char (point-max)) |
| 908 | (let (level) |
| 909 | (while (re-search-backward "^ *[0-9]*:@\\(\\sw+\\)" nil 0) |
| 910 | (goto-char (1- (match-beginning 1))) |
| 911 | (setq level |
| 912 | (or (cadr (assoc (match-string 1) texinfo-section-list)) 2)) |
| 913 | (indent-to-column (+ (current-column) (* 4 (- level 2)))) |
| 914 | (beginning-of-line)))) |
| 915 | ;; Third, go to line corresponding to location in source file |
| 916 | ;; potential bug: two exactly similar `current-location' lines ... |
| 917 | (goto-char (point-min)) |
| 918 | (re-search-forward current-location nil t) |
| 919 | (beginning-of-line) |
| 920 | )) |
| 921 | |
| 922 | \f |
| 923 | ;;; The tex and print function definitions: |
| 924 | |
| 925 | (defcustom texinfo-texi2dvi-command "texi2dvi" |
| 926 | "*Command used by `texinfo-tex-buffer' to run TeX and texindex on a buffer." |
| 927 | :type 'string |
| 928 | :group 'texinfo) |
| 929 | |
| 930 | (defcustom texinfo-tex-command "tex" |
| 931 | "*Command used by `texinfo-tex-region' to run TeX on a region." |
| 932 | :type 'string |
| 933 | :group 'texinfo) |
| 934 | |
| 935 | (defcustom texinfo-texindex-command "texindex" |
| 936 | "*Command used by `texinfo-texindex' to sort unsorted index files." |
| 937 | :type 'string |
| 938 | :group 'texinfo) |
| 939 | |
| 940 | (defcustom texinfo-delete-from-print-queue-command "lprm" |
| 941 | "*Command string used to delete a job from the line printer queue. |
| 942 | Command is used by \\[texinfo-delete-from-print-queue] based on |
| 943 | number provided by a previous \\[tex-show-print-queue] |
| 944 | command." |
| 945 | :type 'string |
| 946 | :group 'texinfo) |
| 947 | |
| 948 | (defvar texinfo-tex-trailer "@bye" |
| 949 | "String appended after a region sent to TeX by `texinfo-tex-region'.") |
| 950 | |
| 951 | (defun texinfo-tex-region (beg end) |
| 952 | "Run TeX on the current region. |
| 953 | This works by writing a temporary file (`tex-zap-file') in the directory |
| 954 | that is the value of `tex-directory', then running TeX on that file. |
| 955 | |
| 956 | The first line of the buffer is copied to the |
| 957 | temporary file; and if the buffer has a header, it is written to the |
| 958 | temporary file before the region itself. The buffer's header is all lines |
| 959 | between the strings defined by `tex-start-of-header' and `tex-end-of-header' |
| 960 | inclusive. The header must start in the first 100 lines. |
| 961 | |
| 962 | The value of `texinfo-tex-trailer' is appended to the temporary file after the region." |
| 963 | (interactive "r") |
| 964 | (require 'tex-mode) |
| 965 | (let ((tex-command texinfo-tex-command) |
| 966 | (tex-trailer texinfo-tex-trailer)) |
| 967 | (tex-region beg end))) |
| 968 | |
| 969 | (defun texinfo-tex-buffer () |
| 970 | "Run TeX on visited file, once or twice, to make a correct `.dvi' file." |
| 971 | (interactive) |
| 972 | (require 'tex-mode) |
| 973 | (let ((tex-command texinfo-texi2dvi-command) |
| 974 | ;; Disable tex-start-options-string. texi2dvi would not |
| 975 | ;; understand anything specified here. |
| 976 | (tex-start-options-string "")) |
| 977 | (tex-buffer))) |
| 978 | |
| 979 | (defun texinfo-texindex () |
| 980 | "Run `texindex' on unsorted index files. |
| 981 | The index files are made by \\[texinfo-tex-region] or \\[texinfo-tex-buffer]. |
| 982 | This runs the shell command defined by `texinfo-texindex-command'." |
| 983 | (interactive) |
| 984 | (require 'tex-mode) |
| 985 | (tex-send-command texinfo-texindex-command (concat tex-zap-file ".??")) |
| 986 | ;; alternatively |
| 987 | ;; (send-string "tex-shell" |
| 988 | ;; (concat texinfo-texindex-command |
| 989 | ;; " " tex-zap-file ".??" "\n")) |
| 990 | (tex-recenter-output-buffer nil)) |
| 991 | |
| 992 | (defun texinfo-tex-print () |
| 993 | "Print `.dvi' file made by \\[texinfo-tex-region] or \\[texinfo-tex-buffer]. |
| 994 | This runs the shell command defined by `tex-dvi-print-command'." |
| 995 | (interactive) |
| 996 | (require 'tex-mode) |
| 997 | (tex-print)) |
| 998 | |
| 999 | (defun texinfo-tex-view () |
| 1000 | "View `.dvi' file made by \\[texinfo-tex-region] or \\[texinfo-tex-buffer]. |
| 1001 | This runs the shell command defined by `tex-dvi-view-command'." |
| 1002 | (interactive) |
| 1003 | (require 'tex-mode) |
| 1004 | (tex-view)) |
| 1005 | |
| 1006 | (defun texinfo-quit-job () |
| 1007 | "Quit currently running TeX job, by sending an `x' to it." |
| 1008 | (interactive) |
| 1009 | (if (not (get-process "tex-shell")) |
| 1010 | (error "No TeX shell running")) |
| 1011 | (tex-send-command "x")) |
| 1012 | ;; alternatively: |
| 1013 | ;; save-excursion |
| 1014 | ;; (set-buffer (get-buffer "*tex-shell*")) |
| 1015 | ;; (goto-char (point-max)) |
| 1016 | ;; (insert "x") |
| 1017 | ;; (comint-send-input) |
| 1018 | |
| 1019 | (defun texinfo-delete-from-print-queue (job-number) |
| 1020 | "Delete job from the line printer spooling queue. |
| 1021 | You are prompted for the job number (use a number shown by a previous |
| 1022 | \\[tex-show-print-queue] command)." |
| 1023 | (interactive "nPrinter job number for deletion: ") |
| 1024 | (require 'tex-mode) |
| 1025 | (if (tex-shell-running) |
| 1026 | (tex-kill-job) |
| 1027 | (tex-start-shell)) |
| 1028 | (tex-send-command texinfo-delete-from-print-queue-command job-number) |
| 1029 | ;; alternatively |
| 1030 | ;; (send-string "tex-shell" |
| 1031 | ;; (concat |
| 1032 | ;; texinfo-delete-from-print-queue-command |
| 1033 | ;; " " |
| 1034 | ;; job-number"\n")) |
| 1035 | (tex-recenter-output-buffer nil)) |
| 1036 | |
| 1037 | (provide 'texinfo) |
| 1038 | |
| 1039 | ;;; texinfo.el ends here |