Also remove -DETAGS_REGEXPS from the target ctags:
[bpt/emacs.git] / lisp / textmodes / reftex.el
CommitLineData
a7ec1775
RS
1;; reftex.el --- Minor mode for doing \label{} \ref{} and \cite{} in LaTeX
2;; Copyright (c) 1997 Free Software Foundation, Inc.
3
4;; Author: Carsten Dominik <dominik@strw.LeidenUniv.nl>
5;; Keywords: tex
6
7;; This file is part of GNU Emacs.
8
9;; GNU Emacs is free software; you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 2, or (at your option)
12;; any later version.
13
14;; GNU Emacs is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18
19;; You should have received a copy of the GNU General Public License
20;; along with GNU Emacs; see the file COPYING. If not, write to the
21;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22;; Boston, MA 02111-1307, USA.
23
24;;---------------------------------------------------------------------------
25;;
26;;; Commentary:
27;;
28;; RefTeX is a minor mode with distinct support for \ref{}, \label{} and
29;; \cite{} commands in (multi-file) LaTeX documents.
30;; Labels are created semi-automatically. Definition context of labels is
31;; provided when creating a reference. Citations are simplified with
32;; efficient database lookup.
33;;
34;; To turn RefTeX Minor Mode on and off in a particular buffer, use
35;; `M-x reftex-mode'.
36;;
37;; To turn on RefTeX Minor Mode for all LaTeX files, add one of the
38;; following lines to your .emacs file:
39;;
40;; (add-hook 'LaTeX-mode-hook 'turn-on-reftex) ; with AUCTeX LaTeX mode
41;; (add-hook 'latex-mode-hook 'turn-on-reftex) ; with Emacs latex mode
42;;
43;; For key bindings, see further down in this documentation.
44;;
45;;---------------------------------------------------------------------------
46;;
47;; OVERVIEW
48;;
49;; 1. USING \label{} AND \ref{}. Labels and references are one of the
50;; strong points of LaTeX. But, in documents with hundreds of
51;; equations, figures, tables etc. it becomes quickly impossible to
52;; find good label names and to actually remember them. Then, also
53;; completion of labels in not enough. One actually needs to see the
54;; context of the label definition to find the right one.
55;;
56;; - RefTeX distinguishes labels for different environments. It
57;; always knows if a certain label references a figure, table
58;; etc. You can configure RefTeX to recognize any additional
59;; labeled environments you might have defined yourself.
60;;
61;; - RefTeX defines automatically unique labels. Type `C-c ('
62;; (reftex-label) to insert a label at point. RefTeX will either
63;; - derive a label from context (default for section labels)
64;; - insert a simple label consisting of a prefix and a number
65;; (default for equations and enumerate items) or
66;; - prompt for a label string (figures and tables)
67;; Which labels are created how can be controlled with the variable
68;; reftex-insert-label-flags.
69;;
70;; - Referencing labels is a snap and I promise you'll love it.
71;; In order to make a reference, type `C-c )' (reftex-reference).
72;; This shows an outline of the documents with all labels of a
73;; certain type (figure, equation,...) and context of the label
74;; definition. Selecting one of the labels inserts a \ref{} macro
75;; into the original buffer. Online help during the selection is
76;; available with `?'.
77;;
78;; 2. CITATIONS. After typing `C-c [' (reftex-citation), RefTeX will
79;; let you specify a regexp to search in current BibTeX database files
80;; (as specified in the \bibliography command) and pull out a formatted
81;; list of matches for you to choose from. The list is *formatted* and
82;; thus much easier to read than the raw database entries. It can also
83;; be sorted. The text inserted into the buffer is by default just
84;; `\cite{KEY}', but can also contain author names and the year in a
85;; configurable way. See documentation of the variable
86;; reftex-cite-format.
87;;
88;; 3. TABLE OF CONTENTS. Typing `C-c =' (reftex-toc) will show
89;; a table of contents of the document. From that buffer, you can
90;; jump quickly to every part of your document. This is similar to
91;; imenu, only it works for entire multifile documents and uses the
92;; keyboard rather than the mouse. The initial version of this
93;; function was contributed by Stephen Eglen.
94;;
95;; 4. MULTIFILE DOCUMENTS are supported in the same way as by AUCTeX.
96;; I.e. if a source file is not a full LaTeX document by itself,
97;; but included by another file, you may specify the name of
98;; the (top level) master file in a local variable section at the
99;; end of the source file, like so:
100;;
101;; %%% Local Variables:
102;; %%% TeX-master: my_master.tex
103;; %%% End:
104;;
105;; This will only take effect when you load the file next time or when
106;; you reset RefTeX with M-x reftex-reset-mode.
107;;
108;; RefTeX will also recognize the file variable tex-main-file. This
109;; variable is used by the Emacs TeX modes and works just like
110;; AUCTeX's TeX-master variable. See the documentation of your TeX/LaTeX
111;; modes.
112;;
113;; RefTeX knows about all files related to a document via input and
114;; include. It provides functions to run regular expression searches and
115;; replaces over the entire document and to create a TAGS file.
116;;
117;; 5. DOCUMENT PARSING. RefTeX needs to parse the document in order to find
118;; labels and other information. It will do it automatically once, when
119;; you start working with a document. If you need to enforce reparsing
120;; later, call any of the functions reftex-citation, reftex-label,
121;; reftex-reference, reftex-toc with a raw C-u prefix.
122;;
123;;-------------------------------------------------------------------------
124;;
125;; CONFIGURATION
126;;
127;; RefTeX contains many configurable options which change the way it works.
128;;
129;; Most importantly, RefTeX needs to be configured if you use labels to
130;; mark non-standard environments. RefTeX always understands LaTeX section
131;; commands and the following environments: figure, figure*,
132;; sidewaysfigure, table, table*, sidewaystable, equation, eqnarray,
133;; enumerate. For everythings else, it needs to be configured.
134;;
135;; A good way to configure RefTeX is with the custom.el package by Per
136;; Abrahamsen, shipped with Emacs 20 and XEmacs 19.15. To do this, just
137;; say `M-x reftex-customize'. This will not work with older versions
138;; of custom.el.
139;;
140;; Here is a complete list of the RefTeX configuration variables with
141;; their default settings. You could copy this list to your .emacs file
142;; and change whatever is necessary. Each variable has an extensive
143;; documentation string. Look it up for more information!
144;;
145;; ;; Configuration Variables and User Options for RefTeX ------------------
146;; ;; Support for \label{} and \ref{} --------------------------------------
147;; (setq reftex-label-alist nil)
148;; (setq reftex-default-label-alist-entries '(Sideways LaTeX))
149;; (setq reftex-use-text-after-label-as-context nil)
150;; ;; Label insertion
151;; (setq reftex-insert-label-flags '("s" "sft"))
152;; (setq reftex-derive-label-parameters '(3 20 t 1 "-"
153;; ("the" "on" "in" "off" "a" "for" "by" "of" "and" "is")))
154;; (setq reftex-label-illegal-re "[\000-\040\177-\377\\\\#$%&~^_{}]")
155;; (setq reftex-abbrev-parameters '(4 2 "^saeiou" "aeiou"))
156;; ;; Label referencing
157;; (setq reftex-label-menu-flags '(t t nil nil nil nil))
158;; (setq reftex-guess-label-type t)
159;; ;; BibteX citation configuration ----------------------------------------
160;; (setq reftex-bibpath-environment-variables '("BIBINPUTS" "TEXBIB"))
161;; (setq reftex-bibfile-ignore-list nil)
162;; (setq reftex-sort-bibtex-matches 'reverse-year)
163;; (setq reftex-cite-format 'reftex-cite-format-default)
164;; ;; Table of contents configuration --------------------------------------
165;; (setq reftex-toc-follow-mode nil)
166;; ;; Miscellaneous configurations -----------------------------------------
167;; (setq reftex-extra-bindings nil)
168;; (setq reftex-use-fonts t)
169;; (setq reftex-keep-temporary-buffers t)
170;; (setq reftex-auto-show-entry t)
171;;
172;; CONFIGURATION EXAMPLES:
173;; =======================
174;;
175;; Suppose you are working with AMS-LaTeX amsmath package (with its math
176;; environments like `align', `multiline' etc.). Here is how you would
177;; configure RefTeX to recognize these environments:
178;;
179;; (setq reftex-label-alist '(AMSTeX))
180;;
181;; This is very easy since RefTeX has builtin support for AMS-LaTeX.
182;; Suppose, however, you are also
183;;
184;; - using "\newtheorem" in LaTeX in order to define two new environments
185;; "Theorem" and "Axiom" like this:
186;;
187;; \newtheorem{axiom}{Axiom}
188;; \newtheorem{theorem}{Theorem}
189;;
190;; - making your figures not directly with the figure environment, but with
191;; a macro like
192;;
193;; \newcommand{\myfig}[4][tbp]{
194;; \begin{figure}[#1]
195;; \epsimp[#4]{#2}
196;; \caption{#3}
197;; \end{figure}}
198;;
199;; which would be called like
200;;
201;; \myfig{filename}{\label{fig:13} caption text}{1}
202;;
203;; Here is how to tell RefTeX to also recognize Theorem and Axiom as
204;; labeled environments, and that any labels defined inside the \myfig
205;; macro are figure labels:
206;;
207;; (setq reftex-label-alist
208;; '(AMSTeX
209;; ("axiom" ?a "ax:" "~\\ref{%s}" nil ("Axiom" "Ax."))
210;; ("theorem" ?h "thr:" "~\\ref{%s}" t ("Theorem" "Theor." "Th."))
211;; ("\\myfig" ?f "fig:" nil t)))
212;;
213;; The type indicator characters ?a and ?h are used for prompts when
214;; RefTeX queries for a label type. Note that "h" was chosen for "theorem"
215;; since "t" is already taken by "table". Note that also "s", "f", "e", "n"
216;; are taken by the standard environments.
217;; The automatic labels for Axioms and Theorems will look like "ax:23" or
218;; "thr:24".
219;; The "\ref{%s}" is a format string indicating how to insert references to
220;; these labels. The nil format in the \myfig entry means to use the same
221;; format as other figure labels.
222;; The next item indicates how to grab context of the label definition.
223;; - t means to get it from a default location (from the beginning of a \macro
224;; or after the \begin{} statement). t is *not* a good choice for eqnarray
225;; and similar environments.
226;; - nil means to use the text right after the label definition.
227;; - For more complex ways of getting context, see the docstring of
228;; reftex-label-alist.
229;; The strings at the end of each entry are used to guess the correct label
230;; type from the word before point when creating a reference. E.g. if you
231;; write: "as we have shown in Theorem" and then press `C-)', RefTeX will
232;; know that you are looking for a Theorem label and restrict the labels in
233;; the menu to only these labels without even asking.
234;; See also the documentation string of the variable reftex-label-alist.
235;;
236;; Depending on how you would like the label insertion and selection for the
237;; new environments to work, you might want to add the letters "a" and "h"
238;; to some of the flags in the following variables:
239;;
240;; reftex-insert-label-flags
241;; reftex-label-menu-flags
242;;
243;; The individual flags in these variables can be set to t or nil to enable or
244;; disable the feature for all label types. They may also contain a string of
245;; label type letters in order to turn on the feature for those types only.
246;;
247;; -----
248;; If you are writing in a language different from english you might want to
249;; add magic words for that language. Here is a German example:
250;;
251;; (setq reftex-label-alist
252;; '((nil ?s nil nil nil ("Kapitel" "Kap." "Abschnitt" "Teil"))
253;; (nil ?e nil nil nil ("Gleichung" "Gl."))
254;; (nil ?t nil nil nil ("Tabelle"))
255;; (nil ?f nil nil nil ("Figur" "Abbildung" "Abb."))
256;; (nil ?n nil nil nil ("Punkt"))))
257;;
258;; Using `nil' as first item in each entry makes sure that this entry does
259;; not replace the original entry for that label type.
260;;
261;; HOOKS
262;; -----
263;; Loading reftex.el runs the hook reftex-load-hook. Turning on reftex-mode
264;; runs reftex-mode-hook.
265;;
266;;-------------------------------------------------------------------------
267;;
268;; KEY BINDINGS
269;;
270;; All important functions of RefTeX can be reached from its menu which
271;; is installed in the menu bar as "Ref" menu. Only the more frequently used
272;; functions have key bindings.
273;;
274;; Here is the default set of keybindings from RefTeX.
275;;
276;; C-c = reftex-toc
277;; C-c ( reftex-label
278;; C-c ) reftex-reference
279;; C-c [ reftex-citation
280;; C-c & reftex-view-crossref
281;;
282;; I've used these bindings in order to avoid interfering with AUCTeX's
283;; settings. Personally, I also bind some functions in the C-c LETTER
284;; map for easier access:
285;;
286;; C-c t reftex-toc
287;; C-c l reftex-label
288;; C-c r reftex-reference
289;; C-c c reftex-citation
290;; C-c v reftex-view-crossref
291;; C-c s reftex-search-document
292;; C-c g reftex-grep-document
293;;
294;; If you want to copy those as well, set in your .emacs file:
295;;
296;; (setq reftex-extra-bindings t)
297;;
298;; It is possible to bind the function for viewing cross references to a
299;; mouse event. Something like the following in .emacs will do the trick:
300;;
301;; (add-hook 'reftex-load-hook
302;; '(lambda ()
303;; (define-key reftex-mode-map [(alt mouse-1)]
304;; 'reftex-mouse-view-crossref)))
305;;
306;;-------------------------------------------------------------------------
307;;
308;; RELATED PACKAGES
309;;
310;; AUCTeX
311;; ------
312;; If you are writing any TeX or LaTeX documents with Emacs, you should
313;; have a look at AUCTeX, the definitive package to work with TeX and LaTeX.
314;; Information on AUCTeX can be found here:
315;;
316;; http://www.sunsite.auc.dk/auctex/
317;;
318;; AUCTeX version 9.7f and later can be configured to delegate label
319;; insertion to RefTeX. Do do that, say in your .emacs file
320;;
321;; (setq LaTeX-label-function 'reftex-label)
322;;
323;; RefTeX also provides functions which can replace TeX-arg-label and
324;; TeX-arg-cite in AUCTeX. These functions are compatible with the originals,
325;; but use RefTeX internals to create and select labels and citation keys.
326;; There are 3 functions: reftex-arg-label, reftex-arg-ref, reftex-arg-cite.
327;;
328;; AUCTeX can support RefTeX via style files. A style file may contain
329;; calls to reftex-add-to-label-alist which defines additions to
330;; reftex-label-alist. The argument taken by this function must have exactly
331;; the same format as reftex-label-alist. E.g. a good entry in a style file
332;; for the amsmath package would be
333;;
334;; (and (fboundp 'reftex-add-to-label-alist)
335;; (reftex-add-to-label-alist '(AMSTeX)))
336;;
337;; while a package defining a proposition environment with \newtheorem
338;; might use
339;;
340;; (and
341;; (fboundp 'reftex-add-to-label-alist)
342;; (reftex-add-to-label-alist
343;; '(("proposition" ?p "prop:" "~\\ref{%s}" t
344;; ("Proposition" "Prop.")))))
345;;
346;; Bib-cite.el
347;; -----------
348;; Once you have written a document with labels, refs and citations, it can be
349;; nice to read such a file like a hypertext document. RefTeX has some support
350;; for that (reftex-view-crossref, reftex-search-document). A more elegant
351;; interface with mouse support and links into Hyperbole is provided (among
352;; other things) by Peter S. Galbraith's bib-cite.el. There is some overlap in
353;; the functionalities of bib-cite and RefTeX. Bib-cite.el comes bundled with
354;; AUCTeX. You can also get the latest version from
355;;
356;; ftp://ftp.phys.ocean.dal.ca/users/rhogee/elisp/bib-cite.el
357;;
358;;-------------------------------------------------------------------------
359;;
360;; PERFORMANCE ISSUES
361;;
362;; 1. RefTeX will load other parts of a multifile document as well as BibTeX
363;; database files for lookup purposes. These buffers are kept, so that
364;; subsequent lookup in the same files is fast. For large documents and
365;; large BibTeX databases, this can use up a lot of memory. If you have
366;; more time than memory, try the following option, which will remove
367;; buffers created for lookup after use.
368;;
369;; (setq reftex-keep-temporary-buffers nil)
370;;
371;; 2. Parsing the document for labels and their context can be slow.
372;; Therefore, RefTeX does it just once automatically. Further parsing
373;; happens only on user request
374;; - with a raw C-u prefix arg to any of the functions reftex-label,
375;; reftex-reference, reftex-citation, reftex-toc.
376;; - with the `r' key from the label selection menu or the *toc* buffer.
377;;
378;; *** If you use reftex-label to create labels, the list will be updated
379;; *** internally, so that no extra parsing is required.
380;;
381;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
382;;
383;; KNOWN BUGS
384;;
385;; o If you change reftex-label-alist in an editing session, you need to
386;; reset reftex with `M-x reftex-reset-mode' in order to make these
387;; changes effective. Changes introduced with the function
388;; reftex-add-to-label-alist as well as changes applied from the
389;; customization buffer automatically trigger a reset.
390;;
391;; o At times the short context shown by RefTeX may not be what you want.
392;; In particular, eqnarray environments can be difficult to
393;; parse. RefTeX's default behavior for eqnarrays is to scan backwards to
394;; either a double backslash or the beginning of the environment. If this
395;; gives unsatisfactory results, make it a habit to place the label
396;; *before* each equation
397;;
398;; \begin{eqnarray}
399;; \label{eq:1}
400;; E = \gamma m c^2 \\
401;; \label{eq:2}
402;; \gamma = \sqrt{1-v^2/c^2}
403;; \end{eqnarray}
404;;
405;; and turn off parsing for context in equation and eqnarray environments
406;; with
407;;
408;; (setq reftex-use-text-after-label-as-context "e").
409;;
410;; o RefTeX keeps only one global copy of the configuration variables.
411;; Also any additions from style files go into a global variable.
412;; Practically, this should not be a problem. Theoretically, it could
413;; give conflicts if two documents used environments with identical
414;; names, but different associated label types.
415;;
416;; o Input, include, bibliography and section statements have to be first
417;; on a line (except for white space) in order to be seen by reftex.
418;;
419;; o When the document is scanned, RefTeX creates a large buffer containing
420;; the entire document instead of scanning the individual files one by
421;; one. This is necessary since a file might not contain the context
422;; needed by RefTeX.
423;;
424;; o If you have two identical section headings in the same file,
425;; reftex-toc will only let you jump to the first one because it searches
426;; for the section heading from the beginning of the file. You can work
427;; around this by changing one of the section titles in a way LaTeX does
428;; not see, e.g. with extra white space. RefTeX will distinguish
429;; \section{Introduction} from \section{ Introduction}.
430;;
431;; o RefTeX sees also labels in regions commented out and will refuse to
432;; make duplicates of such a label. This is considered to be a feature.
433;;
434;; o When RefTeX tries to show a window full of context from inside a
435;; section hidden with outline-minor-mode, it will unhide that section.
436;; This change will not be reversed automatically.
437;;
438;;---------------------------------------------------------------------------
439;;
440;; TO DO
441;;
442;; I think I am pretty much done with this one...
443;;
444;;---------------------------------------------------------------------------
445;;
446;; AUTHOR
447;;
448;; Carsten Dominik <dominik@strw.LeidenUniv.nl>
449;;
450;; with contributions from Stephen Eglen
451;;
452;; The newest version of RefTeX can be found at
453;;
454;; http://www.strw.leidenuniv.nl/~dominik/Tools/
455;; ftp://strw.leidenuniv.nl/pub/dominik/
456;;
457;; THANKS TO:
458;; ---------
459;; At least the following people have invested time to test and bug-fix
460;; reftex.el. Some have send patches for fixes or new features.
461;;
462;; Stephen Eglen <stephene@cogs.susx.ac.uk>
463;; F.E.Burstall <F.E.Burstall@maths.bath.ac.uk>
464;; Karl Eichwalder <ke@ke.Central.DE>
465;; Laurent Mugnier <mugnier@onera.fr>
466;; Rory Molinari <molinari@yunt.math.lsa.umich.edu>
467;; Soren Dayton <csdayton@cs.uchicago.edu>
468;; Daniel Polani <polani@Informatik.Uni-Mainz.DE>
469;; Allan Strand <astrand@trillium.NMSU.Edu>
470;;
471;; The view crossref feature was inspired by the similar function in
472;; Peter S. Galbraith's bib-cite.el.
473;;
474;; Finally thanks to Uwe Bolick <bolick@physik.tu-berlin.de> who first
475;; got me (some years ago) into supporting LaTeX labels and references
476;; with an Editor (which was MicroEmacs at the time).
477\f
478;;; Code:
479
480;; Stuff that needs to be there when we use defcustom
481;; --------------------------------------------------
482
483(require 'custom)
484
485(defvar reftex-tables-dirty t
486 "Flag showing if tables need to be re-computed.")
487
488(eval-and-compile
489 (defun reftex-set-dirty (symbol value)
490 (setq reftex-tables-dirty t)
491 (set symbol value)))
492
493;;; Begin of Configuration Section ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
494
495;; Configuration Variables and User Options for RefTeX ------------------
496
497(defgroup reftex nil
498 "LaTeX label and citation support."
499 :tag "RefTeX"
500 :link '(url-link :tag "Home Page" "http://strw.leidenuniv.nl/~dominik/Tools/")
501 :prefix "reftex-"
502 :group 'tex)
503
504(defun reftex-customize ()
505 "Call the customize function with reftex as argument."
506 (interactive)
507 (if (fboundp 'customize-group)
508 (customize-group 'reftex)
509 (customize 'reftex)))
510
511;; Support for \label{} and \ref{} --------------------------------------
512
513(defgroup reftex-label-support nil
514 "Support for creation, insertion and referencing of labels in LaTeX"
515 :group 'reftex)
516
517(defgroup reftex-defining-label-environments nil
518 "Definition of environments and macros to do with label"
519 :group 'reftex-label-support)
520
521
522(defcustom reftex-label-alist nil
523 "AList with information on environments for \\label{}-\\ref{} use.
524See the definition of reftex-label-alist-builtin for examples. This variable
525should define additions and changes to the default. The only things you MUST
526NOT change is that '?s' is the type indicator for section labels and SPACE is
527for the 'any' label type. These are hard-coded at other places in the code.
528
529Changes to this variable after reftex.el has been loaded become only
530effective when RefTeX is reset with \\[reftex-reset-mode].
531
532Each list entry is a list describing an environment or macro carrying a
533label. The elements of each list entry are:
534
5350. Name of the environment (like \"table\") or macro (like \"\\\\myfig\").
536 Special names: `section' for section labels, `any' to define a group
537 which contains all labels.
538 This may also be nil if this entry is only meant to change some settings
539 associated with the type indicator character (see below).
540
5411. Type indicator character, like ?t.
542 The type indicator is a single character used in prompts for
543 label types. It must be a printable character. The same character
544 may occur several times in this list, to cover cases in which different
545 environments carry the same label type (like equation and eqnarray).
546
5472. Label prefix string, like \"tab:\".
548 The prefix is a short string used as the start of a label. It may be the
549 empty string.
550
5513. Format string for reference insert in buffer. Each %s will be replaced by
552 the label (yes, several %s can be in there, so that you can set this to:
553 \"\\ref{%s} on page~\\pageref{%s}\").
554 When the format starts with ~, whitespace before point will be removed so
555 that the reference cannot be separated from the word before it.
556
5574. Indication on how to find the short context.
558 - If `nil', use the text following the \\label{...} macro.
559 - If `t', use
560 - text following the \\begin{...} statement of environments
561 (not a good choice in in eqnarray or enumerate environments!)
562 - the section heading for section labels.
563 - the begin of the macro for macros.
564 - If a string, use as regexp to search *backward* from the label. Context
565 is then the text following the end of the match. E.g. putting this to
566 \"\\\\\\\\caption{\" will use the beginning of the caption in a figure
567 or table environment. \"\\\\\\\\begin{eqnarray}\\\\|\\\\\\\\\\\\\\\\\"
568 works for eqnarrays.
569 - If a function, call this function with the name of the environment/macro
570 as argument. On call, point will be just after the \\label{} macro. The
571 function is expected to return a suitable context string. It should
572 throw an exception (error) when failing to find context.
573 Consider the following example, which would return the 10 characters
574 following the label as context:
575
576 (defun my-context-function (env-or-mac)
577 (if (> (point-max) (+ 10 (point)))
578 (buffer-substring (point) (+ 10 (point)))
579 (error \"Buffer too small\")))
580
581 Setting the variable reftex-use-text-after-label-as-context to t overrides
582 the setting here.
583
5845. List of magic words which identify a reference to be of this type. If the
585 word before point is equal to one of these words when calling
586 reftex-reference, the label list offered will be automatically restricted
587 to labels of the correct type.
588
589If the type indicator characters of two or more entries are the same, RefTeX
590will use
591 - the first non-nil format and prefix
592 - the magic words of all involved entries.
593
594Any list entry may also be a symbol. If that has an association in
595reftex-label-alist-builtin, the cdr of that association is spliced into the
596list. See the AMSTeX configuration example in the comment section of
597reftex.el."
598 :group 'reftex-defining-label-environments
599 :set 'reftex-set-dirty
600 :type '(list
601 :convert-widget
602 (lambda (widget)
603 (let*
604 ((args
605 (list
606 `(repeat
607 :inline t
608 (radio
609 :value ("" ?a nil nil t nil)
610 (choice
611 :tag "Builtin"
612 :value AMSTeX
613 ,@(mapcar (function (lambda (x)
614 (list 'const ':tag (nth 1 x) (car x))))
615 reftex-label-alist-builtin))
616 (list :tag "Detailed custom entry"
617 (choice :tag "Environment or \\macro "
618 (const :tag "Ignore, just use typekey" nil)
619 (string ""))
620 (character :tag "Typekey character " ?a)
621 (choice :tag "Label prefix string "
622 (const :tag "Copy from similar label type" nil)
623 (string :tag "Specify here" "lab:"))
624 (choice :tag "Label reference format"
625 (const :tag "Copy from similar label type" nil)
626 (string :tag "Specify here" "~\\ref{%s}"))
627 (choice :tag "Grab context method "
628 (const :tag "Default position" t)
629 (const :tag "After label" nil)
630 (regexp :tag "Regular expression" "")
631 (symbol :tag "Function" my-context-function))
632 (repeat :tag "List of Magic Words" (string))))))))
633 (widget-put widget :args args)
634 widget))))
635
636(defcustom reftex-default-label-alist-entries '(Sideways LaTeX)
637 "Default label alist specifications. LaTeX should be the last entry.
638This list describes the default label environments RefTeX should always use in
639addition to the specifications in reftex-label-alist. It is probably a
640mistake to remove the LaTeX symbol from this list.
641
642Here are the current options:
643
644LaTeX The standard LaTeX environments
645Sideways The sidewaysfigure and sidewaystable environments
646AMSTeX The math environments in the AMS_LaTeX amsmath package
647AAS The deluxetable environment from the American Astronomical Society"
648 :group 'reftex-defining-label-environments
649 :set 'reftex-set-dirty
650 :type '(list :indent 4
651 :convert-widget
652 (lambda (widget)
653 (let* ((args
654 (list
655 `(checklist
656 :inline t
657 ,@(reverse
658 (mapcar (lambda (x)
659 (list 'const ':tag (nth 1 x) (car x)))
660 reftex-label-alist-builtin))))))
661 (widget-put widget :args args)
662 widget))))
663
664(defcustom reftex-use-text-after-label-as-context nil
665 "*t means, grab context from directly after the \\label{..} macro.
666This is the fastest method for obtaining context of the label definition, but
667requires discipline when placing labels. Setting this variable to t takes
668precedence over the individual settings in reftex-label-alist.
669This variable may be set to t, nil, or a string of label type letters
670indicating the label types for which it should be true."
671 :group 'reftex-defining-label-environments
672 :set 'reftex-set-dirty
673 :type '(choice
674 (const :tag "on" t) (const :tag "off" nil)
675 (string :tag "Selected label types")))
676
677;; Label insertion
678
679(defgroup reftex-making-and-inserting-labels nil
680 "Options on how to create new labels"
681 :group 'reftex-label-support)
682
683(defcustom reftex-insert-label-flags '("s" "sft")
684 "Flags governing label insertion. First flag DERIVE, second flag PROMPT.
685
686If DERIVE is t, RefTeX will try to derive a sensible label from context.
687A section label for example will be derived from the section heading.
688The conversion of the context to a legal label is governed by the
689specifications given in reftex-derive-label-parameters.
690If RefTeX fails to derive a label, it will prompt the user.
691
692If PROMPT is t, the user will be prompted for a label string. The prompt will
693already contain the prefix, and (if DERIVE is t) a default label derived from
694context. When PROMPT is nil, the default label will be inserted without
695query.
696
697So the combination of DERIVE and PROMPT controls label insertion. Here is a
698table describing all four possibilities:
699
700DERIVE PROMPT ACTION
701-------------------------------------------------------------------------
702 nil nil Insert simple label, like eq:22 or sec:13. No query.
703 nil t Prompt for label
704 t nil Derive a label from context and insert without query
705 t t Derive a label from context and prompt for confirmation
706
707Each flag may be set to t, nil, or a string of label type letters
708indicating the label types for which it should be true.
709Thus, the combination may be set differently for each label type. The
710default settings \"s\" and \"sft\" mean: Derive section labels from headings
711(with confirmation). Prompt for figure and table labels. Use simple labels
712without confirmation for everything else."
713 :group 'reftex-making-and-inserting-labels
714 :type '(list (choice :tag "Derive label from context"
715 (const :tag "always" t)
716 (const :tag "never" nil)
717 (string :tag "for selected label types" ""))
718 (choice :tag "Prompt for label string "
719 :entry-format " %b %v"
720 (const :tag "always" t)
721 (const :tag "never" nil)
722 (string :tag "for selected label types" ""))))
723
724(defcustom reftex-derive-label-parameters '(3 20 t 1 "-" ; continue
725 ("the" "on" "in" "off" "a" "for" "by" "of" "and" "is"))
726 "Parameters for converting a string into a label.
727NWORDS Number of words to use.
728MAXCHAR Maximum number of characters in a label string.
729ILLEGAL nil: Throw away any words containing characters illegal in labels.
730 t: Throw away only the illegal characters, not the whole word.
731ABBREV nil: Never abbreviate words.
732 t: Always abbreviate words (see reftex-abbrev-parameters).
733 not t and not nil: Abbreviate words if necessary to shorten
734 label string below MAXCHAR.
735SEPARATOR String separating different words in the label
736IGNOREWORDS List of words which should not be part of labels"
737 :group 'reftex-making-and-inserting-labels
738 :type '(list (integer :tag "Number of words " 3)
739 (integer :tag "Maximum label length " 20)
740 (choice :tag "Illegal characters in words"
741 (const :tag "throw away entire word" nil)
742 (const :tag "throw away single chars" t))
743 (choice :tag "Abbreviate words "
744 (const :tag "never" nil)
745 (const :tag "always" t)
746 (const :tag "when label is too long" 1))
747 (string :tag "Separator between words " "-")
748 (repeat :tag "Ignore words"
749 :entry-format " %i %d %v"
750 (string :tag ""))))
751
752(defcustom reftex-label-illegal-re "[\000-\040\177-\377\\\\#$%&~^_{}]"
753 "Regexp matching characters not legal in labels.
754For historic reasons, this character class comes *with* the [] brackets."
755 :group 'reftex-making-and-inserting-labels
756 :type '(regexp :tag "Character class"))
757
758(defcustom reftex-abbrev-parameters '(4 2 "^saeiou" "aeiou")
759 "Parameters for abbreviation of words.
760MIN-CHARS minimum number of characters remaining after abbreviation
761MIN-KILL minimum number of characters to remove when abbreviating words
762BEFORE character class before abbrev point in word
763AFTER character class after abbrev point in word"
764 :group 'reftex-making-and-inserting-labels
765 :type '(list
766 (integer :tag "Minimum chars per word" 4)
767 (integer :tag "Shorten by at least " 2)
768 (string :tag "cut before char class " "^saeiou")
769 (string :tag "cut after char class " "aeiou")))
770
771
772;; Label referencing
773
774(defgroup reftex-referencing-labels nil
775 "Options on how to reference labels"
776 :group 'reftex-label-support)
777
778(defcustom reftex-label-menu-flags '(t t nil nil nil nil)
779 "*List of flags governing the label menu makeup.
780The flags are:
781
782TABLE-OF-CONTENTS Show the labels embedded in a table of context.
783SECTION-NUMBERS Include section numbers (like 4.1.3) in table of contents.
784COUNTERS Show counters. This just numbers the labels in the menu.
785NO-CONTEXT Non-nil means do NOT show the short context.
786FOLLOW follow full context in other window.
787SHOW-COMMENTED Show labels from regions which are commented out. RefTeX
788 sees these labels, but does not normally show them.
789
790Each of these flags can be set to t or nil, or to a string of type letters
791indicating the label types for which it should be true. These strings work
792like character classes in regular expressions. Thus, setting one of the
793flags to \"sf\" makes the flag true for section and figure labels, nil
794for everything else. Setting it to \"^ft\" makes it the other way round.
795
796Most options can also be switched from the label menu itself - so if you
797decide here to not have a table of contents in the label menu, you can still
798get one interactively during selection from the label menu."
799 :group 'reftex-referencing-labels
800 :type '(list
801 (choice :tag "Embed in table of contents "
802 (const :tag "on" t) (const :tag "off" nil)
803 (string :tag "Selected label types"))
804 (choice :tag "Show section numbers "
805 (const :tag "on" t) (const :tag "off" nil))
806 (choice :tag "Show individual counters "
807 (const :tag "on" t) (const :tag "off" nil)
808 (string :tag "Selected label types"))
809 (choice :tag "Hide short context "
810 (const :tag "on" t) (const :tag "off" nil)
811 (string :tag "Selected label types"))
812 (choice :tag "Follow context in other window"
813 (const :tag "on" t) (const :tag "off" nil)
814 (string :tag "Selected label types"))
815 (choice :tag "Show commented labels "
816 (const :tag "on" t) (const :tag "off" nil)
817 (string :tag "Selected label types"))))
818
819
820(defcustom reftex-guess-label-type t
821 "*Non-nil means, reftex-reference will try to guess the label type.
822To do that, RefTeX will look at the word before the cursor and compare it with
823the words given in reftex-label-alist. When it finds a match, RefTeX will
824immediately offer the correct label menu - otherwise it will prompt you for
825a label type. If you set this variable to nil, RefTeX will always prompt."
826 :group 'reftex-referencing-labels
827 :type '(boolean))
828
829;; BibteX citation configuration ----------------------------------------
830
831(defgroup reftex-citation-support nil
832 "Support for referencing bibliographic data with BibTeX"
833 :group 'reftex)
834
835(defcustom reftex-bibpath-environment-variables '("BIBINPUTS" "TEXBIB")
836 "*List of env vars which might contain the path to BibTeX database files."
837 :group 'reftex-citation-support
838 :set 'reftex-set-dirty
839 :type '(repeat (string :tag "Environment variable")))
840
841(defcustom reftex-bibfile-ignore-list nil
842 "List of files in \\bibliography{..} RefTeX should *not* parse.
843The file names have to be in the exact same form as in the bibliography
844macro - i.e. without the .bib extension.
845Intended for files which contain only `@string' macro definitions and the
846like, which are ignored by RefTeX anyway."
847 :group 'reftex-citation-support
848 :set 'reftex-set-dirty
849 :type '(repeat (string :tag "File name")))
850
851(defcustom reftex-sort-bibtex-matches 'reverse-year
852 "*Sorting of the entries found in BibTeX databases by reftex-citation.
853Possible values:
854nil Do not sort entries.
855'author Sort entries by author name.
856'year Sort entries by increasing year.
857'reverse-year Sort entries by decreasing year."
858 :group 'reftex-citation-support
859 :type '(choice (const :tag "not" nil)
860 (const :tag "by author" author)
861 (const :tag "by year" year)
862 (const :tag "by year, reversed" reverse-year)))
863
864(defcustom reftex-cite-format 'reftex-cite-format-default
865 "Defines the format of citations to be inserted into the buffer.
866It can be a string, a list of strings, or an alist with characters as keys
867and a list of strings in the car. In the simplest case, this can just
868be the string \"\\cite{KEY}\", which is also the default. See the
869definition of the reftex-cite-format-XXXX constants for more complex
870examples.
871 If reftex-cite-format is a string, it will be used as the format. In
872the format, AUTHOR will be replaced by the last name of the
873author, YEAR will be replaced by the year and KEY by the citation
874key. If AUTHOR is present several times, it will be replaced with
875successive author names.
876See the constant reftex-cite-format-default for an example.
877 If reftex-cite-format is a list of strings, the string used will
878depend upon the number of authors of the article. No authors means,
879the first string will be used, 1 author means, the second string will
880be used etc. The last string in the list will be used for all articles
881with too many authors. See reftex-cite-format-1-author-simple for an
882example.
883 If reftex-cite-format is a list of cons cells, the car of each cell
884needs to be a character. When a selected reference is accepted by
885pressing that key, the cdr of the associated list will be used as
886described above. See reftex-cite-format-2-authors for an example.
887 In order to configure this variable, you can either set
888reftex-cite-format directly yourself or set it to the SYMBOL of one of
889the predefined constants. E.g.:
890(setq reftex-cite-format 'reftex-cite-format-2-authors)"
891 :group 'reftex-citation-support
892 :type
893'(choice
894 (choice :tag "symbolic defaults"
895 :value reftex-cite-format-default
896 (const reftex-cite-format-default)
897 (const reftex-cite-format-1-author-simple)
898 (const reftex-cite-format-2-authors))
899 (string :tag "format string" "\\cite{KEY}")
900 (repeat :tag "list of strings"
901 :value ("\cite{KEY}" "AUTHOR \cite{KEY}" "AUTHOR and AUTHOR \cite{KEY}")
902 (string :tag "format string" ""))
903 (repeat :tag "key-ed lists of strings"
904 :value ((?\r . ("\cite{KEY}" "AUTHOR \cite{KEY}" "AUTHOR and AUTHOR \cite{KEY}")))
905 (cons :tag "Enter a keyed list of format strings"
906 (character :tag "Key character " ?\r)
907 (repeat
908 (string :tag "format string" ""))))))
909
910;; Table of contents configuration --------------------------------------
911
912(defgroup reftex-table-of-contents-browser nil
913 "A multifile table of contents browser."
914 :group 'reftex)
915
916(defcustom reftex-toc-follow-mode nil
917 "Non-nil means, point in *toc* buffer will cause other window to follow.
918The other window will show the corresponding part of the document.
919This flag can be toggled from within the *toc* buffer with the `f' key."
920 :group 'reftex-table-of-contents-browser
921 :type '(boolean))
922
923;; Miscellaneous configurations -----------------------------------------
924
925(defgroup reftex-miscellaneous-configurations nil
926 "Collection of further configurations"
927 :group 'reftex)
928
929(defcustom reftex-extra-bindings nil
930 "Non-nil means, make additional key bindings on startup.
931These extra bindings are located in the users C-c letter map."
932 :group 'reftex-miscellaneous-configurations
933 :type '(boolean))
934
935(defcustom reftex-use-fonts t
936 "*Non-nil means, use fonts in label menu and on-the-fly help.
937Font-lock must be loaded as well to actually get fontified display."
938 :group 'reftex-miscellaneous-configurations
939 :type '(boolean))
940
941(defcustom reftex-keep-temporary-buffers t
942 "*Non-nil means, keep any TeX and BibTeX files loaded for lookup.
943Nil means, kill it immediately after use unless it was already an existing
944buffer before the lookup happened. It is faster to keep the buffers, but can
945use a lot of memory, depending on the size of your database and document."
946 :group 'reftex-miscellaneous-configurations
947 :type '(boolean))
948
949(defcustom reftex-auto-show-entry t
950 "*Non-nil means, showing context in another window may unhide a section.
951This is important when using outline-minor-mode. If the context to be shown
952is in a hidden section, RefTeX will issue a \"show-entry\" command in order
953to show it. This is not reversed when the label is selected - so the section
954remains shown after command completion."
955 :group 'reftex-miscellaneous-configurations
956 :type '(boolean))
957
958
959;;; End of Configuration Section ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
960
961;;;===========================================================================
962;;;
963;;; Define the formal stuff for a minor mode named RefTeX.
964;;;
965
966(defvar reftex-mode nil
967 "Determines if RefTeX minor mode is active.")
968(make-variable-buffer-local 'reftex-mode)
969
970(defvar reftex-mode-map (make-sparse-keymap)
971 "Keymap for RefTeX minor mode.")
972
973(defvar reftex-mode-menu nil)
974
975;;;###autoload
976(defun turn-on-reftex ()
977 "Turn on RefTeX minor mode."
978 (reftex-mode t))
979
980;;;###autoload
981(defun reftex-mode (&optional arg)
982 "Minor mode with distinct support for \\label{}, \\ref{} and \\cite{}
983in LaTeX documents.
984
985Labels can be created with `\\[reftex-label]' and referenced with `\\[reftex-reference]'.
986When referencing, you get a menu with all labels of a given type and
987context of the label definition. The selected label is inserted as a
988\\ref{} macro.
989
990Citations can be made with `\\[reftex-citation]' which will use a regular expression
991to pull out a *formatted* list of articles from your BibTeX
992database. The selected citation is inserted as a \\cite{} macro.
993
994A Table of Contents of the entire (multifile) document with browsing
995capabilities is available with `\\[reftex-toc]'.
996
997Most command have help available on the fly. This help is accessed by
998pressing `?' to any prompt mentioning this feature.
999
1000\\{reftex-mode-map}
1001Under X, these functions will be available also in a menu on the menu bar.
1002
1003------------------------------------------------------------------------------"
1004
1005 (interactive "P")
1006 (setq reftex-mode (not (or (and (null arg) reftex-mode)
1007 (<= (prefix-numeric-value arg) 0))))
1008
1009 ; Add or remove the menu, and run the hook
1010 (if reftex-mode
1011 (progn
1012 (easy-menu-add reftex-mode-menu)
1013 (run-hooks 'reftex-mode-hook))
1014 (easy-menu-remove reftex-mode-menu)))
1015
1016(or (assoc 'reftex-mode minor-mode-alist)
1017 (setq minor-mode-alist
1018 (cons '(reftex-mode " Ref") minor-mode-alist)))
1019
1020(or (assoc 'reftex-mode minor-mode-map-alist)
1021 (setq minor-mode-map-alist
1022 (cons (cons 'reftex-mode reftex-mode-map)
1023 minor-mode-map-alist)))
1024
1025
1026;;; ===========================================================================
1027;;;
1028;;; Interfaces for other packages
1029;;; -----------------------------
1030;;;
1031;;; AUCTeX
1032;;; ------
1033
1034(defun reftex-arg-label (optional &optional prompt definition)
1035 "Use reftex-label to create a label and insert it with TeX-argument-insert.
1036This function is intended for AUCTeX macro support."
1037 (let ((label (reftex-label nil t)))
1038 (if (and definition (not (string-equal "" label)))
1039 (LaTeX-add-labels label))
1040 (TeX-argument-insert label optional optional)))
1041
1042(defun reftex-arg-ref (optional &optional prompt definition)
1043 "Use reftex-reference to select a label, insert it with TeX-argument-insert.
1044This function is intended for AUCTeX macro support."
1045 (let ((label (reftex-reference nil t)))
1046 (if (and definition (not (string-equal "" label)))
1047 (LaTeX-add-labels label))
1048 (TeX-argument-insert label optional optional)))
1049
1050(defun reftex-arg-cite (optional &optional prompt definition)
1051 "Use reftex-citation to select a key, insert it with TeX-argument-insert.
1052This function is intended for AUCTeX macro support."
1053 (let ((key (reftex-citation nil t)))
1054 (TeX-argument-insert (or key "") optional optional)))
1055
1056(defvar reftex-label-alist-external-add-ons nil
1057 "List of label alist entries added with reftex-add-to-label-alist.")
1058
1059;;;###autoload
1060(defun reftex-add-to-label-alist (entry-list)
1061 "Add label environment descriptions to reftex-label-alist-external-add-ons.
1062The format of ENTRY-LIST is exactly like reftex-label-alist. See there
1063for details.
1064This function makes it possible to support RefTeX from AUCTeX style files.
1065The entries in ENTRY-LIST will be processed after the user settings in
1066reftex-label-alist, and before the defaults (specified in
1067reftex-default-label-alist-entries). Any changes made to
1068reftex-label-alist-external-add-ons will raise a flag to the effect that a
1069mode reset is done on the next occasion."
1070 (let (entry)
1071 (while entry-list
1072 (setq entry (car entry-list)
1073 entry-list (cdr entry-list))
1074 (if (not (member entry reftex-label-alist-external-add-ons))
1075 (setq reftex-tables-dirty t
1076 reftex-label-alist-external-add-ons
1077 (cons entry reftex-label-alist-external-add-ons))))))
1078
1079;;; ===========================================================================
1080;;;
1081;;; Multifile support
1082;;;
1083;;; Technical notes: Multifile works as follows: We keep just one list
1084;;; of labels for each master file - this can save a lot of memory.
1085;;; reftex-master-index-list is an alist which connects the true file name
1086;;; of each master file with the symbols holding the information on that
1087;;; document. Each buffer has local variables which point to these symbols.
1088
1089
1090;; List of variables which handle the multifile stuff.
1091;; This list is used to tie, untie, and reset these symbols.
1092(defconst reftex-multifile-symbols
1093 '(reftex-label-numbers-symbol reftex-list-of-labels-symbol
1094 reftex-bibfile-list-symbol))
1095
1096;; Alist connecting master file names with the corresponding lisp symbols
1097(defvar reftex-master-index-list nil)
1098
1099;; Last index used for a master file
1100(defvar reftex-multifile-index 0)
1101
1102;; Alist connecting a master file with all included files.
1103;; This information is not yet used, just collected.
1104(defvar reftex-master-include-list nil)
1105
1106;; Variable holding the symbol with current value of label postfix
1107(defvar reftex-label-numbers-symbol nil )
1108(make-variable-buffer-local 'reftex-label-numbers-symbol)
1109
1110;; Variable holding the symbol with the label list of the document.
1111;; Each element of the label list is again a list with the following elements:
1112;; 0: One character label type indicator
1113;; 1: Short context to put into label menu
1114;; 2: The label
1115;; 3: The name of the file where the label is defined
1116(defvar reftex-list-of-labels-symbol nil)
1117(make-variable-buffer-local 'reftex-list-of-labels-symbol)
1118
1119;; Variable holding the symbol with a list of library files for this document
1120(defvar reftex-bibfile-list-symbol nil)
1121(make-variable-buffer-local 'reftex-bibfile-list-symbol)
1122
1123(defun reftex-next-multifile-index ()
1124 ;; Return the next free index for multifile symbols.
1125 (setq reftex-multifile-index (1+ reftex-multifile-index)))
1126
1127(defun reftex-tie-multifile-symbols ()
1128 ;; Tie the buffer-local symbols to globals connected with the master file.
1129 ;; If the symbols for the current master file do not exist, they are created.
1130
1131 (let* ((master (file-truename (reftex-TeX-master-file)))
1132 (index (assoc master reftex-master-index-list))
1133 (symlist reftex-multifile-symbols)
1134 (symbol nil)
1135 (symname nil)
1136 (newflag nil))
1137 ;; find the correct index
1138 (if index
1139 ;; symbols do exist
1140 (setq index (cdr index))
1141 ;; get a new index and add info to the alist
1142 (setq index (reftex-next-multifile-index)
1143 reftex-master-index-list (cons
1144 (cons master index)
1145 reftex-master-index-list)
1146 newflag t))
1147
1148 ;; get/create symbols and tie them
1149 (while symlist
1150 (setq symbol (car symlist)
1151 symlist (cdr symlist)
1152 symname (symbol-name symbol))
1153 (set symbol (intern (concat symname "-" (int-to-string index))))
1154 ;; initialize if new symbols
1155 (if newflag (set (symbol-value symbol) nil)))
1156
1157 ;; Return t if the symbols did already exist, nil when we've made them
1158 (not newflag)))
1159
1160(defun reftex-untie-multifile-symbols ()
1161 ;; Remove ties from multifile symbols, so that next use makes new ones.
1162 (let ((symlist reftex-multifile-symbols)
1163 (symbol nil))
1164 (while symlist
1165 (setq symbol (car symlist)
1166 symlist (cdr symlist))
1167 (set symbol nil))))
1168
1169(defun reftex-TeX-master-file ()
1170 ;; Return the name of the master file associated with the current buffer.
1171 ;; When AUCTeX is loaded, we will use it's more sophisticated method.
1172 ;; We also support the default TeX and LaTeX modes
1173 ;; by checking for a variable tex-main-file.
1174
1175 (let
1176 ((master
1177 (cond
1178 ((fboundp 'TeX-master-file) ; AUCTeX is loaded. Use its mechanism.
1179 (TeX-master-file t))
1180 ((boundp 'TeX-master) ; The variable is defined - lets use it.
1181 (cond
1182 ((eq TeX-master t)
1183 (buffer-file-name))
1184 ((eq TeX-master 'shared)
1185 (setq TeX-master (read-file-name "Master file: "
1186 nil nil t nil)))
1187 (TeX-master)
1188 (t
1189 (setq TeX-master (read-file-name "Master file: "
1190 nil nil t nil)))))
1191 ((boundp 'tex-main-file)
1192 ;; This is the variable from the default TeX modes
1193 (cond
1194 ((stringp tex-main-file)
1195 ;; ok, this must be it
1196 tex-main-file)
1197 (t
1198 ;; In this case, the buffer is its own master
1199 (buffer-file-name))))
1200 (t
1201 ;; Know nothing about master file. Assume this is a master file.
1202 (buffer-file-name)))))
1203 (cond
1204 ((null master)
1205 (error "Need a filename for this buffer. Please save it first."))
1206 ((or (file-exists-p master)
1207 (reftex-get-buffer-visiting master))
1208 ;; We either see the file, or have a buffer on it. OK.
1209 )
1210 ((or (file-exists-p (concat master ".tex"))
1211 (reftex-get-buffer-visiting (concat master ".tex")))
1212 ;; Ahh, an extra .tex was missing...
1213 (setq master (concat master ".tex")))
1214 (t
1215 ;; Something is wrong here. Throw an exception.
1216 (error "No such master file %s" master)))
1217 (expand-file-name master)))
1218
1219(defun reftex-make-master-buffer (master-file mode)
1220 "Make a master buffer which contains the MASTER-FILE and all includes.
1221This is to prepare a buffer containing the entire document in correct
1222sequence for parsing. Therefore it will even expand includes which are
1223commented out.
1224The function returns the number of input/include files not found."
1225
1226 (interactive "fmaster file: ")
1227 (let ((not-found 0) file file-list tmp (font-lock-maximum-size 1))
1228 (switch-to-buffer "*reftex-master.tex*")
1229 (erase-buffer)
1230 (if (not (eq major-mode mode))
1231 (funcall mode))
1232 ;; first insert the master file
1233 (if (not (file-exists-p master-file))
1234 (error "No such master file: %s" master-file))
1235 (reftex-insert-buffer-or-file master-file)
1236 (subst-char-in-region (point-min) (point-max) ?\r ?\n t)
1237 (setq file-list (cons master-file file-list))
1238 (goto-char 1)
1239 ;; remember from which file these lines came
1240 (put-text-property (point-min) (point-max) 'file
1241 (expand-file-name master-file))
1242 ;; Now find recursively all include/input statements and expand them
1243 (while (re-search-forward
1244 "^[ \t]*\\\\\\(include\\|input\\){\\([^}\n]+\\)}" nil t)
1245 ;; Change default directory, so that relative fine names work correctly
1246 (setq file (reftex-no-props (match-string 2)))
1247 (save-match-data
1248 (cd (file-name-directory
1249 (get-text-property (match-beginning 0) 'file)))
1250 (if (not (string-match "\\.tex$" file))
1251 (setq file (concat file ".tex"))))
1252 (if (file-exists-p file)
1253 (progn
1254 (replace-match
1255 (format "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% START OF %s FILE: %s\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% END OF %s FILE: %s\n"
1256 (match-string 1) file
1257 (match-string 1) file))
1258 (beginning-of-line 0)
1259 (narrow-to-region (point) (point))
1260 ;; insert the file
1261 (reftex-insert-buffer-or-file file)
1262 (subst-char-in-region (point-min) (point-max) ?\r ?\n t)
1263 (setq file-list (cons (expand-file-name file) file-list))
1264 ;; remember from which file these lines came
1265 (put-text-property (point-min) (point-max)
1266 'file (expand-file-name file))
1267 (goto-char (point-min))
1268 (widen))
1269 (message "Input/include file %s not found. Ignored. Continuing..."
1270 file)
1271 (setq not-found (1+ not-found))))
1272 (setq file-list (nreverse file-list))
1273 (while (setq tmp (assoc (car file-list) reftex-master-include-list))
1274 (setq reftex-master-include-list (delq tmp reftex-master-include-list)))
1275 (setq reftex-master-include-list (cons file-list reftex-master-include-list))
1276 not-found))
1277
1278(defun reftex-insert-buffer-or-file (file)
1279 "If there is a buffer associated with FILE, insert it - otherwise the FILE."
1280 (let ((buffer (reftex-get-buffer-visiting file)))
1281 (if buffer
1282 (let (beg end beg1 end1)
1283 (save-excursion
1284 ;; make sure we get the whole buffer
1285 (set-buffer buffer)
1286 (setq beg (point-min) end (point-max))
1287 (widen)
1288 (setq beg1 (point-min) end1 (point-max)))
1289 (insert-buffer-substring buffer beg1 end1)
1290 (save-excursion
1291 (set-buffer buffer)
1292 (narrow-to-region beg end)))
1293 (insert-file-contents file))))
1294
1295
1296(defun reftex-parse-document (&optional buffer)
1297 "Rescan the document."
1298 (interactive)
1299 (save-window-excursion
1300 (save-excursion
1301 (if buffer
1302 (if (not (bufferp buffer))
1303 (error "No such buffer %s" (buffer-name buffer))
1304 (set-buffer buffer)))
1305 (reftex-access-scan-info t))))
1306
1307(defun reftex-access-scan-info (&optional rescan)
1308 ;; Access the scanning info. When the multifile symbols are not yet tied,
1309 ;; tie them. When they are have to be created, do a buffer scan to
1310 ;; fill them.
1311
1312 ;; If RESCAN is non-nil, enforce document scanning
1313
1314 (catch 'exit
1315 (let ((rescan (or (equal rescan t) (equal rescan '(4)))))
1316
1317 ;; Reset the mode if we had changes from style hooks
1318 (and reftex-tables-dirty
1319 (reftex-reset-mode))
1320
1321 (if (eq reftex-list-of-labels-symbol nil)
1322 ;; Symbols are not yet tied: Tie them and see if they are set
1323 (reftex-tie-multifile-symbols))
1324
1325 (if (and (symbol-value reftex-list-of-labels-symbol)
1326 (not rescan))
1327 ;; Lists do already exist and we don't need to rescan.
1328 ;; Return from here.
1329 (throw 'exit t))
1330
1331 ;; We need to rescan
1332 ;; =================
1333
1334 (unwind-protect
1335 (save-window-excursion
1336 (save-excursion
1337
1338 ;; do the scanning
1339
1340 (let ((label-list-symbol reftex-list-of-labels-symbol)
1341 (label-numbers-symbol reftex-label-numbers-symbol)
1342 (bibfile-list-symbol reftex-bibfile-list-symbol))
1343
1344 (message "Creating master buffer...")
1345 (reftex-make-master-buffer (reftex-TeX-master-file) major-mode)
1346
1347 (message "Scanning document...")
1348
1349 (reftex-scan-buffer-for-labels
1350 label-numbers-symbol label-list-symbol)
1351
1352 (reftex-scan-buffer-for-bibliography-statement
1353 bibfile-list-symbol)
1354
1355 (message "Scanning document... done"))))
1356
1357 (if (get-buffer "*reftex-master.tex*")
1358 (kill-buffer "*reftex-master.tex*"))))))
1359
1360(defun reftex-create-tags-file ()
1361 "Create TAGS file by running `etags' on the current document.
1362The TAGS file is also immediately visited with `visit-tags-table."
1363 (interactive)
1364 (reftex-access-scan-info current-prefix-arg)
1365 (let* ((master (reftex-TeX-master-file))
1366 (files (assoc master reftex-master-include-list))
1367 (cmd (format "etags %s" (mapconcat 'identity files " "))))
1368 (save-excursion
1369 (set-buffer (reftex-get-buffer-visiting master))
1370 (message "Running etags to create TAGS file...")
1371 (shell-command cmd)
1372 (visit-tags-table "TAGS"))))
1373
1374;; History of grep commands.
1375(defvar reftex-grep-history nil)
1376(defvar reftex-grep-command "grep -n "
1377 "Last grep command used in \\[reftex-grep-document]; default for next grep.")
1378
1379(defun reftex-grep-document (grep-cmd)
1380 "Run grep query through all files related to this document.
1381With prefix arg, force to rescan document.
1382This works also without an active TAGS table."
1383
1384 (interactive
1385 (list (read-from-minibuffer "Run grep on document (like this): "
1386 reftex-grep-command nil nil
1387 'reftex-grep-history)))
1388 (reftex-access-scan-info current-prefix-arg)
1389 (let* ((master (reftex-TeX-master-file))
1390 (default-directory (file-name-directory master))
1391 (re (format "\\`%s\\(.*\\)" (regexp-quote
1392 (expand-file-name default-directory))))
1393 (files (assoc master reftex-master-include-list))
1394 (cmd (format
1395 "%s %s" grep-cmd
1396 (mapconcat (function (lambda (x)
1397 (if (string-match re x)
1398 (match-string 1 x)
1399 x)))
1400 files " "))))
1401 (grep cmd)))
1402
1403(defun reftex-search-document (&optional regexp)
1404 "Regexp search through all files of the current TeX document.
1405Starts always in the master file. Stops when a match is found.
1406To continue searching for next match, use command \\[tags-loop-continue].
1407This works also without an active TAGS table."
1408 (interactive)
1409 (let ((default (reftex-this-word)))
1410 (if (not regexp)
1411 (setq regexp (read-string (format "Search regexp in document [%s]: "
1412 default))))
1413 (if (string= regexp "") (setq regexp (regexp-quote default)))
1414
1415 (reftex-access-scan-info current-prefix-arg)
1416 (tags-search regexp (list 'assoc (reftex-TeX-master-file)
1417 'reftex-master-include-list))))
1418
1419(defun reftex-query-replace-document (&optional from to delimited)
1420 "Run a query-replace-regexp of FROM with TO over the entire TeX document.
1421Third arg DELIMITED (prefix arg) means replace only word-delimited matches.
1422If you exit (\\[keyboard-quit] or ESC), you can resume the query replace
1423with the command \\[tags-loop-continue].
1424This works also without an active TAGS table."
1425 (interactive)
1426 (let ((default (reftex-this-word)))
1427 (if (not from)
1428 (progn
1429 (setq from (read-string (format "Replace regexp in document [%s]: "
1430 default)))
1431 (if (string= from "") (setq from (regexp-quote default)))))
1432 (if (not to)
1433 (setq to (read-string (format "Replace regexp %s with: " from))))
1434 (reftex-access-scan-info current-prefix-arg)
1435 (tags-query-replace from to (or delimited current-prefix-arg)
1436 (list 'assoc (reftex-TeX-master-file)
1437 'reftex-master-include-list))))
1438
1439(defun reftex-change-label (&optional from to)
1440 "Query replace FROM with TO in all \\label{} and \\ref{} commands.
1441Works on the entire multifile document.
1442If you exit (\\[keyboard-quit] or ESC), you can resume the query replace
1443with the command \\[tags-loop-continue].
1444This works also without an active TAGS table."
1445 (interactive)
1446 (let ((default (reftex-this-word "-a-zA-Z0-9_*.:")))
1447 (if (not from)
1448 (setq from (read-string (format "Replace label globally [%s]: "
1449 default))))
1450 (if (string= from "") (setq from default))
1451 (if (not to)
1452 (setq to (read-string (format "Replace label %s with: "
1453 from))))
1454 (reftex-query-replace-document
1455 (concat "\\\\\\(label\\|[a-z]*ref\\){" (regexp-quote from) "}")
1456 (format "\\\\\\1{%s}" to))))
1457
1458(defun reftex-this-word (&optional class)
1459;; grab the word around point
1460 (setq class (or class "-a-zA-Z0-9:_/.*;|"))
1461 (save-excursion
1462 (buffer-substring-no-properties
1463 (progn (skip-chars-backward class) (point))
1464 (progn (skip-chars-forward class) (point)))))
1465
1466;;; ===========================================================================
1467;;;
1468;;; Functions to create and reference automatic labels
1469
1470;; The following constants are derived from reftex-label-alist
1471
1472;; Prompt used for label type querys directed to the user
1473(defconst reftex-type-query-prompt nil)
1474
1475;; Help string for label type querys
1476(defconst reftex-type-query-help nil)
1477
1478;; Alist relating label type to reference format
1479(defconst reftex-typekey-to-format-alist nil)
1480
1481;; Alist relating label type to label affix
1482(defconst reftex-typekey-to-prefix-alist nil)
1483
1484;; Alist relating environments or macros to label type and context regexp
1485(defconst reftex-env-or-mac-alist nil)
1486
1487;; List of macros carrying a label
1488(defconst reftex-label-mac-list nil)
1489
1490;; List of environments carrying a label
1491(defconst reftex-label-env-list nil)
1492
1493;; List of all typekey letters in use
1494(defconst reftex-typekey-list nil)
1495
1496;; Alist relating magic words to a label type
1497(defconst reftex-words-to-typekey-alist nil)
1498
1499;; The last list-of-labels entry used in a reference
1500(defvar reftex-last-used-reference (list nil nil nil nil))
1501
1502;; The regular expression used to abbreviate words
1503(defconst reftex-abbrev-regexp
1504 (concat
1505 "^\\("
1506 (make-string (nth 0 reftex-abbrev-parameters) ?.)
1507 "[" (nth 2 reftex-abbrev-parameters) "]*"
1508 "\\)"
1509 "[" (nth 3 reftex-abbrev-parameters) "]"
1510 (make-string (1- (nth 1 reftex-abbrev-parameters)) ?.)))
1511
1512;; Global variables used for communication between functions
1513(defvar reftex-default-context-position nil)
1514(defvar reftex-location-start nil)
1515(defvar reftex-call-back-to-this-buffer nil)
1516
1517;; List of buffers created temporarily for lookup, which should be killed
1518(defvar reftex-buffers-to-kill nil)
1519
1520;; The regexp used to find section statements
1521(defconst reftex-section-regexp "^[ ]*\\\\\\(part\\|chapter\\|section\\|subsection\\|subsubsection\\|paragraph\\|subparagraph\\|subsubparagraph\\)\\*?\\(\\[[^]]*\\]\\)?{")
1522
1523;; LaTeX section commands and level numbers
1524(defconst reftex-section-levels
1525 '(
1526 ("part" . 0)
1527 ("chapter" . 1)
1528 ("section" . 2)
1529 ("subsection" . 3)
1530 ("subsubsection" . 4)
1531 ("paragraph" . 5)
1532 ("subparagraph" . 6)
1533 ("subsubparagraph" . 7)
1534 ))
1535
1536(defun reftex-label (&optional environment no-insert)
1537 "Insert a unique label. Return the label.
1538If ENVIRONMENT is given, don't bother to find out yourself.
1539If NO-INSERT is non-nil, do not insert label into buffer.
1540With prefix arg, force to rescan document first.
1541The label is also inserted into the label list.
1542This function is controlled by the settings of reftex-insert-label-flags."
1543
1544 (interactive)
1545
1546 ;; Ensure access to scanning info and rescan buffer if prefix are is '(4)
1547 (reftex-access-scan-info current-prefix-arg)
1548
1549 ;; Find out what kind of environment this is and abort if necessary
1550 (if (or (not environment)
1551 (not (assoc environment reftex-env-or-mac-alist)))
1552 (setq environment (reftex-label-location)))
1553 (if (not environment)
1554 (error "Can't figure out what kind of label should be inserted"))
1555
1556 ;; Ok, go ahead
1557 (let (label num typekey prefix entry cell lab valid default force-prompt)
1558 (setq typekey (nth 1 (assoc environment
1559 reftex-env-or-mac-alist)))
1560 (setq prefix (or (cdr (assoc typekey reftex-typekey-to-prefix-alist))
1561 (concat typekey "-")))
1562
1563 ;; make a default label
1564 (cond
1565
1566 ((reftex-typekey-check typekey (nth 0 reftex-insert-label-flags))
1567 ;; derive a label from context
1568 (setq default (nth 2 (reftex-label-info " ")))
1569 ;; catch the cases where the is actually no context available
1570 (if (or (string-match "NO MATCH FOR CONTEXT REGEXP" default)
1571 (string-match "ILLEGAL VALUE OF PARSE" default)
1572 (string-match "SECTION HEADING NOT FOUND" default)
1573 (string-match "HOOK ERROR" default)
1574 (string-match "^[ \t]*$" default))
1575 (setq default prefix
1576 force-prompt t) ; need to prompt
1577 (setq default (concat prefix (reftex-string-to-label default)))
1578
1579 ;; make it unique
1580 (setq label default)
1581 (setq num 1)
1582 (while (assoc label (symbol-value reftex-list-of-labels-symbol))
1583 (setq label (concat default "-" (setq num (1+ num)))))
1584 (setq default label)))
1585
1586 ((reftex-typekey-check typekey (nth 1 reftex-insert-label-flags)) ; prompt
1587 ;; Minimal default: the user will be prompted
1588 (setq default prefix))
1589
1590 (t
1591 ;; make an automatic label
1592 (while (assoc
1593 (setq default (concat prefix (reftex-next-label-number typekey)))
1594 (symbol-value reftex-list-of-labels-symbol)))))
1595
1596 ;; Should we ask the user?
1597 (if (or (reftex-typekey-check typekey
1598 (nth 1 reftex-insert-label-flags)) ; prompt
1599 force-prompt)
1600
1601 (while (not valid)
1602 ;; iterate until we get a legal label
1603
1604 (setq label (read-string "Label: " default))
1605
1606 ;; Lets make sure that this is a legal label
1607 (cond
1608
1609 ;; Test if label contains strange characters
1610 ((string-match reftex-label-illegal-re label)
1611 (message "Label \"%s\" contains illegal characters" label)
1612 (ding)
1613 (sit-for 2))
1614
1615 ;; Look it up in the label list
1616 ((setq entry (assoc label
1617 (symbol-value reftex-list-of-labels-symbol)))
1618 (message "Label \"%s\" exists in file %s" label (nth 3 entry))
1619 (ding)
1620 (sit-for 2))
1621
1622 ;; Label is ok
1623 (t
1624 (setq valid t))))
1625 (setq label default))
1626
1627 ;; Insert the label
1628 (if (not no-insert)
1629 (insert "\\label{" label "}"))
1630
1631 ;; Insert the label into the label list
1632 (if (symbol-value reftex-list-of-labels-symbol)
1633 (let ((cnt 0)
1634 (pos (point))
1635 (all (symbol-value reftex-list-of-labels-symbol))
1636 (look-for nil)
1637 (note nil)
1638 (text nil)
1639 (file (buffer-file-name)))
1640
1641 ;; find the previous label in order to know where to insert new label
1642 ;; into label list
1643 (save-excursion
1644 (if (re-search-backward "\\\\label{\\([^}]+\\)}" nil 1 2)
1645 (setq look-for (reftex-no-props (match-string 1))))
1646 (if (or (re-search-forward
1647 "\\\\\\(include\\|input\\){[^}\n]+}" pos t)
1648 (re-search-forward reftex-section-regexp pos t)
1649 (null look-for))
1650 (setq note "POSITION UNCERTAIN. RESCAN TO FIX.")))
1651 (if (not look-for)
1652 (set reftex-list-of-labels-symbol
1653 (cons (list label typekey text file note)
1654 (symbol-value reftex-list-of-labels-symbol)))
1655 (while all
1656 (setq cell (car all)
1657 all (cdr all)
1658 cnt (1+ cnt)
1659 lab (nth 0 cell))
1660 (if (string= lab look-for)
1661 (progn
1662 (setcdr
1663 (nthcdr (1- cnt)
1664 (symbol-value reftex-list-of-labels-symbol))
1665 (cons (list label typekey text file note)
1666 (nthcdr
1667 cnt (symbol-value reftex-list-of-labels-symbol))))
1668 ;; to end the loop, set all to nil
1669 (setq all nil)))))))
1670 ;; return value of the function is the label
1671 label))
1672
1673(defun reftex-string-to-label (string)
1674 ;; Convert a string (a sentence) to a label.
1675 ;;
1676 ;; Uses reftex-derive-label-parameters and reftex-abbrev-parameters
1677 ;;
1678
1679 (let* ((words0 (reftex-split "[- \t\n\r]+"
1680 (reftex-no-props string)))
1681 (ignore-words (nth 5 reftex-derive-label-parameters))
1682 words word)
1683
1684 ;; remove words from the ignore list or with funny characters
1685 (while words0
1686 (setq word (car words0) words0 (cdr words0))
1687 (cond
1688 ((member (downcase word) ignore-words))
1689 ((string-match reftex-label-illegal-re word)
1690 (if (nth 2 reftex-derive-label-parameters)
1691 (progn
1692 (while (string-match reftex-label-illegal-re word)
1693 (setq word (replace-match "" nil nil word)))
1694 (setq words (cons word words)))))
1695 (t
1696 (setq words (cons word words)))))
1697 (setq words (nreverse words))
1698
1699 ;; restrict number of words
1700 (if (> (length words) (nth 0 reftex-derive-label-parameters))
1701 (setcdr (nthcdr (1- (nth 0 reftex-derive-label-parameters)) words) nil))
1702
1703 ;; First, try to use all words
1704 (setq string (mapconcat '(lambda(w) w) words
1705 (nth 4 reftex-derive-label-parameters)))
1706
1707 ;; Abbreviate words if enforced by user settings or string length
1708 (if (or (eq t (nth 3 reftex-derive-label-parameters))
1709 (and (nth 3 reftex-derive-label-parameters)
1710 (> (length string) (nth 1 reftex-derive-label-parameters))))
1711 (setq words
1712 (mapcar
1713 '(lambda (w) (if (string-match reftex-abbrev-regexp w)
1714 (match-string 1 w)
1715 w))
1716 words)
1717 string (mapconcat '(lambda(w) w) words
1718 (nth 4 reftex-derive-label-parameters))))
1719
1720 ;; Shorten if still to long
1721 (setq string
1722 (if (> (length string) (nth 1 reftex-derive-label-parameters))
1723 (substring string 0 (nth 1 reftex-derive-label-parameters))
1724 string))
1725
1726 ;; Delete the final punctuation, if any
1727 (if (string-match "[^a-zA-Z0-9]+$" string)
1728 (setq string (replace-match "" nil nil string)))
1729 string))
1730
1731(defun reftex-label-location (&optional bound)
1732 ;; Return the environment or macro which determines the label type at point.
1733 ;; If optional BOUND is an integer, limit backward searches to that point.
1734
1735 (let* ((loc1 (reftex-what-macro reftex-label-mac-list bound))
1736 (loc2 (reftex-what-environment reftex-label-env-list bound))
1737 (p1 (or (cdr loc1) 0))
1738 (p2 (or (cdr loc2) 0)))
1739
1740 (setq reftex-location-start (max p1 p2))
1741 (if (> p1 p2)
1742 (progn
1743 (setq reftex-default-context-position p1)
1744 (car loc1))
1745 (setq reftex-default-context-position
1746 (+ p2 8 (length (car loc2))))
1747 (or (car loc2) "section"))))
1748
1749
1750(defun reftex-next-label-number (type)
1751 ;; Increment value of automatic labels in current buffer. Return new value.
1752
1753 ;; Ensure access to scanning info
1754 (reftex-access-scan-info)
1755
1756 (let ((n (cdr (assoc type (symbol-value reftex-label-numbers-symbol)))))
1757 (if (not (integerp n))
1758 ;; oops - type not known - make one here
1759 (progn
1760 (set reftex-label-numbers-symbol
1761 (cons (cons type 0)
1762 (symbol-value reftex-label-numbers-symbol)))
1763 (setq n 0)))
1764 (setq n (1+ n))
1765 (setcdr (assoc type (symbol-value reftex-label-numbers-symbol)) n)
1766 n))
1767
1768;; Help string for the reference label menu
1769(defconst reftex-reference-label-help
1770 " AVAILABLE KEYS IN REFERENCE LABEL MENU
1771 ======================================
1772 n / p Go to next/previous label (Cursor motion works as well)
1773 r / s Rescan document for labels / Switch label type
1774 t / # Toggle table of contents / Toggle counter mode
1775 c Toggle display of short context
1776 SPACE Show full context for current label in other window
1777 f Toggle follow mode: other window will follow context
1778 a / q Use last referenced label / Quit without accepting label
1779 ? / C-r Display this help message / Recursive Edit into other window
1780 RETURN Accept current label")
1781
1782(defun reftex-reference (&optional type no-insert)
1783 "Make a LaTeX reference. Look only for labels of a certain TYPE.
1784With prefix arg, force to rescan buffer for labels. This should only be
1785necessary if you have recently entered labels yourself without using
1786reftex-label. Rescanning of the buffer can also be requested from the
1787label selection menu.
1788The function returns the selected label or nil.
1789If NO-INSERT is non-nil, do not insert \\ref{} command, just return label.
1790When called with 2 C-u prefix args, disable magic word recognition."
1791
1792 (interactive)
1793
1794 ;; check for active recursive edits
1795 (reftex-check-recursive-edit)
1796
1797 ;; Ensure access to scanning info and rescan buffer if prefix are is '(4)
1798 (reftex-access-scan-info current-prefix-arg)
1799
1800 (if (not type)
1801 ;; guess type from context
1802 (if (and reftex-guess-label-type
1803 (not (= 16 (prefix-numeric-value current-prefix-arg)))
1804 (setq type (assoc (downcase (reftex-word-before-point))
1805 reftex-words-to-typekey-alist)))
1806 (setq type (cdr type))
1807 (setq type (reftex-query-label-type))))
1808
1809 (let (label pair
1810 (form (or (cdr (assoc type reftex-typekey-to-format-alist))
1811 "\\ref{%s}")))
1812
1813 ;; Have the user select a label
1814 (setq pair (reftex-offer-label-menu type))
1815 (setq label (car pair))
1816
1817 (if (and label
1818 (not no-insert))
1819 (progn
1820 ;; do we need to remove spaces?
1821 (if (string= "~" (substring form 0 1))
1822 (while (or (= (preceding-char) ?\ )
1823 (= (preceding-char) ?\C-i))
1824 (backward-delete-char 1)))
1825 ;; ok, insert the reference
1826 (insert (format form label label))
1827 (message ""))
1828 (message "Quit"))
1829 ;; return the label
1830 label))
1831
1832(defun reftex-goto-label (&optional arg)
1833 "Go to a LaTeX label. With prefix ARG: go to label in another window."
1834 (interactive "P")
1835 (let (type label file pair)
1836 (if (not type)
1837 (setq type (reftex-query-label-type)))
1838
1839 (setq pair (reftex-offer-label-menu type)
1840 label (car pair)
1841 file (cdr pair))
1842 (if (and label file (file-exists-p file))
1843 (progn
1844 (if arg
1845 (find-file-other-window file)
1846 (find-file file))
1847 (goto-char (point-min))
1848 (if (not (search-forward (concat "\\label{" label "}") nil t))
1849 (error "No such label found: %s" label)
1850 (reftex-highlight 0 (match-beginning 0) (match-end 0))
1851 (add-hook 'pre-command-hook 'reftex-highlight-shall-die)))
1852 (message "Quit")
1853 nil)))
1854
1855;; Internal list with index numbers of labels in the selection menu
1856(defvar reftex-label-index-list nil)
1857
1858(defun reftex-offer-label-menu (typekey)
1859 ;; Offer a menu with the appropriate labels. Return (label . file).
1860 (let* ((buf (current-buffer))
1861 (near-label (reftex-find-nearby-label))
1862 (toc (reftex-typekey-check typekey reftex-label-menu-flags 0))
1863 (context (not (reftex-typekey-check
1864 typekey reftex-label-menu-flags 3)))
1865 (counter (reftex-typekey-check
1866 typekey reftex-label-menu-flags 2))
1867 (follow (reftex-typekey-check
1868 typekey reftex-label-menu-flags 4))
1869 offset rtn key cnt entry)
1870
1871 (setq reftex-call-back-to-this-buffer buf)
1872 (setq entry (cons nil nil))
1873
1874 (unwind-protect
1875 (catch 'exit
1876 (while t
1877 (save-window-excursion
1878 (switch-to-buffer-other-window "*RefTeX Select*")
1879 (erase-buffer)
1880 (setq truncate-lines t)
1881 (setq reftex-label-index-list (reftex-make-and-insert-label-list
1882 typekey buf toc context counter
1883 near-label))
1884 (setq near-label "_ ") ; turn off search for near label
1885 (setq offset (or (car reftex-label-index-list) offset))
1886 ;; use only when searched
1887 (setq reftex-label-index-list (cdr reftex-label-index-list))
1888 ;; only this is the true list
1889 (if (not reftex-label-index-list)
1890 (error "No labels of type \"%s\"" typekey))
1891 (setq rtn
1892 (reftex-select-item
1893 nil
1894 "Label: [n]ext [p]rev [r]escan [t]oc [ ]context [q]uit RETURN [?]HELP+more"
1895 "^>"
1896 "\n[^.]"
1897 2
1898 reftex-reference-label-help
1899 '(?r ?c ?t ?s ?# ?a)
1900 offset
1901 'reftex-select-label-callback follow))
1902 (setq key (car rtn)
1903 cnt (cdr rtn)
1904 offset (1+ cnt))
1905 (if (not key) (throw 'exit nil))
1906 (cond
1907 ((equal key ?r)
1908 ;; rescan buffer
1909 (reftex-parse-document buf))
1910 ((equal key ?c)
1911 ;; toggle context mode
1912 (setq context (not context)))
1913 ((equal key ?s)
1914 ;; switch type
1915 (setq typekey (reftex-query-label-type)))
1916 ((equal key ?t)
1917 ;; toggle tabel of contents display
1918 (setq toc (not toc)))
1919 ((equal key ?#)
1920 ;; toggle counter display
1921 (setq counter (not counter)))
1922 ((equal key ?a)
1923 ;; reuse the last referenced label again
1924 (setq entry reftex-last-used-reference)
1925 (throw 'exit t))
1926 (t
1927 (set-buffer buf)
1928 (setq entry (nth (nth cnt reftex-label-index-list)
1929 (symbol-value reftex-list-of-labels-symbol)))
1930 (setq reftex-last-used-reference entry)
1931 (throw 'exit t))))))
1932 (kill-buffer "*RefTeX Select*")
1933 (reftex-kill-temporary-buffers))
1934 (cons (reftex-no-props (nth 0 entry)) (nth 3 entry))))
1935
1936;; Indentation for table of context lines in the menu
1937(defconst reftex-toc-indent " ")
1938;; Indentation for the lines containing the label
1939(defconst reftex-label-indent "> ")
1940;; Indentation for context lines
1941(defconst reftex-context-indent ". ")
1942;; Indentation per section level
1943(defvar reftex-level-indent 2
1944 "*Number of spaces to be used for indentation per section level.
1945With more indentation, the label menu looks nicer, but shows less context.
1946Changing this is only fully operational after the next buffer scan.")
1947
1948(defun reftex-make-and-insert-label-list (typekey0 buf toc context
1949 counter near-label)
1950 ;; Insert a menu of all labels in buffer BUF into current buffer.
1951 ;; Return the list of labels, with the index of NEAR-LABEL as extra car.
1952 (let (ins-list index-list offset)
1953 (save-excursion
1954 (set-buffer buf)
1955 (let* ((all nil)
1956 (font (reftex-use-fonts))
1957 (cnt 0)
1958 (file nil)
1959 (index -1)
1960 (toc-indent reftex-toc-indent)
1961 (label-indent
1962 (concat reftex-label-indent
1963 (if toc (make-string (* 7 reftex-level-indent) ?\ ) "")))
1964 (context-indent
1965 (concat reftex-context-indent
1966 (if toc (make-string (* 7 reftex-level-indent) ?\ ) "")))
1967 cell text label typekey note comment)
1968
1969 ; Ensure access to scanning info
1970 (reftex-access-scan-info)
1971
1972 (setq all (symbol-value reftex-list-of-labels-symbol))
1973
1974 (while all
1975
1976 (setq index (1+ index)
1977 cell (car all)
1978 all (cdr all))
1979
1980 (if (null (nth 2 cell))
1981 ;; No context yet. Quick update
1982 (progn
1983 (setq cell (reftex-label-info-update cell))
1984 (setcar (nthcdr index
1985 (symbol-value reftex-list-of-labels-symbol))
1986 cell)))
1987
1988 ;; in the following setq we *copy* the label, since we will change
1989 ;; its properties, and we cannot have any properties in the list
1990 ;; (because of assoc searches)
1991 (setq label (copy-sequence (nth 0 cell))
1992 typekey (nth 1 cell)
1993 text (nth 2 cell)
1994 file (nth 3 cell)
1995 note (nth 4 cell)
1996 comment (get-text-property 0 'in-comment text))
1997
1998 (if (string= label near-label)
1999 (setq offset (1+ cnt)))
2000
2001 (cond
2002 ((and toc (string= typekey "toc"))
2003 (setq ins-list
2004 (cons (concat toc-indent text "\n")
2005 ins-list)))
2006 ((string= typekey "toc"))
2007 ((and (or (string= typekey typekey0) (string= typekey0 " "))
2008 (or (nth 5 reftex-label-menu-flags) ; show-commented?
2009 (null comment)))
2010 (setq cnt (1+ cnt))
2011 (if comment (setq label (concat "% " label)))
2012 (if font
2013 (put-text-property
2014 0 (length label)
2015 'face
2016 (if comment
2017 'font-lock-comment-face
2018 'font-lock-reference-face)
2019 label))
2020 (setq index-list (cons index index-list))
2021 (setq ins-list
2022 (cons (concat
2023 label-indent
2024 label
2025 (if counter (format " (%d) " cnt))
2026 (if comment " LABEL IS COMMENTED OUT ")
2027 (if note (concat " " note) "")
2028 "\n"
2029 (if context (concat context-indent text "\n")))
2030 ins-list))))
2031 )))
2032
2033 (apply 'insert (nreverse ins-list))
2034 (cons offset (nreverse index-list))))
2035
2036(defun reftex-query-label-type ()
2037 ;; Ask for label type
2038 (message reftex-type-query-prompt)
2039 (let ((key (read-char)))
2040 (if (equal key ?\?)
2041 (progn
2042 (save-window-excursion
2043 (with-output-to-temp-buffer "*RefTeX Help*"
2044 (princ reftex-type-query-help))
2045 (setq key (read-char))
2046 (kill-buffer "*RefTeX Help*"))))
2047 (if (not (member (char-to-string key) reftex-typekey-list))
2048 (error "No such label type: %s" (char-to-string key)))
2049 (char-to-string key)))
2050
2051(defun reftex-find-nearby-label ()
2052 ;; Find a nearby label.
2053 (save-excursion
2054 (if (or (re-search-backward "\\\\label{\\([^}]+\\)}" nil t)
2055 (re-search-forward "\\\\label{\\([^}]+\\)}" nil t))
2056 (reftex-no-props (match-string 1))
2057 nil)))
2058
2059;; Variable holding the vector with section numbers
2060(defvar reftex-section-numbers [0 0 0 0 0 0 0 0])
2061
2062(defun reftex-scan-buffer-for-labels (label-numbers-symbol label-list-symbol)
2063 ;; Scan the buffer for labels and save them in a list.
2064 (save-excursion
2065 (let ((regexp (concat "\\\\label{\\([^}]*\\)}" "\\|"
2066 reftex-section-regexp))
2067 (font (reftex-use-fonts))
2068 (bound 0)
2069 (highest-level 100)
2070 file (level 1) start star text text1 label section-number macro find)
2071 (set label-list-symbol nil)
2072 (goto-char 0)
2073
2074 ;; reset label numbers
2075 (set label-numbers-symbol
2076 (mapcar '(lambda(x) (cons x 0)) reftex-typekey-list))
2077
2078 ;; reset section numbers
2079 (reftex-section-number reftex-section-numbers -1)
2080
2081 (while (re-search-forward regexp nil t)
2082 (setq file (get-text-property (match-beginning 0) 'file))
2083 (if (string= (buffer-substring (match-beginning 0)
2084 (+ 7 (match-beginning 0))) "\\label{")
2085 ;; It is a label
2086 (progn
2087 (setq label (reftex-no-props (match-string 1)))
2088 (set label-list-symbol
2089 (cons (reftex-label-info label file bound)
2090 (symbol-value label-list-symbol))))
2091
2092 ;; It is a section
2093 (setq bound (point))
2094 (setq star (= ?* (char-after (match-end 2))))
2095 (setq find (buffer-substring-no-properties
2096 (1- (match-beginning 2)) (match-end 0)))
2097 (setq macro (reftex-no-props (match-string 2)))
2098 (setq level (cdr (assoc macro reftex-section-levels)))
2099
2100 (setq section-number (reftex-section-number
2101 reftex-section-numbers level star))
2102 (setq highest-level (min highest-level level))
2103 (if (= level highest-level)
2104 (message
2105 "Scanning %s %s ..."
2106 (car (nth level reftex-section-levels))
2107 section-number))
2108
2109 ;; get the title
2110 (save-match-data
2111 (setq text1 (reftex-context-substring))
2112 (setq text (reftex-nicify-text text1)))
2113
2114 (setq find (reftex-allow-for-ctrl-m (concat find text1)))
2115
2116 ;; add section number and indentation
2117 (setq text
2118 (concat
2119 (make-string (* reftex-level-indent level) ?\ )
2120 (if (nth 1 reftex-label-menu-flags) ; section number flag
2121 (concat section-number " "))
2122 text))
2123 ;; fontify
2124 (if font (put-text-property 0 (length text)
2125 'face 'font-lock-comment-face text))
2126
2127 ;; insert in list
2128 (set label-list-symbol
2129 (cons (list nil "toc" text file find)
2130 (symbol-value label-list-symbol)))))
2131 (set label-list-symbol
2132 (nreverse (symbol-value label-list-symbol))))))
2133
2134
2135(defun reftex-label-info-update (cell)
2136 ;; Update information about just one label in a different file.
2137 ;; CELL contains the old info list
2138 (let* ((label (nth 0 cell))
2139 (typekey (nth 1 cell))
2140 (text (nth 2 cell))
2141 (file (nth 3 cell))
2142 (note (nth 4 cell))
2143 (buf (reftex-get-file-buffer-force
2144 file (not reftex-keep-temporary-buffers))))
2145 (if (not buf)
2146 (list label typekey "" file "LOST LABEL. RESCAN TO FIX.")
2147 (save-excursion
2148 (set-buffer buf)
2149 (save-restriction
2150 (widen)
2151 (goto-char 1)
2152
2153 (if (re-search-forward (concat "\\\\label{" (regexp-quote label) "}")
2154 nil t)
2155 (append (reftex-label-info label file) (list note))
2156 (list label typekey "" file "LOST LABEL. RESCAN TO FIX.")))))))
2157
2158(defun reftex-label-info (label &optional file bound)
2159 ;; Return info list on LABEL at point.
2160 (let* ((env-or-mac (reftex-label-location bound))
2161 (typekey (nth 1 (assoc env-or-mac reftex-env-or-mac-alist)))
2162 (file (or file (buffer-file-name)))
2163 (parse (if (reftex-typekey-check
2164 typekey reftex-use-text-after-label-as-context)
2165 nil
2166 (nth 2 (assoc env-or-mac reftex-env-or-mac-alist))))
2167 (text (reftex-short-context env-or-mac parse reftex-location-start)))
2168 (if (reftex-in-comment)
2169 (put-text-property 0 1 'in-comment t text))
2170 (list label typekey text file)))
2171
2172(defun reftex-in-comment ()
2173 (save-excursion
2174 (skip-chars-backward "^%\n\r")
2175 (= (preceding-char) ?%)))
2176
2177(defun reftex-short-context (env parse &optional bound)
2178 ;; Get about one line of useful context for the label definition at point.
2179
2180 (reftex-nicify-text
2181
2182 (cond
2183
2184 ((null parse)
2185 (save-excursion
2186 (reftex-context-substring)))
2187
2188 ((eq parse t)
2189 (if (string= env "section")
2190 ;; special treatment for section labels
2191 (save-excursion
2192 (if (re-search-backward reftex-section-regexp (point-min) t)
2193 (progn
2194 (goto-char (match-end 0))
2195 (reftex-context-substring))
2196 "SECTION HEADING NOT FOUND"))
2197 (save-excursion
2198 (goto-char reftex-default-context-position)
2199 (reftex-context-substring))))
2200
2201 ((stringp parse)
2202 (save-excursion
2203 (if (re-search-backward parse bound t)
2204 (progn
2205 (goto-char (match-end 0))
2206 (reftex-context-substring))
2207 "NO MATCH FOR CONTEXT REGEXP")))
2208 ((fboundp parse)
2209 ;; A hook function. Call it.
2210 (save-excursion
2211 (condition-case error-var
2212 (funcall parse env)
2213 ('error (format "HOOK ERROR: %s" (cdr error-var))))))
2214 (t
2215 "ILLEGAL VALUE OF PARSE"))))
2216
2217(defun reftex-context-substring ()
2218 ;; Return up to 100 chars from point
2219 ;; When point is just after a { or [, limit string to matching parenthesis
2220 (cond
2221 ((or (= (preceding-char) ?\{)
2222 (= (preceding-char) ?\[))
2223 ;; inside a list - get only the list, with modified syntax to be perfect
2224 (buffer-substring
2225 (point)
2226 (min (+ 100 (point))
2227 (point-max)
2228 (condition-case nil
2229 (progn
2230 (up-list 1)
2231 (1- (point)))
2232 ('error (point-max))))))
2233 (t
2234 ;; no list - just grab 100 characters
2235 (buffer-substring (point) (min (+ 100 (point)) (point-max))))))
2236
2237(defun reftex-section-number (section-numbers &optional level star)
2238 ;; Return a string with the current section number.
2239 ;; When LEVEL is non-nil, increase section numbers on that level.
2240 (let* ((depth 6) idx n (string ""))
2241 (if level
2242 (progn
2243 (if (and (> level -1) (not star))
2244 (aset section-numbers level (1+ (aref section-numbers level))))
2245 (setq idx (1+ level))
2246 (while (<= idx depth)
2247 (aset section-numbers idx 0)
2248 (setq idx (1+ idx)))))
2249 (setq idx 0)
2250 (while (<= idx depth)
2251 (setq n (aref section-numbers idx))
2252 (setq string (concat string (if (not (string= string "")) "." "")
2253 (int-to-string n)))
2254 (setq idx (1+ idx)))
2255 (save-match-data
2256 (if (string-match "\\`\\(0\\.\\)+" string)
2257 (setq string (replace-match "" nil nil string)))
2258 (if (string-match "\\(\\.0\\)+\\'" string)
2259 (setq string (replace-match "" nil nil string))))
2260 (if star
2261 (concat (make-string (1- (length string)) ?\ ) "*")
2262 string)))
2263
2264;; A variable to remember the index of the last label context shown
2265(defvar reftex-last-cnt 0)
2266
2267(defun reftex-select-label-callback (cnt)
2268 ;; Callback function called from the label selection in order to
2269 ;; show context in another window
2270 (let* ((this-window (selected-window))
2271 index entry label file buffer)
2272 ;; pop to original buffer in order to get correct variables
2273 (catch 'exit
2274 (save-excursion
2275 (set-buffer reftex-call-back-to-this-buffer)
2276 (setq index (nth (or cnt 1) reftex-label-index-list)
2277 entry (nth index (symbol-value reftex-list-of-labels-symbol))
2278 label (nth 0 entry)
2279 file (nth 3 entry)))
2280
2281 ;; goto the file in another window
2282 (setq buffer (reftex-get-file-buffer-force
2283 file (not reftex-keep-temporary-buffers)))
2284 (if buffer
2285 ;; good - the file is available
2286 (switch-to-buffer-other-window buffer)
2287 ;; we have got a problem here. The file does not exist.
2288 ;; Let' get out of here..
2289 (ding)
2290 (throw 'exit nil))
2291
2292
2293 ;; search for that label
2294 (if (not (and (integerp cnt)
2295 (integerp reftex-last-cnt)
2296 (if (> cnt reftex-last-cnt)
2297 (search-forward (concat "\\label{" label "}") nil t)
2298 (search-backward (concat "\\label{" label "}") nil t))))
2299 (progn
2300 (goto-char 1)
2301 (search-forward (concat "\\label{" label "}") nil t)))
2302 (reftex-highlight 0 (match-beginning 0) (match-end 0))
2303 (reftex-show-entry)
2304 (recenter (/ (window-height) 2))
2305 (select-window this-window))))
2306
2307(defun reftex-pop-to-label (label file-list &optional mark-to-kill highlight)
2308 ;; Find LABEL in any file in FILE-LIST in another window.
2309 ;; If mark-to-kill is non-nil, mark new buffer for killing.
2310 ;; If HIGHLIGHT is non-nil, highlight the label definition.
2311 (let* ((re (concat "\\\\label{" (regexp-quote label) "}"))
2312 file buf)
2313 (catch 'exit
2314 (while file-list
2315 (setq file (car file-list)
2316 file-list (cdr file-list))
2317 (if (not (setq buf (reftex-get-file-buffer-force file mark-to-kill)))
2318 (error "No such file %s" file))
2319 (set-buffer buf)
2320 (widen)
2321 (goto-char (point-min))
2322 (if (re-search-forward re nil t)
2323 (progn
2324 (switch-to-buffer-other-window buf)
2325 (goto-char (match-beginning 0))
2326 (recenter (/ (window-height) 2))
2327 (if highlight
2328 (reftex-highlight 0 (match-beginning 0) (match-end 0)))
2329 (throw 'exit (selected-window)))))
2330 (error "Label %s not found" label))))
2331
2332(defun reftex-find-duplicate-labels ()
2333 "Produce a list of all duplicate labels in the document."
2334
2335 (interactive)
2336
2337 ;; Rescan the document to make sure
2338 (reftex-access-scan-info t)
2339
2340 (let ((master (reftex-TeX-master-file))
2341 (dlist
2342 (mapcar
2343 '(lambda(x)
2344 (let (x1)
2345 (cond
2346 ((car x)
2347 (setq x1 (reftex-all-assoc-string
2348 (car x) (symbol-value reftex-list-of-labels-symbol)))
2349 (if (< 1 (length x1))
2350 (append (list (reftex-no-props (car x)))
2351 (mapcar '(lambda(x)
2352 (abbreviate-file-name (nth 3 x))) x1))
2353 (list nil)))
2354 (t nil))))
2355 (reftex-uniquify (symbol-value reftex-list-of-labels-symbol)))))
2356 (setq dlist (reftex-uniquify dlist))
2357 (if (null dlist) (error "No duplicate labels in document"))
2358 (switch-to-buffer-other-window "*Help*")
2359 (make-local-variable 'TeX-master)
2360 (setq TeX-master master)
2361 (erase-buffer)
2362 (insert " MULTIPLE LABELS IN CURRENT DOCUMENT:\n")
2363 (insert " Move point to label and type `M-x reftex-change-label'\n"
2364 " This will run a query-replace on the label and its references\n")
2365 (insert " LABEL FILE\n")
2366 (insert " -------------------------------------------------------------\n")
2367 (while dlist
2368 (if (and (car (car dlist))
2369 (cdr (car dlist)))
2370 (progn
2371 (insert (mapconcat '(lambda(x) x) (car dlist) "\n ") "\n")))
2372 (setq dlist (cdr dlist)))
2373 (goto-char (point-min))))
2374
2375(defun reftex-all-assoc-string (key list)
2376 ;; Return a list of all associations of KEY in LIST. Comparison with string=
2377 (let (rtn)
2378 (while list
2379 (if (string= (car (car list)) key)
2380 (setq rtn (cons (car list) rtn)))
2381 (setq list (cdr list)))
2382 (nreverse rtn)))
2383
2384(defun reftex-kill-temporary-buffers ()
2385 ;; Kill all buffers in the list reftex-kill-temporary-buffers.
2386 (while reftex-buffers-to-kill
2387 (if (bufferp (car reftex-buffers-to-kill))
2388 (progn
2389 (and (buffer-modified-p (car reftex-buffers-to-kill))
2390 (y-or-n-p (format "Save file %s? "
2391 (buffer-file-name
2392 (car reftex-buffers-to-kill))))
2393 (save-excursion
2394 (set-buffer (car reftex-buffers-to-kill))
2395 (save-buffer)))
2396 (kill-buffer (car reftex-buffers-to-kill))))
2397 (setq reftex-buffers-to-kill (cdr reftex-buffers-to-kill))))
2398
2399(defun reftex-show-entry ()
2400 ;; Show entry if point is hidden by outline mode
2401 (let ((pos (point)))
2402 (if (and reftex-auto-show-entry
2403 (boundp 'outline-minor-mode)
2404 outline-minor-mode
2405 (looking-at "[^\n\r]*\r"))
2406 (progn
2407 (outline-back-to-heading)
2408 (show-entry)
2409 (goto-char pos)))))
2410
2411
2412(defun reftex-nicify-text (text)
2413 ;; Make TEXT nice for inclusion into label menu
2414 (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text) ; remove extra whitespace
2415 (setq text (replace-match " " nil t text)))
2416 (if (string-match "\\\\end{.*" text) ; nothing beyond \end{
2417 (setq text (replace-match "" nil t text)))
2418 (if (string-match "\\\\label{[^}]*}" text) ; kill the label
2419 (setq text (replace-match "" nil t text)))
2420 (if (string-match "^ +" text) ; leading whitespace
2421 (setq text (replace-match "" nil t text)))
2422 (cond
2423 ((> (length text) 100) ; not to long
2424 (setq text (substring text 0 100)))
2425 ((= (length text) 0) ; not empty
2426 (setq text " ")))
2427 text)
2428
2429(defun reftex-typekey-check (typekey conf-variable &optional n)
2430 ;; Check if CONF-VARIABLE is true or contains TYPEKEY
2431 (and n (setq conf-variable (nth n conf-variable)))
2432 (or (equal conf-variable t)
2433 (and (stringp conf-variable)
2434 (string-match (concat "[" conf-variable "]") typekey))))
2435
2436;;; ===========================================================================
2437;;;
2438;;; Table of contents (contributed from Stephen Eglen, changed by C. Dominik)
2439
2440;; We keep at most one *toc* buffer - it is easy to make them
2441
2442(defvar reftex-last-toc-master nil
2443 "Stores the name of the tex file that `reftex-toc' was last run on.")
2444
2445(defvar reftex-last-toc-file nil
2446 "Stores the file name from which `reftex-toc' was called. For redo command.")
2447
2448(defvar reftex-toc-return-marker (make-marker)
2449 "Marker which makes it possible to return from toc to old position.")
2450
2451(defun reftex-toc ()
2452 "Show the table of contents for the current document.
2453To see the corresponding part of the LaTeX document, use within the
2454*toc* buffer:
2455
2456SPC Show the corresponding section of the LaTeX document
2457RET Goto the section and hide the *toc* buffer
2458q Hide the *toc* window and return to position of last reftex-toc command
2459Q Kill the *toc* buffer and return to position of last reftex-toc command
2460f Toggle follow mode on and off
2461
2462When called with a raw C-u prefix, rescan the document first."
2463
2464 (interactive)
2465
2466 (and (not (string= reftex-last-toc-master (reftex-TeX-master-file)))
2467 (get-buffer "*toc*")
2468 (kill-buffer "*toc*"))
2469
2470 (setq reftex-last-toc-file (buffer-file-name))
2471 (setq reftex-last-toc-master (reftex-TeX-master-file))
2472
2473 (set-marker reftex-toc-return-marker (point))
2474
2475 ;; if follow mode is active, arrange to delay it one command
2476 (if reftex-toc-follow-mode
2477 (setq reftex-toc-follow-mode 1))
2478
2479 (if (and current-prefix-arg
2480 (get-buffer "*toc*"))
2481 (kill-buffer "*toc*"))
2482
2483 ;; Ensure access to scanning info and rescan buffer if prefix are is '(4)
2484 (reftex-access-scan-info current-prefix-arg)
2485
2486 (let* ((all (symbol-value reftex-list-of-labels-symbol))
2487 (where (reftex-nearest-section))
2488 toc toc1 cell label file find startpos)
2489
2490 (if (and (get-buffer "*toc*")
2491 (get-buffer-window (get-buffer "*toc*")))
2492 (select-window (get-buffer-window (get-buffer "*toc*")))
2493 (delete-other-windows)
2494 (switch-to-buffer-other-window (current-buffer))
2495 (switch-to-buffer-other-window (get-buffer-create "*toc*")))
2496
2497 (cond
2498 ;; buffer is empty - fill it with the table of contents
2499 ((= (buffer-size) 0)
2500
2501 (local-set-key " " 'reftex-toc-view-line)
2502 (local-set-key "\C-m" 'reftex-toc-goto-line-and-hide)
2503 (local-set-key "r" 'reftex-toc-redo)
2504 (local-set-key "q" 'reftex-toc-quit)
2505 (local-set-key "Q" 'reftex-toc-quit-and-kill)
2506 (local-set-key "f" 'reftex-toc-toggle-follow)
2507 (setq truncate-lines t)
2508 (make-local-hook 'post-command-hook)
2509 (make-local-hook 'pre-command-hook)
2510 (setq post-command-hook '(reftex-toc-post-command-hook))
2511 (setq pre-command-hook '(reftex-toc-pre-command-hook))
2512
2513 (insert (format
2514"TABLE-OF-CONTENTS on %s
2515MENU: SPC=view RET=goto [q]uit [Q]uit+kill [r]escan [f]ollow-mode on/off
2516-------------------------------------------------------------------------------
2517" (abbreviate-file-name reftex-last-toc-master)))
2518 (setq startpos (point))
2519
2520 (if (reftex-use-fonts)
2521 (put-text-property 1 (point) 'face 'font-lock-keyword-face))
2522 (put-text-property 1 (point) 'intangible t)
2523
2524 (while all
2525 (setq cell (car all)
2526 all (cdr all))
2527 (setq label (nth 0 cell)
2528 toc (nth 2 cell)
2529 file (nth 3 cell)
2530 find (nth 4 cell))
2531 (if (not label)
2532 (progn
2533 (setq toc1 (concat toc "\n"))
2534 (put-text-property 0 (length toc1)
2535 'file file toc1)
2536 (put-text-property 0 (length toc1)
2537 'find find toc1)
2538 (insert toc1)
2539 )))
2540
2541 (backward-delete-char 1)
2542
2543 (setq buffer-read-only t))
2544 (t
2545 (goto-line 3)
2546 (beginning-of-line)
2547 (setq startpos (point))))
2548
2549 ;; Find the correct section
2550 (goto-char (point-max))
2551 (beginning-of-line)
2552 (while (and (> (point) startpos)
2553 (or (not (string= (get-text-property (point) 'file)
2554 (car where)))
2555 (not (string= (get-text-property (point) 'find)
2556 (cdr where)))))
2557 (beginning-of-line 0))))
2558
2559(defun reftex-nearest-section ()
2560 ;; Return (file . find) of nearest section command
2561 (let (cell label rest)
2562 (save-excursion
2563 (cond
2564 ;; Try to find a section heading
2565 ((or (re-search-backward reftex-section-regexp nil t)
2566 (re-search-forward reftex-section-regexp nil t))
2567 (goto-char (match-end 0))
2568 (cons (buffer-file-name)
2569 (reftex-allow-for-ctrl-m
2570 (concat (buffer-substring-no-properties
2571 (1- (match-beginning 1)) (match-end 0))
2572 (reftex-context-substring)))))
2573 ;; Try to find a label
2574 ((and (or (re-search-backward "\\\\label{\\([^}]+\\)}" nil t)
2575 (re-search-forward "\\\\label{\\([^}]+\\)}" nil t))
2576 (setq label (reftex-no-props (match-string 1)))
2577 (setq cell (assoc label (symbol-value
2578 reftex-list-of-labels-symbol)))
2579 (setq rest (memq cell (symbol-value reftex-list-of-labels-symbol)))
2580 (setq cell (car (memq (assoc nil rest) rest)))
2581 (null (car cell)))
2582 (cons (nth 3 cell) (nth 4 cell)))
2583 (t nil)))))
2584
2585(defun reftex-toc-pre-command-hook ()
2586 ;; used as pre command hook in *toc* buffer
2587 (reftex-unhighlight 0)
2588 (reftex-unhighlight 1))
2589
2590(defun reftex-toc-post-command-hook ()
2591 ;; used in the post-command-hook for the *toc* buffer
2592 (and (> (point) 1)
2593 (save-excursion
2594 (reftex-highlight 1
2595 (progn (beginning-of-line) (point))
2596 (progn (end-of-line) (point)))))
2597 (cond
2598 ((integerp reftex-toc-follow-mode)
2599 ;; remove delayed action
2600 (setq reftex-toc-follow-mode t))
2601 (reftex-toc-follow-mode
2602 ;; show context in other window
2603 (condition-case nil
2604 (reftex-toc-visit-line)
2605 ('error t)))))
2606
2607(defun reftex-toc-toggle-follow ()
2608 "Toggle toc-follow mode.
2609(it is not really a mode, just a flag)."
2610 (interactive)
2611 (setq reftex-toc-follow-mode (not reftex-toc-follow-mode)))
2612(defun reftex-toc-view-line ()
2613 "View document location in other window."
2614 (interactive)
2615 (reftex-toc-visit-line))
2616(defun reftex-toc-goto-line-and-hide ()
2617 "Go to document location in other window. Hide the *toc* window."
2618 (interactive)
2619 (reftex-toc-visit-line 'hide))
2620(defun reftex-toc-quit ()
2621 "Hide the *toc* window and do not move point."
2622 (interactive)
2623 (delete-window)
2624 (switch-to-buffer (marker-buffer reftex-toc-return-marker))
2625 (goto-char (marker-position reftex-toc-return-marker)))
2626(defun reftex-toc-quit-and-kill ()
2627 "Kill the *toc* buffer."
2628 (interactive)
2629 (kill-buffer "*toc*")
2630 (delete-window)
2631 (switch-to-buffer (marker-buffer reftex-toc-return-marker))
2632 (goto-char (marker-position reftex-toc-return-marker)))
2633(defun reftex-toc-redo ()
2634 "Regenerate the *toc* buffer. Call only from within the *toc* buffer"
2635 (interactive)
2636 (switch-to-buffer (reftex-get-file-buffer-force reftex-last-toc-file))
2637 (delete-other-windows)
2638 (setq current-prefix-arg '(4))
2639 (reftex-toc))
2640
2641(defun reftex-toc-visit-line (&optional final)
2642 ;; Visit the tex file corresponding to the toc entry on the current line.
2643 ;; If FINAL is t, stay there
2644 ;; If FINAL is 'hide, hide the *toc* window.
2645 ;; Otherwise, move cursor back into *toc* window
2646
2647 (let (file find beg end (toc-window (selected-window)) show-window)
2648 (save-excursion
2649 (beginning-of-line)
2650 (setq beg (point))
2651 (end-of-line)
2652 (setq end (point)))
2653
2654 ;; get the file and the search string
2655 (setq file (get-text-property (point) 'file))
2656 (setq find (get-text-property (point) 'find))
2657 (if (or (not file) (not find))
2658 (error "Cannot visit line"))
2659
2660 (switch-to-buffer-other-window (reftex-get-file-buffer-force file))
2661 (setq show-window (selected-window))
2662 (goto-char (point-min))
2663
2664 (if (not (re-search-forward find nil t))
2665 (error "Cannot visit line"))
2666
2667 (setq beg (match-beginning 0)
2668 end (match-end 0))
2669
2670 (goto-char beg)
2671 (recenter 1)
2672 (reftex-highlight 0 beg end (current-buffer))
2673
2674 (select-window toc-window)
2675
2676 ;; use the `final' parameter to decide what to do next
2677 (cond
2678 ((equal final t)
2679 (reftex-unhighlight 0)
2680 (select-window show-window))
2681 ((eq final 'hide)
2682 (reftex-unhighlight 0)
2683 (delete-window))
2684 (t nil))))
2685
2686;;; ===========================================================================
2687;;;
2688;;; BibTeX citations.
2689
2690;; Variables and constants
2691
2692;; Internal variable, but used from different functions
2693(defvar reftex-cite-format1 nil)
2694
2695;; The history list of regular expressions used for citations
2696(defvar reftex-cite-regexp-hist nil)
2697
2698;; Help string for citation selection
2699(defconst reftex-citation-help
2700 "AVAILABLE KEYS IN MAKE CITATION MENU
2701---------------------------------------
2702 n / p Go to next/previous entry (Cursor motion works as well)
2703 r restrict selection with another regexp
2704 SPACE Show full database entry in other window
2705 f Toggle follow mode: Other window will follow with full db entry
2706 q Quit without inserting \\cite macro into buffer
2707 ? Display this help message
2708 C-r Recursive edit into other window
2709 RETURN ... Accept current entry and insert in format according to
2710 reftex-cite-format")
2711
2712(defconst reftex-cite-format-default "\\cite{KEY}"
2713 "The default value for reftex-cite-format.
2714Uses the string version of scitex-cite-format.")
2715
2716(defconst reftex-cite-format-1-author-simple
2717 '( "\\cite{KEY}" "AUTHOR \\cite{KEY}" "AUTHOR {\it et al.} \\cite{KEY}")
2718 "Value for reftex-cite format establishing a simple citation with name
2719of the first author.
2720Uses the list version of reftex-cite-format.")
2721
2722(defconst reftex-cite-format-2-authors
2723 '((?\C-m
2724 . ( "\\cite{KEY}" "AUTHOR \\cite{KEY}"
2725 "AUTHOR \\& AUTHOR \\cite{KEY}" "AUTHOR \\etal{} \\cite{KEY}"))
2726 (?\,
2727 . ("\\cite{KEY}" "AUTHOR, \\cite{KEY}"
2728 "AUTHOR \\& AUTHOR, \\cite{KEY}" "AUTHOR \\etal{}, \\cite{KEY}"))
2729 (?\;
2730 . ("\\cite{KEY}" "AUTHOR; \\cite{KEY}"
2731 "AUTHOR \\& AUTHOR; \\cite{KEY}" "AUTHOR \\etal{}; \\cite{KEY}"))
2732 (?\:
2733 . ("\\cite{KEY}" "AUTHOR: \\cite{KEY}"
2734 "AUTHOR \\& AUTHOR: \\cite{KEY}" "AUTHOR \\etal{}: \\cite{KEY}"))
2735 (?\(
2736 . ("(\\cite{KEY})" "AUTHOR (\\cite{KEY})"
2737 "AUTHOR \\& AUTHOR (\\cite{KEY})" "AUTHOR \\etal{} (\\cite{KEY})"))
2738 (?\[
2739 . ("[\\cite{KEY}]" "AUTHOR [\\cite{KEY}]"
2740 "AUTHOR \\& AUTHOR [\\cite{KEY}]" "AUTHOR \\etal{} [\\cite{KEY}]")))
2741 "Value for reftex-cite-format that estabishes an Author/Year citation
2742where the year is supplied from BibTeX. Depending on which character
2743is used during selection to accept the label, an extra ,;: or pair of
2744parenthesis will be inserted.
2745Uses the list-of-cons-cells version of reftex-cite-format.")
2746
2747;; Find bibtex files
2748
2749(defun reftex-get-bibfile-list ()
2750 ;; Return list of bibfiles for current document
2751
2752 ;; Ensure access to scanning info
2753 (reftex-access-scan-info)
2754
2755 (or (symbol-value reftex-bibfile-list-symbol)
2756 (error "No BibTeX files to parse. Add \\bibliography statment to document and reparse.")))
2757
2758(defun reftex-scan-buffer-for-bibliography-statement (bib-list-symbol)
2759 ;; Scan buffer for bibliography macro and store file list in bib-list-symbol.
2760 (let (file-list dir-list)
2761 (setq dir-list
2762 (reftex-split
2763 (concat path-separator "+")
2764 (mapconcat '(lambda(x)
2765 (if (getenv x) (getenv x) ""))
2766 reftex-bibpath-environment-variables
2767 path-separator)))
2768 (goto-char (point-min))
2769 (if (re-search-forward "^[ \t]*\\\\bibliography{[ \t]*\\([^}]+\\)" nil t)
2770 (progn
2771 (setq dir-list
2772 (cons (file-name-directory
2773 (get-text-property (match-beginning 0) 'file))
2774 dir-list))
2775 (setq file-list
2776 (mapcar '(lambda (x) (concat x ".bib"))
2777 (reftex-delete-list
2778 reftex-bibfile-ignore-list
2779 (reftex-split
2780 "[ \t\n]*,[ \t\n]*"
2781 (reftex-no-props (match-string 1)))))))
2782 (message "No \\bibliography command in document."))
2783 (set bib-list-symbol
2784 (if file-list
2785 (reftex-find-files-on-path file-list dir-list
2786 "While parsing \\bibliography{}:")
2787 nil))))
2788
2789(defun reftex-find-files-on-path (file-list path-list &optional error-string)
2790 ;; Search for all files in FILE-LIST on the PATH-LIST. Return absolute names.
2791 ;; A missing file throws an exception with the error message ERROR-STRING.
2792 (let (found-list found file)
2793 (while file-list
2794 (setq file (car file-list)
2795 file-list (cdr file-list)
2796 found nil)
2797 (if (file-name-absolute-p file)
2798 (setq found (expand-file-name file))
2799 (let ((dirs path-list))
2800 (while (and dirs (not found))
2801 (if (and (not (string= (car dirs) ""))
2802 (file-exists-p (expand-file-name file (car dirs))))
2803 (setq found (expand-file-name file (car dirs))))
2804 (setq dirs (cdr dirs)))))
2805 (if (and found
2806 (file-exists-p found))
2807 (add-to-list 'found-list (expand-file-name found))
2808 (error "%s No such file %s."
2809 (or error-string "") file)))
2810 (nreverse found-list)))
2811
2812;; Find a certain reference in any of the BibTeX files.
2813
2814(defun reftex-pop-to-bibtex-entry (key file-list
2815 &optional mark-to-kill highlight)
2816 ;; Find BibTeX KEY in any file in FILE-LIST in another window.
2817 ;; If mark-to-kill is non-nil, mark new buffer to kill."
2818
2819 (let* ((re (concat "@[a-zA-Z]+[ \t\n\r]*{[ \t\n\r]*" (regexp-quote key) "[ \t\n\r,]"))
2820 (window-conf (current-window-configuration))
2821 file buf)
2822 (catch 'exit
2823 (switch-to-buffer-other-window (current-buffer))
2824 (while file-list
2825 (setq file (car file-list)
2826 file-list (cdr file-list))
2827 (if (not (setq buf (reftex-get-file-buffer-force file mark-to-kill)))
2828 (error "No such file %s" file))
2829 (switch-to-buffer buf)
2830 (widen)
2831 (goto-char 0)
2832 (if (re-search-forward re nil t)
2833 (progn
2834 (goto-char (match-beginning 0))
2835 (recenter 0)
2836 (if highlight
2837 (reftex-highlight 0 (match-beginning 0) (match-end 0)))
2838 (throw 'exit (selected-window)))))
2839 (set-window-configuration window-conf)
2840 (beep)
2841 (message "No BibTeX entry with citation key %s" key))))
2842
2843;; Parse bibtex buffers
2844
2845(defun reftex-extract-bib-entries (buffers &optional get-word)
2846 ;; Extract bib entries which match regexps from BUFFERS.
2847 ;; BUFFERS is a list of buffers or file names.
2848 ;; Return list with entries."
2849 (let* (re-list first-re rest-re
2850 ;; avoid fontification of lookup buffers
2851 (lazy-lock-minimum-size 1)
2852 (buffer-list (if (listp buffers) buffers (list buffers)))
2853 found-list entry buffer1 buffer alist
2854 key-point start-point end-point)
2855
2856 (setq re-list (reftex-split "[ \t]*&&[ \t]*"
2857 (read-string "RegExp [ && RegExp...]: "
2858 nil 'reftex-cite-regexp-hist)))
2859
2860 (setq first-re (car re-list) ; We'll use the first re to find things,
2861 rest-re (cdr re-list)) ; the other to narrow down.
2862 (if (string-match "\\`[ \t]*\\'" first-re)
2863 (error "Empty regular expression"))
2864
2865 (save-excursion
2866 (save-window-excursion
2867
2868 ;; walk through all bibtex files
2869 (while buffer-list
2870 (setq buffer (car buffer-list)
2871 buffer-list (cdr buffer-list))
2872 (if (and (bufferp buffer)
2873 (buffer-live-p buffer))
2874 (setq buffer1 buffer)
2875 (setq buffer1 (reftex-get-file-buffer-force
2876 buffer (not reftex-keep-temporary-buffers))))
2877 (if (not buffer1)
2878 (error "Cannot find BibTeX file %s" buffer)
2879 (message "Scanning bibliography database %s" buffer1))
2880
2881 (set-buffer buffer1)
2882 (save-excursion
2883 (goto-char (point-min))
2884 (while (re-search-forward first-re nil t)
2885 (catch 'search-again
2886 (setq key-point (point))
2887 (if (not (re-search-backward
2888 "^[ \t]*@\\([a-zA-Z]+\\)[ \t\n\r]*{" nil t))
2889 (throw 'search-again nil))
2890 (setq start-point (point))
2891 (goto-char (match-end 0))
2892 (condition-case nil
2893 (up-list 1)
2894 ('error (goto-char key-point)
2895 (throw 'search-again nil)))
2896 (setq end-point (point))
2897
2898 ;; Ignore @string, @comment and @c entries or things
2899 ;; outside entries
2900 (if (or (string= (downcase (match-string 1)) "string")
2901 (string= (downcase (match-string 1)) "comment")
2902 (string= (downcase (match-string 1)) "c")
2903 (< (point) key-point)) ; this means match not in {}
2904 (progn
2905 (goto-char key-point)
2906 (throw 'search-again nil)))
2907
2908 ;; Well, we have got a match
2909 (setq entry (concat
2910 (buffer-substring start-point (point)) "\n"))
2911
2912 ;; Check if other regexp match as well
2913 (setq re-list rest-re)
2914 (while re-list
2915 (if (not (string-match (car re-list) entry))
2916 ;; nope - move on
2917 (throw 'search-again nil))
2918 (setq re-list (cdr re-list)))
2919
2920 (setq alist (reftex-parse-bibtex-entry
2921 nil start-point end-point))
2922 (setq alist (cons (cons "&entry" entry) alist))
2923
2924 ;; check for crossref entries
2925 (if (assoc "crossref" alist)
2926 (setq alist
2927 (append
2928 alist (reftex-get-crossref-alist alist))))
2929
2930 ;; format the entry
2931 (setq alist
2932 (cons
2933 (cons "&formatted"
2934 (reftex-format-bib-entry alist))
2935 alist))
2936
2937 ;; add it to the list
2938 (setq found-list (cons alist found-list)))))
2939 (reftex-kill-temporary-buffers))))
2940 (setq found-list (nreverse found-list))
2941
2942 ;; Sorting
2943 (cond
2944 ((eq 'author reftex-sort-bibtex-matches)
2945 (sort found-list 'reftex-bib-sort-author))
2946 ((eq 'year reftex-sort-bibtex-matches)
2947 (sort found-list 'reftex-bib-sort-year))
2948 ((eq 'reverse-year reftex-sort-bibtex-matches)
2949 (sort found-list 'reftex-bib-sort-year-reverse))
2950 (t found-list))))
2951
2952(defun reftex-bib-sort-author (e1 e2)
2953 (let ((al1 (reftex-get-bib-authors e1)) (al2 (reftex-get-bib-authors e2)))
2954 (while (and al1 al2 (string= (car al1) (car al2)))
2955 (setq al1 (cdr al1)
2956 al2 (cdr al2)))
2957 (if (and (stringp (car al1))
2958 (stringp (car al2)))
2959 (string< (car al1) (car al2))
2960 (not (stringp (car al1))))))
2961
2962(defun reftex-bib-sort-year (e1 e2)
2963 (< (string-to-int (cdr (assoc "year" e1)))
2964 (string-to-int (cdr (assoc "year" e2)))))
2965
2966(defun reftex-bib-sort-year-reverse (e1 e2)
2967 (> (string-to-int (or (cdr (assoc "year" e1)) "0"))
2968 (string-to-int (or (cdr (assoc "year" e2)) "0"))))
2969
2970(defun reftex-get-crossref-alist (entry)
2971 ;; return the alist from a crossref entry
2972 (let ((crkey (cdr (assoc "crossref" entry)))
2973 start)
2974 (save-excursion
2975 (save-restriction
2976 (widen)
2977 (if (re-search-forward
2978 (concat "@\\w+{[ \t\n\r]*" (regexp-quote crkey) "[ \t\n\r]*,") nil t)
2979 (progn
2980 (setq start (match-beginning 0))
2981 (condition-case nil
2982 (up-list 1)
2983 ('error nil))
2984 (reftex-parse-bibtex-entry nil start (point)))
2985 nil)))))
2986
2987;; Parse and format individual entries
2988
2989(defun reftex-get-bib-authors (entry)
2990 ;; Return a list with the author names in ENTRY
2991 (let (authors)
2992 (setq authors (reftex-get-bib-field "author" entry))
2993 (if (equal "" authors)
2994 (setq authors (reftex-get-bib-field "editor" entry)))
2995 (while (string-match "\\band\\b[ \t]*" authors)
2996 (setq authors (replace-match "\n" nil t authors)))
2997 (while (string-match "[\\.a-zA-Z\\-]+\\.[ \t]*\\|,.*\\|[{}]+" authors)
2998 (setq authors (replace-match "" nil t authors)))
2999 (while (string-match "^[ \t]+\\|[ \t]+$" authors)
3000 (setq authors (replace-match "" nil t authors)))
3001 (while (string-match "[ \t][ \t]+" authors)
3002 (setq authors (replace-match " " nil t authors)))
3003 (reftex-split "\n" authors)))
3004
3005(defun reftex-parse-bibtex-entry (entry &optional from to)
3006 (let (alist key start field)
3007 (save-excursion
3008 (save-restriction
3009 (if entry
3010 (progn
3011 (switch-to-buffer "*RefTeX-scratch*")
3012 (fundamental-mode)
3013 (erase-buffer)
3014 (insert entry))
3015 (widen)
3016 (narrow-to-region from to))
3017 (goto-char (point-min))
3018
3019 (if (re-search-forward
3020 "@\\(\\w+\\)[ \t\n\r]*{[ \t\n\r]*\\([^ \t\n\r,]+\\)" nil t)
3021 (setq alist
3022 (list
3023 (cons "&type" (downcase (reftex-no-props (match-string 1))))
3024 (cons "&key" (reftex-no-props (match-string 2))))))
3025 (while (re-search-forward "\\(\\w+\\)[ \t\n\r]*=[ \t\n\r]*" nil t)
3026 (setq key (reftex-no-props (downcase (match-string 1))))
3027 (cond
3028 ((= (following-char) ?{)
3029 (forward-char 1)
3030 (setq start (point))
3031 (condition-case nil
3032 (up-list 1)
3033 ('error nil)))
3034 ((= (following-char) ?\")
3035 (forward-char 1)
3036 (setq start (point))
3037 (while (and (search-forward "\"" nil t)
3038 (= ?\\ (char-after (- (point) 2))))))
3039 (t
3040 (setq start (point))
3041 (re-search-forward "[ \t\n\r,}]" nil 1)))
3042 (setq field (buffer-substring-no-properties start (1- (point))))
3043 ;; remove extra whitesp
3044 (while (string-match "[\n\t\r]\\|[ \t][ \t]+" field)
3045 (setq field (replace-match " " nil t field)))
3046 ;; remove leading garbage
3047 (if (string-match "^[ \t{]+" field)
3048 (setq field (replace-match "" nil t field)))
3049 ;; remove trailing garbage
3050 (if (string-match "[ \t}]+$" field)
3051 (setq field (replace-match "" nil t field)))
3052 (setq alist (cons (cons key field) alist)))
3053 alist))))
3054
3055(defun reftex-get-bib-field (fieldname entry)
3056 ;; Extract the field FIELDNAME from an ENTRY
3057 (or (cdr (assoc fieldname entry))
3058 ""))
3059
3060(defun reftex-format-bib-entry (entry)
3061 ;; Format a BibTeX ENTRY so that it is nice to look at
3062 (let*
3063 ((rtn nil)
3064 (auth-list (reftex-get-bib-authors entry))
3065 (authors (mapconcat '(lambda (x) x) auth-list ", "))
3066 (year (reftex-get-bib-field "year" entry))
3067 (title (reftex-get-bib-field "title" entry))
3068 (type (reftex-get-bib-field "&type" entry))
3069 (key (reftex-get-bib-field "&key" entry))
3070 (extra
3071 (cond
3072 ((equal type "article")
3073 (concat (reftex-get-bib-field "journal" entry) " "
3074 (reftex-get-bib-field "volume" entry) ", "
3075 (reftex-get-bib-field "pages" entry)))
3076 ((equal type "book")
3077 (concat "book (" (reftex-get-bib-field "publisher" entry) ")"))
3078 ((equal type "phdthesis")
3079 (concat "PhD: " (reftex-get-bib-field "school" entry)))
3080 ((equal type "mastersthesis")
3081 (concat "Master: " (reftex-get-bib-field "school" entry)))
3082 ((equal type "inbook")
3083 (concat "Chap: " (reftex-get-bib-field "chapter" entry)
3084 ", pp. " (reftex-get-bib-field "pages" entry)))
3085 ((or (equal type "conference")
3086 (equal type "incollection")
3087 (equal type "inproceedings"))
3088 (concat "in: " (reftex-get-bib-field "booktitle" entry)))
3089 (t ""))))
3090 (setq authors
3091 (if (> (length authors) 30)
3092 (concat (substring authors 0 27) "...")
3093 (format "%-30s" authors))
3094 title
3095 (if (> (length title) 70)
3096 (concat (substring title 0 67) "...")
3097 (format "%-70s" title))
3098 extra
3099 (if (> (length extra) 40)
3100 (concat (substring extra 0 37) "...")
3101 (format "%-40s" extra)))
3102 (if (reftex-use-fonts)
3103 (progn
3104 (put-text-property 0 (length authors) 'face 'font-lock-keyword-face
3105 authors)
3106 (put-text-property 0 (length title) 'face 'font-lock-comment-face
3107 title)
3108 (put-text-property 0 (length extra) 'face 'font-lock-reference-face
3109 extra)))
3110 (setq rtn (concat key "\n " authors " " year " " extra
3111 "\n " title "\n\n"))
3112 rtn))
3113
3114;; Make a citation
3115
3116(defun reftex-citation (&optional arg no-insert)
3117 "Make a citation unsing BibTeX database files.
3118After asking for a Regular Expression, it scans the buffers with
3119bibtex entries (taken from the \\bibliography command) and offers the
3120matching entries for selection. The selected entry is formated according
3121to reftex-cite-format and inserted into the buffer.
3122If NO-INSERT is non-nil, nothing is inserted, only the selected key returned.
3123The regular expression uses an expanded syntax: && is interpreted as 'and'.
3124Thus, aaaa&&bbb matches entries which contain both aaaa and bbb.
3125When this function is called with point inside the braces of a \\cite{}
3126command, it will add another key, ignoring the value of reftex-cite-format.
3127When called with a numeric prefix, that many citations will be made and all
3128put into the same \\cite{} command.
3129When called with just C-u as prefix, enforces rescan of buffer for
3130bibliography statement (e.g. if it was changed)."
3131
3132 (interactive "P")
3133
3134 ;; check for recursive edit
3135 (reftex-check-recursive-edit)
3136
3137 ;; if there is just 1 C-u prefix arg, force to rescan buffer
3138 (if (and current-prefix-arg
3139 (listp current-prefix-arg)
3140 (= 4 (prefix-numeric-value arg)))
3141 (reftex-reset-scanning-information))
3142
3143 ;; check if there is already a cite command at point and change cite format
3144 ;; in order to only add another reference in the same cite command.
3145 (let ((pos (point)))
3146 (search-backward "\\" (point-min) 1)
3147 (if (and (looking-at "\\\\[a-zA-Z]*cite\\*?\\(\\[[^]]*\\]\\)*{\\([^}]*\\)")
3148 (>= (match-end 0) pos)
3149 (>= pos (match-beginning 2)))
3150 (progn
3151 (goto-char pos)
3152 (cond
3153 ((or (not arg)
3154 (not (listp arg)))
3155 (setq reftex-cite-format1
3156 (concat
3157 (if (not (or (= (preceding-char) ?{)
3158 (= (preceding-char) ?,)))
3159 ","
3160 "")
3161 "KEY"
3162 (if (not (or (= (following-char) ?})
3163 (= (following-char) ?,)))
3164 ","
3165 ""))))
3166 (t
3167 (setq reftex-cite-format1 "KEY"))))
3168 (setq reftex-cite-format1
3169 (if (symbolp reftex-cite-format)
3170 (symbol-value reftex-cite-format)
3171 reftex-cite-format))
3172 (goto-char pos)))
3173
3174 (let* (key entry cnt rtn ins-string re-list re
3175 ;; scan bibtex files
3176 (lazy-lock-minimum-size 1)
3177 (found-list (reftex-extract-bib-entries
3178 (reftex-get-bibfile-list)))
3179 (found-list-r nil)
3180 (accept-keys
3181 (if (and (listp reftex-cite-format1)
3182 (listp (car reftex-cite-format1)))
3183 (mapcar 'car reftex-cite-format1)
3184 '(?\C-m))))
3185 (if (not found-list)
3186 (error "Sorry, no matches found"))
3187
3188 ;; remember where we came from
3189 (setq reftex-call-back-to-this-buffer (current-buffer))
3190
3191 ;; offer selection
3192 (save-window-excursion
3193 (switch-to-buffer-other-window "*RefTeX Select*")
3194 (erase-buffer)
3195 (mapcar '(lambda (x) (insert (cdr (assoc "&formatted" x))))
3196 found-list)
3197 (if (= 0 (buffer-size))
3198 (error "Sorry, no matches found"))
3199 (setq truncate-lines t)
3200 (goto-char 1)
3201 (if (catch 'exit
3202 (while t
3203 (setq rtn
3204 (reftex-select-item
3205 nil
3206 (concat
3207 "Select: [n]ext [p]rev [r]estrict [q]uit [?]Help ||"
3208 " RETURN "
3209 (condition-case nil
3210 (mapconcat 'char-to-string accept-keys " ")
3211 (error (error "Illegal reftex-cite-format"))))
3212 "^[^ \t\n]"
3213 "\n\n"
3214 4
3215 reftex-citation-help
3216 (cons ?r accept-keys)
3217 nil
3218 'reftex-bibtex-selection-callback nil))
3219 (setq key (car rtn)
3220 cnt (cdr rtn))
3221 (if (not key) (throw 'exit nil))
3222 (cond
3223 ((equal key ?r)
3224 ;; restrict with new regular expression
3225 (setq re-list
3226 (reftex-split "[ \t]*&&[ \t]*"
3227 (read-string "RegExp [ && RegExp...]: "
3228 nil 'reftex-cite-regexp-hist)))
3229 (while re-list
3230 (setq re (car re-list)
3231 re-list (cdr re-list))
3232 (setq found-list-r
3233 (delete ""
3234 (mapcar
3235 '(lambda (x)
3236 (if (string-match re
3237 (cdr (assoc "&entry" x)))
3238 x
3239 ""))
3240 found-list))))
3241 (if found-list-r
3242 (setq found-list found-list-r)
3243 (ding))
3244 (erase-buffer)
3245 (mapcar '(lambda (x) (insert (cdr (assoc "&formatted" x))))
3246 found-list)
3247 (goto-char 1))
3248 ((or (member key accept-keys)
3249 (equal key ?\C-m)
3250 (equal key 'return))
3251 (setq entry (nth cnt found-list))
3252 (throw 'exit t))
3253 (t
3254 (ding)))))
3255 (progn
3256 ;; format the entry
3257 (if (not (integerp key)) (setq key ?\C-m))
3258 (setq ins-string (reftex-format-citation entry key)))
3259 (setq ins-string "")
3260 (message "Quit")))
3261 (kill-buffer "*RefTeX Select*")
3262
3263 (if (not no-insert)
3264 (insert ins-string))
3265 (message "")
3266
3267 ;; Check if the prefix arg was numeric, and call reftex-citation recursively
3268 (if (and (integerp arg)
3269 (> arg 1)
3270 (re-search-backward
3271 "\\\\[a-zA-Z]*cite\\*?\\(\\[[^]]*\\]\\)*{\\([^}]*\\)" nil t))
3272 (progn
3273 (goto-char (match-end 0))
3274 (setq arg (1- arg))
3275 (reftex-citation arg))
3276 (reftex-kill-temporary-buffers))
3277 ;; Return the citation key
3278 (reftex-get-bib-field "&key" entry)))
3279
3280(defun reftex-format-citation (entry key)
3281 ;; Format a citation from the info in the BibTeX ENTRY
3282 (let* ((cite-key (reftex-get-bib-field "&key" entry))
3283 (year (reftex-get-bib-field "year" entry))
3284 (auth-list (reftex-get-bib-authors entry))
3285 (nauthors (length auth-list))
3286 format)
3287
3288 (save-excursion
3289 ;; Find the correct format
3290 (if (and (listp reftex-cite-format1)
3291 (listp (car reftex-cite-format1)))
3292 (if (integerp (car (car reftex-cite-format1)))
3293 (if (assoc key reftex-cite-format1)
3294 (setq format (cdr (assoc key reftex-cite-format1)))
3295 (if (or (equal key ?\C-m)
3296 (equal key 'return))
3297 (setq format (cdr (car reftex-cite-format1)))
3298 (error "Error in reftex-cite-format")))
3299 (error "Error in reftex-cite-format"))
3300 (setq format reftex-cite-format1))
3301
3302 (if (listp format)
3303 (let ((nn (min nauthors (1- (length format)))))
3304 (while (and (> nn 0) (string= "" (nth nn format)))
3305 (setq nn (1- nn)))
3306 (setq format (nth nn format))))
3307 (if (stringp format)
3308 (setq format format)
3309 (setq format "\\cite{KEY}"))
3310
3311 ;; Insert the author names
3312 (while (string-match "\\bAUTHOR\\b" format)
3313 (setq format (replace-match (car auth-list) t t format))
3314 (setq auth-list (cdr auth-list)))
3315 (while (string-match "\\bKEY\\b" format)
3316 (setq format (replace-match cite-key t t format)))
3317 (while (string-match "\\bYEAR\\b" format)
3318 (setq format (replace-match year t t format)))
3319 format)))
3320
3321;; this is slow and not recommended for follow mode
3322(defun reftex-bibtex-selection-callback (cnt)
3323 ;; Callback function to be called from the BibTeX selection, in
3324 ;; order to display context. This function is relatively slow and not
3325 ;; recommended for follow mode, just for individual lookups.
3326 ;; When compiled, this gives a warning about found-list. However,
3327 ;; the calling function binds found-list with let.
3328 (let ((win (selected-window))
3329 (key (reftex-get-bib-field "&key" (nth cnt found-list)))
3330 (bibfile-list (save-excursion
3331 (set-buffer reftex-call-back-to-this-buffer)
3332 (reftex-get-bibfile-list))))
3333 (reftex-pop-to-bibtex-entry key bibfile-list
3334 (not reftex-keep-temporary-buffers) t)
3335 (select-window win)))
3336
3337;;; ===========================================================================
3338;;;
3339;;; Here is the routine used for selection
3340
3341;; Marker for return point from recursive edit
3342(defvar reftex-recursive-edit-marker (make-marker))
3343
3344(defun reftex-check-recursive-edit ()
3345 ;; Check if we are already in a recursive edit. Abort with helpful
3346 ;; message if so.
3347 (if (marker-position reftex-recursive-edit-marker)
3348 (error
3349 (substitute-command-keys
3350 "In unfinished recursive edit. Finish (\\[exit-recursive-edit]) or abort (\\[abort-recursive-edit])."))))
3351
3352(defun reftex-select-item (buffer prompt next-re end-re size help-string
3353 event-list &optional offset
3354 call-back cb-flag)
3355;; Select an item from the buffer BUFFER. Show PROMPT to user, find
3356;; next item with NEXT-RE regular expression, return on any of the
3357;; events listed in EVENT-LIST. The function returns the event along
3358;; with an integer indicating which item was selected. When OFFSET is
3359;; specified, starts at that item in the list. When CALL-BACK is
3360;; given, it is a function which is called with the match of the
3361;; NEXT-RE match and the index of the element.
3362 (let* (key key-sq b e ev cnt cmd
3363 (offset1 (or offset 1)))
3364 (setq ev
3365 (catch 'exit
3366 (save-window-excursion
3367 (if buffer
3368 (switch-to-buffer-other-window buffer))
3369 (if (= 0 (buffer-size))
3370 (throw 'exit nil))
3371 (setq truncate-lines t)
3372 (goto-char 1)
3373 (if (not (re-search-forward next-re nil t offset1))
3374 (progn ; in case the offset is illegal
3375 (setq offset1 1)
3376 (if (not (re-search-forward next-re nil t offset1))
3377 (throw 'exit nil))))
3378 (beginning-of-line 1)
3379 (setq cnt (if offset1 (1- offset1) 0))
3380 (while t
3381 (if (and cb-flag call-back)
3382 (funcall call-back cnt))
3383 (setq b (point)
3384 e (save-excursion
3385 (save-match-data
3386 (re-search-forward end-re nil 1))
3387 (point)))
3388 (reftex-highlight 1 b e)
3389 (if (or (not (pos-visible-in-window-p b))
3390 (not (pos-visible-in-window-p e)))
3391 (recenter (/ (window-height) 2)))
3392 (setq key-sq (read-key-sequence prompt))
3393 (setq key (car
3394 (cond
3395 ((fboundp 'listify-key-sequence) ; Emacs
3396 (listify-key-sequence key-sq))
3397 ((fboundp 'event-to-character) ; XEmacs
3398 (mapcar 'event-to-character key-sq))
3399 (t (error "Please report this problem to dominik@strw.leidenuniv.nl")))))
3400
3401 (setq cmd (key-binding key-sq))
3402
3403 (reftex-unhighlight 0)
3404
3405 (cond
3406
3407 ((or (equal key ?n)
3408 (equal key ?\C-i)
3409 (equal cmd 'next-line))
3410 (if (re-search-forward next-re nil t 2)
3411 (setq cnt (1+ cnt)))
3412 (beginning-of-line 1))
3413
3414 ((equal cmd 'scroll-up)
3415 (setq cnt (1- cnt))
3416 (while (and (pos-visible-in-window-p)
3417 (re-search-forward next-re nil t))
3418 (setq cnt (1+ cnt)))
3419 (beginning-of-line 1)
3420 (recenter 1))
3421
3422 ((or (equal key ?p)
3423 (equal cmd 'previous-line))
3424 (if (re-search-backward next-re nil t)
3425 (setq cnt (1- cnt))))
3426
3427 ((equal cmd 'scroll-down)
3428 (while (and (pos-visible-in-window-p)
3429 (re-search-backward next-re nil t))
3430 (setq cnt (1- cnt)))
3431 (recenter (- (window-height) size 2)))
3432
3433 ((equal key ?q)
3434 (throw 'exit nil))
3435
3436 ((equal key ?\C-g)
3437 (bury-buffer)
3438 (error "Abort"))
3439
3440 ((or (equal key ?\C-m)
3441 (equal key 'return)
3442 (equal cmd 'newline))
3443 (throw 'exit 'return))
3444
3445 ((or (equal key ?C) ; backward compatibility
3446 (equal key ?f))
3447 (setq cb-flag (not cb-flag)))
3448
3449 ((equal key ?\ )
3450 (funcall call-back cnt))
3451
3452 ((equal key ?\?)
3453 (save-window-excursion
3454 (with-output-to-temp-buffer "*RefTeX Help*"
3455 (princ help-string))
3456 (setq unread-command-events
3457 (cons
3458 (cond
3459 ((fboundp 'read-event) ; Emacs
3460 (read-event))
3461 ((fboundp 'next-command-event) ; XEmacs
3462 (next-command-event))
3463 (t (error "Please report this problem to dominik@strw.leidenuniv.nl")))
3464 nil)))
3465 (kill-buffer "*RefTeX Help*"))
3466
3467 ((equal key ?\C-r)
3468 ;; sje - code copied from ispell.el for
3469 ;; performing recursive edit
3470 (set-marker reftex-recursive-edit-marker (point))
3471 (unwind-protect
3472 (progn
3473 (save-window-excursion
3474 (save-excursion
3475 (other-window 1)
3476 (message
3477 (substitute-command-keys
3478 "Recursive edit. Return to selection with \\[exit-recursive-edit]"))
3479 (recursive-edit)))
3480 (if (not (equal (marker-buffer
3481 reftex-recursive-edit-marker)
3482 (current-buffer)))
3483 (error
3484 "Cannot continue RefTeX from this buffer."))
3485 (goto-char reftex-recursive-edit-marker))
3486 (set-marker reftex-recursive-edit-marker nil)))
3487
3488 ((member key event-list)
3489 (throw 'exit key))
3490 (t
3491 (ding)))))))
3492 (message "")
3493 (cons ev cnt)))
3494
3495;;; ===========================================================================
3496;;;
3497;;; View cross references
3498
3499(defun reftex-view-crossref (&optional arg)
3500 "View cross reference of \\ref{} or \\cite{} macro at point.
3501If the macro at point is a \\ref{}, show the corresponding label definition.
3502If it is a \\cite{}, show the BibTeX database entry.
3503If there is no such macro at point, search forward to find one.
3504When you call this function several times in direct successtion, point will
3505move to view subsequent cross references further down in the buffer.
3506With argument, actually select the window showing the cross reference."
3507
3508 (interactive "P")
3509
3510 ;; See where we are.
3511 (let* ((pos (point))
3512 (re "\\\\[a-z]*\\(cite\\|ref\\)\\(\\[[^{}]*\\]\\)?{\\([^}]+\\)}")
3513 (my-window (get-buffer-window (current-buffer)))
3514 pop-window cmd args macro label entry key-start point)
3515
3516 (if (save-excursion
3517 (forward-char 1)
3518 (and (search-backward "\\" nil t)
3519 (looking-at re)
3520 (< pos (match-end 0))))
3521 (setq macro (match-string 1)
3522 key-start (match-beginning 3)))
3523
3524 (if (and macro (eq last-command this-command))
3525 (if (and (string= macro "cite")
3526 (skip-chars-forward "^}, \t\n\r")
3527 (= (following-char) ?,))
3528 (setq key-start (1+ (point)))
3529 (setq macro nil)))
3530
3531 (if (not macro)
3532 (if (re-search-forward re nil t)
3533 (setq macro (match-string 1)
3534 key-start (match-beginning 3))
3535 (error "No further cross references in buffer")))
3536
3537 (goto-char key-start)
3538
3539 ;; Ensure access to scanning info
3540 (reftex-access-scan-info)
3541
3542 (cond
3543 ((string= macro "cite")
3544 (setq cmd 'reftex-pop-to-bibtex-entry
3545 args (list
3546 (reftex-no-props (reftex-this-word "^{},"))
3547 (reftex-get-bibfile-list) nil t)))
3548 ((string= macro "ref")
3549 (let ((label (reftex-no-props (reftex-this-word "^{}")))
3550 (entry (assoc label (symbol-value reftex-list-of-labels-symbol))))
3551 (if entry
3552 (setq cmd 'reftex-pop-to-label
3553 args (list label (list (nth 3 entry)) nil t))
3554 (error "Label %s not known - reparse document might help" label))))
3555 (t (error "This should not happen")))
3556 (setq point (point))
3557 (apply cmd args)
3558 (setq pop-window (selected-window))
3559 (add-hook 'pre-command-hook 'reftex-highlight-shall-die)
3560 (select-window my-window)
3561 (goto-char point)
3562 (and arg (select-window pop-window))))
3563
3564(defun reftex-mouse-view-crossref (ev)
3565 "View cross reference of \\ref{} or \\cite{} macro where you click.
3566If the macro at point is a \\ref{}, show the corresponding label definition.
3567If it is a \\cite{}, show the BibTeX database entry.
3568If there is no such macro at point, search forward to find one.
3569When you call this function several times in direct successtion, point will
3570move to view subsequent cross references further down in the buffer.
3571With argument, actually select the window showing the cross reference."
3572 (interactive "e")
3573 (mouse-set-point ev)
3574 (reftex-view-crossref current-prefix-arg))
3575
3576;;; ===========================================================================
3577;;;
3578;;; Functions that check out the surroundings
3579
3580(defun reftex-what-macro (which &optional bound)
3581 ;; Find out if point is within the arguments of any TeX-macro.
3582 ;; The return value is either (\"\\\\macro\" . (point)) or a list of them.
3583
3584 ;; If WHICH is nil, immediately return nil.
3585 ;; If WHICH is t, return list of all macros enclosing point.
3586 ;; If WHICH is a list of macros, look only for those macros and return the
3587 ;; name of the first macro in this list found to enclose point.
3588 ;; If the optional BOUND is an integer, bound backwards directed
3589 ;; searches to this point. If it is nil, limit to nearest \\section -
3590 ;; like statement.
3591
3592 ;; This function is pretty stable, but can be fooled if the text contains
3593 ;; things like \\macro{aa}{bb} where \\macro is defined to take only one
3594 ;; argument. As RefTeX cannot know this, the string \"bb\" would still be
3595 ;; considered an argument of macro \\macro.
3596
3597 (catch 'exit
3598 (if (null which) (throw 'exit nil))
3599 (let ((bound (or bound (save-excursion (re-search-backward
3600 reftex-section-regexp nil 1)
3601 (point))))
3602 pos cmd-list cmd)
3603 (save-restriction
3604 (save-excursion
3605 (narrow-to-region (max 1 bound) (point-max))
3606 ;; move back out of the current parenthesis
3607 (while (condition-case nil
3608 (progn (up-list -1) t)
3609 (error nil))
3610 ;; move back over any touching sexps
3611 (while (or (= (preceding-char) ?\])
3612 (= (preceding-char) ?\}))
3613 (backward-sexp))
3614 (setq pos (point))
3615 (if (and (or (= (following-char) ?\[)
3616 (= (following-char) ?\{))
3617 (and (re-search-backward "\\(\\\\[a-zA-Z]+\\)" nil t)
3618 (= (match-end 0) pos)))
3619 (progn
3620 (setq cmd (buffer-substring-no-properties
3621 (match-beginning 0) (match-end 0)))
3622 (if (eq t which)
3623 (setq cmd-list (cons (cons cmd (point)) cmd-list))
3624 (if (member cmd which)
3625 (throw 'exit (cons cmd (point)))))))
3626 (goto-char pos)))
3627 (nreverse cmd-list)))))
3628
3629(defun reftex-what-environment (which &optional bound)
3630 ;; Find out if point is inside a LaTeX environment.
3631 ;; The return value is (e.g.) either (\"equation\" . (point)) or a list of
3632 ;; them.
3633
3634 ;; If WHICH is nil, immediately return nil.
3635 ;; If WHICH is t, return list of all environments enclosing point.
3636 ;; If WHICH is a list of environments, look only for those environments and
3637 ;; return the name of the first environment in this list found to enclose
3638 ;; point.
3639
3640 ;; If the optional BOUND is an integer, bound backwards directed searches to
3641 ;; this point. If it is nil, limit to nearest \\section - like statement.
3642
3643 (catch 'exit
3644 (save-excursion
3645 (if (null which) (throw 'exit nil))
3646 (let ((bound (or bound (save-excursion (re-search-backward
3647 reftex-section-regexp nil 1)
3648 (point))))
3649 env-list end-list env)
3650 (while (re-search-backward "\\\\\\(begin\\|end\\){\\([^}]+\\)}"
3651 bound t)
3652 (setq env (buffer-substring-no-properties
3653 (match-beginning 2) (match-end 2)))
3654 (cond
3655 ((string= (match-string 1) "end")
3656 (add-to-list 'end-list env))
3657 ((member env end-list)
3658 (setq end-list (delete env end-list)))
3659 ((eq t which)
3660 (setq env-list (cons (cons env (point)) env-list)))
3661 ((member env which)
3662 (throw 'exit (cons env (point))))))
3663 (nreverse env-list)))))
3664
3665(defun reftex-word-before-point ()
3666 ;; Return the word before point. Word means here:
3667 ;; Consists of [a-zA-Z0-9.:] and ends at point or whitespace.
3668 (let ((pos (point)))
3669 (save-excursion
3670 (re-search-backward "[^ \t\n\r]" (point-min) 1)
3671 (setq pos (1+ (point)))
3672 (if (re-search-backward "[^a-zA-Z0-9\\\.:]" (point-min) 1)
3673 (forward-char 1))
3674 (buffer-substring-no-properties (point) pos))))
3675
3676;; ============================================================================
3677;;
3678;; Some generally useful functions
3679
3680(defun reftex-no-props (string)
3681 ;; Return STRING with all text properties removed
3682 (and (stringp string)
3683 (set-text-properties 0 (length string) nil string))
3684 string)
3685
3686(defun reftex-split (regexp string)
3687 ;; Split like perl
3688 (let ((start 0) list)
3689 (while (string-match regexp string start)
3690 (setq list (cons (substring string start (match-beginning 0)) list))
3691 (setq start (match-end 0)))
3692 (setq list (nreverse (cons (substring string start) list)))))
3693
3694(defun reftex-allow-for-ctrl-m (string)
3695 ;; convert STRING into a regexp, allowing ^M for \n
3696 (let ((start -2))
3697 (setq string (regexp-quote string))
3698 (while (setq start (string-match "[\n\r]" string (+ 3 start)))
3699 (setq string (replace-match "[\n\r]" nil t string)))
3700 string))
3701
3702(defun reftex-delete-list (elt-list list)
3703 ;; like delete, but with a list of things to delete
3704 ;; (original code from Rory Molinari)
3705 (while elt-list
3706 (setq list (delete (car elt-list) list)
3707 elt-list (cdr elt-list)))
3708 list)
3709
3710(defun reftex-get-buffer-visiting (file)
3711 ;; return a buffer visiting FILE
3712 (cond
3713 ((fboundp 'find-buffer-visiting) ; Emacs
3714 (find-buffer-visiting file))
3715 ((boundp 'find-file-compare-truenames) ; XEmacs
3716 (let ((find-file-compare-truenames t))
3717 (get-file-buffer file)))
3718 (t (error "Please report this problem to dominik@strw.leidenuniv.nl"))))
3719
3720(defun reftex-get-file-buffer-force (file &optional mark-to-kill)
3721 ;; Return a buffer visiting file. Make one, if necessary.
3722 ;; If neither such a buffer no the file exist, return nil.
3723 ;; If MARK-TO-KILL in non-nil, put any new buffers into the kill list."
3724
3725 (let ((buf (reftex-get-buffer-visiting file)))
3726 (cond
3727 (buf buf)
3728 ((file-exists-p file)
3729 (setq buf (find-file-noselect file))
3730 (if mark-to-kill
3731 (add-to-list 'reftex-buffers-to-kill buf))
3732 buf)
3733 (t nil))))
3734
3735(defun reftex-splice-symbols-into-list (list alist)
3736 ;; Splice the association in ALIST of any symbols in LIST into the list.
3737 ;; Return new list.
3738 (let (rtn tmp)
3739 (while list
3740 (while (and (not (null (car list)))
3741 (symbolp (car list)))
3742 (setq tmp (car list))
3743 (cond
3744 ((assoc tmp alist)
3745 (setq list (append (cdr (cdr (assoc tmp alist))) (cdr list))))
3746 (t
3747 (error "Cannot treat symbol %s in reftex-label-alist"
3748 (symbol-name tmp)))))
3749 (setq rtn (cons (car list) rtn)
3750 list (cdr list)))
3751 (nreverse rtn)))
3752
3753(defun reftex-uniquify (alist &optional keep-list)
3754 ;; Return a list of all elements in ALIST, but each car only once
3755 ;; Elements of KEEP-LIST are not removed even if duplicate
3756 (let (new elm)
3757 (while alist
3758 (setq elm (car alist)
3759 alist (cdr alist))
3760 (if (or (member (car elm) keep-list)
3761 (not (assoc (car elm) new)))
3762 (setq new (cons elm new))))
3763 (setq new (nreverse new))
3764 new))
3765
3766(defun reftex-use-fonts ()
3767 ;; Return t if we can and want to use fonts
3768 (and window-system
3769 reftex-use-fonts
3770 (boundp 'font-lock-keyword-face)))
3771
3772;; Highlighting uses overlays. If this is for XEmacs, we need to load
3773;; the overlay library, available in version 19.15
3774(and (not (fboundp 'make-overlay))
3775 (condition-case nil
3776 (require 'overlay)
3777 ('error
3778 (error "RefTeX needs overlay emulation (available in XEmacs 19.15)"))))
3779
3780;; We keep a vector with several different overlays to do our highlighting.
3781(defvar reftex-highlight-overlays [nil nil])
3782
3783;; Initialize the overlays
3784(aset reftex-highlight-overlays 0 (make-overlay 1 1))
3785(overlay-put (aref reftex-highlight-overlays 0) 'face 'highlight)
3786(aset reftex-highlight-overlays 1 (make-overlay 1 1))
3787(overlay-put (aref reftex-highlight-overlays 1) 'face 'highlight)
3788
3789;; Two functions for activating and deactivation highlight overlays
3790(defun reftex-highlight (index begin end &optional buffer)
3791 "Highlight a region with overlay INDEX."
3792 (move-overlay (aref reftex-highlight-overlays index)
3793 begin end (or buffer (current-buffer))))
3794(defun reftex-unhighlight (index)
3795 "Detatch overlay INDEX."
3796 (delete-overlay (aref reftex-highlight-overlays index)))
3797
3798(defun reftex-highlight-shall-die ()
3799 ;; Function used in pre-command-hook to remove highlights
3800 (remove-hook 'pre-command-hook 'reftex-highlight-shall-die)
3801 (reftex-unhighlight 0))
3802
3803;;; ---------------------------------------------------------------------------
3804;;;
3805;;; Cursor position after insertion of forms
3806
3807(defun reftex-position-cursor ()
3808 ;; Search back to question mark, delete it, leave point there
3809 (if (search-backward "\?" (- (point) 100) t)
3810 (delete-char 1)))
3811
3812(defun reftex-item ()
3813 "Insert an \\item and provide a label if the environments supports that."
3814 (interactive)
3815 (let ((env (car
3816 (reftex-what-environment '("itemize" "enumerate" "eqnarray")))))
3817
3818 (if (and env (not (bolp))) (newline))
3819
3820 (cond
3821
3822 ((string= env "eqnarray")
3823 (if (not (bolp))
3824 (newline))
3825 (reftex-label env)
3826 (insert "\n & & ")
3827 (beginning-of-line 1))
3828
3829 ((string= env "itemize")
3830 (newline)
3831 (insert "\\item "))
3832
3833 ((string= env "enumerate")
3834 (newline)
3835 (insert "\\item")
3836 (reftex-label env)
3837 (insert " "))
3838 (t
3839 (error "\\item command does not make sense here...")))))
3840
3841;;; ---------------------------------------------------------------------------
3842;;; ---------------------------------------------------------------------------
3843;;; ---------------------------------------------------------------------------
3844;;;
3845;;; Data Section: Definition of large constants
3846
3847
3848(defconst reftex-label-alist-builtin
3849 '(
3850 (LaTeX
3851 "LaTeX default environments"
3852 ("section" ?s "sec:" "~\\ref{%s}" t
3853 ("Part" "Chapter" "Chap." "Section" "Sec." "Sect." "Paragraph" "Par."
3854 "\\S" "Teil" "Kapitel" "Kap." "Abschnitt" ))
3855
3856 ("enumerate" ?n "item:" "~\\ref{%s}" "\\\\item\\(\\[[^]]*\\]\\)?"
3857 ("Item" "Punkt"))
3858
3859 ("equation" ?e "eq:" "~(\\ref{%s})" t
3860 ("Equation" "Eq." "Eqn." "Gleichung" "Gl."))
3861 ("eqnarray" ?e "eq:" nil "\\\\begin{eqnarray}\\|\\\\\\\\")
3862
3863 ("figure" ?f "fig:" "~\\ref{%s}" "\\\\caption\\(\\[[^]]*\\]\\)?{"
3864 ("Figure" "Fig." "Abbildung" "Abb."))
3865 ("figure*" ?f nil nil "\\\\caption\\(\\[[^]]*\\]\\)?{")
3866
3867 ("table" ?t "tab:" "~\\ref{%s}" "\\\\caption\\(\\[[^]]*\\]\\)?{"
3868 ("Table" "Tab." "Tabelle"))
3869 ("table*" ?t nil nil "\\\\caption\\(\\[[^]]*\\]\\)?{")
3870
3871 ("any" ?\ " " "\\ref{%s}" nil))
3872
3873 (Sideways
3874 "Sidewaysfigure and sidewaystable"
3875 ("sidewaysfigure" ?f nil nil "\\\\caption\\(\\[[^]]*\\]\\)?{")
3876 ("sidewaystable" ?t nil nil "\\\\caption\\(\\[[^]]*\\]\\)?{"))
3877
3878 (AMSTeX
3879 "AMS-LaTeX: amsmath package environents"
3880 ("align" ?e "eq:" "~\\eqref{%s}" "\\\\begin{align}\\|\\\\\\\\")
3881 ("gather" ?e "eq:" nil "\\\\begin{gather}\\|\\\\\\\\")
3882 ("multline" ?e "eq:" nil t)
3883 ("flalign" ?e "eq:" nil "\\\\begin{flalign}\\|\\\\\\\\")
3884 ("alignat" ?e "eq:" nil "\\\\begin{alignat}{[0-9]*}\\|\\\\\\\\"))
3885
3886 (AASTeX
3887 "AAS deluxetable environment"
3888 ("deluxetable" ?t "tab:" nil "\\\\caption{")))
3889 "The default label environment descriptions.")
3890
3891;;; ---------------------------------------------------------------------------
3892;;;
3893;;; Functions to compile the tables, reset the mode etc.
3894
3895(defun reftex-reset-mode ()
3896 "Reset RefTeX Mode. Required to implement changes to some list variables.
3897This function will compile the information in reftex-label-alist and similar
3898variables. It is called when RefTeX is first used, and after changes to
3899these variables via reftex-add-to-label-alist."
3900 (interactive)
3901
3902 ; record that we have done this
3903 (setq reftex-tables-dirty nil)
3904
3905 ;; To update buffer-local variables
3906 (hack-local-variables)
3907 (message "updating internal tables...")
3908 (reftex-compute-ref-cite-tables)
3909 (message "updating internal tables... done")
3910 (reftex-reset-scanning-information))
3911
3912(defun reftex-reset-scanning-information ()
3913 "Reset the symbols containing information from buffer scanning.
3914This enforces rescanning the buffer on next use."
3915 (if (and (string= reftex-last-toc-master (reftex-TeX-master-file))
3916 (get-buffer "*toc*"))
3917 (kill-buffer "*toc*"))
3918 (let ((symlist reftex-multifile-symbols)
3919 symbol)
3920 (while symlist
3921 (setq symbol (car symlist)
3922 symlist (cdr symlist))
3923 (if (and (symbolp (symbol-value symbol))
3924 (not (null (symbol-value symbol))))
3925 (set (symbol-value symbol) nil)))))
3926
3927(defun reftex-compute-ref-cite-tables ()
3928 ;; Update ref and cite tables
3929
3930 (interactive)
3931
3932 ;; Compile information in reftex-label-alist
3933 (let ((tmp (reftex-uniquify (reftex-splice-symbols-into-list
3934 (append
3935 reftex-label-alist
3936 reftex-label-alist-external-add-ons
3937 reftex-default-label-alist-entries)
3938 reftex-label-alist-builtin)
3939 '(nil)))
3940 entry env-or-mac typekeychar typekey prefix regexp
3941 fmt wordlist cmd qh-list)
3942
3943 (setq reftex-words-to-typekey-alist nil
3944 reftex-typekey-list nil
3945 reftex-typekey-to-format-alist nil
3946 reftex-typekey-to-prefix-alist nil
3947 reftex-env-or-mac-alist nil
3948 reftex-label-env-list nil
3949 reftex-label-mac-list nil)
3950 (while tmp
3951 (catch 'next-entry
3952 (setq entry (car tmp)
3953 env-or-mac (car entry)
3954 entry (cdr entry)
3955 tmp (cdr tmp))
3956 (if (null env-or-mac)
3957 (setq env-or-mac ""))
3958 (if (stringp (car entry))
3959 ;; This is before version 2.00 - convert entry to new format
3960 ;; This is just to keep old users happy
3961 (setq entry (cons (string-to-char (car entry))
3962 (cons (concat (car entry) ":")
3963 (cdr entry)))))
3964 (setq typekeychar (nth 0 entry)
3965 typekey (char-to-string typekeychar)
3966 prefix (nth 1 entry)
3967 fmt (nth 2 entry)
3968 regexp (nth 3 entry)
3969 wordlist (nth 4 entry))
3970 (if (stringp wordlist)
3971 ;; This is before version 2.04 - convert to new format
3972 (setq wordlist (nthcdr 4 entry)))
3973 (if typekey
3974 (add-to-list 'reftex-typekey-list typekey))
3975 (if (and typekey prefix)
3976 (add-to-list 'reftex-typekey-to-prefix-alist (cons typekey prefix)))
3977 (cond
3978 ((string-match "\\`\\\\" env-or-mac)
3979 ;; It's a macro
3980 (add-to-list 'reftex-label-mac-list env-or-mac))
3981 (t
3982 (or (string= env-or-mac "any")
3983 (string= env-or-mac "")
3984 (add-to-list 'reftex-label-env-list env-or-mac))))
3985 (and fmt
3986 (not (assoc typekey reftex-typekey-to-format-alist))
3987 (setq reftex-typekey-to-format-alist
3988 (cons (cons typekey fmt)
3989 reftex-typekey-to-format-alist)))
3990 (and (not (string= env-or-mac "any"))
3991 (not (string= env-or-mac ""))
3992 (not (assoc env-or-mac reftex-env-or-mac-alist))
3993 (setq reftex-env-or-mac-alist
3994 (cons (list env-or-mac typekey regexp)
3995 reftex-env-or-mac-alist)))
3996 (while (and wordlist (stringp (car wordlist)))
3997 (or (assoc (car wordlist) reftex-words-to-typekey-alist)
3998 (setq reftex-words-to-typekey-alist
3999 (cons (cons (downcase (car wordlist)) typekey)
4000 reftex-words-to-typekey-alist)))
4001 (setq wordlist (cdr wordlist)))
4002 (cond
4003 ((string= "" env-or-mac) nil)
4004 ((assoc typekey qh-list)
4005 (setcdr (assoc typekey qh-list)
4006 (concat (cdr (assoc typekey qh-list)) " " env-or-mac)))
4007 (t
4008 (setq qh-list (cons (cons typekey env-or-mac) qh-list))))))
4009
4010 (setq qh-list (nreverse qh-list))
4011 (setq reftex-typekey-to-prefix-alist
4012 (nreverse reftex-typekey-to-prefix-alist))
4013 (setq reftex-type-query-prompt
4014 (concat "Label type: "
4015 (mapconcat '(lambda(x)
4016 (format "[%s]" (car x)))
4017 qh-list " ")
4018 " (?=Help)"))
4019 (setq reftex-type-query-help
4020 (concat "SELECT A LABEL TYPE:\n--------------------\n"
4021 (mapconcat '(lambda(x)
4022 (format " [%s] %s"
4023 (car x) (cdr x)))
4024 qh-list "\n")))))
4025
4026;;; Keybindings --------------------------------------------------------------
4027
4028(define-key reftex-mode-map "\C-c-" 'reftex-item)
4029(define-key reftex-mode-map "\C-c=" 'reftex-toc)
4030(define-key reftex-mode-map "\C-c(" 'reftex-label)
4031(define-key reftex-mode-map "\C-c)" 'reftex-reference)
4032(define-key reftex-mode-map "\C-c[" 'reftex-citation)
4033(define-key reftex-mode-map "\C-c&" 'reftex-view-crossref)
4034
4035;; If the user requests so, she can have a few more bindings:
4036(cond
4037 (reftex-extra-bindings
4038 (define-key reftex-mode-map "\C-ct" 'reftex-toc)
4039 (define-key reftex-mode-map "\C-cl" 'reftex-label)
4040 (define-key reftex-mode-map "\C-cr" 'reftex-reference)
4041 (define-key reftex-mode-map "\C-cc" 'reftex-citation)
4042 (define-key reftex-mode-map "\C-cv" 'reftex-view-crossref)
4043 (define-key reftex-mode-map "\C-cg" 'reftex-grep-document)
4044 (define-key reftex-mode-map "\C-cs" 'reftex-search-document)))
4045
4046;;; Menus --------------------------------------------------------------------
4047
4048;; Define a menu for the menu bar if Emacs is running under X
4049
4050(require 'easymenu)
4051
4052(easy-menu-define
4053 reftex-mode-menu reftex-mode-map
4054 "Menu used in RefTeX mode"
4055 '("Ref"
4056 ["Table of Contents" reftex-toc t]
4057 "----"
4058 ["\\label{}" reftex-label t]
4059 ["\\ref{}" reftex-reference t]
4060 ["\\cite{}" reftex-citation t]
4061 ["View crossref" reftex-view-crossref t]
4062 "----"
4063 ("Search and Replace"
4064 ["Search whole document" reftex-search-document t]
4065 ["Replace in document" reftex-query-replace-document t]
4066 ["Grep on document" reftex-grep-document t]
4067 "----"
4068 ["Find duplicate labels" reftex-find-duplicate-labels t]
4069 ["Change label and refs" reftex-change-label t]
4070 "----"
4071 ["Create TAGS file" reftex-create-tags-file t])
4072 "----"
4073 ["Parse document" reftex-parse-document t]
4074 ["Reset RefTeX Mode" reftex-reset-mode t]
4075 ["Customize RefTeX" reftex-customize t]))
4076
4077;;; Run Hook ------------------------------------------------------------------
4078
4079(run-hooks 'reftex-load-hook)
4080
4081;;; That's it! ----------------------------------------------------------------
4082
4083; Make sure tabels are compiled
4084(message "updating internal tables...")
4085(reftex-compute-ref-cite-tables)
4086(setq reftex-tables-dirty nil)
4087
4088(provide 'reftex)
4089
4090;;;============================================================================
4091
4092;;; reftex.el end here