"Fossies" - the Fresh Open Source Software Archive

Member "auctex-12.3/tex.el" (18 Oct 2020, 247919 Bytes) of package /linux/misc/auctex-12.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Lisp source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "tex.el": 12.2_vs_12.3.

    1 ;;; tex.el --- Support for TeX documents.
    2 
    3 ;; Copyright (C) 1985-2020 Free Software Foundation, Inc.
    4 
    5 ;; Maintainer: auctex-devel@gnu.org
    6 ;; Keywords: tex
    7 
    8 ;; This file is part of AUCTeX.
    9 
   10 ;; AUCTeX is free software; you can redistribute it and/or modify it
   11 ;; under the terms of the GNU General Public License as published by
   12 ;; the Free Software Foundation; either version 3, or (at your option)
   13 ;; any later version.
   14 
   15 ;; AUCTeX is distributed in the hope that it will be useful, but
   16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
   17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   18 ;; General Public License for more details.
   19 
   20 ;; You should have received a copy of the GNU General Public License
   21 ;; along with AUCTeX; see the file COPYING.  If not, write to the Free
   22 ;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   23 ;; 02110-1301, USA.
   24 
   25 ;;; Commentary:
   26 
   27 ;; This file provides basic functions used by the AUCTeX modes.
   28 
   29 ;;; Code:
   30 
   31 (when (< emacs-major-version 24)
   32   (error "AUCTeX requires Emacs 24 or later"))
   33 
   34 (require 'custom)
   35 (require 'tex-site)
   36 (eval-when-compile
   37   (require 'cl-lib))
   38 (require 'texmathp)
   39 
   40 ;; Silence the compiler for functions:
   41 (declare-function dbus-ignore-errors "ext:dbus"
   42           (&rest body))
   43 (declare-function dbus-get-unique-name "ext:dbusbind.c"
   44           (bus))
   45 (declare-function dbus-ping "ext:dbus"
   46           (bus service &optional timeout))
   47 (declare-function dbus-introspect-get-method "ext:dbus"
   48           (bus service path interface method))
   49 (declare-function dbus-call-method "ext:dbus"
   50           (bus service path interface method &rest args))
   51 (declare-function dbus-register-signal "ext:dbus"
   52           (bus service path interface signal handler &rest args))
   53 (declare-function TeX-output-extension "tex-buf"
   54           nil)
   55 (declare-function TeX-command-expand "tex-buf"
   56           (command file &optional list))
   57 (declare-function TeX-active-master "tex-buf"
   58           (&optional extension nondirectory ignore))
   59 (declare-function TeX-pop-to-buffer "tex-buf"
   60           (buffer &optional other-window norecord))
   61 (declare-function LaTeX-environment-list "latex"
   62           nil)
   63 (declare-function tex--prettify-symbols-compose-p "ext:tex-mode"
   64           (start end match))
   65 ;; spell-buffer was removed in 2008 in favor of ispell
   66 (declare-function spell-buffer "ext:text-mode"
   67           t)
   68 
   69 ;; Silence the compiler for variables:
   70 ;; tex.el: Variables defined somewhere in this file:
   71 (defvar TeX-PDF-from-DVI)
   72 (defvar TeX-PDF-mode)
   73 (defvar TeX-PDF-mode-parsed)
   74 (defvar TeX-all-extensions)
   75 (defvar TeX-command-default)
   76 (defvar TeX-default-extension)
   77 (defvar TeX-esc)
   78 (defvar TeX-interactive-mode)
   79 (defvar TeX-macro-global)
   80 (defvar TeX-mode-map)
   81 (defvar TeX-mode-p)
   82 (defvar TeX-output-extension)
   83 (defvar TeX-output-extension)
   84 (defvar TeX-source-correlate-mode)
   85 (defvar TeX-source-specials-places)
   86 (defvar TeX-source-specials-tex-flags)
   87 (defvar TeX-synctex-tex-flags)
   88 ;; Variables defined in other AUCTeX libraries:
   89 ;; latex.el:
   90 (defvar BibLaTeX-global-style-files)
   91 (defvar BibTeX-global-files)
   92 (defvar BibTeX-global-style-files)
   93 (defvar LaTeX-default-verb-delimiter)
   94 (defvar LaTeX-global-class-files)
   95 (defvar LaTeX-optcl)
   96 (defvar LaTeX-optop)
   97 (defvar TeX-Biber-global-files)
   98 (defvar TeX-global-input-files)
   99 ;; tex-buf.el
  100 (defvar TeX-current-process-region-p)
  101 (defvar TeX-region)
  102 (defvar TeX-region-orig-buffer)
  103 ;; tex-ispell.el
  104 (defvar TeX-ispell-verb-delimiters)
  105 ;; graphicx.el
  106 (defvar LaTeX-includegraphics-global-files)
  107 ;; Others:
  108 (defvar tex--prettify-symbols-alist)    ; tex-mode.el
  109 (defvar Info-file-list-for-emacs)   ; info.el
  110 
  111 (defgroup TeX-file nil
  112   "Files used by AUCTeX."
  113   :group 'AUCTeX)
  114 
  115 (defgroup TeX-command nil
  116   "Calling external commands from AUCTeX."
  117   :group 'AUCTeX)
  118 
  119 (defgroup LaTeX nil
  120   "LaTeX support in AUCTeX."
  121   :tag "LaTeX"
  122   :group 'AUCTeX
  123   :prefix "LaTeX-")
  124 
  125 (defgroup TeX-misc nil
  126   "Various AUCTeX settings."
  127   :group 'AUCTeX)
  128 
  129 ;;; Site Customization
  130 ;;
  131 ;; The following variables are likely to need to be changed for your
  132 ;; site.  You should do this with customize.
  133 
  134 (defcustom TeX-command "tex"
  135   "Command to run plain TeX."
  136   :group 'TeX-command
  137   :type 'string)
  138 
  139 (defcustom TeX-Omega-command "omega"
  140   "Command to run plain TeX on Omega."
  141   :group 'TeX-command
  142   :type '(choice (const :tag "Aleph" "aleph")
  143          (const :tag "Omega" "omega")
  144          (string :tag "Other command")))
  145 
  146 (defcustom LaTeX-command "latex"
  147   "Command to run LaTeX."
  148   :group 'TeX-command
  149   :type 'string)
  150 
  151 (defcustom LaTeX-Omega-command "lambda"
  152   "Command to run LaTeX on Omega."
  153   :group 'TeX-command
  154   :type '(choice (const :tag "Lamed" "lamed")
  155          (const :tag "Lambda" "lambda")
  156          (string :tag "Other command")))
  157 
  158 (defcustom TeX-file-line-error t
  159   "Whether to have TeX produce file:line:error style error messages."
  160   :group 'TeX-command
  161   :type 'boolean)
  162 
  163 (defcustom ConTeXt-engine nil
  164   "Engine to use for --engine in the texexec command.
  165 If nil, none is specified."
  166   :group 'TeX-command
  167   :type '(choice (const :tag "Unspecified" nil)
  168          string))
  169 
  170 (defcustom ConTeXt-Omega-engine TeX-Omega-command
  171   "Engine to use for --engine in the texexec command in Omega mode.
  172 If nil, none is specified."
  173   :group 'TeX-command
  174   :type '(choice (const :tag "Unspecified" nil)
  175          string))
  176 ;; At least in TeXLive 2009 ConTeXt does not support an omega option anymore.
  177 (make-obsolete-variable 'ConTeXt-Omega-engine 'TeX-engine-alist "11.86")
  178 
  179 (defcustom TeX-mode-hook nil
  180   "A hook run in TeX mode buffers."
  181   :type 'hook
  182   :group 'TeX-misc)
  183 
  184 ;; This is the major configuration variable.  Most sites will only need to
  185 ;; change the second string in each entry, which is the name of a command to
  186 ;; send to the shell.  If you use other formatters like AMSLaTeX or AMSTeX, you
  187 ;; can add those to the list.  See `TeX-expand-list' and
  188 ;; `TeX-expand-list-builtin' for a description of the % escapes
  189 
  190 (defcustom TeX-command-list
  191   '(("TeX" "%(PDF)%(tex) %(file-line-error) %`%(extraopts) %S%(PDFout)%(mode)%' %t"
  192      TeX-run-TeX nil
  193      (plain-tex-mode ams-tex-mode texinfo-mode) :help "Run plain TeX")
  194     ("LaTeX" "%`%l%(mode)%' %T"
  195      TeX-run-TeX nil
  196      (latex-mode doctex-mode) :help "Run LaTeX")
  197     ;; Not part of standard TeX.
  198     ("Makeinfo" "makeinfo %(extraopts) %t" TeX-run-compile nil
  199      (texinfo-mode) :help "Run Makeinfo with Info output")
  200     ("Makeinfo HTML" "makeinfo %(extraopts) --html %t" TeX-run-compile nil
  201      (texinfo-mode) :help "Run Makeinfo with HTML output")
  202     ("AmSTeX" "amstex %(PDFout) %`%(extraopts) %S%(mode)%' %t"
  203      TeX-run-TeX nil (ams-tex-mode) :help "Run AMSTeX")
  204     ;; support for ConTeXt  --pg
  205     ;; first version of ConTeXt to support nonstopmode: 2003.2.10
  206     ("ConTeXt" "%(cntxcom) --once --texutil %(extraopts) %(execopts)%t"
  207      TeX-run-TeX nil (context-mode) :help "Run ConTeXt once")
  208     ("ConTeXt Full" "%(cntxcom) %(extraopts) %(execopts)%t"
  209      TeX-run-TeX nil
  210      (context-mode) :help "Run ConTeXt until completion")
  211     ("BibTeX" "bibtex %s" TeX-run-BibTeX nil
  212      (plain-tex-mode latex-mode doctex-mode ams-tex-mode texinfo-mode
  213              context-mode)
  214      :help "Run BibTeX")
  215     ("Biber" "biber %s" TeX-run-Biber nil
  216      (plain-tex-mode latex-mode doctex-mode ams-tex-mode texinfo-mode)
  217      :help "Run Biber")
  218     ("View" "%V" TeX-run-discard-or-function t t :help "Run Viewer")
  219     ("Print" "%p" TeX-run-command t t :help "Print the file")
  220     ("Queue" "%q" TeX-run-background nil t :help "View the printer queue"
  221      :visible TeX-queue-command)
  222     ("File" "%(o?)dvips %d -o %f " TeX-run-dvips t
  223      (plain-tex-mode latex-mode doctex-mode ams-tex-mode texinfo-mode)
  224      :help "Generate PostScript file")
  225     ("Dvips" "%(o?)dvips %d -o %f " TeX-run-dvips nil
  226      (plain-tex-mode latex-mode doctex-mode ams-tex-mode texinfo-mode)
  227      :help "Convert DVI file to PostScript")
  228     ("Dvipdfmx" "dvipdfmx %d" TeX-run-dvipdfmx nil
  229      (plain-tex-mode latex-mode doctex-mode ams-tex-mode texinfo-mode)
  230      :help "Convert DVI file to PDF with dvipdfmx")
  231     ("Ps2pdf" "ps2pdf %f" TeX-run-ps2pdf nil
  232      (plain-tex-mode latex-mode doctex-mode ams-tex-mode texinfo-mode)
  233      :help "Convert PostScript file to PDF")
  234     ("Glossaries" "makeglossaries %s" TeX-run-command nil
  235      (plain-tex-mode latex-mode doctex-mode ams-tex-mode texinfo-mode)
  236      :help "Run makeglossaries to create glossary
  237      file")
  238     ("Index" "makeindex %s" TeX-run-index nil
  239      (plain-tex-mode latex-mode doctex-mode ams-tex-mode texinfo-mode)
  240      :help "Run makeindex to create index file")
  241     ("upMendex" "upmendex %s" TeX-run-index t
  242      (plain-tex-mode latex-mode doctex-mode ams-tex-mode texinfo-mode)
  243      :help "Run upmendex to create index file")
  244     ("Xindy" "texindy %s" TeX-run-command nil
  245      (plain-tex-mode latex-mode doctex-mode ams-tex-mode texinfo-mode)
  246      :help "Run xindy to create index file")
  247     ("Check" "lacheck %s" TeX-run-compile nil (latex-mode)
  248      :help "Check LaTeX file for correctness")
  249     ("ChkTeX" "chktex -v6 %s" TeX-run-compile nil (latex-mode)
  250      :help "Check LaTeX file for common mistakes")
  251     ("Spell" "(TeX-ispell-document \"\")" TeX-run-function nil t
  252      :help "Spell-check the document")
  253     ("Clean" "TeX-clean" TeX-run-function nil t
  254      :help "Delete generated intermediate files")
  255     ("Clean All" "(TeX-clean t)" TeX-run-function nil t
  256      :help "Delete generated intermediate and output files")
  257     ("Other" "" TeX-run-command t t :help "Run an arbitrary command"))
  258   "List of commands to execute on the current document.
  259 
  260 Each element is a list, whose first element is the name of the command
  261 as it will be presented to the user.
  262 
  263 The second element is the string handed to the shell after being
  264 expanded.  The expansion is done using the information found in
  265 `TeX-expand-list'.
  266 
  267 The third element is the function which actually start the process.
  268 Several such hooks has been defined:
  269 
  270 TeX-run-command: Start up the process and show the output in a
  271 separate buffer.  Check that there is not two commands running for the
  272 same file.  Return the process object.
  273 
  274 TeX-run-format: As `TeX-run-command', but assume the output is created
  275 by a TeX macro package.  Return the process object.
  276 
  277 TeX-run-TeX: For TeX output.
  278 
  279 TeX-run-interactive: Run TeX or LaTeX interactively.
  280 
  281 TeX-run-BibTeX: For BibTeX output.
  282 
  283 TeX-run-Biber: For Biber output.
  284 
  285 TeX-run-compile: Use `compile' to run the process.
  286 
  287 TeX-run-shell: Use `shell-command' to run the process.
  288 
  289 TeX-run-discard: Start the process in the background, discarding its
  290 output.
  291 
  292 TeX-run-background: Start the process in the background, show output
  293 in other window.
  294 
  295 TeX-run-silent: Start the process in the background.
  296 
  297 TeX-run-discard-foreground: Start the process in the foreground,
  298 discarding its output.
  299 
  300 TeX-run-function: Execute the Lisp function or function call
  301 specified by the string in the second element.  Consequently,
  302 this hook does not start a process.
  303 
  304 TeX-run-discard-or-function: If the command is a Lisp function,
  305 execute it as such, otherwise start the command as a process,
  306 discarding its output.
  307 
  308 To create your own hook, define a function taking three arguments: The
  309 name of the command, the command string, and the name of the file to
  310 process.  It might be useful to use `TeX-run-command' in order to
  311 create an asynchronous process.
  312 
  313 If the fourth element is non-nil, the user will get a chance to
  314 modify the expanded string.
  315 
  316 The fifth element indicates in which mode(s) the command should be
  317 present in the Command menu.  Use t if it should be active in any
  318 mode.  If it should only be present in some modes, specify a list with
  319 the respective mode names.
  320 
  321 Any additional elements get just transferred to the respective menu entries."
  322   :group 'TeX-command
  323   :type '(repeat (group :value ("" "" TeX-run-command nil t)
  324             (string :tag "Name")
  325             (string :tag "Command")
  326             (choice :tag "How"
  327                 :value TeX-run-command
  328                 (function-item TeX-run-command)
  329                 (function-item TeX-run-format)
  330                 (function-item TeX-run-TeX)
  331                 (function-item TeX-run-interactive)
  332                 (function-item TeX-run-BibTeX)
  333                 (function-item TeX-run-Biber)
  334                 (function-item TeX-run-compile)
  335                 (function-item TeX-run-shell)
  336                 (function-item TeX-run-discard)
  337                 (function-item TeX-run-background)
  338                 (function-item TeX-run-silent)
  339                 (function-item TeX-run-discard-foreground)
  340                 (function-item TeX-run-function)
  341                 (function-item TeX-run-discard-or-function)
  342                 (function :tag "Other"))
  343             (boolean :tag "Prompt")
  344             (choice :tag "Modes"
  345                 (const :tag "All" t)
  346                 (set (const :tag "Plain TeX" plain-tex-mode)
  347                      (const :tag "LaTeX" latex-mode)
  348                      (const :tag "DocTeX" doctex-mode)
  349                      (const :tag "ConTeXt" context-mode)
  350                      (const :tag "Texinfo" texinfo-mode)
  351                      (const :tag "AmSTeX" ams-tex-mode)))
  352             (repeat :tag "Menu elements" :inline t sexp))))
  353 
  354 (defcustom TeX-command-output-list
  355   '(
  356                     ; Add the following line if you want to use htlatex (tex4ht)
  357                     ;    ("\\`htlatex" ("html"))
  358     )
  359   "List of regexps and file extensions.
  360 
  361 Each element is a list, whose first element is a regular expression to
  362 match against the name of the command that will be used to process the TeX
  363 file.
  364 
  365 The second element is either a string or a list with a string as element.
  366 If it is a string this is the default file extension that will be expected
  367 for output files that are produced by commands that match the first
  368 element.  The real file extension will be obtained from the logging output
  369 if possible, defaulting to the given string.
  370 If it is a list, the element of the list will be the fixed extension used
  371 without looking at the logging output.
  372 
  373 If this list does not yield an extension, the default is either \"dvi\"
  374 or \"pdf\", depending on the setting of `TeX-PDF-mode'.
  375 Extensions must be given without the \".\"."
  376 
  377   :group 'TeX-command
  378   :type '(repeat (group (regexp :tag "Command Regexp")
  379             (choice (string :tag "Default Extension")
  380                 (group (string :tag "Fixed Extension"))))))
  381 
  382 ;; You may want to change the default LaTeX version for your site.
  383 (defcustom LaTeX-version "2e"
  384   "Default LaTeX version.  Currently recognized is \"2\" and \"2e\"."
  385   :group 'LaTeX
  386   :type '(radio (const :format "%v\n%h"
  387                :doc "\
  388 The executable `latex' is LaTeX version 2."
  389                "2")
  390         (const :format "%v\n%h"
  391                :doc "\
  392 The executable `latex' is LaTeX version 2e."
  393                "2e")
  394         (string :tag "Other")))
  395 
  396 
  397 ;; Use different compilation commands depending on style.
  398 ;; Only works if parsing is enabled.
  399 
  400 (defcustom LaTeX-command-style
  401   ;; They have all been combined in LaTeX 2e.
  402   '(("" "%(PDF)%(latex) %(file-line-error) %(extraopts) %S%(PDFout)"))
  403 "List of style options and LaTeX commands.
  404 
  405 If the first element (a regular expression) matches the name of one of
  406 the style files, any occurrence of the string `%l' in a command in
  407 `TeX-command-list' will be replaced with the second element.  The first
  408 match is used, if no match is found the `%l' is replaced with the empty
  409 string."
  410   :group 'TeX-command
  411   :type '(repeat (group :value ("" "")
  412             regexp (string :tag "Style"))))
  413 
  414 ;; Printing: If you want to print, TeX-print-command must be non-nil
  415 ;; (if it is nil, you'll get a complaint when using the print menu).
  416 ;; If you want to view the queue, TeX-queue-command needs to be
  417 ;; non-nil (if it is nil, it won't get mentioned in the menu).  If
  418 ;; TeX-printer-list is nil, nothing else gets asked: the menu entries
  419 ;; lead directly to the respective commands.  If those commands
  420 ;; contain %p, the value of TeX-printer-default gets inserted there,
  421 ;; no questions asked.  Now if TeX-printer-list is non-nil, you'll
  422 ;; always get asked which printer you want to use.  You can enter a
  423 ;; configured printer from TeX-printer-list, or an unknown one.  The
  424 ;; respective menus will show all configured printers.  Since you can
  425 ;; enter unknown printers, the printer name _must_ be set with %p in
  426 ;; TeX-print-command.
  427 
  428 (defcustom TeX-print-command
  429   "{ test -e %s.dvi && %(o?)dvips -P%p %r %s; } || lpr -P%p %o"
  430   "Command used to print a file.
  431 
  432 First `%p' is expanded to the printer name, then ordinary expansion is
  433 performed as specified in `TeX-expand-list'.  If it is nil,
  434 then customization is requested."
  435   :group 'TeX-command
  436   :type '(choice (string :tag "Print command")
  437          (const :tag "No print command customized" nil)))
  438 
  439 (defcustom TeX-queue-command "lpq -P%p"
  440   "Command used to show the status of a printer queue.
  441 
  442 First `%p' is expanded to the printer name, then ordinary expansion is
  443 performed as specified in `TeX-expand-list'.  If this is nil,
  444 the printer has no corresponding command."
  445   :group 'TeX-command
  446   :type '(choice (string :tag "Queue check command")
  447          (const :tag "No such command" nil)))
  448 
  449 ;; Enter the names of the printers available at your site, or nil if
  450 ;; you only have one printer.
  451 
  452 (defcustom TeX-printer-list
  453   '(("Default"
  454      ;; Print to the (unnamed) default printer.  If there is a DVI
  455      ;; file print via Dvips.  If not, pass the output file (which
  456      ;; should then be a Postscript or PDF file) directly to lpr.
  457      "{ test -e %s.dvi && %(o?)dvips -f %r %s | lpr; } || lpr %o"
  458      ;; Show the queue for the (unnamed) default printer.
  459      "lpq"))
  460   "List of available printers.
  461 
  462 The first element of each entry is the printer name.
  463 
  464 The second element is the command used to print to this
  465 printer.  It defaults to the value of `TeX-print-command' when nil.
  466 
  467 The third element is the command used to examine the print queue for
  468 this printer.  It defaults to the value of `TeX-queue-command' similarly.
  469 
  470 Any occurrence of `%p' in the second or third element is expanded to
  471 the printer name given in the first element, then ordinary expansion
  472 is performed as specified in `TeX-expand-list'.
  473 
  474 If this list is empty, only `TeX-print-command' and `TeX-queue-command'
  475 get consulted."
  476   :group 'TeX-command
  477   :type '(repeat (group (string :tag "Name")
  478             (option (group :inline t
  479                        :extra-offset -4
  480                        (choice :tag "Print"
  481                            (const :tag "default")
  482                            (string :format "%v"))
  483                        (option (choice :tag "Queue"
  484                                (const :tag "default")
  485                                (string
  486                             :format "%v"))))))))
  487 
  488 ;; The name of the most used printer.
  489 
  490 (defcustom TeX-printer-default (or (getenv "PRINTER")
  491                    (and TeX-printer-list
  492                     (car (car TeX-printer-list)))
  493                    "lp")
  494   "Default printer to use with `TeX-command'."
  495   :group 'TeX-command
  496   :type 'string)
  497 
  498 (defcustom TeX-print-style '(("^landscape$" "-t landscape"))
  499   "List of style options and print options.
  500 
  501 If the first element (a regular expression) matches the name of one of
  502 the style files, any occurrence of the string `%r' in a command in
  503 `TeX-command-list' will be replaced with the second element.  The first
  504 match is used, if no match is found the `%r' is replaced with the empty
  505 string."
  506   :group 'TeX-command
  507   :type '(repeat (group regexp (string :tag "Command"))))
  508 
  509 (defcustom TeX-command-extra-options ""
  510   "String with the extra options to be given to the TeX processor."
  511   :type 'string)
  512 (make-variable-buffer-local 'TeX-command-extra-options)
  513 
  514 ;; This is the list of expansion for the commands in
  515 ;; TeX-command-list.  Not likely to be changed, but you may e.g. want
  516 ;; to handle .ps files.
  517 
  518 (defvar TeX-expand-list-builtin
  519   '(("%q" (lambda ()
  520         (TeX-printer-query t)))
  521     ("%V" (lambda ()
  522         (TeX-source-correlate-start-server-maybe)
  523         (TeX-view-command-raw)))
  524     ("%vv" (lambda ()
  525          (TeX-source-correlate-start-server-maybe)
  526          (TeX-output-style-check TeX-output-view-style)))
  527     ("%v" (lambda ()
  528         (TeX-source-correlate-start-server-maybe)
  529         (TeX-style-check TeX-view-style)))
  530     ("%r" (lambda ()
  531         (TeX-style-check TeX-print-style)))
  532     ("%l" (lambda ()
  533         (TeX-style-check LaTeX-command-style)))
  534     ("%(PDF)" (lambda ()
  535         (if (and (eq TeX-engine 'default)
  536              (if TeX-PDF-mode
  537                  (not (TeX-PDF-from-DVI))
  538                TeX-DVI-via-PDFTeX))
  539             "pdf"
  540           "")))
  541     ("%(PDFout)" (lambda ()
  542            (cond ((eq major-mode 'ams-tex-mode)
  543               (if TeX-PDF-mode
  544                   " -output-format=pdf"
  545                 " -output-format=dvi"))
  546              ((and (eq TeX-engine 'xetex)
  547                    (not TeX-PDF-mode))
  548               " -no-pdf")
  549              ((and (eq TeX-engine 'luatex)
  550                    (not TeX-PDF-mode))
  551               " --output-format=dvi")
  552              ((and (eq TeX-engine 'default)
  553                    (not TeX-PDF-mode)
  554                    TeX-DVI-via-PDFTeX)
  555               " \"\\pdfoutput=0 \"")
  556              (t ""))))
  557     ("%(mode)" (lambda ()
  558          (if TeX-interactive-mode
  559              ""
  560            " -interaction=nonstopmode")))
  561     ("%(file-line-error)"
  562      (lambda () (if TeX-file-line-error " -file-line-error" "")))
  563     ("%(o?)" (lambda () (if (eq TeX-engine 'omega) "o" "")))
  564     ("%(tex)" (lambda () (eval (nth 2 (TeX-engine-in-engine-alist TeX-engine)))))
  565     ("%(latex)" (lambda () (eval (nth 3 (TeX-engine-in-engine-alist TeX-engine)))))
  566     ("%(cntxcom)" ConTeXt-expand-command)
  567     ("%(execopts)" ConTeXt-expand-options)
  568     ("%(extraopts)" (lambda () TeX-command-extra-options))
  569     ("%S" TeX-source-correlate-expand-options)
  570     ("%dS" TeX-source-specials-view-expand-options)
  571     ("%cS" TeX-source-specials-view-expand-client)
  572     ("%(outpage)" (lambda ()
  573             ;; When `TeX-source-correlate-output-page-function' is nil
  574             ;; and we are using synctex, fallback on
  575             ;; `TeX-synctex-output-page'.
  576             (and TeX-source-correlate-mode
  577              (null TeX-source-correlate-output-page-function)
  578              (eq (TeX-source-correlate-method-active) 'synctex)
  579              (setq TeX-source-correlate-output-page-function
  580                    'TeX-synctex-output-page))
  581             (or (if TeX-source-correlate-output-page-function
  582                 (funcall TeX-source-correlate-output-page-function))
  583             "1")))
  584     ;; `file' means to call `TeX-master-file', `TeX-region-file' or `TeX-active-master'
  585     ("%s" file nil t)
  586     ("%t" file t t)
  587     ;; If any TeX codes appear in the interval between %` and %', move
  588     ;; all of them after the interval and supplement " \input".  The
  589     ;; appearance is marked by leaving the bind to `TeX-command-text'
  590     ;; with the TeX codes.
  591     ;; Rule:
  592     ;; 1. %` and %' must appear in pair.
  593     ;; 2. %` and %' must not appear more than once in one command
  594     ;;    line string (including the results of %-expansion).
  595     ;; 3. Each TeX codes between %` and %' must be enclosed in
  596     ;;    double quotes and preceded by a space.
  597     ("%`" (lambda nil
  598         (setq TeX-command-pos t TeX-command-text nil)
  599         ""))
  600     (" \"\\" (lambda nil
  601            (if (eq TeX-command-pos t)
  602            (setq TeX-command-pos pos
  603              pos (+ 3 pos))
  604          (setq pos (1+ pos)))))
  605     ("\"" (lambda nil (if (numberp TeX-command-pos)
  606               (setq TeX-command-text
  607                 (concat
  608                  TeX-command-text
  609                  (substring command
  610                         TeX-command-pos
  611                         (1+ pos)))
  612                 command
  613                 (concat
  614                  (substring command
  615                         0
  616                         TeX-command-pos)
  617                  (substring command
  618                         (1+ pos)))
  619                 pos TeX-command-pos
  620                 TeX-command-pos t)
  621             (setq pos (1+ pos)))))
  622     ("%'" (lambda nil
  623         (setq TeX-command-pos nil)
  624         (if (stringp TeX-command-text)
  625         (progn
  626           (setq pos (+ pos (length TeX-command-text) 9))
  627           (concat TeX-command-text " \"\\input\""))
  628           "")))
  629     ;; The fourth argument of t is actually for wrapper function
  630     ;; provided by `TeX--master-or-region-file-with-extra-quotes'.
  631     ;; See its doc string as well as the comments in
  632     ;; `TeX-command-expand'.
  633     ("%T" file t t nil t)
  634     ("%n" TeX-current-line)
  635     ("%d" file "dvi" t)
  636     ("%f" file "ps" t)
  637     ("%o" (lambda nil (funcall file (TeX-output-extension) t)))
  638     ;; for source specials the file name generated for the xdvi
  639     ;; command needs to be relative to the master file, just in
  640     ;; case the file is in a different subdirectory
  641     ("%b" TeX-current-file-name-master-relative)
  642     ;; Okular forward PDF search requires absolute path.
  643     ("%a" (lambda nil (prin1-to-string (expand-file-name (buffer-file-name)))))
  644     ;; the following is for preview-latex.
  645     ("%m" preview-create-subdirectory))
  646   "List of built-in expansion strings for TeX command names.
  647 
  648 This should not be changed by the user who can use
  649 `TeX-expand-list' variable.  The latter variable also contains a
  650 description of the data format.
  651 
  652 Programs should not use these variables directly but the function
  653 `TeX-expand-list'.")
  654 
  655 (defcustom TeX-expand-list nil
  656   "List of expansion strings for TeX command names defined by the user.
  657 
  658 Each entry is a list with two or more elements.  The first
  659 element is the string to be expanded.  The second element is the
  660 name of a function returning the expanded string when called with
  661 the remaining elements as arguments.  The special value `file'
  662 will be expanded to the name of the file being processed, with an
  663 optional extension.
  664 
  665 Built-in expansions provided in `TeX-expand-list-builtin' can be
  666 overwritten by defining expansions strings with the same
  667 expander.  Only \"%p\" expander cannot be overwritten.
  668 
  669 Programs should not use these variables directly but the function
  670 `TeX-expand-list'."
  671   :group 'TeX-command
  672   :type '(repeat (group (string :tag "Key")
  673             (sexp :tag "Expander")
  674             (repeat :inline t
  675                 :tag "Arguments"
  676                 (sexp :format "%v")))))
  677 
  678 (defun TeX-expand-list ()
  679   "Complete list of expansion strings for TeX command names.
  680 
  681 Concatenate `TeX-expand-list' and `TeX-expand-list-builtin' making
  682 sure \"%p\" is the first entry."
  683   (append
  684    ;; %p must be the first entry, see `TeX-print-command'.
  685    '(("%p" TeX-printer-query))
  686    TeX-expand-list
  687    TeX-expand-list-builtin))
  688 
  689 ;; The following dependencies are not done with autoload cookies since
  690 ;; they are only useful when tex.el is loaded, anyway.  tex-buf.el
  691 ;; should remain unloaded as long as one is only editing files, so
  692 ;; requiring it here would be wrong.
  693 
  694 (autoload 'TeX-region-create "tex-buf" nil nil)
  695 (autoload 'TeX-save-document "tex-buf" nil t)
  696 (autoload 'TeX-home-buffer "tex-buf" nil t)
  697 (autoload 'TeX-pin-region "tex-buf" nil t)
  698 (autoload 'TeX-command-region "tex-buf" nil t)
  699 (autoload 'TeX-command-buffer "tex-buf" nil t)
  700 (autoload 'TeX-command-master "tex-buf" nil t)
  701 (autoload 'LaTeX-command-section "tex-buf" nil t)
  702 (autoload 'TeX-command-run-all "tex-buf" nil t)
  703 (autoload 'TeX-command-run-all-region "tex-buf" nil t)
  704 (autoload 'LaTeX-command-run-all-section "tex-buf" nil t)
  705 (autoload 'TeX-command "tex-buf" nil nil)
  706 (autoload 'TeX-kill-job "tex-buf" nil t)
  707 (autoload 'TeX-recenter-output-buffer "tex-buf" nil t)
  708 (autoload 'TeX-next-error "tex-buf" nil t)
  709 (autoload 'TeX-error-overview "tex-buf" nil t)
  710 (autoload 'TeX-region-file "tex-buf" nil nil)
  711 (autoload 'TeX-current-offset "tex-buf" nil nil)
  712 (autoload 'TeX-process-set-variable "tex-buf" nil nil)
  713 (autoload 'TeX-view "tex-buf" nil t)
  714 
  715 ;;; Portability.
  716 
  717 (defmacro TeX--if-macro-fboundp (name then &rest else)
  718   "Execute THEN if macro NAME is bound and ELSE otherwise.
  719 Essentially,
  720 
  721   (TeX--if-macro-fboundp name then else...)
  722 
  723 is equivalent to
  724 
  725   (if (fboundp 'name) then else...)
  726 
  727 but takes care of byte-compilation issues where the byte-code for
  728 the latter could signal an error if it has been compiled with
  729 emacs 24.1 and is then later run by emacs 24.5."
  730   (declare (indent 2) (debug (symbolp form &rest form)))
  731   (if (fboundp name)            ;If macro exists at compile-time, just use it.
  732       then
  733     `(if (fboundp ',name)       ;Else, check if it exists at run-time.
  734      (eval ',then)          ;If it does, then run the then code.
  735        ,@else)))                ;Otherwise, run the else code.
  736 
  737 (require 'easymenu)
  738 
  739 ;;; Documentation for Info-goto-emacs-command-node and similar
  740 
  741 (eval-after-load 'info '(dolist (elt '("TeX" "LaTeX" "ConTeXt" "Texinfo"
  742                        "docTeX"))
  743               (add-to-list 'Info-file-list-for-emacs
  744                        (cons elt "AUCTeX"))))
  745 
  746 (defadvice hack-one-local-variable (after TeX-hack-one-local-variable-after
  747                       activate)
  748   "Call minor mode function if minor mode variable is found."
  749   (let ((var (ad-get-arg 0))
  750     (val (ad-get-arg 1)))
  751     ;; Instead of checking for each mode explicitely `minor-mode-list'
  752     ;; could be used.  But this may make the byte compiler pop up.
  753     (when (memq var '(TeX-PDF-mode
  754               TeX-source-correlate-mode TeX-interactive-mode
  755               TeX-fold-mode LaTeX-math-mode))
  756       (if (symbol-value val) (funcall var 1) (funcall var 0)))))
  757 
  758 (defvar TeX-overlay-priority-step 16
  759   "Numerical difference of priorities between nested overlays.
  760 The step should be big enough to allow setting a priority for new
  761 overlays between two existing ones.")
  762 
  763 ;; require crm here, because we often do
  764 ;;
  765 ;; (let ((crm-separator ","))
  766 ;;   (TeX-completing-read-multiple ...))
  767 ;;
  768 ;; which results in a void-variable error if crm hasn't been loaded before.
  769 (require 'crm)
  770 
  771 (if (or (and (= emacs-major-version 24) (>= emacs-minor-version 4))
  772     (>= emacs-major-version 25))
  773     ;; For GNU Emacs 24.4 or later, based on `completing-read-multiple' of
  774     ;; git commit b14abca9476cba2f500b5eda89441d593dd0f12b
  775     ;;   2013-01-10  * lisp/emacs-lisp/crm.el: Allow any regexp for separators.
  776     (defun TeX-completing-read-multiple
  777     (prompt table &optional predicate require-match initial-input
  778         hist def inherit-input-method)
  779       "Like `completing-read-multiple' which see.
  780 Retain zero-length substrings but ensure that empty input results
  781 in nil across different emacs versions."
  782       (unwind-protect
  783       (progn
  784         (add-hook 'choose-completion-string-functions
  785               'crm--choose-completion-string)
  786         (let* ((minibuffer-completion-table #'crm--collection-fn)
  787            (minibuffer-completion-predicate predicate)
  788            ;; see completing_read in src/minibuf.c
  789            (minibuffer-completion-confirm
  790             (unless (eq require-match t) require-match))
  791            (crm-completion-table table)
  792            (map (if require-match
  793                 crm-local-must-match-map
  794               crm-local-completion-map))
  795            ;; If the user enters empty input, `read-from-minibuffer'
  796            ;; returns the empty string, not DEF.
  797            (input (read-from-minibuffer
  798                prompt initial-input map
  799                nil hist def inherit-input-method))
  800            result)
  801           (and def (string-equal input "") (setq input def))
  802           (if (equal (setq result (split-string input crm-separator))
  803              '(""))
  804           nil
  805         result)))
  806     (remove-hook 'choose-completion-string-functions
  807              'crm--choose-completion-string)))
  808   ;; For GNU Emacs <= 24.3.
  809   (defun TeX-completing-read-multiple
  810       (prompt table &optional predicate require-match initial-input
  811           hist def inherit-input-method)
  812     "Like `completing-read-multiple' which see.
  813 Ensures that empty input results in nil across different emacs versions."
  814     (let ((result (completing-read-multiple prompt table predicate
  815                         require-match initial-input
  816                         hist def inherit-input-method)))
  817       (if (equal result '("")) nil result))))
  818 
  819 (defun TeX-read-string (prompt &optional initial-input history default-value)
  820   (read-string prompt initial-input history default-value t))
  821 
  822 (defun TeX-active-mark ()
  823   (and transient-mark-mode mark-active))
  824 
  825 (defun TeX-activate-region ()
  826   (setq deactivate-mark nil)
  827   (activate-mark))
  828 
  829 (defun TeX-overlay-prioritize (start end)
  830   "Calculate a priority for an overlay extending from START to END.
  831 The calculated priority is lower than the minimum of priorities
  832 of surrounding overlays and higher than the maximum of enclosed
  833 overlays."
  834   (let (outer-priority inner-priority ov-priority)
  835     (dolist (ov (overlays-in start end))
  836       (when (or (eq (overlay-get ov 'category) 'TeX-fold)
  837         (overlay-get ov 'preview-state))
  838     (setq ov-priority (overlay-get ov 'priority))
  839     (if (>= (overlay-start ov) start)
  840         (setq inner-priority (max ov-priority (or inner-priority
  841                               ov-priority)))
  842       (setq outer-priority (min ov-priority (or outer-priority
  843                             ov-priority))))))
  844     (cond ((and inner-priority (not outer-priority))
  845        (+ inner-priority TeX-overlay-priority-step))
  846       ((and (not inner-priority) outer-priority)
  847        (/ outer-priority 2))
  848       ((and inner-priority outer-priority)
  849        (+ (/ (- outer-priority inner-priority) 2) inner-priority))
  850       (t TeX-overlay-priority-step))))
  851 
  852 (defun TeX-delete-dups-by-car (alist &optional keep-list)
  853   "Return a list of all elements in ALIST, but each car only once.
  854 Elements of KEEP-LIST are not removed even if duplicate."
  855   ;; Copy of `reftex-uniquify-by-car' (written by David Kastrup).
  856   (setq keep-list (TeX-sort-strings keep-list))
  857   (setq alist (sort (copy-sequence alist)
  858             #'TeX-car-string-lessp))
  859   (let ((new alist) elt)
  860     (while (cdr new)
  861       (setq elt (caar new))
  862       (while (and keep-list (string< (car keep-list) elt))
  863     (setq keep-list (cdr keep-list)))
  864       (unless (and keep-list (string= elt (car keep-list)))
  865     (while (string= elt (car (cadr new)))
  866       (setcdr new (cddr new))))
  867       (setq new (cdr new))))
  868   alist)
  869 
  870 (defun TeX-delete-duplicate-strings (list)
  871   "Return a list of all strings in LIST, but each only once."
  872   (setq list (TeX-sort-strings list))
  873   (let ((new list) elt)
  874     (while (cdr new)
  875       (setq elt (car new))
  876       (while (string= elt (cadr new))
  877     (setcdr new (cddr new)))
  878       (setq new (cdr new))))
  879   list)
  880 
  881 (defun TeX-sort-strings (list)
  882   "Return sorted list of all strings in LIST."
  883   (sort (copy-sequence list) #'string<))
  884 
  885 (defun TeX-car-string-lessp (s1 s2)
  886   "Compare the cars of S1 and S2 in lexicographic order.
  887 Return t if first is less than second in lexicographic order."
  888   (string-lessp (car s1) (car s2)))
  889 
  890 ;;; Buffer
  891 
  892 (defgroup TeX-output nil
  893   "Parsing TeX output."
  894   :prefix "TeX-"
  895   :group 'AUCTeX)
  896 
  897 (defcustom TeX-display-help t
  898   "Control type of help display when stepping through errors with \\[TeX-next-error].
  899 If t display help buffer.  If nil display message about error in
  900 echo area.  If `expert' display output buffer with raw processor output."
  901   :group 'TeX-output
  902   :type '(choice (const :tag "Help buffer" t)
  903          (const :tag "Echo area" nil)
  904          (const :tag "Output buffer" expert)))
  905 
  906 (defcustom TeX-debug-bad-boxes nil
  907   "Non-nil means also find overfull/underfull box warnings with \\[TeX-next-error]."
  908   :group 'TeX-output
  909   :type 'boolean)
  910 
  911 (defcustom TeX-debug-warnings nil
  912   "Non-nil means also find LaTeX or package warnings with \\[TeX-next-error]."
  913   :group 'TeX-output
  914   :type 'boolean)
  915 
  916 (defcustom TeX-ignore-warnings nil
  917   "Controls which warnings are to be ignored.
  918 
  919 It can be either a regexp matching warnings to be ignored, or a
  920 symbol with the name of a custom function taking as arguments all
  921 the information of the warning listed in `TeX-error-list', except
  922 the last one about whether to ignore the warning.
  923 
  924 If you want to use the custom function, see how it is used in the
  925 code of `TeX-warning'."
  926   :group 'TeX-command
  927   :type '(choice (const  :tag "Do not ignore anything" nil)
  928          (string :tag "Regexp")
  929          (symbol :tag "Function name")))
  930 
  931 (defcustom TeX-suppress-ignored-warnings nil
  932   "Whether to actually show ignored warnings.
  933 
  934 Note that `TeX-debug-warnings' always takes the precedence."
  935   :group 'TeX-command
  936   :type 'boolean)
  937 
  938 (defun TeX-toggle-debug-bad-boxes ()
  939   "Toggle if the debugger should display \"bad boxes\" too."
  940   (interactive)
  941   (setq TeX-debug-bad-boxes (not TeX-debug-bad-boxes))
  942   (message (concat "TeX-debug-bad-boxes: "
  943            (if TeX-debug-bad-boxes "on" "off"))))
  944 
  945 (defun TeX-toggle-debug-warnings ()
  946   "Toggle if the debugger should display warnings too."
  947   (interactive)
  948   (setq TeX-debug-warnings (not TeX-debug-warnings))
  949   (message (concat "TeX-debug-warnings: "
  950            (if TeX-debug-warnings "on" "off"))))
  951 
  952 (defun TeX-toggle-suppress-ignored-warnings ()
  953   "Toggle if the debugger should display ignored warnings too.
  954 
  955 See `TeX-suppress-ignored-warnings' and `TeX-ignore-warnings' for
  956 more details."
  957   (interactive)
  958   (setq TeX-suppress-ignored-warnings (not TeX-suppress-ignored-warnings))
  959   (message (concat "TeX-suppress-ignored-warnings: "
  960            (if TeX-suppress-ignored-warnings "on" "off"))))
  961 
  962 ;;; Mode names.
  963 
  964 (defvar TeX-base-mode-name nil
  965   "Base name of mode.")
  966 (make-variable-buffer-local 'TeX-base-mode-name)
  967 
  968 (defun TeX-set-mode-name (&optional changed local reset)
  969   "Build and set the mode name.
  970 The base mode name will be concatenated with indicators for
  971 helper modes where appropriate.
  972 
  973 If CHANGED is non-nil, it indicates which global mode
  974 may have changed so that all corresponding buffers
  975 without a local value might get their name updated.
  976 A value of t will thus update all buffer names.
  977 
  978 If LOCAL is non-nil and CHANGED is buffer-local, only
  979 a local change has been performed and only the local
  980 name is to be updated.
  981 
  982 If RESET is non-nil, `TeX-command-next' is reset to
  983 `TeX-command-default' in updated buffers."
  984   (if (and changed
  985        (not (and local (local-variable-p changed (current-buffer)))))
  986       (dolist (buffer (buffer-list))
  987     (and (local-variable-p 'TeX-mode-p buffer)
  988          (not (local-variable-p changed buffer))
  989          (with-current-buffer buffer (TeX-set-mode-name nil nil reset))))
  990     (if TeX-mode-p
  991     (let ((trailing-flags
  992            (concat
  993         (and (boundp 'TeX-fold-mode) TeX-fold-mode "F")
  994         (and (boundp 'LaTeX-math-mode) LaTeX-math-mode "M")
  995         (and TeX-PDF-mode "P")
  996         (and TeX-interactive-mode "I")
  997         (and TeX-source-correlate-mode "S"))))
  998       (setq mode-name (concat TeX-base-mode-name
  999                   (when (> (length trailing-flags) 0)
 1000                     (concat "/" trailing-flags))))
 1001       (when reset
 1002         (TeX-process-set-variable (TeX-master-file)
 1003                       'TeX-command-next TeX-command-default)
 1004         (TeX-process-set-variable (TeX-region-file)
 1005                       'TeX-command-next TeX-command-default))
 1006       (set-buffer-modified-p (buffer-modified-p))))))
 1007 
 1008 (defun TeX-mode-prefix (&optional mode)
 1009   "Return the prefix for the symbol MODE as string.
 1010 If no mode is given the current major mode is used."
 1011   (cdr (assoc (or mode major-mode) '((plain-tex-mode . "plain-TeX")
 1012                      (latex-mode . "LaTeX")
 1013                      (ams-tex-mode . "AmSTeX")
 1014                      (doctex-mode . "docTeX")
 1015                      (texinfo-mode . "Texinfo")
 1016                      (context-mode . "ConTeXt")))))
 1017 
 1018 ;;; Viewing
 1019 
 1020 (defgroup TeX-view nil
 1021   "Calling viewers from AUCTeX."
 1022   :group 'TeX-command)
 1023 
 1024 (defcustom TeX-view-style
 1025   `((,(concat
 1026       "^" (regexp-opt '("a4paper" "a4dutch" "a4wide" "sem-a4")) "$")
 1027      "%(o?)xdvi %dS -paper a4 %d")
 1028     (,(concat "^" (regexp-opt '("a5paper" "a5comb")) "$")
 1029      "%(o?)xdvi %dS -paper a5 %d")
 1030     ("^b5paper$" "%(o?)xdvi %dS -paper b5 %d")
 1031     ("^letterpaper$" "%(o?)xdvi %dS -paper us %d")
 1032     ("^legalpaper$" "%(o?)xdvi %dS -paper legal %d")
 1033     ("^executivepaper$" "%(o?)xdvi %dS -paper 7.25x10.5in %d")
 1034     ("^landscape$" "%(o?)xdvi %dS -paper a4r -s 0 %d")
 1035     ;; The latest xdvi can show embedded postscript.  If you don't
 1036     ;; have that, uncomment next line.
 1037     ;; ("^epsf$" "ghostview %f")
 1038     ("." "%(o?)xdvi %dS %d"))
 1039   "List of style options and view options.
 1040 
 1041 If the first element (a regular expression) matches the name of
 1042 one of the style files, any occurrence of the string `%v' in a
 1043 command in `TeX-command-list' will be replaced with the second
 1044 element.  The first match is used, if no match is found the `%v'
 1045 is replaced with the empty string.
 1046 
 1047 As a default, the \"View\" command in `TeX-command-list' is set
 1048 to `%V'.  This means that `TeX-output-view-style' will be
 1049 consulted before `TeX-view-style'.  Only if no match is found in
 1050 `TeX-output-view-style' the settings in `TeX-view-style' will be
 1051 considered.  If you want to bypass `TeX-output-view-style', which
 1052 is not recommended because it is more powerful than
 1053 `TeX-view-style', use `%v' in the \"View\" command."
 1054   :group 'TeX-view
 1055   :type '(repeat (group regexp (string :tag "Command"))))
 1056 
 1057 (defcustom TeX-output-view-style
 1058   `(("^dvi$" ("^landscape$" "^pstricks$\\|^pst-\\|^psfrag$")
 1059      "%(o?)dvips -t landscape %d -o && gv %f")
 1060     ("^dvi$" "^pstricks$\\|^pst-\\|^psfrag$" "%(o?)dvips %d -o && gv %f")
 1061     ("^dvi$" (,(concat
 1062         "^" (regexp-opt '("a4paper" "a4dutch" "a4wide" "sem-a4")) "$")
 1063           "^landscape$")
 1064      "%(o?)xdvi %dS -paper a4r -s 0 %d")
 1065     ("^dvi$" ,(concat
 1066            "^" (regexp-opt '("a4paper" "a4dutch" "a4wide" "sem-a4")) "$")
 1067      "%(o?)xdvi %dS -paper a4 %d")
 1068     ("^dvi$" (,(concat "^" (regexp-opt '("a5paper" "a5comb")) "$")
 1069           "^landscape$")
 1070      "%(o?)xdvi %dS -paper a5r -s 0 %d")
 1071     ("^dvi$" ,(concat "^" (regexp-opt '("a5paper" "a5comb")) "$")
 1072      "%(o?)xdvi %dS -paper a5 %d")
 1073     ("^dvi$" "^b5paper$" "%(o?)xdvi %dS -paper b5 %d")
 1074     ("^dvi$" "^letterpaper$" "%(o?)xdvi %dS -paper us %d")
 1075     ("^dvi$" "^legalpaper$" "%(o?)xdvi %dS -paper legal %d")
 1076     ("^dvi$" "^executivepaper$" "%(o?)xdvi %dS -paper 7.25x10.5in %d")
 1077     ("^dvi$" "." "%(o?)xdvi %dS %d")
 1078     ("^pdf$" "." "xpdf -remote %s -raise %o %(outpage)")
 1079     ("^html?$" "." "netscape %o"))
 1080   "List of output file extensions and view options.
 1081 
 1082 If the first element (a regular expression) matches the output
 1083 file extension, and the second element (a regular expression)
 1084 matches the name of one of the style options, any occurrence of
 1085 the string `%V' in a command in `TeX-command-list' will be
 1086 replaced with the third element.  The first match is used; if no
 1087 match is found the `%V' is replaced with `%v'.  The outcome of `%v'
 1088 is determined by the settings in `TeX-view-style' which therefore
 1089 serves as a fallback for `TeX-output-view-style'.  The second
 1090 element may also be a list of regular expressions, in which case
 1091 all the regular expressions must match for the element to apply."
 1092   :group 'TeX-view
 1093   :type '(repeat (group
 1094           (regexp :tag "Extension")
 1095           (choice regexp (repeat :tag "List" regexp))
 1096           (string :tag "Command"))))
 1097 
 1098 ;;; Viewing (new implementation)
 1099 
 1100 (defvar TeX-view-predicate-list-builtin
 1101   '((output-dvi
 1102      (string-match "dvi" (TeX-output-extension)))
 1103     (output-pdf
 1104      (string-match "pdf" (TeX-output-extension)))
 1105     (output-html
 1106      (string-match "html" (TeX-output-extension)))
 1107     (has-no-display-manager
 1108      (not (display-graphic-p)))
 1109     (style-pstricks
 1110      (TeX-match-style "^pstricks$\\|^pst-\\|^psfrag$"))
 1111     (engine-omega
 1112      (eq TeX-engine 'omega))
 1113     (engine-xetex
 1114      (eq TeX-engine 'xetex))
 1115     (mode-io-correlate
 1116      TeX-source-correlate-mode)
 1117     (paper-landscape
 1118      (and (fboundp 'LaTeX-match-class-option)
 1119       (LaTeX-match-class-option "\\`landscape\\'")))
 1120     (paper-portrait
 1121      (not (and (fboundp 'LaTeX-match-class-option)
 1122            (LaTeX-match-class-option "\\`landscape\\'"))))
 1123     (paper-a4
 1124      (let ((regex "\\`\\(?:a4paper\\|a4dutch\\|a4wide\\|sem-a4\\)\\'"))
 1125        (or (TeX-match-style regex)
 1126        (and (fboundp 'LaTeX-match-class-option)
 1127         (LaTeX-match-class-option regex)))))
 1128     (paper-a5
 1129      (let ((regex "\\`\\(?:a5paper\\|a5comb\\)\\'"))
 1130        (or (TeX-match-style regex)
 1131        (and (fboundp 'LaTeX-match-class-option)
 1132         (LaTeX-match-class-option regex)))))
 1133     (paper-b5
 1134      (and (fboundp 'LaTeX-match-class-option)
 1135       (LaTeX-match-class-option "\\`b5paper\\'")))
 1136     (paper-letter
 1137      (and (fboundp 'LaTeX-match-class-option)
 1138       (LaTeX-match-class-option "\\`letterpaper\\'")))
 1139     (paper-legal
 1140      (and (fboundp 'LaTeX-match-class-option)
 1141       (LaTeX-match-class-option "\\`legalpaper\\'")))
 1142     (paper-executive
 1143      (and (fboundp 'LaTeX-match-class-option)
 1144       (LaTeX-match-class-option "\\`executivepaper\\'"))))
 1145   "Alist of built-in predicates for viewer selection and invocation.
 1146 See the doc string of `TeX-view-predicate-list' for a short
 1147 description of each predicate.")
 1148 
 1149 (defcustom TeX-view-predicate-list nil
 1150   "Alist of predicates for viewer selection and invocation.
 1151 The key of each list item is a symbol and the value a Lisp form
 1152 to be evaluated.  The form should return nil if the predicate is
 1153 not fulfilled.
 1154 
 1155 Built-in predicates provided in `TeX-view-predicate-list-builtin'
 1156 can be overwritten by defining predicates with the same symbol.
 1157 
 1158 The following built-in predicates are available:
 1159   `output-dvi': The output is a DVI file.
 1160   `output-pdf': The output is a PDF file.
 1161   `output-html': The output is an HTML file.
 1162   `style-pstricks': The document loads a PSTricks package.
 1163   `engine-omega': The Omega engine is used for typesetting.
 1164   `engine-xetex': The XeTeX engine is used for typesetting.
 1165   `mode-io-correlate': TeX Source Correlate mode is active.
 1166   `paper-landscape': The document is typeset in landscape orientation.
 1167   `paper-portrait': The document is not typeset in landscape orientation.
 1168   `paper-a4': The paper format is A4.
 1169   `paper-a5': The paper format is A5.
 1170   `paper-b5': The paper format is B5.
 1171   `paper-letter': The paper format is letter.
 1172   `paper-legal': The paper format is legal.
 1173   `paper-executive': The paper format is executive."
 1174   :group 'TeX-view
 1175   :type '(alist :key-type symbol :value-type (group sexp)))
 1176 
 1177 ;; XXX: Atril and xreader are forks of Evince and share an almost
 1178 ;; identical interface with it. Instead of having different functions
 1179 ;; for each program, we keep the original *-evince-* functions and
 1180 ;; make them accept arguments to specify the actual name of the
 1181 ;; program and the desktop environment, that will be used to set up
 1182 ;; DBUS communication.
 1183 
 1184 ;; Require dbus at compile time to prevent errors due to `dbus-ignore-errors'
 1185 ;; not being defined.
 1186 (eval-when-compile (and (featurep 'dbusbind)
 1187             (require 'dbus nil :no-error)))
 1188 (defun TeX-evince-dbus-p (de app &rest options)
 1189   "Return non-nil, if an evince-compatible reader is accessible via DBUS.
 1190 Additional OPTIONS may be given to extend the check.  If none are
 1191 given, only the minimal requirements needed by backward search
 1192 are checked.  If OPTIONS include `:forward', which is currently
 1193 the only option, then additional requirements needed by forward
 1194 search are checked, too.
 1195 
 1196 DE is the name of the desktop environment, APP is the name of viewer."
 1197   (let ((dbus-debug nil))
 1198     (and (featurep 'dbusbind)
 1199      (require 'dbus nil :no-error)
 1200      (dbus-ignore-errors (dbus-get-unique-name :session))
 1201      (dbus-ping :session (format "org.%s.%s.Daemon" de app))
 1202      (or (not (memq :forward options))
 1203          (let ((spec (dbus-introspect-get-method
 1204               :session (format "org.%s.%s.Daemon" de app)
 1205               (format "/org/%s/%s/Daemon" de app)
 1206               (format "org.%s.%s.Daemon" de app)
 1207               "FindDocument")))
 1208            ;; FindDocument must exist, and its signature must be (String,
 1209            ;; Boolean, String).  Evince versions between 2.30 and 2.91.x
 1210            ;; didn't have the Boolean spawn argument we need to start evince
 1211            ;; initially.
 1212            (and spec
 1213             (equal '("s" "b" "s")
 1214                (delq nil (mapcar (lambda (elem)
 1215                            (when (and (listp elem)
 1216                               (eq (car elem) 'arg))
 1217                          (cdr (caar (cdr elem)))))
 1218                          spec)))))))))
 1219 
 1220 (defun TeX-pdf-tools-sync-view ()
 1221   "Focus the focused page/paragraph in `pdf-view-mode'.
 1222 If `TeX-source-correlate-mode' is disabled, only find and pop to
 1223 the output PDF file.  Used by default for the PDF Tools viewer
 1224 entry in `TeX-view-program-list-builtin'."
 1225   ;; Make sure `pdf-tools' is at least in the `load-path', but the user must
 1226   ;; take care of properly loading and installing the package.  We used to test
 1227   ;; "(featurep 'pdf-tools)", but that doesn't play well with deferred loading.
 1228   (unless (fboundp 'pdf-tools-install)
 1229     (error "PDF Tools are not available"))
 1230   (unless TeX-PDF-mode
 1231     (error "PDF Tools only work with PDF output"))
 1232   (add-hook 'pdf-sync-backward-redirect-functions
 1233         #'TeX-source-correlate-handle-TeX-region)
 1234   (if (and TeX-source-correlate-mode
 1235        (fboundp 'pdf-sync-forward-search))
 1236       (with-current-buffer (or (when TeX-current-process-region-p
 1237                  (get-file-buffer (TeX-region-file t)))
 1238                    (current-buffer))
 1239     (pdf-sync-forward-search))
 1240     (let ((pdf (concat file "." (TeX-output-extension))))
 1241       (pop-to-buffer (or (find-buffer-visiting pdf)
 1242              (find-file-noselect pdf))))))
 1243 
 1244 (defcustom TeX-view-evince-keep-focus nil
 1245   "Whether Emacs retains the focus when viewing PDF files with Evince.
 1246 
 1247 When calling `TeX-evince-sync-view', Evince normally captures the
 1248 focus. If this option is set to non-nil, Emacs will retain the
 1249 focus."
 1250   :group 'TeX-view
 1251   :type 'boolean)
 1252 
 1253 (defun TeX-evince-sync-view-1 (de app)
 1254   "Focus the focused page/paragraph in Evince with the position
 1255 of point in emacs by using Evince's DBUS API.  Used by default
 1256 for the Evince-compatible entries in
 1257 `TeX-view-program-list-builtin' if the requirements are met.
 1258 
 1259 DE is the name of the desktop environment, APP is the name of
 1260 viewer."
 1261   (require 'url-util)
 1262   (let* ((uri (concat "file://" (url-encode-url
 1263                  (expand-file-name
 1264                   (concat file "." (TeX-output-extension))))))
 1265      (owner (dbus-call-method
 1266          :session (format "org.%s.%s.Daemon" de app)
 1267          (format "/org/%s/%s/Daemon" de app)
 1268          (format "org.%s.%s.Daemon" de app)
 1269          "FindDocument"
 1270          uri
 1271          t)))
 1272     (if owner
 1273     (with-current-buffer (or (when TeX-current-process-region-p
 1274                    (get-file-buffer (TeX-region-file t)))
 1275                  (current-buffer))
 1276       (dbus-call-method
 1277        :session owner
 1278        (format "/org/%s/%s/Window/0" de app)
 1279        (format "org.%s.%s.Window" de app)
 1280        "SyncView"
 1281        (buffer-file-name)
 1282        (list :struct :int32 (1+ (TeX-current-offset))
 1283          ;; FIXME: Using `current-column' here is dubious.
 1284          ;; Most of CJK letters count as occupying 2 columns,
 1285          ;; so the column number is not equal to the number of
 1286          ;; the characters counting from the beginning of a
 1287          ;; line.  What is the right number to specify here?
 1288          ;; number of letters? bytes in UTF8? or other?
 1289          :int32 (1+ (current-column)))
 1290        :uint32 0)
 1291           (when TeX-view-evince-keep-focus
 1292             (select-frame-set-input-focus (selected-frame))))
 1293       (error "Couldn't find the %s instance for %s" (capitalize app) uri))))
 1294 
 1295 (defun TeX-atril-sync-view ()
 1296   "Run `TeX-evince-sync-view-1', which see, set up for Atril."
 1297   (TeX-evince-sync-view-1 "mate" "atril"))
 1298 
 1299 (defun TeX-evince-sync-view ()
 1300   "Run `TeX-evince-sync-view-1', which see, set up for Evince."
 1301   (TeX-evince-sync-view-1 "gnome" "evince"))
 1302 
 1303 (defun TeX-xreader-sync-view ()
 1304   "Run `TeX-evince-sync-view-1', which see, set up for Evince."
 1305   (TeX-evince-sync-view-1 "x" "reader"))
 1306 
 1307 (defun TeX-view-program-select-evince (de app)
 1308   "Select how to call the Evince-like viewer.
 1309 
 1310 DE is the name of the desktop environment, APP is the name of
 1311 viewer."
 1312   (if (TeX-evince-dbus-p de app :forward)
 1313       (intern (format "TeX-%s-sync-view" app))
 1314     `(,app (mode-io-correlate
 1315         ;; With evince 3, -p N opens the page *labeled* N,
 1316         ;; and -i,--page-index the physical page N.
 1317         ,(if (string-match "--page-index"
 1318                    (shell-command-to-string (concat app " --help")))
 1319          " -i %(outpage)"
 1320            " -p %(outpage)")) " %o")))
 1321 
 1322 (defvar TeX-view-program-list-builtin
 1323   (cond
 1324    ((eq system-type 'windows-nt)
 1325     '(("Yap" ("yap -1" (mode-io-correlate " -s %n%b") " %o") "yap")
 1326       ("dviout" ("dviout -1 "
 1327          ((paper-a4 paper-portrait) "-y=A4 ")
 1328          ((paper-a4 paper-landscape) "-y=A4L ")
 1329          ((paper-a5 paper-portrait) "-y=A5 ")
 1330          ((paper-a5 paper-landscape) "-y=A5L ")
 1331          ((paper-b5 paper-portrait) "-y=E5 ")
 1332          ((paper-b5 paper-landscape) "-y=E5L ")
 1333          ((paper-b4jis paper-portrait) "-y=B4 ")
 1334          ((paper-b4jis paper-landscape) "-y=B4L ")
 1335          ((paper-b5jis paper-portrait) "-y=B5 ")
 1336          ((paper-b5jis paper-landscape) "-y=B5L ")
 1337          (paper-legal "-y=Legal ")
 1338          (paper-letter "-y=Letter ")
 1339          (paper-executive "-y=Executive ")
 1340          "%d" (mode-io-correlate " \"# %n '%b'\"")) "dviout")
 1341       ("PDF Tools" TeX-pdf-tools-sync-view)
 1342       ("SumatraPDF"
 1343        ("SumatraPDF -reuse-instance"
 1344     (mode-io-correlate " -forward-search \"%b\" %n") " %o")
 1345        "SumatraPDF")
 1346       ("dvips and start" "dvips %d -o && start \"\" %f" "dvips")
 1347       ("start" "start \"\" %o")))
 1348    ((eq system-type 'darwin)
 1349     '(("Preview.app" "open -a Preview.app %o" "open")
 1350       ("Skim" "open -a Skim.app %o" "open")
 1351       ("PDF Tools" TeX-pdf-tools-sync-view)
 1352       ("displayline" "displayline %n %o %b" "displayline")
 1353       ("open" "open %o" "open")))
 1354    (t
 1355     `(("dvi2tty" ("dvi2tty -q -w 132 %o"))
 1356       ("xdvi" ("%(o?)xdvi"
 1357            (mode-io-correlate " -sourceposition \"%n %b\" -editor \"%cS\"")
 1358            ((paper-a4 paper-portrait) " -paper a4")
 1359            ((paper-a4 paper-landscape) " -paper a4r")
 1360            ((paper-a5 paper-portrait) " -paper a5")
 1361            ((paper-a5 paper-landscape) " -paper a5r")
 1362            (paper-b5 " -paper b5")
 1363            (paper-letter " -paper us")
 1364            (paper-legal " -paper legal")
 1365            (paper-executive " -paper 7.25x10.5in")
 1366            " %d") "%(o?)xdvi")
 1367       ("dvips and gv" "%(o?)dvips %d -o && gv %f" ,(list "%(o?)dvips" "gv"))
 1368       ("gv" "gv %o" "gv")
 1369       ("xpdf" ("xpdf -remote %s -raise %o" (mode-io-correlate " %(outpage)")) "xpdf")
 1370       ("Evince" ,(TeX-view-program-select-evince "gnome" "evince") "evince")
 1371       ("Atril" ,(TeX-view-program-select-evince "mate" "atril") "atril")
 1372       ("Xreader" ,(TeX-view-program-select-evince "x" "reader") "xreader")
 1373       ("Okular" ("okular --unique %o" (mode-io-correlate "#src:%n%a")) "okular")
 1374       ("xdg-open" "xdg-open %o" "xdg-open")
 1375       ("PDF Tools" TeX-pdf-tools-sync-view)
 1376       ("Zathura"
 1377        ("zathura %o"
 1378     (mode-io-correlate
 1379      " --synctex-forward %n:0:\"%b\" -x \"emacsclient +%{line} %{input}\""))
 1380        "zathura"))))
 1381   "Alist of built-in viewer specifications.
 1382 This variable should not be changed by the user who can use
 1383 `TeX-view-program-list' to add new viewers or overwrite the
 1384 definition of built-in ones.  The latter variable also contains a
 1385 description of the data format.")
 1386 
 1387 (defcustom TeX-view-program-list nil
 1388   "List of viewer specifications.
 1389 This variable can be used to specify how a viewer is to be
 1390 invoked and thereby add new viewers on top of the built-in list
 1391 of viewers defined in `TeX-view-program-list-builtin' or override
 1392 entries in the latter.
 1393 
 1394 The car of each item is a string with a user-readable name.  The
 1395 second element can be a command line to be run as a process or a
 1396 Lisp function to be executed.  The command line can either be
 1397 specified as a single string or a list of strings and two-part
 1398 lists.  The first element of the two-part lists is a symbol or a
 1399 list of symbols referring to one or more of the predicates in
 1400 `TeX-view-predicate-list' or `TeX-view-predicate-list-builtin'.
 1401 The second part of the two-part lists is a command line part.
 1402 The command line for the viewer is constructed by concatenating
 1403 the command line parts.  Parts with a predicate are only
 1404 considered if the predicate was evaluated with a positive result.
 1405 Note that the command line can contain placeholders as defined in
 1406 `TeX-expand-list' which are expanded before the viewer is called.
 1407 The third element of the item is optional and is a string, or a
 1408 list of strings, with the name of the executable, or executables,
 1409 needed to open the output file in the viewer.  Placeholders
 1410 defined in `TeX-expand-list' can be used here.  This element is
 1411 used to check whether the viewer is actually available on the
 1412 system.
 1413 
 1414 The use of a function as the second element only works if the
 1415 View command in `TeX-command-list' makes use of the hook
 1416 `TeX-run-discard-or-function'.
 1417 
 1418 Note: Predicates defined in the current Emacs session will only
 1419 show up in the customization interface for this variable after
 1420 restarting Emacs."
 1421   :group 'TeX-view
 1422   :type
 1423   `(repeat
 1424     (list
 1425      (string :tag "Name")
 1426      (choice
 1427       (group :tag "Command" (string :tag "Command"))
 1428       (group :inline t :tag "Command parts"
 1429          (repeat
 1430           :tag "Command parts"
 1431           (choice
 1432            (string :tag "Command part")
 1433            (list :tag "Predicate and command part"
 1434              ,(let (list)
 1435             ;; Build the list of available predicates.
 1436             (mapc (lambda (spec)
 1437                 (add-to-list 'list `(const ,(car spec))))
 1438                   (append TeX-view-predicate-list
 1439                       TeX-view-predicate-list-builtin))
 1440             ;; Sort the list alphabetically.
 1441             (setq list (sort list
 1442                      (lambda (a b)
 1443                        (string<
 1444                         (downcase (symbol-name (cadr a)))
 1445                         (downcase (symbol-name (cadr b)))))))
 1446             `(choice
 1447               (choice :tag "Predicate" ,@list)
 1448               (repeat :tag "List of predicates"
 1449                   (choice :tag "Predicate" ,@list))))
 1450              (string :tag "Command part")))))
 1451       (group :tag "Function" function))
 1452      (choice :tag "Viewer executable(s)"
 1453          (string :tag "One executable")
 1454          (repeat :tag "List of executables" (string :tag "Name"))
 1455          (const :tag "No executable" nil)))))
 1456 
 1457 (defcustom TeX-view-program-selection
 1458   (cond
 1459    ((eq system-type 'windows-nt)
 1460     '(((output-dvi style-pstricks) "dvips and start")
 1461       (output-dvi "Yap")
 1462       (output-pdf "start")
 1463       (output-html "start")))
 1464    ((eq system-type 'darwin)
 1465     '((output-dvi "open")
 1466       (output-pdf "open")
 1467       (output-html "open")))
 1468    (t
 1469     '(((output-dvi has-no-display-manager) "dvi2tty")
 1470       ((output-dvi style-pstricks) "dvips and gv")
 1471       (output-dvi "xdvi")
 1472       (output-pdf "Evince")
 1473       (output-html "xdg-open"))))
 1474   "Alist of predicates and viewers.
 1475 Each entry consists of a list with two elements.  The first
 1476 element is a symbol or list of symbols referring to predicates as
 1477 defined in `TeX-view-predicate-list' or
 1478 `TeX-view-predicate-list-builtin'.  The second element is a
 1479 string referring to the name of a viewer as defined in
 1480 `TeX-view-program-list' or `TeX-view-program-list-builtin'.
 1481 \(Note: Viewers added to `TeX-view-program-list' in the current
 1482 Emacs session will not show up in the customization interface of
 1483 `TeX-view-program-selection' until you restart Emacs.)
 1484 
 1485 When a viewer is called for, the entries are evaluated in turn
 1486 and the viewer related to the first entry all predicates of which
 1487 are evaluated positively is chosen."
 1488   :group 'TeX-view
 1489   :type `(alist :key-type
 1490         ;; Offer list of defined predicates.
 1491         ,(let (list)
 1492            (mapc (lambda (spec)
 1493                (add-to-list 'list `(const ,(car spec))))
 1494              (append TeX-view-predicate-list
 1495                  TeX-view-predicate-list-builtin))
 1496            (setq list (sort list
 1497                     (lambda (a b)
 1498                       (string<
 1499                        (downcase (symbol-name (cadr a)))
 1500                        (downcase (symbol-name (cadr b)))))))
 1501            `(choice (choice :tag "Single predicate" ,@list)
 1502                 (repeat :tag "Multiple predicates"
 1503                     (choice ,@list))))
 1504         :value-type
 1505         ;; Offer list of defined viewers.
 1506         (group (choice :tag "Viewer"
 1507                    ,@(let (list)
 1508                    (mapc (lambda (spec)
 1509                        (add-to-list 'list
 1510                             `(const ,(car spec))))
 1511                      (append TeX-view-program-list
 1512                          TeX-view-program-list-builtin))
 1513                    (sort list
 1514                      (lambda (a b)
 1515                        (string< (downcase (cadr a))
 1516                             (downcase (cadr b))))))))))
 1517 
 1518 (defun TeX-match-style (regexp)
 1519   "Check if a style matching REGEXP is active."
 1520   (TeX-member regexp (TeX-style-list) 'string-match))
 1521 
 1522 (defun TeX-view-match-predicate (predicate)
 1523   "Check if PREDICATE is true.
 1524 PREDICATE can be a symbol or a list of symbols defined in
 1525 `TeX-view-predicate-list-builtin' or `TeX-view-predicate-list'.
 1526 In case of a single symbol, return t if the predicate is true,
 1527 nil otherwise.  In case of a list of symbols, return t if all
 1528 predicates are true, nil otherwise."
 1529   (let ((pred-symbols (if (listp predicate) predicate (list predicate)))
 1530     (pred-defs (append TeX-view-predicate-list
 1531                TeX-view-predicate-list-builtin))
 1532     (result t)
 1533     elt)
 1534     (while (and (setq elt (pop pred-symbols)) result)
 1535       (unless (eval (cadr (assq elt pred-defs)))
 1536     (setq result nil)))
 1537     result))
 1538 
 1539 (defun TeX-view-command-raw ()
 1540   "Choose a viewer and return its unexpanded command string."
 1541   (let ((selection TeX-view-program-selection)
 1542     entry viewer item executable spec command)
 1543     ;; Find the appropriate viewer.
 1544     (while (and (setq entry (pop selection)) (not viewer))
 1545       (when (TeX-view-match-predicate (car entry))
 1546     (setq viewer (cadr entry))))
 1547     (unless viewer
 1548       (error "No matching viewer found"))
 1549     (setq item (assoc viewer (append TeX-view-program-list
 1550                      TeX-view-program-list-builtin))
 1551       ;; Get the command line or function spec.
 1552       spec (cadr item)
 1553       ;; Get the name of the executable(s) associated to the viewer.
 1554       executable (nth 2 item))
 1555     ;; Check the executable exists.
 1556     (unless (or (null executable)
 1557         (cond
 1558          ((stringp executable)
 1559           (executable-find (TeX-command-expand executable nil)))
 1560          ((listp executable)
 1561           (catch 'notfound
 1562             (dolist (exec executable t)
 1563               (unless (executable-find (TeX-command-expand exec nil))
 1564             (throw 'notfound nil)))))))
 1565       (error (format "Cannot find %S viewer.  \
 1566 Select another one in `TeX-view-program-selection'" viewer)))
 1567     (cond ((functionp spec)
 1568        ;; Converting the function call to a string is ugly, but
 1569        ;; the backend currently only supports strings.
 1570        (prin1-to-string spec))
 1571       ((stringp spec)
 1572        spec)
 1573       ((null spec)
 1574        (error
 1575         (format "Unknown %S viewer. \
 1576 Check the `TeX-view-program-selection' variable" viewer)))
 1577       (t
 1578        ;; Build the unexpanded command line.  Pieces with predicates are
 1579        ;; only added if the predicate is evaluated positively.
 1580        (dolist (elt spec)
 1581          (cond ((stringp elt)
 1582             (setq command (concat command elt)))
 1583            ((listp elt)
 1584             (when (TeX-view-match-predicate (car elt))
 1585               (setq command (concat command (cadr elt)))))))
 1586        (if (stringp command)
 1587            command
 1588          ;; Signal an error if `command' isn't a string.  This prevents an
 1589          ;; infinite loop in `TeX-command-expand' if `command' is nil.
 1590          (error "Wrong viewer specification in `TeX-view-program-list'"))))))
 1591 
 1592 ;;; Engine
 1593 
 1594 (defvar TeX-engine-alist-builtin
 1595   '((default "Default" TeX-command LaTeX-command ConTeXt-engine)
 1596     (xetex "XeTeX" "xetex" "xelatex" "xetex")
 1597     ;; Some lualatex versions before 0.71 would use "texput" as file
 1598     ;; name if --jobname were not supplied
 1599     (luatex "LuaTeX" "luatex" "lualatex --jobname=%s" "luatex")
 1600     (omega "Omega" TeX-Omega-command LaTeX-Omega-command ConTeXt-Omega-engine))
 1601   "Alist of built-in TeX engines and associated commands.
 1602 For a description of the format see `TeX-engine-alist'.")
 1603 
 1604 (defcustom TeX-engine-alist nil
 1605   "Alist of TeX engines and associated commands.
 1606 Each entry is a list with a maximum of five elements.  The first
 1607 element is a symbol used to identify the engine.  The second is a
 1608 string describing the engine.  The third is the command to be
 1609 used for plain TeX.  The fourth is the command to be used for
 1610 LaTeX.  The fifth is the command to be used for the --engine
 1611 parameter of ConTeXt's texexec program.  Each command can either
 1612 be a variable or a string.  An empty string or nil means there is
 1613 no command available.
 1614 
 1615 You can override a built-in engine defined in the variable
 1616 `TeX-engine-alist-builtin' by adding an entry beginning with the
 1617 same symbol as the built-in entry to `TeX-engine-alist'."
 1618   :group 'TeX-command
 1619   :type '(repeat (group symbol
 1620             (string :tag "Name")
 1621             (choice :tag "Plain TeX command" string variable)
 1622             (choice :tag "LaTeX command" string variable)
 1623             (choice :tag "ConTeXt command" string variable))))
 1624 
 1625 (defun TeX-engine-alist ()
 1626   "Return an alist of TeX engines.
 1627 The function appends the built-in engine specs from
 1628 `TeX-engine-alist-builtin' and the user-defined engines from
 1629 `TeX-engine-alist' and deletes any entries from the built-in part
 1630 where an entry with the same car exists in the user-defined part."
 1631   (TeX-delete-dups-by-car (append TeX-engine-alist TeX-engine-alist-builtin)))
 1632 
 1633 (defun TeX-engine-in-engine-alist (engine)
 1634   "Return the `engine' entry in `TeX-engine-alist'.
 1635 
 1636 Throw an error if `engine' is not present in the alist."
 1637   (or
 1638    (assq engine (TeX-engine-alist))
 1639    (error "`%s' is not a known engine.  Valid values are: %s." engine
 1640       (mapconcat
 1641        (lambda (x) (prin1-to-string (car x)))
 1642        (TeX-engine-alist) ", "))))
 1643 
 1644 (defcustom TeX-engine 'default
 1645   (concat "Type of TeX engine to use.
 1646 It should be one of the following symbols:\n\n"
 1647       (mapconcat (lambda (x) (format "* `%s'" (car x)))
 1648              (TeX-engine-alist) "\n"))
 1649   :group 'TeX-command
 1650   :type `(choice ,@(mapcar (lambda (x)
 1651                  `(const :tag ,(nth 1 x) ,(car x)))
 1652                (TeX-engine-alist))))
 1653 (make-variable-buffer-local 'TeX-engine)
 1654 (put 'TeX-engine 'safe-local-variable
 1655      (lambda (arg) (memq arg (mapcar 'car TeX-engine-alist-builtin))))
 1656 
 1657 (defun TeX-engine-set (type)
 1658   "Set TeX engine to TYPE.
 1659 For available TYPEs, see variable `TeX-engine'."
 1660   (interactive (list (completing-read "Engine: "
 1661                       (mapcar (lambda (x)
 1662                         (symbol-name (car x)))
 1663                           (TeX-engine-alist))
 1664                       nil t)))
 1665   (when (stringp type)
 1666     (setq type (intern type)))
 1667   (setq TeX-engine type)
 1668   ;; Automatically enable or disable TeX PDF mode as a convenience
 1669   (cond ((eq type 'xetex)
 1670      (TeX-PDF-mode 1)
 1671      (setq TeX-PDF-from-DVI nil))
 1672     ((eq type 'omega) (TeX-PDF-mode 0))))
 1673 
 1674 (define-minor-mode TeX-Omega-mode
 1675   "Minor mode for using the Omega engine."
 1676   nil nil nil
 1677   :group 'TeX-command
 1678   (TeX-engine-set (if TeX-Omega-mode 'omega 'default)))
 1679 (defalias 'tex-omega-mode 'TeX-Omega-mode)
 1680 (make-obsolete 'TeX-Omega-mode 'TeX-engine-set "11.86")
 1681 (make-obsolete-variable 'TeX-Omega-mode 'TeX-engine "11.86")
 1682 
 1683 ;;; Forward and inverse search
 1684 
 1685 (defcustom TeX-source-correlate-method
 1686   '((dvi . source-specials) (pdf . synctex))
 1687   "Method to use for enabling forward and inverse search.
 1688 This can be `source-specials' if source specials should be used,
 1689 `synctex' if SyncTeX should be used, or `auto' if AUCTeX should
 1690 decide.
 1691 
 1692 The previous values determine the variable for both DVI and PDF
 1693 mode.  This variable can also be an alist of the kind
 1694 
 1695   ((dvi . <source-specials or synctex>)
 1696    (pdf . <source-specials or synctex>))
 1697 
 1698 in which the CDR of each entry is a symbol specifying the method
 1699 to be used in the corresponding mode.
 1700 
 1701 Programs should not use this variable directly but the function
 1702 `TeX-source-correlate-method-active' which returns the method
 1703 actually used for forward and inverse search."
 1704   :type '(choice (const auto)
 1705          (const synctex)
 1706          (const source-specials)
 1707          (list :tag "Different method for DVI and PDF"
 1708                (cons (const dvi)
 1709                  (choice :tag "Method for DVI mode"
 1710                      (const synctex)
 1711                      (const source-specials)))
 1712                (cons (const pdf)
 1713                  (choice :tag "Method for PDF mode"
 1714                      (const synctex)
 1715                      (const source-specials)))))
 1716   :group 'TeX-view)
 1717 
 1718 (defvar TeX-source-correlate-output-page-function nil
 1719   "Symbol of function returning an output page relating to buffer position.
 1720 The function should take no arguments and return the page numer
 1721 as a string.")
 1722 (make-variable-buffer-local 'TeX-source-correlate-output-page-function)
 1723 
 1724 (defcustom TeX-source-correlate-start-server 'ask
 1725   "Control if server should be started for inverse search."
 1726   :type '(choice (const :tag "Always" t)
 1727          (const :tag "Never" nil)
 1728          (const :tag "Ask" ask))
 1729   :group 'TeX-view)
 1730 (when (fboundp 'defvaralias)
 1731   (defvaralias 'TeX-source-specials-view-start-server
 1732     'TeX-source-correlate-start-server))
 1733 
 1734 (defvar TeX-source-correlate-start-server-asked nil
 1735   "Keep track if question about server start search was asked.")
 1736 
 1737 (defvar TeX-source-correlate-start-server-flag nil
 1738   "If non-nil, `TeX-source-correlate-start-server-maybe' will start a server.
 1739 Code related to features requiring a server, e.g. for inverse
 1740 search, can set the variable.")
 1741 
 1742 (defun TeX-source-correlate-gnuserv-p ()
 1743   "Guess whether to use gnuserv when a server is requested."
 1744   (cond ((and (boundp 'gnuserv-process)
 1745           (processp gnuserv-process)))
 1746     ((and (boundp 'server-process)
 1747           (processp server-process))
 1748      nil)))
 1749 
 1750 (defun TeX-source-correlate-server-enabled-p ()
 1751   "Return non-nil if Emacs server or gnuserv is enabled."
 1752   (let* ((gnuserv-p (TeX-source-correlate-gnuserv-p))
 1753      (process (if gnuserv-p 'gnuserv-process 'server-process)))
 1754     (and (boundp process) (processp (symbol-value process)))))
 1755 
 1756 (defun TeX-source-correlate-start-server-maybe ()
 1757   "Start Emacs server or gnuserv if a feature using it is enabled.
 1758 This is the case if `TeX-source-correlate-start-server-flag' is non-nil."
 1759   (when (and TeX-source-correlate-start-server-flag
 1760          (not (TeX-source-correlate-server-enabled-p)))
 1761     (let* ((gnuserv-p (TeX-source-correlate-gnuserv-p))
 1762        (start (if gnuserv-p 'gnuserv-start 'server-start)))
 1763       (cond
 1764        ;; Server should be started unconditionally
 1765        ((eq TeX-source-correlate-start-server t)
 1766     (funcall start))
 1767        ;; Ask user if server is to be started
 1768        ((and (eq TeX-source-correlate-start-server 'ask)
 1769          (not TeX-source-correlate-start-server-asked)
 1770          (prog1
 1771          (y-or-n-p (format "Start %s for inverse search in viewer? "
 1772                    (if gnuserv-p
 1773                        "gnuserv"
 1774                      "Emacs server")))
 1775            (setq TeX-source-correlate-start-server-asked t)))
 1776     (funcall start))))))
 1777 
 1778 (defun TeX-source-correlate-determine-method ()
 1779   "Determine which method is available for forward and inverse search."
 1780   (let ((help (condition-case nil
 1781           (with-output-to-string
 1782             (call-process LaTeX-command
 1783                   nil (list standard-output nil) nil "--help"))
 1784         (error ""))))
 1785     (if (string-match "^[ ]*-?-synctex" help)
 1786     'synctex
 1787       'source-specials)))
 1788 
 1789 (defun TeX-source-correlate-method-active ()
 1790   "Return the method actually used for forward and inverse search."
 1791   (cond
 1792    ((eq TeX-source-correlate-method 'auto)
 1793     (TeX-source-correlate-determine-method))
 1794    ((listp TeX-source-correlate-method)
 1795     (if TeX-PDF-mode
 1796     (cdr (assoc 'pdf TeX-source-correlate-method))
 1797       (cdr (assoc 'dvi TeX-source-correlate-method))))
 1798    (t
 1799     TeX-source-correlate-method)))
 1800 
 1801 (defun TeX-source-correlate-expand-options ()
 1802   "Return TeX engine command line option for forward search facilities.
 1803 The return value depends on the value of `TeX-source-correlate-mode'.
 1804 If this is nil, an empty string will be returned."
 1805   (if TeX-source-correlate-mode
 1806       (if (eq (TeX-source-correlate-method-active) 'source-specials)
 1807       (concat TeX-source-specials-tex-flags
 1808           (if TeX-source-specials-places
 1809               ;; -src-specials=WHERE: insert source specials
 1810               ;; in certain places of the DVI file. WHERE is a
 1811               ;; comma-separated value list: cr display hbox
 1812               ;; math par parend vbox
 1813               (concat "=" (mapconcat 'identity
 1814                          TeX-source-specials-places ","))))
 1815     TeX-synctex-tex-flags)
 1816     ""))
 1817 
 1818 (defvar TeX-source-correlate-map (make-sparse-keymap)
 1819   "Keymap for `TeX-source-correlate-mode'.
 1820 You could use this for unusual mouse bindings.")
 1821 
 1822 (defun TeX-source-correlate-handle-TeX-region (file line col)
 1823   "Translate backward search info with respect to `TeX-region'.
 1824 That is, if FILE is `TeX-region', update FILE to the real tex
 1825 file and LINE to (+ LINE offset-of-region).  Else, return nil."
 1826   (when (string-equal TeX-region (file-name-sans-extension
 1827                   (file-name-nondirectory file)))
 1828     (with-current-buffer (or (find-buffer-visiting file)
 1829                  (find-file-noselect file))
 1830       (goto-char 0)
 1831       ;; Same regexp used in `preview-parse-messages'.  XXX: XEmacs doesn't
 1832       ;; support regexp classes, so we can't use "[:digit:]" here.
 1833       (when (re-search-forward "!offset(\\([---0-9]+\\))" nil t)
 1834     (let ((offset (string-to-number (match-string-no-properties 1))))
 1835       (when TeX-region-orig-buffer
 1836         (list (expand-file-name (buffer-file-name TeX-region-orig-buffer))
 1837           (+ line offset) col)))))))
 1838 
 1839 (defcustom TeX-raise-frame-function #'raise-frame
 1840   "A function which will be called to raise the Emacs frame.
 1841 The function is called after `TeX-source-correlate-sync-source'
 1842 has processed an inverse search DBUS request from
 1843 Evince-compatible viewers in order to raise the Emacs frame.
 1844 
 1845 The default value is `raise-frame', however, depending on window
 1846 manager and focus stealing policies, it might very well be that
 1847 Emacs doesn't pop into the foreground.  So you can do whatever it
 1848 takes here.
 1849 
 1850 For some users, `x-focus-frame' does the trick.  For some
 1851 users (on GNOME 3.20),
 1852 
 1853   (lambda ()
 1854     (run-at-time 0.5 nil #'x-focus-frame))
 1855 
 1856 does the trick.  Some other users use the external wmctrl tool to
 1857 raise the Emacs frame like so:
 1858 
 1859   (lambda ()
 1860     (call-process
 1861      \"wmctrl\" nil nil nil \"-i\" \"-R\"
 1862      (frame-parameter (selected-frame) 'outer-window-id)))"
 1863   :type 'function
 1864   :group 'TeX-view)
 1865 
 1866 (defun TeX-source-correlate-sync-source (file linecol &rest ignored)
 1867   "Show TeX FILE with point at LINECOL.
 1868 This function is called when emacs receives a SyncSource signal
 1869 emitted from the Evince document viewer.  IGNORED absorbs an
 1870 unused id field accompanying the DBUS signal sent by Evince-3.0.0
 1871 or newer.
 1872 
 1873 If the Emacs frame isn't raised, customize
 1874 `TeX-raise-frame-function'."
 1875   ;; FILE may be given as relative path to the TeX-master root document or as
 1876   ;; absolute file:// URL.  In the former case, the tex file has to be already
 1877   ;; opened.
 1878   (let* ((file (progn
 1879          (require 'url-parse)
 1880          (require 'url-util)
 1881          (url-unhex-string (aref (url-generic-parse-url file) 6))))
 1882      (flc (or (apply #'TeX-source-correlate-handle-TeX-region file linecol)
 1883           (apply #'list file linecol)))
 1884      (file (car flc))
 1885      (line (cadr flc))
 1886      (col  (nth 2 flc)))
 1887     (pop-to-buffer (or (find-buffer-visiting file)
 1888                        (find-file-noselect file)))
 1889     (push-mark nil 'nomsg)
 1890     (let ((pos
 1891        (when (> line 0)
 1892          (save-excursion
 1893            (save-restriction
 1894          (widen)
 1895          (goto-char 1)
 1896          (forward-line (1- line))
 1897          (when (> col 0)
 1898            (forward-char (1- col)))
 1899          (point))))))
 1900       (when pos
 1901     (when (or (< pos (point-min))
 1902           (> pos (point-max)))
 1903       (widen))
 1904     (goto-char pos))
 1905       (when TeX-raise-frame-function
 1906     (funcall TeX-raise-frame-function)))))
 1907 
 1908 (define-minor-mode TeX-source-correlate-mode
 1909   "Minor mode for forward and inverse search.
 1910 
 1911 If enabled, the viewer can be advised to show the output page
 1912 corresponding to the point in the source and vice versa.
 1913 
 1914 The method to be used can be controlled with the variable
 1915 `TeX-source-correlate-method'.  Currently source specials or
 1916 SyncTeX are recognized."
 1917   :group 'TeX-view
 1918   ;; Since this is a global minor mode and we don't want to require
 1919   ;; tex.el when the mode variable is set, the mode function is called
 1920   ;; explicitely (if necessary) in `VirTeX-common-initialization'.  We
 1921   ;; do it there because otherwise `kill-all-local-variables' would
 1922   ;; reset `TeX-source-correlate-output-page-function' which is
 1923   ;; buffer-local.
 1924   :global t
 1925   (set-keymap-parent TeX-mode-map (and TeX-source-correlate-mode
 1926                        TeX-source-correlate-map))
 1927   (TeX-set-mode-name 'TeX-source-correlate-mode t t)
 1928   (setq TeX-source-correlate-start-server-flag TeX-source-correlate-mode)
 1929   ;; Register Emacs for the SyncSource DBUS signal emitted by
 1930   ;; Evince-compatible viewers.
 1931   (dolist (de-app '(("gnome" "evince") ("mate" "atril") ("x" "reader")))
 1932     (when (TeX-evince-dbus-p (car de-app) (cadr de-app))
 1933       (dbus-register-signal
 1934        :session nil (format "/org/%s/%s/Window/0" (car de-app) (cadr de-app))
 1935        (format "org.%s.%s.Window" (car de-app) (cadr de-app))
 1936        "SyncSource"
 1937        'TeX-source-correlate-sync-source))))
 1938 
 1939 (defalias 'TeX-source-specials-mode 'TeX-source-correlate-mode)
 1940 (make-obsolete 'TeX-source-specials-mode 'TeX-source-correlate-mode "11.86")
 1941 (defalias 'tex-source-correlate-mode 'TeX-source-correlate-mode)
 1942 (put 'TeX-source-correlate-mode 'safe-local-variable #'booleanp)
 1943 (setq minor-mode-map-alist
 1944       (delq (assq 'TeX-source-correlate-mode minor-mode-map-alist)
 1945         minor-mode-map-alist))
 1946 
 1947 
 1948 ;;; Source Specials
 1949 
 1950 (defcustom TeX-source-specials-tex-flags "-src-specials"
 1951   "Extra flags to pass to TeX commands to generate source specials."
 1952   :group 'TeX-view
 1953   :type 'string)
 1954 
 1955 (defcustom TeX-source-specials-places nil
 1956   "List of places where to insert source specials into the DVI file.
 1957 If nil, use (La)TeX's defaults."
 1958   :group 'TeX-view
 1959   :type '(list (set :inline t
 1960             ;; :tag "Options known to work"
 1961             ;; cr display hbox math par parend vbox
 1962             (const "cr")
 1963             (const "display")
 1964             (const "hbox")
 1965             (const "math")
 1966             (const "par")
 1967             (const "parend")
 1968             (const "vbox"))
 1969            (repeat :inline t
 1970                :tag "Other options"
 1971                (string))))
 1972 
 1973 (defcustom TeX-source-specials-view-position-flags
 1974   "-sourceposition \"%n %b\""
 1975   "Flags to pass to the DVI viewer commands for the position in the source."
 1976   :group 'TeX-view
 1977   :type 'string)
 1978 
 1979 (defcustom TeX-source-specials-view-editor-flags
 1980   "-editor \"%cS\""
 1981   "Flags to pass to DVI viewer commands for inverse search."
 1982   :group 'TeX-view
 1983   :type 'string)
 1984 
 1985 (defcustom TeX-source-specials-view-gnuclient-flags
 1986   "-q +%%l %%f"
 1987   "Flags to pass to gnuclient for inverse search."
 1988   :group 'TeX-view
 1989   :type 'string)
 1990 
 1991 (defcustom TeX-source-specials-view-emacsclient-flags
 1992   "--no-wait +%%l %%f"
 1993   "Flags to emacsclient for inverse search."
 1994   :group 'TeX-view
 1995   :type 'string)
 1996 
 1997 ;; FIXME: Make client binaries configurable.
 1998 (defun TeX-source-specials-view-expand-client ()
 1999   "Return gnuclient or emacslient executable with options.
 2000 Return the full path to the executable if possible."
 2001   (let* ((gnuserv-p (TeX-source-correlate-gnuserv-p))
 2002      (client-base (if gnuserv-p
 2003               "gnuclient"
 2004             "emacsclient"))
 2005      (client-full (and invocation-directory
 2006                (expand-file-name client-base
 2007                          invocation-directory)))
 2008      (options (if gnuserv-p
 2009               TeX-source-specials-view-gnuclient-flags
 2010             TeX-source-specials-view-emacsclient-flags)))
 2011     (if (and client-full (file-executable-p client-full))
 2012     (concat client-full " " options)
 2013       (concat client-base " " options))))
 2014 
 2015 (defun TeX-source-specials-view-expand-options (&optional viewer)
 2016   "Return source specials command line option for viewer command.
 2017 The return value depends on the values of
 2018 `TeX-source-correlate-mode' and
 2019 `TeX-source-correlate-method-active'.  If those are nil or not
 2020 `source-specials' respectively, an empty string will be
 2021 returned."
 2022   (if (and TeX-source-correlate-mode
 2023        (eq (TeX-source-correlate-method-active) 'source-specials))
 2024       (concat TeX-source-specials-view-position-flags
 2025           (when (TeX-source-correlate-server-enabled-p)
 2026         (concat " " TeX-source-specials-view-editor-flags)))
 2027     ""))
 2028 
 2029 ;;; SyncTeX
 2030 
 2031 (defvar TeX-synctex-tex-flags "--synctex=1"
 2032   "Extra flags to pass to TeX commands to enable SyncTeX.")
 2033 
 2034 (defun TeX-synctex-output-page-1 (file)
 2035   "Return the page corresponding to the current position in FILE.
 2036 This method assumes that the document was compiled with SyncTeX
 2037 enabled and the `synctex' binary is available."
 2038   (let ((synctex-output
 2039      (with-output-to-string
 2040        (call-process "synctex" nil (list standard-output nil) nil "view"
 2041              "-i" (format "%s:%s:%s" (1+ (TeX-current-offset))
 2042                       ;; FIXME: Using `current-column'
 2043                       ;; here is dubious.  See comment in
 2044                       ;; `TeX-evince-sync-view-1'.
 2045                       (1+ (current-column))
 2046                       file)
 2047              "-o" (TeX-active-master (TeX-output-extension))))))
 2048     (when (string-match "^Page:\\([0-9]+\\)" synctex-output)
 2049       (match-string 1 synctex-output))))
 2050 
 2051 (defun TeX-synctex-output-page ()
 2052   "Return the page corresponding to the position in the current buffer.
 2053 This method assumes that the document was compiled with SyncTeX
 2054 enabled and the `synctex' binary is available."
 2055   (let* ((file (file-relative-name (buffer-file-name)
 2056                    (file-name-directory
 2057                     (TeX-active-master))))
 2058      (abs-file (concat (expand-file-name (or (file-name-directory (TeX-active-master))
 2059                          (file-name-directory (buffer-file-name))))
 2060                "./" file)))
 2061     ;; It's known that depending on synctex version one of
 2062     ;; /absolute/path/./foo/bar.tex, foo/bar.tex, or ./foo/bar.tex (relative to
 2063     ;; TeX-master, and the "." in the absolute path is important) are needed.
 2064     ;; So try all variants before falling back to page 1.
 2065     (or (TeX-synctex-output-page-1 abs-file)
 2066     (TeX-synctex-output-page-1 file)
 2067     (TeX-synctex-output-page-1 (concat "./" file))
 2068     "1")))
 2069 
 2070 ;;; Miscellaneous minor modes
 2071 
 2072 (defvar TeX-mode-p nil
 2073   "This indicates a TeX mode being active.")
 2074 (make-variable-buffer-local 'TeX-mode-p)
 2075 
 2076 (defun TeX-mode-set (var value)
 2077   (set-default var value)
 2078   (TeX-set-mode-name var nil t))
 2079 
 2080 (defcustom TeX-PDF-mode t nil
 2081   :group 'TeX-command
 2082   :set 'TeX-mode-set
 2083   :type 'boolean)
 2084 (put 'TeX-PDF-mode 'safe-local-variable #'booleanp)
 2085 
 2086 (define-minor-mode TeX-PDF-mode
 2087   "Minor mode for using PDFTeX.
 2088 
 2089 If enabled, PDFTeX will be used as an executable by default.
 2090 You can customize an initial value, and you can use the
 2091 function `TeX-global-PDF-mode' for toggling this value."
 2092   :group 'TeX-command
 2093   (when (eq TeX-engine 'omega)
 2094     (setq TeX-PDF-mode nil))
 2095   (setq TeX-PDF-mode-parsed nil)
 2096   (TeX-set-mode-name nil nil t)
 2097   (setq TeX-output-extension
 2098     (if TeX-PDF-mode "pdf" "dvi")))
 2099 (add-to-list 'minor-mode-alist '(TeX-PDF-mode ""))
 2100 
 2101 (defun TeX-global-PDF-mode (&optional arg)
 2102   "Toggle default for `TeX-PDF-mode'."
 2103   (interactive "P")
 2104   (prog1
 2105       (setq-default TeX-PDF-mode
 2106             (if arg (> (prefix-numeric-value arg) 0)
 2107               (not (default-value 'TeX-PDF-mode))))
 2108     (TeX-set-mode-name 'TeX-PDF-mode nil t)))
 2109 
 2110 (defalias 'tex-pdf-mode 'TeX-PDF-mode)
 2111 
 2112 (defvar TeX-PDF-mode-parsed nil
 2113   "Set if `TeX-PDF-mode' has come about by parsing.")
 2114 
 2115 (make-variable-buffer-local 'TeX-PDF-mode-parsed)
 2116 
 2117 (defun TeX-PDF-mode-parsed (arg)
 2118   "Change `TeX-PDF-mode' to ARG based on parsing.
 2119 If this conflicts with previous parsed settings,
 2120 just use the default.  If an explicit setting is
 2121 already established, don't do anything."
 2122 
 2123 ;; Basically we have the following situations:
 2124 ;; TeX-PDF-mode-parsed (local-variable-p 'TeX-PDF-mode):
 2125 ;; nil nil : virgin state
 2126 ;; nil t   : stably set state (possibly because of conflicting parse info)
 2127 ;; t   t   : non-conflicting parsed info
 2128 
 2129   (if TeX-PDF-mode-parsed
 2130       (unless (eq TeX-PDF-mode arg)
 2131     (TeX-PDF-mode (if (default-value 'TeX-PDF-mode) 1 0)))
 2132     (unless (local-variable-p 'TeX-PDF-mode (current-buffer))
 2133       (TeX-PDF-mode (if arg 1 0))
 2134       (setq TeX-PDF-mode-parsed t))))
 2135 
 2136 (defun TeX-PDF-mode-on ()
 2137   "Use only from parsing routines."
 2138   (TeX-PDF-mode-parsed t))
 2139 
 2140 (defun TeX-PDF-mode-off ()
 2141   "Use only from parsing routines."
 2142   (TeX-PDF-mode-parsed nil))
 2143 
 2144 (defcustom TeX-DVI-via-PDFTeX nil
 2145   "Whether to use PDFTeX also for producing DVI files."
 2146   :group 'TeX-command
 2147   :type 'boolean)
 2148 
 2149 (defcustom TeX-PDF-from-DVI nil
 2150   "Specify if and how to produce PDF output from a DVI file.
 2151 
 2152 If non-nil, the default compiler produces DVI output.  The value
 2153 should be the name of the command used to convert the DVI file to
 2154 PDF or to an intermediate type.
 2155 
 2156 Possible values are
 2157 
 2158 * \"Dvips\": the DVI file is converted to PS with dvips.  After
 2159   successfully running it, ps2pdf will be the default command to
 2160   convert the PS file to PDF
 2161 * \"Dvipdfmx\": the PDF is produced with dvipdfmx
 2162 
 2163 Programs should not use this variable directly but the function
 2164 `TeX-PDF-from-DVI' which handles now obsolete variable
 2165 `TeX-PDF-via-dvips-ps2pdf'."
 2166   :group 'TeX-command
 2167   :type '(choice
 2168       (const :tag "No DVI to PDF conversion" nil)
 2169       (const :tag "dvips - ps2pdf sequence" "Dvips")
 2170       (const :tag "dvipdfmx" "Dvipdfmx")))
 2171 ;; If you plan to support new values of `TeX-PDF-from-DVI' remember to update
 2172 ;; `TeX-command-default' accordingly.
 2173 (make-variable-buffer-local 'TeX-PDF-from-DVI)
 2174 (put 'TeX-PDF-from-DVI 'safe-local-variable
 2175      (lambda (x) (or (stringp x) (null x))))
 2176 
 2177 (defcustom TeX-PDF-via-dvips-ps2pdf nil
 2178   "Whether to produce PDF output through the (La)TeX - dvips - ps2pdf sequence."
 2179   :group 'TeX-command
 2180   :type 'boolean)
 2181 (make-variable-buffer-local 'TeX-PDF-via-dvips-ps2pdf)
 2182 (put 'TeX-PDF-via-dvips-ps2pdf 'safe-local-variable #'booleanp)
 2183 (make-obsolete-variable 'TeX-PDF-via-dvips-ps2pdf 'TeX-PDF-from-DVI "11.90")
 2184 
 2185 (defun TeX-PDF-from-DVI ()
 2186   "Return the value of variable `TeX-PDF-from-DVI'.
 2187 
 2188 If `TeX-PDF-from-DVI' is not set and obsolete option
 2189 `TeX-PDF-via-dvips-ps2pdf' is non-nil, return \"Dvips\"
 2190 for backward compatibility."
 2191   (cond
 2192    (TeX-PDF-from-DVI)
 2193    (TeX-PDF-via-dvips-ps2pdf
 2194     "Dvips")))
 2195 
 2196 (define-minor-mode TeX-interactive-mode
 2197   "Minor mode for interactive runs of TeX."
 2198   nil nil nil
 2199   :group 'TeX-command
 2200   (TeX-set-mode-name 'TeX-interactive-mode t t))
 2201 (defalias 'tex-interactive-mode 'TeX-interactive-mode)
 2202 (add-to-list 'minor-mode-alist '(TeX-interactive-mode ""))
 2203 
 2204 ;;; Commands
 2205 
 2206 (defgroup TeX-command-name nil
 2207   "Names for external commands in AUCTeX."
 2208   :group 'TeX-command)
 2209 
 2210 (defcustom TeX-command-BibTeX "BibTeX"
 2211   "*The name of the BibTeX entry in `TeX-command-list'."
 2212   :group 'TeX-command-name
 2213   :type 'string)
 2214   (make-variable-buffer-local 'TeX-command-BibTeX)
 2215 
 2216 (defcustom TeX-command-Biber "Biber"
 2217   "*The name of the Biber entry in `TeX-command-list'."
 2218   :group 'TeX-command-name
 2219   :type 'string)
 2220   (make-variable-buffer-local 'TeX-command-Biber)
 2221 
 2222 (defcustom TeX-command-Show "View"
 2223   "*The default command to show (view or print) a TeX file.
 2224 Must be the car of an entry in `TeX-command-list'."
 2225   :group 'TeX-command-name
 2226   :type 'string)
 2227   (make-variable-buffer-local 'TeX-command-Show)
 2228 
 2229 (defcustom TeX-command-Print "Print"
 2230   "The name of the Print entry in `TeX-command-Print'."
 2231   :group 'TeX-command-name
 2232   :type 'string)
 2233 
 2234 (defcustom TeX-command-Queue "Queue"
 2235   "The name of the Queue entry in `TeX-command-Queue'."
 2236   :group 'TeX-command-name
 2237   :type 'string)
 2238 
 2239 (defvar TeX-trailer-start nil
 2240   "Regular expression delimiting start of trailer in a TeX file.")
 2241 
 2242  (make-variable-buffer-local 'TeX-trailer-start)
 2243 
 2244 (defvar TeX-header-end nil
 2245   "Regular expression delimiting end of header in a TeX file.")
 2246 
 2247  (make-variable-buffer-local 'TeX-header-end)
 2248 
 2249 (defvar TeX-command-default nil
 2250   "The default command for `TeX-command' in the current major mode.")
 2251 
 2252  (make-variable-buffer-local 'TeX-command-default)
 2253 
 2254 (put 'TeX-command-default 'safe-local-variable 'stringp)
 2255 
 2256 (defvar TeX-clean-default-intermediate-suffixes
 2257   '("\\.aux" "\\.bbl" "\\.blg" "\\.brf" "\\.fot"
 2258     "\\.glo" "\\.gls" "\\.idx" "\\.ilg" "\\.ind"
 2259     "\\.lof" "\\.log" "\\.lot" "\\.nav" "\\.out"
 2260     "\\.snm" "\\.toc" "\\.url" "\\.synctex\\.gz"
 2261     "\\.bcf" "\\.run\\.xml" "\\.fls" "-blx\\.bib")
 2262   "List of regexps matching suffixes of files to be cleaned.
 2263 Used as a default in TeX, LaTeX and docTeX mode.")
 2264 
 2265 (defvar TeX-clean-default-output-suffixes
 2266   '("\\.dvi" "\\.pdf" "\\.ps" "\\.xdv")
 2267   "List of regexps matching suffixes of files to be cleaned.
 2268 Used as a default in TeX, LaTeX and docTeX mode.")
 2269 
 2270 (defcustom TeX-clean-confirm t
 2271   "If non-nil, ask before deleting files."
 2272   :type 'boolean
 2273   :group 'TeX-command)
 2274 
 2275 (autoload 'dired-mark-pop-up "dired")
 2276 
 2277 (defun TeX-clean (&optional arg)
 2278   "Delete generated files associated with current master and region files.
 2279 If prefix ARG is non-nil, not only remove intermediate but also
 2280 output files."
 2281   (interactive "P")
 2282   (let* ((mode-prefix (TeX-mode-prefix))
 2283      (suffixes (append (symbol-value
 2284                 (intern (concat mode-prefix
 2285                         "-clean-intermediate-suffixes")))
 2286                (when arg
 2287                  (symbol-value
 2288                   (intern (concat mode-prefix
 2289                           "-clean-output-suffixes"))))))
 2290      (master (TeX-active-master))
 2291      (master-dir (file-name-directory master))
 2292      (regexp (concat "\\("
 2293              (regexp-quote (file-name-nondirectory master)) "\\|"
 2294              (regexp-quote (TeX-region-file nil t))
 2295              "\\)"
 2296              "\\("
 2297              (mapconcat 'identity suffixes "\\|")
 2298              "\\)\\'"
 2299              "\\|" (regexp-quote (TeX-region-file t t))))
 2300      (files (when regexp
 2301           (directory-files (or master-dir ".") nil regexp))))
 2302     (if files
 2303     (when (or (not TeX-clean-confirm)
 2304           (dired-mark-pop-up " *Deletions*" 'delete
 2305                      (if (> (length files) 1)
 2306                      files
 2307                        (cons t files))
 2308                      'y-or-n-p "Delete files? "))
 2309       (dolist (file files)
 2310         (delete-file (concat master-dir file))))
 2311       (message "No files to be deleted"))))
 2312 
 2313 ;;; Master File
 2314 
 2315 (defcustom TeX-master t
 2316   "*The master file associated with the current buffer.
 2317 If the file being edited is actually included from another file, you
 2318 can tell AUCTeX the name of the master file by setting this variable.
 2319 If there are multiple levels of nesting, specify the top level file.
 2320 
 2321 If this variable is nil, AUCTeX will query you for the name.
 2322 
 2323 If the variable is t, AUCTeX will assume the file is a master file
 2324 itself.
 2325 
 2326 If the variable is 'shared, AUCTeX will query for the name, but not
 2327 change the file.
 2328 
 2329 If the variable is 'dwim, AUCTeX will try to avoid querying by
 2330 attempting to `do what I mean'; and then change the file.
 2331 
 2332 It is suggested that you use the File Variables (see the info node in
 2333 the Emacs manual) to set this variable permanently for each file."
 2334   :group 'TeX-command
 2335   :group 'TeX-parse
 2336   :type '(choice (const :tag "Query" nil)
 2337          (const :tag "This file" t)
 2338          (const :tag "Shared" shared)
 2339          (const :tag "Dwim" dwim)
 2340          (string :format "%v")))
 2341 (make-variable-buffer-local 'TeX-master)
 2342 (put 'TeX-master 'safe-local-variable
 2343      '(lambda (x)
 2344     (or (stringp x)
 2345         (member x (quote (t nil shared dwim))))))
 2346 
 2347 (defcustom TeX-one-master "\\.\\(texi?\\|dtx\\)$"
 2348   "*Regular expression matching ordinary TeX files.
 2349 
 2350 You should set this variable to match the name of all files, where
 2351 automatically adding a file variable with the name of the master file
 2352 is a good idea.  When AUCTeX adds the name of the master file as a
 2353 file variable, it does not need to ask next time you edit the file.
 2354 
 2355 If you dislike AUCTeX automatically modifying your files, you can set
 2356 this variable to \"<none>\"."
 2357   :group 'TeX-command
 2358   :type 'regexp)
 2359 
 2360 ;; Can be let-bound temporarily in order to inhibit the master file question
 2361 ;; by using its value instead in case `TeX-master' is nil or 'shared.
 2362 (defvar TeX-transient-master nil)
 2363 
 2364 (defun TeX-dwim-master ()
 2365   "Find a likely `TeX-master'."
 2366   (let ((dir default-directory))
 2367     (cl-loop for buf in (buffer-list)
 2368              until
 2369              (when (with-current-buffer buf
 2370                  (and (equal dir default-directory)
 2371                   (stringp TeX-master)))
 2372                (cl-return (with-current-buffer buf TeX-master))))))
 2373 
 2374 (defun TeX-master-file-ask ()
 2375   "Ask for master file, set `TeX-master' and add local variables."
 2376   (interactive)
 2377   (if (TeX-local-master-p)
 2378       (error "Master file already set")
 2379     (let* ((default (TeX-dwim-master))
 2380        (name (or (and (eq 'dwim TeX-master) default)
 2381              (condition-case nil
 2382              (read-file-name (format "Master file (default %s): "
 2383                          (or default "this file"))
 2384                      nil default)
 2385                (quit "<quit>")))))
 2386       (cond ((string= name "<quit>")
 2387          (setq TeX-master t))
 2388         ((string= name default)
 2389          (setq TeX-master default)
 2390          (TeX-add-local-master))
 2391         ((or
 2392           ;; Default `read-file-name' proposes and buffer visits a file.
 2393           (string= (expand-file-name name) (buffer-file-name))
 2394           ;; Default of `read-file-name' and buffer does not visit a file.
 2395           (string= name default-directory)
 2396           ;; User typed <RET> in an empty minibuffer.
 2397           (string= name ""))
 2398          (setq TeX-master t)
 2399          (TeX-add-local-master))
 2400         (t
 2401          (setq TeX-master (TeX-strip-extension (file-relative-name name)
 2402                            (list TeX-default-extension)
 2403                            'path))
 2404          (TeX-add-local-master))))))
 2405 
 2406 (defun TeX-master-file (&optional extension nondirectory ask)
 2407   "Set and return the name of the master file for the current document.
 2408 
 2409 If optional argument EXTENSION is non-nil, add that file extension to
 2410 the name.  Special value t means use `TeX-default-extension'.
 2411 
 2412 If optional second argument NONDIRECTORY is non-nil, do not include
 2413 the directory.
 2414 
 2415 If optional third argument ASK is non-nil, ask the user for the
 2416 name of master file if it cannot be determined otherwise."
 2417   (interactive)
 2418   (if (eq extension t)
 2419       (setq extension TeX-default-extension))
 2420   (let ((my-name (if (buffer-file-name)
 2421              (TeX-strip-extension nil (list TeX-default-extension) t)
 2422            "<none>")))
 2423     (save-excursion
 2424       (save-restriction
 2425     (widen)
 2426     (goto-char (point-min))
 2427     (cond
 2428      ((and TeX-transient-master
 2429            (or (not TeX-master) (eq TeX-master 'shared)))
 2430       (setq TeX-master TeX-transient-master))
 2431      ;; Special value 't means it is own master (a free file).
 2432      ((equal TeX-master my-name)
 2433       (setq TeX-master t))
 2434 
 2435      ;; For files shared between many documents.
 2436      ((and (eq 'shared TeX-master) ask)
 2437       (setq TeX-master
 2438         (let* ((default (TeX-dwim-master))
 2439                (name (read-file-name
 2440                   (format "Master file (default %s): "
 2441                       (or default "this file"))
 2442                   nil default)))
 2443           (cond ((string= name default)
 2444              default)
 2445             ((or
 2446               ;; Default `read-file-name' proposes and
 2447               ;; buffer visits a file.
 2448               (string= (expand-file-name name)
 2449                    (buffer-file-name))
 2450               ;; Default of `read-file-name' and
 2451               ;; buffer does not visit a file.
 2452               (string= name default-directory)
 2453               ;; User typed <RET> in an empty minibuffer.
 2454               (string= name ""))
 2455              t)
 2456             (t
 2457              (TeX-strip-extension
 2458               name (list TeX-default-extension) 'path))))))
 2459 
 2460      ;; We might already know the name.
 2461      ((or (eq TeX-master t) (stringp TeX-master)) TeX-master)
 2462 
 2463      ;; Ask the user (but add it as a local variable).
 2464      (ask (TeX-master-file-ask)))))
 2465 
 2466     (let ((name (if (stringp TeX-master)
 2467             TeX-master
 2468           my-name)))
 2469 
 2470       (if (TeX-match-extension name)
 2471       ;; If it already has an extension...
 2472       (if (equal extension TeX-default-extension)
 2473           ;; Use instead of the default extension
 2474           (setq extension nil)
 2475         ;; Otherwise drop it.
 2476         (setq name (TeX-strip-extension name))))
 2477 
 2478       ;; Remove directory if needed.
 2479       (if nondirectory
 2480       (setq name (file-name-nondirectory name)))
 2481 
 2482       (if extension
 2483       (concat name "." extension)
 2484     name))))
 2485 
 2486 (defun TeX-master-directory ()
 2487   "Directory of master file."
 2488   (file-name-as-directory
 2489    (abbreviate-file-name
 2490     (substitute-in-file-name
 2491      (expand-file-name
 2492       (let ((dir (file-name-directory (TeX-master-file))))
 2493     (if dir (directory-file-name dir) "."))
 2494       (and buffer-file-name
 2495        (file-name-directory buffer-file-name)))))))
 2496 
 2497 (defun TeX-add-local-master ()
 2498   "Add local variable for `TeX-master'.
 2499 
 2500 Get `major-mode' from master file and enable it."
 2501   (when (and (buffer-file-name)
 2502          (string-match TeX-one-master
 2503                (file-name-nondirectory (buffer-file-name)))
 2504          (not buffer-read-only))
 2505     (goto-char (point-max))
 2506     (if (re-search-backward "^\\([^\n]+\\)Local Variables:"
 2507                 (- (point-max) 3000) t)
 2508     (let ((prefix (TeX-match-buffer 1)))
 2509       (re-search-forward (regexp-quote (concat prefix
 2510                            "End:")))
 2511       (beginning-of-line 1)
 2512       (insert prefix "TeX-master: " (prin1-to-string TeX-master) "\n"))
 2513       (let* ((mode (if (stringp TeX-master)
 2514                (with-current-buffer
 2515                (find-file-noselect
 2516                 (TeX-master-file TeX-default-extension))
 2517              major-mode)
 2518              major-mode))
 2519          (comment-prefix (cond ((eq mode 'texinfo-mode) "@c ")
 2520                    ((eq mode 'doctex-mode) "% ")
 2521                    (t "%%% ")))
 2522          (mode-string (concat (and (boundp 'japanese-TeX-mode) japanese-TeX-mode
 2523                        "japanese-")
 2524                   (substring (symbol-name mode) 0 -5))))
 2525     (newline)
 2526     (when (eq major-mode 'doctex-mode)
 2527       (insert comment-prefix TeX-esc "endinput\n"))
 2528     (insert
 2529      comment-prefix "Local Variables:\n"
 2530      comment-prefix "mode: " mode-string "\n"
 2531      comment-prefix "TeX-master: " (prin1-to-string TeX-master) "\n"
 2532      comment-prefix "End:\n")
 2533     (unless (eq mode major-mode)
 2534       (funcall mode)
 2535       ;; TeX modes run `VirTeX-common-initialization' which kills all local
 2536       ;; variables, thus `TeX-master' will be forgotten after `(funcall
 2537       ;; mode)'.  Reparse local variables in order to bring it back.
 2538       (hack-local-variables))))))
 2539 
 2540 (defun TeX-local-master-p ()
 2541   "Return non-nil if there is a `TeX-master' entry in local variables spec.
 2542 Return nil otherwise."
 2543   (save-excursion
 2544     ;; XXX: Checking -*- line necessary as well?
 2545     (goto-char (point-max))
 2546     (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) 'move)
 2547     (re-search-forward "^%+ *TeX-master:" nil t)))
 2548 
 2549 ;;; Style Paths
 2550 
 2551 (defcustom TeX-style-global (expand-file-name "style" TeX-data-directory)
 2552   "*Directory containing hand generated TeX information.
 2553 
 2554 These correspond to TeX macros shared by all users of a site."
 2555   :group 'TeX-file
 2556   :type 'directory)
 2557 
 2558 (defcustom TeX-auto-local "auto"
 2559   "*Directory containing automatically generated TeX information.
 2560 
 2561 This correspond to TeX macros found in the current directory, and must
 2562 be relative to that."
 2563   :group 'TeX-file
 2564   :type 'string)
 2565 
 2566 (defcustom TeX-style-local "style"
 2567   "*Directory containing hand generated TeX information.
 2568 
 2569 These correspond to TeX macros found in the current directory, and must
 2570 be relative to that."
 2571   :group 'TeX-file
 2572   :type 'string)
 2573 
 2574 (defun TeX-split-string (regexp string)
 2575   "Return a list of strings.
 2576 Given REGEXP the STRING is split into sections which in string was
 2577 seperated by REGEXP.
 2578 
 2579 Examples:
 2580 
 2581       (TeX-split-string \"\:\" \"abc:def:ghi\")
 2582       -> (\"abc\" \"def\" \"ghi\")
 2583 
 2584       (TeX-split-string \" +\" \"dvips  -Plw -p3 -c4 testfile.dvi\")
 2585 
 2586       -> (\"dvips\" \"-Plw\" \"-p3\" \"-c4\" \"testfile.dvi\")
 2587 
 2588 If REGEXP is nil, or \"\", an error will occur."
 2589 
 2590   (let ((start 0) result match)
 2591     (while (setq match (string-match regexp string start))
 2592       (push (substring string start match) result)
 2593       (setq start (match-end 0)))
 2594     (push (substring string start) result)
 2595     (nreverse result)))
 2596 
 2597 (defun TeX-parse-path (env)
 2598   "Return a list if private TeX directories found in environment variable ENV."
 2599   (let* ((value (getenv env))
 2600      (entries (and value
 2601                (TeX-split-string
 2602             (if (string-match ";" value) ";" ":")
 2603             value)))
 2604      entry
 2605      answers)
 2606     (while entries
 2607       (setq entry (car entries))
 2608       (setq entries (cdr entries))
 2609       (setq entry (file-name-as-directory
 2610            (if (string-match "/?/?\\'" entry)
 2611                (substring entry 0 (match-beginning 0))
 2612              entry)))
 2613       (or (not (file-name-absolute-p entry))
 2614       (member entry (append '("/" "\\") TeX-macro-global))
 2615       (setq answers (cons entry answers))))
 2616     answers))
 2617 
 2618 (defun TeX-kpathsea-detect-path-delimiter ()
 2619   "Auto detect the path delimiter for kpsewhich command.
 2620 Usually return \":\" or \";\".  If auto detect fails for some reason,
 2621 return nil."
 2622   (let ((res (ignore-errors
 2623            (with-output-to-string
 2624          (call-process "kpsewhich" nil
 2625                    (list standard-output nil) nil
 2626                    "--expand-path" "{.,..}")))))
 2627     ;; kpsewhich expands "{.,..}" to ".:SOMEDIR" or ".;SOMEDIR"
 2628     ;; according to its environment.
 2629     ;; Don't use "{.,.}" instead because kpsewhich of MiKTeX 2.9
 2630     ;; simplifies it to just a ".", not ".;.".
 2631     (and (stringp res) (> (length res) 0)
 2632      ;; Check whether ; is contained.  This should work even if
 2633      ;; some implementation of kpsewhich considers it sane to
 2634      ;; insert drive letters or directory separators or whatever
 2635      ;; else to the current directory.
 2636      (if (string-match ";" res) ";" ":"))))
 2637 
 2638 (defcustom TeX-kpathsea-path-delimiter
 2639   (TeX-kpathsea-detect-path-delimiter)
 2640   "Path delimiter for kpathsea output.
 2641 t means autodetect, nil means kpathsea is disabled."
 2642   :group 'TeX-file
 2643   :type '(choice (const ":")
 2644          (const ";")
 2645          (const :tag "Autodetect" t)
 2646          (const :tag "Off" nil)))
 2647 
 2648 (defun TeX-tree-expand (vars program &optional subdirs)
 2649   "Return directories corresponding to the kpathsea variables VARS.
 2650 This is done calling `kpsewhich --expand-path' for the variables.
 2651 PROGRAM if non-nil is passed as the parameter for --progname.
 2652 Optional argument SUBDIRS are subdirectories which are appended
 2653 to the directories of the TeX trees.  Only existing directories
 2654 are returned."
 2655   ;; FIXME: The GNU convention only uses "path" to mean "list of directories"
 2656   ;; and uses "filename" for the name of a file even if it contains possibly
 2657   ;; several elements separated by "/".
 2658   (if (eq TeX-kpathsea-path-delimiter t)
 2659       (setq TeX-kpathsea-path-delimiter
 2660         (TeX-kpathsea-detect-path-delimiter)))
 2661   (when TeX-kpathsea-path-delimiter
 2662     (let* ((exit-status 1)
 2663        (args `(,@(if program `("--progname" ,program))
 2664            "--expand-path"
 2665            ,(mapconcat #'identity vars
 2666                    TeX-kpathsea-path-delimiter)))
 2667        (path-list (ignore-errors
 2668             (with-output-to-string
 2669               (setq exit-status
 2670                 (apply #'call-process
 2671                        "kpsewhich" nil
 2672                        (list standard-output nil) nil
 2673                        args))))))
 2674       (if (not (zerop exit-status))
 2675       ;; kpsewhich is not available.  Disable subsequent usage.
 2676       (setq TeX-kpathsea-path-delimiter nil)
 2677     (let ((separators (format "[\n\r%s]" TeX-kpathsea-path-delimiter))
 2678           path input-dir-list)
 2679       (dolist (item (split-string path-list separators t))
 2680         (if subdirs
 2681         (dolist (subdir subdirs)
 2682           (setq path (file-name-as-directory (concat item subdir)))
 2683           (when (file-exists-p path)
 2684             (cl-pushnew path input-dir-list :test #'equal)))
 2685           (setq path (file-name-as-directory item))
 2686           (when (file-exists-p path)
 2687         (cl-pushnew path input-dir-list :test #'equal))))
 2688       ;; No duplication in result is assured since `cl-pushnew' is
 2689       ;; used above.  Should we introduce an option for speed just
 2690       ;; to accumulate all the results without care for
 2691       ;; duplicates?
 2692       (nreverse input-dir-list))))))
 2693 
 2694 (defun TeX-macro-global ()
 2695   "Return directories containing the site's TeX macro and style files."
 2696   (or (TeX-tree-expand '("$SYSTEXMF" "$TEXMFLOCAL" "$TEXMFMAIN" "$TEXMFDIST")
 2697                "latex" '("/tex/" "/bibtex/bst/"))
 2698       '("/usr/share/texmf/tex/" "/usr/share/texmf/bibtex/bst/")))
 2699 
 2700 (defun TeX-macro-private ()
 2701   "Return directories containing the user's TeX macro and style files."
 2702   (TeX-tree-expand '("$TEXMFHOME") "latex" '("/tex/" "/bibtex/bst/")))
 2703 
 2704 (defcustom TeX-macro-global (TeX-macro-global)
 2705   "Directories containing the site's TeX macro and style files."
 2706   :group 'TeX-file
 2707   :type '(repeat (directory :format "%v")))
 2708 
 2709 (defcustom TeX-macro-private (or (append (TeX-parse-path "TEXINPUTS")
 2710                      (TeX-parse-path "BIBINPUTS"))
 2711                  (TeX-macro-private))
 2712   "Directories where you store your personal TeX macros."
 2713   :group 'TeX-file
 2714   :type '(repeat (file :format "%v")))
 2715 
 2716 (defcustom TeX-auto-private
 2717   (list (expand-file-name TeX-auto-local
 2718               (or (and (boundp 'user-emacs-directory)
 2719                    (concat user-emacs-directory "auctex/"))
 2720                   "~/.emacs.d/auctex/")))
 2721   "List of directories containing automatically generated AUCTeX style files.
 2722 
 2723 These correspond to the personal TeX macros."
 2724   :group 'TeX-file
 2725   :type '(repeat (file :format "%v")))
 2726 
 2727 (if (stringp TeX-auto-private)      ;Backward compatibility
 2728     (setq TeX-auto-private (list TeX-auto-private)))
 2729 
 2730 (defcustom TeX-style-private
 2731   (list (expand-file-name TeX-style-local
 2732               (or (and (boundp 'user-emacs-directory)
 2733                    (concat user-emacs-directory "auctex/"))
 2734                   "~/.emacs.d/auctex/")))
 2735   "List of directories containing hand-generated AUCTeX style files.
 2736 
 2737 These correspond to the personal TeX macros."
 2738   :group 'TeX-file
 2739   :type '(repeat (file :format "%v")))
 2740 
 2741 (if (stringp TeX-style-private)     ;Backward compatibility
 2742     (setq TeX-style-private (list TeX-style-private)))
 2743 
 2744 (defcustom TeX-style-path
 2745   (let ((path))
 2746     ;; Put directories in an order where the more local files can
 2747     ;; override the more global ones.
 2748     (mapc (lambda (file)
 2749         (when (and file (not (member file path)))
 2750           (setq path (cons file path))))
 2751           (append (list TeX-auto-global TeX-style-global)
 2752                   TeX-auto-private TeX-style-private
 2753                   (list TeX-auto-local TeX-style-local)))
 2754     (nreverse path))
 2755   "List of directories to search for AUCTeX style files.
 2756 Per default the list is built from the values of the variables
 2757 `TeX-auto-global', `TeX-style-global', `TeX-auto-private',
 2758 `TeX-style-private', `TeX-auto-local', and `TeX-style-local'."
 2759   :group 'TeX-file
 2760   :type '(repeat (file :format "%v")))
 2761 
 2762 (defcustom TeX-check-path
 2763   (append (list ".") TeX-macro-private TeX-macro-global)
 2764   "Directory path to search for dependencies.
 2765 
 2766 If nil, just check the current file.
 2767 Used when checking if any files have changed."
 2768   :group 'TeX-file
 2769   :type '(repeat (file :format "%v")))
 2770 
 2771 ;;; Style Files
 2772 
 2773 (defvar TeX-style-hook-list nil
 2774   "List of TeX style hooks currently loaded.
 2775 
 2776 Each entry is a list:
 2777 
 2778  (STYLE HOOK1 HOOK2 ...)
 2779 
 2780 where the first element STYLE is the name of the style, and the
 2781 remaining elements HOOKN, if any, are hooks to be run when that
 2782 style is active.
 2783 
 2784 A hook HOOKN may be a hook function HOOK-FUN to be run in
 2785 all TeX dialects (LaTeX, Texinfo, etc.), or a vector like:
 2786 
 2787      [TeX-style-hook HOOK-FUN DIALECT-SET]
 2788 
 2789 where HOOK-FUN is the hook function to be run, and DIALECT-SET is
 2790 a non-empty set of dialects in which the hook function may be
 2791 run.
 2792 
 2793 This set is instantiated by function `TeX-add-style-hook' through
 2794 functions manipulating style hook dialect expression named with a
 2795 `TeX-shdex-' prefix.
 2796 
 2797 For supported dialects, see variables `TeX-style-hook-dialect'.")
 2798 
 2799 (defvar TeX-style-hook-dialect :latex
 2800   "Dialect for running hooks locally to the considered file.
 2801 Supported values are described below:
 2802 
 2803 * `:bibtex'  for files in BibTeX mode.
 2804 * `:context' for files in ConTeXt mode.
 2805 * `:latex'   for files in LaTeX mode, or any mode derived
 2806          thereof.
 2807 * `:plain-tex' for files in plain-TeX mode.
 2808 * `:texinfo' for Texinfo files.
 2809 * `:classopt' for class options of LaTeX document.  Just
 2810           considered as a pseudo-dialect.
 2811 
 2812 Purpose is notably to prevent non-Texinfo hooks to be run in
 2813 Texinfo files, due to ambiguous style name, as this may cause bad
 2814 side effect e.g. on variable `TeX-font-list'.")
 2815 
 2816 (defcustom TeX-byte-compile nil
 2817   "*Not nil means try to byte compile auto files before loading."
 2818   :group 'TeX-parse
 2819   :type 'boolean)
 2820 
 2821 (defun TeX-bibtex-set-BibTeX-dialect ()
 2822   "Set `TeX-style-hook-dialect' to `:bibtex' locally to BibTeX buffers."
 2823   (set (make-local-variable 'TeX-style-hook-dialect) :bibtex))
 2824 
 2825 (defun TeX-load-style (style)
 2826   "Search for and load each definition for STYLE in `TeX-style-path'."
 2827   (cond ((assoc style TeX-style-hook-list)) ; We already found it
 2828     ((string-match "\\`\\(.+[/\\]\\)\\([^/\\]*\\)\\'" style) ;Complex path
 2829      (let* ((dir (substring style (match-beginning 1) (match-end 1)))
 2830         (style (substring style (match-beginning 2) (match-end 2)))
 2831         (master-dir (if (stringp TeX-master)
 2832                 (file-name-directory
 2833                  (file-relative-name TeX-master))
 2834                   "./"))
 2835         (TeX-style-path (append (list (expand-file-name
 2836                            TeX-auto-local dir)
 2837                           (expand-file-name
 2838                            TeX-auto-local master-dir)
 2839                           (expand-file-name
 2840                            TeX-style-local dir)
 2841                           (expand-file-name
 2842                            TeX-style-local master-dir))
 2843                     TeX-style-path)))
 2844        (TeX-load-style style)))
 2845     (t              ;Relative path
 2846      ;; Insert empty list to mark the fact that we have searched.
 2847      (setq TeX-style-hook-list (cons (list style) TeX-style-hook-list))
 2848      ;; Now check each element of the path
 2849      (dolist (name TeX-style-path)
 2850        (TeX-load-style-file (expand-file-name style name))))))
 2851 
 2852 (defun TeX-load-style-file (file)
 2853   "Load FILE checking for a Lisp extensions."
 2854   (let ((el (concat file ".el"))
 2855     (elc (concat file ".elc")))
 2856     (cond ((file-newer-than-file-p el elc)
 2857        (if (file-readable-p el)
 2858            (if (and TeX-byte-compile
 2859             (file-writable-p elc)
 2860             (save-excursion
 2861               ;; `byte-compile-file' switches buffer in Emacs 20.3.
 2862               (byte-compile-file el))
 2863             (file-readable-p elc))
 2864            (load-file elc)
 2865          (load-file el))))
 2866       ((file-readable-p elc)
 2867        (load-file elc))
 2868       ((file-readable-p el)
 2869        (load-file el)))))
 2870 
 2871 (defconst TeX-style-hook-dialect-weight-alist
 2872   '((:latex . 1) (:texinfo . 2) (:bibtex . 4) (:plain-tex . 8) (:context . 16)
 2873     (:classopt . 32))
 2874   "Association list to map dialects to binary weight, in order to
 2875   implement dialect sets as bitmaps."  )
 2876 
 2877 (defun TeX-shdex-eval (dialect-expr)
 2878   "Evaluate a style hook dialect expression DIALECT-EXPR."
 2879   (cond
 2880    ((symbolp dialect-expr)
 2881     (let ((cell (assq dialect-expr TeX-style-hook-dialect-weight-alist)))
 2882       (if cell (cdr cell)
 2883     (error "Invalid dialect expression : %S." dialect-expr))))
 2884    ((and (consp dialect-expr)
 2885      (memq (car dialect-expr) '(or not and nor)))
 2886     (apply (intern
 2887         (concat "TeX-shdex-" (symbol-name  (car dialect-expr))))
 2888        (cdr dialect-expr)))
 2889    (t
 2890     (error "Invalid dialect expression : %S." dialect-expr))))
 2891 
 2892 (defsubst TeX-shdex-or (&rest args)
 2893   "OR operator for style hook dialect expressions."
 2894   (apply 'logior (mapcar 'TeX-shdex-eval args)))
 2895 
 2896 (defsubst TeX-shdex-and (&rest args)
 2897   "AND operator for style hook dialect expressions."
 2898   (apply 'logand (mapcar 'TeX-shdex-eval args)))
 2899 
 2900 (defsubst TeX-shdex-nor (&rest args)
 2901   "NOR operator for style hook dialect expressions."
 2902   (lognot (apply 'TeX-shdex-or args)))
 2903 
 2904 (defsubst TeX-shdex-not (arg)
 2905   "NOT operator for style hook dialect expressions."
 2906    (lognot (TeX-shdex-eval arg)))
 2907 
 2908 (defsubst TeX-shdex-in-p (dialect dialect-set)
 2909   "Test whether dialect DIALECT is in dialect set DIALECT-SET."
 2910   (let ((cell (assq dialect TeX-style-hook-dialect-weight-alist)))
 2911     (if cell
 2912     (/= 0 (logand (cdr cell) dialect-set))
 2913       (error "Invalid dialect %S" dialect))))
 2914 
 2915 (defsubst TeX-shdex-listify (dialect-set)
 2916   "Converts a dialect set DIALECT-SET to a list of all dialect
 2917 comprised in this set, where dialects are symbols"
 2918   (let (ret)
 2919     (dolist (c dialect-set)
 2920       (when (/= 0 (logand (cdr c) dialect-set))
 2921     (push (car c) ret)))
 2922     ret))
 2923 
 2924 (defun TeX-add-style-hook (style hook &optional dialect-expr)
 2925   "Give STYLE yet another HOOK to run.
 2926 
 2927 DIALECT-EXPR serves the purpose of marking the hook to be run only in
 2928 that dicontext.
 2929 
 2930 DIALECT-EXPR may be a single symbol defining the dialect, see
 2931 variable `TeX-style-hook-dialect' for supported dialects.
 2932 
 2933 DIALECT-EXPR can also be an expression like one of the following:
 2934 
 2935 * (or  DIALECT1 DIALECT2 ...)
 2936 * (nor DIALECT1 DIALECT2 ...)
 2937 * (and DIALECT1 DIALECT2 ...)
 2938 * (not DIALECT )
 2939 
 2940 When omitted DIALECT-EXPR is equivalent to `(nor )', ie all
 2941 dialected are allowed."
 2942   (let ((entry (assoc-string style TeX-style-hook-list)))
 2943     (and dialect-expr (setq hook (vector 'TeX-style-hook hook
 2944                      (TeX-shdex-eval dialect-expr))))
 2945     (cond ((null entry)
 2946        ;; New style, add entry.
 2947        (setq TeX-style-hook-list (cons (list style hook)
 2948                        TeX-style-hook-list)))
 2949       ((member hook entry)
 2950        ;; Old style, hook already there, do nothing.
 2951        nil)
 2952       (t
 2953        ;; Old style, new hook.
 2954        (setcdr entry (cons hook (cdr entry)))))))
 2955 
 2956 (defun TeX-keep-hooks-in-dialect (hooks dialect-list)
 2957   "Scan HOOKS for all hooks the associated dialect of which is
 2958 found in DIALECT-LIST and return the list thereof."
 2959   (let (ret dialect-list-1)
 2960     (dolist (hook hooks)
 2961       (setq dialect-list-1 (and (vectorp hook) (eq (aref hook 0) 'TeX-style-hook)
 2962                 (TeX-shdex-listify (aref hook 2))))
 2963       (while dialect-list-1
 2964     (when (memq (pop dialect-list-1) dialect-list)
 2965       (push hook ret)
 2966       (setq dialect-list-1 nil)))
 2967     ret)))
 2968 
 2969 (defun TeX-unload-style (style &optional dialect-list)
 2970   "Forget that we once loaded STYLE. If DIALECT-LIST is provided
 2971 the STYLE is only removed for those dialects in DIALECT-LIST.
 2972 
 2973 See variable `TeX-style-hook-dialect' for supported dialects."
 2974   (let ((style-data (assoc-string style TeX-style-hook-list)))
 2975     (if style-data
 2976     (let ((hooks (and dialect-list (TeX-keep-hooks-in-dialect (cdr style-data) dialect-list))))
 2977       (if hooks
 2978           (setcdr style-data hooks)
 2979         (setq TeX-style-hook-list (delq style-data TeX-style-hook-list)))))))
 2980 
 2981 (defcustom TeX-virgin-style (if (and TeX-auto-global
 2982                      (file-directory-p TeX-auto-global))
 2983                 "virtex"
 2984                   "NoVirtexSymbols")
 2985   "Style all documents use."
 2986   :group 'TeX-parse
 2987   :type 'string)
 2988 
 2989 (defvar TeX-active-styles nil
 2990   "List of styles currently active in the document.")
 2991  (make-variable-buffer-local 'TeX-active-styles)
 2992 
 2993 (defun TeX-run-style-hooks (&rest styles)
 2994   "Run the TeX style hooks STYLES."
 2995   (mapcar (lambda (style)
 2996         ;; Avoid recursion.
 2997         (unless (TeX-member style TeX-active-styles 'string-equal)
 2998           (setq TeX-active-styles
 2999             (cons style TeX-active-styles))
 3000           (TeX-load-style style)
 3001           (let ((default-directory default-directory))
 3002         ;; Complex path.
 3003         (when (string-match "\\`\\(.+[/\\]\\)\\([^/\\]*\\)\\'" style)
 3004           ;; Set `default-directory' to directory of master
 3005           ;; file since style files not stored in the fixed
 3006           ;; style directories are usually located there.
 3007           (setq default-directory (save-match-data
 3008                         (TeX-master-directory))
 3009             style (substring style
 3010                      (match-beginning 2) (match-end 2))))
 3011         (condition-case nil
 3012             (mapcar (lambda (hook)
 3013                   (cond
 3014                    ((functionp hook)
 3015                 (funcall hook))
 3016                    ((and (vectorp hook)
 3017                      (eq (aref hook 0) 'TeX-style-hook))
 3018                 (and (TeX-shdex-in-p TeX-style-hook-dialect (aref hook 2))
 3019                      (funcall (aref hook 1))))
 3020                    (t (error "Invalid style hook %S" hook))))
 3021                 ;; Reverse the list of style hooks in order to run
 3022                 ;; styles in the order global, private, local
 3023                 ;; (assuming TeX-style-path has that ordering,
 3024                 ;; too).
 3025                 (reverse (cdr-safe (assoc-string style TeX-style-hook-list))))
 3026           ;; This happens in case some style added a new parser, and
 3027           ;; now the style isn't used anymore (user deleted
 3028           ;; \usepackage{style}).  Then we're left over with, e.g.,
 3029           ;; (LaTeX-add-siunitx-units "\\parsec"), but the function is
 3030           ;; defined in a style siunitx.el that's not loaded anymore.
 3031           (void-function nil)))))
 3032       styles))
 3033 
 3034 (defcustom TeX-parse-self nil
 3035   "Parse file after loading it if no style hook is found for it."
 3036   :group 'TeX-parse
 3037   :type 'boolean)
 3038 
 3039 (defvar TeX-style-hook-applied-p nil
 3040   "Nil, unless the style specific hooks have been applied.")
 3041  (make-variable-buffer-local 'TeX-style-hook-applied-p)
 3042 
 3043 (defvar TeX-update-style-hook nil
 3044   "Hook run as soon as style specific hooks were applied.")
 3045 
 3046 (defun TeX-update-style (&optional force)
 3047   "Run style specific hooks for the current document.
 3048 
 3049 Only do this if it has not been done before, or if optional argument
 3050 FORCE is not nil."
 3051   (unless (or (and (boundp 'TeX-auto-update)
 3052            (eq TeX-auto-update 'BibTeX)) ; Not a real TeX buffer
 3053           (and (not force)
 3054            TeX-style-hook-applied-p))
 3055     (setq TeX-style-hook-applied-p t)
 3056     (message "Applying style hooks...")
 3057     (TeX-run-style-hooks (TeX-strip-extension nil nil t))
 3058     ;; Run parent style hooks if it has a single parent that isn't itself.
 3059     (if (or (not (memq TeX-master '(nil t)))
 3060         (and (buffer-file-name)
 3061          (string-match TeX-one-master
 3062                    (file-name-nondirectory (buffer-file-name)))))
 3063     (TeX-run-style-hooks (TeX-master-file)))
 3064     (if (and TeX-parse-self
 3065          (null (cdr-safe (assoc (TeX-strip-extension nil nil t)
 3066                     TeX-style-hook-list))))
 3067     (TeX-auto-apply))
 3068     (run-hooks 'TeX-update-style-hook)
 3069     (message "Applying style hooks...done")))
 3070 
 3071 (defvar TeX-remove-style-hook nil
 3072   "List of hooks to call when we remove the style specific information.")
 3073 
 3074 (defun TeX-remove-style ()
 3075   "Remove all style specific information."
 3076   (setq TeX-style-hook-applied-p nil)
 3077   (run-hooks 'TeX-remove-style-hook)
 3078   (setq TeX-active-styles (list TeX-virgin-style)))
 3079 
 3080 (defun TeX-style-list ()
 3081   "Return a list of all styles (subfiles) used by the current document."
 3082   (TeX-update-style)
 3083   TeX-active-styles)
 3084 
 3085 ;;; Special Characters
 3086 
 3087 (defvar TeX-esc "\\" "The TeX escape character.")
 3088  (make-variable-buffer-local 'TeX-esc)
 3089 
 3090 (defvar TeX-grop "{" "The TeX group opening character.")
 3091  (make-variable-buffer-local 'TeX-grop)
 3092 
 3093 (defvar TeX-grcl "}" "The TeX group closing character.")
 3094  (make-variable-buffer-local 'TeX-grcl)
 3095 
 3096 ;;; Symbols
 3097 
 3098 ;; Must be before keymaps.
 3099 
 3100 (defgroup TeX-macro nil
 3101   "Support for TeX macros in AUCTeX."
 3102   :prefix "TeX-"
 3103   :group 'AUCTeX)
 3104 
 3105 (defcustom TeX-complete-word 'ispell-complete-word
 3106   "*Function to call for completing non-macros in `tex-mode'."
 3107   :type 'function
 3108   :group 'TeX-macro)
 3109 
 3110 (defcustom TeX-complete-expert-commands nil
 3111   "Complete macros and environments marked as expert commands.
 3112 
 3113 Possible values are nil, t, or a list of style names.
 3114 
 3115   - nil           Don't complete expert commands (default).
 3116   - t             Always complete expert commands.
 3117   - (STYLES ...)  Only complete expert commands of STYLES."
 3118   :group 'TeX-macro
 3119   :type '(choice (const  :tag "Don't complete expert commands" nil)
 3120          (const  :tag "Always complete expert commands" t)
 3121          (repeat :tag "Complete expert commands of certain styles" string)))
 3122 
 3123 (defmacro TeX-complete-make-expert-command-functions (thing list-var prefix)
 3124   (let* ((plural (concat thing "s"))
 3125      (upcase (upcase thing))
 3126      (upcase-plural (upcase plural)))
 3127     `(progn
 3128        (defvar ,(intern (format "%s-expert-%s-table" prefix thing))
 3129      (make-hash-table :test 'equal)
 3130      ,(format "A hash-table mapping %s names to the style name providing it.
 3131 
 3132 A %s occuring in this table is considered an expert %s and
 3133 treated specially in the completion." thing thing thing))
 3134 
 3135        (defun ,(intern (format "%s-declare-expert-%s" prefix plural)) (style &rest ,(intern plural))
 3136      ,(format "Declare %s as expert %s of STYLE.
 3137 
 3138 Expert %s are completed depending on `TeX-complete-expert-commands'."
 3139           upcase-plural plural plural)
 3140      (dolist (x ,(intern plural))
 3141        (if (null style)
 3142            (remhash x TeX-expert-macro-table)
 3143          (puthash x style TeX-expert-macro-table))))
 3144 
 3145        (defun ,(intern (format "%s-filtered" list-var)) ()
 3146      ,(format "Return (%s) filtered depending on `TeX-complete-expert-commands'."
 3147           list-var)
 3148      (delq nil
 3149            (mapcar
 3150         (lambda (entry)
 3151           (if (eq t TeX-complete-expert-commands)
 3152               entry
 3153             (let* ((cmd (car entry))
 3154                (style (gethash cmd TeX-expert-macro-table)))
 3155               (when (or (null style)
 3156                 (member style TeX-complete-expert-commands))
 3157             entry))))
 3158         (,list-var)))))))
 3159 
 3160 (TeX-complete-make-expert-command-functions "macro" TeX-symbol-list "TeX")
 3161 (TeX-complete-make-expert-command-functions "environment" LaTeX-environment-list "LaTeX")
 3162 
 3163 (defvar TeX-complete-list nil
 3164   "List of ways to complete the preceding text.
 3165 
 3166 Each entry is a list with the following elements:
 3167 
 3168 0. Regexp matching the preceding text or a predicate of arity 0
 3169 which returns non-nil and sets `match-data' appropriately if it
 3170 is applicable.
 3171 1. A number indicating the subgroup in the regexp containing the
 3172 text.
 3173 2. A function returning an alist of possible completions.
 3174 3. Text to append after a succesful completion.
 3175 
 3176 Or alternatively:
 3177 
 3178 0. Regexp matching the preceding text.
 3179 1. Function to do the actual completion.")
 3180 
 3181 (defun TeX--complete-find-entry ()
 3182   "Return the first applicable entry of `TeX-complete-list'."
 3183   (let ((list TeX-complete-list)
 3184     entry)
 3185     (while list
 3186       (setq entry (car list)
 3187         list (cdr list))
 3188       (when (if (functionp (car entry))
 3189         (funcall (car entry))
 3190           (TeX-looking-at-backward (car entry) 250))
 3191     (setq list nil)))
 3192     entry))
 3193 
 3194 (defun TeX-complete-symbol ()
 3195   "Perform completion on TeX/LaTeX symbol preceding point."
 3196   (interactive "*")
 3197   (let ((entry (TeX--complete-find-entry)))
 3198     (when entry
 3199       (if (numberp (nth 1 entry))
 3200       (let* ((sub (nth 1 entry))
 3201          (close (if (and (nth 3 entry)
 3202                                  (listp (nth 3 entry))
 3203                                  (symbolp (car (nth 3 entry))))
 3204                             (eval (nth 3 entry))
 3205                           (nth 3 entry)))
 3206          (begin (match-beginning sub))
 3207          (end (match-end sub))
 3208          (pattern (TeX-match-buffer 0))
 3209          (symbol (buffer-substring begin end))
 3210          (list (funcall (nth 2 entry)))
 3211          (completion (try-completion symbol list))
 3212          (buf-name "*Completions*"))
 3213         (cond ((eq completion t)
 3214            (and close
 3215             (not (looking-at (regexp-quote close)))
 3216             (insert close))
 3217            (let ((window (get-buffer-window buf-name)))
 3218              (when window (delete-window window))))
 3219           ((null completion)
 3220            (error "Can't find completion for \"%s\"" pattern))
 3221           ((not (string-equal symbol completion))
 3222            (delete-region begin end)
 3223            (insert completion)
 3224            (and close
 3225             (eq (try-completion completion list) t)
 3226             (not (looking-at (regexp-quote close)))
 3227             (insert close))
 3228            (let ((window (get-buffer-window buf-name)))
 3229              (when window (delete-window window))))
 3230           (t
 3231            (if (fboundp 'completion-in-region)
 3232                (completion-in-region begin end
 3233                          (all-completions symbol list nil))
 3234              (message "Making completion list...")
 3235              (let ((list (all-completions symbol list nil)))
 3236                (with-output-to-temp-buffer buf-name
 3237              (display-completion-list list)))
 3238              (set-window-dedicated-p (get-buffer-window buf-name) 'soft)
 3239              (message "Making completion list...done")))))
 3240     (funcall (nth 1 entry))))))
 3241 
 3242 (defun TeX--completion-at-point ()
 3243   "(La)TeX completion at point function.
 3244 See `completion-at-point-functions'."
 3245   (let ((entry (TeX--complete-find-entry)))
 3246     (when entry
 3247       (if (numberp (nth 1 entry))
 3248       (let* ((sub (nth 1 entry))
 3249          (begin (match-beginning sub))
 3250          (end (match-end sub))
 3251          (symbol (buffer-substring-no-properties begin end))
 3252          (list (funcall (nth 2 entry))))
 3253         (list begin end (all-completions symbol list)))
 3254     ;; We intentionally don't call the fallback completion functions because
 3255     ;; they do completion on their own and don't work too well with things
 3256     ;; like company-mode.  And the default function `ispell-complete-word'
 3257     ;; isn't so useful anyway.
 3258     nil))))
 3259 
 3260 (defcustom TeX-default-macro "ref"
 3261   "*The default macro when creating new ones with `TeX-insert-macro'."
 3262   :group 'TeX-macro
 3263   :type 'string)
 3264 
 3265 (make-variable-buffer-local 'TeX-default-macro)
 3266 
 3267 (defcustom TeX-insert-braces t
 3268   "*If non-nil, append a empty pair of braces after inserting a macro.
 3269 
 3270 See also `TeX-insert-braces-alist'."
 3271   :group 'TeX-macro
 3272   :type 'boolean)
 3273 
 3274 (defcustom TeX-insert-braces-alist nil
 3275   "Alist of macros to which braces should or should not be appended.
 3276 
 3277 Each element is a cons cell, whose CAR is the macro name, and the
 3278 CDR is non-nil or nil, depending on whether a pair of braces
 3279 should be, respectively, appended or not to the macro.
 3280 
 3281 If a macro has an element in this variable, `TeX-parse-macro'
 3282 will use its value to decide what to do, whatever the value of
 3283 the variable `TeX-insert-braces'."
 3284   :group 'TeX-macro
 3285   :type '(repeat (cons (string :tag "Macro name")
 3286                (boolean :tag "Append braces?"))))
 3287 (make-variable-buffer-local 'TeX-insert-braces-alist)
 3288 
 3289 (defcustom TeX-insert-macro-default-style 'show-optional-args
 3290   "Specifies whether `TeX-insert-macro' will ask for all optional arguments.
 3291 
 3292 If set to the symbol `show-optional-args', `TeX-insert-macro'
 3293 asks for optional arguments of TeX marcos, unless the previous
 3294 optional argument has been rejected.  If set to
 3295 `show-all-optional-args', `TeX-insert-macro' asks for all
 3296 optional arguments.  If set to `mandatory-args-only',
 3297 `TeX-insert-macro' asks only for mandatory argument.
 3298 
 3299 When `TeX-insert-macro' is called with \\[universal-argument], it's the other
 3300 way round.
 3301 
 3302 Note that for some macros, there are special mechanisms, see e.g.
 3303 `LaTeX-includegraphics-options-alist' and `TeX-arg-cite-note-p'."
 3304   :group 'TeX-macro
 3305   :type '(choice (const mandatory-args-only)
 3306          (const show-optional-args)
 3307          (const show-all-optional-args)))
 3308 
 3309 (defvar TeX-arg-opening-brace nil
 3310   "String used as an opening brace for argument insertion.
 3311 The variable will be temporarily let-bound with the necessary value.")
 3312 
 3313 (defvar TeX-arg-closing-brace nil
 3314   "String used as a closing brace for argument insertion.
 3315 The variable will be temporarily let-bound with the necessary value.")
 3316 
 3317 (defvar TeX-after-insert-macro-hook nil
 3318   "A hook run after `TeX-insert-macro'.")
 3319 
 3320 (defvar TeX-macro-history nil)
 3321 
 3322 (defun TeX-insert-macro (symbol)
 3323   "Insert TeX macro SYMBOL with completion.
 3324 
 3325 AUCTeX knows of some macros and may query for extra arguments, depending on
 3326 the value of `TeX-insert-macro-default-style' and whether `TeX-insert-macro'
 3327 is called with \\[universal-argument]."
 3328   ;; When called with a prefix (C-u), only ask for mandatory arguments,
 3329   ;; i.e. all optional arguments are skipped.  See `TeX-parse-arguments' for
 3330   ;; details.  Note that this behavior may be changed in favor of a more
 3331   ;; flexible solution in the future, therefore we don't document it at the
 3332   ;; moment.
 3333   (interactive (list (completing-read (concat "Macro (default "
 3334                           TeX-default-macro
 3335                           "): "
 3336                           TeX-esc)
 3337                       (TeX-symbol-list-filtered) nil nil nil
 3338                       'TeX-macro-history TeX-default-macro)))
 3339   (when (called-interactively-p 'any)
 3340     (setq TeX-default-macro symbol))
 3341   (TeX-parse-macro symbol (cdr-safe (assoc symbol (TeX-symbol-list))))
 3342   (run-hooks 'TeX-after-insert-macro-hook))
 3343 
 3344 (defvar TeX-electric-macro-map
 3345   (let ((map (make-sparse-keymap)))
 3346     (set-keymap-parent map minibuffer-local-completion-map)
 3347     (define-key map " " 'minibuffer-complete-and-exit)
 3348     map))
 3349 
 3350 (defun TeX-electric-macro ()
 3351   "Insert TeX macro with completion.
 3352 
 3353 AUCTeX knows of some macros, and may query for extra arguments.
 3354 Space will complete and exit."
 3355   (interactive)
 3356   (cond ((eq (preceding-char) ?\\)
 3357      (call-interactively 'self-insert-command))
 3358     ((eq (preceding-char) ?.)
 3359      (let ((TeX-default-macro " ")
 3360            (minibuffer-local-completion-map TeX-electric-macro-map))
 3361        (call-interactively 'TeX-insert-macro)))
 3362     (t
 3363      (let ((minibuffer-local-completion-map TeX-electric-macro-map))
 3364        (call-interactively 'TeX-insert-macro)))))
 3365 
 3366 (defun TeX-parse-macro (symbol args)
 3367   "How to parse TeX macros which takes one or more arguments.
 3368 
 3369 First argument SYMBOL is the name of the macro.
 3370 
 3371 If ARGS is nil, insert macro with point inside braces.
 3372 Otherwise, each element in ARGS should match an argument to the
 3373 TeX macro.  What is done depend on the type of the element:
 3374 
 3375   string: Use the string as a prompt to prompt for the argument.
 3376 
 3377   number: Insert that many braces, leave point inside the first.
 3378 
 3379   nil: Insert empty braces.
 3380 
 3381   t: Insert empty braces, leave point between the braces.
 3382 
 3383   other symbols: Call the symbol as a function.  You can define
 3384   your own hook, or use one of the predefined argument hooks.  If
 3385   you add new hooks, you can assume that point is placed directly
 3386   after the previous argument, or after the macro name if this is
 3387   the first argument.  Please leave point located after the
 3388   argument you are inserting.  If you want point to be located
 3389   somewhere else after all hooks have been processed, set the value
 3390   of `exit-mark'.  It will point nowhere, until the argument hook
 3391   set it.  By convention, these hooks all start with `TeX-arg-'.
 3392 
 3393   list: If the car is a string, insert it as a prompt and the next
 3394   element as initial input.  Otherwise, call the car of the list
 3395   with the remaining elements as arguments.
 3396 
 3397   vector: Optional argument.  If it has more than one element,
 3398   parse it as a list, otherwise parse the only element as above.
 3399   Use square brackets instead of curly braces, and is not inserted
 3400   on empty user input."
 3401   (let ((TeX-grop (if (and (or (atom args) (= (length args) 1))
 3402                (fboundp 'LaTeX-verbatim-macros-with-delims)
 3403                (member symbol (LaTeX-verbatim-macros-with-delims)))
 3404               LaTeX-default-verb-delimiter
 3405             TeX-grop))
 3406     (TeX-grcl (if (and (or (atom args) (= (length args) 1))
 3407                (fboundp 'LaTeX-verbatim-macros-with-delims)
 3408                (member symbol (LaTeX-verbatim-macros-with-delims)))
 3409               LaTeX-default-verb-delimiter
 3410             TeX-grcl)))
 3411     (if (and (TeX-active-mark)
 3412          (> (point) (mark)))
 3413     (exchange-point-and-mark))
 3414     (insert TeX-esc symbol)
 3415     (let ((exit-mark (make-marker))
 3416       (position (point)))
 3417       (TeX-parse-arguments args)
 3418       (cond ((marker-position exit-mark)
 3419          (goto-char (marker-position exit-mark))
 3420          (set-marker exit-mark nil))
 3421         ((let ((element (assoc symbol TeX-insert-braces-alist)))
 3422            ;; If in `TeX-insert-braces-alist' there is an element associated
 3423            ;; to the current macro, use its value to decide whether inserting
 3424            ;; a pair of braces, otherwise use the standard criterion.
 3425            (if element
 3426            (cdr element)
 3427          (and TeX-insert-braces
 3428               ;; Do not add braces if the argument is 0 or -1.
 3429               (not (and (= (safe-length args) 1)
 3430                 (numberp (car args))
 3431                 (<= (car args) 0)))
 3432               (equal position (point))
 3433               (string-match "[a-zA-Z]+" symbol))))
 3434          (if (texmathp)
 3435          (when (TeX-active-mark)
 3436            (insert TeX-grop)
 3437            (exchange-point-and-mark)
 3438            (insert TeX-grcl))
 3439            (insert TeX-grop)
 3440            (if (TeX-active-mark)
 3441            (progn
 3442              (exchange-point-and-mark)
 3443              (insert TeX-grcl))
 3444          (insert TeX-grcl)
 3445          (backward-char))))))))
 3446 
 3447 (defun TeX-arg-string (optional &optional prompt initial-input)
 3448   "Prompt for a string.
 3449 
 3450 If OPTIONAL is not nil then the PROMPT will start with ``(Optional) ''.
 3451 INITIAL-INPUT is a string to insert before reading input."
 3452   (TeX-argument-insert
 3453    (if (and (not optional) (TeX-active-mark))
 3454        (let ((TeX-argument (buffer-substring (point) (mark))))
 3455      (delete-region (point) (mark))
 3456      TeX-argument)
 3457      (TeX-read-string (TeX-argument-prompt optional prompt "Text") initial-input))
 3458    optional))
 3459 
 3460 (defun TeX-parse-arguments (args)
 3461   "Parse TeX macro arguments ARGS.
 3462 
 3463 See `TeX-parse-macro' for details."
 3464   (let ((last-optional-rejected nil))
 3465     (while args
 3466       (if (vectorp (car args))
 3467       ;; Maybe get rid of all optional arguments.  See `TeX-insert-macro'
 3468       ;; for more comments.  See `TeX-insert-macro-default-style'.
 3469       ;; The macro `LaTeX-check-insert-macro-default-style' in
 3470       ;; `latex.el' uses the code inside (unless ...)  This macro
 3471       ;; should be adapted if the code here changs.
 3472       (unless (if (eq TeX-insert-macro-default-style 'show-all-optional-args)
 3473               (equal current-prefix-arg '(4))
 3474             (or
 3475              (and (eq TeX-insert-macro-default-style 'show-optional-args)
 3476               (equal current-prefix-arg '(4)))
 3477              (and (eq TeX-insert-macro-default-style 'mandatory-args-only)
 3478               (null (equal current-prefix-arg '(4))))
 3479              last-optional-rejected))
 3480         (let ((TeX-arg-opening-brace LaTeX-optop)
 3481           (TeX-arg-closing-brace LaTeX-optcl))
 3482           (TeX-parse-argument t (if (equal (length (car args)) 1)
 3483                     (aref (car args) 0)
 3484                       (append (car args) nil)))))
 3485     (let ((TeX-arg-opening-brace TeX-grop)
 3486           (TeX-arg-closing-brace TeX-grcl))
 3487       (setq last-optional-rejected nil)
 3488       (TeX-parse-argument nil (car args))))
 3489       (setq args (cdr args)))))
 3490 
 3491 (defun TeX-parse-argument (optional arg)
 3492   "Depending on OPTIONAL, insert TeX macro argument ARG.
 3493 If OPTIONAL is set, only insert if there is anything to insert, and
 3494 then use square brackets instead of curly braces.
 3495 
 3496 See `TeX-parse-macro' for details."
 3497   (let (insert-flag)
 3498     (cond ((stringp arg)
 3499        (TeX-arg-string optional arg)
 3500        (setq insert-flag t))
 3501       ((numberp arg)
 3502        (cond ((< arg 0)
 3503           (when (TeX-active-mark)
 3504             ;; Put both the macro and the marked region in a TeX group.
 3505             (let ((beg (min (point) (mark)))
 3506               (end (set-marker (make-marker) (max (point) (mark)))))
 3507               (insert " ")
 3508               (goto-char beg)
 3509               (skip-chars-backward "^\\\\")
 3510               (backward-char)
 3511               (insert TeX-arg-opening-brace)
 3512               (goto-char (marker-position end))
 3513               (insert TeX-arg-closing-brace)
 3514               (setq insert-flag t))))
 3515          ((= arg 0)) ; nop for clarity
 3516          ((> arg 0)
 3517           (TeX-parse-argument optional t)
 3518           (while (> arg 1)
 3519             (TeX-parse-argument optional nil)
 3520             (setq arg (- arg 1))))))
 3521       ((null arg)
 3522        (insert TeX-arg-opening-brace)
 3523        (when (and (not optional) (TeX-active-mark))
 3524          (exchange-point-and-mark))
 3525        (insert TeX-arg-closing-brace)
 3526        (setq insert-flag t))
 3527       ((eq arg t)
 3528        (insert TeX-arg-opening-brace)
 3529        (if (and (not optional) (TeX-active-mark))
 3530            (progn
 3531          (exchange-point-and-mark))
 3532          (set-marker exit-mark (point)))
 3533        (insert TeX-arg-closing-brace)
 3534        (setq insert-flag t))
 3535       ((symbolp arg)
 3536        (funcall arg optional))
 3537       ((listp arg)
 3538        (let ((head (car arg))
 3539          (tail (cdr arg)))
 3540          (cond ((stringp head)
 3541             (apply 'TeX-arg-string optional arg))
 3542            ((symbolp head)
 3543             (apply head optional tail))
 3544            (t (error "Unknown list argument type %s"
 3545                  (prin1-to-string head))))))
 3546       (t (error "Unknown argument type %s" (prin1-to-string arg))))
 3547     (when (and insert-flag (not optional) (TeX-active-mark))
 3548       (deactivate-mark))))
 3549 
 3550 (defun TeX-argument-insert (name optional &optional prefix)
 3551   "Insert NAME surrounded by curly braces.
 3552 
 3553 If OPTIONAL, only insert it if not empty, and then use square brackets.
 3554 If PREFIX is given, insert it before NAME."
 3555   (if (and optional (string-equal name ""))
 3556       (setq last-optional-rejected t)
 3557     (insert TeX-arg-opening-brace)
 3558     (if prefix
 3559     (insert prefix))
 3560     (if (and (string-equal name "")
 3561          (null (marker-position exit-mark)))
 3562     (set-marker exit-mark (point))
 3563       (insert name))
 3564     (insert TeX-arg-closing-brace)))
 3565 
 3566 (defun TeX-argument-prompt (optional prompt default &optional complete)
 3567   "Return a argument prompt.
 3568 
 3569 If OPTIONAL is not nil then the prompt will start with ``(Optional) ''.
 3570 
 3571 PROMPT will be used if not nil, otherwise use DEFAULT.
 3572 
 3573 Unless optional argument COMPLETE is non-nil, ``: '' will be appended."
 3574   (concat (if optional "(Optional) " "")
 3575       (if prompt prompt default)
 3576       (if complete "" ": ")))
 3577 
 3578 (defun TeX-string-divide-number-unit (string)
 3579   "Divide number and unit in STRING and return a list (number unit)."
 3580   (if (string-match "[0-9]*\\.?[0-9]+" string)
 3581       (list (substring string 0 (string-match "[^.0-9]" string))
 3582         (substring string (if (string-match "[^.0-9]" string)
 3583                   (string-match "[^.0-9]" string)
 3584                 (length string))))
 3585     (list "" string)))
 3586 
 3587 (defcustom TeX-default-unit-for-image "cm"
 3588   "Default unit when prompting for an image size."
 3589   :group 'TeX-macro
 3590   :type '(choice (const "cm")
 3591          (const "in")
 3592          (const "\\linewidth")
 3593          (string :tag "Other")))
 3594 
 3595 (defun TeX-arg-maybe (symbol list form)
 3596   "Evaluates FORM, if SYMBOL is an element of LIST."
 3597   (when (memq symbol list)
 3598     (eval form)))
 3599 
 3600 (defun TeX-arg-free (optional &rest args)
 3601   "Parse its arguments but use no braces when they are inserted."
 3602   (let ((TeX-arg-opening-brace "")
 3603     (TeX-arg-closing-brace ""))
 3604     (if (equal (length args) 1)
 3605     (TeX-parse-argument optional (car args))
 3606       (TeX-parse-argument optional args))))
 3607 
 3608 (defun TeX-arg-literal (optional &rest args)
 3609   "Insert its arguments ARGS into the buffer.
 3610 Used for specifying extra syntax for a macro.  The compatibility
 3611 argument OPTIONAL is ignored."
 3612   (apply 'insert args))
 3613 
 3614 
 3615 ;;; Font Locking
 3616 
 3617 (defcustom TeX-install-font-lock 'font-latex-setup
 3618   "Function to call to install font lock support.
 3619 Choose `ignore' if you don't want AUCTeX to install support for font locking."
 3620   :group 'TeX-misc
 3621   :type '(radio (function-item font-latex-setup)
 3622         (function-item tex-font-setup)
 3623         (function-item ignore)
 3624         (function :tag "Other")))
 3625 
 3626 ;;; The Mode
 3627 
 3628 (defvar TeX-format-list
 3629   '(("JLATEX" japanese-latex-mode
 3630      "\\\\\\(documentstyle\\|documentclass\\)[^%\n]*{u?\\(j[s-]?\\|t\\)\
 3631 \\(article\\|report\\|book\\|slides\\)")
 3632     ("JTEX" japanese-plain-tex-mode
 3633      "-- string likely in Japanese TeX --")
 3634     ("AMSTEX" ams-tex-mode
 3635      "\\\\document\\b")
 3636     ("CONTEXT" context-mode
 3637      "\\\\\\(start\\(text\\|tekst\\|proje[ck]t\\|proiect\\|\
 3638 produ[ck]t\\|produs\\|environment\\|omgeving\\|umgebung\\|prostredi\\|mediu\\|\
 3639 component\\|onderdeel\\|komponent[ea]\\|componenta\\)\
 3640 \\|inizia\\(testo\\|progetto\\|prodotto\\|ambiente\\|componente\\)\
 3641 \\)\\|%.*?interface=")
 3642     ("LATEX" latex-mode
 3643      "\\\\\\(begin\\|\\(?:sub\\)\\{0,2\\}section\\|chapter\\|documentstyle\\|\
 3644 documentclass\\)\\b")
 3645     ("TEX" plain-tex-mode "."))
 3646   "*List of format packages to consider when choosing a TeX mode.
 3647 
 3648 A list with an entry for each format package available at the site.
 3649 
 3650 Each entry is a list with three elements.
 3651 
 3652 1. The name of the format package.
 3653 2. The name of the major mode.
 3654 3. A regexp typically matched in the beginning of the file.
 3655 
 3656 When entering `tex-mode', each regexp is tried in turn in order to find
 3657 the major mode to be used.")
 3658 
 3659 (defcustom TeX-default-mode 'latex-mode
 3660   "*Mode to enter for a new file when it can't be determined otherwise."
 3661   :group 'TeX-misc
 3662   :type '(radio (function-item latex-mode)
 3663         (function-item plain-tex-mode)
 3664         (function :tag "Other")))
 3665 
 3666 (defcustom TeX-force-default-mode nil
 3667   "*If set to nil, try to infer the mode of the file from its content."
 3668   :group 'TeX-misc
 3669   :type 'boolean)
 3670 
 3671 ;;;###autoload
 3672 (defun TeX-tex-mode ()
 3673   "Major mode in AUCTeX for editing TeX or LaTeX files.
 3674 Tries to guess whether this file is for plain TeX or LaTeX.
 3675 
 3676 The algorithm is as follows:
 3677 
 3678    1) if the file is empty or `TeX-force-default-mode' is not set to nil,
 3679       `TeX-default-mode' is chosen
 3680    2) If \\documentstyle or \\begin{, \\section{, \\part{ or \\chapter{ is
 3681       found, `latex-mode' is selected.
 3682    3) Otherwise, use `plain-tex-mode'"
 3683   (interactive)
 3684 
 3685   (funcall (if (or (equal (buffer-size) 0)
 3686            TeX-force-default-mode)
 3687            TeX-default-mode
 3688          (save-excursion
 3689            (goto-char (point-min))
 3690            (let ((comment-start-skip ;Used by TeX-in-comment
 3691               (concat
 3692                "\\(\\(^\\|[^\\\n]\\)\\("
 3693                (regexp-quote TeX-esc)
 3694                (regexp-quote TeX-esc)
 3695                "\\)*\\)\\(%+ *\\)"))
 3696              (entry TeX-format-list)
 3697              answer case-fold-search)
 3698          (while (and entry (not answer))
 3699            (if (re-search-forward (nth 2 (car entry))
 3700                       10000 t)
 3701                (if (not (TeX-in-comment))
 3702                (setq answer (nth 1 (car entry))))
 3703              (setq entry (cdr entry))))
 3704          (if answer
 3705              answer
 3706            TeX-default-mode))))))
 3707 
 3708 (when (and (boundp 'tex--prettify-symbols-alist)
 3709        (boundp 'prettify-symbols-compose-predicate))
 3710   (defun TeX--prettify-symbols-compose-p (start end match)
 3711     (and (tex--prettify-symbols-compose-p start end match)
 3712      (not (let ((face (get-text-property end 'face)))
 3713         (if (consp face)
 3714             (memq 'font-latex-verbatim-face face)
 3715           (eq face 'font-latex-verbatim-face)))))))
 3716 
 3717 (defun VirTeX-common-initialization ()
 3718   "Perform basic initialization."
 3719   (kill-all-local-variables)
 3720   (setq TeX-mode-p t)
 3721   (setq TeX-output-extension (if TeX-PDF-mode "pdf" "dvi"))
 3722   (setq indent-tabs-mode nil)
 3723 
 3724   ;; Ispell support
 3725   (set (make-local-variable 'ispell-parser) 'tex)
 3726   (set (make-local-variable 'ispell-tex-p) t)
 3727 
 3728   ;; Redefine some standard variables
 3729   (make-local-variable 'paragraph-start)
 3730   (make-local-variable 'paragraph-separate)
 3731   (set (make-local-variable 'comment-start) "%")
 3732   (set (make-local-variable 'comment-start-skip)
 3733        (concat
 3734     "\\(\\(^\\|[^\\\n]\\)\\("
 3735     (regexp-quote TeX-esc)
 3736     (regexp-quote TeX-esc)
 3737     "\\)*\\)\\(%+[ \t]*\\)"))
 3738   (set (make-local-variable 'comment-end-skip) "[ \t]*\\(\\s>\\|\n\\)")
 3739   (set (make-local-variable 'comment-use-syntax) t)
 3740   ;; `comment-padding' is defined here as an integer for compatibility
 3741   ;; reasons because older Emacsen could not cope with a string.
 3742   (set (make-local-variable 'comment-padding) 1)
 3743   ;; Removed as commenting in (La)TeX is done with one `%' not two
 3744   ;; (make-local-variable 'comment-add)
 3745   ;; (setq comment-add 1) ;default to `%%' in comment-region
 3746   (set (make-local-variable 'comment-indent-function) 'TeX-comment-indent)
 3747   (set (make-local-variable 'comment-multi-line) nil)
 3748   (make-local-variable 'compile-command)
 3749   (unless (boundp 'compile-command)
 3750     (setq compile-command "make"))
 3751   (set (make-local-variable 'words-include-escapes) nil)
 3752 
 3753   ;; Make TAB stand out
 3754   ;;  (make-local-variable 'buffer-display-table)
 3755   ;;  (setq buffer-display-table (if standard-display-table
 3756   ;;                 (copy-sequence standard-display-table)
 3757   ;;                   (make-display-table)))
 3758   ;;  (aset buffer-display-table ?\t (apply 'vector (append "<TAB>" nil)))
 3759 
 3760   ;; Symbol completion.
 3761   (set (make-local-variable 'TeX-complete-list)
 3762        (list (list "\\\\\\([a-zA-Z]*\\)"
 3763            1 'TeX-symbol-list-filtered
 3764            (if TeX-insert-braces "{}"))
 3765          (list "" TeX-complete-word)))
 3766 
 3767   (funcall TeX-install-font-lock)
 3768 
 3769   ;; We want this to be early in the list, so we do not add it before
 3770   ;; we enter TeX mode the first time.
 3771   (add-hook 'write-file-functions #'TeX-safe-auto-write nil t)
 3772   (set (make-local-variable 'TeX-auto-update) t)
 3773 
 3774   (define-key TeX-mode-map "\C-xng" 'TeX-narrow-to-group)
 3775 
 3776   ;; Minor modes
 3777   (when TeX-source-correlate-mode
 3778     (TeX-source-correlate-mode 1))
 3779 
 3780   ;; Prettify Symbols mode
 3781   (when (fboundp 'TeX--prettify-symbols-compose-p)
 3782     (set (make-local-variable 'prettify-symbols-alist) tex--prettify-symbols-alist)
 3783     (TeX--if-macro-fboundp add-function
 3784     (add-function :override (local 'prettify-symbols-compose-predicate)
 3785               #'TeX--prettify-symbols-compose-p)
 3786       (set (make-local-variable 'prettify-symbols-compose-predicate)
 3787        #'TeX--prettify-symbols-compose-p)))
 3788 
 3789   ;; Standard Emacs completion-at-point support
 3790   (when (boundp 'completion-at-point-functions)
 3791     (add-hook 'completion-at-point-functions
 3792           #'TeX--completion-at-point nil t))
 3793 
 3794   ;; Let `TeX-master-file' be called after a new file was opened and
 3795   ;; call `TeX-update-style' on any file opened.  (The addition to the
 3796   ;; hook has to be made here because its local value will be deleted
 3797   ;; by `kill-all-local-variables' if it is added e.g. in `tex-mode'.)
 3798   ;;
 3799   ;; `TeX-update-style' has to be called before
 3800   ;; `global-font-lock-mode', which may also be specified in
 3801   ;; `find-file-hook', gets called.  Otherwise style-based
 3802   ;; fontification will break (in XEmacs).  That means, `add-hook'
 3803   ;; cannot be called with a non-nil value of the APPEND argument.
 3804   ;;
 3805   ;; `(TeX-master-file nil nil t)' has to be called *before*
 3806   ;; `TeX-update-style' as the latter will call `TeX-master-file'
 3807   ;; without the `ask' bit set.
 3808   (add-hook 'find-file-hook
 3809         (lambda ()
 3810           ;; Check if we are looking at a new or shared file.
 3811           (when (or (not (file-exists-p (buffer-file-name)))
 3812             (eq TeX-master 'shared))
 3813         (TeX-master-file nil nil t))
 3814           (TeX-update-style t)) nil t))
 3815 
 3816 
 3817 ;;; Hilighting
 3818 
 3819 (if (boundp 'hilit-patterns-alist)
 3820     (let ((latex-patterns (cdr-safe (assq 'latex-mode hilit-patterns-alist)))
 3821       (plain-tex-patterns (cdr-safe (assq 'plain-tex-mode
 3822                           hilit-patterns-alist))))
 3823       (if (and latex-patterns plain-tex-patterns)
 3824       (setq hilit-patterns-alist
 3825         (append (list (cons 'ams-tex-mode plain-tex-patterns))
 3826             hilit-patterns-alist)))))
 3827 
 3828 ;;; Parsing
 3829 
 3830 (defgroup TeX-parse nil
 3831   "Parsing TeX files from AUCTeX."
 3832   :group 'AUCTeX)
 3833 
 3834 (defvar TeX-auto-parser '((styles TeX-auto-file TeX-run-style-hooks)))
 3835 ;; Alist of parsed information.
 3836 ;; Each entry is a list with the following elements:
 3837 ;;
 3838 ;; 0. Name of information type.
 3839 ;; 1. Name of temporary variable used when parsing.
 3840 ;; 2. Name of function to add information to add to #3.
 3841 ;; 3. Name of variable holding buffer local information.
 3842 ;; 4. Name of variable indicating that #3 has changed.
 3843 
 3844 
 3845 (defconst TeX-auto-parser-temporary 1)
 3846 (defconst TeX-auto-parser-add 2)
 3847 (defconst TeX-auto-parser-local 3)
 3848 (defconst TeX-auto-parser-change 4)
 3849 
 3850 (defun TeX-auto-add-information (name entries)
 3851   "For NAME in `TeX-auto-parser' add ENTRIES."
 3852   (let* ((entry (assoc name TeX-auto-parser))
 3853      (change (nth TeX-auto-parser-change entry))
 3854      (change-value (symbol-value change))
 3855      (local (nth TeX-auto-parser-local entry))
 3856      (local-value (symbol-value local)))
 3857     (if change-value
 3858     (set local (cons entries local-value))
 3859       (set change t)
 3860       (set local (list entries local-value)))))
 3861 
 3862 (defun TeX-auto-list-information (name)
 3863   "Return information in `TeX-auto-parser' about NAME."
 3864   (TeX-update-style)
 3865   (let* ((entry (assoc name TeX-auto-parser))
 3866      (change (nth TeX-auto-parser-change entry))
 3867      (change-value (symbol-value change))
 3868      (local (nth TeX-auto-parser-local entry)))
 3869     (if (not change-value)
 3870     ()
 3871       (set change nil)
 3872       ;; Sort it
 3873       (message "Sorting %s..." name)
 3874       (set local
 3875        (sort (mapcar 'TeX-listify (apply 'append (symbol-value local)))
 3876          'TeX-car-string-lessp))
 3877       (message "Sorting %s...done" name)
 3878       ;; Make it unique
 3879       (message "Removing duplicates...")
 3880       (let ((entry (symbol-value local)))
 3881     (while (and entry (cdr entry))
 3882       (let ((this (car entry))
 3883         (next (car (cdr entry))))
 3884         (if (not (string-equal (car this) (car next)))
 3885         (setq entry (cdr entry))
 3886           ;; We have two equal symbols.  Use the one with
 3887           ;; most arguments.
 3888           (if (> (length next) (length this))
 3889           (setcdr this (cdr next)))
 3890           (setcdr entry (cdr (cdr entry)))))))
 3891       (message "Removing duplicates...done"))
 3892     (symbol-value local)))
 3893 
 3894 (defmacro TeX-auto-add-type (name prefix &optional plural)
 3895   "Add information about NAME to the parser using PREFIX.
 3896 
 3897 Optional third argument PLURAL is the plural form of NAME.
 3898 By default just add an `s'.
 3899 
 3900 This macro creates a set of variables and functions to maintain a
 3901 separate type of information in the parser."
 3902   (let* ((names (or plural (concat name "s")))
 3903      (tmp (intern (concat prefix "-auto-" name)))
 3904      (add (intern (concat prefix "-add-" names)))
 3905      (local (intern (concat prefix "-" name "-list")))
 3906      (change (intern (concat prefix "-" name "-changed")))
 3907      (vardoc (concat "Information about " names
 3908               " in the current buffer.
 3909 Generated by `TeX-auto-add-type'.")))
 3910     `(progn
 3911        (defvar ,tmp nil ,vardoc)
 3912        (defvar ,local nil ,vardoc)
 3913        (make-variable-buffer-local ',local)
 3914        (defvar ,change nil ,vardoc)
 3915        (make-variable-buffer-local ',change)
 3916        (defun ,add (&rest ,(intern names))
 3917      ,(concat "Add information about " (upcase names)
 3918           " to the current buffer.
 3919 Generated by `TeX-auto-add-type'.")
 3920      (TeX-auto-add-information ,name ,(intern names)))
 3921        (defun ,local ()
 3922      ,(concat "List of " names
 3923           " active in the current buffer.
 3924 Generated by `TeX-auto-add-type'.")
 3925      (TeX-auto-list-information ,name))
 3926        ;; Append new type to `TeX-auto-parser' in order to make `style' type
 3927        ;; always the first.
 3928        (add-to-list 'TeX-auto-parser ',(list name tmp add local change) t)
 3929        (add-hook 'TeX-remove-style-hook
 3930          (lambda ()
 3931            (setq ,local nil))))))
 3932 
 3933 (TeX-auto-add-type "symbol" "TeX")
 3934 
 3935 (defvar TeX-auto-apply-hook nil
 3936   "Hook run when a buffer is parsed and the information is applied.")
 3937 
 3938 (defun TeX-auto-apply ()
 3939   "Parse and apply TeX information in the current buffer."
 3940   (TeX-auto-parse)
 3941   (run-hooks 'TeX-auto-apply-hook)
 3942   (mapcar 'TeX-auto-apply-entry TeX-auto-parser))
 3943 
 3944 (defun TeX-auto-apply-entry (entry)
 3945   "Apply the information in ENTRY in `TeX-auto-parser'."
 3946   (let ((value (symbol-value (nth TeX-auto-parser-temporary entry)))
 3947     (add (nth TeX-auto-parser-add entry)))
 3948     (if value (apply add value))))
 3949 
 3950 (defun TeX-safe-auto-write ()
 3951   "Call `TeX-auto-write' safely."
 3952   (condition-case name
 3953       (and (boundp 'TeX-auto-update)
 3954        TeX-auto-update
 3955        (TeX-auto-write))
 3956     (error nil))
 3957   ;; Continue with the other write file hooks.
 3958   nil)
 3959 
 3960 (defcustom TeX-auto-save nil
 3961   "*Automatically save style information when saving the buffer."
 3962   :group 'TeX-parse
 3963   :type 'boolean)
 3964 
 3965 (defcustom TeX-auto-untabify nil
 3966   "*Automatically untabify when saving the buffer."
 3967   :group 'TeX-parse
 3968   :type 'boolean)
 3969 
 3970 (defun TeX-auto-write ()
 3971   "Save all relevant TeX information from the current buffer."
 3972   (if TeX-auto-untabify
 3973       (untabify (point-min) (point-max)))
 3974   (if (and TeX-auto-save TeX-auto-local)
 3975       (let* ((file (expand-file-name
 3976             (concat
 3977              (file-name-as-directory TeX-auto-local)
 3978              (TeX-strip-extension nil TeX-all-extensions t)
 3979              ".el")
 3980             (TeX-master-directory)))
 3981          (dir (file-name-directory file)))
 3982     ;; Create auto directory if possible.
 3983     (if (not (file-exists-p dir))
 3984         (condition-case name
 3985         (make-directory dir)
 3986           (error nil)))
 3987     (if (file-writable-p file)
 3988         (save-excursion
 3989           (TeX-update-style)
 3990           (TeX-auto-store file))
 3991       (message "Can't write style information.")))))
 3992 
 3993 (defcustom TeX-macro-default (car-safe TeX-macro-private)
 3994   "*Default directory to search for TeX macros."
 3995   :group 'TeX-file
 3996   :type 'directory)
 3997 
 3998 (defcustom TeX-auto-default (car-safe TeX-auto-private)
 3999   "*Default directory to place automatically generated TeX information."
 4000   :group 'TeX-file
 4001   :type 'directory)
 4002 
 4003 (defcustom TeX-ignore-file
 4004   "\\(^\\|[/\\]\\)\\(\\.\\|\\.\\.\\|RCS\\|SCCS\\|CVS\\|babel\\..*\\)$"
 4005   "Regular expression matching file names to ignore.
 4006 
 4007 These files or directories will not be considered when searching for
 4008 TeX files in a directory."
 4009   :group 'TeX-parse
 4010   :type 'regexp)
 4011 
 4012 (defcustom TeX-file-recurse t
 4013   "Whether to search TeX directories recursively.
 4014 nil means do not recurse, a positive integer means go that far deep in the
 4015 directory hierarchy, t means recurse indefinitely."
 4016   :group 'TeX-parse
 4017   :type '(choice (const :tag "On" t)
 4018          (const :tag "Off" nil)
 4019          (integer :tag "Depth" :value 1)))
 4020 
 4021 (defvar TeX-file-extensions)
 4022 (defvar BibTeX-file-extensions)
 4023 (defvar TeX-Biber-file-extensions)
 4024 
 4025 ;;;###autoload
 4026 (defun TeX-auto-generate (tex auto)
 4027   "Generate style file for TEX and store it in AUTO.
 4028 If TEX is a directory, generate style files for all files in the directory."
 4029   (interactive (list (setq TeX-macro-default
 4030                (expand-file-name (read-file-name
 4031                           "TeX file or directory: "
 4032                           TeX-macro-default
 4033                           TeX-macro-default 'confirm)))
 4034              (setq TeX-auto-default
 4035                (expand-file-name (read-file-name
 4036                           "AUTO lisp directory: "
 4037                           TeX-auto-default
 4038                           TeX-auto-default 'confirm)))))
 4039   (cond ((not (file-readable-p tex)))
 4040     ((string-match TeX-ignore-file tex))
 4041     ((file-directory-p tex)
 4042      (let ((files (directory-files (expand-file-name tex)))
 4043            (default-directory (file-name-as-directory
 4044                    (expand-file-name tex)))
 4045            (TeX-file-recurse (cond ((symbolp TeX-file-recurse)
 4046                     TeX-file-recurse)
 4047                        ((zerop TeX-file-recurse)
 4048                     nil)
 4049                        ((1- TeX-file-recurse)))))
 4050        (mapcar (lambda (file)
 4051              (if (or TeX-file-recurse
 4052                  (not (file-directory-p file)))
 4053              (TeX-auto-generate file auto)))
 4054            files)))
 4055     ((not (file-newer-than-file-p
 4056            tex
 4057            (concat (file-name-as-directory auto)
 4058                (TeX-strip-extension tex TeX-all-extensions t)
 4059                ".el"))))
 4060     ((TeX-match-extension tex (TeX-delete-duplicate-strings
 4061                    (append TeX-file-extensions
 4062                        BibTeX-file-extensions
 4063                        TeX-Biber-file-extensions)))
 4064      (with-current-buffer (let (enable-local-eval)
 4065                 (find-file-noselect tex))
 4066        (message "Parsing %s..." tex)
 4067        (TeX-auto-store (concat (file-name-as-directory auto)
 4068                    (TeX-strip-extension tex
 4069                             TeX-all-extensions
 4070                             t)
 4071                    ".el"))
 4072        (kill-buffer (current-buffer))
 4073        (message "Parsing %s...done" tex)))))
 4074 
 4075 ;;;###autoload
 4076 (defun TeX-auto-generate-global ()
 4077   "Create global auto directory for global TeX macro definitions."
 4078   (interactive)
 4079   (unless (file-directory-p TeX-auto-global)
 4080     (make-directory TeX-auto-global))
 4081   (let ((TeX-file-extensions '("cls" "sty"))
 4082     (BibTeX-file-extensions nil)
 4083     (TeX-Biber-file-extensions nil))
 4084     (mapc (lambda (macro) (TeX-auto-generate macro TeX-auto-global))
 4085       TeX-macro-global))
 4086   (byte-recompile-directory TeX-auto-global 0))
 4087 
 4088 (defun TeX-auto-store (file)
 4089   "Extract information for AUCTeX from current buffer and store it in FILE."
 4090   (TeX-auto-parse)
 4091 
 4092   (if (member nil (mapcar 'TeX-auto-entry-clear-p TeX-auto-parser))
 4093       (let ((style (TeX-strip-extension nil TeX-all-extensions t))
 4094         (class-opts (if (boundp 'LaTeX-provided-class-options)
 4095                 LaTeX-provided-class-options))
 4096         (pkg-opts (if (boundp 'LaTeX-provided-package-options)
 4097               LaTeX-provided-package-options))
 4098         (tex-cmd-opts TeX-command-extra-options)
 4099         (verb-envs (when (boundp 'LaTeX-verbatim-environments-local)
 4100              LaTeX-verbatim-environments-local))
 4101         (verb-macros-delims (when (boundp 'LaTeX-verbatim-macros-with-delims-local)
 4102                   LaTeX-verbatim-macros-with-delims-local))
 4103         (verb-macros-braces (when (boundp 'LaTeX-verbatim-macros-with-braces-local)
 4104                   LaTeX-verbatim-macros-with-braces-local))
 4105         (dialect TeX-style-hook-dialect))
 4106     (TeX-unload-style style)
 4107     (with-current-buffer (generate-new-buffer file)
 4108       (erase-buffer)
 4109       (insert "(TeX-add-style-hook\n \""
 4110           style "\"\n (lambda ()")
 4111       (unless (string= tex-cmd-opts "")
 4112         (insert "\n   (setq TeX-command-extra-options\n"
 4113             "         " (prin1-to-string tex-cmd-opts) ")"))
 4114       (when class-opts
 4115         (insert "\n   (TeX-add-to-alist 'LaTeX-provided-class-options\n"
 4116             "                     '" (prin1-to-string class-opts) ")"))
 4117       (when pkg-opts
 4118         (insert "\n   (TeX-add-to-alist 'LaTeX-provided-package-options\n"
 4119             "                     '" (prin1-to-string pkg-opts) ")"))
 4120       (dolist (env verb-envs)
 4121         (insert
 4122          (format "\n   (add-to-list 'LaTeX-verbatim-environments-local \"%s\")"
 4123              env)))
 4124       (dolist (env verb-macros-braces)
 4125         (insert
 4126          (format "\n   (add-to-list 'LaTeX-verbatim-macros-with-braces-local \"%s\")"
 4127              env)))
 4128       (dolist (env verb-macros-delims)
 4129         (insert
 4130          (format "\n   (add-to-list 'LaTeX-verbatim-macros-with-delims-local \"%s\")"
 4131              env)))
 4132       (mapc (lambda (el) (TeX-auto-insert el style))
 4133         TeX-auto-parser)
 4134       (insert ")")
 4135       (if dialect (insert (concat "\n " (prin1-to-string dialect))))
 4136       (insert ")\n\n")
 4137       (write-region (point-min) (point-max) file nil 'silent)
 4138       (kill-buffer (current-buffer))))
 4139     (if (file-exists-p (concat file "c"))
 4140     (delete-file (concat file "c")))
 4141     (if (file-exists-p file)
 4142     (delete-file file))))
 4143 
 4144 (defun TeX-auto-entry-clear-p (entry)
 4145   "Check if the temporary for `TeX-auto-parser' entry ENTRY is clear."
 4146   ;; FIXME: This doc-string isn't clear to me.  -- rs
 4147   (null (symbol-value (nth TeX-auto-parser-temporary entry))))
 4148 
 4149 (defun TeX-auto-insert (entry &optional skip)
 4150   "Insert code to initialize ENTRY from `TeX-auto-parser'.
 4151 
 4152 If SKIP is not-nil, don't insert code for SKIP."
 4153   (let ((name (symbol-name (nth TeX-auto-parser-add entry)))
 4154     (list (symbol-value (nth TeX-auto-parser-temporary entry))))
 4155     (unless (null list)
 4156       (insert "\n   (" name)
 4157       (dolist (el list)
 4158     (cond ((and (stringp el) (not (string= el skip)))
 4159            (insert "\n    ")
 4160            (insert (prin1-to-string el)))
 4161           ((not (stringp el))
 4162            (insert "\n    ")
 4163            (insert "'" (prin1-to-string el)))))
 4164       (insert ")"))))
 4165 
 4166 (defvar TeX-auto-ignore
 4167   '("csname" "filedate" "fileversion" "docdate" "next" "labelitemi"
 4168     "labelitemii" "labelitemiii" "labelitemiv" "labelitemv"
 4169     "labelenumi" "labelenumii" "labelenumiii" "labelenumiv"
 4170     "labelenumv" "theenumi" "theenumii" "theenumiii" "theenumiv"
 4171     "theenumv" "document" "par" "do" "expandafter")
 4172   "List of symbols to ignore when scanning a TeX style file.")
 4173 
 4174 (defcustom TeX-auto-regexp-list 'TeX-auto-full-regexp-list
 4175   "List of regular expressions used for parsing the current file."
 4176   :type '(radio (variable-item TeX-auto-empty-regexp-list)
 4177         (variable-item TeX-auto-full-regexp-list)
 4178         (variable-item plain-TeX-auto-regexp-list)
 4179         (variable-item LaTeX-auto-minimal-regexp-list)
 4180         (variable-item LaTeX-auto-label-regexp-list)
 4181         (variable-item LaTeX-auto-regexp-list)
 4182         (symbol :tag "Other")
 4183         (repeat :tag "Specify"
 4184             (group (regexp :tag "Match")
 4185                    (sexp :tag "Groups")
 4186                    symbol)))
 4187   :group 'TeX-parse)
 4188   (make-variable-buffer-local 'TeX-auto-regexp-list)
 4189 
 4190 (defun TeX-auto-add-regexp (regexp)
 4191   "Add REGEXP to `TeX-auto-regexp-list' if not already a member."
 4192   (if (symbolp TeX-auto-regexp-list)
 4193       (setq TeX-auto-regexp-list (symbol-value TeX-auto-regexp-list)))
 4194   (or (memq regexp TeX-auto-regexp-list)
 4195       (setq TeX-auto-regexp-list (cons regexp TeX-auto-regexp-list))))
 4196 
 4197 (defvar TeX-auto-empty-regexp-list
 4198   '(("<IMPOSSIBLE>\\(\\'\\`\\)" 1 ignore))
 4199   "List of regular expressions guaranteed to match nothing.")
 4200 
 4201 (defvar TeX-token-char
 4202   (if (featurep 'mule)
 4203       "\\(?:[a-zA-Z]\\|\\cj\\)"
 4204     "[a-zA-Z]")
 4205   "Regexp matching a character in a TeX macro.
 4206 
 4207 Please use a shy group if you use a grouping construct, because
 4208 the functions/variables which use `TeX-token-char' expect not to
 4209 alter the numbering of any ordinary, non-shy groups.")
 4210 
 4211 (defvar plain-TeX-auto-regexp-list
 4212   (let ((token TeX-token-char))
 4213     `((,(concat "\\\\def\\\\\\(" token "+\\)[^a-zA-Z@]")
 4214        1 TeX-auto-symbol-check)
 4215       (,(concat "\\\\let\\\\\\(" token "+\\)[^a-zA-Z@]")
 4216        1 TeX-auto-symbol-check)
 4217       (,(concat "\\\\font\\\\\\(" token "+\\)[^a-zA-Z@]") 1 TeX-auto-symbol)
 4218       (,(concat "\\\\chardef\\\\\\(" token "+\\)[^a-zA-Z@]") 1 TeX-auto-symbol)
 4219       (,(concat "\\\\new\\(?:count\\|dimen\\|muskip\\|skip\\)\\\\\\(" token
 4220         "+\\)[^a-zA-Z@]")
 4221        1 TeX-auto-symbol)
 4222       (,(concat "\\\\newfont{?\\\\\\(" token "+\\)}?") 1 TeX-auto-symbol)
 4223       (,(concat "\\\\typein\\[\\\\\\(" token "+\\)\\]") 1 TeX-auto-symbol)
 4224       ("\\\\input +\\(\\.*[^#%\\\\\\.\n\r]+\\)\\(\\.[^#%\\\\\\.\n\r]+\\)?"
 4225        1 TeX-auto-file)
 4226       (,(concat "\\\\mathchardef\\\\\\(" token "+\\)[^a-zA-Z@]")
 4227        1 TeX-auto-symbol)))
 4228   "List of regular expression matching common plain TeX macro definitions.")
 4229 
 4230 (defvar TeX-auto-full-regexp-list plain-TeX-auto-regexp-list
 4231   "Full list of regular expression matching TeX macro definitions.")
 4232 
 4233 (defvar TeX-auto-prepare-hook nil
 4234   "List of hooks to be called before parsing a TeX file.")
 4235 
 4236 (defvar TeX-auto-cleanup-hook nil
 4237   "List of hooks to be called after parsing a TeX file.")
 4238 
 4239 (defcustom TeX-auto-parse-length 999999
 4240   "Maximal length of TeX file (in characters) that will be parsed."
 4241   :group 'TeX-parse
 4242   :type 'integer)
 4243   (make-variable-buffer-local 'TeX-auto-parse-length)
 4244 
 4245 (defcustom TeX-auto-x-parse-length 0
 4246   "Maximum length of TeX file that will be parsed additionally.
 4247 Use `TeX-auto-x-regexp-list' for parsing the region between
 4248 `TeX-auto-parse-length' and this value."
 4249   :group 'TeX-parse
 4250   :type 'integer)
 4251   (make-variable-buffer-local 'TeX-auto-x-parse-length)
 4252 
 4253 (defcustom TeX-auto-x-regexp-list 'LaTeX-auto-label-regexp-list
 4254   "List of regular expressions used for additional parsing.
 4255 See `TeX-auto-x-parse-length'."
 4256   :type '(radio (variable-item TeX-auto-empty-regexp-list)
 4257         (variable-item TeX-auto-full-regexp-list)
 4258         (variable-item plain-TeX-auto-regexp-list)
 4259         (variable-item LaTeX-auto-minimal-regexp-list)
 4260         (variable-item LaTeX-auto-label-regexp-list)
 4261         (variable-item LaTeX-auto-regexp-list)
 4262         (symbol :tag "Other")
 4263         (repeat :tag "Specify"
 4264             (group (regexp :tag "Match")
 4265                    (sexp :tag "Groups")
 4266                    symbol)))
 4267   :group 'TeX-parse)
 4268   (make-variable-buffer-local 'TeX-auto-x-regexp-list)
 4269 
 4270 (defun TeX-regexp-group-count (regexp)
 4271   "Return number of groups in a REGEXP.  This is not foolproof:
 4272 you should not use something like `[\\(]' for a character range."
 4273   (let (start (n 0))
 4274     (while (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\([^?]"
 4275              regexp start)
 4276       (setq start (- (match-end 0) 2)
 4277         n (1+ n)))
 4278     n))
 4279 
 4280 (defun TeX-auto-parse-region (regexp-list beg end)
 4281   "Parse TeX information according to REGEXP-LIST between BEG and END."
 4282   (if (symbolp regexp-list)
 4283       (setq regexp-list (and (boundp regexp-list) (symbol-value regexp-list))))
 4284   (if regexp-list
 4285       ;; Extract the information.
 4286       (let* (groups
 4287          (count 1)
 4288          (regexp (concat "\\("
 4289                  (mapconcat
 4290                   (lambda(x)
 4291                 (push (cons count x) groups)
 4292                 (setq count
 4293                       (+ 1 count
 4294                      (TeX-regexp-group-count (car x))))
 4295                 (car x))
 4296                   regexp-list "\\)\\|\\(")
 4297                  "\\)"))
 4298          syms
 4299          lst)
 4300     (setq count 0)
 4301     (goto-char (if end (min end (point-max)) (point-max)))
 4302     (while (re-search-backward regexp beg t)
 4303       (let* ((entry (cdr (TeX-member nil groups
 4304                      (lambda (a b)
 4305                        (match-beginning (car b))))))
 4306          (symbol (nth 2 entry))
 4307          (match (nth 1 entry)))
 4308         (unless (TeX-in-comment)
 4309           (looking-at (nth 0 entry))
 4310           (if (fboundp symbol)
 4311           (funcall symbol match)
 4312         (puthash (if (listp match)
 4313                  (mapcar #'TeX-match-buffer match)
 4314                (TeX-match-buffer match))
 4315              (setq count (1- count))
 4316              (cdr (or (assq symbol syms)
 4317                   (car (push
 4318                     (cons symbol
 4319                           (make-hash-table :test 'equal))
 4320                     syms)))))))))
 4321     (setq count 0)
 4322     (dolist (symbol syms)
 4323       (setq lst (symbol-value (car symbol)))
 4324       (while lst
 4325         (puthash (pop lst)
 4326              (setq count (1+ count))
 4327              (cdr symbol)))
 4328       (maphash (lambda (key value)
 4329              (push (cons value key) lst))
 4330            (cdr symbol))
 4331       (clrhash (cdr symbol))
 4332       (set (car symbol) (mapcar #'cdr (sort lst #'car-less-than-car)))))))
 4333 
 4334 (defun TeX-auto-parse ()
 4335   "Parse TeX information in current buffer.
 4336 
 4337 Call the functions in `TeX-auto-prepare-hook' before parsing, and the
 4338 functions in `TeX-auto-cleanup-hook' after parsing."
 4339 
 4340   (let ((case-fold-search nil))
 4341 
 4342     (mapc 'TeX-auto-clear-entry TeX-auto-parser)
 4343     (run-hooks 'TeX-auto-prepare-hook)
 4344 
 4345     (save-excursion
 4346       (and (> TeX-auto-x-parse-length TeX-auto-parse-length)
 4347        (> (point-max) TeX-auto-parse-length)
 4348        (TeX-auto-parse-region TeX-auto-x-regexp-list
 4349                   TeX-auto-parse-length
 4350                   TeX-auto-x-parse-length))
 4351       (TeX-auto-parse-region TeX-auto-regexp-list
 4352                  nil TeX-auto-parse-length))
 4353 
 4354     ;; Cleanup ignored symbols.
 4355 
 4356     ;; NOTE: This is O(N M) where it could be O(N log N + M log M) if we
 4357     ;; sorted the lists first.
 4358     (while (member (car TeX-auto-symbol) TeX-auto-ignore)
 4359       (setq TeX-auto-symbol (cdr TeX-auto-symbol)))
 4360     (let ((list TeX-auto-symbol))
 4361       (while (and list (cdr list))
 4362     (if (member (car (cdr list)) TeX-auto-ignore)
 4363         (setcdr list (cdr (cdr list)))
 4364       (setq list (cdr list)))))
 4365 
 4366     (run-hooks 'TeX-auto-cleanup-hook)))
 4367 
 4368 (defun TeX-auto-clear-entry (entry)
 4369   "Set the temporary variable in ENTRY to nil."
 4370   (set (nth TeX-auto-parser-temporary entry) nil))
 4371 
 4372 (defvar LaTeX-auto-end-symbol nil)
 4373 
 4374 (defun TeX-auto-symbol-check (match)
 4375   "Add MATCH to TeX-auto-symbols.
 4376 Check for potential LaTeX environments."
 4377   (let ((symbol (if (listp match)
 4378             (mapcar 'TeX-match-buffer match)
 4379           (TeX-match-buffer match))))
 4380     (if (and (stringp symbol)
 4381          (string-match "^end\\(.+\\)$" symbol))
 4382     (add-to-list 'LaTeX-auto-end-symbol
 4383              (substring symbol (match-beginning 1) (match-end 1)))
 4384       (if (listp symbol)
 4385       (dolist (elt symbol)
 4386         (add-to-list 'TeX-auto-symbol elt))
 4387     (add-to-list 'TeX-auto-symbol symbol)))))
 4388 
 4389 
 4390 ;;; File Extensions
 4391 
 4392 (defgroup TeX-file-extension nil
 4393   "File extensions recognized by AUCTeX."
 4394   :group 'TeX-file)
 4395 
 4396 (defcustom TeX-file-extensions '("tex" "sty" "cls" "ltx" "texi" "txi" "texinfo" "dtx")
 4397   "*File extensions used by manually generated TeX files."
 4398   :group 'TeX-file-extension
 4399   :type '(repeat (regexp :format "%v")))
 4400 
 4401 (defcustom TeX-all-extensions '("[^.\n]+")
 4402   "All possible file extensions."
 4403   :group 'TeX-file-extension
 4404   :type '(repeat (regexp :format "%v")))
 4405 
 4406 (defcustom TeX-default-extension "tex"
 4407   "*Default extension for TeX files."
 4408   :group 'TeX-file-extension
 4409   :type 'string)
 4410 
 4411   (make-variable-buffer-local 'TeX-default-extension)
 4412 
 4413 (defvar TeX-doc-extensions
 4414   '("dvi" "pdf" "ps" "txt" "html" "dvi\\.gz" "pdf\\.gz" "ps\\.gz" "txt\\.gz"
 4415     "html\\.gz" "dvi\\.bz2" "pdf\\.bz2" "ps\\.bz2" "txt\\.bz2" "html\\.bz2")
 4416   "File extensions of documentation files.")
 4417 
 4418 (defcustom docTeX-default-extension "dtx"
 4419   "*Default extension for docTeX files."
 4420   :group 'TeX-file-extension
 4421   :type 'string)
 4422 
 4423 (defvar TeX-output-extension nil
 4424   "Extension of TeX output file.
 4425 This is either a string or a list with
 4426 a string as element.  Its value is obtained from `TeX-command-output-list'.
 4427 Access to the value should be through the function `TeX-output-extension'.")
 4428 
 4429   (make-variable-buffer-local 'TeX-output-extension)
 4430 
 4431 (defcustom TeX-Biber-file-extensions '("bib" "ris" "xml")
 4432   "Valid file extensions for Biber files."
 4433   :group 'TeX-file-extension
 4434   :type '(repeat (regexp :format "%v")))
 4435 
 4436 (defcustom BibTeX-file-extensions '("bib")
 4437   "Valid file extensions for BibTeX files."
 4438   :group 'TeX-file-extension
 4439   :type '(repeat (regexp :format "%v")))
 4440 
 4441 (defcustom BibLaTeX-style-extensions '("bbx")
 4442   "Valid file extensions for BibLaTeX styles."
 4443   :group 'TeX-file-extension
 4444   :type '(repeat (regexp :format "%v")))
 4445 
 4446 (defcustom BibTeX-style-extensions '("bst")
 4447   "Valid file extensions for BibTeX styles."
 4448   :group 'TeX-file-extension
 4449   :type '(repeat (regexp :format "%v")))
 4450 
 4451 (defun TeX-match-extension (file &optional extensions)
 4452   "Return non-nil if FILE has one of EXTENSIONS.
 4453 
 4454 If EXTENSIONS is not specified or nil, the value of
 4455 `TeX-file-extensions' is used instead."
 4456 
 4457   (if (null extensions)
 4458       (setq extensions TeX-file-extensions))
 4459 
 4460   (let ((regexp (concat "\\.\\("
 4461             (mapconcat 'identity extensions "\\|")
 4462             "\\)$"))
 4463     (case-fold-search t))
 4464     (string-match regexp file)))
 4465 
 4466 (defun TeX-strip-extension (&optional string extensions nodir nostrip)
 4467   "Return STRING without any trailing extension in EXTENSIONS.
 4468 If NODIR is t, also remove directory part of STRING.
 4469 If NODIR is `path', remove directory part of STRING if it is equal to
 4470 the current directory, `TeX-macro-private' or `TeX-macro-global'.
 4471 If NOSTRIP is set, do not remove extension after all.
 4472 STRING defaults to the name of the current buffer.
 4473 EXTENSIONS defaults to `TeX-file-extensions'."
 4474 
 4475   (if (null string)
 4476       (setq string (or (buffer-file-name) "<none>")))
 4477 
 4478   (if (null extensions)
 4479       (setq extensions TeX-file-extensions))
 4480 
 4481   (let* ((strip (if (and (not nostrip)
 4482              (TeX-match-extension string extensions))
 4483             (substring string 0 (match-beginning 0))
 4484           string))
 4485      (dir (expand-file-name (or (file-name-directory strip) "./"))))
 4486     (if (or (eq nodir t)
 4487         (string-equal dir (expand-file-name "./"))
 4488         (member dir TeX-macro-global)
 4489         (member dir TeX-macro-private))
 4490     (file-name-nondirectory strip)
 4491       strip)))
 4492 
 4493 
 4494 ;;; File Searching
 4495 
 4496 (defun TeX-tree-roots ()
 4497   "Return a list of available TeX tree roots."
 4498   (let (list)
 4499     (dolist (dir (TeX-tree-expand '("$TEXMFHOME" "$TEXMFMAIN" "$TEXMFLOCAL"
 4500                     "$TEXMFDIST")
 4501                                   "latex"))
 4502       (when (file-readable-p dir)
 4503         (cl-pushnew dir list :test #'equal)))
 4504     (nreverse list)))
 4505 
 4506 (defcustom TeX-tree-roots (TeX-tree-roots)
 4507   "List of all available TeX tree root directories."
 4508   :group 'TeX-file
 4509   :type '(repeat directory))
 4510 
 4511 ;; We keep this function in addition to `TeX-search-files' because it
 4512 ;; is faster.  Since it does not look further into subdirectories,
 4513 ;; this comes at the price of finding a smaller number of files.
 4514 (defun TeX-search-files-kpathsea (var extensions scope nodir strip)
 4515   "Return a list of files in directories determined by expanding VAR.
 4516 Only files which match EXTENSIONS are returned.  SCOPE defines
 4517 the scope for the search and can be `local' or `global' besides
 4518 nil.  If NODIR is non-nil, remove directory part.  If STRIP is
 4519 non-nil, remove file extension."
 4520   (when TeX-kpathsea-path-delimiter
 4521     (let ((dirs (if (eq scope 'local)
 4522             '("./")
 4523           (TeX-tree-expand (list var) nil)))
 4524       result)
 4525       (if (eq scope 'global)
 4526       (setq dirs (delete "./" dirs)))
 4527       (setq extensions (concat "\\.\\(?:"
 4528                    (mapconcat #'identity extensions "\\|")
 4529                    "\\)\\'")
 4530         result (apply #'append (mapcar (lambda (x)
 4531                          (when (file-readable-p x)
 4532                            (directory-files
 4533                         x (not nodir) extensions t)))
 4534                        dirs)))
 4535       (if strip
 4536       (mapcar (lambda (x)
 4537             (if (string-match extensions x)
 4538             (substring x 0 (match-beginning 0))
 4539               x))
 4540           result)
 4541     result))))
 4542 
 4543 (defun TeX-search-files (&optional directories extensions nodir strip)
 4544   "Return a list of all reachable files in DIRECTORIES ending with EXTENSIONS.
 4545 If optional argument NODIR is set, remove directory part.
 4546 If optional argument STRIP is set, remove file extension.
 4547 If optional argument DIRECTORIES is set, search in those directories.
 4548 Otherwise, search in all TeX macro directories.
 4549 If optional argument EXTENSIONS is not set, use `TeX-file-extensions'"
 4550   (when (null extensions)
 4551     (setq extensions TeX-file-extensions))
 4552   (when (null directories)
 4553     (setq directories (cons "./" (append TeX-macro-private TeX-macro-global))))
 4554   (let (match
 4555     (TeX-file-recurse (cond ((symbolp TeX-file-recurse)
 4556                  TeX-file-recurse)
 4557                 ((zerop TeX-file-recurse)
 4558                  nil)
 4559                 ((1- TeX-file-recurse)))))
 4560     (while directories
 4561       (let* ((directory (car directories))
 4562          (content (and directory
 4563                (file-readable-p directory)
 4564                (file-directory-p directory)
 4565                (directory-files directory))))
 4566     (setq directories (cdr directories))
 4567     (while content
 4568       (let ((file (concat directory (car content))))
 4569         (setq content (cdr content))
 4570         (cond ((string-match TeX-ignore-file file))
 4571           ((not (file-readable-p file)))
 4572           ((file-directory-p file)
 4573            (if TeX-file-recurse
 4574                (setq match
 4575                  (append match
 4576                      (TeX-search-files
 4577                       (list (file-name-as-directory file))
 4578                       extensions nodir strip)))))
 4579           ((TeX-match-extension file extensions)
 4580            (setq match (cons (TeX-strip-extension
 4581                       file extensions nodir (not strip))
 4582                      match))))))))
 4583     match))
 4584 
 4585 ;; The variables `TeX-macro-private' and `TeX-macro-global' are not
 4586 ;; used for specifying the directories because the number of
 4587 ;; directories to be searched should be limited as much as possible
 4588 ;; and the TeX-macro-* variables are just too broad for this.
 4589 (defvar TeX-search-files-type-alist
 4590   '((texinputs "${TEXINPUTS}" ("tex/") TeX-file-extensions)
 4591     (docs "${TEXDOCS}" ("doc/") TeX-doc-extensions)
 4592     (bibinputs "${BIBINPUTS}" ("bibtex/bib/") BibTeX-file-extensions)
 4593     (bstinputs "${BSTINPUTS}" ("bibtex/bst/") BibTeX-style-extensions))
 4594   "Alist of filetypes with locations and file extensions.
 4595 Each element of the alist consists of a symbol expressing the
 4596 filetype, a variable which can be expanded on kpathsea-based
 4597 systems into the directories where files of the given type
 4598 reside, a list of absolute directories, relative directories
 4599 below the root of a TDS-compliant TeX tree or a list of variables
 4600 with either type of directories as an alternative for
 4601 non-kpathsea-based systems and a list of extensions to be matched
 4602 upon a file search.  Note that the directories have to end with a
 4603 directory separator.
 4604 
 4605 Each AUCTeX mode should set the variable buffer-locally with a
 4606 more specific value.  See `LaTeX-search-files-type-alist' for an
 4607 example.")
 4608 
 4609 (defun TeX-search-files-by-type (filetype &optional scope nodir strip)
 4610   "Return a list of files in TeX's search path with type FILETYPE.
 4611 FILETYPE is a symbol used to choose the search paths and
 4612 extensions.  See `TeX-search-files-type-alist' for supported
 4613 symbols.
 4614 
 4615 The optional argument SCOPE sets the scope for the search.
 4616 Besides nil the symbols `local' and `global' are accepted.
 4617 `local' means to search in the current directory only, `global'
 4618 in the global directories only and nil in both.
 4619 
 4620 If optional argument NODIR is non-nil, remove directory part.
 4621 
 4622 If optional argument STRIP is non-nil, remove file extension."
 4623   (let* ((gc-cons-threshold 10000000)
 4624      (spec (assq filetype TeX-search-files-type-alist))
 4625      (kpse-var (nth 1 spec))
 4626      (rawdirs (nth 2 spec))
 4627      (exts (nth 3 spec))
 4628      expdirs dirs local-files)
 4629     (setq exts (if (symbolp exts) (eval exts) exts))
 4630     (or (TeX-search-files-kpathsea kpse-var exts scope nodir strip)
 4631     (progn
 4632       (unless (eq scope 'global)
 4633         (setq local-files
 4634           (let ((TeX-file-recurse nil))
 4635             (TeX-search-files '("./") exts nodir strip))))
 4636       (if (eq scope 'local)
 4637           local-files
 4638         (if (null TeX-tree-roots)
 4639         (error "No TeX trees available; configure `TeX-tree-roots'")
 4640           ;; Expand variables.
 4641               (setq expdirs
 4642             ;; Don't use `delete-dups' instead of
 4643             ;; `TeX-delete-duplicate-strings' here.
 4644             ;; Otherwise, when the last element of `rawdirs'
 4645             ;; is a variable, its value might be truncated as
 4646             ;; side effect.
 4647                     (TeX-delete-duplicate-strings
 4648                      (apply #'append
 4649                             (mapcar (lambda (rawdir)
 4650                                       (if (symbolp rawdir)
 4651                                           (symbol-value rawdir)
 4652                                         (list rawdir)))
 4653                                     rawdirs))))
 4654           ;; Assumption: Either all paths are absolute or all are relative.
 4655           (if (file-name-absolute-p (car expdirs))
 4656           (setq dirs expdirs)
 4657         ;; Append relative TDS subdirs to all TeX tree roots.
 4658         (dolist (root TeX-tree-roots)
 4659           (dolist (dir expdirs)
 4660                     (let ((dir (expand-file-name dir root)))
 4661                       (unless (member dir dirs)
 4662                         (setq dirs (append dirs (list dir)))))))))
 4663         (append local-files (TeX-search-files dirs exts nodir strip)))))))
 4664 
 4665 ;;; Narrowing
 4666 
 4667 (defun TeX-narrow-to-group ()
 4668   "Make text outside current group invisible."
 4669   (interactive)
 4670   (save-excursion
 4671     (widen)
 4672     (let ((opoint (point))
 4673       beg end)
 4674       (if (null (search-backward "{" nil t))
 4675       (message "Nothing to be narrowed here.")
 4676     (setq beg (point))
 4677     (forward-sexp)
 4678     (setq end (point))
 4679     (if (< end opoint)
 4680         (message "Nothing to be narrowed here.")
 4681       (narrow-to-region beg end))))))
 4682 (put 'TeX-narrow-to-group 'disabled t)
 4683 
 4684 ;;; Utilities
 4685 ;;
 4686 ;; Some of these functions has little to do with TeX, but nonetheless we
 4687 ;; should use the "TeX-" prefix to avoid name clashes.
 4688 
 4689 (defun TeX-listify (elt)
 4690   "Return a newly created list with element ELT.
 4691 If ELT already is a list, return ELT."
 4692   (if (listp elt) elt (list elt)))
 4693 
 4694 (defun TeX-member (elt list how)
 4695   "Return the member ELT in LIST.  Comparison done with HOW.
 4696 Return nil if ELT is not a member of LIST."
 4697   (while (and list (not (funcall how elt (car list))))
 4698     (setq list (cdr list)))
 4699   (car-safe list))
 4700 
 4701 (defun TeX-elt-of-list-member (elts list)
 4702   "Return non-nil if an element of ELTS is a member of LIST."
 4703   (catch 'found
 4704     (dolist (elt elts)
 4705       (when (member elt list)
 4706     (throw 'found t)))))
 4707 
 4708 (defun TeX-assoc (key list)
 4709   "Return non-nil if KEY is `equal' to the car of an element of LIST.
 4710 Like assoc, except case insensitive."
 4711   (let ((case-fold-search t))
 4712     (TeX-member key list
 4713         (lambda (a b)
 4714           (string-match (concat "^" (regexp-quote a) "$")
 4715                 (car b))))))
 4716 
 4717 (defun TeX-match-buffer (n)
 4718   "Return the substring corresponding to the N'th match.
 4719 See `match-data' for details."
 4720   (if (match-beginning n)
 4721       (buffer-substring-no-properties (match-beginning n) (match-end n))
 4722     ""))
 4723 
 4724 (defun TeX-looking-at-backward (regexp &optional limit)
 4725   "Return non-nil if the text before point matches REGEXP.
 4726 Optional second argument LIMIT gives a max number of characters
 4727 to look backward for."
 4728   (let ((pos (point)))
 4729     (save-excursion
 4730       (and (re-search-backward regexp
 4731                    (if limit (max (point-min) (- (point) limit)))
 4732                    t)
 4733        (eq (match-end 0) pos)))))
 4734 
 4735 (defun TeX-current-line ()
 4736   "The current line number."
 4737   (format "%d" (1+ (TeX-current-offset))))
 4738 
 4739 (defun TeX-current-file-name-master-relative ()
 4740   "Return current filename, relative to master directory."
 4741   (file-relative-name
 4742    (buffer-file-name)
 4743    (TeX-master-directory)))
 4744 
 4745 (defun TeX-near-bobp ()
 4746   "Return t iff there's nothing but whitespace between (bob) and (point)."
 4747   (save-excursion
 4748     (skip-chars-backward " \t\n")
 4749     (bobp)))
 4750 
 4751 (defun TeX-add-to-alist (alist-var new-alist)
 4752   "Add NEW-ALIST to the ALIST-VAR.
 4753 If an element with the same key as the key of an element of
 4754 NEW-ALIST is already present in ALIST-VAR, add the new values to
 4755 it; if a matching element is not already present, append the new
 4756 element to ALIST-VAR."
 4757   ;; Loop over all elements of NEW-ALIST.
 4758   (while new-alist
 4759     (let* ((new-element (car new-alist))
 4760        ;; Get the element of ALIST-VAR with the same key of the current
 4761        ;; element of NEW-ALIST, if any.
 4762        (old-element (assoc (car new-element) (symbol-value alist-var))))
 4763       (if old-element
 4764       (progn
 4765         (set alist-var (delete old-element (symbol-value alist-var)))
 4766         ;; Append to `old-element' the values of the current element of
 4767         ;; NEW-ALIST.
 4768         (mapc (lambda (elt) (add-to-list 'old-element elt t))
 4769           (cdr new-element))
 4770         (set alist-var (add-to-list alist-var old-element t)))
 4771     (add-to-list alist-var new-element t)))
 4772     ;; Next element of NEW-ALIST.
 4773     (setq new-alist (cdr new-alist))))
 4774 
 4775 ;;; Syntax Table
 4776 
 4777 (defvar TeX-mode-syntax-table (make-syntax-table)
 4778   "Syntax table used while in TeX mode.")
 4779 
 4780  (make-variable-buffer-local 'TeX-mode-syntax-table)
 4781 
 4782 (progn ; Define TeX-mode-syntax-table.
 4783   (modify-syntax-entry (string-to-char TeX-esc)
 4784                "\\" TeX-mode-syntax-table)
 4785   (modify-syntax-entry ?\f ">"  TeX-mode-syntax-table)
 4786   (modify-syntax-entry ?\n ">"  TeX-mode-syntax-table)
 4787   (modify-syntax-entry (string-to-char TeX-grop)
 4788                (concat "(" TeX-grcl)
 4789                TeX-mode-syntax-table)
 4790   (modify-syntax-entry (string-to-char TeX-grcl)
 4791                (concat ")" TeX-grop)
 4792                TeX-mode-syntax-table)
 4793   (modify-syntax-entry ?%  "<"  TeX-mode-syntax-table)
 4794   (modify-syntax-entry ?\" "."  TeX-mode-syntax-table)
 4795   (modify-syntax-entry ?&  "."  TeX-mode-syntax-table)
 4796   (modify-syntax-entry ?_  "."  TeX-mode-syntax-table)
 4797   (modify-syntax-entry ?@  "_"  TeX-mode-syntax-table)
 4798   (modify-syntax-entry ?~  "."  TeX-mode-syntax-table)
 4799   (modify-syntax-entry ?$  "$"  TeX-mode-syntax-table)
 4800   (modify-syntax-entry ?'  "w"  TeX-mode-syntax-table)
 4801   (modify-syntax-entry ?«  "."  TeX-mode-syntax-table)
 4802   (modify-syntax-entry ?»  "."  TeX-mode-syntax-table)
 4803   (modify-syntax-entry ?|  "."  TeX-mode-syntax-table))
 4804 
 4805 ;;; Menu Support
 4806 
 4807 (defvar TeX-command-current 'TeX-command-master
 4808   "Specify whether to run command on master, buffer or region.")
 4809 ;; Function used to run external command.
 4810 
 4811 (defun TeX-command-select-master ()
 4812   "Determine that the next command will be on the master file."
 4813   (interactive)
 4814   (message "Next command will be on the master file.")
 4815   (setq TeX-command-current 'TeX-command-master))
 4816 
 4817 (defun TeX-command-select-buffer ()
 4818   "Determine that the next command will be on the buffer."
 4819   (interactive)
 4820   (message "Next command will be on the buffer")
 4821   (setq TeX-command-current 'TeX-command-buffer))
 4822 
 4823 (defun TeX-command-select-region ()
 4824   "Determine that the next command will be on the region."
 4825   (interactive)
 4826   (message "Next command will be on the region")
 4827   (setq TeX-command-current 'TeX-command-region))
 4828 
 4829 (defvar TeX-command-force nil)
 4830 ;; If non-nil, TeX-command-query will return the value of this
 4831 ;; variable instead of quering the user.
 4832 
 4833 (defun TeX-command-menu (name)
 4834   "Execute `TeX-command-list' NAME from a menu."
 4835   (let ((TeX-command-force name))
 4836     (funcall TeX-command-current)))
 4837 
 4838 (defun TeX-command-menu-print (printer command name)
 4839   "Print on PRINTER using method COMMAND to run NAME."
 4840   (let ((TeX-printer-default (unless (string= printer "Other") printer))
 4841     (TeX-printer-list (and (string= printer "Other") TeX-printer-list))
 4842     (TeX-print-command command)
 4843     (TeX-queue-command command))
 4844     (TeX-command-menu name)))
 4845 
 4846 (defun TeX-command-menu-printer-entry (entry lookup command name)
 4847   "Return `TeX-printer-list' ENTRY as a menu item."
 4848   (vector (nth 0 entry)
 4849       (list 'TeX-command-menu-print
 4850         (nth 0 entry)
 4851         (or (nth lookup entry) command)
 4852         name)))
 4853 
 4854 (defun TeX-command-menu-entry (entry)
 4855   "Return `TeX-command-list' ENTRY as a menu item."
 4856   (let ((name (car entry)))
 4857     (cond ((and (string-equal name TeX-command-Print)
 4858         TeX-printer-list)
 4859        (cons TeX-command-Print
 4860          (mapcar (lambda (entry)
 4861                (TeX-command-menu-printer-entry
 4862                 entry 1 TeX-print-command name))
 4863              (append TeX-printer-list '(("Other"))))))
 4864       ((and (string-equal name TeX-command-Queue)
 4865         TeX-printer-list)
 4866        (cons TeX-command-Queue
 4867          (mapcar (lambda (entry)
 4868                (TeX-command-menu-printer-entry
 4869                 entry 2 TeX-queue-command name))
 4870              (append TeX-printer-list '(("Other"))))))
 4871       (t
 4872        (vconcat `(,name (TeX-command-menu ,name))
 4873             (nthcdr 5 entry))))))
 4874 
 4875 (defconst TeX-command-menu-name "Command"
 4876   "Name to be displayed for the command menu in all modes defined by AUCTeX.")
 4877 
 4878 ;;; Keymap
 4879 
 4880 (defcustom TeX-electric-escape nil
 4881   "If non-nil, ``\\'' will offer on-the-fly completion.
 4882 In Texinfo-mode, ``@'' will do that job instead and ``\\'' is not
 4883 affected.  See `TeX-electric-macro' for detail."
 4884   :group 'TeX-macro
 4885   :type 'boolean)
 4886 
 4887 (defcustom TeX-electric-sub-and-superscript nil
 4888   "If non-nil, insert braces after typing `^' and `_' in math mode."
 4889   :group 'TeX-macro
 4890   :type 'boolean)
 4891 
 4892 (defcustom TeX-newline-function 'newline
 4893   "Function to be called upon pressing `RET'."
 4894   :group 'TeX-indentation
 4895   :type '(choice (const newline)
 4896          (const newline-and-indent)
 4897          (const reindent-then-newline-and-indent)
 4898          (sexp :tag "Other")))
 4899 
 4900 (defun TeX-insert-backslash (arg)
 4901   "Either insert typed key ARG times or call `TeX-electric-macro'.
 4902 `TeX-electric-macro' will be called if `TeX-electric-escape' is non-nil."
 4903   (interactive "*p")
 4904   (if TeX-electric-escape
 4905       (TeX-electric-macro)
 4906     (self-insert-command arg)))
 4907 
 4908 (defun TeX-insert-sub-or-superscript (arg)
 4909   "Insert typed key ARG times and possibly a pair of braces.
 4910 Brace insertion is only done if point is in a math construct and
 4911 `TeX-electric-sub-and-superscript' has a non-nil value."
 4912   (interactive "*p")
 4913   (self-insert-command arg)
 4914   (when (and TeX-electric-sub-and-superscript (texmathp))
 4915     (insert (concat TeX-grop TeX-grcl))
 4916     (backward-char)))
 4917 
 4918 (defun TeX-newline ()
 4919   "Call the function specified by the variable `TeX-newline-function'."
 4920   (interactive) (call-interactively TeX-newline-function))
 4921 
 4922 (defvar TeX-mode-map
 4923   (let ((map (make-sparse-keymap)))
 4924     ;; Standard
 4925     ;; (define-key map "\177"     'backward-delete-char-untabify)
 4926     (define-key map "\C-c}"    'up-list)
 4927     (define-key map "\C-c#"    'TeX-normal-mode)
 4928     (define-key map "\C-c\C-n" 'TeX-normal-mode)
 4929     (define-key map "\C-c?"    'TeX-documentation-texdoc)
 4930     (define-key map "\C-c\C-i" 'TeX-goto-info-page)
 4931     (define-key map "\r"       'TeX-newline)
 4932 
 4933     ;; From tex.el
 4934     (define-key map "\""       'TeX-insert-quote)
 4935     (define-key map "$"        'TeX-insert-dollar)
 4936     ;; Removed because LaTeX 2e have a better solution to italic correction.
 4937     ;; (define-key map "."        'TeX-insert-punctuation)
 4938     ;; (define-key map ","        'TeX-insert-punctuation)
 4939     (define-key map "\C-c{"    'TeX-insert-braces)
 4940     (define-key map "\C-c\C-f" 'TeX-font)
 4941     (define-key map "\C-c\C-m" 'TeX-insert-macro)
 4942     (define-key map "\\"       'TeX-insert-backslash)
 4943     (define-key map "^"        'TeX-insert-sub-or-superscript)
 4944     (define-key map "_"        'TeX-insert-sub-or-superscript)
 4945     (define-key map "\e\t"     'TeX-complete-symbol) ;*** Emacs 19 way
 4946 
 4947     (define-key map "\C-c'"    'TeX-comment-or-uncomment-paragraph) ;*** Old way
 4948     (define-key map "\C-c:"    'comment-or-uncomment-region) ;*** Old way
 4949     (define-key map "\C-c\""   'TeX-uncomment) ;*** Old way
 4950 
 4951     (define-key map "\C-c;"    'comment-or-uncomment-region)
 4952     (define-key map "\C-c%"    'TeX-comment-or-uncomment-paragraph)
 4953 
 4954     (define-key map "\C-c\C-t\C-p"   'TeX-PDF-mode)
 4955     (define-key map "\C-c\C-t\C-i"   'TeX-interactive-mode)
 4956     (define-key map "\C-c\C-t\C-s"   'TeX-source-correlate-mode)
 4957     (define-key map "\C-c\C-t\C-r"   'TeX-pin-region)
 4958     (define-key map "\C-c\C-w"       'TeX-toggle-debug-bad-boxes); to be removed
 4959     (define-key map "\C-c\C-t\C-b"   'TeX-toggle-debug-bad-boxes)
 4960     (define-key map "\C-c\C-t\C-w"   'TeX-toggle-debug-warnings)
 4961     (define-key map "\C-c\C-t\C-x"   'TeX-toggle-suppress-ignored-warnings)
 4962     (define-key map "\C-c\C-v" 'TeX-view)
 4963     ;; From tex-buf.el
 4964     (define-key map "\C-c\C-d" 'TeX-save-document)
 4965     (define-key map "\C-c\C-r" 'TeX-command-region)
 4966     (define-key map "\C-c\C-b" 'TeX-command-buffer)
 4967     (define-key map "\C-c\C-c" 'TeX-command-master)
 4968     (define-key map "\C-c\C-a" 'TeX-command-run-all)
 4969     (define-key map "\C-c\C-k" 'TeX-kill-job)
 4970     (define-key map "\C-c\C-l" 'TeX-recenter-output-buffer)
 4971     (define-key map "\C-c^" 'TeX-home-buffer)
 4972     (define-key map "\C-c`"    'TeX-next-error)
 4973     ;; Remap bindings of `next-error'
 4974     (define-key map [remap next-error] 'TeX-next-error)
 4975     ;; Remap bindings of `previous-error'
 4976     (define-key map [remap previous-error] 'TeX-previous-error)
 4977     ;; From tex-fold.el
 4978     (define-key map "\C-c\C-o\C-f" 'TeX-fold-mode)
 4979 
 4980     ;; Multifile
 4981     (define-key map "\C-c_" 'TeX-master-file-ask)  ;*** temporary
 4982     map)
 4983   "Keymap for common TeX and LaTeX commands.")
 4984 
 4985 (defun TeX-mode-specific-command-menu (mode)
 4986   "Return a Command menu specific to the major MODE."
 4987   (list TeX-command-menu-name
 4988         :filter `(lambda (&rest ignored)
 4989                    (TeX-mode-specific-command-menu-entries ',mode))
 4990         "Bug."))
 4991 
 4992 (defun TeX-mode-specific-command-menu-entries (mode)
 4993   "Return the entries for a Command menu specific to the major MODE."
 4994   (append
 4995    `("Command on"
 4996      [ "Master File" TeX-command-select-master
 4997        :keys "C-c C-c" :style radio
 4998        :selected (eq TeX-command-current 'TeX-command-master)
 4999        :help "Commands in this menu work on the Master File"]
 5000      [ "Buffer" TeX-command-select-buffer
 5001        :keys "C-c C-b" :style radio
 5002        :selected (eq TeX-command-current 'TeX-command-buffer)
 5003        :help "Commands in this menu work on the current buffer"]
 5004      [ "Region" TeX-command-select-region
 5005        :keys "C-c C-r" :style radio
 5006        :selected (eq TeX-command-current 'TeX-command-region)
 5007        :help "Commands in this menu work on the region"]
 5008      [ "Fix the Region" TeX-pin-region
 5009        :active (or (if prefix-arg
 5010                (<= (prefix-numeric-value prefix-arg) 0)
 5011              (and (boundp 'TeX-command-region-begin)
 5012               (markerp TeX-command-region-begin)))
 5013            mark-active)
 5014        ;;:visible (eq TeX-command-current 'TeX-command-region)
 5015        :style toggle
 5016        :selected (and (boundp 'TeX-command-region-begin)
 5017               (markerp TeX-command-region-begin))
 5018        :help "Fix the region for \"Command on Region\""]
 5019      "-"
 5020      ["Recenter Output Buffer" TeX-recenter-output-buffer
 5021       :help "Show the output of current TeX process"]
 5022      ["Kill Job" TeX-kill-job
 5023       :help "Kill the current TeX process"]
 5024      ["Next Error" TeX-next-error
 5025       :help "Jump to the next error of the last TeX run"]
 5026      ["Previous Error" TeX-previous-error
 5027       :help "Jump to the previous error of the last TeX run"
 5028       :visible TeX-parse-all-errors]
 5029      ["Error Overview" TeX-error-overview
 5030       :help "Open an overview of errors occured in the last TeX run"
 5031       :visible (and TeX-parse-all-errors (fboundp 'tabulated-list-mode))]
 5032      ["Quick View" TeX-view
 5033       :help "Start a viewer without prompting"]
 5034      "-"
 5035      ("TeXing Options"
 5036       ,@(mapcar (lambda (x)
 5037           (let ((symbol (car x)) (name (nth 1 x)))
 5038             `[ ,(format "Use %s engine" name) (TeX-engine-set ',symbol)
 5039                :style radio :selected (eq TeX-engine ',symbol)
 5040                :help ,(format "Use %s engine for compiling" name) ]))
 5041         (TeX-engine-alist))
 5042       "-"
 5043       [ "Generate PDF" TeX-PDF-mode
 5044     :style toggle :selected TeX-PDF-mode
 5045     :active (not (eq TeX-engine 'omega))
 5046     :help "Use PDFTeX to generate PDF instead of DVI"]
 5047       ( "PDF from DVI"
 5048     :visible TeX-PDF-mode
 5049     :help "Compile to DVI with (La)TeX and convert to PDF"
 5050     [ "Compile directly to PDF"
 5051       (lambda () (interactive) (setq TeX-PDF-from-DVI nil))
 5052       :style radio :selected (null (TeX-PDF-from-DVI))
 5053       :help "Compile directly to PDF without intermediate conversions"]
 5054     [ "dvips + ps2pdf"
 5055       (lambda () (interactive) (setq TeX-PDF-from-DVI "Dvips"))
 5056       :style radio :selected (equal (TeX-PDF-from-DVI) "Dvips")
 5057       :help "Convert DVI to PDF with dvips + ps2pdf sequence"]
 5058     [ "dvipdfmx"
 5059       (lambda () (interactive) (setq TeX-PDF-from-DVI "Dvipdfmx"))
 5060       :style radio :selected (equal (TeX-PDF-from-DVI) "Dvipdfmx")
 5061       :help "Convert DVI to PDF with dvipdfmx"])
 5062       [ "Run Interactively" TeX-interactive-mode
 5063     :style toggle :selected TeX-interactive-mode :keys "C-c C-t C-i"
 5064     :help "Stop on errors in a TeX run"]
 5065       [ "Correlate I/O" TeX-source-correlate-mode
 5066     :style toggle :selected TeX-source-correlate-mode
 5067     :help "Enable forward and inverse search in the previewer"]
 5068       ["Debug Bad Boxes" TeX-toggle-debug-bad-boxes
 5069        :style toggle :selected TeX-debug-bad-boxes :keys "C-c C-t C-b"
 5070        :help "Make \"Next Error\" show overfull and underfull boxes"]
 5071       ["Debug Warnings" TeX-toggle-debug-warnings
 5072        :style toggle :selected TeX-debug-warnings
 5073        :help "Make \"Next Error\" show warnings"])
 5074      ["Compile and view" TeX-command-run-all
 5075       :help "Compile the document until it is ready and open the viewer"])
 5076    (let ((file 'TeX-command-on-current)) ;; is this actually needed?
 5077      (delq nil
 5078        (mapcar #'TeX-command-menu-entry
 5079            (TeX-mode-specific-command-list mode))))))
 5080 
 5081 (defun TeX-mode-specific-command-list (mode)
 5082   "Return the list of commands available in the given MODE."
 5083   (let ((full-list TeX-command-list)
 5084     out-list
 5085     entry)
 5086     (while (setq entry (pop full-list))
 5087       ;; `(nth 4 entry)' may be either an atom in case of which the
 5088       ;; entry should be present in any mode or a list of major modes.
 5089       (if (or (atom (nth 4 entry))
 5090           (memq mode (nth 4 entry)))
 5091       (push entry out-list)))
 5092     (nreverse out-list)))
 5093 
 5094 (defvar TeX-fold-menu
 5095   '("Show/Hide"
 5096     ["Fold Mode" TeX-fold-mode
 5097      :style toggle
 5098      :selected (and (boundp 'TeX-fold-mode) TeX-fold-mode)
 5099      :help "Toggle folding mode"]
 5100     "-"
 5101     ["Hide All in Current Buffer" TeX-fold-buffer
 5102      :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
 5103      :help "Hide all configured TeX constructs in the current buffer"]
 5104     ["Hide All in Current Region" TeX-fold-region
 5105      :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
 5106      :help "Hide all configured TeX constructs in the marked region"]
 5107     ["Hide All in Current Paragraph" TeX-fold-paragraph
 5108      :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
 5109      :help "Hide all configured TeX constructs in the paragraph containing point"]
 5110     ["Hide Current Macro" TeX-fold-macro
 5111      :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
 5112      :help "Hide the macro containing point"]
 5113     ["Hide Current Environment" TeX-fold-env
 5114      :visible (not (eq major-mode 'plain-tex-mode))
 5115      :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
 5116      :help "Hide the environment containing point"]
 5117     ["Hide Current Comment" TeX-fold-comment
 5118      :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
 5119      :help "Hide the comment containing point"]
 5120     "-"
 5121     ["Show All in Current Buffer" TeX-fold-clearout-buffer
 5122      :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
 5123      :help "Permanently show all folded content again"]
 5124     ["Show All in Current Region" TeX-fold-clearout-region
 5125      :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
 5126      :help "Permanently show all folded content in marked region"]
 5127     ["Show All in Current Paragraph" TeX-fold-clearout-paragraph
 5128      :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
 5129      :help "Permanently show all folded content in paragraph containing point"]
 5130     ["Show Current Item" TeX-fold-clearout-item
 5131      :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
 5132      :help "Permanently show the item containing point"]
 5133     "-"
 5134     ["Hide or Show Current Item" TeX-fold-dwim
 5135      :active (and (boundp 'TeX-fold-mode) TeX-fold-mode)
 5136      :help "Hide or show the item containing point"])
 5137   "Menu definition for commands from tex-fold.el.")
 5138 
 5139 (defvar TeX-customization-menu nil)
 5140 
 5141 (defvar TeX-common-menu-entries
 5142   `(("Multifile/Parsing"
 5143      ["Switch to Master File" TeX-home-buffer
 5144       :help "Switch to buffer of Master File, or buffer of last TeX command"]
 5145      ["Save Document" TeX-save-document
 5146       :help "Save all buffers associated with the current Master File"]
 5147      ["Set Master File" TeX-master-file-ask
 5148       :active (not (TeX-local-master-p))
 5149       :help "Set the main file to run TeX commands on"]
 5150      ["Reset Buffer" TeX-normal-mode
 5151       :help "Save and reparse the current buffer for style information"]
 5152      ["Reset AUCTeX" (TeX-normal-mode t) :keys "C-u C-c C-n"
 5153       :help "Reset buffer and reload AUCTeX style files"])
 5154     ["Find Documentation..." TeX-documentation-texdoc
 5155      :help "Get help on commands, packages, or TeX-related topics in general"]
 5156     ["Read the AUCTeX Manual" TeX-goto-info-page
 5157      :help "Everything worth reading"]
 5158     ("Customize AUCTeX"
 5159      ["Browse Options"
 5160       (customize-group 'AUCTeX)
 5161       :help "Open the customization buffer for AUCTeX"]
 5162      ["Extend this Menu"
 5163       (progn
 5164     (easy-menu-add-item
 5165      nil
 5166      ;; Ugly hack because docTeX mode uses the LaTeX menu.
 5167      (list (if (eq major-mode 'doctex-mode) "LaTeX" TeX-base-mode-name))
 5168      (or TeX-customization-menu
 5169          (setq TeX-customization-menu
 5170            (customize-menu-create 'AUCTeX "Customize AUCTeX")))))
 5171       :help "Make this menu a full-blown customization menu"])
 5172     ["Report AUCTeX Bug" TeX-submit-bug-report
 5173      :help ,(format "Problems with AUCTeX %s? Mail us!"
 5174             AUCTeX-version)]))
 5175 
 5176 
 5177 ;;; Verbatim constructs
 5178 
 5179 (defvar TeX-verbatim-p-function nil
 5180   "Mode-specific function to be called by `TeX-verbatim-p'.")
 5181 (make-variable-buffer-local 'TeX-verbatim-p-function)
 5182 
 5183 ;; XXX: We only have an implementation for LaTeX mode at the moment (Oct 2009).
 5184 (defun TeX-verbatim-p (&optional pos)
 5185   "Return non-nil if position POS is in a verbatim-like construct.
 5186 A mode-specific implementation is required.  If it is not
 5187 available, the function always returns nil."
 5188   (when TeX-verbatim-p-function
 5189     (funcall TeX-verbatim-p-function)))
 5190 
 5191 
 5192 ;;; Comments
 5193 
 5194 (defvar TeX-comment-start-regexp "%"
 5195   "Regular expression matching a comment starter.
 5196 Unlike the variable `comment-start-skip' it should not match any
 5197 whitespace after the comment starter or any character before it.")
 5198 (make-variable-buffer-local 'TeX-comment-start-regexp)
 5199 
 5200 (defun TeX-uncomment ()
 5201   "Delete comment characters from the beginning of each line in a comment."
 5202   (interactive)
 5203   (save-excursion
 5204     ;; Find first comment line
 5205     (beginning-of-line)
 5206     (while (and (looking-at (concat "^[ \t]*" TeX-comment-start-regexp))
 5207         (not (bobp)))
 5208       (forward-line -1))
 5209     (let ((beg (point)))
 5210       (forward-line 1)
 5211       ;; Find last comment line
 5212       (while (and (looking-at (concat "^[ \t]*" TeX-comment-start-regexp))
 5213           (not (eobp)))
 5214     (forward-line 1))
 5215       ;; Uncomment region
 5216       (uncomment-region beg (point)))))
 5217 
 5218 (defun TeX-comment-or-uncomment-paragraph ()
 5219   "Comment or uncomment current paragraph."
 5220   (interactive)
 5221   (if (TeX-in-commented-line)
 5222       (TeX-uncomment)
 5223     (save-excursion
 5224       (beginning-of-line)
 5225       ;; Don't do anything if we are in an empty line.  If this line
 5226       ;; is followed by a lot of commented lines, this shall prevent
 5227       ;; that mark-paragraph skips over these lines and marks a
 5228       ;; paragraph outside the visible window which might get
 5229       ;; commented without the user noticing.
 5230       (unless (looking-at "^[ \t]*$")
 5231     (mark-paragraph)
 5232     (comment-region (point) (mark))))))
 5233 
 5234 (defun TeX-in-comment ()
 5235   "Return non-nil if point is in a comment."
 5236   (if (or (bolp)
 5237       (null comment-start-skip)
 5238       (eq (preceding-char) ?\r))
 5239       nil
 5240     (save-excursion
 5241       (save-match-data
 5242     (let ((pos (point)))
 5243       (beginning-of-line)
 5244       (and (or (looking-at comment-start-skip)
 5245            (re-search-forward comment-start-skip pos t))
 5246            (not (TeX-verbatim-p))))))))
 5247 
 5248 (defun TeX-in-commented-line ()
 5249   "Return non-nil if point is in a line consisting only of a comment.
 5250 The comment can be preceded by whitespace.  This means that
 5251 `TeX-in-commented-line' is more general than `TeX-in-line-comment'
 5252 which will not match commented lines with leading whitespace.  But
 5253 `TeX-in-commented-line' will match commented lines without leading
 5254 whitespace as well."
 5255   (save-excursion
 5256     (forward-line 0)
 5257     (skip-chars-forward " \t")
 5258     (string= (buffer-substring-no-properties
 5259           (point) (min (point-max) (+ (point) (length comment-start))))
 5260          comment-start)))
 5261 
 5262 (defun TeX-in-line-comment ()
 5263   "Return non-nil if point is in a line comment.
 5264 A line comment is a comment starting in column one, i.e. there is
 5265 no whitespace before the comment sign."
 5266   (save-excursion
 5267     (forward-line 0)
 5268     (string= (buffer-substring-no-properties
 5269           (point) (min (point-max) (+ (point) (length comment-start))))
 5270          comment-start)))
 5271 
 5272 (defun TeX-comment-prefix ()
 5273   "Return the comment prefix of the current line.
 5274 If there are no comment starters after potential whitespace at
 5275 the beginning of the line, return nil."
 5276   (save-excursion
 5277     (beginning-of-line)
 5278     (save-match-data
 5279       (when (looking-at (concat "\\([ \t]*" TeX-comment-start-regexp "+\\)+"))
 5280     (match-string 0)))))
 5281 
 5282 (defun TeX-forward-comment-skip (&optional count limit)
 5283   "Move forward to the next comment skip.
 5284 This may be a switch between commented and not commented adjacent
 5285 lines or between lines with different comment prefixes.  With
 5286 argument COUNT do it COUNT times.  If argument LIMIT is given, do
 5287 not move point further than this value."
 5288   (unless count (setq count 1))
 5289   ;; A value of 0 is nonsense.
 5290   (when (= count 0) (setq count 1))
 5291   (unless limit (setq limit (point-max)))
 5292   (dotimes (i (abs count))
 5293     (if (< count 0)
 5294     (forward-line -1)
 5295       (beginning-of-line))
 5296     (let ((prefix (when (looking-at (concat "\\([ \t]*"
 5297                         TeX-comment-start-regexp "+\\)+"))
 5298             (buffer-substring (+ (line-beginning-position)
 5299                      (current-indentation))
 5300                       (match-end 0)))))
 5301       (while (save-excursion
 5302            (and (if (> count 0)
 5303             (<= (point) limit)
 5304               (>= (point) limit))
 5305             (zerop (if (> count 0)
 5306                    (forward-line 1)
 5307                  (forward-line -1)))
 5308             (if prefix
 5309             (if (looking-at (concat "\\([ \t]*"
 5310                         TeX-comment-start-regexp
 5311                         "+\\)+"))
 5312                 ;; If the preceding line is a commented line
 5313                 ;; as well, check if the prefixes are
 5314                 ;; identical.
 5315                 (string= prefix
 5316                      (buffer-substring
 5317                       (+ (line-beginning-position)
 5318                      (current-indentation))
 5319                       (match-end 0)))
 5320               nil)
 5321               (not (looking-at (concat "[ \t]*"
 5322                            TeX-comment-start-regexp))))))
 5323     (if (> count 0)
 5324         (forward-line 1)
 5325       (forward-line -1)))
 5326       (if (> count 0)
 5327       (forward-line 1)))))
 5328 
 5329 (defun TeX-backward-comment-skip (&optional count limit)
 5330   "Move backward to the next comment skip.
 5331 This may be a switch between commented and not commented adjacent
 5332 lines or between lines with different comment prefixes.  With
 5333 argument COUNT do it COUNT times.  If argument LIMIT is given, do
 5334 not move point to a position less than this value."
 5335   (unless count (setq count 1))
 5336   (when (= count 0) (setq count 1))
 5337   (unless limit (setq limit (point-min)))
 5338   (TeX-forward-comment-skip (- count) limit))
 5339 
 5340 (defun TeX-comment-forward (&optional n)
 5341   "Skip forward over N comments.
 5342 Just like `forward-comment' but only for positive N
 5343 and can use regexps instead of syntax."
 5344   (comment-normalize-vars)
 5345   (comment-forward n))
 5346 
 5347 (defun TeX-comment-padding-string ()
 5348   "Return  comment padding as a string.
 5349 The variable `comment-padding' can hold an integer or a string.
 5350 This function will return the appropriate string representation
 5351 regardless of its data type."
 5352   (if (integerp comment-padding)
 5353       (make-string comment-padding ? )
 5354     comment-padding))
 5355 
 5356 
 5357 ;;; Indentation
 5358 
 5359 (defgroup TeX-indentation nil
 5360   "Indentation of TeX buffers in AUCTeX."
 5361   :group 'AUCTeX)
 5362 
 5363 (defcustom TeX-brace-indent-level 2
 5364   "*The level of indentation produced by an open brace."
 5365   :group 'TeX-indentation
 5366   :type 'integer)
 5367 
 5368 (defun TeX-comment-indent ()
 5369   "Determine the indentation of a comment."
 5370   (if (looking-at "%%%")
 5371       (current-column)
 5372     (skip-chars-backward " \t")
 5373     (max (if (bolp) 0 (1+ (current-column)))
 5374      comment-column)))
 5375 
 5376 (defun TeX-brace-count-line ()
 5377   "Count number of open/closed braces."
 5378   (save-excursion
 5379     (let ((count 0) (limit (line-end-position)) char)
 5380       (while (progn
 5381            (skip-chars-forward "^{}\\\\" limit)
 5382            (when (and (< (point) limit) (not (TeX-in-comment)))
 5383          (setq char (char-after))
 5384          (forward-char)
 5385          (cond ((eq char ?\{)
 5386             (setq count (+ count TeX-brace-indent-level)))
 5387                ((eq char ?\})
 5388             (setq count (- count TeX-brace-indent-level)))
 5389                ((eq char ?\\)
 5390             (when (< (point) limit)
 5391               (forward-char)
 5392               t))))))
 5393       count)))
 5394 
 5395 ;;; Navigation
 5396 
 5397 (defvar TeX-search-syntax-table
 5398   (let ((table (make-syntax-table (make-char-table 'syntax-table))))
 5399     ;; Preset mode-independent syntax entries.  (Mode-dependent
 5400     ;; entries are set in the function `TeX-search-syntax-table'.)
 5401     ;; ?\", ?\( and ?\) explicitely get whitespace syntax because
 5402     ;; Emacs 21.3 and XEmacs don't generate a completely empty syntax
 5403     ;; table.
 5404     (dolist (elt '((?\f . ">") (?\n . ">") (?\" . " ") (?\( . " ") (?\) . " ")))
 5405       (modify-syntax-entry (car elt) (cdr elt) table))
 5406     table)
 5407   "Syntax table used for searching purposes.
 5408 It should be accessed through the function `TeX-search-syntax-table'.")
 5409 
 5410 (defun TeX-search-syntax-table (&rest args)
 5411   "Return a syntax table for searching purposes.
 5412 ARGS may be a list of characters.  For each of them the
 5413 respective predefined syntax is set.  Currently the parenthetical
 5414 characters ?{, ?}, ?[, ?], ?\(, ?\), ?<, and ?> are supported.
 5415 The syntax of each of these characters not specified will be
 5416 reset to \" \"."
 5417   (let ((char-syntax-alist '((?\{ . "(}") (?\} . "){")
 5418                  (?\[ . "(]") (?\] . ")[")
 5419                  (?\( . "()") (?\) . ")(")
 5420                  (?\< . "(>") (?\> . ")<"))))
 5421     ;; Clean entries possibly set before.
 5422     (modify-syntax-entry ?\\ " " TeX-search-syntax-table)
 5423     (modify-syntax-entry ?@ " " TeX-search-syntax-table)
 5424     (modify-syntax-entry ?\% " " TeX-search-syntax-table)
 5425     ;; Preset mode-dependent syntax entries.  (Mode-independent entries
 5426     ;; are set when the variable `TeX-search-syntax-table' is created.)
 5427     (modify-syntax-entry (string-to-char TeX-esc) "\\" TeX-search-syntax-table)
 5428     (unless (eq major-mode 'texinfo-mode)
 5429       (modify-syntax-entry ?\% "<" TeX-search-syntax-table))
 5430     ;; Clean up the entries which can be specified as arguments.
 5431     (dolist (elt char-syntax-alist)
 5432       (modify-syntax-entry (car elt) " " TeX-search-syntax-table))
 5433     ;; Now set what we got.
 5434     (dolist (elt args)
 5435       (unless (assoc elt char-syntax-alist) (error "Char not supported"))
 5436       (modify-syntax-entry elt (cdr (assoc elt char-syntax-alist))
 5437                TeX-search-syntax-table))
 5438     ;; Return the syntax table.
 5439     TeX-search-syntax-table))
 5440 
 5441 (defun TeX-find-balanced-brace (&optional count depth limit)
 5442   "Return the position of a balanced brace in a TeX group.
 5443 The function scans forward COUNT parenthetical groupings.
 5444 Default is 1.  If COUNT is negative, it searches backwards.  With
 5445 optional DEPTH>=1, find that outer level.  If LIMIT is non-nil,
 5446 do not search further than this position in the buffer."
 5447   (let ((count (if count
 5448            (if (= count 0) (error "COUNT has to be <> 0") count)
 5449          1))
 5450     (depth (if depth
 5451            (if (< depth 1) (error "DEPTH has to be > 0") depth)
 5452          1)))
 5453     (save-restriction
 5454       (when limit
 5455     (if (> count 0)
 5456         (narrow-to-region (point-min) limit)
 5457       (narrow-to-region limit (point-max))))
 5458       (with-syntax-table (TeX-search-syntax-table ?\{ ?\})
 5459     (condition-case nil
 5460         (scan-lists (point) count depth)
 5461       (error nil))))))
 5462 
 5463 (defun TeX-find-closing-brace (&optional depth limit)
 5464   "Return the position of the closing brace in a TeX group.
 5465 The function assumes that point is inside the group, i.e. after
 5466 an opening brace.  With optional DEPTH>=1, find that outer level.
 5467 If LIMIT is non-nil, do not search further down than this
 5468 position in the buffer."
 5469   (TeX-find-balanced-brace 1 depth limit))
 5470 
 5471 (defun TeX-find-opening-brace (&optional depth limit)
 5472   "Return the position of the opening brace in a TeX group.
 5473 The function assumes that point is inside the group, i.e. before
 5474 a closing brace.  With optional DEPTH>=1, find that outer level.
 5475 If LIMIT is non-nil, do not search further up than this position
 5476 in the buffer."
 5477   (TeX-find-balanced-brace -1 depth limit))
 5478 
 5479 (defun TeX-find-macro-boundaries (&optional lower-bound)
 5480   "Return a list containing the start and end of a macro.
 5481 If LOWER-BOUND is given, do not search backward further than this
 5482 point in buffer.  Arguments enclosed in brackets or braces are
 5483 considered part of the macro."
 5484   (save-restriction
 5485     (when lower-bound
 5486       (narrow-to-region lower-bound (point-max)))
 5487     (let ((orig-point (point))
 5488       start-point)
 5489       ;; Point is located directly at the start of a macro. (-!-\foo{bar})
 5490       (when (and (eq (char-after) (aref TeX-esc 0))
 5491          (not (TeX-escaped-p)))
 5492     (setq start-point (point)))
 5493       ;; Point is located on a macro. (\fo-!-o{bar})
 5494       (unless start-point
 5495     (save-excursion
 5496       (skip-chars-backward "A-Za-z@*")
 5497       (when (and (eq (char-before) (aref TeX-esc 0))
 5498              (not (TeX-escaped-p (1- (point)))))
 5499         (setq start-point (1- (point))))))
 5500       ;; Point is located in the argument of a macro. (\foo{ba-!-r})
 5501       (unless start-point
 5502     (save-excursion
 5503       (catch 'abort
 5504         (let ((parse-sexp-ignore-comments t))
 5505           (when (condition-case nil (progn (up-list) t) (error nil))
 5506         (while (progn
 5507              (condition-case nil (backward-sexp)
 5508                (error (throw 'abort nil)))
 5509              (forward-comment -1)
 5510              (and (memq (char-before) '(?\] ?\}))
 5511                   (not (TeX-escaped-p (1- (point)))))))
 5512         (skip-chars-backward "A-Za-z@*")
 5513         (when (and (eq (char-before) (aref TeX-esc 0))
 5514                (not (TeX-escaped-p (1- (point)))))
 5515           (setq start-point (1- (point)))))))))
 5516       ;; Search forward for the end of the macro.
 5517       (when start-point
 5518     (save-excursion
 5519       (goto-char (TeX-find-macro-end-helper start-point))
 5520       (if (< orig-point (point))
 5521           (cons start-point (point))
 5522         nil))))))
 5523 
 5524 (defun TeX-find-macro-end-helper (start)
 5525   "Find the end of a macro given its START.
 5526 START is the position just before the starting token of the macro.
 5527 If the macro is followed by square brackets or curly braces,
 5528 those will be considered part of it."
 5529   (save-excursion
 5530     (save-match-data
 5531       (catch 'found
 5532     (goto-char (1+ start))
 5533     (if (zerop (skip-chars-forward "A-Za-z@"))
 5534         (forward-char)
 5535       (skip-chars-forward "*"))
 5536     (while (not (eobp))
 5537       (cond
 5538        ;; Skip over pairs of square brackets
 5539        ((or (looking-at "[ \t]*\n?\\(\\[\\)") ; Be conservative: Consider
 5540                     ; only consecutive lines.
 5541         (and (looking-at (concat "[ \t]*" TeX-comment-start-regexp))
 5542              (save-excursion
 5543                (forward-line 1)
 5544                (looking-at "[ \t]*\\(\\[\\)"))))
 5545         (goto-char (match-beginning 1))
 5546         (condition-case nil
 5547         (forward-sexp)
 5548           (scan-error (throw 'found (point)))))
 5549        ;; Skip over pairs of curly braces
 5550        ((or (looking-at "[ \t]*\n?{") ; Be conservative: Consider
 5551                     ; only consecutive lines.
 5552         (and (looking-at (concat "[ \t]*" TeX-comment-start-regexp))
 5553              (save-excursion
 5554                (forward-line 1)
 5555                (looking-at "[ \t]*{"))))
 5556         (goto-char (match-end 0))
 5557         (goto-char (or (TeX-find-closing-brace)
 5558                ;; If we cannot find a regular end, use the
 5559                ;; next whitespace.
 5560                (save-excursion (skip-chars-forward "^ \t\n")
 5561                        (