Mercurial > emacs
changeset 20102:c00f010468c2
Using cl macros push, pop, when, unless throughout
the file. This is not further mentioned in this ChangeLog entry.
Documentation largely updated. Parser rewritten for better
Multifile Document processing. Macros with naked label arguments
supported. Some Mule related changes.
(reftex-default-label-alist-entries): Customization type is now
computed from reftex-label-alist-builtin. Enumerate has new
typekey `i'. `n' is now reserved for footnotes etc.
(reftex-label-alist): Introduced default regular expressions.
Customization type is now computed from
reftex-label-alist-builtin.
(reftex-label-menu-flags): New flag for showing file borders.
(reftex-refontify-context): New option.
(reftex-bibfile-ignore-list): Now a user option (was: variable).
(reftex-cite-format): Now a user option (was: variable).
Customization type is now computed from
reftex-cite-format-builtin.
(reftex-comment-citations): Now a user option (was: variable).
(reftex-toc-follow-mode): Now a user option (was: variable).
(reftex-optimizations-for-large-documents): New custom group.
(reftex-keep-temporary-buffers): 1 as additional value.
(reftex-initialize-temporary-buffers): New option.
(reftex-enable-partial-scans): New option.
(reftex-save-parse-info): New option.
(reftex-plug-into-AUCTeX): Now a user option (was: variable).
(reftex-auto-show-entry): New value 'copy allowed.
(reftex-load-hook): Now a declared variable.
(reftex-mode-hook): Now a declared variable.
(reftex-label-numbers-symbol): Variable removed.
(reftex-list-of-labels-symbol): Variable removed.
(reftex-label-numbers-symbol): Variable removed.
(reftex-bibfile-list-symbol): Variable removed.
(reftex-docstruct-symbol): New variable (buffer-local).
(reftex-master-include-list): Variable removed.
(reftex-make-master-buffer): Function removed.
(reftex-make-master-buffer-hook): Hook removed.
(reftex-insert-buffer-or-file): Function removed.
(reftex-parse-document): Function adapted to new parser.
(reftex-access-scan-info): Changed to fit new parser. Now detects
changes in label-alist related variables automatically.
(reftex-parse-one,reftex-parse-all): New functions.
(reftex-all-document-files): New function.
(reftex-grep-document,reftex-search-document,
reftex-query-replace-document): Now use
`reftex-all-document-files'.
(reftex-section-or-include-regexp): New variable.
(reftex-everything-regexp): New variable.
(reftex-find-label-regexp-format): New variable.
(reftex-find-label-regexp-format2): New variable.
(reftex-do-parse): New function.
(reftex-is-multi): New function.
(reftex-parse-from-file): New function.
(reftex-locate-bibliography-files): New function.
(reftex-last-assoc-before-elt): New function.
(reftex-replace-label-list-segment): New function.
(reftex-silence-toc-markers): New function.
(reftex-access-parse-file): New function.
(reftex-label): Now uses `reftex-where-am-I'.
(reftex-offer-label-menu): New keys `%' and `i' and `r'.
(reftex-select-item): Recursive edit moved to key `e'. New key
`x' for external documents. Works now also with nin-nil
pop-frame.
(reftex-offer-label-menu): Now uses `reftex-where-am-I'.
(reftex-make-and-insert-label-menu): More efficient, allow
optional extra fontification.
(reftex-find-nearby-label): Function removed.
(reftex-scan-buffer-for-labels): Function removed.
(reftex-section-info): New function.
(reftex-nth-parens-substring): Renamed to reftex-nth-arg. Return
nil when not enough args are present.
(reftex-move-over-touching-args): New function.
(reftex-where-am-I): New function.
(reftex-nth-arg-wrapper): New function.
(reftex-select-label-callback): Deal with special macros as well.
(reftex-find-duplicate-labels): Ignore special entries in
docstruct.
(reftex-kill-temporary-buffers): New arg buffer.
(reftex-show-entry): Copy context when necessary.
(reftex-toc): New key `R', use reftex-where-am-I.
(reftex-nearest-section): Use reftex-where-am-I.
(reftex-toc-visit-line): Completely rewritten. Uses markers and
several backup methods.
(reftex-citation): Recursive edit moved to `e' key.
(reftex-scan-buffer): Function removed.
(reftex-get-bibfile-list): Changed to work with chapterbib
package.
(reftex-find-tex-file): New function.
(reftex-find-files-on-path): Now first looks for file with
additional .tex extension, then for the naked file name.
(reftex-citation): Split into reftex-citation and
reftex-do-citation.
(reftex-do-citation): Recursive edit now on `e' key.
(reftex-what-macro): Allow white space between macro arguments.
(reftex-allow-for-ctrl-m): Renamed to
`reftex-make-regexp-allow-for-ctrl-m'.
(reftex-nearest-match): New function.
(reftex-auto-mode-alist): New function.
(reftex-make-desparate-section-regexp): New funtion.
(reftex-get-file-buffer-force): Rewritten to use new variable
`reftex-initialize-temporary-buffers'.
(reftex-label-alist-builtin): Use abbreviated regexps.
(reftex-label-mac-list): New variable.
(reftex-parse-args): New function.
(easy-menu-define): Menu extended. Some parts are now computed.
from the user options.
(reftex-move-to-next-arg,reftex-move-to-previous-arg) New
functions. Now we can parse macros with distributed arguments.
(reftex-goto-label): Function removed.
(reftex-position-cursor): Function removed.
(reftex-item): Function removed.
(reftex-add-to-label-alist): No longer autoloaded.
(reftex-toc-indent): Constant removed.
(reftex-label-indent): Constant removed.
(reftex-context-indent): Constant removed.
(reftex-match-string): New function.
(reftex-memory): New variable
(reftex-reset-mode): No longer hacks local variables. Now resets
path variables as well.
(reftex-truncate): New functions, to make RefTeX work with Mule.
(reftex-fp): New macro, to make RefTeX work with Mule.
(reftex-format-bib-entry): Now uses `reftex-truncate' to truncate
author names. `extra' and `title' are no longer truncated at all.
(reftex-all-assq): New function.
(reftex-view-crossref): Works now also if mouse click is on macro.
(reftex-context-substring): Now returns substring without text
properties.
(reftex-tex-path,reftex-bib-path): New variables.
(reftex-split): Function replaced with builtin `split-string'.
(reftex-find-bib-file): New function.
(reftex-find-files-on-path): Function removed.
(reftex-find-file-on-path): New function.
(reftex-access-search-path,reftex-parse-colon-path,
reftex-recursive-directory-list,reftex-expand-path): New
functions, dealing with recursive TEXINPUTS and BIBINPUTS
definitions.
author | Karl Heuer <kwzh@gnu.org> |
---|---|
date | Tue, 21 Oct 1997 03:15:20 +0000 |
parents | 1920690627a2 |
children | 7867bb9ff46a |
files | lisp/textmodes/reftex.el |
diffstat | 1 files changed, 3078 insertions(+), 2168 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/textmodes/reftex.el Tue Oct 21 03:06:34 1997 +0000 +++ b/lisp/textmodes/reftex.el Tue Oct 21 03:15:20 1997 +0000 @@ -1,5 +1,4 @@ ;; reftex.el --- Minor mode for doing \label, \ref and \cite in LaTeX - ;; Copyright (c) 1997 Free Software Foundation, Inc. ;; Author: Carsten Dominik <dominik@strw.LeidenUniv.nl> @@ -30,7 +29,8 @@ ;; \cite commands in (multi-file) LaTeX documents. ;; Labels are created semi-automatically. Definition context of labels is ;; provided when creating a reference. Citations are simplified with -;; efficient database lookup. +;; efficient database lookup. A table of contents buffer provides easy +;; access to any part of a document. ;; ;; To turn RefTeX Minor Mode on and off in a particular buffer, use ;; `M-x reftex-mode'. @@ -41,51 +41,68 @@ ;; (add-hook 'LaTeX-mode-hook 'turn-on-reftex) ; with AUCTeX LaTeX mode ;; (add-hook 'latex-mode-hook 'turn-on-reftex) ; with Emacs latex mode ;; -;; For key bindings, see further down in this documentation. +;; For default key bindings, see further down in this documentation. +;; +;;--------------------------------------------------------------------------- +;; +;; CONTENTS +;; -------- +;; +;; Overview............................ All you need to know to get started. ;; +;; Configuration....................... How to configure RefTeX. +;; Configuration Examples........... Tutorial examples. +;; Hooks............................ Available hooks. +;; Configuration Variables.......... Complete listing. +;; Key Bindings........................ A list of default bindings. +;; Multifile Documents................. Documents spread over many files. +;; References to Other Documents....... RefTeX and the LaTeX package `xr'. +;; Optimizations for Large Documents... How to improve speed and memory use. +;; Related Packages.................... Other Emacs packages. +;; Known Bugs and Work-Arounds......... First aid. +;; Author.............................. Who wrote RefTeX and who helped. ;;--------------------------------------------------------------------------- ;; ;; OVERVIEW -;; -;; 1. USING \label AND \ref. Labels and references are one of the -;; strong points of LaTeX. But, in documents with hundreds of -;; equations, figures, tables etc. it becomes quickly impossible to -;; find good label names and to actually remember them. Then, also -;; completion of labels in not enough. One actually needs to see the -;; context of the label definition to find the right one. -;; -;; - RefTeX distinguishes labels for different environments. It -;; always knows if a certain label references a figure, table -;; etc.. You can configure RefTeX to recognize any additional -;; labeled environments you might have defined yourself. +;; ======== +;; +;; 1. USING \label AND \ref. Labels and references are one of the strong +;; points of LaTeX. But, in documents with hundreds of equations, +;; figures, tables etc. it becomes quickly impossible to find good label +;; names and to actually remember them. Then, also completion of labels +;; is not enough. One actually needs to see the context of the label +;; definition to find the right one. +;; +;; - RefTeX distinguishes labels for different environments. It always +;; knows if a certain label references a figure, table etc.. You can +;; configure RefTeX to recognize any additional labeled environments +;; you have defined yourself. ;; ;; - RefTeX defines automatically unique labels. Type `C-c (' -;; (reftex-label) to insert a label at point. RefTeX will either +;; (`reftex-label') to insert a label at point. RefTeX will either ;; - derive a label from context (default for section labels) ;; - insert a simple label consisting of a prefix and a number -;; (default for equations and enumerate items) or +;; (default for equations,enumerate items, and footnotes) or ;; - prompt for a label string (figures and tables). ;; Which labels are created how can be controlled with the variable ;; `reftex-insert-label-flags'. ;; -;; - Referencing labels is a snap and I promise you'll love it. -;; In order to make a reference, type `C-c )' (`reftex-reference'). -;; This shows an outline of the document with all labels of a -;; certain type (figure, equation,...) and context of the label -;; definition. Selecting one of the labels inserts a \ref macro -;; into the original buffer. Online help during the selection is -;; available with `?'. -;; -;; 2. CITATIONS. After typing `C-c [' (`reftex-citation'), RefTeX will -;; let you specify a regexp to search in current BibTeX database files -;; (as specified in the \bibliography command) and pull out a formatted -;; list of matches for you to choose from. The list is *formatted* and -;; thus much easier to read than the raw database entries. It can also -;; be sorted. The text inserted into the buffer is by default just -;; `\cite{KEY}', but can also contain author names and the year in a -;; configurable way. See documentation of the variable -;; `reftex-cite-format'. -;; +;; - Referencing labels is a snap and I promise you'll love it. In +;; order to make a reference, type `C-c )' (`reftex-reference'). This +;; shows an outline of the document with all labels of a certain type +;; (figure, equation,...) and context of the label definition. +;; Selecting one of the labels inserts a \ref macro into the original +;; buffer. Online help during the selection is available with `?'. +;; +;; 2. CITATIONS. After typing `C-c [' (`reftex-citation'), RefTeX will let +;; you specify a regexp to search in current BibTeX database files (as +;; specified in the \bibliography command) and pull out a formatted list +;; of matches for you to choose from. The list is *formatted* and +;; sorted, thus much easier to read than the raw database entries. The +;; text inserted into the buffer is by default just `\cite{KEY}', but +;; can also contain author names and the year in a configurable way. +;; See documentation of the variable `reftex-cite-format'. +;; ;; 3. TABLE OF CONTENTS. Typing `C-c =' (`reftex-toc') will show a table ;; of contents of the document. From that buffer, you can jump quickly ;; to every part of your document. This is similar to imenu, only it @@ -95,163 +112,150 @@ ;; ;; 4. MULTIFILE DOCUMENTS are fully supported by RefTeX. Such documents ;; consist of a master file and many other files being included via -;; \input or \include. (La)TeX source files included from another file -;; should specify the name of the top level master file with a `file -;; variable' (see the Emacs documentation on file variables for details: -;; [Emacs/Customization/Variables/File Variables]). With AUCTeX, this -;; variable is called `TeX-master'. The Emacs (La)TeX modes use -;; `tex-main-file' instead. RefTeX will check for both. Check the -;; documentation of your (La)TeX modes on how to specify the master -;; file. -;; RefTeX knows about all files related to a document via \input and -;; \include. It provides functions to run regular expression searches -;; and replaces over the entire document and to create a TAGS file. -;; -;; 5. DOCUMENT PARSING. RefTeX needs to parse the document in order to find -;; labels and other information. It will do it automatically once, when -;; you start working with a document. If you need to enforce reparsing -;; later, call any of the functions `reftex-citation', `reftex-label', -;; `reftex-reference', `reftex-toc' with a raw C-u prefix. +;; \input or \include. RefTeX will provide cross referencing +;; information from all files which are part of the document. See +;; `RefTeX and Multifile Documents' further down in the documentation +;; for more information on this topic. ;; -;;------------------------------------------------------------------------- -;; -;; CONFIGURATION -;; -;; RefTeX contains configurable options which change the way it works. +;; 5. DOCUMENT PARSING. RefTeX needs to parse the document in order to +;; find labels and other information. It will do it automatically once, +;; when you start working with a document. Re-parsing should not be +;; necessary too often since RefTeX updates its lists internally when +;; you make a new label with `reftex-label'. To enforce reparsing, +;; call any of the functions `reftex-citation', `reftex-label', +;; `reftex-reference', `reftex-toc' with a raw C-u prefix, or press the +;; `r' key in the label menu and table of contents buffer. +;;--------------------------------------------------------------------------- ;; -;; Most importantly, RefTeX needs to be configured if you use labels to -;; mark non-standard environments. RefTeX always understands LaTeX section -;; commands and the following environments: figure, figure*, -;; sidewaysfigure, table, table*, sidewaystable, equation, eqnarray, -;; enumerate. For everythings else, it needs to be configured. +;; CONFIGURATION +;; ============= ;; -;; A good way to configure RefTeX is with the custom.el package by Per -;; Abrahamsen, shipped with Emacs 20 and XEmacs 19.15. To do this, just -;; say `M-x reftex-customize'. -;; -;; Here is a complete list of the RefTeX configuration variables with -;; their default settings. You could copy part of this list to your -;; .emacs file and change whatever is necessary. Each variable has an -;; extensive documentation string. Look it up for more information! +;; RefTeX needs to be configured if you use labels to mark environments +;; defined by yourself (e.g. with `\newenvironment') or in packages not +;; included in the standard LaTeX distribution. RefTeX's default settings +;; make it recognize practically all labeled environments and macros +;; discussed in `The LaTeX Companion' by Goossens, Mittelbach & Samarin, +;; Addison-Wesley 1994. These are: ;; -;; ;; Configuration Variables and User Options for RefTeX ------------------ -;; ;; Support for \label and \ref ------------------------------------------ -;; (setq reftex-label-alist nil) -;; (setq reftex-default-label-alist-entries '(Sideways LaTeX)) -;; (setq reftex-use-text-after-label-as-context nil) -;; ;; Label insertion -;; (setq reftex-insert-label-flags '("s" "sft")) -;; (setq reftex-derive-label-parameters '(3 20 t 1 "-" -;; ("the" "on" "in" "off" "a" "for" "by" "of" "and" "is"))) -;; (setq reftex-label-illegal-re "[\000-\040\177-\377\\\\#$%&~^_{}]") -;; (setq reftex-abbrev-parameters '(4 2 "^saeiou" "aeiou")) -;; ;; Label referencing -;; (setq reftex-label-menu-flags '(t t nil nil nil nil t)) -;; (setq reftex-guess-label-type t) -;; ;; BibteX citation configuration ---------------------------------------- -;; (setq reftex-bibpath-environment-variables '("BIBINPUTS" "TEXBIB")) -;; (setq reftex-bibfile-ignore-list nil) -;; (setq reftex-sort-bibtex-matches 'reverse-year) -;; (setq reftex-cite-format 'default) -;; (setq reftex-comment-citations nil) -;; (setq reftex-cite-comment-format -;; "%% %2a %y, %j %v, %P, %e: %b, %u, %s %<\n") -;; (setq reftex-cite-punctuation '(", " " \\& " " {\\it et al.}")) -;; ;; Table of contents configuration -------------------------------------- -;; (setq reftex-toc-follow-mode nil) -;; ;; Miscellaneous configurations ----------------------------------------- -;; (setq reftex-extra-bindings nil) -;; (setq reftex-plug-into-AUCTeX nil) -;; (setq reftex-use-fonts t) -;; (setq reftex-keep-temporary-buffers t) -;; (setq reftex-auto-show-entry t) +;; - figure, figure*, table, table*, equation, eqnarray, enumerate, +;; the \footnote macro (this is the LaTeX core stuff) +;; - align, gather, multline, flalign, alignat, xalignat, xxalignat, +;; subequations (from AMS-LaTeX's amsmath.sty package) +;; - the \endnote macro (from endnotes.sty) +;; - Beqnarray (fancybox.sty) +;; - floatingfig (floatfig.sty) +;; - longtable (longtable.sty) +;; - figwindow, tabwindow (picinpar.sty) +;; - sidewaysfigure, sidewaystable (rotating.sty) +;; - subfigure, subfigure*, the \subfigure macro (subfigure.sty) +;; - supertabular (supertab.sty) +;; - wrapfigure (wrapfig.sty) ;; -;; CONFIGURATION EXAMPLES: -;; ======================= +;; If you want to use any other labeled environments or macros, you need +;; to configure RefTeX. ;; -;; Suppose you are working with AMS-LaTeX amsmath package (with its math -;; environments like `align', `multline' etc.). Here is how you would -;; configure RefTeX to recognize these environments: +;; Per Abrahamsens custom.el package provides a simple way to do +;; configuration. To try it out, use `M-x reftex-customize'. ;; -;; (setq reftex-label-alist '(AMSTeX)) +;; CONFIGURATION EXAMPLES +;; ---------------------- ;; -;; This is very easy since RefTeX has builtin support for AMS-LaTeX. -;; Suppose, however, you are also +;; Suppose you are working with AMS-LaTeX amsmath package (with its math +;; environments like `align', `multline' etc.). RefTeX is preconfigured to +;; recognize these - so there is nothing you have to do. ;; -;; - using "\newtheorem" in LaTeX in order to define two new environments -;; "Theorem" and "Axiom" like this: +;; Suppose you are also using `\newtheorem' in LaTeX in order to define two +;; new environments `theorem' and `axiom' ;; ;; \newtheorem{axiom}{Axiom} ;; \newtheorem{theorem}{Theorem} ;; -;; - making your figures not directly with the figure environment, but with -;; a macro like +;; to be used like this: ;; -;; \newcommand{\myfig}[4][tbp]{ -;; \begin{figure}[#1] -;; \epsimp[#4]{#2} -;; \caption{#3} -;; \end{figure}} -;; -;; which would be called like -;; -;; \myfig{filename}{\label{fig:13} caption text}{1} +;; \begin{axiom} +;; \label{ax:first} +;; .... +;; \end{axiom} ;; -;; Here is how to tell RefTeX to also recognize Theorem and Axiom as -;; labeled environments, and that any labels defined inside the \myfig -;; macro are figure labels: +;; So we need to tell RefTeX that `theorem' and `axiom' are new labeled +;; environments which define their own label categories. Here is how: ;; -;; (setq reftex-label-alist -;; '(AMSTeX -;; ("axiom" ?a "ax:" "~\\ref{%s}" nil ("Axiom" "Ax.")) -;; ("theorem" ?h "thr:" "~\\ref{%s}" t ("Theorem" "Theor." "Th.")) -;; ("\\myfig" ?f "fig:" nil 2))) +;; (setq reftex-label-alist +;; '(("axiom" ?a "ax:" "~\\ref{%s}" nil ("Axiom" "Ax.")) +;; ("theorem" ?h "thr:" "~\\ref{%s}" t ("Theorem" "Theor." "Th.")))) ;; -;; The type indicator characters ?a and ?h are used for prompts when -;; RefTeX queries for a label type. Note that "h" was chosen for "theorem" -;; since "t" is already taken by "table". Note that also "s", "f", "e", "n" -;; are taken by the standard environments. +;; The type indicator characters ?a and ?h are used for prompts when RefTeX +;; queries for a label type. Note that `h' was chosen for `theorem' since +;; `t' is already taken by `table'. Note that also `s', `f', `e', `i', `n' +;; are already used for standard environments. ;; The automatic labels for Axioms and Theorems will look like "ax:23" or ;; "thr:24". ;; The "\ref{%s}" is a format string indicating how to insert references to -;; these labels. The nil format in the \myfig entry means to use the same -;; format as other figure labels. -;; The next item indicates how to grab context of the label definition. -;; - t means to get it from a default location (from the beginning of a \macro -;; or after the \begin statement). t is *not* a good choice for eqnarray -;; and similar environments. +;; these labels. +;; The next item indicates how to grab context of the label definition. +;; - t means to get it from a default location (from the beginning of a +;; \macro or after the \begin statement). t is *not* a good choice for +;; eqnarray and similar environments. ;; - nil means to use the text right after the label definition. -;; - 2 means grab the 2nd macro argument: \myfig{xxx}{THIS IS CONTEXT}{1} ;; - For more complex ways of getting context, see the docstring of ;; `reftex-label-alist'. ;; The strings at the end of each entry are used to guess the correct label ;; type from the word before point when creating a reference. E.g. if you -;; write: "As we have shown in Theorem" and then press `C-)', RefTeX will -;; know that you are looking for a Theorem label and restrict the labels in -;; the menu to only these labels without even asking. -;; See also the documentation string of the variable `reftex-label-alist'. +;; write: "As we have shown in Theorem" and then press `C-c )', RefTeX will +;; know that you are looking for a theorem label and restrict the menu to +;; only these labels without even asking. +;; +;; Depending on how you would like the label insertion and selection for +;; the new environments to work, you might want to add the letters "a" and +;; "h" to some of the flags in the following variables: +;; +;; reftex-insert-label-flags reftex-label-menu-flags +;; +;; Suppose you want to make figures not directly with the figure +;; environment, but with a macro like +;; +;; \newcommand{\myfig}[5][tbp]{% +;; \begin{figure}[#1] +;; \epsimp[#5]{#2} +;; \caption{#3} +;; \label{#4} +;; \end{figure}} ;; -;; Depending on how you would like the label insertion and selection for the -;; new environments to work, you might want to add the letters "a" and "h" -;; to some of the flags in the following variables: +;; which would be called like +;; +;; \myfig[htp]{filename}{caption text}{label}{1} +;; +;; Now we also need to tell RefTeX that the 4th argument of the \myfig +;; macro is a figure label, and where to find the context. ;; -;; reftex-insert-label-flags -;; reftex-label-menu-flags +;; (setq reftex-label-alist +;; '(("axiom" ?a "ax:" "~\\ref{%s}" nil ("Axiom" "Ax.")) +;; ("theorem" ?h "thr:" "~\\ref{%s}" t ("Theorem" "Theor." "Th.")) +;; ("\\myfig[]{}{}{*}{}" ?f nil nil 3))) ;; -;; The individual flags in these variables can be set to t or nil to enable or -;; disable the feature for all label types. They may also contain a string of -;; label type letters in order to turn on the feature for those types only. +;; The empty pairs of brackets indicate the different arguments of the +;; \myfig macro. The `*' marks the label argument. `?f' indicates that +;; this is a figure label which will be listed together with labels from +;; normal figure environments. The nil entries for prefix and reference +;; format mean to use the defaults for figure labels. The `3' for the +;; context method means to grab the 3rd macro argument - the caption. +;; +;; As a side effect of this configuration, `reftex-label' will now insert +;; the required naked label (without the \label macro) when point is +;; directly after the opening parenthesis of a \myfig macro argument. ;; ;; ----- -;; If you are writing in a language different from English you might want to -;; add magic words for that language. Here is a German example: ;; -;; (setq reftex-label-alist +;; If you are writing in a language different from English you might want +;; to add magic words for that language. Here is a German example: +;; +;; (setq reftex-label-alist ;; '((nil ?s nil nil nil ("Kapitel" "Kap." "Abschnitt" "Teil")) ;; (nil ?e nil nil nil ("Gleichung" "Gl.")) ;; (nil ?t nil nil nil ("Tabelle")) ;; (nil ?f nil nil nil ("Figur" "Abbildung" "Abb.")) -;; (nil ?n nil nil nil ("Punkt")))) +;; (nil ?n nil nil nil ("Anmerkung" "Anm.")) +;; (nil ?i nil nil nil ("Punkt")))) ;; ;; Using nil as first item in each entry makes sure that this entry does ;; not replace the original entry for that label type, but just adds magic @@ -259,12 +263,25 @@ ;; ;; ----- ;; +;; Normally, RefTeX inserts equation references with parenthesis like +;; "~(\ref{KEY})". If you want to change this to square brackets, use +;; +;; (setq reftex-label-alist '((nil ?e nil "~[\\ref{%s}]" nil nil))) +;; +;; In order to use the AMS-LaTeX \eqref macro instead, either of the +;; following lines does the job. +;; +;; (setq reftex-label-alist '((nil ?e nil "~\\eqref{%s}" nil nil))) +;; (setq reftex-label-alist '(AMSTeX)) +;; +;; ---- +;; ;; By default, citations are inserted simply as \cite{KEY}. You can have ;; more complex citation commands with many available packages, most ;; notably the harvard and natbib packages. RefTeX can be configured to -;; support these and other styles by setting the variable reftex-cite-format. -;; E.g., for the natbib package you would use -;; +;; support these and other styles by setting the variable +;; `reftex-cite-format'. E.g., for the natbib package you would use +;; ;; (setq reftex-cite-format 'natbib) ;; ;; This can also be done as a file variable. For the full list of builtin @@ -274,18 +291,61 @@ ;; ----- ;; - Loading reftex.el runs the hook `reftex-load-hook'. ;; - Turning on reftex-mode runs `reftex-mode-hook'. -;; - Creating the master buffer runs `reftex-make-master-buffer-hook' -;; on the master buffer just before parsing starts. +;; - Files visited literally are processed with +;; `reftex-initialize-temporary-buffers' if that is a list of functions. +;; +;; CONFIGURATION VARIABLES +;; ----------------------- +;; +;; The best way to learn about all configuration variables is via the +;; browser interface of the custom library. For reference, I am giving +;; here a complete list. ;; +;; ;; Defining label environments +;; reftex-default-label-alist-entries +;; reftex-label-alist +;; reftex-use-text-after-label-as-context +;; reftex-section-levels +;; reftex-default-context-regexps +;; ;; Label insertion +;; reftex-insert-label-flags +;; reftex-derive-label-parameters +;; reftex-label-illegal-re +;; reftex-abbrev-parameters +;; ;; Label referencing +;; reftex-label-menu-flags +;; reftex-level-indent +;; reftex-refontify-context +;; reftex-guess-label-type +;; ;; BibteX citation configuration +;; reftex-bibpath-environment-variables +;; reftex-bibfile-ignore-list +;; reftex-sort-bibtex-matches +;; reftex-cite-format +;; reftex-comment-citations +;; reftex-cite-comment-format +;; reftex-cite-punctuation +;; ;; Table of contents configuration +;; reftex-toc-follow-mode +;; ;; Fine-tuning the parser +;; reftex-keep-temporary-buffers +;; reftex-initialize-temporary-buffers +;; reftex-enable-partial-scans +;; reftex-save-parse-info +;; ;; Miscellaneous configurations +;; reftex-extra-bindings +;; reftex-plug-into-AUCTeX +;; reftex-use-fonts +;; reftex-auto-show-entry +;; reftex-load-hook +;; reftex-mode-hook ;;------------------------------------------------------------------------- ;; ;; KEY BINDINGS +;; ============ ;; -;; All important functions of RefTeX can be reached from its menu which -;; is installed in the menu bar as "Ref" menu. Only the more frequently used -;; functions have key bindings. -;; -;; Here is the default set of keybindings from RefTeX. +;; All RefTeX commands can be reached from its menu, the `Ref' menu on the +;; menu bar. More frequently used commands have key bindings: ;; ;; C-c = reftex-toc ;; C-c ( reftex-label @@ -293,9 +353,9 @@ ;; C-c [ reftex-citation ;; C-c & reftex-view-crossref ;; -;; I've used these bindings in order to avoid interfering with AUCTeX's -;; settings. Personally, I also bind some functions in the C-c LETTER -;; map for easier access: +;; These keys are chosen to avoid interfering with AUCTeX's settings. +;; Personally, I also bind some functions in the C-c LETTER map for +;; easier access: ;; ;; C-c t reftex-toc ;; C-c l reftex-label @@ -306,20 +366,101 @@ ;; C-c g reftex-grep-document ;; ;; If you want to copy those as well, set in your .emacs file: -;; +;; ;; (setq reftex-extra-bindings t) ;; ;; It is possible to bind the function for viewing cross references to a -;; mouse event. Something like the following in .emacs will do the trick: +;; mouse event. Something like the following will do the trick: ;; -;; (add-hook 'reftex-load-hook +;; (add-hook 'reftex-load-hook ;; '(lambda () -;; (define-key reftex-mode-map [(alt mouse-1)] +;; (define-key reftex-mode-map [(shift mouse-2)] ;; 'reftex-mouse-view-crossref))) -;; +;;------------------------------------------------------------------------- +;; +;; REFTEX AND MULTIFILE DOCUMENTS +;; ============================== +;; +;; The following is relevant when using RefTeX for multi-file documents: +;; +;; o RefTeX has full support for multifile documents. You can edit parts +;; of several (multifile) documents at the same time without conflicts. +;; RefTeX provides functions to run `grep', `search' and `query-replace' +;; on all files which are part of a multifile document. +;; +;; o All files belonging to a multifile document should have a File +;; Variable (`TeX-master' for AUCTeX or `tex-main-file' for the standard +;; Emacs LaTeX mode) set to the name of the master file. See the +;; documentation of your (La)TeX mode and the Emacs documentation on +;; file variables: [Emacs/Customization/Variables/File Variables]. +;; +;; o The context of a label definition must be found in the same file as +;; the label itself in order to be processed correctly by RefTeX. The +;; only exception is that section labels referring to a section statement +;; outside the current file can still use that section title as context. ;;------------------------------------------------------------------------- ;; +;; REFERENCES TO OTHER DOCUMENTS +;; ============================= +;; +;; RefTeX supports the LaTeX package `xr', which makes it possible to +;; reference labels defined in another document. See the documentation on +;; `xr' for details. +;; When the document is set up to work with `xr', you can use the `x' key +;; in the reference label menu to switch to the label menu of an external +;; document and select any labels from there. In the *toc* buffer, the +;; `x' key can be used to switch to the table of contents of an external +;; document. +;; +;; For this kind of inter-document cross references, saving of parsing +;; information can mean a large speed-up. +;; +;; (setq reftex-save-parse-info t) +;; +;;------------------------------------------------------------------------- +;; +;; OPTIMIZATIONS FOR LARGE DOCUMENTS +;; ================================= +;; +;; The default settings of RefTeX ensure a safe ride for beginners and +;; casual users. However, when using RefTeX for a large project and/or on +;; a small computer, there are ways to improve speed and memory usage. +;; +;; o RefTeX will load other parts of a multifile document as well as BibTeX +;; database files for lookup purposes. These buffers are kept, so that +;; subsequent use of the same files is fast. If you can't afford keeping +;; these buffers around, and if you can live with a speed penalty, try +;; +;; (setq reftex-keep-temporary-buffers nil) +;; +;; o The `C-u' prefix on the major RefTeX commands `reftex-label', +;; `reftex-reference', `reftex-citation' and `reftex-toc' initiates +;; re-parsing of the entire document in order to update the parsing +;; information. For a large document this can be unnecessary, in +;; particular if only one file has changed. RefTeX can be configured to +;; do partial scans instead of full ones. `C-u' re-parsing then does +;; apply only to the current buffer and files included from it. +;; Likewise, the `r' key in both the label menu and the table-of-contents +;; buffer will only prompt scanning of the file in which the label or +;; section macro near the cursor was defined. Re-parsing of the entire +;; document is still available by using `C-u C-u' as a prefix, or the +;; capital `R' key in the menus. To use this feature, try +;; +;; (setq reftex-enable-partial-scans t) +;; +;; o Even with partial scans enabled, RefTeX still has to make one full +;; scan, when you start working with a document. To avoid this, parsing +;; information can stored in a file. The file `MASTER.rel' is used for +;; storing information about a document with master file MASTER.tex. +;; It is written each time RefTeX parses (part of) the document, and +;; restored when you begin working with a document in a new editing +;; session. To use this feature, put into .emacs: +;; +;; (setq reftex-save-parse-info t) +;;---------------------------------------------------------------------------- +;; ;; RELATED PACKAGES +;; ================ ;; ;; AUCTeX ;; ------ @@ -329,33 +470,33 @@ ;; ;; http://www.sunsite.auc.dk/auctex/ ;; -;; Instead of using the RefTeX functions described above directly, you -;; can also use them indirectly through AUCTeX (>9.7p). RefTeX provides -;; several interface functions which can be used as replacement for -;; corresponding AUCTeX functions dealing with labels and citations. -;; In this way you can work normally with AUCTeX and use RefTeX +;; Instead of using the RefTeX functions described above directly, you can +;; also use them indirectly, through AUCTeX (version 9.8a or later). +;; RefTeX provides several interface functions which can be used as +;; replacement for corresponding AUCTeX functions dealing with labels and +;; citations. In this way you can work normally with AUCTeX and use RefTeX ;; internals to create and complete labels and citation keys. ;; ;; `reftex-label' can be used as the `LaTeX-label-function' which does -;; label insertion when new environments are created with C-c C-e. +;; label insertion when new environments are created with `C-c C-e'. ;; ;; `reftex-arg-label', `reftex-arg-ref' and `reftex-arg-cite' can replace -;; the corresponding `TeX-arg-...' functions. E.g. when you insert a -;; label macro with `C-c RET label RET', RefTeX will be transparently used -;; to create the label. +;; the corresponding `TeX-arg-...' functions. E.g. when you insert a label +;; macro with `C-c RET label RET', RefTeX will be transparently used to +;; create the label. ;; -;; In order to plug all 4 functions into AUCTeX, use in .emacs: +;; In order to plug all 4 functions into AUCTeX, use: ;; ;; (setq reftex-plug-into-AUCTeX t) ;; -;; You may also choose to plug in only some of these functions. See -;; the doc string of `reftex-plug-into-AUCTeX'. +;; You may also choose to plug in only some of these functions. See the +;; docstring of `reftex-plug-into-AUCTeX'. ;; ;; AUCTeX can support RefTeX via style files. A style file may contain ;; calls to `reftex-add-to-label-alist' which defines additions to -;; `reftex-label-alist'. The argument taken by this function must have -;; the same format as `reftex-label-alist'. The `amsmath.el' style file -;; of AUCTeX (>9.7p) for example contains the following: +;; `reftex-label-alist'. The argument taken by this function must have the +;; same format as `reftex-label-alist'. The `amsmath.el' style file of +;; AUCTeX (>9.7p) for example contains the following: ;; ;; (TeX-add-style-hook "amsmath" ;; (function @@ -371,125 +512,93 @@ ;; (lambda () ;; (if (featurep 'reftex) ;; (reftex-add-to-label-alist -;; '(("proposition" ?p "prop:" "~\\ref{%s}" t +;; '(("proposition" ?p "prop:" "~\\ref{%s}" t ;; ("Proposition" "Prop.")))))))) ;; ;; Bib-cite.el ;; ----------- -;; Once you have written a document with labels, refs and citations, -;; it can be nice to read such a file like a hypertext document. -;; RefTeX has some support for that (`reftex-view-crossref', -;; `reftex-search-document'). A more elegant interface with mouse -;; support and links into Hyperbole is provided (among other things) -;; by Peter S. Galbraith's `bib-cite.el'. There is some overlap in the -;; functionalities of Bib-cite and RefTeX. Bib-cite.el comes bundled -;; with AUCTeX. You can also get the latest version from +;; Once you have written a document with labels, refs and citations, it can +;; be nice to read such a file like a hypertext document. RefTeX has some +;; support for that (`reftex-view-crossref', `reftex-search-document'). A +;; more elegant interface with mouse support and links into Hyperbole is +;; provided (among other things) by Peter S. Galbraith's `bib-cite.el'. +;; There is some overlap in the functionalities of Bib-cite and RefTeX. +;; Bib-cite.el comes bundled with AUCTeX. You can also get the latest +;; version from ;; ;; ftp://ftp.phys.ocean.dal.ca/users/rhogee/elisp/bib-cite.el -;; -;;------------------------------------------------------------------------- -;; -;; PERFORMANCE ISSUES -;; -;; 1. RefTeX will load other parts of a multifile document as well as BibTeX -;; database files for lookup purposes. These buffers are kept, so that -;; subsequent lookup in the same files is fast. For large documents and -;; large BibTeX databases, this can use up a lot of memory. If you have -;; more time than memory, try the following option, which will remove -;; buffers created for lookup after use. -;; -;; (setq reftex-keep-temporary-buffers nil) -;; -;; 2. Parsing the document for labels and their context can be slow. -;; Therefore, RefTeX does it just once automatically. Further parsing -;; happens only on user request -;; - with a raw C-u prefix arg to any of the functions `reftex-label', -;; `reftex-reference', `reftex-citation', `reftex-toc'. -;; - with the `r' key from the label selection menu or the *toc* buffer. -;; -;; *** If you use `reftex-label' to create labels, the list will be -;; *** updated internally, so that no extra parsing is required. -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;--------------------------------------------------------------------------- ;; ;; KNOWN BUGS AND WORK-AROUNDS +;; =========================== ;; -;; o If you change `reftex-label-alist' in an editing session, you need to -;; reset reftex with `M-x reftex-reset-mode' in order to make these -;; changes effective. Changes introduced with the function -;; `reftex-add-to-label-alist' as well as changes applied from the -;; customization buffer automatically trigger a reset. +;; o \input, \include, \bibliography and \section (etc.) statements have +;; to be first on a line (except for white space). ;; -;; o At times the short context shown by RefTeX may not be what you want. -;; In particular, eqnarray environments can be difficult to parse. -;; RefTeX's default behavior for eqnarrays is to scan backwards to either -;; a double backslash or the beginning of the environment. If this gives -;; unsatisfactory results, make it a habit to place the label *before* -;; each equation -;; -;; \begin{eqnarray} -;; \label{eq:1} -;; E = \gamma m c^2 \\ -;; \label{eq:2} -;; \gamma = \sqrt{1-v^2/c^2} -;; \end{eqnarray} -;; -;; and turn off parsing for context in equation and eqnarray environments -;; with -;; -;; (setq reftex-use-text-after-label-as-context "e"). +;; o RefTeX sees also labels in regions commented out and will refuse to +;; make duplicates of such a label. This is considered to be a feature. ;; -;; o RefTeX keeps only one global copy of the configuration variables. +;; o When using partial scans (`reftex-enable-partial-scans'), the section +;; numbers in the table of contents may eventually become wrong. A full +;; scan will fix this. +;; +;; o RefTeX keeps only a global copy of the configuration variables. ;; Also, any additions from style files go into a global variable. ;; Practically, this should not be a problem. Theoretically, it could ;; give conflicts if two documents used environments with identical ;; names, but different associated label types. -;; -;; o Input, include, bibliography and section statements have to be first -;; on a line (except for white space) in order to be seen by RefTeX. -;; -;; o When the document is scanned, RefTeX creates a large "master" buffer -;; containing the entire document instead of scanning the individual -;; files one by one. I hope to change this eventually. +;; +;; o When using packages which make the buffer representation of a file +;; different from its disk representation (e.g. x-symbol, isotex, +;; iso-cvt) you may find that RefTeX's parsing information sometimes +;; reflects the disk state of a file. This happens only in *unvisited* +;; parts of a multifile document, because RefTeX visits these files +;; literally for speed reasons. Then both short context and section +;; headings may look different from what you usually see on your screen. +;; In rare cases `reftex-toc' may have problems to jump to an affected +;; section heading. There are three possible ways to deal with this: ;; -;; o Creating the master buffer bypasses `find-file-hook' as well as -;; TeX/LaTeX mode hooks for efficiency reasons. If any of the relevant -;; hooks contains functions filtering (La)TeX files (e.g. isotex), these -;; functions should go into `reftex-make-master-buffer-hook' as well. +;; - (setq reftex-keep-temporary-buffers t) +;; This implies that RefTeX will load all parts of a multifile +;; document into Emacs (i.e. there will be no temporary buffers). +;; - (setq reftex-initialize-temporary-buffers t) +;; This means full initialization of temporary buffers. It involves +;; a penalty when the same file is used for lookup often. +;; - Set `reftex-initialize-temporary-buffers' to a list of hook +;; functions doing a minimal initialization. ;; -;; o If you have two identical section headings in the same file, -;; `reftex-toc' will only let you jump to the first one because it searches -;; for the section heading from the beginning of the file. You can work -;; around this by changing one of the section titles in a way LaTeX does -;; not see, e.g. with extra white space. RefTeX will distinguish -;; \section{Introduction} from \section{ Introduction}. +;; You might also want to check the variable `reftex-refontify-context'. ;; -;; o RefTeX needs a \label macro to identify a label during parsing. Some -;; packages, however, define environments and macros which require a naked -;; label as argument. This is currently not possible with RefTeX. It -;; will be in version 3.00. +;; o Some nasty :-# packages use an additional argument to a \begin macro +;; to specify a label. E.g. Lamport's "pf.sty" uses both ;; -;; o RefTeX sees also labels in regions commented out and will refuse to -;; make duplicates of such a label. This is considered to be a feature. -;; -;; o When RefTeX tries to show a window full of context from inside a -;; section hidden with `outline-minor-mode', it will unhide that section. -;; This change will not be reversed automatically. +;; \step{LABEL}{CLAIM} and \begin{step+}{LABEL} +;; CLAIM +;; \end{step+} +;; +;; We need to trick RefTeX into swallowing this: ;; -;;--------------------------------------------------------------------------- -;; -;; TO DO +;; ;; Configuration for Lamport's pf.sty +;; (setq reftex-label-alist +;; '(("\\step{*}{}" ?p "st:" "~\\stepref{%s}" 2 ("Step" "St.")) +;; ("\\begin{step+}{*}" ?p "st:" "~\\stepref{%s}" 1000))) ;; -;; Rewriting the parser so that it can parse the file without making a -;; master buffer, save parsing information and reparse only parts of -;; the document. This will make RefTeX better suited for very large -;; projects. +;; The first line is just a normal configuration for a macro. For the +;; `step+' environment we actually tell RefTeX to look for the *macro* +;; "\begin{step+}" and interprete the *first* argument (which in reality +;; is a second argument to the macro \begin) as a label of type ?p. +;; Argument count for this macro starts only after the {step+}, also +;; when specifying how to get context. ;; -;; Deal with naked labels. -;; +;; o In XEmacs 19.15, the overlay library has a bug. RefTeX does not +;; suffer from it, but since it loads the library, other packages like +;; GNUS will switch from extents to overlays and hit the bug. Upgrade +;; to XEmacs 20, or fix the overlay library (in line 180 of overlay.el, +;; change `(list before after)' to `(cons before after)'). ;;--------------------------------------------------------------------------- ;; ;; AUTHOR +;; ====== ;; ;; Carsten Dominik <dominik@strw.LeidenUniv.nl> ;; @@ -503,10 +612,11 @@ ;; THANKS TO: ;; --------- ;; At least the following people have invested time to test and bug-fix -;; reftex.el. Some have send patches for fixes or new features. +;; reftex.el. Some have send patches for fixes or new features, or came +;; up with useful ideas. ;; ;; Stephen Eglen <stephene@cogs.susx.ac.uk> -;; F.E.Burstall <F.E.Burstall@maths.bath.ac.uk> +;; F.E. Burstall <F.E.Burstall@maths.bath.ac.uk> ;; Karl Eichwalder <ke@ke.Central.DE> ;; Laurent Mugnier <mugnier@onera.fr> ;; Rory Molinari <molinari@yunt.math.lsa.umich.edu> @@ -515,10 +625,13 @@ ;; Allan Strand <astrand@trillium.NMSU.Edu> ;; Adrian Lanz <lanz@waho.ethz.ch> ;; Jan Vroonhof <vroonhof@math.ethz.ch> +;; Alastair Burt <alastair.burt@dfki.de> +;; Dieter Kraft <dkraft@acm.org> +;; Robin S. Socha <r.socha@franck.pc.uni-koeln.de> ;; -;; The view crossref feature was inspired by the similar function in +;; The view crossref feature was inspired by the similar function in ;; Peter S. Galbraith's bib-cite.el. -;; +;; ;; Finally thanks to Uwe Bolick <bolick@physik.tu-berlin.de> who first ;; got me (some years ago) into supporting LaTeX labels and references ;; with an Editor (which was MicroEmacs at the time). @@ -528,6 +641,8 @@ ;;; Code: +(eval-when-compile (require 'cl)) + ;; Stuff that needs to be there when we use defcustom ;; -------------------------------------------------- @@ -541,14 +656,156 @@ (setq reftex-tables-dirty t) (set symbol value))) +(eval-and-compile + (defmacro reftex-fp (n) + (if (fboundp 'forward-point) + (list 'forward-point n) + (list '+ '(point) n)))) + ;;; Begin of Configuration Section ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Define the two constants which are needed during compilation + +(eval-and-compile +(defconst reftex-label-alist-builtin + '( + ;; Some aliases, mostly for backward compatibility + (Sideways "Alias for -->rotating" (rotating)) + (AMSTeX "amsmath with eqref macro" + ((nil ?e nil "~\\eqref{%s}") + amsmath)) + + ;; Individual package defaults + (amsmath "AMS-LaTeX math environments" + (("align" ?e nil nil eqnarray-like) + ("gather" ?e nil nil eqnarray-like) + ("multline" ?e nil nil t) + ("flalign" ?e nil nil eqnarray-like) + ("alignat" ?e nil nil alignat-like) + ("xalignat" ?e nil nil alignat-like) + ("xxalignat" ?e nil nil alignat-like) + ("subequations" ?e nil nil t))) + + (endnotes "The \\endnote macro" + (("\\endnote[]{}" ?n nil nil 2 ("Endnote")))) + + (fancybox "The Beqnarray environment" + (("Beqnarray" ?e nil nil eqnarray-like))) + + (floatfig "The floatingfigure environment" + (("floatingfigure" ?f nil nil caption))) + + (longtable "The longtable environment" + (("longtable" ?t nil nil caption))) + + (picinpar "The figwindow and tabwindow environments" + (("figwindow" ?f nil nil 1) + ("tabwindow" ?f nil nil 1))) + + (rotating "Sidewaysfigure and table" + (("sidewaysfigure" ?f nil nil caption) + ("sidewaystable" ?t nil nil caption))) + + (subfigure "Subfigure environments/macro" + (("subfigure" ?f nil nil caption) + ("subfigure*" ?f nil nil caption) + ("\\subfigure[]{}" ?f nil nil 1))) + + (supertab "Supertabular environment" + (("supertabular" ?t nil nil "\\tablecaption{"))) + + (wrapfig "The wrapfigure environment" + (("wrapfigure" ?f nil nil caption))) + + ;; The LaTeX core stuff + (LaTeX "LaTeX default environments" + (("section" ?s "sec:" "~\\ref{%s}" (nil . t) + ("Part" "Chapter" "Chap." "Section" "Sec." "Sect." "Paragraph" "Par." + "\\S" "Teil" "Kapitel" "Kap." "Abschnitt" )) + + ("enumerate" ?i "item:" "~\\ref{%s}" item + ("Item" "Punkt")) + + ("equation" ?e "eq:" "~(\\ref{%s})" t + ("Equation" "Eq." "Eqn." "Gleichung" "Gl.")) + ("eqnarray" ?e "eq:" nil eqnarray-like) + + ("figure" ?f "fig:" "~\\ref{%s}" caption + ("Figure" "Fig." "Abbildung" "Abb.")) + ("figure*" ?f nil nil caption) + + ("table" ?t "tab:" "~\\ref{%s}" caption + ("Table" "Tab." "Tabelle")) + ("table*" ?t nil nil caption) + + ("\\footnote[]{}" ?n "note:" "~\\ref{%s}" 2 + ("Footnote" "Note")) + + ("any" ?\ " " "\\ref{%s}" nil))) + + ) + "The default label environment descriptions. +Lower-case symbols correspond to a style file of the same name in the LaTeX +distribution. Mixed-case symbols are convenience aliases.") + +(defconst reftex-cite-format-builtin + '( + (default "Default macro \\cite{%l}" + "\\cite{%l}") + (natbib "The Natbib package" + ((?\C-m . "\\cite{%l}") + (?t . "\\citet{%l}") + (?T . "\\citet*{%l}") + (?p . "\\citep{%l}") + (?P . "\\citep*{%l}") + (?e . "\\citep[e.g.][]{%l}") + (?a . "\\citeauthor{%l}") + (?y . "\\citeyear{%l}"))) + (harvard "The Harvard package" + ((?\C-m . "\\cite{%l}") + (?p . "\\cite{%l}") + (?t . "\\citeasnoun{%l}") + (?n . "\\citeasnoun{%l}") + (?s . "\\possessivecite{%l}") + (?e . "\\citeaffixed{%l}{?}") + (?y . "\\citeyear{%l}") + (?a . "\\citename{%l}"))) + (chicago "The Chicago package" + ((?\C-m . "\\cite{%l}") + (?t . "\\citeN{%l}") + (?T . "\\shortciteN{%l}") + (?p . "\\cite{%l}") + (?P . "\\shortcite{%l}") + (?a . "\\citeA{%l}") + (?A . "\\shortciteA{%l}") + (?y . "\\citeyear{key}"))) + (astron "The Astron package" + ((?\C-m . "\\cite{%l}") + (?p . "\\cite{%l}" ) + (?t . "%2a (\\cite{%l})"))) + (author-year "Do-it-yourself Author-year" + ((?\C-m . "\\cite{%l}") + (?t . "%2a (%y)\\nocite{%l}") + (?p . "(%2a %y\\nocite{%l})"))) + (locally "Full info in parenthesis" + "(%2a %y, %j %v, %P, %e: %b, %u, %s %<)") + ;; undocumented feature: `%<' kills white space and punctuation locally. + ) + "Builtin versions of for the citation format. +The following conventions are valid for all alist entries: +`?\C-m' should always point to a straight \\cite{%l} macro. +`?t' should point to a textual citation (citation as a noun). +`?p' should point to a parenthetical citation.") +) + ;; Configuration Variables and User Options for RefTeX ------------------ (defgroup reftex nil "LaTeX label and citation support." :tag "RefTeX" - :link '(url-link :tag "Home Page" "http://strw.leidenuniv.nl/~dominik/Tools/") + :link '(url-link :tag "Home Page" + "http://strw.leidenuniv.nl/~dominik/Tools/") + :link '(emacs-commentary-link :tag "Commentary in reftex.el" "reftex.el") :prefix "reftex-" :group 'tex) @@ -561,8 +818,9 @@ (customize-browse 'reftex)) ((fboundp 'customize-group) (customize-group 'reftex)) - (t - (customize 'reftex)))) + ((fboundp 'customize) + (customize 'reftex)) + (t (error "Custom.el not available")))) (defun reftex-show-commentary () "Use the finder to view the file documentation from `reftex.el'." @@ -580,35 +838,85 @@ "Definition of environments and macros to do with label." :group 'reftex-label-support) +;; Make a constant for the customization stuff +(eval-and-compile + (defconst reftex-tmp + '((const :tag "Default position" t) + (const :tag "After label" nil) + (number :tag "Macro arg nr" 1) + (regexp :tag "Regexp" "") + (const :tag "Caption in float" caption) + (const :tag "Item in list" item) + (const :tag "Eqnarray-like" eqnarray-like) + (const :tag "Alignat-like" alignat-like) + (symbol :tag "Function" my-func)))) + +(defcustom reftex-default-label-alist-entries + '(amsmath endnotes fancybox floatfig longtable picinpar + rotating subfigure supertab wrapfig LaTeX) + "Default label alist specifications. LaTeX should be the last entry. +This list describes the default label environments RefTeX should always use. +It is probably a mistake to remove the LaTeX symbol from this list. + +The options include: +LaTeX The standard LaTeX environments. +Sideways The sidewaysfigure and sidewaystable environments. +AMSTeX The math environments in the AMS-LaTeX amsmath package. + +For the full list of options, try + +M-x customize-variable RET reftex-default-label-alist-entries RET." + :group 'reftex-defining-label-environments + :set 'reftex-set-dirty + :type `(set + :indent 4 + :inline t + :greedy t + ,@(mapcar + (function + (lambda (x) + (list 'const ':tag (concat (symbol-name (nth 0 x)) + ": " (nth 1 x)) + (nth 0 x)))) + reftex-label-alist-builtin))) + (defcustom reftex-label-alist nil "Alist with information on environments for \\label-\\ref use. -See the definition of `reftex-label-alist-builtin' for examples. This variable -should define additions and changes to the default. The only things you MUST -NOT change is that `?s' is the type indicator for section labels and SPACE is -for the `any' label type. These are hard-coded at other places in the code. - -Changes to this variable after RefTeX has been loaded become only -effective when RefTeX is reset with \\[reftex-reset-mode]. - -Each list entry is a list describing an environment or macro carrying a -label. The elements of each list entry are: + +This docstring is easier to understand after reading the configuration +examples in `reftex.el'. Looking at the builtin defaults in the constant +`reftex-label-alist-builtin' may also be instructive. + +Set this variable to define additions and changes to the default. The only +things you MUST NOT change is that `?s' is the type indicator for section +labels, and SPC for the `any' label type. These are hard-coded at other +places in the code. + +Each list entry describes either an environment carrying a counter for use +with \\label and \\ref, or a LaTeX macro defining a label as (or inside) +one of its arguments. The elements of each list entry are: 0. Name of the environment (like \"table\") or macro (like \"\\\\myfig\"). + For macros, indicate the macro arguments for best results, as in + \"\\\\myfig[]{}{}{*}{}\". Use square brackets for optional arguments, + a star to mark the label argument, if any. The macro does not have to + have a label argument - you could also use \\label{..} inside one of + its arguments. Special names: `section' for section labels, `any' to define a group which contains all labels. - This may also be nil if this entry is only meant to change some settings + This may also be nil if the entry is only meant to change some settings associated with the type indicator character (see below). -1. Type indicator character, like `?t'. - The type indicator is a single character used in prompts for - label types. It must be a printable character. The same character - may occur several times in this list, to cover cases in which different - environments carry the same label type (like equation and eqnarray). +1. Type indicator character, like `?t', must be a printable ASCII character. + The type indicator is a single character which defines a label type. + Any label inside the environment or macro is assumed to belong to this + type. The same character may occur several times in this list, to cover + cases in which different environments carry the same label type (like + `equation' and `eqnarray'). 2. Label prefix string, like \"tab:\". The prefix is a short string used as the start of a label. It may be the - empty string. If `nil', a prefix will be constructed from the typekey. - The prefix may contain the following `%' escapes: + empty string. The prefix may contain the following `%' escapes: %f Current file name with directory and extension stripped. %F Current file name relative to directory of master file. %u User login name, on systems which support this. @@ -623,17 +931,21 @@ 4. Indication on how to find the short context. - If nil, use the text following the \\label{...} macro. - If t, use - - text following the \\begin{...} statement of environments - (not a good choice in in eqnarray or enumerate environments!) - the section heading for section labels. - - the begin of the macro for macros. - - If an integer, use the nth argument of the macro. If there are less - than n arguments (parenthesis pairs), use text after the last one. + - text following the \\begin{...} statement of environments. + (not a good choice for environments like eqnarray or enumerate, + where one has several labels in a single environment). + - text after the macro name (stearting with the first arg) for macros. + - If an integer, use the nth argument of the macro. As a special case, + 1000 means to get text after the last macro argument. - If a string, use as regexp to search *backward* from the label. Context is then the text following the end of the match. E.g. putting this to - \"\\\\\\\\caption{\" will use the beginning of the caption in a figure - or table environment. + \"\\\\\\\\caption{\" will use the caption in a figure or table + environment. \"\\\\\\\\begin{eqnarray}\\\\|\\\\\\\\\\\\\\\\\" works for eqnarrays. + - If any of `caption', `item', `eqnarray-like', `alignat-like', this + symbol will internally be translated into an appropriate regexp + (see also the variable `reftex-default-context-regexps'). - If a function, call this function with the name of the environment/macro as argument. On call, point will be just after the \\label macro. The function is expected to return a suitable context string. It should @@ -668,91 +980,47 @@ Any list entry may also be a symbol. If that has an association in `reftex-label-alist-builtin', the cdr of that association is spliced into the -list. See the AMSTeX configuration example in the comment section of -`reftex.el'." +list. However, builtin defaults should normally be set here but with the +variable `reftex-default-label-alist-entries." :group 'reftex-defining-label-environments :set 'reftex-set-dirty :type - '(repeat - :inline t - (radio - :value ("" ?a nil nil t nil) - (choice - :tag "Builtin" + `(repeat + (choice + :value ("" ?a nil nil nil nil) + (list :tag "Detailed label alist entry" + :value ("" ?a nil nil nil nil) + (choice :tag "Environment or \\macro " + (const :tag "Ignore, just use typekey" nil) + (string "")) + (character :tag "Typekey character " ?a) + (choice :tag "Label prefix string " + (const :tag "Default" nil) + (string :tag "String" "lab:")) + (choice :tag "Label reference format" + (const :tag "Default" nil) + (string :tag "String" "~\\ref{%s}")) + (choice :tag "Context" + (choice + :tag "1 method" + ,@reftex-tmp) + (cons :tag "Split methods" + (choice + :tag " Display context " + ,@reftex-tmp) + (choice + :tag " Derive label context" + ,@reftex-tmp))) + (repeat :tag "List of Magic Words" (string))) + (choice + :tag "Package" :value AMSTeX - ;; Update here with: update-builtin-label-1 - (const :tag "Sideways : Alias for -->rotating" Sideways) - (const :tag "AMSTeX : Alias for -->amsmath" AMSTeX) - (const :tag "amsmath : AMS math environments" amsmath) - (const :tag "longtable: The longtable environment" longtable) - (const :tag "rotating : Sidewaysfigure and table" rotating) - (const :tag "subfigure: Subfigure environments/macro" subfigure) - (const :tag "LaTeX : LaTeX default environments" LaTeX)) - (list :tag "Detailed custom entry" - (choice :tag "Environment or \\macro " - (const :tag "Ignore, just use typekey" nil) - (string "")) - (character :tag "Typekey character " ?a) - (choice :tag "Label prefix string " - (const :tag "Default" nil) - (string :tag "String" "lab:")) - (choice :tag "Label reference format" - (const :tag "Default" nil) - (string :tag "String" "~\\ref{%s}")) - (choice :tag "Context" - (choice - :tag "1 method" - (const :tag "Default position" t) - (const :tag "After label" nil) - (number :tag "Macro arg nr" 1) - (regexp :tag "Regexp" "") - (symbol :tag "Function" my-func)) - (cons :tag "2 different methods" - (choice - :tag " Display context " - (const :tag "Default position" t) - (const :tag "After label" nil) - (number :tag "Macro arg nr" 1) - (regexp :tag "Regexp" "") - (symbol :tag "Function" my-func)) - (choice - :tag " Derive label context" - (const :tag "Default position" t) - (const :tag "After label" nil) - (number :tag "Macro arg nr" 1) - (regexp :tag "Regexp" "") - (symbol :tag "Function" my-func)))) - (repeat :tag "List of Magic Words" (string)))))) - -(defcustom reftex-default-label-alist-entries '(Sideways LaTeX) - "Default label alist specifications. LaTeX should be the last entry. -This list describes the default label environments RefTeX should always use -in addition to the specifications in reftex-label-alist. It is probably a -mistake to remove the LaTeX symbol from this list. - -The options include: -LaTeX The standard LaTeX environments -Sideways The sidewaysfigure and sidewaystable environments -AMSTeX The math environments in the AMS_LaTeX amsmath package - -For the full list of options, try - -M-x customize-variable RET reftex-default-label-alist-entries RET." - :group 'reftex-defining-label-environments - :set 'reftex-set-dirty - :type '(set - :indent 4 - :inline t - :greedy t - ;; Update here with: update-builtin-label-2 - (const :tag "Sideways : Alias for -->rotating" Sideways) - (const :tag "AMSTeX : Alias for -->amsmath" AMSTeX) - (const :tag "amsmath : AMS math environments" amsmath) - (const :tag "longtable: The longtable environment" longtable) - (const :tag "rotating : Sidewaysfigure and table" rotating) - (const :tag "subfigure: Subfigure environments/macro" subfigure) - (const :tag "LaTeX : LaTeX default environments" LaTeX)) - ) + ,@(mapcar + (function + (lambda (x) + (list 'const ':tag (concat (symbol-name (nth 0 x))); ": " (nth 1 x)) + (nth 0 x)))) + reftex-label-alist-builtin))))) (defcustom reftex-use-text-after-label-as-context nil "*t means, grab context from directly after the \\label{..} macro. @@ -764,8 +1032,8 @@ :group 'reftex-defining-label-environments :set 'reftex-set-dirty :type '(choice - (const :tag "on" t) (const :tag "off" nil) - (string :tag "Selected label types"))) + (const :tag "on" t) (const :tag "off" nil) + (string :tag "Selected label types"))) ;; Label insertion @@ -781,6 +1049,8 @@ The conversion of the context to a legal label is governed by the specifications given in `reftex-derive-label-parameters'. If RefTeX fails to derive a label, it will prompt the user. +If DERIVE is nil, the label generated will consist of the prefix and a +unique number, like `eq:23'. If PROMPT is t, the user will be prompted for a label string. The prompt will already contain the prefix, and (if DERIVE is t) a default label derived from @@ -814,7 +1084,7 @@ (const :tag "never" nil) (string :tag "selected label types" "")))) -(defcustom reftex-derive-label-parameters '(3 20 t 1 "-" ; continue +(defcustom reftex-derive-label-parameters '(3 20 t 1 "-" ("the" "on" "in" "off" "a" "for" "by" "of" "and" "is")) "Parameters for converting a string into a label. NWORDS Number of words to use. @@ -829,19 +1099,19 @@ IGNOREWORDS List of words which should not be part of labels." :group 'reftex-making-and-inserting-labels :type '(list (integer :tag "Number of words " 3) - (integer :tag "Maximum label length " 20) - (choice :tag "Illegal characters in words" - (const :tag "throw away entire word" nil) - (const :tag "throw away single chars" t)) - (choice :tag "Abbreviate words " - (const :tag "never" nil) - (const :tag "always" t) - (const :tag "when label is too long" 1)) - (string :tag "Separator between words " "-") - (repeat :tag "Ignore words" - :entry-format " %i %d %v" - (string :tag "")))) - + (integer :tag "Maximum label length " 20) + (choice :tag "Illegal characters in words" + (const :tag "throw away entire word" nil) + (const :tag "throw away single chars" t)) + (choice :tag "Abbreviate words " + (const :tag "never" nil) + (const :tag "always" t) + (const :tag "when label is too long" 1)) + (string :tag "Separator between words " "-") + (repeat :tag "Ignore words" + :entry-format " %i %d %v" + (string :tag "")))) + (defcustom reftex-label-illegal-re "[\000-\040\177-\377\\\\#$%&~^_{}]" "Regexp matching characters not legal in labels. For historic reasons, this character class comes *with* the [] brackets." @@ -856,10 +1126,10 @@ AFTER Character class after abbrev point in word." :group 'reftex-making-and-inserting-labels :type '(list - (integer :tag "Minimum chars per word" 4) - (integer :tag "Shorten by at least " 2) - (string :tag "cut before char class " "^saeiou") - (string :tag "cut after char class " "aeiou"))) + (integer :tag "Minimum chars per word" 4) + (integer :tag "Shorten by at least " 2) + (string :tag "cut before char class " "^saeiou") + (string :tag "cut after char class " "aeiou"))) ;; Label referencing @@ -867,8 +1137,14 @@ "Options on how to reference labels." :group 'reftex-label-support) -(defcustom reftex-label-menu-flags '(t t nil nil nil nil t) - "*List of flags governing the label menu makeup. +(eval-and-compile + (defconst reftex-tmp + '((const :tag "on" t) + (const :tag "off" nil) + (string :tag "Selected label types")))) + +(defcustom reftex-label-menu-flags '(t t nil nil nil nil t nil) + "List of flags governing the label menu makeup. The flags are: TABLE-OF-CONTENTS Show the labels embedded in a table of context. @@ -878,6 +1154,7 @@ FOLLOW Follow full context in other window. SHOW-COMMENTED Show labels from regions which are commented out. MATCH-IN-TOC Searches in label menu will also match in toc lines. +SHOW FILES Show Begin and end of included files. Each of these flags can be set to t or nil, or to a string of type letters indicating the label types for which it should be true. These strings work @@ -889,28 +1166,37 @@ decide here to not have a table of contents in the label menu, you can still get one interactively during selection from the label menu." :group 'reftex-referencing-labels - :type '(list - (choice :tag "Embed in table of contents " - (const :tag "on" t) (const :tag "off" nil) - (string :tag "Selected label types")) - (choice :tag "Show section numbers " - (const :tag "on" t) (const :tag "off" nil)) - (choice :tag "Show individual counters " - (const :tag "on" t) (const :tag "off" nil) - (string :tag "Selected label types")) - (choice :tag "Hide short context " - (const :tag "on" t) (const :tag "off" nil) - (string :tag "Selected label types")) - (choice :tag "Follow context in other window" - (const :tag "on" t) (const :tag "off" nil) - (string :tag "Selected label types")) - (choice :tag "Show commented labels " - (const :tag "on" t) (const :tag "off" nil) - (string :tag "Selected label types")) - (choice :tag "Searches match in toc lines " - (const :tag "on" t) (const :tag "off" nil) - (string :tag "Selected label types")))) - + :type + `(list + (choice :tag "Embed in table of contents " ,@reftex-tmp) + (choice :tag "Show section numbers " ,@reftex-tmp) + (choice :tag "Show individual counters " ,@reftex-tmp) + (choice :tag "Hide short context " ,@reftex-tmp) + (choice :tag "Follow context in other window " ,@reftex-tmp) + (choice :tag "Show commented labels " ,@reftex-tmp) + (choice :tag "Searches match in toc lines " ,@reftex-tmp) + (choice :tag "Show begin/end of included files" ,@reftex-tmp))) + +(defcustom reftex-level-indent 2 + "*Number of spaces to be used for indentation per section level." + :group 'reftex-referencing-labels + :type '(integer)) + +(defcustom reftex-refontify-context 1 + "*Non-nil means, re-fontify the context in the label menu with font-lock. +This slightly slows down the creation of the label menu. It is only necessay +when you definitely want the context fontified. + +This option may have 3 different values: +nil Never refontify. +t Always refontify. +1 Refontify when absolutly necessary, e.g. when with the x-symbol package. +The option is ignored when `reftex-use-fonts' is nil." + :group 'reftex-referencing-labels + :type '(choice + (const :tag "Never" nil) + (const :tag "Always" t) + (const :tag "When necessary" 1))) (defcustom reftex-guess-label-type t "*Non-nil means, `reftex-reference' will try to guess the label type. @@ -934,7 +1220,7 @@ :type '(repeat (string :tag "Environment variable"))) (defcustom reftex-bibfile-ignore-list nil - "List of files in \\bibliography{..} RefTeX should *not* parse. + "*List of files in \\bibliography{..} RefTeX should *not* parse. The file names have to be in the exact same form as in the bibliography macro - i.e. without the `.bib' extension. Intended for files which contain only `@string' macro definitions and the @@ -952,12 +1238,12 @@ 'reverse-year Sort entries by decreasing year." :group 'reftex-citation-support :type '(choice (const :tag "not" nil) - (const :tag "by author" author) - (const :tag "by year" year) - (const :tag "by year, reversed" reverse-year))) + (const :tag "by author" author) + (const :tag "by year" year) + (const :tag "by year, reversed" reverse-year))) (defcustom reftex-cite-format 'default - "The format of citations to be inserted into the buffer. + "*The format of citations to be inserted into the buffer. It can be a string or an alist. In the simplest case this is just the string \"\\cite{%l}\", which is also the default. See the definition of `reftex-cite-format-builtin' for more complex examples. @@ -987,33 +1273,34 @@ `reftex-cite-format' directly yourself or set it to the SYMBOL of one of the predefined styles (see `reftex-cite-format-builtin'). E.g.: (setq reftex-cite-format 'harvard)" - :group 'reftex-citation-support - :type -'(choice :format "%{%t%}: \n%[Value Menu%] %v" - (radio :tag "Symbolic Builtins" - :indent 4 - :value default - ;; Update here with: update-builtin-cite - (const :tag "default: Default macro \\cite{%l}" default) - (const :tag "harvard: P. William's and T. Schnier's Harvard package" harvard) - (const :tag "natbib: Patrick W. Daly's Natbib package" natbib) - (const :tag "astron: S. Hogeveen's Astron package" astron) - (const :tag "author-year: Do-it-yourself Author year citation" author-year) - (const :tag "locally: Put full info in parenthesis" locally)) - (string :tag "format string" "\\cite{%l}") - (repeat :tag "key-ed format strings" - :value ((?\r . "\\cite{%l}") - (?t . "\\cite{%l}") (?p . "\\cite{%l}")) - (cons (character :tag "Key character" ?\r) - (string :tag "Format string" ""))))) + :group 'reftex-citation-support + :type + `(choice + :format "%{%t%}: \n%[Value Menu%] %v" + (radio :tag "Symbolic Builtins" + :indent 4 + :value default + ,@(mapcar + (function + (lambda (x) + (list 'const ':tag (concat (symbol-name (nth 0 x)) + ": " (nth 1 x)) + (nth 0 x)))) + reftex-cite-format-builtin)) + (string :tag "format string" "\\cite{%l}") + (repeat :tag "key-ed format strings" + :value ((?\r . "\\cite{%l}") + (?t . "\\cite{%l}") (?p . "\\cite{%l}")) + (cons (character :tag "Key character" ?\r) + (string :tag "Format string" ""))))) (defcustom reftex-comment-citations nil - "Non-nil means add a comment for each citation describing the full entry. + "*Non-nil means add a comment for each citation describing the full entry. The comment is formatted according to `reftex-cite-comment-format'." :group 'reftex-citation-support :type '(boolean)) -(defcustom reftex-cite-comment-format ; continue +(defcustom reftex-cite-comment-format "%% %2a %y, %j %v, %P, %e: %b, %u, %s %<\n" "Citation format used for commented citations. Must NOT contain %l." :group 'reftex-citation-support @@ -1025,11 +1312,11 @@ 1. normal names separator, like \", \" in Jones, Brown and Miller 2. final names separator, like \" and \" in Jones, Brown and Miller 3. The \"et al\" string, like \" {...}\" in Jones {\\it et al.}" - :group 'reftex-citation-support + :group 'reftex-citation-support :type '(list - (string :tag "Separator for names ") - (string :tag "Separator for last name in list") - (string :tag "string used as et al. "))) + (string :tag "Separator for names ") + (string :tag "Separator for last name in list") + (string :tag "string used as et al. "))) ;; Table of contents configuration -------------------------------------- @@ -1038,12 +1325,79 @@ :group 'reftex) (defcustom reftex-toc-follow-mode nil - "Non-nil means, point in *toc* buffer will cause other window to follow. + "*Non-nil means, point in *toc* buffer will cause other window to follow. The other window will show the corresponding part of the document. This flag can be toggled from within the *toc* buffer with the `f' key." :group 'reftex-table-of-contents-browser :type '(boolean)) +;; Tuning the parser ---------------------------------------------------- + +(defgroup reftex-optimizations-for-large-documents nil + "Configuration of parser speed and memory usage." + :group 'reftex) + +(defcustom reftex-keep-temporary-buffers 1 + "*Non-nil means, keep buffers created for parsing and lookup. +RefTeX sometimes needs to visit files related to the current document. +We distinguish files visited for +PARSING: Parts of a multifile document loaded when (re)-parsing the document. +LOOKUP: BibTeX database files and TeX files loaded to find a reference, + to display label context, etc. +The created buffers can be kept for later use, or be thrown away immediately +after use, depending on the value of this variable: + +nil Throw away as much as possible. +t Keep everything. +1 Throw away buffers created for parsing, but keep the ones created + for lookup. + +If a buffer is to be kept, the file is visited normally (which is potentially +slow but will happen only once). +If a buffer is to be thrown away, the initialization of the buffer depends +upon the variable `reftex-initialize-temporary-buffers'." + :group 'reftex-miscellaneous-configurations + :type '(choice + (const :tag "Throw away everything" nil) + (const :tag "Keep everything" t) + (const :tag "Keep lookup buffers only" 1))) + +(defcustom reftex-initialize-temporary-buffers nil + "*Non-nil means do initializations even when visiting file temporarily. +When nil, RefTeX may turn off find-file hooks and other stuff to briefly +visit a file. +When t, the full default initializations are done (find-file-hook etc.). +Instead of t or nil, this variable may also be a list of hook functions to +do a minimal initialization." + :group 'reftex-miscellaneous-configurations + :type '(choice + (const :tag "Read files literally" nil) + (const :tag "Fully initialize buffers" t) + (repeat :tag "Hook functions" :value (nil) + (function-item)))) + +(defcustom reftex-enable-partial-scans nil + "*Non-nil means, re-parse only 1 file when asked to re-parse. +Re-parsing is normally requested with a `C-u' prefix to many RefTeX commands, +or with the `r' key in menus. When this option is t in a multifile document, +we will only parse the current buffer, or the file associated with the label +or section heading near point in a menu. Requesting re-parsing of an entire +multifile document then requires a `C-u C-u' prefix or the capital `R' key +in menus." + :group 'reftex-optimizations-for-large-documents + :type 'boolean) + +(defcustom reftex-save-parse-info nil + "*Non-nil means, save information gathered with parsing in a file. +The file MASTER.rel in the same directory as MASTER.tex is used to save the +information. When this variable is t, +- accessing the parsing information for the first time in an editing session + will read that file (if available) instead of parsing the document. +- each time (part of) the document is rescanned, a new version of the file + is written." + :group 'reftex-optimizations-for-large-documents + :type 'boolean) + ;; Miscellaneous configurations ----------------------------------------- (defgroup reftex-miscellaneous-configurations nil @@ -1054,10 +1408,10 @@ "Non-nil means, make additional key bindings on startup. These extra bindings are located in the users `C-c letter' map." :group 'reftex-miscellaneous-configurations - :type '(boolean)) + :type '(boolean)) (defcustom reftex-plug-into-AUCTeX nil - "Plug-in flags for AUCTeX interface. + "*Plug-in flags for AUCTeX interface. This variable is a list of 4 boolean flags. When a flag is non-nil, it means: @@ -1077,15 +1431,15 @@ may require a restart of Emacs in order to become effective." :group 'reftex-miscellaneous-configurations :type '(choice (const :tag "No plug-ins" nil) - (const :tag "All possible plug-ins" t) - (list - :tag "Individual choice" - :value (nil nil nil nil) - (boolean :tag "Use reftex-label as LaTeX-label-function") - (boolean :tag "Use reftex-arg-label as TeX-arg-label ") - (boolean :tag "Use reftex-arg-ref as TeX-arg-ref ") - (boolean :tag "Use reftex-arg-cite as TeX-arg-cite ") - ))) + (const :tag "All possible plug-ins" t) + (list + :tag "Individual choice" + :value (nil nil nil nil) + (boolean :tag "Use reftex-label as LaTeX-label-function") + (boolean :tag "Use reftex-arg-label as TeX-arg-label ") + (boolean :tag "Use reftex-arg-ref as TeX-arg-ref ") + (boolean :tag "Use reftex-arg-cite as TeX-arg-cite ") + ))) (defcustom reftex-use-fonts t "*Non-nil means, use fonts in label menu and on-the-fly help. @@ -1093,22 +1447,28 @@ :group 'reftex-miscellaneous-configurations :type '(boolean)) -(defcustom reftex-keep-temporary-buffers t - "*Non-nil means, keep any TeX and BibTeX files loaded for lookup. -Nil means, kill it immediately after use unless it was already an existing -buffer before the lookup happened. It is faster to keep the buffers, but can -use a lot of memory, depending on the size of your database and document." +(defcustom reftex-auto-show-entry 'copy + "*Non-nil means, do something when context in other window is hidden. +Some modes like `outline-mode' or `folding-mode' hide parts of buffers. +When RefTeX is asked to show context for a label definition, and the context +is invisible, it can unhide that section permanently (value t), or copy the +context to a temporary buffer (value 'copy)." :group 'reftex-miscellaneous-configurations - :type '(boolean)) - -(defcustom reftex-auto-show-entry t - "*Non-nil means, showing context in another window may unhide a section. -This is important when using outline-minor-mode. If the context to be shown -is in a hidden section, RefTeX will issue a \"show-entry\" command in order -to show it. This is not reversed when the label is selected - so the section -remains shown after command completion." + :type '(radio :value copy + :indent 4 + (const :tag "Do nothing" nil) + (const :tag "Unhide section permanently" t) + (const :tag "Copy context to show" copy))) + +(defcustom reftex-load-hook nil + "Hook which is being run when loading reftex.el." :group 'reftex-miscellaneous-configurations - :type '(boolean)) + :type 'hook) + +(defcustom reftex-mode-hook nil + "Hook which is being run when turning on RefTeX mode." + :group 'reftex-miscellaneous-configurations + :type 'hook) ;;; End of Configuration Section ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1140,7 +1500,7 @@ context of the label definition. The selected label is inserted as a \\ref macro. -Citations can be made with `\\[reftex-citation]' which will use a regular expression +Citations can be made with `\\[reftex-citation]' which will use a regular expression to pull out a *formatted* list of articles from your BibTeX database. The selected citation is inserted as a \\cite macro. @@ -1150,10 +1510,12 @@ Most command have help available on the fly. This help is accessed by pressing `?' to any prompt mentioning this feature. -Extensive documentation about reftex is in the file header of `reftex.el'. +Extensive documentation about RefTeX is in the file header of `reftex.el'. +You can view this information with `\\[reftex-show-commentary]'. \\{reftex-mode-map} -Under X, these functions will also be available in a menu on the menu bar. +Under X, these and other functions will also be available as `Ref' menu +on the menu bar. ------------------------------------------------------------------------------" @@ -1164,28 +1526,16 @@ ; Add or remove the menu, and run the hook (if reftex-mode (progn - (easy-menu-add reftex-mode-menu) - (reftex-plug-into-AUCTeX) - (run-hooks 'reftex-mode-hook)) + (easy-menu-add reftex-mode-menu) + (reftex-plug-into-AUCTeX) + (run-hooks 'reftex-mode-hook)) (easy-menu-remove reftex-mode-menu))) - + (or (assoc 'reftex-mode minor-mode-alist) - (setq minor-mode-alist - (cons '(reftex-mode " Ref") minor-mode-alist))) + (push '(reftex-mode " Ref") minor-mode-alist)) (or (assoc 'reftex-mode minor-mode-map-alist) - (setq minor-mode-map-alist - (cons (cons 'reftex-mode reftex-mode-map) - minor-mode-map-alist))) - - - - - - - - - + (push (cons 'reftex-mode reftex-mode-map) minor-mode-map-alist)) ;;; =========================================================================== ;;; @@ -1203,61 +1553,60 @@ ;;; AUCTeX ;;; ------ -(defun reftex-arg-label (optional &optional prompt definition) +(defun reftex-arg-label (optional &optional prompt definition) "Use `reftex-label' to create label. Insert it with `TeX-argument-insert'. This function is intended for AUCTeX macro support." (let ((label (reftex-label nil t))) - (if (and definition (not (string-equal "" label))) - (LaTeX-add-labels label)) + (if (and definition (not (string-equal "" label))) + (LaTeX-add-labels label)) (TeX-argument-insert label optional optional))) -(defun reftex-arg-ref (optional &optional prompt definition) +(defun reftex-arg-ref (optional &optional prompt definition) "Use `reftex-reference' to select label. Insert with `TeX-argument-insert'. This function is intended for AUCTeX macro support." (let ((label (reftex-reference nil t))) - (if (and definition (not (string-equal "" label))) - (LaTeX-add-labels label)) + (if (and definition (not (string-equal "" label))) + (LaTeX-add-labels label)) (TeX-argument-insert label optional optional))) -(defun reftex-arg-cite (optional &optional prompt definition) +(defun reftex-arg-cite (optional &optional prompt definition) "Use reftex-citation to select a key. Insert with `TeX-argument-insert'. This function is intended for AUCTeX macro support." - (let ((key (reftex-citation nil t))) + (let ((key (reftex-citation t))) (TeX-argument-insert (or key "") optional optional))) (defun reftex-plug-into-AUCTeX () ;; Replace AucTeX functions with RefTeX functions. ;; Which functions are replaced is controlled by the variable ;; `reftex-plug-into-AUCTeX'. - (let ((flags - (cond ((eq reftex-plug-into-AUCTeX t) '(t t t t)) - ((eq reftex-plug-into-AUCTeX nil) '(nil nil nil nil)) - (t reftex-plug-into-AUCTeX)))) + (let ((flags + (cond ((eq reftex-plug-into-AUCTeX t) '(t t t t)) + ((eq reftex-plug-into-AUCTeX nil) '(nil nil nil nil)) + (t reftex-plug-into-AUCTeX)))) (and (nth 0 flags) - (boundp 'LaTeX-label-function) - (setq LaTeX-label-function 'reftex-label)) + (boundp 'LaTeX-label-function) + (setq LaTeX-label-function 'reftex-label)) (and (nth 1 flags) - (fboundp 'TeX-arg-label) - (fset 'TeX-arg-label 'reftex-arg-label)) + (fboundp 'TeX-arg-label) + (fset 'TeX-arg-label 'reftex-arg-label)) (and (nth 2 flags) - (fboundp 'TeX-arg-ref) - (fset 'TeX-arg-ref 'reftex-arg-ref)) + (fboundp 'TeX-arg-ref) + (fset 'TeX-arg-ref 'reftex-arg-ref)) (and (nth 3 flags) - (fboundp 'TeX-arg-cite) - (fset 'TeX-arg-cite 'reftex-arg-cite)))) - + (fboundp 'TeX-arg-cite) + (fset 'TeX-arg-cite 'reftex-arg-cite)))) + (defvar reftex-label-alist-external-add-ons nil "List of label alist entries added with reftex-add-to-label-alist.") -;;;###autoload (defun reftex-add-to-label-alist (entry-list) "Add label environment descriptions to `reftex-label-alist-external-add-ons'. -The format of ENTRY-LIST is exactly like `reftex-label-alist'. See there +The format of ENTRY-LIST is exactly like `reftex-label-alist'. See there for details. This function makes it possible to support RefTeX from AUCTeX style files. The entries in ENTRY-LIST will be processed after the user settings in @@ -1269,10 +1618,9 @@ (while entry-list (setq entry (car entry-list) entry-list (cdr entry-list)) - (if (not (member entry reftex-label-alist-external-add-ons)) - (setq reftex-tables-dirty t - reftex-label-alist-external-add-ons - (cons entry reftex-label-alist-external-add-ons)))))) + (unless (member entry reftex-label-alist-external-add-ons) + (setq reftex-tables-dirty t) + (push entry reftex-label-alist-external-add-ons))))) ;;; =========================================================================== ;;; @@ -1287,8 +1635,7 @@ ;; List of variables which handle the multifile stuff. ;; This list is used to tie, untie, and reset these symbols. (defconst reftex-multifile-symbols - '(reftex-label-numbers-symbol reftex-list-of-labels-symbol - reftex-bibfile-list-symbol)) + '(reftex-docstruct-symbol)) ;; Alist connecting master file names with the corresponding lisp symbols. (defvar reftex-master-index-list nil) @@ -1296,29 +1643,13 @@ ;; Last index used for a master file. (defvar reftex-multifile-index 0) -;; Alist connecting a master file with all included files. -(defvar reftex-master-include-list nil) - -;; Variable holding the symbol with current value of label postfix. -(defvar reftex-label-numbers-symbol nil ) -(make-variable-buffer-local 'reftex-label-numbers-symbol) - ;; Variable holding the symbol with the label list of the document. -;; Each element of the label list is again a list with the following elements: -;; 0: One character label type indicator. -;; 1: Short context to put into label menu. -;; 2: The label. -;; 3: The name of the file where the label is defined. -(defvar reftex-list-of-labels-symbol nil) -(make-variable-buffer-local 'reftex-list-of-labels-symbol) - -;; Variable holding the symbol with a list of library files for this document. -(defvar reftex-bibfile-list-symbol nil) -(make-variable-buffer-local 'reftex-bibfile-list-symbol) +(defvar reftex-docstruct-symbol nil) +(make-variable-buffer-local 'reftex-docstruct-symbol) (defun reftex-next-multifile-index () ;; Return the next free index for multifile symbols. - (setq reftex-multifile-index (1+ reftex-multifile-index))) + (incf reftex-multifile-index)) (defun reftex-tie-multifile-symbols () ;; Tie the buffer-local symbols to globals connected with the master file. @@ -1336,10 +1667,8 @@ (setq index (cdr index)) ;; Get a new index and add info to the alist. (setq index (reftex-next-multifile-index) - reftex-master-index-list (cons - (cons master index) - reftex-master-index-list) - newflag t)) + newflag t) + (push (cons master index) reftex-master-index-list)) ;; Get/create symbols and tie them. (while symlist @@ -1412,170 +1741,33 @@ (error "No such master file %s" master))) (expand-file-name master))) -(defun reftex-make-master-buffer (master-file) -;; Make a master buffer which contains the MASTER-FILE and all includes. -;; This is to prepare a buffer containing the entire document in correct -;; sequence for parsing. -;; After making the buffer, it runs reftex-make-master-buffer-hook. -;; The function returns the number of input/include files not found. - - (let ((not-found 0) file file1 - file-list dir-list tmp - (this-syntax-table (syntax-table)) - (format-alist nil) - (default-major-mode 'fundamental-mode) - (after-insert-file-functions nil)) - - ;; Set up the buffer with correct syntax table for parsing a tex buffer. - ;; We do not use the mode because that may involve heavy stuff - ;; like font-lock etc. - (switch-to-buffer "*RefTeX Master*") - (erase-buffer) - (set-syntax-table this-syntax-table) - - ;; First insert the master file. - (if (not (file-exists-p master-file)) - (error "No such master file: %s" master-file)) - (reftex-insert-buffer-or-file master-file) - (subst-char-in-region (point-min) (point-max) ?\r ?\n t) - (setq file-list (cons master-file file-list)) - (goto-char 1) - - ;; Remember from which file these lines came. - (put-text-property (point-min) (point-max) 'file - (expand-file-name master-file)) - - ;; Make the default directory that of the master file. - ;; All input and include stuff works relative to that directory. - (cd (file-name-directory (expand-file-name master-file))) - - ;; Create the list of directories from the TEXINPUTS environment variable - (setq dir-list (cons default-directory - (reftex-split (concat path-separator "+") - (or (getenv "TEXINPUTS") "")))) - - ;; Now find recursively all include/input statements and expand them. - (while - (re-search-forward - "^[ \t]*\\\\\\(include\\|input\\)[{ \t]+\\([^} \t\n\r]+\\)[} \t\n\r]" - nil t) - (setq file (reftex-no-props (match-string 2))) - (if (not (and (> (length file) 4) - (string= (substring file -4) ".tex"))) - (setq file (concat file ".tex"))) - (setq file1 file) - (if (setq file (car (reftex-find-files-on-path (list file) dir-list))) - (progn - (replace-match - (format "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% START OF %s FILE: %s\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% END OF %s FILE: %s\n" - (match-string 1) file - (match-string 1) file)) - (beginning-of-line 0) - (narrow-to-region (point) (point)) - ;; Insert the file. - (reftex-insert-buffer-or-file file) - (subst-char-in-region (point-min) (point-max) ?\r ?\n t) - (setq file-list (cons (expand-file-name file) file-list)) - ;; Remember from which file these lines came. - (put-text-property (point-min) (point-max) - 'file (expand-file-name file)) - (goto-char (point-min)) - (widen)) - (message "Input/include file %s not found. Ignored. Continuing..." - file1) - (setq not-found (1+ not-found)))) - (setq file-list (nreverse file-list)) - (while (setq tmp (assoc (car file-list) reftex-master-include-list)) - (setq reftex-master-include-list (delq tmp reftex-master-include-list))) - (setq reftex-master-include-list - (cons file-list reftex-master-include-list)) - - ;; Run the hook - (run-hooks 'reftex-make-master-buffer-hook) - - not-found)) - -(defun reftex-insert-buffer-or-file (file) - "If there is a buffer associated with FILE, insert it - otherwise the FILE." - (let ((buffer (reftex-get-buffer-visiting file))) - (if buffer - (let (beg end beg1 end1) - (save-excursion - ;; Make sure we get the whole buffer. - (set-buffer buffer) - (setq beg (point-min) end (point-max)) - (widen) - (setq beg1 (point-min) end1 (point-max))) - (insert-buffer-substring buffer beg1 end1) - (save-excursion - (set-buffer buffer) - (narrow-to-region beg end))) - (insert-file-contents file)))) - - -(defun reftex-parse-document (&optional buffer) - "Rescan the document." +(defun reftex-parse-one () + "Re-parse this file." + (interactive) + (let ((reftex-enable-partial-scans t)) + (reftex-access-scan-info '(4)))) + +(defun reftex-parse-all () + "Re-parse entire document." (interactive) - (save-window-excursion - (save-excursion - (if buffer - (if (not (bufferp buffer)) - (error "No such buffer %s" (buffer-name buffer)) - (set-buffer buffer))) - (reftex-access-scan-info t)))) - -(defun reftex-access-scan-info (&optional rescan) - ;; Access the scanning info. When the multifile symbols are not yet tied, - ;; tie them. When they are have to be created, do a buffer scan to - ;; fill them. - - ;; If RESCAN is non-nil, enforce document scanning - - (catch 'exit - (let ((rescan (or (equal rescan t) (equal rescan '(4))))) - - ;; Reset the mode if we had changes from style hooks. - (and reftex-tables-dirty - (reftex-reset-mode)) - - (if (eq reftex-list-of-labels-symbol nil) - ;; Symbols are not yet tied: Tie them and see if they are set. - (reftex-tie-multifile-symbols)) - - (if (and (symbol-value reftex-list-of-labels-symbol) - (not rescan)) - ;; Lists do already exist and we don't need to rescan. - ;; Return from here. - (throw 'exit t)) - - ;; We need to rescan - ;; ================= - - (unwind-protect - (save-window-excursion - (save-excursion - - ;; Do the scanning. - - (let ((label-list-symbol reftex-list-of-labels-symbol) - (label-numbers-symbol reftex-label-numbers-symbol) - (bibfile-list-symbol reftex-bibfile-list-symbol)) - - (message "Creating master buffer...") - (reftex-make-master-buffer (reftex-TeX-master-file)) - - (message "Scanning document...") - - (reftex-scan-buffer-for-labels - label-numbers-symbol label-list-symbol) - - (reftex-scan-buffer-for-bibliography-statement - bibfile-list-symbol) - - (message "Scanning document... done")))) - - (if (get-buffer "*RefTeX Master*") - (kill-buffer "*RefTeX Master*")))))) + (reftex-access-scan-info '(16))) + +(defun reftex-all-document-files (&optional relative) + ;; Return a list of all files belonging to the current document. + ;; When RELATIVE is non-nil, give file names relative to directory + ;; of master file. + (let* ((all (symbol-value reftex-docstruct-symbol)) + (master-dir (file-name-directory (reftex-TeX-master-file))) + (re (concat "\\`" (regexp-quote master-dir))) + file-list tmp file) + (while (setq tmp (assoc 'bof all)) + (setq file (nth 1 tmp) + all (cdr (memq tmp all))) + (and relative + (string-match re file) + (setq file (substring file (match-end 0)))) + (push file file-list)) + (nreverse file-list))) (defun reftex-create-tags-file () "Create TAGS file by running `etags' on the current document. @@ -1583,8 +1775,8 @@ (interactive) (reftex-access-scan-info current-prefix-arg) (let* ((master (reftex-TeX-master-file)) - (files (assoc master reftex-master-include-list)) - (cmd (format "etags %s" (mapconcat 'identity files " ")))) + (files (reftex-all-document-files)) + (cmd (format "etags %s" (mapconcat 'identity files " ")))) (save-excursion (set-buffer (reftex-get-buffer-visiting master)) (message "Running etags to create TAGS file...") @@ -1603,21 +1795,13 @@ (interactive (list (read-from-minibuffer "Run grep on document (like this): " - reftex-grep-command nil nil + reftex-grep-command nil nil 'reftex-grep-history))) (reftex-access-scan-info current-prefix-arg) - (let* ((master (reftex-TeX-master-file)) - (default-directory (file-name-directory master)) - (re (format "\\`%s\\(.*\\)" (regexp-quote - (expand-file-name default-directory)))) - (files (assoc master reftex-master-include-list)) - (cmd (format - "%s %s" grep-cmd - (mapconcat (function (lambda (x) - (if (string-match re x) - (match-string 1 x) - x))) - files " ")))) + (let* ((files (reftex-all-document-files t)) + (cmd (format + "%s %s" grep-cmd + (mapconcat 'identity files " ")))) (grep cmd))) (defun reftex-search-document (&optional regexp) @@ -1627,14 +1811,13 @@ This works also without an active TAGS table." (interactive) (let ((default (reftex-this-word))) - (if (not regexp) - (setq regexp (read-string (format "Search regexp in document [%s]: " - default)))) + (unless regexp + (setq regexp (read-string (format "Search regexp in document [%s]: " + default)))) (if (string= regexp "") (setq regexp (regexp-quote default))) (reftex-access-scan-info current-prefix-arg) - (tags-search regexp (list 'assoc (reftex-TeX-master-file) - 'reftex-master-include-list)))) + (tags-search regexp (list 'reftex-all-document-files)))) (defun reftex-query-replace-document (&optional from to delimited) "Run a query-replace-regexp of FROM with TO over the entire TeX document. @@ -1644,17 +1827,15 @@ This works also without an active TAGS table." (interactive) (let ((default (reftex-this-word))) - (if (not from) - (progn - (setq from (read-string (format "Replace regexp in document [%s]: " - default))) - (if (string= from "") (setq from (regexp-quote default))))) - (if (not to) - (setq to (read-string (format "Replace regexp %s with: " from)))) + (unless from + (setq from (read-string (format "Replace regexp in document [%s]: " + default))) + (if (string= from "") (setq from (regexp-quote default)))) + (unless to + (setq to (read-string (format "Replace regexp %s with: " from)))) (reftex-access-scan-info current-prefix-arg) (tags-query-replace from to (or delimited current-prefix-arg) - (list 'assoc (reftex-TeX-master-file) - 'reftex-master-include-list)))) + (list 'reftex-all-document-files)))) (defun reftex-change-label (&optional from to) "Query replace FROM with TO in all \\label and \\ref commands. @@ -1664,25 +1845,17 @@ This works also without an active TAGS table." (interactive) (let ((default (reftex-this-word "-a-zA-Z0-9_*.:"))) - (if (not from) - (setq from (read-string (format "Replace label globally [%s]: " - default)))) + (unless from + (setq from (read-string (format "Replace label globally [%s]: " + default)))) (if (string= from "") (setq from default)) - (if (not to) - (setq to (read-string (format "Replace label %s with: " - from)))) + (unless to + (setq to (read-string (format "Replace label %s with: " + from)))) (reftex-query-replace-document (concat "\\\\\\(label\\|[a-z]*ref\\){" (regexp-quote from) "}") (format "\\\\\\1{%s}" to)))) -(defun reftex-this-word (&optional class) -;; Grab the word around point. - (setq class (or class "-a-zA-Z0-9:_/.*;|")) - (save-excursion - (buffer-substring-no-properties - (progn (skip-chars-backward class) (point)) - (progn (skip-chars-forward class) (point))))) - ;;; =========================================================================== ;;; ;;; Functions to create and reference automatic labels. @@ -1722,7 +1895,7 @@ ;; The regular expression used to abbreviate words. (defconst reftex-abbrev-regexp (concat - "^\\(" + "\\`\\(" (make-string (nth 0 reftex-abbrev-parameters) ?.) "[" (nth 2 reftex-abbrev-parameters) "]*" "\\)" @@ -1733,12 +1906,22 @@ (defvar reftex-default-context-position nil) (defvar reftex-location-start nil) (defvar reftex-call-back-to-this-buffer nil) +(defvar reftex-active-toc nil) +(defvar reftex-tex-path nil) +(defvar reftex-bib-path nil) + +;; Internal list with index numbers of labels in the selection menu +(defvar reftex-label-index-list) ;; List of buffers created temporarily for lookup, which should be killed. (defvar reftex-buffers-to-kill nil) ;; Regexp to find section statements. Computed from reftex-section-levels. (defvar reftex-section-regexp nil) +(defvar reftex-section-or-include-regexp nil) +(defvar reftex-everything-regexp nil) +(defvar reftex-find-label-regexp-format nil) +(defvar reftex-find-label-regexp-format2 nil) ;; LaTeX section commands and level numbers (defcustom reftex-section-levels @@ -1753,13 +1936,389 @@ ("subsubparagraph" . 7) ) "Commands and levels used for defining sections in the document. -The car of each cons cell is the name of the section macro. The cdr is a +The car of each cons cell is the name of the section macro. The cdr is a number indicating its level." :group 'reftex-defining-label-environments :set 'reftex-set-dirty :type '(repeat - (cons (string :tag "sectioning macro" "") - (number :tag "level " 0)))) + (cons (string :tag "sectioning macro" "") + (number :tag "level " 0)))) + +;; The parser functions ---------------------------------- + +(defvar reftex-memory nil + "Memorizes old variable values to indicate changes in these variables.") + +(defun reftex-access-scan-info (&optional rescan file) + ;; Access the scanning info. When the multifile symbols are not yet tied, + ;; tie them. When they are empty or RESCAN is non-nil, scan the document. + + ;; Reset the mode if we had changes to important variables. + (when (or reftex-tables-dirty + (not (eq reftex-label-alist (nth 0 reftex-memory))) + (not (eq reftex-label-alist-external-add-ons + (nth 1 reftex-memory))) + (not (eq reftex-default-label-alist-entries + (nth 2 reftex-memory)))) + (reftex-reset-mode)) + + (if (eq reftex-docstruct-symbol nil) + ;; Symbols are not yet tied: Tie them. + (reftex-tie-multifile-symbols)) + + (if (and (null (symbol-value reftex-docstruct-symbol)) + reftex-save-parse-info) + ;; Try to read the stuff from a file + (reftex-access-parse-file 'read)) + + (cond + ((not (symbol-value reftex-docstruct-symbol)) + (reftex-do-parse 1 file)) + ((member rescan '(t 1 (4) (16))) + (reftex-do-parse rescan file)))) + +(defun reftex-do-parse (rescan &optional file) + ;; Access the scanning info. When the multifile symbols are not yet tied, + ;; tie them. When they are have to be created, do a buffer scan to + ;; fill them. + + ;; If RESCAN is non-nil, enforce document scanning + + ;; Normalize the rescan argument + (setq rescan (cond ((eq rescan t) t) + ((eq rescan 1) 1) + ((equal rescan '(4)) t) + ((equal rescan '(16)) 1) + (t 1))) + + ;; Partial scans only when allowed + (unless reftex-enable-partial-scans + (setq rescan 1)) + + ;; Do the scanning. + + (let* ((old-list (symbol-value reftex-docstruct-symbol)) + (master (reftex-TeX-master-file)) + (master-dir (file-name-as-directory (file-name-directory master))) + (file (or file (buffer-file-name))) + from-file + docstruct tmp) + + ;; Make sure replacement is really an option here + (when (and (eq rescan t) + (not (and (member (list 'bof file) old-list) + (member (list 'eof file) old-list)))) + (message "Scanning whole document (no file section %s)" file) + (setq rescan 1)) + (when (string= file master) + (message "Scanning whole document (%s is master)" file) + (setq rescan 1)) + + ;; From which file do we start? + (setq from-file + (cond ((eq rescan t) (or file master)) + ((eq rescan 1) master) + (t (error "horrible!!")))) + + ;; Find active toc entry and initialize section-numbers + (setq reftex-active-toc + (reftex-last-assoc-before-elt + 'toc (list 'bof from-file) old-list)) + (reftex-init-section-numbers reftex-active-toc) + + (if (eq rescan 1) + (message "Scanning entire document...") + (message "Scanning document from %s..." from-file)) + + (save-window-excursion + (save-excursion + (unwind-protect + (setq docstruct + (reftex-parse-from-file + from-file docstruct master-dir)) + (reftex-kill-temporary-buffers)))) + + (message "Scanning document... done") + + ;; Turn the list around. + (setq docstruct (nreverse docstruct)) + + ;; Set or insert + (setq docstruct (reftex-replace-label-list-segment + old-list docstruct (eq rescan 1))) + + ;; Add all missing information + (unless (assq 'label-numbers docstruct) + (push (cons 'label-numbers nil) docstruct)) + (unless (assq 'master-dir docstruct) + (push (cons 'master-dir master-dir) docstruct)) + (let* ((bof1 (memq (assq 'bof docstruct) docstruct)) + (bof2 (assq 'bof (cdr bof1))) + (is-multi (not (not (and bof1 bof2)))) + (entry (or (assq 'is-multi docstruct) + (car (push (list 'is-multi is-multi) docstruct))))) + (setcdr entry (cons is-multi nil))) + (unless (assq 'xr docstruct) + (let* ((allxr (reftex-all-assq 'xr-doc docstruct)) + (alist (mapcar + '(lambda (x) + (if (setq tmp (reftex-find-tex-file (nth 2 x) + master-dir)) + (cons (nth 1 x) tmp) + (message "Can't find external document %s" + (nth 2 x)) + nil)) + allxr)) + (alist (delete nil alist)) + (allprefix (delete nil (mapcar 'car alist))) + (regexp (concat "\\`\\(" (mapconcat 'identity allprefix "\\|") + "\\)"))) + (push (list 'xr alist regexp) docstruct))) + + (set reftex-docstruct-symbol docstruct) + + ;; Save the parsing informtion into a file? + (if reftex-save-parse-info + (reftex-access-parse-file 'write)))) + +(defun reftex-is-multi () + ;; Tell if this is a multifile document. When not sure, say yes. + (let ((entry (assq 'is-multi (symbol-value reftex-docstruct-symbol)))) + (if entry + (nth 1 entry) + t))) + +(defun reftex-parse-from-file (file docstruct master-dir) + ;; Scan the buffer for labels and save them in a list. + (let ((regexp reftex-everything-regexp) + (bound 0) + file-found tmp + (level 1) + (highest-level 100) + toc-entry next-buf) + + (catch 'exit + (setq file-found (reftex-find-tex-file file master-dir)) + (unless file-found + (push (list 'file-error file) docstruct) + (throw 'exit nil)) + + (save-excursion + + (message "Scanning file %s" file) + (set-buffer + (setq next-buf + (reftex-get-file-buffer-force + file-found + (not (eq t reftex-keep-temporary-buffers))))) + + ;; Begin of file mark + (setq file (buffer-file-name)) + (push (list 'bof file) docstruct) + + (save-excursion + (save-restriction + (widen) + (goto-char 1) + + (while (re-search-forward regexp nil t) + + (cond + + ((match-end 1) + ;; It is a label + (push (reftex-label-info (reftex-match-string 1) file bound) + docstruct)) + + ((match-end 3) + ;; It is a section + (setq bound (point)) + + ;; Insert in List + (setq toc-entry (reftex-section-info file)) + (setq level (nth 5 toc-entry)) + (setq highest-level (min highest-level level)) + (if (= level highest-level) + (message + "Scanning %s %s ..." + (car (nth level reftex-section-levels)) + (nth 6 toc-entry))) + + (push toc-entry docstruct) + (setq reftex-active-toc toc-entry)) + + ((match-end 7) + ;; It's an include or input + (setq docstruct + (reftex-parse-from-file + (reftex-match-string 7) + docstruct master-dir))) + + ((match-end 8) + ;; A macro with label + (save-excursion + (let* ((mac (reftex-match-string 8)) + (label (progn (goto-char (match-end 8)) + (save-match-data + (reftex-no-props + (reftex-nth-arg-wrapper + mac))))) + (entry (progn (goto-char (match-end 0)) + (reftex-label-info + label file bound mac)))) + (push entry docstruct)))) + (t (error "This should not happen (reftex-parse-from-file)"))) + ) + + + ;; Find bibliography statement + (when (setq tmp (reftex-locate-bibliography-files master-dir)) + (push (cons 'bib tmp) docstruct)) + + ;; Find external document specifications + (goto-char 1) + (while (re-search-forward "[\n\r][ \t]*\\\\externaldocument\\(\\[\\([^]]*\\)\\]\\)?{\\([^}]+\\)}" nil t) + (push (list 'xr-doc (reftex-match-string 2) + (reftex-match-string 3)) + docstruct)) + + ;; End of file mark + (push (list 'eof file) docstruct)))) + + ;; Kill the scanned buffer + (reftex-kill-temporary-buffers next-buf)) + + ;; Return the list + docstruct)) + +(defun reftex-locate-bibliography-files (master-dir) + ;; Scan buffer for bibliography macro and return file list. + (let (file-list) + (save-excursion + (goto-char (point-min)) + (if (re-search-forward + "\\(\\`\\|[\n\r]\\)[ \t]*\\\\bibliography{[ \t]*\\([^}]+\\)" nil t) + (setq file-list + (mapcar '(lambda (x) (concat x ".bib")) + (reftex-delete-list + reftex-bibfile-ignore-list + (split-string + (reftex-match-string 2) + "[ \t\n\r]*,[ \t\n\r]*"))))) + (delete nil + (mapcar + (function + (lambda (file) (reftex-find-bib-file file master-dir))) + file-list))))) + +(defun reftex-last-assoc-before-elt (key elt list) + ;; Find the last association of KEY in LIST before or at ELT + ;; ELT is found in LIST with equal, not eq. + ;; Returns nil when either KEY or elt are not found in LIST. + ;; On success, returns the association. + (let* ((elt (car (member elt list))) ass last-ass) + + (while (and (setq ass (assoc key list)) + (setq list (memq ass list)) + (memq elt list)) + (setq last-ass ass + list (cdr list))) + last-ass)) + +(defun reftex-replace-label-list-segment (old insert &optional entirely) + ;; Replace the segment in OLD which corresponds to INSERT. + ;; Works with side effects, directly changes old. + ;; If entirely is t, just return INSERT. + ;; This function also makes sure the old toc markers do not point anywhere. + + (cond + (entirely + (reftex-silence-toc-markers old (length old)) + insert) + (t (let* ((new old) + (file (nth 1 (car insert))) + (eof-list (member (list 'eof file) old)) + (bof-list (member (list 'bof file) old)) + n) + (if (not (and bof-list eof-list)) + (error "Cannot splice") + ;; Splice + (reftex-silence-toc-markers bof-list (- (length bof-list) + (length eof-list))) + (setq n (- (length old) (length bof-list))) + (setcdr (nthcdr n new) (cdr insert)) + (setcdr (nthcdr (1- (length new)) new) (cdr eof-list))) + new)))) + +(defun reftex-silence-toc-markers (list n) + ;; Set all markers in list to nil + (while (and list (> (decf n) -1)) + (and (eq (car (car list)) 'toc) + (markerp (nth 4 (car list))) + (set-marker (nth 4 (car list)) nil)) + (pop list))) + +(defun reftex-access-parse-file (action) + (let* ((list (symbol-value reftex-docstruct-symbol)) + (master (reftex-TeX-master-file)) + (enable-local-variables nil) + (file (if (string-match "\\.[a-zA-Z]+\\'" master) + (concat (substring master 0 (match-beginning 0)) ".rel") + (concat master ".rel")))) + (cond + ((eq action 'readable) + (file-readable-p file)) + ((eq action 'restore) + (if (eq reftex-docstruct-symbol nil) + ;; Symbols are not yet tied: Tie them. + (reftex-tie-multifile-symbols)) + (if (file-exists-p file) + ;; load the file and return t for success + (progn (load-file file) t) + ;; return nil for failure + nil)) + ((eq action 'read) + (if (file-exists-p file) + ;; load the file and return t for success + (progn (load-file file) t) + ;; return nil for failure + nil)) + (t + (save-excursion + (if (file-writable-p file) + (progn + (message "Writing parse file %s" (abbreviate-file-name file)) + (find-file file) + (erase-buffer) + (insert (format ";; RefTeX parse info file\n")) + (insert (format ";; File: %s\n" master)) + (insert (format ";; Date: %s\n" + (format-time-string "%D %T" + (current-time)))) + (insert (format ";; User: %s (%s)\n\n" + (user-login-name) (user-full-name))) + (insert "(set reftex-docstruct-symbol '(\n\n") + (let ((standard-output (current-buffer))) + (mapcar + (function + (lambda (x) + (cond ((eq (car x) 'toc) + ;; A toc entry. Do not save the marker. + ;; Save the markers position at position 8 + (print (list 'toc "toc" (nth 2 x) (nth 3 x) + nil (nth 5 x) (nth 6 x) (nth 7 x) + (or (and (markerp (nth 4 x)) + (marker-position (nth 4 x))) + (nth 8 x))))) + (t (print x))))) + list)) + (insert "))") + (save-buffer 0) + (kill-buffer (current-buffer))) + (error "Cannot write to file %s" file))) + t)))) + +;; Creating labels -------------- (defun reftex-label (&optional environment no-insert) "Insert a unique label. Return the label. @@ -1770,6 +2329,7 @@ This function is controlled by the settings of reftex-insert-label-flags." (interactive) + ;; Ensure access to scanning info and rescan buffer if prefix are is '(4). (reftex-access-scan-info current-prefix-arg) @@ -1777,14 +2337,19 @@ (if (or (not environment) (not (assoc environment reftex-env-or-mac-alist))) (setq environment (reftex-label-location))) - (if (not environment) - (error "Can't figure out what kind of label should be inserted")) + (unless environment + (error "Can't figure out what kind of label should be inserted")) ;; Ok, go ahead. - (let (label typekey prefix - entry format cell lab valid default force-prompt) - (setq typekey (nth 1 (assoc environment reftex-env-or-mac-alist)) - format (nth 3 (assoc environment reftex-env-or-mac-alist))) + (let* ((entry (assoc environment reftex-env-or-mac-alist)) + (typekey (nth 1 entry)) + (format (nth 3 entry)) + label prefix valid default force-prompt) + (when (and (eq (string-to-char environment) ?\\) + (nth 4 entry) + (memq (preceding-char) '(?\[ ?\{))) + (setq format "%s")) + (setq prefix (or (cdr (assoc typekey reftex-typekey-to-prefix-alist)) (concat typekey "-"))) ;; Replace any escapes in the prefix @@ -1795,7 +2360,11 @@ ((reftex-typekey-check typekey (nth 0 reftex-insert-label-flags)) ;; Derive a label from context. - (setq default (nth 2 (reftex-label-info " " nil nil t))) + (setq reftex-active-toc (reftex-last-assoc-before-elt + 'toc (car (reftex-where-am-I)) + (symbol-value reftex-docstruct-symbol))) + (setq default (reftex-no-props + (nth 2 (reftex-label-info " " nil nil t)))) ;; Catch the cases where the is actually no context available. (if (or (string-match "NO MATCH FOR CONTEXT REGEXP" default) (string-match "ILLEGAL VALUE OF PARSE" default) @@ -1807,7 +2376,7 @@ (setq default (concat prefix (reftex-string-to-label default))) ;; Make it unique. - (setq default (reftex-uniquify-label default nil "-")))) + (setq default (reftex-uniquify-label default nil "-")))) ((reftex-typekey-check typekey (nth 1 reftex-insert-label-flags)) ; prompt ;; Minimal default: the user will be prompted. @@ -1825,7 +2394,9 @@ (while (not valid) ;; iterate until we get a legal label - (setq label (read-string "Label: " default)) + (setq label (read-string + (if (string= format "%s") "Naked Label: " "Label: ") + default)) ;; Lets make sure that this is a legal label (cond @@ -1838,7 +2409,7 @@ ;; Look it up in the label list ((setq entry (assoc label - (symbol-value reftex-list-of-labels-symbol))) + (symbol-value reftex-docstruct-symbol))) (message "Label \"%s\" exists in file %s" label (nth 3 entry)) (ding) (sit-for 2)) @@ -1848,49 +2419,24 @@ (setq valid t)))) (setq label default)) - ;; Insert the label - (if (not no-insert) - (insert (format format label))) - ;; Insert the label into the label list - (if (symbol-value reftex-list-of-labels-symbol) - (let ((cnt 0) - (pos (point)) - (all (symbol-value reftex-list-of-labels-symbol)) - (look-for nil) - (note nil) - (text nil) - (file (buffer-file-name))) - - ;; find the previous label in order to know where to insert new label - ;; into label list - (save-excursion - (if (re-search-backward "\\\\[a-z]*label{\\([^}]+\\)}" nil 1 2) - (setq look-for (reftex-no-props (match-string 1)))) - (if (or (re-search-forward - "\\\\\\(include\\|input\\){[^}\n]+}" pos t) - (re-search-forward reftex-section-regexp pos t) - (null look-for)) - (setq note "POSITION UNCERTAIN. RESCAN TO FIX."))) - (if (not look-for) - (set reftex-list-of-labels-symbol - (cons (list label typekey text file note) - (symbol-value reftex-list-of-labels-symbol))) - (while all - (setq cell (car all) - all (cdr all) - cnt (1+ cnt) - lab (nth 0 cell)) - (if (string= lab look-for) - (progn - (setcdr - (nthcdr (1- cnt) - (symbol-value reftex-list-of-labels-symbol)) - (cons (list label typekey text file note) - (nthcdr - cnt (symbol-value reftex-list-of-labels-symbol)))) - ;; to end the loop, set all to nil - (setq all nil))))))) + (let* ((here-I-am-info (reftex-where-am-I)) + (here-I-am (car here-I-am-info)) + (note (if (cdr here-I-am-info) + "" + "POSITION UNCERTAIN. RESCAN TO FIX.")) + (file (buffer-file-name)) + (text nil) + (tail (memq here-I-am (symbol-value reftex-docstruct-symbol)))) + + (if tail + (setcdr tail (cons (list label typekey text file note) + (cdr tail))))) + + ;; Insert the label into the buffer + (unless no-insert + (insert (format format label))) + ;; return value of the function is the label label)) @@ -1900,24 +2446,21 @@ ;; Uses reftex-derive-label-parameters and reftex-abbrev-parameters ;; - (let* ((words0 (reftex-split "[- \t\n\r]+" - (reftex-no-props string))) + (let* ((words0 (split-string string "[- \t\n\r]+")) (ignore-words (nth 5 reftex-derive-label-parameters)) words word) ;; remove words from the ignore list or with funny characters - (while words0 - (setq word (car words0) words0 (cdr words0)) + (while (setq word (pop words0)) (cond ((member (downcase word) ignore-words)) ((string-match reftex-label-illegal-re word) - (if (nth 2 reftex-derive-label-parameters) - (progn - (while (string-match reftex-label-illegal-re word) - (setq word (replace-match "" nil nil word))) - (setq words (cons word words))))) + (when (nth 2 reftex-derive-label-parameters) + (while (string-match reftex-label-illegal-re word) + (setq word (replace-match "" nil nil word))) + (push word words))) (t - (setq words (cons word words))))) + (push word words)))) (setq words (nreverse words)) ;; restrict number of words @@ -1948,7 +2491,7 @@ string)) ;; Delete the final punctuation, if any - (if (string-match "[^a-zA-Z0-9]+$" string) + (if (string-match "[^a-zA-Z0-9]+\\'" string) (setq string (replace-match "" nil nil string))) string)) @@ -1957,24 +2500,24 @@ (save-match-data (let (letter (num 0) replace) (while (string-match "\\%\\([a-zA-Z]\\)" prefix num) - (setq letter (match-string 1 prefix)) - (setq replace - (cond - ((equal letter "f") - (file-name-sans-extension - (file-name-nondirectory (buffer-file-name)))) - ((equal letter "F") - (let ((masterdir (file-name-directory (reftex-TeX-master-file))) - (file (file-name-sans-extension (buffer-file-name)))) - (if (string-match (concat "\\`" (regexp-quote masterdir)) - file) - (substring file (length masterdir)) - file))) - ((equal letter "u") - (or (user-login-name) "")) - (t ""))) - (setq num (1- (+ (match-beginning 1) (length replace))) - prefix (replace-match replace nil nil prefix))) + (setq letter (match-string 1 prefix)) + (setq replace + (cond + ((equal letter "f") + (file-name-sans-extension + (file-name-nondirectory (buffer-file-name)))) + ((equal letter "F") + (let ((masterdir (file-name-directory (reftex-TeX-master-file))) + (file (file-name-sans-extension (buffer-file-name)))) + (if (string-match (concat "\\`" (regexp-quote masterdir)) + file) + (substring file (length masterdir)) + file))) + ((equal letter "u") + (or (user-login-name) "")) + (t ""))) + (setq num (1- (+ (match-beginning 1) (length replace))) + prefix (replace-match replace nil nil prefix))) prefix))) (defun reftex-label-location (&optional bound) @@ -1987,15 +2530,13 @@ (p2 (or (cdr loc2) 0))) (setq reftex-location-start (max p1 p2)) - (if (> p1 p2) + (if (>= p1 p2) (progn - (setq reftex-default-context-position p1) - (car loc1)) - (setq reftex-default-context-position - (+ p2 8 (length (car loc2)))) + (setq reftex-default-context-position (+ p1 (length (car loc1)))) + (or (car loc1) "section")) + (setq reftex-default-context-position (+ p2 8 (length (car loc2)))) (or (car loc2) "section")))) - (defun reftex-uniquify-label (label &optional force separator) ;; Make label unique by appending a number. ;; Optional FORCE means, force appending a number, even if label is unique. @@ -2003,41 +2544,44 @@ ;; Ensure access to scanning info (reftex-access-scan-info) - + (cond ((and (not force) - (not (assoc label (symbol-value reftex-list-of-labels-symbol)))) + (not (assoc label (symbol-value reftex-docstruct-symbol)))) label) (t - (let* ((cell (or (assoc label (symbol-value reftex-label-numbers-symbol)) - (car - (set reftex-label-numbers-symbol - (cons (cons label 0) - (symbol-value reftex-label-numbers-symbol)))))) - (num (1+ (cdr cell))) - (sep (or separator ""))) + (let* ((label-numbers (assq 'label-numbers + (symbol-value reftex-docstruct-symbol))) + (label-numbers-alist (cdr label-numbers)) + (cell (or (assoc label label-numbers-alist) + (car (setcdr label-numbers + (cons (cons label 0) + label-numbers-alist))))) + (num (1+ (cdr cell))) + (sep (or separator ""))) (while (assoc (concat label sep (int-to-string num)) - (symbol-value reftex-list-of-labels-symbol)) - (setq num (1+ num))) + (symbol-value reftex-docstruct-symbol)) + (incf num)) (setcdr cell num) (concat label sep (int-to-string num)))))) ;; Help string for the reference label menu (defconst reftex-select-label-prompt - "Select: [n]ext [p]revious [r]escan [ ]context [q]uit RET [?]HELP+more") + "Select: [n]ext [p]revious [r]escan [ ]context e[x]tern [q]uit RET [?]HELP+more") (defconst reftex-select-label-help " AVAILABLE KEYS IN REFERENCE LABEL MENU - ====================================== + -------------------------------------- n / p Go to next/previous label (Cursor motion works as well) C-s / C-r Search forward/backward. Use repeated C-s/C-r as in isearch. - r / s Rescan document for labels / Switch label type - t / # Toggle table of contents / Toggle counter mode - c Toggle display of short context + r / s Reparse document / Switch label type + x Switch to label menu of external document (with LaTeX package `xr') + t i c # % Toggle: [i]ncl. file borders, [t]able of contents, [c]ontext + [#] label counters, [%] labels in comments SPC Show full context for current label in other window f Toggle follow mode: other window will follow context - l / q Reuse last referenced label / Quit without accepting label - M-r Recursive Edit into other window + l / q Reuse last referenced label / Quit without accepting label + e Recursive Edit into other window RET Accept current label") (defun reftex-reference (&optional type no-insert) @@ -2058,14 +2602,13 @@ ;; Ensure access to scanning info and rescan buffer if prefix are is '(4) (reftex-access-scan-info current-prefix-arg) - (if (not type) - ;; guess type from context - (if (and reftex-guess-label-type - (not (= 16 (prefix-numeric-value current-prefix-arg))) - (setq type (assoc (downcase (reftex-word-before-point)) - reftex-words-to-typekey-alist))) - (setq type (cdr type)) - (setq type (reftex-query-label-type)))) + (unless type + ;; guess type from context + (if (and reftex-guess-label-type + (setq type (assoc (downcase (reftex-word-before-point)) + reftex-words-to-typekey-alist))) + (setq type (cdr type)) + (setq type (reftex-query-label-type)))) (let (label pair (form (or (cdr (assoc type reftex-typekey-to-format-alist)) @@ -2090,89 +2633,74 @@ ;; return the label label)) -(defun reftex-goto-label (&optional arg) - "Go to a LaTeX label. With prefix ARG, go to label in another window." - (interactive "P") - (let (type label file pair) - (if (not type) - (setq type (reftex-query-label-type))) - - (setq pair (reftex-offer-label-menu type) - label (car pair) - file (cdr pair)) - (if (and label file (file-exists-p file)) - (progn - (if arg - (find-file-other-window file) - (find-file file)) - (goto-char (point-min)) - (if (not (re-search-forward - (concat "\\\\[a-z]*label{" (regexp-quote label) "}") - nil t)) - (error "No such label found: %s" label) - (reftex-highlight 0 (match-beginning 0) (match-end 0)) - (add-hook 'pre-command-hook 'reftex-highlight-shall-die))) - (message "Quit") - nil))) - -;; Internal list with index numbers of labels in the selection menu -(defvar reftex-label-index-list nil) - (defun reftex-offer-label-menu (typekey) ;; Offer a menu with the appropriate labels. Return (label . file). (let* ((buf (current-buffer)) - (near-label (reftex-find-nearby-label)) + (xr-data (assq 'xr (symbol-value reftex-docstruct-symbol))) + (xr-alist (cons (cons "" (buffer-file-name)) (nth 1 xr-data))) + (xr-index 0) + (here-I-am (car (reftex-where-am-I))) (toc (reftex-typekey-check typekey reftex-label-menu-flags 0)) + (files (reftex-typekey-check typekey reftex-label-menu-flags 7)) (context (not (reftex-typekey-check typekey reftex-label-menu-flags 3))) (counter (reftex-typekey-check typekey reftex-label-menu-flags 2)) (follow (reftex-typekey-check typekey reftex-label-menu-flags 4)) - (match-everywhere (reftex-typekey-check - typekey reftex-label-menu-flags 6)) + (commented (nth 5 reftex-label-menu-flags)) + (match-everywhere (reftex-typekey-check + typekey reftex-label-menu-flags 6)) + (prefix "") offset rtn key cnt last-cnt entry) - (setq reftex-call-back-to-this-buffer buf) (setq entry (cons nil nil)) + ;; The following unwind-protect kills temporary buffers after use (unwind-protect (catch 'exit (while t (save-window-excursion + (setq reftex-call-back-to-this-buffer buf) (switch-to-buffer-other-window "*RefTeX Select*") (erase-buffer) (setq truncate-lines t) - (setq reftex-label-index-list (reftex-make-and-insert-label-list - typekey buf toc context counter - near-label)) - (setq near-label "_ ") ; turn off search for near label + (setq mode-line-format + (list "---- " 'mode-line-buffer-identification + " " (abbreviate-file-name + (buffer-file-name buf)) + " -%-")) + + (setq reftex-label-index-list + (reftex-make-and-insert-label-list + typekey buf toc files context counter commented + here-I-am prefix)) + (setq here-I-am nil) ; turn off determination of offset + ;; use only when searched (setq offset (or (car reftex-label-index-list) offset)) - ;; use only when searched - (setq reftex-label-index-list (cdr reftex-label-index-list)) ;; only this is the true list - (if (not reftex-label-index-list) - (error "No labels of type \"%s\"" typekey)) + (pop reftex-label-index-list) (setq rtn (reftex-select-item - reftex-select-label-prompt + reftex-select-label-prompt "^>" 2 reftex-select-label-help - '(?r ?g ?c ?t ?s ?# ?l) + '(?r ?R ?g ?c ?t ?s ?# ?i ?l ?% ?x) offset 'reftex-select-label-callback follow - match-everywhere)) + match-everywhere)) (setq key (car rtn) cnt (nth 1 rtn) last-cnt (nth 2 rtn) - offset (1+ (or cnt last-cnt))) - (if (not key) (throw 'exit nil)) + offset (1+ (or cnt last-cnt 0))) + (unless key (throw 'exit nil)) (cond ((or (eq key ?r) - (eq key ?g)) + (eq key ?R) + (eq key ?g)) ;; rescan buffer - (reftex-parse-document buf)) + (reftex-parse-document buf (or cnt last-cnt) key)) ((eq key ?c) ;; toggle context mode (setq context (not context))) @@ -2182,231 +2710,254 @@ ((eq key ?t) ;; toggle tabel of contents display (setq toc (not toc))) + ((eq key ?i) + ;; toggle display of included file borders + (setq files (not files))) ((eq key ?#) ;; toggle counter display (setq counter (not counter))) + ((eq key ?%) + ;; toggle display of commented labels + (setq commented (not commented))) ((eq key ?l) ;; reuse the last referenced label again (setq entry reftex-last-used-reference) (throw 'exit t)) + ((eq key ?x) + ;; select an external document + (setq xr-index (reftex-select-external-document + xr-alist xr-index)) + (setq buf (or (reftex-get-file-buffer-force + (cdr (nth xr-index xr-alist)) t) + (error "Cannot switch document")) + prefix (or (car (nth xr-index xr-alist)) "") + offset nil)) (t (set-buffer buf) - (if cnt - (progn - (setq entry (nth (nth cnt reftex-label-index-list) - (symbol-value reftex-list-of-labels-symbol))) - (setq reftex-last-used-reference entry)) - (setq entry nil)) + (if cnt + (progn + (setq entry (nth (nth cnt reftex-label-index-list) + (symbol-value reftex-docstruct-symbol))) + (setq reftex-last-used-reference entry)) + (setq entry nil)) (throw 'exit t)))))) (kill-buffer "*RefTeX Select*") + (and (get-buffer "*RefTeX Context Copy*") + (kill-buffer "*RefTeX Context Copy*")) (reftex-kill-temporary-buffers)) - (cons (reftex-no-props (nth 0 entry)) (nth 3 entry)))) - -;; Indentation for table of context lines in the menu -(defconst reftex-toc-indent " ") -;; Indentation for the lines containing the label -(defconst reftex-label-indent "> ") -;; Indentation for context lines -(defconst reftex-context-indent ". ") -;; Indentation per section level -(defvar reftex-level-indent 2 - "*Number of spaces to be used for indentation per section level. -With more indentation, the label menu looks nicer, but shows less context. -Changing this is only fully operational after the next buffer scan.") - -(defun reftex-make-and-insert-label-list (typekey0 buf toc context - counter near-label) + (cons (if (nth 0 entry) (concat prefix (nth 0 entry)) nil) + (nth 3 entry)))) + +(defun reftex-select-external-document (xr-alist xr-index) + ;; Return index of an external document. + (cond + ((= (length xr-alist) 1) + (ding) 0) + ((= (length xr-alist) 2) + (- 1 xr-index)) + (t + (save-window-excursion + (let* ((fmt " [%c] %-5s %s\n") (n (1- ?0)) key) + (with-output-to-temp-buffer "*RefTeX Select*" + (princ + (concat "Select a document by pressing a number key:\n KEY PREFIX DOCUMENT\n----------------------\n" + (mapconcat '(lambda (x) + (format fmt (incf n) (or (car x) "") + (abbreviate-file-name (cdr x)))) + xr-alist "")))) + (setq key (read-char)) + (if (< (- key ?1) (length xr-alist)) + (- key ?0) + (error "Illegal document selection [%c]" key))))))) + +(defun reftex-make-and-insert-label-list + (typekey0 buf toc files context counter show-commented here-I-am xr-prefix) ;; Insert a menu of all labels in buffer BUF into current buffer. - ;; Return the list of labels, with the index of NEAR-LABEL as extra car. - (let (ins-list index-list offset) + ;; Return the list of labels, with the index of HERE-I-AM as extra car. + (let* ((font (reftex-use-fonts)) + (refont (reftex-refontify)) + (cnt 0) + (index -1) + (toc-indent " ") + (label-indent + (concat "> " + (if toc (make-string (* 7 reftex-level-indent) ?\ ) ""))) + (context-indent + (concat ". " + (if toc (make-string (* 7 reftex-level-indent) ?\ ) ""))) + all cell text label typekey note comment master-dir-re + index-list offset docstruct-symbol from from1 to) + + ;; Pop to buffer buf to get the correct buffer-local variables (save-excursion (set-buffer buf) - (let* ((all nil) - (font (reftex-use-fonts)) - (cnt 0) - ;; (file nil) - (index -1) - (toc-indent reftex-toc-indent) - (label-indent - (concat reftex-label-indent - (if toc (make-string (* 7 reftex-level-indent) ?\ ) ""))) - (context-indent - (concat reftex-context-indent - (if toc (make-string (* 7 reftex-level-indent) ?\ ) ""))) - cell text label typekey note comment) - - ; Ensure access to scanning info - (reftex-access-scan-info) - - (setq all (symbol-value reftex-list-of-labels-symbol)) - - (while all - - (setq index (1+ index) - cell (car all) - all (cdr all)) - - (if (null (nth 2 cell)) - ;; No context yet. Quick update - (progn - (setq cell (reftex-label-info-update cell)) - (setcar (nthcdr index - (symbol-value reftex-list-of-labels-symbol)) - cell))) - - ;; in the following setq we *copy* the label, since we will change - ;; its properties, and we cannot have any properties in the list - ;; (because of assoc searches) - (setq label (if (stringp (car cell)) - (copy-sequence (car cell)) - (car cell)) - typekey (nth 1 cell) - text (nth 2 cell) - ;; file (nth 3 cell) - note (nth 4 cell) - comment (get-text-property 0 'in-comment text)) - - (if (string= label near-label) - (setq offset (1+ cnt))) - - (cond - ((and toc (string= typekey "toc")) - (setq ins-list - (cons (concat toc-indent text "\n") - ins-list))) - ((string= typekey "toc")) - ((and (or (string= typekey typekey0) (string= typekey0 " ")) - (or (nth 5 reftex-label-menu-flags) ; show-commented? - (null comment))) - (setq cnt (1+ cnt)) - (if comment (setq label (concat "% " label))) - (if font - (put-text-property - 0 (length label) - 'face - (if comment - 'font-lock-comment-face - 'font-lock-reference-face) - label)) - (setq index-list (cons index index-list)) - (setq ins-list - (cons (concat - label-indent - label - (if counter (format " (%d) " cnt)) - (if comment " LABEL IS COMMENTED OUT ") - (if note (concat " " note) "") - "\n" - (if context (concat context-indent text "\n"))) - ins-list)) - (put-text-property 0 (length (car ins-list)) 'cnt (1- cnt) - (car ins-list)) - )) - ))) - - (apply 'insert (nreverse ins-list)) + + ;; Ensure access to scanning info + (reftex-access-scan-info) + + (setq docstruct-symbol reftex-docstruct-symbol + all (symbol-value reftex-docstruct-symbol) + reftex-active-toc nil + master-dir-re + (concat "\\`" (regexp-quote + (file-name-directory (reftex-TeX-master-file)))))) + + (when refont + ;; Calculate font-lock-defaults as in LaTeX mode. + (make-local-variable 'font-lock-defaults) + (setq font-lock-defaults nil) + (let ((major-mode 'latex-mode)) + (font-lock-set-defaults)) + ;; The following is only needed for XEmacs, but does not hurt Emacs. + (setq font-lock-mode nil)) + + ;; Walk the docstruct and insert the appropriate stuff + + (while (setq cell (pop all)) + + (incf index) + (setq from (point)) + + (if (eq cell here-I-am) (setq offset (1+ cnt))) + + (cond + + ((memq (car cell) '(bib label-numbers master-dir is-multi + xr xr-doc))) + ;; These are currently ignored + + ((memq (car cell) '(bof eof file-error)) + ;; Beginning or end of a file + (when files + (insert + " " (if (string-match master-dir-re (nth 1 cell)) + (substring (nth 1 cell) (match-end 0)) + (nth 1 cell)) + (cond ((eq (car cell) 'bof) " starts here\n") + ((eq (car cell) 'eof) " ends here\n") + ((eq (car cell) 'file-error) " was not found\n"))) + (when font + (put-text-property from (point) + 'face 'font-lock-function-name-face)))) + + ((eq (car cell) 'toc) + ;; a table of contents entry + (when toc + (setq reftex-active-toc cell) + (insert (concat toc-indent (nth 2 cell) "\n")))) + + ((stringp (car cell)) + ;; a label + (when (null (nth 2 cell)) + ;; No context yet. Quick update. + (setq cell (reftex-label-info-update cell)) + (setcar (nthcdr index (symbol-value docstruct-symbol)) + cell)) + + (setq label (car cell) + typekey (nth 1 cell) + text (nth 2 cell) + note (nth 4 cell) + comment (get-text-property 0 'in-comment text)) + + (when (and (or (string= typekey typekey0) (string= typekey0 " ")) + (or show-commented (null comment))) + + ;; Yes we want this one + (incf cnt) + (push index index-list) + + (setq label (concat xr-prefix label)) + (when comment (setq label (concat "% " label))) + (insert label-indent label) + (when font + (put-text-property + (- (point) (length label)) (point) + 'face (if comment + 'font-lock-comment-face + 'font-lock-reference-face))) + + (insert (if counter (format " (%d) " cnt) "") + (if comment " LABEL IS COMMENTED OUT " "") + (if note (concat " " note) "") + "\n") + (setq to (point)) + + (when context + (setq from1 to) + (insert context-indent text "\n") + (setq to (point)) + (when refont + (font-lock-fontify-region from1 to) + (goto-char to))) + (put-text-property from to 'cnt (1- cnt)) + (goto-char to))))) + + ;; Return the index list (cons offset (nreverse index-list)))) +(defun reftex-parse-document (&optional buffer cnt key) + "Rescan the document." + (interactive) + (save-window-excursion + (save-excursion + (if buffer + (if (not (bufferp buffer)) + (error "No such buffer %s" (buffer-name buffer)) + (set-buffer buffer))) + (let ((arg (if (eq key ?R) '(16) '(4))) + (file (if cnt + (nth 3 + (nth (nth cnt reftex-label-index-list) + (symbol-value reftex-docstruct-symbol)))))) + (reftex-access-scan-info arg file))))) + (defun reftex-query-label-type () ;; Ask for label type (message reftex-type-query-prompt) (let ((key (read-char))) - (if (eq key ?\?) - (progn - (save-window-excursion - (with-output-to-temp-buffer "*RefTeX Help*" - (princ reftex-type-query-help)) - (setq key (read-char)) - (kill-buffer "*RefTeX Help*")))) - (if (not (member (char-to-string key) reftex-typekey-list)) - (error "No such label type: %s" (char-to-string key))) + (when (eq key ?\?) + (save-window-excursion + (with-output-to-temp-buffer "*RefTeX Help*" + (princ reftex-type-query-help)) + (setq key (read-char)) + (kill-buffer "*RefTeX Help*"))) + (unless (member (char-to-string key) reftex-typekey-list) + (error "No such label type: %s" (char-to-string key))) (char-to-string key))) -(defun reftex-find-nearby-label () - ;; Find a nearby label. - (save-excursion - (if (or (re-search-backward "\\\\[a-z]*label{\\([^}]+\\)}" nil t) - (re-search-forward "\\\\[a-z]*label{\\([^}]+\\)}" nil t)) - (reftex-no-props (match-string 1)) - nil))) - ;; Variable holding the vector with section numbers (defvar reftex-section-numbers [0 0 0 0 0 0 0 0]) -(defun reftex-scan-buffer-for-labels (label-numbers-symbol label-list-symbol) - ;; Scan the buffer for labels and save them in a list. - (save-excursion - (let ((regexp (concat "\\\\[a-z]*label{\\([^}]*\\)}" "\\|" - reftex-section-regexp)) - (font (reftex-use-fonts)) - (bound 0) - (highest-level 100) - file (level 1) star text text1 label section-number macro find) - (set label-list-symbol nil) - (goto-char 0) - - ;; reset label numbers - (set label-numbers-symbol nil) - - ;; reset section numbers - (reftex-init-section-numbers reftex-section-numbers) - - (while (re-search-forward regexp nil t) - (setq file (get-text-property (match-beginning 0) 'file)) - (if (match-string 1) - ;; It is a label - (progn - (setq label (reftex-no-props (match-string 1))) - (set label-list-symbol - (cons (reftex-label-info label file bound) - (symbol-value label-list-symbol)))) - - ;; It is a section - (setq bound (point)) - (setq star (= ?* (char-after (match-end 2)))) - (setq find (buffer-substring-no-properties - (1- (match-beginning 2)) (match-end 0))) - (setq macro (reftex-no-props (match-string 2))) - (setq level (cdr (assoc macro reftex-section-levels))) - - (setq section-number (reftex-section-number - reftex-section-numbers level star)) - (setq highest-level (min highest-level level)) - (if (= level highest-level) - (message - "Scanning %s %s ..." - (car (nth level reftex-section-levels)) - section-number)) - - ;; get the title - (save-match-data - (save-excursion - (setq text1 (reftex-context-substring)) - (setq text (reftex-nicify-text text1)))) - - (setq find - (reftex-allow-for-ctrl-m - (concat find text1 - (char-to-string - (char-after (+ (match-end 0) (length text1))))))) - - ;; add section number and indentation - (setq text - (concat - (make-string (* reftex-level-indent level) ?\ ) - (if (nth 1 reftex-label-menu-flags) ; section number flag - (concat section-number " ")) - text)) - ;; fontify - (if font (put-text-property 0 (length text) - 'face 'font-lock-comment-face text)) - - ;; insert in list - (set label-list-symbol - (cons (list 'toc "toc" text file find level section-number) - (symbol-value label-list-symbol))))) - (set label-list-symbol - (nreverse (symbol-value label-list-symbol)))))) +(defun reftex-section-info (file) + ;; Return a section entry for the current match. + ;; Carefull: This function expects the match-data to be still in place! + (let* ((marker (set-marker (make-marker) (1- (match-beginning 3)))) + (macro (reftex-match-string 3)) + (star (= ?* (char-after (match-end 3)))) + (level (cdr (assoc macro reftex-section-levels))) + (section-number (reftex-section-number + reftex-section-numbers level star)) + (text1 (save-match-data (save-excursion (reftex-context-substring)))) + (literal (buffer-substring-no-properties + (1- (match-beginning 3)) + (min (point-max) (+ (match-end 0) (length text1) 1)))) + ;; Literal can be too short since text1 too short. No big problem. + (text (reftex-nicify-text text1))) + + ;; Add section number and indentation + (setq text + (concat + (make-string (* reftex-level-indent level) ?\ ) + (if (nth 1 reftex-label-menu-flags) ; section number flag + (concat section-number " ")) + text)) + ;; Fontify + (if (reftex-use-fonts) + (put-text-property 0 (length text) + 'face 'font-lock-comment-face text)) + (list 'toc "toc" text file marker level section-number + literal (marker-position marker)))) (defun reftex-label-info-update (cell) ;; Update information about just one label in a different file. @@ -2417,7 +2968,7 @@ (file (nth 3 cell)) (note (nth 4 cell)) (buf (reftex-get-file-buffer-force - file (not reftex-keep-temporary-buffers)))) + file (not (eq t reftex-keep-temporary-buffers))))) (if (not buf) (list label typekey "" file "LOST LABEL. RESCAN TO FIX.") (save-excursion @@ -2426,15 +2977,21 @@ (widen) (goto-char 1) - (if (re-search-forward (concat "\\\\[a-z]*label{" - (regexp-quote label) "}") - nil t) - (append (reftex-label-info label file) (list note)) + (if (or (re-search-forward + (format reftex-find-label-regexp-format + (regexp-quote label)) nil t) + (re-search-forward + (format reftex-find-label-regexp-format2 + (regexp-quote label)) nil t)) + + (progn + (backward-char 1) + (append (reftex-label-info label file) (list note))) (list label typekey "" file "LOST LABEL. RESCAN TO FIX."))))))) -(defun reftex-label-info (label &optional file bound derive) +(defun reftex-label-info (label &optional file bound derive env-or-mac) ;; Return info list on LABEL at point. - (let* ((env-or-mac (reftex-label-location bound)) + (let* ((env-or-mac (or env-or-mac (reftex-label-location bound))) (typekey (nth 1 (assoc env-or-mac reftex-env-or-mac-alist))) (file (or file (buffer-file-name))) (parse (if (reftex-typekey-check @@ -2442,7 +2999,7 @@ nil (nth 2 (assoc env-or-mac reftex-env-or-mac-alist)))) (text (reftex-short-context env-or-mac parse reftex-location-start - derive))) + derive))) (if (reftex-in-comment) (put-text-property 0 1 'in-comment t text)) (list label typekey text file))) @@ -2450,7 +3007,7 @@ (defun reftex-in-comment () (save-excursion (skip-chars-backward "^%\n\r") - (= (preceding-char) ?%))) + (eq (preceding-char) ?%))) (defun reftex-short-context (env parse &optional bound derive) ;; Get about one line of useful context for the label definition at point. @@ -2470,13 +3027,21 @@ (if (string= env "section") ;; special treatment for section labels (save-excursion - (if (re-search-backward reftex-section-regexp (point-min) t) + (if (and (re-search-backward reftex-section-or-include-regexp + (point-min) t) + (match-end 2)) (progn (goto-char (match-end 0)) (reftex-context-substring)) - "SECTION HEADING NOT FOUND")) + (if reftex-active-toc + (progn + (string-match "{\\([^}]*\\)" (nth 7 reftex-active-toc)) + (match-string 1 (nth 7 reftex-active-toc))) + "SECTION HEADING NOT FOUND"))) (save-excursion - (goto-char reftex-default-context-position) + (goto-char reftex-default-context-position) + (unless (eq (string-to-char env) ?\\) + (reftex-move-over-touching-args)) (reftex-context-substring)))) ((stringp parse) @@ -2488,9 +3053,12 @@ "NO MATCH FOR CONTEXT REGEXP"))) ((integerp parse) - (save-excursion - (goto-char reftex-default-context-position) - (reftex-nth-parens-substring parse))) + (or (save-excursion + (goto-char reftex-default-context-position) + (reftex-nth-arg + parse + (nth 6 (assoc env reftex-env-or-mac-alist)))) + "")) ((fboundp parse) ;; A hook function. Call it. @@ -2501,17 +3069,172 @@ (t "ILLEGAL VALUE OF PARSE")))) -(defun reftex-nth-parens-substring (n) +(defun reftex-where-am-I () + ;; Return the docstruct entry above point. Actually returns a cons + ;; cell in which the cdr is a flag indicating if the information is + ;; exact (t) or approximate (nil). + (interactive) + + (let ((docstruct (symbol-value reftex-docstruct-symbol)) + (cnt 0) rtn + found) + (save-excursion + (while (not rtn) + (incf cnt) + (setq found (re-search-backward reftex-everything-regexp nil t)) + (setq rtn + (cond + ((not found) + ;; no match + (or + (car (member (list 'bof (buffer-file-name)) docstruct)) + (not (setq cnt 2)) + (assq 'bof docstruct) ;; for safety reasons + 'corrupted)) + ((match-end 1) + ;; Label + (assoc (reftex-match-string 1) + (symbol-value reftex-docstruct-symbol))) + ((match-end 3) + ;; Section + (goto-char (1- (match-beginning 3))) + (let* ((list (member (list 'bof (buffer-file-name)) + docstruct)) + (endelt (car (member (list 'eof (buffer-file-name)) + list))) + rtn1) + (while (and list (not (eq endelt (car list)))) + (if (and (eq (car (car list)) 'toc) + (string= (buffer-file-name) + (nth 3 (car list)))) + (cond + ((equal (point) + (or (and (markerp (nth 4 (car list))) + (marker-position (nth 4 (car list)))) + (nth 8 (car list)))) + ;; Fits with marker position or recorded position + (setq rtn1 (car list) list nil)) + ((looking-at (reftex-make-regexp-allow-for-ctrl-m + (nth 7 (car list)))) + ;; Same title + (setq rtn1 (car list) list nil cnt 2)))) + (pop list)) + rtn1)) + ((match-end 7) + ;; Input or include... + (car + (member (list 'eof (reftex-find-tex-file + (reftex-match-string 7) + (cons + (cdr (assq 'master-dir docstruct)) + reftex-tex-path))) + docstruct))) + ((match-end 8) + (save-excursion + (goto-char (match-end 8)) + (assoc (reftex-no-props + (reftex-nth-arg-wrapper + (reftex-match-string 8))) + (symbol-value reftex-docstruct-symbol)))) + (t + (error "This should not happen (reftex-where-am-I)")))))) + (cons rtn (eq cnt 1)))) + +(defun reftex-parse-args (macro) + ;; Return a list of macro name, nargs, arg-nr which is label and a list of + ;; optional argument indices. + (if (string-match "[[{]\\*?[]}]" macro) + (progn + (let ((must-match (substring macro 0 (match-beginning 0))) + (args (substring macro (match-beginning 0))) + opt-list nlabel (cnt 0)) + (while (string-match "\\`[[{]\\(\\*\\)?[]}]" args) + (incf cnt) + (when (eq ?\[ (string-to-char args)) + (push cnt opt-list)) + (when (and (match-end 1) + (not nlabel)) + (setq nlabel cnt)) + (setq args (substring args (match-end 0)))) + (list must-match cnt nlabel opt-list))) + nil)) + +(defsubst reftex-move-to-next-arg (&optional ignore) + ;; Assuming that we are at the end of a macro name or a macro argument, + ;; move forward to the opening parenthesis of the next argument. + ;; This function understands the splitting of macros over several lines + ;; in TeX. + (cond + ;; Just to be quick: + ((memq (following-char) '(?\[ ?\{))) + ;; Do a search + ((looking-at "[ \t]*[\n\r]?\\([ \t]*%[^\n\r]*[\n\r]\\)*[ \t]*[[{]") + (goto-char (1- (match-end 0))) + t) + (t nil))) + +(defsubst reftex-move-to-previous-arg (&optional bound) + ;; Assuming that we are in front of a macro argument, + ;; move backward to the closing parenthesis of the previous argument. + ;; This function understands the splitting of macros over several lines + ;; in TeX. + (cond + ;; Just to be quick: + ((memq (preceding-char) '(?\] ?\}))) + ;; Do a search + ((re-search-backward + "[]}][ \t]*[\n\r]?\\([ \t]*%[^\n\r]*[\n\r]\\)*[ \t]*\\=" bound t) + (goto-char (1+ (match-beginning 0))) + t) + (t nil))) + +(defun reftex-nth-arg-wrapper (key) + (let ((entry (assoc key reftex-env-or-mac-alist))) + (reftex-nth-arg (nth 5 entry) (nth 6 entry)))) + +(defun reftex-nth-arg (n &optional opt-args) ;; Return the nth following {} or [] parentheses content. - ;; If we are sitting at a macro start, skip to ent of macro name. + ;; OPT-ARGS is a list of argument numbers which are optional. + + ;; If we are sitting at a macro start, skip to end of macro name. (and (eq (following-char) ?\\) (skip-chars-forward "a-zA-Z*\\\\")) - - ;; Skip parenthesis pairs. - (while (and (> (setq n (1- n)) 0) - (or (eq (following-char) ?{) (eq (following-char) ?\[)) - (condition-case nil (or (forward-list 1) t) (error nil)))) - (skip-chars-forward "{\\[") - (reftex-context-substring)) + + (if (= n 1000) + ;; Special case: Skip all touching arguments + (progn + (reftex-move-over-touching-args) + (reftex-context-substring)) + + ;; Do the real thing. + (let ((cnt 1)) + + (when (reftex-move-to-next-arg) + + (while (< cnt n) + (while (and (member cnt opt-args) + (eq (following-char) ?\{)) + (incf cnt)) + (when (< cnt n) + (unless (and (condition-case nil + (or (forward-list 1) t) + (error nil)) + (reftex-move-to-next-arg) + (incf cnt)) + (setq cnt 1000)))) + + (while (and (memq cnt opt-args) + (eq (following-char) ?\{)) + (incf cnt))) + (if (and (= n cnt) + (> (skip-chars-forward "{\\[") 0)) + (reftex-context-substring) + nil)))) + +(defun reftex-move-over-touching-args () + (condition-case nil + (while (memq (following-char) '(?\[ ?\{)) + (forward-list 1)) + (error nil))) (defun reftex-context-substring () ;; Return up to 100 chars from point @@ -2520,58 +3243,57 @@ ((or (= (preceding-char) ?\{) (= (preceding-char) ?\[)) ;; Inside a list - get only the list. - (buffer-substring + (buffer-substring-no-properties (point) - (min (+ 100 (point)) - (point-max) - (condition-case nil - (progn - (up-list 1) - (1- (point))) - (error (point-max)))))) + (min (reftex-fp 150) + (point-max) + (condition-case nil + (progn + (up-list 1) + (1- (point))) + (error (point-max)))))) (t ;; no list - just grab 100 characters - (buffer-substring (point) (min (+ 100 (point)) (point-max)))))) - -(defun reftex-init-section-numbers (section-numbers &optional toc-entry) + (buffer-substring-no-properties (point) (min (reftex-fp 150) (point-max)))))) + +(defun reftex-init-section-numbers (&optional toc-entry) ;; Initialize the section numbers with zeros or with what is found ;; in the toc entry. (let* ((level (or (nth 5 toc-entry) -1)) - (numbers (nreverse (reftex-split "\\." (or (nth 6 toc-entry) "")))) - (depth (1- (length section-numbers))) - (i depth)) + (numbers (nreverse (split-string (or (nth 6 toc-entry) "") "\\."))) + (depth (1- (length reftex-section-numbers))) + (i depth)) (while (>= i 0) (if (> i level) - (aset section-numbers i 0) - (aset section-numbers i (string-to-int (or (car numbers) "0"))) - (setq numbers (cdr numbers))) - (setq i (1- i))))) + (aset reftex-section-numbers i 0) + (aset reftex-section-numbers i (string-to-int (or (car numbers) "0"))) + (pop numbers)) + (decf i)))) (defun reftex-section-number (section-numbers &optional level star) ;; Return a string with the current section number. ;; When LEVEL is non-nil, increase section numbers on that level. (let* ((depth (1- (length section-numbers))) idx n (string "")) - (if level - (progn - (if (and (> level -1) (not star)) - (aset section-numbers level (1+ (aref section-numbers level)))) - (setq idx (1+ level)) - (while (<= idx depth) - (aset section-numbers idx 0) - (setq idx (1+ idx))))) + (when level + (when (and (> level -1) (not star)) + (aset section-numbers level (1+ (aref section-numbers level)))) + (setq idx (1+ level)) + (while (<= idx depth) + (aset section-numbers idx 0) + (incf idx))) (setq idx 0) (while (<= idx depth) (setq n (aref section-numbers idx)) (setq string (concat string (if (not (string= string "")) "." "") (int-to-string n))) - (setq idx (1+ idx))) + (incf idx)) (save-match-data (if (string-match "\\`\\(0\\.\\)+" string) (setq string (replace-match "" nil nil string))) (if (string-match "\\(\\.0\\)+\\'" string) (setq string (replace-match "" nil nil string)))) - (if star - (concat (make-string (1- (length string)) ?\ ) "*") + (if star + (concat (make-string (1- (length string)) ?\ ) "*") string))) ;; A variable to remember the index of the last label context shown @@ -2581,13 +3303,13 @@ ;; Callback function called from the label selection in order to ;; show context in another window (let* ((this-window (selected-window)) - index entry label file buffer) + index entry label file buffer re) ;; pop to original buffer in order to get correct variables (catch 'exit (save-excursion (set-buffer reftex-call-back-to-this-buffer) (setq index (nth (or cnt 1) reftex-label-index-list) - entry (nth index (symbol-value reftex-list-of-labels-symbol)) + entry (nth index (symbol-value reftex-docstruct-symbol)) label (nth 0 entry) file (nth 3 entry))) @@ -2604,47 +3326,49 @@ ;; search for that label - (if (not (and (integerp cnt) - (integerp reftex-last-cnt) - (if (> cnt reftex-last-cnt) - (re-search-forward - (concat "\\\\[a-z]*label{" (regexp-quote label) - "}") nil t) - (re-search-backward - (concat "\\\\[a-z]*label{" (regexp-quote label) - "}") nil t)))) - (progn - (goto-char 1) - (re-search-forward (concat "\\\\[a-z]*label{" - (regexp-quote label) "}") nil t))) - (reftex-highlight 0 (match-beginning 0) (match-end 0)) - (reftex-show-entry) - (recenter (/ (window-height) 2)) + (setq re (format reftex-find-label-regexp-format (regexp-quote label))) + (unless (and (integerp cnt) + (integerp reftex-last-cnt) + (if (> cnt reftex-last-cnt) + (re-search-forward re nil t) + (re-search-backward re nil t))) + (goto-char (point-min)) + (unless (re-search-forward re nil t) + ;; Ooops. Must be in a macro with distributed args. + (re-search-forward (format reftex-find-label-regexp-format2 + (regexp-quote label)) nil t))) + (when (match-end 3) + (reftex-highlight 0 (match-beginning 3) (match-end 3)) + (reftex-show-entry (- (point) (match-beginning 3)) + (- (point) (match-end 3))) + (recenter (/ (window-height) 2))) (select-window this-window)))) (defun reftex-pop-to-label (label file-list &optional mark-to-kill highlight) ;; Find LABEL in any file in FILE-LIST in another window. ;; If mark-to-kill is non-nil, mark new buffer for killing. ;; If HIGHLIGHT is non-nil, highlight the label definition. - (let* ((re (concat "\\\\[a-z]*label{" (regexp-quote label) "}")) + (let* ((re1 (format reftex-find-label-regexp-format (regexp-quote label))) + (re2 (format reftex-find-label-regexp-format2 (regexp-quote label))) + (re-list (list re1 re2)) re + (file-list-1 file-list) file buf) (catch 'exit - (while file-list - (setq file (car file-list) - file-list (cdr file-list)) - (if (not (setq buf (reftex-get-file-buffer-force file mark-to-kill))) - (error "No such file %s" file)) - (set-buffer buf) - (widen) - (goto-char (point-min)) - (if (re-search-forward re nil t) - (progn - (switch-to-buffer-other-window buf) - (goto-char (match-beginning 0)) - (recenter (/ (window-height) 2)) - (if highlight - (reftex-highlight 0 (match-beginning 0) (match-end 0))) - (throw 'exit (selected-window))))) + (while (setq re (pop re-list)) + (setq file-list file-list-1) + (while (setq file (pop file-list)) + (unless (setq buf (reftex-get-file-buffer-force file mark-to-kill)) + (error "No such file %s" file)) + (set-buffer buf) + (widen) + (goto-char (point-min)) + (when (re-search-forward re nil t) + (switch-to-buffer-other-window buf) + (goto-char (match-beginning 0)) + (recenter (/ (window-height) 2)) + (if highlight + (reftex-highlight 0 (match-beginning 3) (match-end 3))) + (throw 'exit (selected-window))))) (error "Label %s not found" label)))) (defun reftex-find-duplicate-labels () @@ -2656,21 +3380,24 @@ (reftex-access-scan-info t) (let ((master (reftex-TeX-master-file)) - (dlist + (dlist (mapcar '(lambda(x) (let (x1) (cond - ((memq (car x) '(toc bof eof)) nil) + ((memq (car x) + '(toc bof eof bib label-numbers xr xr-doc + master-dir file-error is-multi)) + nil) (t (setq x1 (reftex-all-assoc-string - (car x) (symbol-value reftex-list-of-labels-symbol))) + (car x) (symbol-value reftex-docstruct-symbol))) (if (< 1 (length x1)) - (append (list (reftex-no-props (car x))) + (append (list (car x)) (mapcar '(lambda(x) (abbreviate-file-name (nth 3 x))) x1)) (list nil)))))) - (reftex-uniquify (symbol-value reftex-list-of-labels-symbol))))) + (reftex-uniquify (symbol-value reftex-docstruct-symbol))))) (setq dlist (reftex-uniquify dlist)) (if (null dlist) (error "No duplicate labels in document")) (switch-to-buffer-other-window "*Duplicate Labels*") @@ -2679,70 +3406,103 @@ (erase-buffer) (insert " MULTIPLE LABELS IN CURRENT DOCUMENT:\n") (insert " Move point to label and type `M-x reftex-change-label'\n" - " This will run a query-replace on the label and its references\n") + " This will run a query-replace on the label and its references\n") (insert " LABEL FILE\n") (insert " -------------------------------------------------------------\n") (while dlist - (if (and (car (car dlist)) - (cdr (car dlist))) - (progn - (insert (mapconcat '(lambda(x) x) (car dlist) "\n ") "\n"))) - (setq dlist (cdr dlist))) + (when (and (car (car dlist)) + (cdr (car dlist))) + (insert (mapconcat '(lambda(x) x) (car dlist) "\n ") "\n")) + (pop dlist)) (goto-char (point-min)))) +(defun reftex-all-assq (key list) + ;; Return a list of all associations of KEY in LIST. Comparison with string= + (let (rtn) + (while (setq list (memq (assq key list) list)) + (push (car list) rtn) + (pop list)) + (nreverse rtn))) + (defun reftex-all-assoc-string (key list) ;; Return a list of all associations of KEY in LIST. Comparison with string= (let (rtn) (while list (if (string= (car (car list)) key) - (setq rtn (cons (car list) rtn))) - (setq list (cdr list))) + (push (car list) rtn)) + (pop list)) (nreverse rtn))) -(defun reftex-kill-temporary-buffers () +(defun reftex-kill-temporary-buffers (&optional buffer) ;; Kill all buffers in the list reftex-kill-temporary-buffers. - (while reftex-buffers-to-kill - (if (bufferp (car reftex-buffers-to-kill)) - (progn - (and (buffer-modified-p (car reftex-buffers-to-kill)) - (y-or-n-p (format "Save file %s? " - (buffer-file-name - (car reftex-buffers-to-kill)))) - (save-excursion - (set-buffer (car reftex-buffers-to-kill)) - (save-buffer))) - (kill-buffer (car reftex-buffers-to-kill)))) - (setq reftex-buffers-to-kill (cdr reftex-buffers-to-kill)))) - -(defun reftex-show-entry () + (cond + (buffer + (when (member buffer reftex-buffers-to-kill) + (kill-buffer buffer) + (setq reftex-buffers-to-kill + (delete buffer reftex-buffers-to-kill)))) + (t + (while (setq buffer (pop reftex-buffers-to-kill)) + (when (bufferp buffer) + (and (buffer-modified-p buffer) + (y-or-n-p (format "Save file %s? " + (buffer-file-name buffer))) + (save-excursion + (set-buffer buffer) + (save-buffer))) + (kill-buffer buffer)) + (pop reftex-buffers-to-kill))))) + +(defun reftex-show-entry (beg-hlt end-hlt) ;; Show entry if point is hidden by outline mode - (let ((pos (point))) + (let* ((pos (point)) + (n (/ (window-height) 2)) + (beg (save-excursion + (re-search-backward "[\n\r]" nil 1 n) (point))) + (end (save-excursion + (re-search-forward "[\n\r]" nil 1 n) (point)))) (if (and reftex-auto-show-entry - (boundp 'outline-minor-mode) - outline-minor-mode - (looking-at "[^\n\r]*\r")) - (progn - (outline-back-to-heading) - (show-entry) - (goto-char pos))))) - + (string-match + "\r" (buffer-substring beg end))) + (cond + ((eq t reftex-auto-show-entry) + (subst-char-in-region + (save-excursion (search-backward "\n" nil t) (point)) + (save-excursion (search-forward "\n" nil t) (point)) + ?\r ?\n t)) + ((eq reftex-auto-show-entry 'copy) + (let ((string (buffer-substring beg end))) + (switch-to-buffer "*RefTeX Context Copy*") + (setq buffer-read-only nil) + (erase-buffer) + (insert string) + (subst-char-in-region (point-min) (point-max) ?\r ?\n t) + (goto-char (- pos beg)) + (reftex-highlight 0 (1+ (- (point) beg-hlt)) + (1+ (- (point) end-hlt))) + (when (reftex-refontify) + (make-local-variable 'font-lock-defaults) + (setq font-lock-defaults nil) + (let ((major-mode 'latex-mode)) + (font-lock-set-defaults) + (font-lock-fontify-buffer))) + (setq buffer-read-only t))) + )))) (defun reftex-nicify-text (text) - ;; Make TEXT nice for inclusion into label menu + ;; Make TEXT nice for inclusion as context into label menu (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text) ; remove extra whitespace (setq text (replace-match " " nil t text))) (if (string-match "\\\\end{.*" text) ; nothing beyond \end{ (setq text (replace-match "" nil t text))) - (if (string-match "\\\\[a-z]*label{[^}]*}" text) ; kill the label + (if (string-match "\\\\label{[^}]*}" text) ; kill the label (setq text (replace-match "" nil t text))) - (if (string-match "^ +" text) ; leading whitespace + (if (string-match "\\`[ }]+" text) ; leading whitespace, `}' (setq text (replace-match "" nil t text))) (cond - ((> (length text) 100) ; not to long - (setq text (substring text 0 100))) - ((= (length text) 0) ; not empty - (setq text " "))) - text) + ((> (length text) 100) (substring text 0 100)) + ((= (length text) 0) " ") + (t text))) (defun reftex-typekey-check (typekey conf-variable &optional n) ;; Check if CONF-VARIABLE is true or contains TYPEKEY @@ -2753,7 +3513,7 @@ ;;; =========================================================================== ;;; -;;; Table of contents (contributed from Stephen Eglen, changed by C. Dominik) +;;; Table of contents ;; We keep at most one *toc* buffer - it is easy to make them @@ -2776,7 +3536,8 @@ RET Goto the section and hide the *toc* buffer (also on mouse-2). q / Q Hide/Kill *toc* buffer, return to position of last reftex-toc command. f Toggle follow mode on and off. -r / g Reparse the LaTeX document.") +r / g Reparse the LaTeX document. +x Switch to TOC of external document (with LaTeX package `xr').") (defun reftex-toc () "Show the table of contents for the current document. @@ -2785,7 +3546,7 @@ (interactive) (if (or (not (string= reftex-last-toc-master (reftex-TeX-master-file))) - current-prefix-arg) + current-prefix-arg) (reftex-empty-toc-buffer)) (setq reftex-last-toc-file (buffer-file-name)) @@ -2800,9 +3561,11 @@ ;; Ensure access to scanning info and rescan buffer if prefix are is '(4) (reftex-access-scan-info current-prefix-arg) - (let* ((all (symbol-value reftex-list-of-labels-symbol)) + (let* ((all (symbol-value reftex-docstruct-symbol)) + (xr-data (assq 'xr all)) + (xr-alist (cons (cons "" (buffer-file-name)) (nth 1 xr-data))) (where (reftex-nearest-section)) - toc toc1 cell label file find startpos) + toc1 cell startpos) (if (get-buffer-window "*toc*") (select-window (get-buffer-window "*toc*")) @@ -2819,10 +3582,12 @@ (local-set-key "\C-m" 'reftex-toc-goto-line-and-hide) (local-set-key "\C-i" 'reftex-toc-goto-line) (local-set-key "r" 'reftex-toc-redo) + (local-set-key "R" 'reftex-toc-Redo) (local-set-key "g" 'revert-buffer) (local-set-key "q" 'reftex-toc-quit) (local-set-key "Q" 'reftex-toc-quit-and-kill) (local-set-key "f" 'reftex-toc-toggle-follow) + (local-set-key "x" 'reftex-toc-external) (local-set-key [(mouse-2)] 'reftex-toc-mouse-goto-line-and-hide); Emacs (local-set-key [(button2)] 'reftex-toc-mouse-goto-line-and-hide); XEmacs (make-local-variable 'revert-buffer-function) @@ -2835,7 +3600,7 @@ (insert (format "TABLE-OF-CONTENTS on %s - SPC=view TAB=goto RET=goto+hide [q]uit [r]escan [f]ollow-mode [?]Help +SPC=view TAB=goto RET=goto+hide [q]uit [r]escan [f]ollow-mode e[x]tern [?]Help ------------------------------------------------------------------------------- " (abbreviate-file-name reftex-last-toc-master))) (setq startpos (point)) @@ -2843,23 +3608,15 @@ (if (reftex-use-fonts) (put-text-property 1 (point) 'face 'font-lock-keyword-face)) (put-text-property 1 (point) 'intangible t) + (put-text-property 1 2 'xr-alist xr-alist) (while all (setq cell (car all) all (cdr all)) - (setq label (nth 0 cell) - toc (nth 2 cell) - file (nth 3 cell) - find (nth 4 cell)) - (if (eq label 'toc) - (progn - (setq toc1 (concat toc "\n")) - (put-text-property 0 (length toc1) - 'file file toc1) - (put-text-property 0 (length toc1) - 'find find toc1) - (insert toc1) - ))) + (when (eq (car cell) 'toc) + (setq toc1 (concat (nth 2 cell) "\n")) + (put-text-property 0 (length toc1) 'toc cell toc1) + (insert toc1))) (backward-delete-char 1) @@ -2873,41 +3630,14 @@ (goto-char (point-max)) (beginning-of-line) (while (and (> (point) startpos) - (or (not (string= (get-text-property (point) 'file) - (car where))) - (not (string= (get-text-property (point) 'find) - (cdr where))))) + (not (eq (get-text-property (point) 'toc) where))) (beginning-of-line 0)))) (defun reftex-nearest-section () ;; Return (file . find) of nearest section command - (let (cell label rest pos text1 text2) - (save-excursion - (cond - ;; Try to find a section heading - ((or (re-search-backward reftex-section-regexp nil t) - (re-search-forward reftex-section-regexp nil t)) - (goto-char (match-end 0)) - (setq pos (point) - text1 (buffer-substring-no-properties - (1- (match-beginning 1)) (match-end 0)) - text2 (reftex-context-substring)) - (cons (buffer-file-name) - (reftex-allow-for-ctrl-m - (concat text1 text2 - (char-to-string - (char-after (+ pos (length text2)))))))) - ;; Try to find a label - ((and (or (re-search-backward "\\\\[a-z]*label{\\([^}]+\\)}" nil t) - (re-search-forward "\\\\[a-z]*label{\\([^}]+\\)}" nil t)) - (setq label (reftex-no-props (match-string 1))) - (setq cell (assoc label (symbol-value - reftex-list-of-labels-symbol))) - (setq rest (memq cell (symbol-value reftex-list-of-labels-symbol))) - (setq cell (car (memq (assoc nil rest) rest))) - (null (car cell))) - (cons (nth 3 cell) (nth 4 cell))) - (t nil))))) + (let* ((here-I-am (car (reftex-where-am-I)))) + (reftex-last-assoc-before-elt + 'toc here-I-am (symbol-value reftex-docstruct-symbol)))) (defun reftex-toc-pre-command-hook () ;; used as pre command hook in *toc* buffer @@ -2918,9 +3648,9 @@ ;; used in the post-command-hook for the *toc* buffer (and (> (point) 1) (save-excursion - (reftex-highlight 1 - (progn (beginning-of-line) (point)) - (progn (end-of-line) (point))))) + (reftex-highlight 1 + (progn (beginning-of-line) (point)) + (progn (end-of-line) (point))))) (cond ((integerp reftex-toc-follow-mode) ;; remove delayed action @@ -2933,15 +3663,15 @@ (defun reftex-empty-toc-buffer () (if (get-buffer "*toc*") - (save-excursion - (set-buffer "*toc*") - (setq buffer-read-only nil) - (erase-buffer)))) + (save-excursion + (set-buffer "*toc*") + (setq buffer-read-only nil) + (erase-buffer)))) (defun reftex-re-enlarge () - (enlarge-window - (max 0 (- (or reftex-last-window-height (window-height)) - (window-height))))) + (enlarge-window + (max 0 (- (or reftex-last-window-height (window-height)) + (window-height))))) (defun reftex-toc-show-help () (interactive) @@ -2979,7 +3709,7 @@ (or (one-window-p) (delete-window)) (switch-to-buffer (marker-buffer reftex-toc-return-marker)) (reftex-re-enlarge) - (goto-char (marker-position reftex-toc-return-marker))) + (goto-char (or (marker-position reftex-toc-return-marker) (point)))) (defun reftex-toc-quit-and-kill () "Kill the *toc* buffer." (interactive) @@ -2989,49 +3719,94 @@ (reftex-re-enlarge) (goto-char (marker-position reftex-toc-return-marker))) (defun reftex-toc-redo (&rest ignore) - "Regenerate the *toc* buffer. Call only from within the *toc* buffer" + "Regenerate the *toc* buffer by reparsing file of last reftex-toc command." + (interactive) + (if reftex-enable-partial-scans + (let ((file (nth 3 (get-text-property (point) 'toc)))) + (if (not file) + (error "Don't know which file to rescan. Try `R'.") + (switch-to-buffer-other-window + (reftex-get-file-buffer-force file)) + (setq current-prefix-arg '(4)) + (reftex-toc))) + (reftex-toc-Redo)) + (reftex-kill-temporary-buffers)) +(defun reftex-toc-Redo (&rest ignore) + "Regenerate the *toc* buffer by reparsing the entire document." (interactive) (switch-to-buffer-other-window (reftex-get-file-buffer-force reftex-last-toc-file)) - (setq current-prefix-arg '(4)) + (setq current-prefix-arg '(16)) (reftex-toc)) +(defun reftex-toc-external (&rest ignore) + "Switch to table of contents of an external document." + (interactive) + (let* ((xr-alist (get-text-property 1 'xr-alist)) + (xr-index (reftex-select-external-document + xr-alist 0))) + (switch-to-buffer-other-window (or (reftex-get-file-buffer-force + (cdr (nth xr-index xr-alist))) + (error "Cannot switch document"))) + (reftex-toc))) (defun reftex-toc-visit-line (&optional final) ;; Visit the tex file corresponding to the toc entry on the current line. ;; If FINAL is t, stay there ;; If FINAL is 'hide, hide the *toc* window. - ;; Otherwise, move cursor back into *toc* window - - (let (file find beg end (toc-window (selected-window)) - show-window show-buffer) - (save-excursion - (beginning-of-line) - (setq beg (point)) - (end-of-line) - (setq end (point))) - - ;; get the file and the search string - (setq file (get-text-property (point) 'file)) - (setq find (get-text-property (point) 'find)) - (if (or (not file) (not find)) - (error "Cannot visit line")) - - (switch-to-buffer-other-window (reftex-get-file-buffer-force file)) - (setq show-window (selected-window)) - (setq show-buffer (current-buffer)) - (goto-char (point-min)) - - (if (not (re-search-forward find nil t)) - (progn - (select-window toc-window) - (error "Cannot visit line"))) - - (setq beg (match-beginning 0) - end (match-end 0)) - - (goto-char beg) + ;; Otherwise, move cursor back into *toc* window. + ;; This function is pretty clever about finding back a section heading, + ;; even if the buffer is not live, or things like outline, x-symbol etc. + ;; have been active. + + (let* ((toc (get-text-property (point) 'toc)) + (file (nth 3 toc)) + (marker (nth 4 toc)) + (level (nth 5 toc)) + (literal (nth 7 toc)) + (emergency-point (nth 8 toc)) + (toc-window (selected-window)) + show-window show-buffer match) + + (unless toc (error "Don't know which toc line to visit")) + + (setq match + (cond + ((and (markerp marker) (marker-buffer marker)) + ;; Buffer is still live and we have the marker. Should be easy. + (switch-to-buffer-other-window (marker-buffer marker)) + (goto-char (marker-position marker)) + (or (looking-at (regexp-quote literal)) + (looking-at (reftex-make-regexp-allow-for-ctrl-m literal)) + (looking-at (reftex-make-desparate-section-regexp literal)) + (looking-at (concat "\\\\" + (regexp-quote + (car (rassq level reftex-section-levels))) + "[[{]")))) + (t + ;; Marker is lost. Use the backup method. + (switch-to-buffer-other-window + (reftex-get-file-buffer-force file nil)) + (goto-char (or emergency-point (point-min))) + (or (looking-at (regexp-quote literal)) + (let ((pos (point))) + (re-search-backward "\\`\\|[\r\n][ \t]*[\r\n]" nil t) + (or (reftex-nearest-match (regexp-quote literal) pos) + (reftex-nearest-match + (reftex-make-regexp-allow-for-ctrl-m literal) pos) + (reftex-nearest-match + (reftex-make-desparate-section-regexp literal) pos))))) + )) + + (setq show-window (selected-window) + show-buffer (current-buffer)) + + (unless match + (select-window toc-window) + (error "Cannot find line")) + + (goto-char (match-beginning 0)) (recenter 1) - (reftex-highlight 0 beg end (current-buffer)) + (reftex-highlight 0 (match-beginning 0) (match-end 0) (current-buffer)) (select-window toc-window) @@ -3073,80 +3848,69 @@ SPC Show full database entry in other window. f Toggle follow mode: Other window will follow with full db entry. q Quit without inserting \\cite macro into buffer. - M-r Recursive edit into other window. + e Recursive edit into other window. RET / a Accept current entry / Accept all entries.") ;; Find bibtex files (defun reftex-get-bibfile-list () - ;; Return list of bibfiles for current document + ;; Return list of bibfiles for current document. + ;; When using the chapterbib or bibunits package you should either + ;; use the same database files everywhere, or separate parts using + ;; different databases into different files (included into the mater file). + ;; Then this function will return the applicable database files. ;; Ensure access to scanning info (reftex-access-scan-info) - - (or (symbol-value reftex-bibfile-list-symbol) - (error "No BibTeX files to parse. Add \\bibliography statment to document and reparse."))) - -(defun reftex-scan-buffer-for-bibliography-statement (bib-list-symbol) - ;; Scan buffer for bibliography macro and store file list in bib-list-symbol. - (let (file-list dir-list) - (setq dir-list - (reftex-split - (concat path-separator "+") - (mapconcat '(lambda(x) - (if (getenv x) (getenv x) "")) - reftex-bibpath-environment-variables - path-separator))) - (goto-char (point-min)) - (if (re-search-forward "^[ \t]*\\\\bibliography{[ \t]*\\([^}]+\\)" nil t) - (progn - (setq dir-list - (cons (file-name-directory - (get-text-property (match-beginning 0) 'file)) - dir-list)) - (setq file-list - (mapcar '(lambda (x) (concat x ".bib")) - (reftex-delete-list - reftex-bibfile-ignore-list - (reftex-split - "[ \t\n]*,[ \t\n]*" - (reftex-no-props (match-string 1))))))) - (message "No \\bibliography command in document.")) - (set bib-list-symbol - (if file-list - (reftex-find-files-on-path file-list dir-list - "While parsing \\bibliography:") - nil)))) - -(defun reftex-find-files-on-path (file-list path-list &optional error-string) - ;; Search for all files in FILE-LIST on PATH-LIST. Return absolute names. - ;; A missing file throws an exception with the error message ERROR-STRING. - ;; When error-string is nil, no exception is thrown. - - (let (found-list found file) - (while file-list - (setq file (car file-list) - file-list (cdr file-list) - found nil) - (if (file-name-absolute-p file) - (setq found (expand-file-name file)) - (let ((dirs path-list)) - (while (and dirs (not found)) - (if (and (not (string= (car dirs) "")) - (file-exists-p (expand-file-name file (car dirs)))) - (setq found (expand-file-name file (car dirs)))) - (setq dirs (cdr dirs))))) - (if (and found - (file-exists-p found)) - (add-to-list 'found-list (expand-file-name found)) - (and error-string - (error "%s No such file %s." error-string file)))) - (nreverse found-list))) + (or + ;; Try inside this file (and its includes) + (cdr (reftex-last-assoc-before-elt + 'bib (list 'eof (buffer-file-name)) + (member (list 'bof (buffer-file-name)) + (symbol-value reftex-docstruct-symbol)))) + ;; Try after the beginning of this file + (cdr (assq 'bib (member (list 'bof (buffer-file-name)) + (symbol-value reftex-docstruct-symbol)))) + ;; Anywhere in the entire document + (cdr (assq 'bib (symbol-value reftex-docstruct-symbol))) + (error "\\bibliography statment missing or .bib files not found."))) + +(defun reftex-find-tex-file (file master-dir &optional die) + ;; Find FILE in MASTER-DIR or on reftex-tex-path. + ;; FILE may be given without the .tex extension. + (reftex-access-search-path "tex") + (let* ((path (cons master-dir reftex-tex-path)) + file1) + (setq file1 + (or (reftex-find-file-on-path (concat file ".tex") path) + (reftex-find-file-on-path file path))) + (unless file1 + (reftex-access-search-path "tex" t file) + (setq path (cons master-dir reftex-tex-path)) + (setq file1 + (or (reftex-find-file-on-path (concat file ".tex") path) + (reftex-find-file-on-path file path)))) + (cond (file1 file1) + (die (error "No such file: %s" file) nil) + (t (message "No such file: %s (ignored)" file) nil)))) + +(defun reftex-find-bib-file (file master-dir &optional die) + ;; Find FILE in MASTER-DIR or on reftex-bib-path + (reftex-access-search-path "bib") + (let ((file1 (reftex-find-file-on-path + file (cons master-dir reftex-bib-path)))) + (unless file1 + (reftex-access-search-path "bib" t file) + (setq file1 (reftex-find-file-on-path + file (cons master-dir reftex-bib-path)))) + (cond (file1 file1) + (die (error "No such file: %s" file) nil) + (t (message "No such file: %s (ignored)" file) nil)))) ;; Find a certain reference in any of the BibTeX files. (defun reftex-pop-to-bibtex-entry (key file-list - &optional mark-to-kill highlight) + &optional mark-to-kill highlight) ;; Find BibTeX KEY in any file in FILE-LIST in another window. ;; If mark-to-kill is non-nil, mark new buffer to kill." @@ -3158,18 +3922,17 @@ (while file-list (setq file (car file-list) file-list (cdr file-list)) - (if (not (setq buf (reftex-get-file-buffer-force file mark-to-kill))) - (error "No such file %s" file)) + (unless (setq buf (reftex-get-file-buffer-force file mark-to-kill)) + (error "No such file %s" file)) (switch-to-buffer buf) (widen) - (goto-char 0) - (if (re-search-forward re nil t) - (progn - (goto-char (match-beginning 0)) - (recenter 0) - (if highlight - (reftex-highlight 0 (match-beginning 0) (match-end 0))) - (throw 'exit (selected-window))))) + (goto-char (point-min)) + (when (re-search-forward re nil t) + (goto-char (match-beginning 0)) + (recenter 0) + (if highlight + (reftex-highlight 0 (match-beginning 0) (match-end 0))) + (throw 'exit (selected-window)))) (set-window-configuration window-conf) (beep) (message "No BibTeX entry with citation key %s" key)))) @@ -3181,15 +3944,14 @@ ;; BUFFERS is a list of buffers or file names. ;; Return list with entries." (let* (re-list first-re rest-re - ;; avoid fontification of lookup buffers - (lazy-lock-minimum-size 1) (buffer-list (if (listp buffers) buffers (list buffers))) found-list entry buffer1 buffer alist key-point start-point end-point) - (setq re-list (reftex-split "[ \t]*&&[ \t]*" - (read-string "RegExp [ && RegExp...]: " - nil 'reftex-cite-regexp-hist))) + (setq re-list (split-string + (read-string "RegExp [ && RegExp...]: " + nil 'reftex-cite-regexp-hist) + "[ \t]*&&[ \t]*")) (setq first-re (car re-list) ; We'll use the first re to find things, rest-re (cdr re-list)) ; the other to narrow down. @@ -3199,7 +3961,7 @@ (save-excursion (save-window-excursion - ;; walk through all bibtex files + ;; Walk through all bibtex files (while buffer-list (setq buffer (car buffer-list) buffer-list (cdr buffer-list)) @@ -3213,67 +3975,64 @@ (message "Scanning bibliography database %s" buffer1)) (set-buffer buffer1) - (save-excursion - (goto-char (point-min)) - (while (re-search-forward first-re nil t) - (catch 'search-again - (setq key-point (point)) - (if (not (re-search-backward - "^[ \t]*@\\([a-zA-Z]+\\)[ \t\n\r]*[{(]" nil t)) - (throw 'search-again nil)) - (setq start-point (point)) - (goto-char (match-end 0)) - (condition-case nil - (up-list 1) - (error (goto-char key-point) - (throw 'search-again nil))) - (setq end-point (point)) - - ;; Ignore @string, @comment and @c entries or things - ;; outside entries - (if (or (string= (downcase (match-string 1)) "string") - (string= (downcase (match-string 1)) "comment") - (string= (downcase (match-string 1)) "c") - (< (point) key-point)) ; this means match not in {} - (progn - (goto-char key-point) - (throw 'search-again nil))) - - ;; Well, we have got a match - (setq entry (concat - (buffer-substring start-point (point)) "\n")) - - ;; Check if other regexp match as well - (setq re-list rest-re) - (while re-list - (if (not (string-match (car re-list) entry)) - ;; nope - move on - (throw 'search-again nil)) - (setq re-list (cdr re-list))) - - (setq alist (reftex-parse-bibtex-entry - nil start-point end-point)) - (setq alist (cons (cons "&entry" entry) alist)) - - ;; check for crossref entries - (if (assoc "crossref" alist) - (setq alist - (append - alist (reftex-get-crossref-alist alist)))) - - ;; format the entry - (setq alist - (cons - (cons "&formatted" (reftex-format-bib-entry alist)) - alist)) - - ;; add it to the list - (setq found-list (cons alist found-list))))) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward first-re nil t) + (catch 'search-again + (setq key-point (point)) + (unless (re-search-backward + "\\(\\`\\|[\n\r]\\)[ \t]*@\\([a-zA-Z]+\\)[ \t\n\r]*[{(]" nil t) + (throw 'search-again nil)) + (setq start-point (point)) + (goto-char (match-end 0)) + (condition-case nil + (up-list 1) + (error (goto-char key-point) + (throw 'search-again nil))) + (setq end-point (point)) + + ;; Ignore @string, @comment and @c entries or things + ;; outside entries + (when (or (string= (downcase (match-string 2)) "string") + (string= (downcase (match-string 2)) "comment") + (string= (downcase (match-string 2)) "c") + (< (point) key-point)) ; this means match not in {} + (goto-char key-point) + (throw 'search-again nil)) + + ;; Well, we have got a match + (setq entry (concat + (buffer-substring start-point (point)) "\n")) + + ;; Check if other regexp match as well + (setq re-list rest-re) + (while re-list + (unless (string-match (car re-list) entry) + ;; nope - move on + (throw 'search-again nil)) + (pop re-list)) + + (setq alist (reftex-parse-bibtex-entry + nil start-point end-point)) + (push (cons "&entry" entry) alist) + + ;; check for crossref entries + (if (assoc "crossref" alist) + (setq alist + (append + alist (reftex-get-crossref-alist alist)))) + + ;; format the entry + (push (cons "&formatted" (reftex-format-bib-entry alist)) + alist) + + ;; add it to the list + (push alist found-list)))) (reftex-kill-temporary-buffers)))) (setq found-list (nreverse found-list)) - + ;; Sorting - (cond + (cond ((eq 'author reftex-sort-bibtex-matches) (sort found-list 'reftex-bib-sort-author)) ((eq 'year reftex-sort-bibtex-matches) @@ -3284,13 +4043,13 @@ (defun reftex-bib-sort-author (e1 e2) (let ((al1 (reftex-get-bib-names "author" e1)) - (al2 (reftex-get-bib-names "author" e2))) + (al2 (reftex-get-bib-names "author" e2))) (while (and al1 al2 (string= (car al1) (car al2))) - (setq al1 (cdr al1) - al2 (cdr al2))) + (pop al1) + (pop al2)) (if (and (stringp (car al1)) - (stringp (car al2))) - (string< (car al1) (car al2)) + (stringp (car al2))) + (string< (car al1) (car al2)) (not (stringp (car al1)))))) (defun reftex-bib-sort-year (e1 e2) @@ -3309,7 +4068,8 @@ (save-restriction (widen) (if (re-search-forward - (concat "@\\w+[{(][ \t\n\r]*" (regexp-quote crkey) "[ \t\n\r]*,") nil t) + (concat "@\\w+[{(][ \t\n\r]*" (regexp-quote crkey) + "[ \t\n\r]*,") nil t) (progn (setq start (match-beginning 0)) (condition-case nil @@ -3333,7 +4093,7 @@ (setq names (replace-match "" nil t names))) (while (string-match "[ \t][ \t]+" names) (setq names (replace-match " " nil t names))) - (reftex-split "\n" names))) + (split-string names "\n"))) (defun reftex-parse-bibtex-entry (entry &optional from to) (let (alist key start field) @@ -3349,14 +4109,14 @@ (narrow-to-region from to)) (goto-char (point-min)) - (if (re-search-forward + (if (re-search-forward "@\\(\\w+\\)[ \t\n\r]*[{(][ \t\n\r]*\\([^ \t\n\r,]+\\)" nil t) (setq alist (list - (cons "&type" (downcase (reftex-no-props (match-string 1)))) - (cons "&key" (reftex-no-props (match-string 2)))))) + (cons "&type" (downcase (reftex-match-string 1))) + (cons "&key" (reftex-match-string 2))))) (while (re-search-forward "\\(\\w+\\)[ \t\n\r]*=[ \t\n\r]*" nil t) - (setq key (reftex-no-props (downcase (match-string 1)))) + (setq key (downcase (reftex-match-string 1))) (cond ((= (following-char) ?{) (forward-char 1) @@ -3382,8 +4142,8 @@ ;; remove trailing garbage (if (string-match "[ \t}]+$" field) (setq field (replace-match "" nil t field))) - (setq alist (cons (cons key field) alist))) - alist)))) + (push (cons key field) alist)))) + alist)) (defun reftex-get-bib-field (fieldname entry) ;; Extract the field FIELDNAME from an ENTRY @@ -3393,8 +4153,7 @@ (defun reftex-format-bib-entry (entry) ;; Format a BibTeX ENTRY so that it is nice to look at (let* - ((rtn nil) - (auth-list (reftex-get-bib-names "author" entry)) + ((auth-list (reftex-get-bib-names "author" entry)) (authors (mapconcat '(lambda (x) x) auth-list ", ")) (year (reftex-get-bib-field "year" entry)) (title (reftex-get-bib-field "title" entry)) @@ -3420,33 +4179,19 @@ (equal type "inproceedings")) (concat "in: " (reftex-get-bib-field "booktitle" entry))) (t "")))) - (setq authors - (if (> (length authors) 30) - (concat (substring authors 0 27) "...") - (format "%-30s" authors)) - title - (if (> (length title) 70) - (concat (substring title 0 67) "...") - (format "%-70s" title)) - extra - (if (> (length extra) 40) - (concat (substring extra 0 37) "...") - (format "%-40s" extra))) - (if (reftex-use-fonts) - (progn - (put-text-property 0 (length authors) 'face 'font-lock-keyword-face - authors) - (put-text-property 0 (length title) 'face 'font-lock-comment-face - title) - (put-text-property 0 (length extra) 'face 'font-lock-reference-face - extra))) - (setq rtn (concat key "\n " authors " " year " " extra - "\n " title "\n\n")) - rtn)) + (setq authors (reftex-truncate authors 30 t t)) + (when (reftex-use-fonts) + (put-text-property 0 (length authors) 'face 'font-lock-keyword-face + authors) + (put-text-property 0 (length title) 'face 'font-lock-comment-face + title) + (put-text-property 0 (length extra) 'face 'font-lock-reference-face + extra)) + (concat key "\n " authors " " year " " extra "\n " title "\n\n"))) ;; Make a citation -(defun reftex-citation (&optional arg no-insert) +(defun reftex-citation (&optional no-insert) "Make a citation using BibTeX database files. After asking for a Regular Expression, it scans the buffers with bibtex entries (taken from the \\bibliography command) and offers the @@ -3462,22 +4207,27 @@ When called with just C-u as prefix, enforces rescan of buffer for bibliography statement (e.g. if it was changed)." - (interactive "P") + (interactive) ;; check for recursive edit (reftex-check-recursive-edit) ;; if there is just 1 C-u prefix arg, force to rescan buffer - (if (and current-prefix-arg - (listp current-prefix-arg) - (= 4 (prefix-numeric-value arg))) - (reftex-reset-scanning-information)) - - ;; check if there is already a cite command at point and change cite format + (reftex-access-scan-info current-prefix-arg) + + ;; Call reftex-do-citation, but protected + (unwind-protect + (reftex-do-citation current-prefix-arg no-insert) + (reftex-kill-temporary-buffers))) + +(defun reftex-do-citation (&optional arg no-insert) + ;; This really does the work of reftex-citation. + + ;; Check if there is already a cite command at point and change cite format ;; in order to only add another reference in the same cite command. (let (key format (macro (car (car (reftex-what-macro t))))) (if (and (stringp macro) - (string-match "\\`\\\\cite\\|cite\\'" macro)) + (string-match "\\`\\\\cite\\|cite\\'" macro)) (progn (cond ((or (not arg) @@ -3497,157 +4247,153 @@ (setq format "%l")))) ;; else: figure out the correct format (setq format - (cond - ((stringp reftex-cite-format) reftex-cite-format) - ((and (symbolp reftex-cite-format) - (assq reftex-cite-format reftex-cite-format-builtin)) - (nth 2 (assq reftex-cite-format reftex-cite-format-builtin))) - (t reftex-cite-format))) + (cond + ((stringp reftex-cite-format) reftex-cite-format) + ((and (symbolp reftex-cite-format) + (assq reftex-cite-format reftex-cite-format-builtin)) + (nth 2 (assq reftex-cite-format reftex-cite-format-builtin))) + (t reftex-cite-format))) (if (listp format) - (save-window-excursion - (with-output-to-temp-buffer "*RefTeX Select*" - (princ "SELECT A CITATION FORMAT\n\n") - (princ - (mapconcat - (function (lambda (x) - (format "[%c] %s %s" (car x) - (if (> (car x) 31) " " "") - (cdr x)))) - format "\n"))) - (setq key (read-char)) - (if (assq key format) - (setq format (cdr (assq key format))) - (error "No citation format associated with key `%c'" key))))) + (save-window-excursion + (with-output-to-temp-buffer "*RefTeX Select*" + (princ "SELECT A CITATION FORMAT\n\n") + (princ + (mapconcat + (function (lambda (x) + (format "[%c] %s %s" (car x) + (if (> (car x) 31) " " "") + (cdr x)))) + format "\n"))) + (setq key (read-char)) + (if (assq key format) + (setq format (cdr (assq key format))) + (error "No citation format associated with key `%c'" key))))) (let* (entry cnt rtn ins-string re-list re - ;; scan bibtex files - (lazy-lock-minimum-size 1) - (reftex-found-list (reftex-extract-bib-entries - (reftex-get-bibfile-list))) - (found-list-r nil)) - (if (not reftex-found-list) - (error "Sorry, no matches found")) + ;; scan bibtex files + (reftex-found-list (reftex-extract-bib-entries + (reftex-get-bibfile-list))) + (found-list-r nil)) + (unless reftex-found-list + (error "Sorry, no matches found")) ;; remember where we came from (setq reftex-call-back-to-this-buffer (current-buffer)) ;; offer selection (save-window-excursion - (switch-to-buffer-other-window "*RefTeX Select*") - (erase-buffer) - (reftex-insert-bib-matches reftex-found-list) - (if (= 0 (buffer-size)) - (error "Sorry, no matches found")) - (setq truncate-lines t) - (goto-char 1) - (if (catch 'exit - (while t - (setq rtn - (reftex-select-item - reftex-citation-prompt - "^[^ \t\n]" - 4 - reftex-citation-help - '(?r ?a ?g ?\C-m) - nil - 'reftex-bibtex-selection-callback nil)) - (setq key (car rtn) - cnt (nth 1 rtn)) - (if (not key) (throw 'exit nil)) - (cond - ((eq key ?g) - (setq reftex-found-list - (save-excursion - (set-buffer reftex-call-back-to-this-buffer) - (reftex-extract-bib-entries - (reftex-get-bibfile-list)))) - (erase-buffer) - (reftex-insert-bib-matches reftex-found-list) - (if (= 0 (buffer-size)) - (error "Sorry, no matches found")) - (goto-char 1)) - - ((eq key ?r) - ;; restrict with new regular expression - (setq re-list - (reftex-split "[ \t]*&&[ \t]*" - (read-string - "RegExp [ && RegExp...]: " - nil 'reftex-cite-regexp-hist))) - (while re-list - (setq re (car re-list) - re-list (cdr re-list)) - (setq found-list-r - (delete "" - (mapcar - '(lambda (x) - (if (string-match - re (cdr (assoc "&entry" x))) - x - "")) - reftex-found-list)))) - (if found-list-r - (setq reftex-found-list found-list-r) - (ding)) - (erase-buffer) - (reftex-insert-bib-matches reftex-found-list) - (goto-char 1)) - ((eq key ?a) - (setq entry 'all) - (throw 'exit t)) - ((or (eq key ?\C-m) - (eq key 'return)) - (if cnt - (setq entry (nth cnt reftex-found-list)) - (setq entry nil)) - (throw 'exit t)) - (t - (ding))))) - (progn - ;; format the entry - (if (eq entry 'all) - (setq ins-string - (mapconcat - '(lambda (entry) - (reftex-format-citation entry format)) - reftex-found-list "\n")) - (setq ins-string (reftex-format-citation entry format)))) - (setq ins-string "") - (message "Quit"))) + (switch-to-buffer-other-window "*RefTeX Select*") + (erase-buffer) + (reftex-insert-bib-matches reftex-found-list) + (if (= 0 (buffer-size)) + (error "Sorry, no matches found")) + (setq truncate-lines t) + (goto-char 1) + (if (catch 'exit + (while t + (setq rtn + (reftex-select-item + reftex-citation-prompt + "^[^ \t\n\r]" + 4 + reftex-citation-help + '(?r ?a ?g ?\C-m) + nil + 'reftex-bibtex-selection-callback nil)) + (setq key (car rtn) + cnt (nth 1 rtn)) + (unless key (throw 'exit nil)) + (cond + ((eq key ?g) + (setq reftex-found-list + (save-excursion + (set-buffer reftex-call-back-to-this-buffer) + (reftex-extract-bib-entries + (reftex-get-bibfile-list)))) + (erase-buffer) + (reftex-insert-bib-matches reftex-found-list) + (if (= 0 (buffer-size)) + (error "Sorry, no matches found")) + (goto-char 1)) + + ((eq key ?r) + ;; restrict with new regular expression + (setq re-list + (split-string (read-string + "RegExp [ && RegExp...]: " + nil 'reftex-cite-regexp-hist) + "[ \t]*&&[ \t]*")) + (while re-list + (setq re (car re-list) + re-list (cdr re-list)) + (setq found-list-r + (delete "" + (mapcar + '(lambda (x) + (if (string-match + re (cdr (assoc "&entry" x))) + x + "")) + reftex-found-list)))) + (if found-list-r + (setq reftex-found-list found-list-r) + (ding)) + (erase-buffer) + (reftex-insert-bib-matches reftex-found-list) + (goto-char 1)) + ((eq key ?a) + (setq entry 'all) + (throw 'exit t)) + ((or (eq key ?\C-m) + (eq key 'return)) + (if cnt + (setq entry (nth cnt reftex-found-list)) + (setq entry nil)) + (throw 'exit t)) + (t + (ding))))) + (progn + ;; format the entry + (if (eq entry 'all) + (setq ins-string + (mapconcat + '(lambda (entry) + (reftex-format-citation entry format)) + reftex-found-list "\n")) + (setq ins-string (reftex-format-citation entry format)))) + (setq ins-string "") + (message "Quit"))) (kill-buffer "*RefTeX Select*") - (if (not no-insert) - (progn - (insert ins-string) - (if (string-match "\\?" ins-string) - (progn - (search-backward "?") - (delete-char 1))))) + (unless no-insert + (insert ins-string) + (when (string-match "\\?" ins-string) + (search-backward "?") + (delete-char 1))) (message "") - + ;; Check if the prefix arg was numeric, and call recursively - (if (and (integerp arg) - (> arg 1) - (re-search-backward - "\\\\\\([a-zA-Z]*cite\\|cite[a-zA-Z]*\\)\\**\\(\\[[^]]*\\]\\)*{\\([^}]*\\)" nil t)) ;;; FIXME this can break with ? in format - (progn - (goto-char (match-end 0)) - (setq arg (1- arg)) - (reftex-citation arg)) - (reftex-kill-temporary-buffers)) + (when (and (integerp arg) + (> arg 1) + (re-search-backward + "\\\\\\([a-zA-Z]*cite\\|cite[a-zA-Z]*\\)\\**\\(\\[[^]]*\\]\\)*{\\([^}]*\\)" nil t)) + (goto-char (match-end 0)) + (decf arg) + (reftex-do-citation arg)) + ;; Return the citation key (or (eq entry 'all) - (reftex-get-bib-field "&key" entry))))) - + (reftex-get-bib-field "&key" entry))))) + (defun reftex-insert-bib-matches (list) ;; Insert the bib matches and number them correctly (let ((cnt -1) tmp) (mapcar '(lambda (x) - (setq tmp (cdr (assoc "&formatted" x)) - cnt (1+ cnt)) - (put-text-property 0 (length tmp) 'cnt cnt tmp) - (insert tmp)) - list))) + (setq tmp (cdr (assoc "&formatted" x))) + (incf cnt) + (put-text-property 0 (length tmp) 'cnt cnt tmp) + (insert tmp)) + list))) (defun reftex-format-names (namelist n) (interactive) @@ -3657,7 +4403,7 @@ ((> len n) (concat (car namelist) (nth 2 reftex-cite-punctuation))) (t (setq n (min len n) - last (nth (1- n) namelist)) + last (nth (1- n) namelist)) (setcdr (nthcdr (- n 2) namelist) nil) (concat (mapconcat 'identity namelist (nth 0 reftex-cite-punctuation)) @@ -3667,58 +4413,58 @@ (defun reftex-format-citation (entry format) ;; Format a citation from the info in the BibTeX ENTRY - (if (not (stringp format)) (setq format "\\cite{%l}")) + (unless (stringp format) (setq format "\\cite{%l}")) (if (and reftex-comment-citations - (string-match "%l" reftex-cite-comment-format)) + (string-match "%l" reftex-cite-comment-format)) (error "reftex-cite-comment-format contains illeagal %%l")) - (while (string-match - "\\(\\`\\|[^%]\\)\\(\\(%\\([0-9]*\\)\\([a-zA-Z]\\)\\)[.,;: ]*\\)" - format) + (while (string-match + "\\(\\`\\|[^%]\\)\\(\\(%\\([0-9]*\\)\\([a-zA-Z]\\)\\)[.,;: ]*\\)" + format) (let ((n (string-to-int (match-string 4 format))) - (l (string-to-char (match-string 5 format))) - rpl b e) + (l (string-to-char (match-string 5 format))) + rpl b e) (save-match-data - (setq rpl - (cond - ((= l ?l) (concat - (reftex-get-bib-field "&key" entry) - (if reftex-comment-citations - reftex-cite-comment-format - ""))) - ((= l ?a) (reftex-format-names - (reftex-get-bib-names "author" entry) - (or n 2))) - ((= l ?A) (car (reftex-get-bib-names "author" entry))) - ((= l ?b) (reftex-get-bib-field "booktitle" entry)) - ((= l ?c) (reftex-get-bib-field "chapter" entry)) - ((= l ?d) (reftex-get-bib-field "edition" entry)) - ((= l ?e) (reftex-format-names - (reftex-get-bib-names "editor" entry) - (or n 2))) - ((= l ?E) (car (reftex-get-bib-names "editor" entry))) - ((= l ?h) (reftex-get-bib-field "howpublished" entry)) - ((= l ?i) (reftex-get-bib-field "institution" entry)) - ((= l ?j) (reftex-get-bib-field "journal" entry)) - ((= l ?k) (reftex-get-bib-field "key" entry)) - ((= l ?m) (reftex-get-bib-field "month" entry)) - ((= l ?n) (reftex-get-bib-field "number" entry)) - ((= l ?o) (reftex-get-bib-field "organization" entry)) - ((= l ?p) (reftex-get-bib-field "pages" entry)) - ((= l ?P) (car (reftex-split - "[- .]+" - (reftex-get-bib-field "pages" entry)))) - ((= l ?s) (reftex-get-bib-field "school" entry)) - ((= l ?u) (reftex-get-bib-field "publisher" entry)) - ((= l ?r) (reftex-get-bib-field "address" entry)) - ((= l ?t) (reftex-get-bib-field "title" entry)) - ((= l ?v) (reftex-get-bib-field "volume" entry)) - ((= l ?y) (reftex-get-bib-field "year" entry))))) + (setq rpl + (cond + ((= l ?l) (concat + (reftex-get-bib-field "&key" entry) + (if reftex-comment-citations + reftex-cite-comment-format + ""))) + ((= l ?a) (reftex-format-names + (reftex-get-bib-names "author" entry) + (or n 2))) + ((= l ?A) (car (reftex-get-bib-names "author" entry))) + ((= l ?b) (reftex-get-bib-field "booktitle" entry)) + ((= l ?c) (reftex-get-bib-field "chapter" entry)) + ((= l ?d) (reftex-get-bib-field "edition" entry)) + ((= l ?e) (reftex-format-names + (reftex-get-bib-names "editor" entry) + (or n 2))) + ((= l ?E) (car (reftex-get-bib-names "editor" entry))) + ((= l ?h) (reftex-get-bib-field "howpublished" entry)) + ((= l ?i) (reftex-get-bib-field "institution" entry)) + ((= l ?j) (reftex-get-bib-field "journal" entry)) + ((= l ?k) (reftex-get-bib-field "key" entry)) + ((= l ?m) (reftex-get-bib-field "month" entry)) + ((= l ?n) (reftex-get-bib-field "number" entry)) + ((= l ?o) (reftex-get-bib-field "organization" entry)) + ((= l ?p) (reftex-get-bib-field "pages" entry)) + ((= l ?P) (car (split-string + (reftex-get-bib-field "pages" entry) + "[- .]+"))) + ((= l ?s) (reftex-get-bib-field "school" entry)) + ((= l ?u) (reftex-get-bib-field "publisher" entry)) + ((= l ?r) (reftex-get-bib-field "address" entry)) + ((= l ?t) (reftex-get-bib-field "title" entry)) + ((= l ?v) (reftex-get-bib-field "volume" entry)) + ((= l ?y) (reftex-get-bib-field "year" entry))))) (if (string= rpl "") - (setq b (match-beginning 2) e (match-end 2)) - (setq b (match-beginning 3) e (match-end 3))) + (setq b (match-beginning 2) e (match-end 2)) + (setq b (match-beginning 3) e (match-end 3))) (setq format (concat (substring format 0 b) rpl (substring format e))))) (while (string-match "%%" format) (setq format (replace-match "%" t t format))) @@ -3726,7 +4472,7 @@ (setq format (replace-match "" t t format))) format) -;; this is slow and not recommended for follow mode +;; This is slow and not recommended for follow mode (defun reftex-bibtex-selection-callback (cnt) ;; Callback function to be called from the BibTeX selection, in ;; order to display context. This function is relatively slow and not @@ -3766,50 +4512,47 @@ ;; function which is called with the index of the element. (let* (key key-sq b e ev cnt last-cnt cmd skip-callback - (search-str "") tmp search-start matched forward mini-map last-key - (offset1 (or offset 1))) + (search-str "") tmp search-start matched forward mini-map last-key + (offset1 (or offset 1)) win1 win2) ;; Set up a minibuffer keymap for the search stuff (setq mini-map (copy-keymap minibuffer-local-map)) - (define-key mini-map "\C-s" + (define-key mini-map "\C-s" '(lambda () (interactive) (setq forward t) (exit-minibuffer))) - (define-key mini-map "\C-r" + (define-key mini-map "\C-r" '(lambda () (interactive) (setq forward nil) (exit-minibuffer))) (define-key mini-map "\C-m" 'exit-minibuffer) (setq ev (catch 'exit (save-window-excursion - (if (= 0 (buffer-size)) - (throw 'exit nil)) (setq truncate-lines t) (goto-char 1) - (if (not (re-search-forward next-re nil t offset1)) - (progn ; in case the offset is illegal - (setq offset1 1) - (if (not (re-search-forward next-re nil t offset1)) - (throw 'exit nil)))) + (unless (re-search-forward next-re nil t offset1) + ;; in case the offset is illegal + (setq offset1 1) + (re-search-forward next-re nil t offset1)) (beginning-of-line 1) (while t - (setq last-cnt (or cnt last-cnt)) - (setq cnt (get-text-property (point) 'cnt)) + (setq last-cnt (or cnt last-cnt)) + (setq cnt (get-text-property (point) 'cnt)) (if (and cnt cb-flag call-back (not skip-callback)) (funcall call-back cnt)) - (setq skip-callback nil) - (if cnt - (setq b (or (previous-single-property-change - (1+ (point)) 'cnt) - (point-min)) - e (or (next-single-property-change - (point) 'cnt) - (point-max))) - (setq b (point) e (point))) - (reftex-highlight 1 b e) + (setq skip-callback nil) + (if cnt + (setq b (or (previous-single-property-change + (1+ (point)) 'cnt) + (point-min)) + e (or (next-single-property-change + (point) 'cnt) + (point-max))) + (setq b (point) e (point))) + (reftex-highlight 1 b e) (if (or (not (pos-visible-in-window-p b)) (not (pos-visible-in-window-p e))) (recenter (/ (window-height) 2))) (setq key-sq (read-key-sequence prompt)) - (setq last-key key) + (setq last-key key) (setq key (car (cond ((fboundp 'listify-key-sequence) ; Emacs @@ -3820,23 +4563,23 @@ (setq cmd (key-binding key-sq)) - (reftex-unhighlight 2) + (reftex-unhighlight 2) (reftex-unhighlight 0) (cond - ;; Single line motions + ;; Single line motions ((or (eq key ?n) (eq key ?\C-i) (eq cmd 'next-line)) - (forward-char 1) + (or (eobp) (forward-char 1)) (re-search-forward next-re nil t 1) (beginning-of-line 1)) ((or (eq key ?p) (eq cmd 'previous-line)) (re-search-backward next-re nil t)) - ;; Page motions + ;; Page motions ((eq cmd 'scroll-up) (while (and (pos-visible-in-window-p) (re-search-forward next-re nil t))) @@ -3847,23 +4590,23 @@ (re-search-backward next-re nil t))) (recenter (- (window-height) size 2))) - ;; Begin and end of buffer - ((eq cmd 'beginning-of-buffer) - (goto-char (point-min)) - (re-search-forward next-re nil t) - (beginning-of-line 1)) - ((eq cmd 'end-of-buffer) - (goto-char (point-max)) - (re-search-backward next-re nil t)) - - ;; Exit + ;; Begin and end of buffer + ((eq cmd 'beginning-of-buffer) + (goto-char (point-min)) + (re-search-forward next-re nil t) + (beginning-of-line 1)) + ((eq cmd 'end-of-buffer) + (goto-char (point-max)) + (re-search-backward next-re nil t)) + + ;; Exit ((eq key ?q) (throw 'exit nil)) ((eq key ?\C-g) - (if (or (eq last-key ?\C-s) (eq last-key ?\C-r)) - (ding) - (bury-buffer) - (error "Abort"))) + (if (or (eq last-key ?\C-s) (eq last-key ?\C-r)) + (ding) + (bury-buffer) + (error "Abort"))) ((or (eq key ?\C-m) (eq key 'return) (eq cmd 'newline)) @@ -3871,54 +4614,62 @@ ((memq key event-list) (throw 'exit key)) - ;; Callback + ;; Callback ((or (eq key ?C) ; backward compatibility (eq key ?f)) (setq cb-flag (not cb-flag))) ((eq key ?\ ) - (if cnt (funcall call-back cnt) (ding))) - - ;; Help + (if cnt (funcall call-back cnt) (ding))) + + ;; Help ((eq key ?\?) - (with-output-to-temp-buffer "*RefTeX Help*" - (princ help-string)) - (setq skip-callback t)) - - ;; Searching - ((or (setq forward (eq key ?\C-s)) (eq key ?\C-r)) - (if (or (and (not (eq last-key ?\C-s)) - (not (eq last-key ?\C-r))) - (string= search-str "")) - (setq tmp ; get a new string - (read-from-minibuffer - (if (string= search-str "") - "Search: " - (format "Search [%s]:" search-str)) - nil mini-map) - search-str (if (string= tmp "") - search-str tmp))) - (setq search-start (point)) - (and (not (string= search-str "")) - (progn - (while - (and (setq matched - (if forward - (search-forward search-str nil 1) - (search-backward search-str nil 1))) - (or (>= (save-excursion - (goto-char (match-beginning 0)) - (current-column)) - (window-width)) - (not (or (get-text-property (point) 'cnt) - match-everywhere))))) - (if matched - (reftex-highlight 2 (match-beginning 0) - (match-end 0)) - (ding) - (goto-char search-start))))) - - ;; Recursive edit - ((eq key ?\M-r) + (with-output-to-temp-buffer "*RefTeX Help*" + (princ help-string)) + (setq win1 (selected-window) + win2 (get-buffer-window "*RefTeX Help*" t)) + (select-window win2) + (unless (and (pos-visible-in-window-p 1) + (pos-visible-in-window-p (point-max))) + (enlarge-window (1+ (- (count-lines 1 (point-max)) + (window-height))))) + (select-window win1) + (setq skip-callback t)) + + ;; Searching + ((or (setq forward (eq key ?\C-s)) (eq key ?\C-r)) + (if (or (and (not (eq last-key ?\C-s)) + (not (eq last-key ?\C-r))) + (string= search-str "")) + (setq tmp ; get a new string + (read-from-minibuffer + (if (string= search-str "") + "Search: " + (format "Search [%s]:" search-str)) + nil mini-map) + search-str (if (string= tmp "") + search-str tmp))) + (setq search-start (point)) + (and (not (string= search-str "")) + (progn + (while + (and (setq matched + (if forward + (search-forward search-str nil 1) + (search-backward search-str nil 1))) + (or (>= (save-excursion + (goto-char (match-beginning 0)) + (current-column)) + (window-width)) + (not (or (get-text-property (point) 'cnt) + match-everywhere))))) + (if matched + (reftex-highlight 2 (match-beginning 0) + (match-end 0)) + (ding) + (goto-char search-start))))) + + ;; Recursive edit + ((eq key ?e) (set-marker reftex-recursive-edit-marker (point)) (unwind-protect (progn @@ -3929,11 +4680,10 @@ (substitute-command-keys "Recursive edit. Return to selection with \\[exit-recursive-edit]")) (recursive-edit))) - (if (not (equal (marker-buffer - reftex-recursive-edit-marker) - (current-buffer))) - (error - "Cannot continue RefTeX from this buffer.")) + (unless (equal (marker-buffer + reftex-recursive-edit-marker) + (current-buffer)) + (error "Cannot continue RefTeX from this buffer.")) (goto-char reftex-recursive-edit-marker)) (set-marker reftex-recursive-edit-marker nil))) @@ -3963,59 +4713,80 @@ ;; See where we are. (let* ((re "\\\\\\([a-z]*\\(cite\\|ref\\)\\|\\(cite\\|ref\\)[a-z]*\\)\\**\\(\\[[^{}]*\\]\\)?{") - (macro (car (car (reftex-what-macro t)))) - (this-word (reftex-this-word "*a-zA-Z\\\\")) - (my-window (get-buffer-window (current-buffer))) - pop-window cmd args label point) - - (if (and macro - (string-match "\\`\\\\cite\\|\\`\\\\ref\\|cite\\'\\|ref\\'" - macro)) - (and (setq macro (match-string 0 macro)) - (string-match "\\`\\\\" macro) - (setq macro (substring macro 1))) + (macro (car (car (reftex-what-macro t)))) + (this-word (reftex-this-word "*a-zA-Z\\\\")) + (my-window (selected-window)) + pop-window cmd args point) + + (if (and macro + (string-match "\\`\\\\cite\\|\\`\\\\ref\\|cite\\'\\|ref\\'" + macro)) + (and (setq macro (match-string 0 macro)) + (string-match "\\`\\\\" macro) + (setq macro (substring macro 1))) (setq macro nil)) - + (if (and macro (eq last-command this-command)) - (if (string= macro "cite") - (progn - (skip-chars-forward "^},%") - (while (and (eq (following-char) ?%) - (or (beginning-of-line 2) t) - (skip-chars-forward " \t\n"))) - (skip-chars-forward ",") - (if (eq (following-char) ?}) - (setq macro nil))) - (setq macro nil))) - - (if (and (not macro) - (eq this-command 'reftex-view-crossref) - (or (not (string-match "\\`\\\\" this-word)) - (search-backward "\\" nil t) - t) - (re-search-forward re nil t)) - (setq macro (or (match-string 2) (match-string 3)))) - - (if (not macro) - (error "No cross reference to display")) + (if (string= macro "cite") + (progn + (skip-chars-forward "^},%") + (while (and (eq (following-char) ?%) + (or (beginning-of-line 2) t) + (skip-chars-forward " \t\n\r"))) + (skip-chars-forward ",") + (if (eq (following-char) ?}) + (setq macro nil))) + (setq macro nil))) + + (if (and (not macro) + (or (not (string-match "\\`\\\\" this-word)) + (eq (following-char) ?\\) + (search-backward "\\" nil t) + t)) + (if (interactive-p) + ;; Only move far if this function was called directly + (and (re-search-forward re nil t) + (setq macro (or (match-string 2) (match-string 3)))) + ;; The macro needs to be at point + (and (looking-at re) + (setq macro (or (match-string 2) (match-string 3))) + (goto-char (match-end 0))))) + + + (unless macro + (error "No cross reference to display")) ;; Ensure access to scanning info (reftex-access-scan-info) - (cond + (cond ((string= macro "cite") (setq cmd 'reftex-pop-to-bibtex-entry - args (list - (reftex-no-props (reftex-this-word "^{},%\n")) - (reftex-get-bibfile-list) nil t))) + args (list + (reftex-this-word "^{},%\n\r") + (reftex-get-bibfile-list) nil t))) ((string= macro "ref") - (let* ((label (reftex-no-props (reftex-this-word "^{}%\n"))) - (entry (assoc label (symbol-value reftex-list-of-labels-symbol)))) + (let* ((label (reftex-this-word "^{}%\n\r")) + (xr-data (assoc 'xr (symbol-value reftex-docstruct-symbol))) + (xr-re (nth 2 xr-data)) + (entry (assoc label (symbol-value reftex-docstruct-symbol)))) + (if (and (not entry) (string-match xr-re label)) + ;; Label is defined in external document + (save-excursion + (save-match-data + (set-buffer + (or (reftex-get-file-buffer-force + (cdr (assoc (match-string 1 label) (nth 1 xr-data)))) + (error "Problem with external label %s" label)))) + (setq label (substring label (match-end 1))) + (reftex-access-scan-info) + (setq entry + (assoc label (symbol-value reftex-docstruct-symbol))))) (if entry (setq cmd 'reftex-pop-to-label - args (list label (list (nth 3 entry)) nil t)) - (error "Label %s not known - reparse document might help" label)))) - (t (error "This should not happen"))) + args (list label (list (nth 3 entry)) nil t)) + (error "Label %s not known - reparse document might help" label)))) + (t (error "This should not happen (reftex-view-crossref)"))) (setq point (point)) (apply cmd args) (setq pop-window (selected-window)) @@ -4061,7 +4832,7 @@ (let ((bound (or bound (save-excursion (re-search-backward reftex-section-regexp nil 1) (point)))) - pos cmd-list cmd) + pos cmd-list cmd cnt cnt-opt entry) (save-restriction (save-excursion (narrow-to-region (max 1 bound) (point-max)) @@ -4069,22 +4840,32 @@ (while (condition-case nil (progn (up-list -1) t) (error nil)) + (setq cnt 1 cnt-opt 0) ;; move back over any touching sexps - (while (or (= (preceding-char) ?\]) - (= (preceding-char) ?\})) - (backward-sexp)) + (while (and (reftex-move-to-previous-arg bound) + (condition-case nil + (progn (backward-sexp) t) + (error nil))) + (if (eq (following-char) ?\[) (incf cnt-opt)) + (incf cnt)) (setq pos (point)) - (if (and (or (= (following-char) ?\[) - (= (following-char) ?\{)) - (and (re-search-backward "\\(\\\\[*a-zA-Z]+\\)" nil t) - (= (match-end 0) pos))) - (progn - (setq cmd (buffer-substring-no-properties - (match-beginning 0) (match-end 0))) - (if (eq t which) - (setq cmd-list (cons (cons cmd (point)) cmd-list)) - (if (member cmd which) - (throw 'exit (cons cmd (point))))))) + (when (and (or (= (following-char) ?\[) + (= (following-char) ?\{)) + (re-search-backward "\\\\[*a-zA-Z]+\\=" nil t)) + (setq cmd (reftex-match-string 0)) + (when (looking-at "\\\\begin{[^}]*}") + (setq cmd (reftex-match-string 0) + cnt (1- cnt))) + ;; This does ignore optional arguments. Very hard to fix. + (when (setq entry (assoc cmd reftex-env-or-mac-alist)) + (if (> cnt (or (nth 4 entry) 100)) + (setq cmd nil))) + (cond + ((null cmd)) + ((eq t which) + (push (cons cmd (point)) cmd-list)) + ((member cmd which) + (throw 'exit (cons cmd (point)))))) (goto-char pos))) (nreverse cmd-list))))) @@ -4119,7 +4900,7 @@ ((member env end-list) (setq end-list (delete env end-list))) ((eq t which) - (setq env-list (cons (cons env (point)) env-list))) + (push (cons env (point)) env-list)) ((member env which) (throw 'exit (cons env (point)))))) (nreverse env-list))))) @@ -4130,7 +4911,7 @@ (let ((pos (point))) (save-excursion (re-search-backward "[^ \t\n\r]" (point-min) 1) - (setq pos (1+ (point))) + (setq pos (min (1+ (point)) (point-max))) (if (re-search-backward "[^a-zA-Z0-9\\\.:]" (point-min) 1) (forward-char 1)) (buffer-substring-no-properties (point) pos)))) @@ -4145,22 +4926,168 @@ (set-text-properties 0 (length string) nil string)) string) -(defun reftex-split (regexp string) - ;; Split like perl - (let ((start 0) list) - (while (string-match regexp string start) - (setq list (cons (substring string start (match-beginning 0)) list)) - (setq start (match-end 0))) - (setq list (nreverse (cons (substring string start) list))))) - -(defun reftex-allow-for-ctrl-m (string) - ;; convert STRING into a regexp, allowing ^M for \n +(defun reftex-match-string (n) + ;; Match string without properties + (when (match-beginning n) + (buffer-substring-no-properties (match-beginning n) (match-end n)))) + +(defun reftex-this-word (&optional class) + ;; Grab the word around point. + (setq class (or class "-a-zA-Z0-9:_/.*;|")) + (save-excursion + (buffer-substring-no-properties + (progn (skip-chars-backward class) (point)) + (progn (skip-chars-forward class) (point))))) + +(defun reftex-truncate (string ncols &optional ellipses padding) + ;; Truncate a string to NCHAR characters. + ;; Works fast with ASCII and correctly with Mule characters. + ;; When ELLIPSES is non-nil, put three dots at the end of the string. + (setq string + (cond + ((and (boundp 'enable-multibyte-characters) + enable-multibyte-characters) + (if (<= (string-width string) ncols) + string + (if ellipses + (concat (truncate-string-to-width string (- ncols 3)) "...") + (truncate-string-to-width string ncols)))) + (t + (if (<= (length string) ncols) + string + (if ellipses + (concat (substring string 0 (- ncols 3)) "...") + (substring string 0 ncols)))))) + (if padding + (format (format "%%-%ds" ncols) string) + string)) + +(defun reftex-nearest-match (regexp &optional pos) + ;; Find the nearest match of REGEXP. Set the match data. + ;; If POS is given, calculate distances relative to it. + ;; Return nil if there is no match. + (let ((start (point)) (pos (or pos (point))) match1 match2 match) + (goto-char start) + (when (re-search-backward regexp nil t) + (setq match1 (match-data))) + (goto-char start) + (when (re-search-forward regexp nil t) + (setq match2 (match-data))) + (goto-char start) + (setq match + (cond + ((not match1) match2) + ((not match2) match1) + ((< (abs (- pos (car match1))) (abs (- pos (car match2)))) match1) + (t match2))) + (if match (progn (store-match-data match) t) nil))) + +(defun reftex-auto-mode-alist () + ;; Return an `auto-mode-alist' with only the .gz (etc) thingies. + ;; Stolen from gnus nnheader. + (let ((alist auto-mode-alist) + out) + (while alist + (when (listp (cdr (car alist))) + (push (car alist) out)) + (pop alist)) + (nreverse out))) + +(defun reftex-access-search-path (which &optional recurse file) + ;; Access path from environment variables. WHICH is either "tex" or "bib". + ;; When RECURSE is t, expand recursive paths, ending in double slash + ;; FILE is just for the message. + (let* ((pathvar (intern (concat "reftex-" which "-path"))) + (status (get pathvar 'status))) + (cond + ((eq status 'recursed)) + ((and status (null recurse))) + ((null status) + (let ((env-vars (if (equal which "tex") (list "TEXINPUTS") + reftex-bibpath-environment-variables))) + (set pathvar (reftex-parse-colon-path + (mapconcat '(lambda(x) (or (getenv x) "")) + env-vars path-separator)))) + (put pathvar 'status 'split)) + ((and (eq 'split status) recurse) + (message "Expanding search path to find %s file: %s ..." which file) + (set pathvar (reftex-expand-path (symbol-value pathvar))) + (put pathvar 'status 'recursed))))) + +(defun reftex-find-file-on-path (file path) + ;; Find FILE along the directory list PATH. + (catch 'exit + (when (file-name-absolute-p file) + (if (file-exists-p file) + (throw 'exit file) + (throw 'exit nil))) + (let* ((thepath path) file1 dir + (doubleslash (concat "/" "/"))) + (while (setq dir (pop thepath)) + (when (string= (substring dir -2) doubleslash) + (setq dir (substring dir 0 -1))) + (setq file1 (expand-file-name file dir)) + (if (file-exists-p file1) + (throw 'exit file1))) + ;; No such file + nil))) + +(defun reftex-parse-colon-path (path) + ;; Like parse-colon-parse, but // or /~ have no effects. + (mapcar 'file-name-as-directory + (delete "" (split-string path (concat path-separator "+"))))) + +(defun reftex-expand-path (path) + ;; Expand parts of path ending in a double slash + (let (path1 dir dirs (doubleslash (concat "/" "/"))) + (while (setq dir (pop path)) + (if (string= (substring dir -2) doubleslash) + (progn + (setq dir (substring dir 0 -1)) + (setq dirs (reftex-recursive-directory-list dir)) + (setq path1 (append dirs path1))) + (push dir path1))) + (nreverse path1))) + +(defun reftex-recursive-directory-list (dir) + (let ((path (list dir)) dirs path1) + (while (setq dir (pop path)) + (setq dirs + (delete nil + (mapcar (function + (lambda (x) + (if (and (file-directory-p x) + (not (string-match "/\\.+\\'" x))) + (file-name-as-directory x) + nil))) + (directory-files dir t)))) + (setq path (append dirs path)) + (push dir path1)) + path1)) + +(defun reftex-make-regexp-allow-for-ctrl-m (string) + ;; convert STRING into a regexp, allowing ^M for \n and vice versa (let ((start -2)) (setq string (regexp-quote string)) (while (setq start (string-match "[\n\r]" string (+ 3 start))) (setq string (replace-match "[\n\r]" nil t string))) string)) +(defun reftex-make-desparate-section-regexp (old) + ;; Return a regexp which will still match a section statement even if + ;; x-symbol or isotex or the like have been at work in the mean time. + (let* ((n (1+ (string-match "[[{]" old))) + (new (regexp-quote (substring old 0 (1+ (string-match "[[{]" old))))) + (old (substring old n))) + (while (string-match + "\\([\r\n]\\)\\|\\(\\`\\|[ \t\n\r]\\)\\([a-zA-Z0-9]+\\)\\([ \t\n\r]\\|}\\'\\)" + old) + (if (match-beginning 1) + (setq new (concat new "[^\n\r]*[\n\r]")) + (setq new (concat new "[^\n\r]*" (match-string 3 old)))) + (setq old (substring old (match-end 0)))) + new)) + (defun reftex-delete-list (elt-list list) ;; like delete, but with a list of things to delete ;; (original code from Rory Molinari) @@ -4181,26 +5108,59 @@ (defun reftex-get-file-buffer-force (file &optional mark-to-kill) ;; Return a buffer visiting file. Make one, if necessary. - ;; If neither such a buffer no the file exist, return nil. - ;; If MARK-TO-KILL in non-nil, put any new buffers into the kill list." + ;; If neither such a buffer nor the file exist, return nil. + ;; If MARK-TO-KILL is t and there is no live buffer, load the file with + ;; initializations according to `reftex-initialize-temporary-buffers', + ;; and mark the buffer to be killed after use. (let ((buf (reftex-get-buffer-visiting file))) - (cond - (buf buf) - ((file-exists-p file) - (setq buf (find-file-noselect file)) - (if mark-to-kill - (add-to-list 'reftex-buffers-to-kill buf)) - buf) - (t nil)))) + + (cond (buf + ;; We have it already as a buffer - just return it + buf) + + ((file-readable-p file) + ;; At least there is such a file and we can read it. + + (if (or (not mark-to-kill) + (eq t reftex-initialize-temporary-buffers)) + + ;; Visit the file with full magic + (setq buf (find-file-noselect file)) + + ;; Else: Visit the file just briefly, without or + ;; with limited Magic + + ;; The magic goes away + (let ((format-alist nil) + (auto-mode-alist (reftex-auto-mode-alist)) + (default-major-mode 'fundamental-mode) + (after-insert-file-functions nil)) + (setq buf (find-file-noselect file))) + + ;; Is there a hook to run? + (when (listp reftex-initialize-temporary-buffers) + (save-excursion + (set-buffer buf) + (run-hooks 'reftex-initialize-temporary-buffers)))) + + ;; Lets see if we got a license to kill :-| + (and mark-to-kill + (add-to-list 'reftex-buffers-to-kill buf)) + + ;; Return the new buffer + buf) + + ;; If no such file exists, return nil + (t nil)))) (defun reftex-splice-symbols-into-list (list alist) ;; Splice the association in ALIST of any symbols in LIST into the list. ;; Return new list. (let (rtn tmp) (while list - (while (and (not (null (car list))) - (symbolp (car list))) + (while (and (not (null (car list))) ;; keep list elements nil + (symbolp (car list))) (setq tmp (car list)) (cond ((assoc tmp alist) @@ -4208,8 +5168,7 @@ (t (error "Cannot treat symbol %s in reftex-label-alist" (symbol-name tmp))))) - (setq rtn (cons (car list) rtn) - list (cdr list))) + (push (pop list) rtn)) (nreverse rtn))) (defun reftex-uniquify (alist &optional keep-list) @@ -4217,26 +5176,31 @@ ;; Elements of KEEP-LIST are not removed even if duplicate. (let (new elm) (while alist - (setq elm (car alist) - alist (cdr alist)) + (setq elm (pop alist)) (if (or (member (car elm) keep-list) - (not (assoc (car elm) new))) - (setq new (cons elm new)))) - (setq new (nreverse new)) - new)) + (not (assoc (car elm) new))) + (push elm new))) + (nreverse new))) (defun reftex-use-fonts () ;; Return t if we can and want to use fonts. (and window-system reftex-use-fonts - (boundp 'font-lock-keyword-face))) + (featurep 'font-lock))) + +(defun reftex-refontify () + ;; Return t if we need to refontify context + (and (reftex-use-fonts) + (or (eq t reftex-refontify-context) + (and (eq 1 reftex-refontify-context) + (or (featurep 'x-symbol)))))) ;; Highlighting uses overlays. If this is for XEmacs, we need to load ;; the overlay library, available in version 19.15 (and (not (fboundp 'make-overlay)) (condition-case nil (require 'overlay) - (error + (error (error "RefTeX needs overlay emulation (available in XEmacs 19.15)")))) ;; We keep a vector with several different overlays to do our highlighting. @@ -4248,8 +5212,8 @@ (aset reftex-highlight-overlays 1 (make-overlay 1 1)) (overlay-put (aref reftex-highlight-overlays 1) 'face 'highlight) (aset reftex-highlight-overlays 2 (make-overlay 1 1)) -(overlay-put (aref reftex-highlight-overlays 2) 'face - (if (string-match "XEmacs" emacs-version) 'zmacs-region 'region)) +(overlay-put (aref reftex-highlight-overlays 2) 'face + (if (string-match "XEmacs" emacs-version) 'zmacs-region 'region)) ;; Two functions for activating and deactivation highlight overlays (defun reftex-highlight (index begin end &optional buffer) @@ -4267,173 +5231,40 @@ ;;; --------------------------------------------------------------------------- ;;; -;;; Cursor position after insertion of forms - -(defun reftex-position-cursor () - ;; Search back to question mark, delete it, leave point there - (if (search-backward "\?" (- (point) 100) t) - (delete-char 1))) - -(defun reftex-item () - "Insert an \\item and provide a label if the environments supports that." - (interactive) - (let ((env (car - (reftex-what-environment '("itemize" "enumerate" "eqnarray"))))) - - (if (and env (not (bolp))) (newline)) - - (cond - - ((string= env "eqnarray") - (if (not (bolp)) - (newline)) - (reftex-label env) - (insert "\n & & ") - (beginning-of-line 1)) - - ((string= env "itemize") - (newline) - (insert "\\item ")) - - ((string= env "enumerate") - (newline) - (insert "\\item") - (reftex-label env) - (insert " ")) - (t - (error "\\item command does not make sense here..."))))) - -;;; --------------------------------------------------------------------------- -;;; --------------------------------------------------------------------------- -;;; --------------------------------------------------------------------------- -;;; -;;; Data Section: Definition of large constants - -(defconst reftex-label-alist-builtin - '( - ;; Some aliases, mostly for backward compatibility - (Sideways "Alias for -->rotating" (rotating)) - (AMSTeX "Alias for -->amsmath" (amsmath)) - - ;; Here come the individual packages of the LaTeX distribution - (amsmath "AMS math environments" - (("align" ?e "eq:" "~\\eqref{%s}" "\\\\begin{align}\\|\\\\\\\\") - ("gather" ?e "eq:" nil "\\\\begin{gather}\\|\\\\\\\\") - ("multline" ?e "eq:" nil t) - ("flalign" ?e "eq:" nil "\\\\begin{flalign}\\|\\\\\\\\") - ("alignat" ?e "eq:" nil "\\\\begin{alignat}{[0-9]*}\\|\\\\\\\\") - ("xalignat" ?e "eq:" nil "\\\\begin{xalignat}{[0-9]*}\\|\\\\\\\\") - ("xxalignat" ?e "eq:" nil "\\\\begin{xxalignat}{[0-9]*}\\|\\\\\\\\"))) - - (longtable "The longtable environment" - (("longtable" ?t nil nil "\\\\caption\\(\\[[^]]*\\]\\)?{"))) - - (rotating "Sidewaysfigure and table" - (("sidewaysfigure" ?f nil nil "\\\\caption\\(\\[[^]]*\\]\\)?{") - ("sidewaystable" ?t nil nil "\\\\caption\\(\\[[^]]*\\]\\)?{"))) - - (subfigure "Subfigure environments/macro" - (("subfigure" ?f nil nil "\\\\caption\\(\\[[^]]*\\]\\)?{") - ("subfigure*" ?f nil nil "\\\\caption\\(\\[[^]]*\\]\\)?{") - ("\\subfigure" ?f nil nil "\\\\subfigure[[{]"))) - - (LaTeX "LaTeX default environments" - (("section" ?s "sec:" "~\\ref{%s}" (nil . t) - ("Part" "Chapter" "Chap." "Section" "Sec." "Sect." "Paragraph" "Par." - "\\S" "Teil" "Kapitel" "Kap." "Abschnitt" )) - - ("enumerate" ?n "item:" "~\\ref{%s}" "\\\\item\\(\\[[^]]*\\]\\)?" - ("Item" "Punkt")) - - ("equation" ?e "eq:" "~(\\ref{%s})" t - ("Equation" "Eq." "Eqn." "Gleichung" "Gl.")) - ("eqnarray" ?e "eq:" nil "\\\\begin{eqnarray}\\|\\\\\\\\") - - ("figure" ?f "fig:" "~\\ref{%s}" "\\\\caption\\(\\[[^]]*\\]\\)?{" - ("Figure" "Fig." "Abbildung" "Abb.")) - ("figure*" ?f nil nil "\\\\caption\\(\\[[^]]*\\]\\)?{") - - ("table" ?t "tab:" "~\\ref{%s}" "\\\\caption\\(\\[[^]]*\\]\\)?{" - ("Table" "Tab." "Tabelle")) - ("table*" ?t nil nil "\\\\caption\\(\\[[^]]*\\]\\)?{") - - ("any" ?\ " " "\\ref{%s}" nil))) - - ) - "The default label environment descriptions. -Lower-case symbols correspond to a style file of the same name in the LaTeX -distribution. Mixed-case symbols are convenience aliases.") - -(defconst reftex-cite-format-builtin - '( - (default "Default macro \\cite{%l}" - "\\cite{%l}") - (harvard "P. William's and T. Schnier's Harvard package" - ((?\C-m . "\\cite{%l}") - (?p . "\\cite{%l}") - (?t . "\\citeasnoun{%l}") - (?n . "\\citeasnoun{%l}") - (?s . "\\possessivecite{%l}") - (?e . "\\citeaffixed{%l}{?}") - (?y . "\\citeyear{%l}") - (?a . "\\citename{%l}"))) - (natbib "Patrick W. Daly's Natbib package" - ((?\C-m . "\\cite{%l}") - (?t . "\\citet{%l}") - (?T . "\\citet*{%l}") - (?p . "\\citep{%l}") - (?P . "\\citep*{%l}") - (?e . "\\citep[e.g.][]{%l}") - (?a . "\\citeauthor{%l}") - (?y . "\\citeyear{%l}"))) - (astron "S. Hogeveen's Astron package" - ((?\C-m . "\\cite{%l}") - (?p . "\\cite{%l}" ) - (?t . "%2a (\\cite{%l})"))) - (author-year "Do-it-yourself Author year citation" - ((?\C-m . "\\cite{%l}") - (?t . "%2a (%y)\\nocite{%l}") - (?p . "(%2a %y\\nocite{%l})"))) - (locally "Put full info in parenthesis" - "(%2a %y, %j %v, %P, %e: %b, %u, %s %<)") - ;; undocumented feature: `%<' kills white space and punctuation locally. - ) - "Builtin versions of for the citation format. -The following conventions are valid for all alist entries: -`?\C-m' should always point to a straight \\cite{%l} macro. -`?t' should point to a textual citation (citation as a noun). -`?p' should point to a parenthetical citation.") - -;;; --------------------------------------------------------------------------- -;;; ;;; Functions to compile the tables, reset the mode etc. (defun reftex-reset-mode () "Reset RefTeX Mode. Required to implement changes to some list variables. This function will compile the information in `reftex-label-alist' and similar variables. It is called when RefTeX is first used, and after changes to -these variables via `reftex-add-to-label-alist'." +these variables." (interactive) ;; Record that we have done this (setq reftex-tables-dirty nil) + (setq reftex-memory + (list reftex-label-alist reftex-label-alist-external-add-ons + reftex-default-label-alist-entries)) + + ;; Reset the file search path variables + (put 'reftex-tex-path 'status nil) + (put 'reftex-bib-path 'status nil) ;; Kill temporary buffers associated with RefTeX - just in case they ;; were not cleaned up properly (let ((buffer-list '("*RefTeX Master*" "*RefTeX Help*" "*RefTeX Select*" - "*Duplicate Labels*" "*toc*" "*RefTeX-scratch*"))) - (while buffer-list - (if (get-buffer (car buffer-list)) - (kill-buffer (car buffer-list))) - (setq buffer-list (cdr buffer-list)))) - + "*Duplicate Labels*" "*toc*" "*RefTeX-scratch*")) + buf) + (while (setq buf (pop buffer-list)) + (if (get-buffer buf) + (kill-buffer buf)))) + + ;; Make sure the current document will be rescanned soon. (reftex-reset-scanning-information) - ;; Plug functions into AUCTeX if the user option says so + ;; Plug functions into AUCTeX if the user option says so. (reftex-plug-into-AUCTeX) - ;; To update buffer-local variables - (hack-local-variables) (message "updating internal tables...") (reftex-compute-ref-cite-tables) (message "updating internal tables... done")) @@ -4452,6 +5283,18 @@ (not (null (symbol-value symbol)))) (set (symbol-value symbol) nil))))) +(defcustom reftex-default-context-regexps + '((caption . "\\\\\\(rot\\)?caption\\*?\\(\\[[^]]*\\]\\)?{") + (item . "\\\\item\\(\\[[^]]*\\]\\)?") + (eqnarray-like . "\\\\begin{%s}\\|\\\\\\\\") + (alignat-like . "\\\\begin{%s}{[0-9]*}\\|\\\\\\\\")) +"Alist with default regular expressions for finding context. +The form (format regexp (regexp-quote environment)) is used to calculate +the final regular expression - so %s will be replaced with the environment +or macro." + :group 'reftex-defining-label-environments + :type '(repeat (cons (symbol) (regexp)))) + (defun reftex-compute-ref-cite-tables () ;; Update ref and cite tables @@ -4459,14 +5302,15 @@ ;; Compile information in reftex-label-alist (let ((tmp (reftex-uniquify (reftex-splice-symbols-into-list - (append - reftex-label-alist - reftex-label-alist-external-add-ons - reftex-default-label-alist-entries) - reftex-label-alist-builtin) - '(nil))) - entry env-or-mac typekeychar typekey prefix context - fmt reffmt labelfmt wordlist qh-list) + (append + reftex-label-alist + reftex-label-alist-external-add-ons + reftex-default-label-alist-entries) + reftex-label-alist-builtin) + '(nil))) + entry env-or-mac typekeychar typekey prefix context word + fmt reffmt labelfmt wordlist qh-list macros-with-labels + nargs nlabel opt-args cell sum) (setq reftex-words-to-typekey-alist nil reftex-typekey-list nil @@ -4477,78 +5321,86 @@ reftex-label-mac-list nil) (while tmp (catch 'next-entry - (setq entry (car tmp) - env-or-mac (car entry) - entry (cdr entry) - tmp (cdr tmp)) - (if (null env-or-mac) - (setq env-or-mac "")) - (if (stringp (car entry)) - ;; This is before version 2.00 - convert entry to new format - ;; This is just to keep old users happy - (setq entry (cons (string-to-char (car entry)) - (cons (concat (car entry) ":") - (cdr entry))))) - (setq typekeychar (nth 0 entry) - typekey (char-to-string typekeychar) - prefix (nth 1 entry) - fmt (nth 2 entry) - context (nth 3 entry) - wordlist (nth 4 entry)) - (if (stringp wordlist) - ;; This is before version 2.04 - convert to new format - (setq wordlist (nthcdr 4 entry))) - - (if (and (stringp fmt) - (string-match "@" fmt)) - ;; special syntax for specifying a label format - (setq fmt (reftex-split "@+" fmt)) - (setq fmt (list "\\label{%s}" fmt))) - (setq labelfmt (car fmt) - reffmt (nth 1 fmt)) - (if typekey - (add-to-list 'reftex-typekey-list typekey)) - (if (and typekey prefix - (not (assoc typekey reftex-typekey-to-prefix-alist))) - (add-to-list 'reftex-typekey-to-prefix-alist (cons typekey prefix))) - (cond - ((string-match "\\`\\\\" env-or-mac) - ;; It's a macro - (add-to-list 'reftex-label-mac-list env-or-mac)) - (t - (cond ((string= env-or-mac "any")) - ((string= env-or-mac "")) - ((string= env-or-mac "section")) - (t - (add-to-list 'reftex-label-env-list env-or-mac) - ;; if context is t, translate to skip many parens pairs - (if (eq t context) (setq context 100)))))) - (and reffmt - (not (assoc typekey reftex-typekey-to-format-alist)) - (setq reftex-typekey-to-format-alist - (cons (cons typekey reffmt) - reftex-typekey-to-format-alist))) - (and (not (string= env-or-mac "any")) - (not (string= env-or-mac "")) - (not (assoc env-or-mac reftex-env-or-mac-alist)) - (setq reftex-env-or-mac-alist - (cons (list env-or-mac typekey context labelfmt) - reftex-env-or-mac-alist))) - (while (and wordlist (stringp (car wordlist))) - (or (assoc (car wordlist) reftex-words-to-typekey-alist) - (setq reftex-words-to-typekey-alist - (cons (cons (downcase (car wordlist)) typekey) - reftex-words-to-typekey-alist))) - (setq wordlist (cdr wordlist))) - (cond - ((string= "" env-or-mac) nil) - ((assoc typekey qh-list) - (setcdr (assoc typekey qh-list) - (concat (cdr (assoc typekey qh-list)) " " env-or-mac))) - (t - (setq qh-list (cons (cons typekey env-or-mac) qh-list)))))) - - (setq qh-list (nreverse qh-list)) + (setq entry (car tmp) + env-or-mac (car entry) + entry (cdr entry) + tmp (cdr tmp)) + (if (null env-or-mac) + (setq env-or-mac "")) + (if (stringp (car entry)) + ;; This is before version 2.00 - convert entry to new format + ;; This is just to keep old users happy + (setq entry (cons (string-to-char (car entry)) + (cons (concat (car entry) ":") + (cdr entry))))) + (setq typekeychar (nth 0 entry) + typekey (char-to-string typekeychar) + prefix (nth 1 entry) + fmt (nth 2 entry) + context (nth 3 entry) + wordlist (nth 4 entry)) + (if (stringp wordlist) + ;; This is before version 2.04 - convert to new format + (setq wordlist (nthcdr 4 entry))) + + (if (and (stringp fmt) + (string-match "@" fmt)) + ;; special syntax for specifying a label format + (setq fmt (split-string fmt "@+")) + (setq fmt (list "\\label{%s}" fmt))) + (setq labelfmt (car fmt) + reffmt (nth 1 fmt)) + (if typekey + (add-to-list 'reftex-typekey-list typekey)) + (if (and typekey prefix + (not (assoc typekey reftex-typekey-to-prefix-alist))) + (add-to-list 'reftex-typekey-to-prefix-alist + (cons typekey prefix))) + (cond + ((string-match "\\`\\\\" env-or-mac) + ;; It's a macro + (let ((result (reftex-parse-args env-or-mac))) + (setq env-or-mac (or (first result) env-or-mac) + nargs (second result) + nlabel (third result) + opt-args (fourth result)) + (if nlabel (add-to-list 'macros-with-labels env-or-mac))) + (add-to-list 'reftex-label-mac-list env-or-mac)) + (t + (setq nargs nil nlabel nil opt-args nil) + (cond ((string= env-or-mac "any")) + ((string= env-or-mac "")) + ((string= env-or-mac "section")) + (t + (add-to-list 'reftex-label-env-list env-or-mac) + ;; Translate some special context cases + (when (assq context reftex-default-context-regexps) + (setq context + (format + (cdr (assq context reftex-default-context-regexps)) + (regexp-quote env-or-mac)))))))) + (and reffmt + (not (assoc typekey reftex-typekey-to-format-alist)) + (push (cons typekey reffmt) reftex-typekey-to-format-alist)) + (and (not (string= env-or-mac "any")) + (not (string= env-or-mac "")) + (not (assoc env-or-mac reftex-env-or-mac-alist)) + (push (list env-or-mac typekey context labelfmt + nargs nlabel opt-args) + reftex-env-or-mac-alist)) + (while (and (setq word (pop wordlist)) + (stringp word)) + (setq word (downcase word)) + (or (assoc word reftex-words-to-typekey-alist) + (push (cons word typekey) reftex-words-to-typekey-alist))) + (cond + ((string= "" env-or-mac) nil) + ((setq cell (assoc typekey qh-list)) + (push env-or-mac (cdr cell))) + (t + (push (list typekey env-or-mac) qh-list))))) + + (setq qh-list (sort qh-list '(lambda (x1 x2) (string< (car x1) (car x2))))) (setq reftex-typekey-to-prefix-alist (nreverse reftex-typekey-to-prefix-alist)) (setq reftex-type-query-prompt @@ -4559,21 +5411,51 @@ " (?=Help)")) (setq reftex-type-query-help (concat "SELECT A LABEL TYPE:\n--------------------\n" - (mapconcat '(lambda(x) - (format " [%s] %s" - (car x) (cdr x))) - qh-list "\n"))) - - ;; Calculate the section regexp - (setq reftex-section-regexp - (concat "^[ ]*\\\\\\(" - (mapconcat 'car reftex-section-levels "\\|") - "\\)\\*?\\(\\[[^]]*\\]\\)?{")) - )) + (mapconcat + '(lambda(x) + (setq sum 0) + (format " [%s] %s" + (car x) + (mapconcat + '(lambda(x) + (setq sum (+ sum (length x))) + (if (< sum 60) + x + (setq sum 0) + (concat "\n " x))) + (cdr x) " "))) + qh-list "\n"))) + + ;; Calculate the regular expressions + (let ((label-re "\\\\label{\\([^}]*\\)}") + (include-re "\\(\\`\\|[\n\r]\\)[ \t]*\\\\\\(include\\|input\\)[{ \t]+\\([^} \t\n\r]+\\)") + (section-re + (concat "\\(\\`\\|[\n\r]\\)[ \t]*\\\\\\(" + (mapconcat 'car reftex-section-levels "\\|") + "\\)\\*?\\(\\[[^]]*\\]\\)?{")) + (macro-re + (if macros-with-labels + (concat "\\(" + (mapconcat 'regexp-quote macros-with-labels "\\|") + "\\)[[{]") + "")) + (find-label-re-format + (concat "\\(" + (mapconcat 'regexp-quote (append '("\\label") + macros-with-labels) "\\|") + "\\)\\([[{][^]}]*[]}]\\)*[[{]\\(%s\\)[]}]"))) + (setq reftex-section-regexp section-re + reftex-section-or-include-regexp + (concat section-re "\\|" include-re) + reftex-everything-regexp + (concat label-re "\\|" section-re "\\|" include-re + (if macros-with-labels "\\|" "") macro-re) + reftex-find-label-regexp-format find-label-re-format + reftex-find-label-regexp-format2 + "\\([]} \t\n\r]\\)\\([[{]\\)\\(%s\\)[]}]")))) ;;; Keybindings -------------------------------------------------------------- -(define-key reftex-mode-map "\C-c-" 'reftex-item) (define-key reftex-mode-map "\C-c=" 'reftex-toc) (define-key reftex-mode-map "\C-c(" 'reftex-label) (define-key reftex-mode-map "\C-c)" 'reftex-reference) @@ -4597,31 +5479,59 @@ (require 'easymenu) -(easy-menu-define +(easy-menu-define reftex-mode-menu reftex-mode-map "Menu used in RefTeX mode" - '("Ref" + `("Ref" ["Table of Contents" reftex-toc t] "----" ["\\label" reftex-label t] ["\\ref" reftex-reference t] ["\\cite" reftex-citation t] - ["View crossref" reftex-view-crossref t] + ["View Crossref" reftex-view-crossref t] "----" - ("Search and Replace" - ["Search whole document" reftex-search-document t] - ["Replace in document" reftex-query-replace-document t] - ["Grep on document" reftex-grep-document t] + ("Multifile" + ["Search Whole Document" reftex-search-document t] + ["Replace in Document" reftex-query-replace-document t] + ["Grep on Document" reftex-grep-document t] + "----" + ["Create TAGS File" reftex-create-tags-file t] + "----" + ["Find Duplicate Labels" reftex-find-duplicate-labels t] + ["Change Label and Refs" reftex-change-label t]) + ("Parse Document" + ["Only this File" reftex-parse-one t] + ["Entire Document" reftex-parse-all (reftex-is-multi)] + ["Save to file" (reftex-access-parse-file 'write) + (> (length (symbol-value reftex-docstruct-symbol)) 0)] + ["Restore from File" (reftex-access-parse-file 'restore) + (reftex-access-parse-file 'readable)] "----" - ["Find duplicate labels" reftex-find-duplicate-labels t] - ["Change label and refs" reftex-change-label t] - "----" - ["Create TAGS file" reftex-create-tags-file t]) + ["Turn Auto-Save On" (setq reftex-save-parse-info t) + (not reftex-save-parse-info)] + ["Turn Auto-Save Off" (setq reftex-save-parse-info nil) + reftex-save-parse-info] + "---" + ["Reset RefTeX Mode" reftex-reset-mode t]) "----" - ["Parse document" reftex-parse-document t] - ["Reset RefTeX Mode" reftex-reset-mode t] - ["Show documentation" reftex-show-commentary t] - ["Customize RefTeX" reftex-customize t])) + ["Customize RefTeX" reftex-customize t] + ("Set Citation Format" + ,@(mapcar + (function + (lambda (x) + (vector + (symbol-name (car x)) + (list 'setq 'reftex-cite-format (list 'quote (car x))) + (list 'not (list 'eq 'reftex-cite-format + (list 'quote (car x))))))) + reftex-cite-format-builtin) + "----" + ["Turn Comments On" (setq reftex-comment-citations t) + (not reftex-comment-citations)] + ["Turn Comments Off" (setq reftex-comment-citations nil) + reftex-comment-citations]) + "----" + ["Show Documentation" reftex-show-commentary t])) ;;; Run Hook ------------------------------------------------------------------ @@ -4629,14 +5539,14 @@ ;;; That's it! ---------------------------------------------------------------- +(provide 'reftex) + ; Make sure tabels are compiled (message "updating internal tables...") (reftex-compute-ref-cite-tables) (message "updating internal tables...done") (setq reftex-tables-dirty nil) -(provide 'reftex) - ;;;============================================================================ ;;; reftex.el ends here