EasyPG 1.07 Released
[packages] / xemacs-packages / auctex / tex-info.el
1 ;;; tex-info.el --- Support for editing Texinfo source.
2
3 ;; Copyright (C) 1993, 1994, 1997, 2000, 2001, 2004, 2005, 2006,
4 ;;               2011-2015, 2017  Free Software Foundation, Inc.
5
6 ;; Maintainer: auctex-devel@gnu.org
7 ;; Keywords: tex
8
9 ;; This file is part of AUCTeX.
10
11 ;; AUCTeX is free software; you can redistribute it and/or modify it
12 ;; under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 3, or (at your option)
14 ;; any later version.
15
16 ;; AUCTeX is distributed in the hope that it will be useful, but
17 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 ;; General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with AUCTeX; see the file COPYING.  If not, write to the Free
23 ;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 ;; 02110-1301, USA.
25
26 ;;; Code:
27
28 (eval-when-compile (require 'cl))
29
30 (require 'tex)
31
32 (require 'texinfo)
33 ;; Make sure the Texinfo mode of AUCTeX is still used after loading
34 ;; texinfo.el.  (This is only an issue on Emacs 21.)
35 (when (and (boundp 'TeX-modes)
36            (memq 'texinfo-mode TeX-modes))
37   (defalias 'texinfo-mode 'TeX-texinfo-mode))
38
39 ;;; Environments:
40 (defvar Texinfo-environment-list
41   '(("cartouche") ("command") ("copying") ("defcv") ("deffn") ("defivar")
42     ("defmac") ("defmethod") ("defop") ("defopt") ("defspec")
43     ("deftp") ("deftypefn") ("deftypefun") ("deftypevar") ("deftypevr")
44     ("defun") ("defvar") ("defvr") ("description") ("detailmenu")
45     ("direntry") ("display") ("documentdescription") ("enumerate")
46     ("example") ("float") ("flushleft") ("flushright") ("format") ("ftable")
47     ("group") ("html") ("ifclear") ("ifdocbook") ("ifhtml") ("ifinfo")
48     ("ifnotdocbook") ("ifnothtml") ("ifnotinfo") ("ifnotplaintext")
49     ("ifnottex") ("ifnotxml") ("ifplaintext") ("ifset") ("iftex")
50     ("ifxml") ("ignore") ("itemize") ("lisp") ("macro") ("menu")
51     ("multitable") ("quotation") ("smalldisplay") ("smallexample")
52     ("smallformat") ("smalllisp") ("table") ("tex") ("titlepage")
53     ("verbatim") ("vtable"))
54   "Alist of Texinfo environments.")
55
56 (defconst texinfo-environment-regexp
57   ;; Overwrite version from `texinfo.el'.
58   (concat "^@\\("
59           (mapconcat 'car Texinfo-environment-list "\\|")
60           "\\|end\\)\\>")
61   "Regexp for environment-like Texinfo list commands.
62 Subexpression 1 is what goes into the corresponding `@end' statement.")
63
64 (defun Texinfo-environment (env &optional arg)
65   "Make Texinfo environment ENV.
66 With optional ARG, modify current environment."
67   ;; XXX: This could be enhanced to act like `LaTeX-environment',
68   ;; i.e. suggest a default environment and have its own history.
69   (interactive (list (completing-read "Environment: "
70                                       Texinfo-environment-list)
71                      current-prefix-arg))
72   (if arg
73       (Texinfo-modify-environment env)
74     (Texinfo-insert-environment env)))
75
76 (defun Texinfo-insert-environment (env)
77   "Insert Texinfo environment ENV."
78   (if (and (TeX-active-mark)
79            (not (eq (mark) (point))))
80       (progn
81         (when (< (mark) (point))
82           (exchange-point-and-mark))
83         (unless (TeX-looking-at-backward "^[ \t]*")
84           (newline))
85         (insert "@" env)
86         (newline)
87         (goto-char (mark))
88         (unless (TeX-looking-at-backward "^[ \t]*")
89           (newline))
90         (insert "@end " env)
91         (save-excursion (newline))
92         (end-of-line 0))
93     (insert "@" env "\n\n@end " env "\n")
94     (if (null (cdr-safe (assoc "defcv" Texinfo-environment-list)))
95         (forward-line -2))))
96
97 (defun Texinfo-modify-environment (env)
98   "Change current environment to environment ENV."
99   (save-excursion
100     (Texinfo-find-env-end)
101     (re-search-backward (concat (regexp-quote TeX-esc) "end \\([a-zA-Z]*\\)")
102                         (line-beginning-position))
103     (replace-match env t t nil 1)
104     (beginning-of-line)
105     (Texinfo-find-env-start)
106     (re-search-forward (concat (regexp-quote TeX-esc) "\\([a-zA-Z]*\\)")
107                        (line-end-position))
108     (replace-match env t t nil 1)))
109
110 (defun Texinfo-find-env-end ()
111   "Move point to the end of the current environment."
112   (interactive)
113   (let* ((envs (mapcar 'car Texinfo-environment-list))
114          (regexp (concat "^[ \t]*" (regexp-quote TeX-esc) "\\(end \\)*"
115                          (regexp-opt envs t) "\\b"))
116          (orig-pos (point))
117          (level 1)
118          case-fold-search)
119     (save-restriction
120       (save-excursion
121         (save-excursion
122           (beginning-of-line)
123           ;; Stop if point is inside of an @end <env> command, but not
124           ;; if it is behind it.
125           (when (and (looking-at regexp)
126                      (match-string 1)
127                      (> (match-end 0) orig-pos))
128             (setq level 0)))
129         (while (and (> level 0) (re-search-forward regexp nil t))
130           (if (match-string 1)
131               (setq level (1- level))
132             (setq level (1+ level)))))
133       (if (= level 0)
134           (goto-char (match-end 0))
135         (error "Can't locate end of current environment")))))
136
137 (defun Texinfo-find-env-start ()
138   "Move point to the start of the current environment."
139   (interactive)
140   (let* ((envs (mapcar 'car Texinfo-environment-list))
141          (regexp (concat "^[ \t]*\\(" (regexp-quote TeX-esc) "\\)\\(end \\)*"
142                          (regexp-opt envs t) "\\b"))
143          (level 1)
144          (orig-pos (point))
145          case-fold-search)
146     (save-restriction
147       (save-excursion
148         (save-excursion
149           (beginning-of-line)
150           ;; Stop if point is inside of an @<env> command, but not if
151           ;; it is before it.
152           (when (and (looking-at regexp)
153                      (not (match-string 2))
154                      (< (match-beginning 1) orig-pos))
155             (setq level 0)))
156         (while (and (> level 0) (re-search-backward regexp nil t))
157           (if (match-string 2)
158               (setq level (1+ level))
159             (setq level (1- level)))))
160       (if (= level 0)
161           (goto-char (match-beginning 0))
162         (error "Can't locate start of current environment")))))
163
164 (defun Texinfo-mark-environment (&optional count)
165   "Set mark to end of current environment and point to the matching begin.
166 If prefix argument COUNT is given, mark the respective number of
167 enclosing environments.  The command will not work properly if
168 there are unbalanced begin-end pairs in comments and verbatim
169 environments."
170   ;; TODO:
171   ;; This is identical to the LaTeX counterpart but for the find begin/end
172   ;; functions. So some day the implemenation should be factorized.
173   (interactive "p")
174   (setq count (if count (abs count) 1))
175   (let ((cur (point)) beg end)
176     ;; Only change point and mark after beginning and end were found.
177     ;; Point should not end up in the middle of nowhere if the search fails.
178     (save-excursion
179       (dotimes (c count)
180         (Texinfo-find-env-end))
181       (setq end (line-beginning-position 2))
182       (goto-char cur)
183       (dotimes (c count)
184         (Texinfo-find-env-start)
185         (unless (= (1+ c) count)
186           (beginning-of-line 0)))
187       (setq beg (point)))
188     (push-mark end)
189     (goto-char beg)
190     (TeX-activate-region)))
191
192 (defun Texinfo-mark-section (&optional no-subsection)
193   "Mark current section, with inclusion of any containing node.
194
195 The current section is detected as starting by any of the
196 structuring commands matched by regexp in variable
197 `outline-regexp' which in turn is a regexp matching any element
198 of variable `texinfo-section-list'.
199
200 If optional argument NO-SUBSECTION is set to any integer or is a
201 non nil empty argument (i.e. `C-u \\[Texinfo-mark-section]'),
202 then mark the current section with exclusion of any subsections.
203
204 Otherwise, any included subsections are also marked along with
205 current section.
206
207 Note that when current section is starting immediatley after a
208 node commande, then the node command is also marked as part as
209 the section."
210   (interactive "P")
211   (let (beg end is-beg-section is-end-section
212             (section-re (concat "^\\s-*" outline-regexp)))
213     (if (and (consp no-subsection) (eq (car no-subsection) 4))
214         ;; section with exclusion of any subsection
215         (setq beg (save-excursion
216                     (unless (looking-at section-re)
217                       (end-of-line))
218                     (re-search-backward section-re nil t))
219               is-beg-section t
220               end (save-excursion
221                     (beginning-of-line)
222                     (when
223                         (re-search-forward (concat section-re
224                                                    "\\|^\\s-*@bye\\_>" ) nil t)
225                       (save-match-data
226                         (beginning-of-line)
227                         (point))))
228               is-end-section (match-string 1))
229       ;; full section without exclusion of any subsection
230       (let (section-command-level)
231         (setq beg
232               (save-excursion
233                 (end-of-line)
234                 (re-search-backward section-re nil t)))
235         (when beg
236           (setq is-beg-section t
237                 section-command-level
238                 (cadr (assoc (match-string 1) texinfo-section-list))
239                 end
240                 (save-excursion
241                   (beginning-of-line)
242                   (while
243                       (and (re-search-forward
244                             (concat section-re "\\|^\\s-*@bye\\_>" ) nil t)
245                            (or (null (setq is-end-section  (match-string 1)))
246                                (> (cadr (assoc is-end-section
247                                                texinfo-section-list))
248                                   section-command-level))))
249                   (when (match-string 0)
250                     (beginning-of-line)
251                     (point)))))));  (if ...)
252     (when (and beg end)
253       ;; now take also enclosing node of beg and end
254       (dolist
255           (boundary '(beg end))
256         (when (symbol-value (intern (concat "is-" (symbol-name boundary)
257                                             "-section")))
258           (save-excursion
259             (goto-char (symbol-value boundary))
260             (while
261                 (and
262                  (null (bobp))
263                  (progn
264                    (beginning-of-line 0)
265                    (looking-at "^\\s-*\\($\\|@\\(c\\|comment\\)\\_>\\)"))))
266             (when  (looking-at "^\\s-*@node\\_>")
267               (set boundary (point))))))
268
269       (push-mark end)
270       (goto-char beg)
271       (TeX-activate-region) )))
272
273 (defun Texinfo-mark-node ()
274   "Mark the current node.  \
275 This is the node in which the pointer is.  It is starting at
276 previous beginning of keyword `@node' and ending at next
277 beginning of keyword `@node' or `@bye'."
278   (interactive)
279   (let ((beg (save-excursion
280                (unless (looking-at "^\\s-*@\\(?:node\\)\\_>")
281                  (end-of-line))
282                (re-search-backward "^\\s-*@\\(?:node\\)\\_>" nil t )))
283         (end (save-excursion
284                (beginning-of-line)
285                (and (re-search-forward "^\\s-*@\\(?:node\\|bye\\)\\_>" nil t )
286                     (progn (beginning-of-line) (point))))))
287
288     (when (and beg end)
289       (push-mark end)
290       (goto-char beg)
291       (TeX-activate-region) )))
292
293 (defun Texinfo-nodename-de-escape (node-name)
294   "In NODE-NAME, convert `@comma{}' commands to the corresponding `,'
295 character. Return the resulting string."
296   (let ((pos 0) (map '(("comma" . ","))))
297     (while (and (< pos (length
298                         node-name)) (string-match "@\\(comma\\)[[:blank:]]*{}" node-name pos))
299       (setq node-name (concat  (substring node-name 0 (match-beginning 0))
300                                (cdr (TeX-assoc-string (match-string 1 node-name) map))
301                                (substring node-name (match-end 0)))
302             pos (1+ (match-beginning 0)))))
303   node-name)
304
305
306 (defun Texinfo-nodename-escape (node-name)
307   "Convert in NODE-NAME the `,' characters to `@comma{}'
308 commands. Return the resulting string."
309   (let* ((pos 0)
310          (map '(("," . "comma")))
311          (re (regexp-opt (mapcar 'car map))) )
312     (while (and (< pos (length node-name)) (string-match re node-name pos))
313       (setq node-name (concat  (substring node-name 0 (match-beginning 0))
314                                "@" (cdr (TeX-assoc-string (match-string 0 node-name) map))
315                                "{}"
316                                (substring node-name (match-end 0)))
317             pos (1+ (match-beginning 0)))))
318   node-name)
319
320
321 (defun Texinfo-make-node-list ()
322   ;; Build list of nodes in current buffer.
323   ;; (What about using `imenu--index-alist'?)
324   ;; FIXME: Support multi-file documents.
325   (save-excursion
326     (goto-char (point-min))
327     (let (nodes dups)
328       (while (re-search-forward "^@node\\b" nil t)
329         (skip-chars-forward "[:blank:]")
330         (pushnew (list (Texinfo-nodename-de-escape
331                         (buffer-substring-no-properties
332                          (point) (progn (skip-chars-forward "^\r\n,")
333                                         (skip-chars-backward "[:blank:]")
334                                         (point)))))
335                  nodes
336                  :test (lambda (a b)
337                          (when (equal a b)
338                            (push (cons a (TeX-line-number-at-pos (point))) dups)
339                            t))))
340       (when dups
341         (display-warning
342          'AUCTeX
343          (format "There are duplicate nodes:\n%s"
344                  (mapconcat (lambda (dup)
345                               (format "    %s on line %d" (car dup) (cdr dup)))
346                             (nreverse dups)
347                             "\n"))))
348       (nreverse nodes))))
349
350 (defun Texinfo-insert-node ()
351   "Insert a Texinfo node in the current buffer.
352 That means, insert the string `@node' and prompt for current,
353 next, previous and upper node.  If there is an active region, use
354 this for the current node and inhibit the prompt for it.  Insert
355 a comment on the following line indicating the order of arguments
356 for @node."
357   (interactive)
358   (let ((active-mark (and (TeX-active-mark) (not (eq (mark) (point)))))
359         (nodes (Texinfo-make-node-list))
360         node-name next-node previous-node up-node)
361     (unless active-mark
362       (setq node-name (Texinfo-nodename-escape
363                        (TeX-read-string "Node name: "))))
364     ;; FIXME: What if key binding for `minibuffer-complete' was changed?
365     ;; `substitute-command-keys' doesn't return the correct value.
366     (setq next-node (Texinfo-nodename-escape
367                      (completing-read "Next node (TAB completes): " nodes)))
368     (setq previous-node
369           (Texinfo-nodename-escape
370            (completing-read "Previous node (TAB completes): " nodes)))
371     (setq up-node (Texinfo-nodename-escape
372                    (completing-read "Upper node (TAB completes): " nodes)))
373     (when (and active-mark
374                (< (mark) (point)))
375       (exchange-point-and-mark))
376     (insert "@node ")
377     (if active-mark
378         (goto-char (mark))
379       (insert node-name))
380     (insert ", " next-node ", " previous-node ", " up-node
381             "\n@comment  node-name,  next,  previous,  up\n")
382     ;; Position point at first empty field.
383     (unless (and (or (> (length node-name) 0) active-mark)
384                  (> (length next-node) 0)
385                  (> (length previous-node) 0)
386                  (> (length  up-node) 0))
387       (forward-line -2)
388       (forward-char 6)
389       (catch 'break
390         (if (or (> (length node-name) 0) active-mark)
391             (progn (skip-chars-forward "^,") (forward-char 2))
392           (throw 'break nil))
393         (dolist (node (list next-node previous-node up-node))
394           (if (> (length node) 0)
395               (progn (skip-chars-forward "^,") (forward-char 2))
396             (throw 'break nil)))))))
397
398 (defun Texinfo-arg-nodename (optional &optional prompt definition)
399   "Prompt for a node name completing with known node names.
400 OPTIONAL is ignored.
401 Use PROMPT as the prompt string.
402 If DEFINITION is non-nil, then chosen node name is a node name to be
403 added to the list of defined node names. Current implementation
404 ignored DEFINITION as the full document is scanned for node names at
405 each invocation."
406   (let ((node-name (completing-read (TeX-argument-prompt optional prompt "Node")
407                                     (Texinfo-make-node-list))))
408     (insert "{" (Texinfo-nodename-escape node-name) "}" )))
409
410 (defun Texinfo-arg-lrc (optional &rest args)
411   (let ((l (read-from-minibuffer "Enter left part: "))
412         (c (read-from-minibuffer "Enter center part: "))
413         (r (read-from-minibuffer "Enter right part: ")))
414     (insert " " l " @| " c " @| " r)))
415
416 (defun Texinfo-arg-next-line (optional &rest args)
417   "Go to the beginning of next line if we are at the end of line. Otherwise insert an end-of-line."
418   (if (eolp)  (forward-line) (insert "\n")))
419
420 (defun Texinfo-arg-on|off (optional &optional prompt style)
421   "Prompt for a boolean input.
422 OPTIONAL is ignored.
423 Use PROMPT as the prompt string.
424 STYLE may be one of `:on|off' or `:true|false', if omitted `:on|off'
425 is assumed by default."
426 (let ((collection  (cdr (assq style
427                          '((nil . #1=("on" "off"))
428                            (:on|off . #1#)
429                            (:true|false "true" "false"))))))
430   (insert (if (y-or-n-p  (TeX-argument-prompt optional prompt (concat (car collection) ", not " (cadr collection))))
431                          (car collection)
432             (cadr collection)))))
433
434 (defun Texinfo-arg-choice (optional &optional prompt collection)
435   (insert (completing-read (TeX-argument-prompt optional prompt "Key")
436                            collection)))
437
438 ;; Silence the byte-compiler from warnings for variables and functions declared
439 ;; in reftex.
440 (defvar reftex-section-levels-all)
441 (defvar reftex-level-indent)
442 (defvar reftex-label-menu-flags)
443 (defvar reftex-tables-dirty)
444
445 (eval-when-compile
446   (when (fboundp 'declare-function)
447     (declare-function reftex-match-string "reftex" (n))
448     (declare-function reftex-section-number "reftex-parse" (&optional level star))
449     (declare-function reftex-nicify-text "reftex" (text))
450     (declare-function reftex-ensure-compiled-variables "reftex" ())))
451
452 (defun Texinfo-reftex-section-info (file)
453   ;; Return a section entry for the current match.
454   ;; Carefull: This function expects the match-data to be still in place!
455   (let* ((marker (set-marker (make-marker) (1- (match-beginning 3))))
456          (macro (reftex-match-string 3))
457          (level-exp (cdr (assoc macro reftex-section-levels-all)))
458          (level (if (symbolp level-exp)
459                     (save-match-data (funcall level-exp))
460                   level-exp))
461          (unnumbered  (< level 0))
462          (level (abs level))
463          (section-number (reftex-section-number level unnumbered))
464          (text1 (save-match-data
465                   (save-excursion
466                     (buffer-substring-no-properties (point) (progn (end-of-line) (point))))))
467          (literal (buffer-substring-no-properties
468                    (1- (match-beginning 3))
469                    (min (point-max) (+ (match-end 0) (length text1) 1))))
470          ;; Literal can be too short since text1 too short. No big problem.
471          (text (reftex-nicify-text text1)))
472
473     ;; Add section number and indentation
474     (setq text
475           (concat
476            (make-string (* reftex-level-indent level) ?\ )
477            (if (nth 1 reftex-label-menu-flags) ; section number flag
478                (concat section-number " "))
479            text))
480     (list 'toc "toc" text file marker level section-number
481           literal (marker-position marker))))
482
483 (defun Texinfo-reftex-hook ()
484   "Hook function to plug Texinfo into RefTeX."
485   ;; force recompilation of variables
486   (when (string= TeX-base-mode-name "Texinfo")
487     ;; dirty temporary hook to remove when reftex has a Texinfo builtin
488     ;; TODO --- taken on <2014-01-06 mon> --- remove the dirty trick once reftex
489     ;; has been corrected for long enough a time
490     (unless (assq 'Texinfo reftex-label-alist-builtin)
491       (setq reftex-label-alist-builtin (append reftex-label-alist-builtin
492                                                '((Texinfo "Texinfo default environments" nil)))))
493     (dolist (v `((reftex-section-pre-regexp . "@")
494                  ; section post-regexp must contain exactly one group
495                  (reftex-section-post-regexp . "\\([ \t]+\\)")
496                  (reftex-section-info-function . Texinfo-reftex-section-info)
497                  (reftex-default-label-alist-entries . (Texinfo))
498                (reftex-section-levels
499                 . ,(mapcar
500                     (lambda (x)
501                       (if (string-match "\\(\\`unnumbered\\)\\|\\(heading\\'\\)\\|\\(\\`top\\'\\)"
502                                         (car x))
503                           (cons (car x) (- (cadr x)))
504                         (cons (car x) (cadr x))))
505                     texinfo-section-list))))
506       (set (make-local-variable (car v) ) (cdr v)))
507     (reftex-ensure-compiled-variables)))
508
509 ;;; Keymap:
510
511 (defvar Texinfo-mode-map
512   (let ((map (make-sparse-keymap)))
513     (set-keymap-parent map TeX-mode-map)
514
515     ;; From texinfo.el
516     ;; bindings for updating nodes and menus
517     (define-key map "\C-c\C-um"      'texinfo-master-menu)
518     (define-key map "\C-c\C-u\C-m"   'texinfo-make-menu)
519     (define-key map "\C-c\C-u\C-n"   'texinfo-update-node)
520     (define-key map "\C-c\C-u\C-e"   'texinfo-every-node-update)
521     (define-key map "\C-c\C-u\C-a"   'texinfo-all-menus-update)
522
523     ;; Simulating LaTeX-mode
524     (define-key map "\C-c\C-e" 'Texinfo-environment)
525     (define-key map "\C-c." 'Texinfo-mark-environment)
526     (define-key map "\C-c*" 'Texinfo-mark-section)
527     (define-key map "\M-\C-h" 'Texinfo-mark-node)
528     (define-key map "\C-c\n"   'texinfo-insert-@item)
529     (or (key-binding "\e\r")
530         (define-key map "\e\r" 'texinfo-insert-@item)) ;*** Alias
531     (define-key map "\C-c\C-s" 'Texinfo-insert-node)
532     (define-key map "\C-c]" 'texinfo-insert-@end)
533     map)
534   "Keymap for Texinfo mode.")
535
536 (easy-menu-define Texinfo-command-menu
537   Texinfo-mode-map
538   "Menu used in Texinfo mode for external commands."
539   (TeX-mode-specific-command-menu 'texinfo-mode))
540
541 (easy-menu-define Texinfo-mode-menu
542   Texinfo-mode-map
543   "Menu used in Texinfo mode."
544   (TeX-menu-with-help
545    `("Texinfo"
546      ["Node ..." texinfo-insert-@node
547       :help "Insert a node"]
548      ["Macro ..." TeX-insert-macro
549       :help "Insert a macro and possibly arguments"]
550      ["Complete Macro" TeX-complete-symbol
551       :help "Complete the current macro"]
552      ["Environment ..." Texinfo-insert-environment
553       :help "Insert an environment"]
554      ["Item" texinfo-insert-@item
555       :help "Insert an @item"]
556      "-"
557      ("Insert Font"
558       ["Emphasize"  (TeX-font nil ?\C-e) :keys "C-c C-f C-e"]
559       ["Bold"       (TeX-font nil ?\C-b) :keys "C-c C-f C-b"]
560       ["Typewriter" (TeX-font nil ?\C-t) :keys "C-c C-f C-t"]
561       ["Small Caps" (TeX-font nil ?\C-c) :keys "C-c C-f C-c"]
562       ["Italic"     (TeX-font nil ?\C-i) :keys "C-c C-f C-i"]
563       ["Sample"    (TeX-font nil ?\C-s) :keys "C-c C-f C-s"]
564       ["Roman"      (TeX-font nil ?\C-r) :keys "C-c C-f C-r"])
565      ("Replace Font"
566       ["Emphasize"  (TeX-font t ?\C-e) :keys "C-u C-c C-f C-e"]
567       ["Bold"       (TeX-font t ?\C-b) :keys "C-u C-c C-f C-b"]
568       ["Typewriter" (TeX-font t ?\C-t) :keys "C-u C-c C-f C-t"]
569       ["Small Caps" (TeX-font t ?\C-c) :keys "C-u C-c C-f C-c"]
570       ["Italic"     (TeX-font t ?\C-i) :keys "C-u C-c C-f C-i"]
571       ["Sample"    (TeX-font t ?\C-s) :keys "C-u C-c C-f C-s"]
572       ["Roman"      (TeX-font t ?\C-r) :keys "C-u C-c C-f C-r"])
573      ["Delete Font" (TeX-font t ?\C-d) :keys "C-c C-f C-d"]
574      "-"
575      ["Create Master Menu" texinfo-master-menu
576       :help "Make a master menu for the whole Texinfo file"]
577      ["Create Menu" texinfo-make-menu
578       :help "Make or update the menu for the current section"]
579      ["Update Node" texinfo-update-node
580       :help "Update the current node"]
581      ["Update Every Node" texinfo-every-node-update
582       :help "Update every node in the current file"]
583      ["Update All Menus" texinfo-all-menus-update
584       :help "Update every menu in the current file"]
585      "-"
586      ("Commenting"
587       ["Comment or Uncomment Region"
588        TeX-comment-or-uncomment-region
589        :help "Comment or uncomment the currently selected region"]
590       ["Comment or Uncomment Paragraph"
591        TeX-comment-or-uncomment-paragraph
592        :help "Comment or uncomment the current paragraph"])
593      ,TeX-fold-menu
594      "-"
595      . ,TeX-common-menu-entries)))
596
597 (defvar Texinfo-font-list
598   '((?\C-b "@b{" "}")
599     (?\C-c "@sc{" "}")
600     (?\C-e "@emph{" "}")
601     (?\C-i "@i{" "}")
602     (?\C-r "@r{" "}")
603     (?\C-s "@samp{" "}")
604     (?\C-t "@t{" "}")
605     (?s    "@strong{" "}")
606     (?\C-f "@file{" "}")
607     (?d "@dfn{" "}")
608     (?\C-v "@var{" "}")
609     (?k    "@key{" "}")
610     (?\C-k "@kbd{" "}")
611     (?c    "@code{" "}")
612     (?C    "@cite{" "}")
613     (?\C-d "" "" t))
614   "Font commands used in Texinfo mode.  See `TeX-font-list'.")
615
616 ;;; Mode:
617
618 ;;;###autoload
619 (defalias 'Texinfo-mode 'texinfo-mode)
620
621 ;;;###autoload
622 (defun TeX-texinfo-mode ()
623   "Major mode in AUCTeX for editing Texinfo files.
624
625 Special commands:
626 \\{Texinfo-mode-map}
627
628 Entering Texinfo mode calls the value of `text-mode-hook'  and then the
629 value of `Texinfo-mode-hook'."
630   (interactive)
631   (kill-all-local-variables)
632   (setq TeX-mode-p t)
633   (setq TeX-output-extension (if TeX-PDF-mode "pdf" "dvi"))
634   (setq TeX-sentinel-default-function 'TeX-TeX-sentinel)
635   ;; Mostly stolen from texinfo.el
636   (setq TeX-base-mode-name "Texinfo")
637   (setq major-mode 'texinfo-mode)
638   (use-local-map Texinfo-mode-map)
639   (set-syntax-table texinfo-mode-syntax-table)
640
641   (set (make-local-variable 'page-delimiter)
642        (concat
643         "^@node [ \t]*[Tt]op\\|^@\\("
644         texinfo-chapter-level-regexp
645         "\\)"))
646   (set (make-local-variable 'require-final-newline) t)
647   (set (make-local-variable 'indent-tabs-mode) nil)
648   (set (make-local-variable 'paragraph-separate)
649        (concat "\b\\|@[a-zA-Z]*[ \n]\\|" paragraph-separate))
650   (set (make-local-variable 'paragraph-start)
651        (concat "\b\\|@[a-zA-Z]*[ \n]\\|" paragraph-start))
652   (set (make-local-variable 'fill-column) 72)
653   (set (make-local-variable 'comment-start) "@c ")
654   (set (make-local-variable 'comment-start-skip) "@c +\\|@comment +")
655   (set (make-local-variable 'comment-use-syntax) nil)
656   (set (make-local-variable 'words-include-escapes) t)
657   (set (make-local-variable 'imenu-generic-expression)
658        texinfo-imenu-generic-expression)
659
660   (set (make-local-variable 'font-lock-defaults)
661         ;; COMPATIBILITY for Emacs 20
662         (if (boundp 'texinfo-font-lock-syntactic-keywords)
663             '(texinfo-font-lock-keywords
664               nil nil nil backward-paragraph
665               (font-lock-syntactic-keywords
666                . texinfo-font-lock-syntactic-keywords))
667           ;; This is for Emacs >= 23.3, when
668           ;; `texinfo-font-lock-syntactic-keywords' was removed.
669           '(texinfo-font-lock-keywords nil nil nil backward-paragraph)))
670
671   ;; Outline settings.
672   (set (make-local-variable 'outline-regexp)
673        (concat "@\\("
674                (mapconcat 'car texinfo-section-list "\\>\\|")
675                "\\>\\)"))
676   (set (make-local-variable 'outline-level) 'texinfo-outline-level)
677
678   ;; Mostly AUCTeX stuff
679   (easy-menu-add Texinfo-mode-menu Texinfo-mode-map)
680   (easy-menu-add Texinfo-command-menu Texinfo-mode-map)
681   (set (make-local-variable 'TeX-command-current) 'TeX-command-master)
682
683   (setq TeX-default-extension "texi")
684   (set (make-local-variable 'TeX-esc) "@")
685
686   (set (make-local-variable 'TeX-auto-regexp-list) 'TeX-auto-empty-regexp-list)
687   (set (make-local-variable 'TeX-auto-update) t)
688
689   (setq TeX-command-default "TeX")
690   (setq TeX-header-end "%*end")
691   (setq TeX-trailer-start (regexp-quote (concat TeX-esc "bye")))
692
693   (set (make-local-variable 'TeX-complete-list)
694         (list (list "@\\([a-zA-Z]*\\)" 1 'TeX-symbol-list-filtered nil)
695               (list "" TeX-complete-word)))
696
697   (set (make-local-variable 'TeX-font-list) Texinfo-font-list)
698   (set (make-local-variable 'TeX-font-replace-function) 'TeX-font-replace-macro)
699   (set (make-local-variable 'TeX-style-hook-dialect) :texinfo)
700
701   (add-hook 'find-file-hook (lambda ()
702                               (unless (file-exists-p (buffer-file-name))
703                                 (TeX-master-file nil nil t)))
704             nil t)
705
706   (when (and (boundp 'add-log-current-defun-function)
707              (fboundp 'texinfo-current-defun-name))
708     (setq add-log-current-defun-function
709           #'texinfo-current-defun-name))
710
711   (TeX-add-symbols
712    '("acronym" "Acronym")
713    '("allowcodebreaks" (TeX-arg-literal " ") (Texinfo-arg-on|off nil :true|false) (Texinfo-arg-next-line))
714    '("appendix" (TeX-arg-literal " ") (TeX-arg-free "Title"))
715    '("appendixsec" (TeX-arg-literal " ") (TeX-arg-free "Title"))
716    '("appendixsection" (TeX-arg-literal " ") (TeX-arg-free "Title"))
717    '("appendixsubsec" (TeX-arg-literal " ") (TeX-arg-free "Title"))
718    '("appendixsubsubsec" (TeX-arg-literal " ") (TeX-arg-free "Title"))
719    '("asis")
720    '("atchar" nil)
721    '("author" (TeX-arg-literal " ") (TeX-arg-free "Author"))
722    '("b" "Text")
723    '("bullet")
724    '("bye")
725    '("c" (TeX-arg-literal " ") (TeX-arg-free "Comment"))
726    '("caption" "Caption"
727      ;; TODO: caption is meaningful only inside float env. Maybe some checking
728      ;; and warning would be good.
729      )
730    '("center" (TeX-arg-literal " ") (TeX-arg-free "Line of text"))
731    '("chapheading" (TeX-arg-literal " ") (TeX-arg-free "Title"))
732    '("chapter" (TeX-arg-literal " ") (TeX-arg-free "Title"))
733    '("cindex" (TeX-arg-literal " ") (TeX-arg-free "Entry"))
734    '("cite" "Reference")
735    '("clear" (TeX-arg-literal " ") (TeX-arg-free "Flag"))
736    '("code" "Sample code")
737    '("codequotebacktick" (TeX-arg-literal " ") (Texinfo-arg-on|off) (Texinfo-arg-next-line))
738    '("codequoteundirected"  (TeX-arg-literal " ") (Texinfo-arg-on|off) (Texinfo-arg-next-line))
739    '("command" "Command")
740    '("comment" (TeX-arg-literal " ") (TeX-arg-free "Comment"))
741    '("contents")
742    '("copyright" nil)
743    '("defcodeindex" (TeX-arg-literal " ") (TeX-arg-free "Index name"))
744    '("defindex" (TeX-arg-literal " ") (TeX-arg-free "Index name"))
745    '("dfn" "Term")
746    '("dmn" "Dimension")
747    '("documentlanguage"  (TeX-arg-literal " ") (Texinfo-arg-choice "Language" ("ca" "cs" "de" "en" "es" "fr" "hu" "is" "it" "ja" "nb" "nl" "nn" "pl" "pt" "ru" "sr" "tr" "uk"))  (Texinfo-arg-next-line))
748    '("documentencoding"  (TeX-arg-literal " ") (Texinfo-arg-choice "Encoding" ("US-ASCII" "UTF-8" "ISO-8859-1" "ISO-8859-15" "ISO-8859-2" "koi8-r" "koi8-u"))  (Texinfo-arg-next-line))
749    '("dots" nil)
750    '("emph" "Text")
751    '("email" "Email address")
752    '("equiv" nil)
753    '("error")
754    '("evenfooting" Texinfo-arg-lrc)
755    '("evenheading" Texinfo-arg-lrc)
756    '("everyfooting" Texinfo-arg-lrc)
757    '("everyheading" Texinfo-arg-lrc)
758    '("exdent" (TeX-arg-literal " ") (TeX-arg-free "Line of text"))
759    '("expansion" nil)
760    '("file" "Filename")
761    '("finalout")
762    '("findex" (TeX-arg-literal " ") (TeX-arg-free "Entry"))
763    '("footnote" "Text of footnote")
764    '("footnotestyle" (TeX-arg-literal " ") (TeX-arg-free "Style"))
765    '("guillemetleft")
766    '("guillemetright")
767    '("guilsinglleft")
768    '("guilsinglright")
769    '("heading" (TeX-arg-literal " ") (TeX-arg-free "Title"))
770    ;; XXX: Would be nice with completion.
771    '("headings" (TeX-arg-literal " ") (TeX-arg-free "On off single double"))
772    '("i" "Text")
773    '("ignore")
774    '("include" (TeX-arg-literal " ") (TeX-arg-free "Filename"))
775    '("inforef" "Node name" "Info file name")
776    '("item")
777    '("itemx")
778    '("kbd" "Keyboard characters")
779    '("key" "Key name")
780    '("kindex" (TeX-arg-literal " ") (TeX-arg-free "Entry"))
781    '("LaTeX" nil)
782    '("lowersections" 0)
783    '("majorheading" (TeX-arg-literal " ") (TeX-arg-free "Title"))
784    '("menu")
785    '("minus")
786    '("need" "N")
787    '("node" (TeX-arg-literal " ") (TeX-arg-free "Name")
788      (TeX-arg-literal ", ") (TeX-arg-free "Next")
789      (TeX-arg-literal ", ") (TeX-arg-free "Previous")
790      (TeX-arg-literal ", ") (TeX-arg-free "Up"))
791    '("noindent")
792    '("oddfooting" Texinfo-arg-lrc)
793    '("oddheading" Texinfo-arg-lrc)
794    '("page")
795    '("paragraphindent" (TeX-arg-literal " ") (TeX-arg-free "Indent"))
796    '("pindex" "Entry")
797    '("point" nil)
798    '("print")
799    '("printindex" (TeX-arg-literal " ") (TeX-arg-free "Index name"))
800    '("pxref" (Texinfo-arg-nodename "Node name"))
801    '("quotedblbase")
802    '("quotesinglbase")
803    '("r" "Text")
804    '("raisesections" 0)
805    '("ref" (Texinfo-arg-nodename "Node name"))
806    '("refill")
807    '("result")
808    '("samp" "Text")
809    '("sc" "Text")
810    '("section" (TeX-arg-literal " ") (TeX-arg-free "Title"))
811    '("set" (TeX-arg-literal " ") (TeX-arg-free "Flag"))
812    '("setchapternewpage" (TeX-arg-literal " ") (Texinfo-arg-choice "On off odd" ("on" "off" "odd")) (Texinfo-arg-next-line))
813    '("setfilename" (TeX-arg-literal " ") (TeX-arg-free "Info file name"))
814    '("settitle" (TeX-arg-literal " ") (TeX-arg-free "Title"))
815    '("shortcontents")
816    '("smallbook")
817    '("sp" "N")
818    '("strong" "Text")
819    '("subheading" (TeX-arg-literal " ") (TeX-arg-free "Title"))
820    '("subsection" (TeX-arg-literal " ") (TeX-arg-free "Title"))
821    '("subsubheading" (TeX-arg-literal " ") (TeX-arg-free "Title"))
822    '("subsubsection" (TeX-arg-literal " ") (TeX-arg-free "Title"))
823    '("subtitle" (TeX-arg-literal " ") (TeX-arg-free "Title"))
824    '("summarycontents")
825    '("syncodeindex" (TeX-arg-literal " ") (TeX-arg-free "From index")
826      (TeX-arg-literal " ") (TeX-arg-free "Into index"))
827    '("synindex" (TeX-arg-literal " ") (TeX-arg-free "From index")
828      (TeX-arg-literal " ") (TeX-arg-free "Into index"))
829    '("t" "Text")
830    '("TeX" nil)
831    '("thischapter")
832    '("thischaptername")
833    '("thisfile")
834    '("thispage")
835    '("tie")
836    '("tindex" (TeX-arg-literal " ") (TeX-arg-free "Entry"))
837    '("title" (TeX-arg-literal " ") (TeX-arg-free "Title"))
838    '("titlefont" "Text")
839    '("titlepage")
840    '("today" nil)
841    '("top" (TeX-arg-literal " ") (TeX-arg-free "Title"))
842    '("unnumbered" (TeX-arg-literal " ") (TeX-arg-free "Title"))
843    '("unnumberedsec" (TeX-arg-literal " ") (TeX-arg-free "Title"))
844    '("unnumberedsubsec" (TeX-arg-literal " ") (TeX-arg-free "Title"))
845    '("unnumberedsubsubsec" (TeX-arg-literal " ") (TeX-arg-free "Title"))
846    '("url" "Link")
847    '("value" "Flag")
848    '("var" "Metasyntactic variable")
849    '("vindex" (TeX-arg-literal " ") (TeX-arg-free "Entry"))
850    '("vskip" (TeX-arg-literal " ") (TeX-arg-free "Amount"))
851    '("w" "Text")
852    '("xref" (Texinfo-arg-nodename "Node name")))
853
854   ;; RefTeX plugging
855   (add-hook 'reftex-mode-hook 'Texinfo-reftex-hook)
856   (if (and (boundp 'reftex-mode) reftex-mode)
857       (Texinfo-reftex-hook))
858
859   (TeX-run-mode-hooks 'text-mode-hook 'Texinfo-mode-hook)
860   (TeX-set-mode-name))
861
862 (defcustom Texinfo-clean-intermediate-suffixes nil
863   "List of regexps matching suffixes of files to be deleted.
864 The regexps will be anchored at the end of the file name to be matched,
865 i.e. you do _not_ have to cater for this yourself by adding \\\\' or $."
866   :type '(repeat regexp)
867   :group 'TeX-command)
868
869 (defcustom Texinfo-clean-output-suffixes
870   ;; See `man texi2html' for the HTML stuff.
871   '("\\.info\\(-[0-9]+\\)?" "\\.dvi" "\\.pdf" "\\.ps" "\\.html"
872     "_toc\\.html" "_fot\\.html" "_abt\\.html" "_[0-9]+\\.html" "_l2h_img.+")
873   "List of regexps matching suffixes of files to be deleted.
874 The regexps will be anchored at the end of the file name to be matched,
875 i.e. you do _not_ have to cater for this yourself by adding \\\\' or $."
876   :type '(repeat regexp)
877   :group 'TeX-command)
878
879 (provide 'tex-info)
880
881 ;;; tex-info.el ends here