(inferior-octave-prompt): Also match prompts of the form
[bpt/emacs.git] / lisp / textmodes / reftex.el
CommitLineData
5abdc915 1;;; reftex.el --- Minor mode for doing \label, \ref and \cite in LaTeX
2faef409 2;; Copyright (c) 1997, 1998 Free Software Foundation, Inc.
a7ec1775
RS
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;;
fba437e6
RS
28;; RefTeX is a minor mode with distinct support for \ref, \label and
29;; \cite commands in (multi-file) LaTeX documents.
a7ec1775
RS
30;; Labels are created semi-automatically. Definition context of labels is
31;; provided when creating a reference. Citations are simplified with
396e0b08
KH
32;; efficient database lookup. A table of contents buffer provides easy
33;; access to any part of a document.
a7ec1775 34;;
2faef409 35;;
a6611c0d
CD
36;; INSTALLATION
37;; ------------
38;;
39;; If you got reftex.el with an Emacs distribution, it is already
40;; installed. If not, follow the instructions in the INSTALL file of
41;; the distribution.
42;;
b849548d 43;; To turn RefTeX Mode on and off in a particular buffer, use
a7ec1775
RS
44;; `M-x reftex-mode'.
45;;
b849548d
CD
46;; To turn on RefTeX Mode for all LaTeX files, add one of the following
47;; lines to your .emacs file:
a7ec1775
RS
48;;
49;; (add-hook 'LaTeX-mode-hook 'turn-on-reftex) ; with AUCTeX LaTeX mode
50;; (add-hook 'latex-mode-hook 'turn-on-reftex) ; with Emacs latex mode
51;;
396e0b08 52;;
2faef409
RS
53;; DOCUMENTATION
54;; -------------
396e0b08 55;;
a6611c0d
CD
56;; See below for a short summary of how to use RefTeX.
57;;
2faef409
RS
58;; There is an extensive texinfo document describing RefTeX in detail.
59;; When you are getting reftex.el with the Emacs distribution, the
60;; info files should already be installed. To view this
61;; documentation, use `M-x reftex-info RET'.
a7ec1775 62;;
a6611c0d 63;; The documentation in various formats is also available at
396e0b08 64;;
2faef409 65;; http://www.strw.leidenuniv.nl/~dominik/Tools/
396e0b08 66;;
2faef409
RS
67;;---------------------------------------------------------------------------
68;;
69;; RefTeX in a Nutshell
70;; ====================
71;;
b849548d
CD
72;; 1. Labels and References
73;; RefTeX distinguishes labels for different environments. It knows
74;; about all standard environments (and many others), and can be
75;; configured to recognize any additional labeled environments you
a6611c0d 76;; have defined yourself (variable REFTEX-LABEL-ALIST).
b849548d
CD
77;;
78;; * Creating Labels
79;; Type `C-c (' (`reftex-label') to insert a label at point.
80;; RefTeX will either
81;; - derive a label from context (default for section labels)
82;; - prompt for a label string (default for figures and
83;; tables) or
84;; - insert a simple label made of a prefix and a number (all
85;; other environments).
86;; Which labels are created how is configurable (variable
87;; REFTEX-INSERT-LABEL-FLAGS).
88;;
89;; * Referencing Labels
90;; In order to make a reference, type `C-c )'
91;; (`reftex-reference'). This shows an outline of the document
92;; with all labels of a certain type (figure, equation,...) and
93;; context of the label definition. Selecting a label inserts a
94;; `\ref{LABEL}' macro into the original buffer.
95;;
96;; 2. Citations
97;; After typing `C-c [' (`reftex-citation'), RefTeX will let you
98;; specify a regular expression to search in current BibTeX database
99;; files (as specified in the `\bibliography' command) and pull out a
100;; list of matches for you to choose from. The list is *formatted*
101;; and sorted. The selected article is referenced as `\cite{KEY}'
102;; (customizable with variable REFTEX-CITE-FORMAT).
103;;
104;; 3. Viewing Cross References
105;; When no other message occupies the echo area and point is idle on
106;; the argument of a `\ref' or `\cite' macro, the echo area will
107;; display information about the citation/cross reference.
a6611c0d 108;; With point on the argument of such a macro, press `C-c &'
b849548d
CD
109;; (`reftex-view-crossref'), or click with `S-mouse-2' on the macro
110;; argument. This will display the corresponding label definition or
111;; BibTeX database entry in another window.
112;;
113;; 4. Table of Contents
114;; Typing `C-c =' (`reftex-toc') will show a table of contents of the
115;; document. From that buffer, you can jump quickly to every part of
116;; your document.
117;;
118;; 5. Multifile Documents
119;; Multifile Documents are fully supported. RefTeX will provide cross
120;; referencing information from all files which are part of the
121;; document, and even across document borders (`xr.sty').
122;;
123;; 6. Document Parsing
124;; RefTeX needs to parse the document in order to find labels and
125;; other information. It does it automatically once, when you start
126;; working with a document. RefTeX updates its lists internally when
127;; you make a new label with `reftex-label'. To enforce reparsing,
128;; call any of the commands described above with a raw `C-u' prefix,
129;; or press the `r' key in the label selection buffer or the table of
130;; contents buffer.
131;;
a6611c0d
CD
132;; 7. Useful Settings
133;; To make RefTeX faster for large documents include, and to integrate
134;; it with AUCTeX, try these:
135;;
b849548d
CD
136;; (setq reftex-enable-partial-scans t)
137;; (setq reftex-save-parse-info t)
138;; (setq reftex-use-multiple-selection-buffers t)
a6611c0d 139;; (setq reftex-plug-into-AUCTeX t)
a7ec1775 140;;
a7ec1775
RS
141;;---------------------------------------------------------------------------
142;;
143;; AUTHOR
396e0b08 144;; ======
a7ec1775
RS
145;;
146;; Carsten Dominik <dominik@strw.LeidenUniv.nl>
147;;
148;; with contributions from Stephen Eglen
149;;
150;; The newest version of RefTeX can be found at
151;;
152;; http://www.strw.leidenuniv.nl/~dominik/Tools/
a6611c0d 153;; ftp://ftp.strw.leidenuniv.nl/pub/dominik/
a7ec1775 154;;
b849548d
CD
155;; At that site you can also get version 3.22 of RefTeX which is still
156;; compatible with Emacs 19. The file you are reading now as well as the
157;; ones distributed with Emacs 20 are not.
2faef409 158;;
a7ec1775
RS
159;; THANKS TO:
160;; ---------
2faef409
RS
161;; Thanks to the people on the Net who have used RefTeX and helped
162;; developing it with their reports. In particular thanks to
a7ec1775 163;;
2faef409
RS
164;; F. Burstall, Alastair Burt, Soren Dayton, Stephen Eglen,
165;; Karl Eichwalder, Peter Galbraith, Dieter Kraft, Adrian Lanz,
166;; Rory Molinari, Laurent Mugnier, Sudeep Kumar Palat, Daniel Polani,
167;; Robin Socha, Richard Stanton, Allan Strand, Jan Vroonhof,
a6611c0d 168;; Christoph Wedler, Alan Williams.
a7ec1775 169;;
2faef409
RS
170;; Finally thanks to Uwe Bolick who first got me (some years ago) into
171;; supporting LaTeX labels and references with an Editor (which was
172;; MicroEmacs at the time).
025bb635 173;;
a6611c0d 174;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
c52bdfca 175;;
a6611c0d 176;;;;;;
a7ec1775
RS
177\f
178;;; Code:
179
396e0b08
KH
180(eval-when-compile (require 'cl))
181
a7ec1775 182;; Stuff that needs to be there when we use defcustom
a7ec1775
RS
183(require 'custom)
184
185(defvar reftex-tables-dirty t
186 "Flag showing if tables need to be re-computed.")
187
188(eval-and-compile
189 (defun reftex-set-dirty (symbol value)
190 (setq reftex-tables-dirty t)
191 (set symbol value)))
192
b849548d
CD
193;;; ======================================================================
194;;;
195;;; Configuration Section
a7ec1775 196
396e0b08
KH
197;; Define the two constants which are needed during compilation
198
199(eval-and-compile
200(defconst reftex-label-alist-builtin
201 '(
202 ;; Some aliases, mostly for backward compatibility
203 (Sideways "Alias for -->rotating" (rotating))
204 (AMSTeX "amsmath with eqref macro"
205 ((nil ?e nil "~\\eqref{%s}")
206 amsmath))
207
208 ;; Individual package defaults
209 (amsmath "AMS-LaTeX math environments"
210 (("align" ?e nil nil eqnarray-like)
211 ("gather" ?e nil nil eqnarray-like)
212 ("multline" ?e nil nil t)
213 ("flalign" ?e nil nil eqnarray-like)
214 ("alignat" ?e nil nil alignat-like)
215 ("xalignat" ?e nil nil alignat-like)
216 ("xxalignat" ?e nil nil alignat-like)
217 ("subequations" ?e nil nil t)))
218
219 (endnotes "The \\endnote macro"
2faef409 220 (("\\endnote[]{}" ?n nil nil 2 (regexp "Endnotes?"))))
396e0b08
KH
221
222 (fancybox "The Beqnarray environment"
223 (("Beqnarray" ?e nil nil eqnarray-like)))
224
225 (floatfig "The floatingfigure environment"
226 (("floatingfigure" ?f nil nil caption)))
227
228 (longtable "The longtable environment"
229 (("longtable" ?t nil nil caption)))
230
231 (picinpar "The figwindow and tabwindow environments"
232 (("figwindow" ?f nil nil 1)
233 ("tabwindow" ?f nil nil 1)))
234
235 (rotating "Sidewaysfigure and table"
236 (("sidewaysfigure" ?f nil nil caption)
237 ("sidewaystable" ?t nil nil caption)))
238
29d593f8
KH
239 (sidecap "CSfigure and SCtable"
240 (("SCfigure" ?f nil nil caption)
241 ("SCtable" ?t nil nil caption)))
242
396e0b08
KH
243 (subfigure "Subfigure environments/macro"
244 (("subfigure" ?f nil nil caption)
245 ("subfigure*" ?f nil nil caption)
246 ("\\subfigure[]{}" ?f nil nil 1)))
247
248 (supertab "Supertabular environment"
249 (("supertabular" ?t nil nil "\\tablecaption{")))
250
251 (wrapfig "The wrapfigure environment"
252 (("wrapfigure" ?f nil nil caption)))
253
254 ;; The LaTeX core stuff
255 (LaTeX "LaTeX default environments"
256 (("section" ?s "sec:" "~\\ref{%s}" (nil . t)
b849548d
CD
257 (regexp "parts?" "chapters?" "chap\\." "sections?" "sect?\\."
258 "paragraphs?" "par\\."
2faef409 259 "\\\\S" "\247" "Teile?" "Kapitel" "Kap\\." "Abschnitte?"
b849548d 260 "appendi\\(x\\|ces\\)" "App\\." "Anh\"?ange?" "Anh\\."))
396e0b08
KH
261
262 ("enumerate" ?i "item:" "~\\ref{%s}" item
b849548d 263 (regexp "items?" "Punkte?"))
2faef409 264
396e0b08 265 ("equation" ?e "eq:" "~(\\ref{%s})" t
b849548d 266 (regexp "equations?" "eqs?\\." "eqn\\." "Gleichung\\(en\\)?" "Gl\\."))
396e0b08 267 ("eqnarray" ?e "eq:" nil eqnarray-like)
2faef409 268
396e0b08 269 ("figure" ?f "fig:" "~\\ref{%s}" caption
b849548d 270 (regexp "figure?[sn]?" "figs?\\." "Abbildung\\(en\\)?" "Abb\\."))
396e0b08 271 ("figure*" ?f nil nil caption)
2faef409 272
396e0b08 273 ("table" ?t "tab:" "~\\ref{%s}" caption
b849548d 274 (regexp "tables?" "tab\\." "Tabellen?"))
396e0b08 275 ("table*" ?t nil nil caption)
2faef409 276
396e0b08 277 ("\\footnote[]{}" ?n "note:" "~\\ref{%s}" 2
b849548d 278 (regexp "footnotes?" "notes?" "Anmerkung\\(en\\)?" "Anm\\."))
2faef409 279
b849548d
CD
280 ("any" ?\ " " "~\\ref{%s}" nil)
281
282 ;; The label macro is hard coded, but it *could* be defined like this:
283 ;;("\\label{*}" nil nil nil nil)
284 ))
396e0b08
KH
285
286 )
287 "The default label environment descriptions.
288Lower-case symbols correspond to a style file of the same name in the LaTeX
289distribution. Mixed-case symbols are convenience aliases.")
290
291(defconst reftex-cite-format-builtin
292 '(
293 (default "Default macro \\cite{%l}"
294 "\\cite{%l}")
295 (natbib "The Natbib package"
296 ((?\C-m . "\\cite{%l}")
297 (?t . "\\citet{%l}")
298 (?T . "\\citet*{%l}")
299 (?p . "\\citep{%l}")
300 (?P . "\\citep*{%l}")
301 (?e . "\\citep[e.g.][]{%l}")
b849548d 302 (?s . "\\citep[see][]{%l}")
396e0b08 303 (?a . "\\citeauthor{%l}")
b849548d 304 (?A . "\\citeauthor*{%l}")
396e0b08
KH
305 (?y . "\\citeyear{%l}")))
306 (harvard "The Harvard package"
307 ((?\C-m . "\\cite{%l}")
308 (?p . "\\cite{%l}")
309 (?t . "\\citeasnoun{%l}")
310 (?n . "\\citeasnoun{%l}")
311 (?s . "\\possessivecite{%l}")
312 (?e . "\\citeaffixed{%l}{?}")
313 (?y . "\\citeyear{%l}")
314 (?a . "\\citename{%l}")))
315 (chicago "The Chicago package"
316 ((?\C-m . "\\cite{%l}")
317 (?t . "\\citeN{%l}")
318 (?T . "\\shortciteN{%l}")
319 (?p . "\\cite{%l}")
320 (?P . "\\shortcite{%l}")
321 (?a . "\\citeA{%l}")
322 (?A . "\\shortciteA{%l}")
2faef409 323 (?y . "\\citeyear{%l}")))
396e0b08
KH
324 (astron "The Astron package"
325 ((?\C-m . "\\cite{%l}")
326 (?p . "\\cite{%l}" )
327 (?t . "%2a (\\cite{%l})")))
328 (author-year "Do-it-yourself Author-year"
329 ((?\C-m . "\\cite{%l}")
330 (?t . "%2a (%y)\\nocite{%l}")
331 (?p . "(%2a %y\\nocite{%l})")))
332 (locally "Full info in parenthesis"
333 "(%2a %y, %j %v, %P, %e: %b, %u, %s %<)")
396e0b08 334 )
b849548d 335 "Builtin versions of the citation format.
396e0b08
KH
336The following conventions are valid for all alist entries:
337`?\C-m' should always point to a straight \\cite{%l} macro.
338`?t' should point to a textual citation (citation as a noun).
339`?p' should point to a parenthetical citation.")
340)
341
a7ec1775
RS
342;; Configuration Variables and User Options for RefTeX ------------------
343
344(defgroup reftex nil
345 "LaTeX label and citation support."
346 :tag "RefTeX"
396e0b08
KH
347 :link '(url-link :tag "Home Page"
348 "http://strw.leidenuniv.nl/~dominik/Tools/")
349 :link '(emacs-commentary-link :tag "Commentary in reftex.el" "reftex.el")
a7ec1775
RS
350 :prefix "reftex-"
351 :group 'tex)
352
a7ec1775 353(defgroup reftex-label-support nil
c52bdfca 354 "Support for creation, insertion and referencing of labels in LaTeX."
a7ec1775
RS
355 :group 'reftex)
356
357(defgroup reftex-defining-label-environments nil
c52bdfca 358 "Definition of environments and macros to do with label."
a7ec1775
RS
359 :group 'reftex-label-support)
360
396e0b08
KH
361(defcustom reftex-default-label-alist-entries
362 '(amsmath endnotes fancybox floatfig longtable picinpar
29d593f8 363 rotating sidecap subfigure supertab wrapfig LaTeX)
396e0b08
KH
364 "Default label alist specifications. LaTeX should be the last entry.
365This list describes the default label environments RefTeX should always use.
366It is probably a mistake to remove the LaTeX symbol from this list.
367
368The options include:
369LaTeX The standard LaTeX environments.
370Sideways The sidewaysfigure and sidewaystable environments.
371AMSTeX The math environments in the AMS-LaTeX amsmath package.
372
373For the full list of options, try
374
375M-x customize-variable RET reftex-default-label-alist-entries RET."
376 :group 'reftex-defining-label-environments
377 :set 'reftex-set-dirty
378 :type `(set
379 :indent 4
380 :inline t
381 :greedy t
382 ,@(mapcar
383 (function
384 (lambda (x)
385 (list 'const ':tag (concat (symbol-name (nth 0 x))
386 ": " (nth 1 x))
387 (nth 0 x))))
388 reftex-label-alist-builtin)))
389
a7ec1775 390(defcustom reftex-label-alist nil
fba437e6 391 "Alist with information on environments for \\label-\\ref use.
a7ec1775 392
396e0b08
KH
393This docstring is easier to understand after reading the configuration
394examples in `reftex.el'. Looking at the builtin defaults in the constant
395`reftex-label-alist-builtin' may also be instructive.
396
397Set this variable to define additions and changes to the default. The only
398things you MUST NOT change is that `?s' is the type indicator for section
399labels, and SPC for the `any' label type. These are hard-coded at other
400places in the code.
a7ec1775 401
396e0b08
KH
402Each list entry describes either an environment carrying a counter for use
403with \\label and \\ref, or a LaTeX macro defining a label as (or inside)
404one of its arguments. The elements of each list entry are:
a7ec1775
RS
405
4060. Name of the environment (like \"table\") or macro (like \"\\\\myfig\").
396e0b08
KH
407 For macros, indicate the macro arguments for best results, as in
408 \"\\\\myfig[]{}{}{*}{}\". Use square brackets for optional arguments,
409 a star to mark the label argument, if any. The macro does not have to
410 have a label argument - you could also use \\label{..} inside one of
411 its arguments.
a7ec1775
RS
412 Special names: `section' for section labels, `any' to define a group
413 which contains all labels.
396e0b08 414 This may also be nil if the entry is only meant to change some settings
a7ec1775
RS
415 associated with the type indicator character (see below).
416
396e0b08
KH
4171. Type indicator character, like `?t', must be a printable ASCII character.
418 The type indicator is a single character which defines a label type.
419 Any label inside the environment or macro is assumed to belong to this
420 type. The same character may occur several times in this list, to cover
421 cases in which different environments carry the same label type (like
422 `equation' and `eqnarray').
b849548d
CD
423 If the type indicator is nil and the macro has a label argument {*},
424 the macro defines neutral labels just like \label. In this case
425 the reminder of this entry is ignored.
a7ec1775
RS
426
4272. Label prefix string, like \"tab:\".
f52b232e 428 The prefix is a short string used as the start of a label. It may be the
396e0b08 429 empty string. The prefix may contain the following `%' escapes:
206c6f82
RS
430 %f Current file name with directory and extension stripped.
431 %F Current file name relative to directory of master file.
432 %u User login name, on systems which support this.
433
434 Example: In a file `intro.tex', \"eq:%f:\" will become \"eq:intro:\").
a7ec1775 435
206c6f82
RS
4363. Format string for reference insert in buffer. `%s' will be replaced by
437 the label.
2faef409
RS
438 When the format starts with `~', the `~' will only be inserted if
439 there is not already a whitespace before point.
a7ec1775
RS
440
4414. Indication on how to find the short context.
f52b232e
RS
442 - If nil, use the text following the \\label{...} macro.
443 - If t, use
a7ec1775 444 - the section heading for section labels.
396e0b08
KH
445 - text following the \\begin{...} statement of environments.
446 (not a good choice for environments like eqnarray or enumerate,
447 where one has several labels in a single environment).
2faef409 448 - text after the macro name (starting with the first arg) for macros.
396e0b08
KH
449 - If an integer, use the nth argument of the macro. As a special case,
450 1000 means to get text after the last macro argument.
f52b232e
RS
451 - If a string, use as regexp to search *backward* from the label. Context
452 is then the text following the end of the match. E.g. putting this to
baec1250 453 \"\\\\\\\\caption[[{]\" will use the caption in a figure or table
396e0b08 454 environment.
c52bdfca 455 \"\\\\\\\\begin{eqnarray}\\\\|\\\\\\\\\\\\\\\\\" works for eqnarrays.
396e0b08
KH
456 - If any of `caption', `item', `eqnarray-like', `alignat-like', this
457 symbol will internally be translated into an appropriate regexp
458 (see also the variable `reftex-default-context-regexps').
a7ec1775 459 - If a function, call this function with the name of the environment/macro
f52b232e
RS
460 as argument. On call, point will be just after the \\label macro. The
461 function is expected to return a suitable context string. It should
a7ec1775 462 throw an exception (error) when failing to find context.
206c6f82
RS
463 As an example, here is a function returning the 10 chars following
464 the label macro as context:
a7ec1775
RS
465
466 (defun my-context-function (env-or-mac)
467 (if (> (point-max) (+ 10 (point)))
468 (buffer-substring (point) (+ 10 (point)))
469 (error \"Buffer too small\")))
470
206c6f82
RS
471 Label context is used in two ways by RefTeX: For display in the label
472 menu, and to derive a label string. If you want to use a different
473 method for each of these, specify them as a dotted pair.
474 E.g. `(nil . t)' uses the text after the label (nil) for display, and
475 text from the default position (t) to derive a label string. This is
476 actually used for section labels.
477
f52b232e
RS
478 Setting the variable `reftex-use-text-after-label-as-context' to t
479 overrides the setting here.
a7ec1775 480
c52bdfca
RS
4815. List of magic words which identify a reference to be of this type.
482 If the word before point is equal to one of these words when calling
206c6f82
RS
483 `reftex-reference', the label list offered will be automatically
484 restricted to labels of the correct type.
2faef409
RS
485 If the first element of this wordlist is the symbol `regexp', the
486 strings are interpreted as regular expressions. RefTeX will add
487 a \"\\\\W\" to the beginning and other stuff to the end of the regexp.
a7ec1775
RS
488
489If the type indicator characters of two or more entries are the same, RefTeX
490will use
491 - the first non-nil format and prefix
492 - the magic words of all involved entries.
493
f52b232e 494Any list entry may also be a symbol. If that has an association in
2faef409
RS
495`reftex-label-alist-builtin', the cddr of that association is spliced into the
496list. However, builtin defaults should normally be set with the variable
497`reftex-default-label-alist-entries."
a7ec1775
RS
498 :group 'reftex-defining-label-environments
499 :set 'reftex-set-dirty
206c6f82 500 :type
396e0b08 501 `(repeat
b849548d 502 (choice :tag "Package or Detailed "
396e0b08 503 :value ("" ?a nil nil nil nil)
b849548d 504 (list :tag "Detailed Entry"
396e0b08
KH
505 :value ("" ?a nil nil nil nil)
506 (choice :tag "Environment or \\macro "
507 (const :tag "Ignore, just use typekey" nil)
508 (string ""))
b849548d
CD
509 (choice :tag "Type specification "
510 (const :tag "unspecified, like in \\label" nil)
511 (character :tag "Char " ?a))
396e0b08
KH
512 (choice :tag "Label prefix string "
513 (const :tag "Default" nil)
514 (string :tag "String" "lab:"))
515 (choice :tag "Label reference format"
516 (const :tag "Default" nil)
517 (string :tag "String" "~\\ref{%s}"))
b849548d
CD
518 (choice :tag "Context method "
519 (const :tag "Default position" t)
520 (const :tag "After label" nil)
521 (number :tag "Macro arg nr" 1)
522 (regexp :tag "Regexp" "")
523 (const :tag "Caption in float" caption)
524 (const :tag "Item in list" item)
525 (const :tag "Eqnarray-like" eqnarray-like)
526 (const :tag "Alignat-like" alignat-like)
527 (symbol :tag "Function" my-func))
528 (repeat :tag "Magic words" :extra-offset 2 (string)))
396e0b08
KH
529 (choice
530 :tag "Package"
206c6f82 531 :value AMSTeX
396e0b08
KH
532 ,@(mapcar
533 (function
534 (lambda (x)
2faef409 535 (list 'const ':tag (concat (symbol-name (nth 0 x)))
396e0b08
KH
536 (nth 0 x))))
537 reftex-label-alist-builtin)))))
a7ec1775 538
baec1250
KH
539;; LaTeX section commands and level numbers
540(defcustom reftex-section-levels
541 '(
542 ("part" . 0)
543 ("chapter" . 1)
544 ("section" . 2)
545 ("subsection" . 3)
546 ("subsubsection" . 4)
547 ("paragraph" . 5)
548 ("subparagraph" . 6)
549 ("subsubparagraph" . 7)
550 )
551 "Commands and levels used for defining sections in the document.
552The car of each cons cell is the name of the section macro. The cdr is a
553number indicating its level."
554 :group 'reftex-defining-label-environments
555 :set 'reftex-set-dirty
556 :type '(repeat
557 (cons (string :tag "sectioning macro" "")
558 (number :tag "level " 0))))
559
560(defcustom reftex-default-context-regexps
561 '((caption . "\\\\\\(rot\\)?caption\\*?[[{]")
562 (item . "\\\\item\\(\\[[^]]*\\]\\)?")
563 (eqnarray-like . "\\\\begin{%s}\\|\\\\\\\\")
564 (alignat-like . "\\\\begin{%s}{[0-9]*}\\|\\\\\\\\"))
565"Alist with default regular expressions for finding context.
566The form (format regexp (regexp-quote environment)) is used to calculate
567the final regular expression - so %s will be replaced with the environment
568or macro."
569 :group 'reftex-defining-label-environments
570 :type '(repeat (cons (symbol) (regexp))))
571
a7ec1775
RS
572(defcustom reftex-use-text-after-label-as-context nil
573 "*t means, grab context from directly after the \\label{..} macro.
574This is the fastest method for obtaining context of the label definition, but
c52bdfca
RS
575requires discipline when placing labels. Setting this variable to t takes
576precedence over the individual settings in `reftex-label-alist'.
a7ec1775
RS
577This variable may be set to t, nil, or a string of label type letters
578indicating the label types for which it should be true."
579 :group 'reftex-defining-label-environments
580 :set 'reftex-set-dirty
581 :type '(choice
396e0b08
KH
582 (const :tag "on" t) (const :tag "off" nil)
583 (string :tag "Selected label types")))
a7ec1775
RS
584
585;; Label insertion
586
587(defgroup reftex-making-and-inserting-labels nil
c52bdfca 588 "Options on how to create new labels."
a7ec1775
RS
589 :group 'reftex-label-support)
590
591(defcustom reftex-insert-label-flags '("s" "sft")
c52bdfca 592 "Flags governing label insertion. First flag DERIVE, second flag PROMPT.
a7ec1775
RS
593
594If DERIVE is t, RefTeX will try to derive a sensible label from context.
595A section label for example will be derived from the section heading.
596The conversion of the context to a legal label is governed by the
c52bdfca 597specifications given in `reftex-derive-label-parameters'.
a7ec1775 598If RefTeX fails to derive a label, it will prompt the user.
396e0b08
KH
599If DERIVE is nil, the label generated will consist of the prefix and a
600unique number, like `eq:23'.
a7ec1775 601
c52bdfca 602If PROMPT is t, the user will be prompted for a label string. The prompt will
a7ec1775
RS
603already contain the prefix, and (if DERIVE is t) a default label derived from
604context. When PROMPT is nil, the default label will be inserted without
605query.
606
c52bdfca 607So the combination of DERIVE and PROMPT controls label insertion. Here is a
a7ec1775
RS
608table describing all four possibilities:
609
610DERIVE PROMPT ACTION
611-------------------------------------------------------------------------
c52bdfca
RS
612 nil nil Insert simple label, like eq:22 or sec:13. No query.
613 nil t Prompt for label.
614 t nil Derive a label from context and insert without query.
615 t t Derive a label from context and prompt for confirmation.
a7ec1775
RS
616
617Each flag may be set to t, nil, or a string of label type letters
2faef409
RS
618indicating the label types for which it should be true. The strings work
619like character classes.
c52bdfca 620Thus, the combination may be set differently for each label type. The
a7ec1775 621default settings \"s\" and \"sft\" mean: Derive section labels from headings
c52bdfca 622(with confirmation). Prompt for figure and table labels. Use simple labels
2faef409
RS
623without confirmation for everything else.
624The available label types are: s (section), f (figure), t (table), i (item),
625e (equation), n (footnote), plus any definitions in `reftex-label-alist'."
a7ec1775
RS
626 :group 'reftex-making-and-inserting-labels
627 :type '(list (choice :tag "Derive label from context"
628 (const :tag "always" t)
629 (const :tag "never" nil)
206c6f82 630 (string :tag "selected label types" ""))
a7ec1775
RS
631 (choice :tag "Prompt for label string "
632 :entry-format " %b %v"
633 (const :tag "always" t)
634 (const :tag "never" nil)
206c6f82 635 (string :tag "selected label types" ""))))
a7ec1775 636
b849548d
CD
637(defcustom reftex-string-to-label-function 'reftex-string-to-label
638 "Function to turn an arbitrary string into a legal label.
639RefTeX's default function uses the variable `reftex-derive-label-parameters'."
640 :group 'reftex-making-and-inserting-labels
641 :type 'symbol)
642
a6611c0d 643(defcustom reftex-translate-to-ascii-function 'reftex-latin1-to-ascii
b849548d 644 "Filter function which will process a context string before it is used
a6611c0d
CD
645to derive a label from it. The intended application is to convert ISO or
646Mule characters into something legal in labels. The default function
647removes the accents from Latin-1 characters. X-Symbol (>=2.6) sets this
648variable to the much more general `x-symbol-translate-to-ascii'."
b849548d
CD
649 :group 'reftex-making-and-inserting-labels
650 :type 'symbol)
651
396e0b08 652(defcustom reftex-derive-label-parameters '(3 20 t 1 "-"
b849548d 653 ("the" "on" "in" "off" "a" "for" "by" "of" "and" "is" "to") t)
a7ec1775
RS
654 "Parameters for converting a string into a label.
655NWORDS Number of words to use.
656MAXCHAR Maximum number of characters in a label string.
657ILLEGAL nil: Throw away any words containing characters illegal in labels.
658 t: Throw away only the illegal characters, not the whole word.
659ABBREV nil: Never abbreviate words.
c52bdfca 660 t: Always abbreviate words (see `reftex-abbrev-parameters').
a7ec1775
RS
661 not t and not nil: Abbreviate words if necessary to shorten
662 label string below MAXCHAR.
c52bdfca 663SEPARATOR String separating different words in the label.
b849548d
CD
664IGNOREWORDS List of words which should not be part of labels.
665DOWNCASE t: Downcase words before using them."
a7ec1775
RS
666 :group 'reftex-making-and-inserting-labels
667 :type '(list (integer :tag "Number of words " 3)
396e0b08
KH
668 (integer :tag "Maximum label length " 20)
669 (choice :tag "Illegal characters in words"
670 (const :tag "throw away entire word" nil)
671 (const :tag "throw away single chars" t))
672 (choice :tag "Abbreviate words "
673 (const :tag "never" nil)
674 (const :tag "always" t)
675 (const :tag "when label is too long" 1))
676 (string :tag "Separator between words " "-")
677 (repeat :tag "Ignore words"
678 :entry-format " %i %d %v"
b849548d
CD
679 (string :tag ""))
680 (option (boolean :tag "Downcase words "))))
396e0b08 681
a6611c0d
CD
682(defcustom reftex-label-illegal-re "[^-a-zA-Z0-9_+=:;,.]"
683 "Regexp matching characters not legal in labels."
a7ec1775 684 :group 'reftex-making-and-inserting-labels
a6611c0d 685 :type '(regexp :tag "Regular Expression"))
a7ec1775 686
b849548d 687(defcustom reftex-abbrev-parameters '(4 2 "^aeiou" "aeiou")
a7ec1775 688 "Parameters for abbreviation of words.
c52bdfca
RS
689MIN-CHARS Minimum number of characters remaining after abbreviation.
690MIN-KILL Minimum number of characters to remove when abbreviating words.
691BEFORE Character class before abbrev point in word.
692AFTER Character class after abbrev point in word."
a7ec1775
RS
693 :group 'reftex-making-and-inserting-labels
694 :type '(list
396e0b08
KH
695 (integer :tag "Minimum chars per word" 4)
696 (integer :tag "Shorten by at least " 2)
697 (string :tag "cut before char class " "^saeiou")
698 (string :tag "cut after char class " "aeiou")))
a7ec1775 699
2faef409
RS
700(defcustom reftex-format-label-function nil
701 "Function which produces the string to insert as a label definition.
702Normally should be nil, unless you want to do something fancy.
703The function will be called with two arguments, the LABEL and the DEFAULT
704FORMAT, which usually is `\label{%s}'. The function should return the
705string to insert into the buffer."
706 :group 'reftex-making-and-inserting-labels
707 :type 'function)
708
a7ec1775
RS
709;; Label referencing
710
711(defgroup reftex-referencing-labels nil
c52bdfca 712 "Options on how to reference labels."
a7ec1775
RS
713 :group 'reftex-label-support)
714
396e0b08
KH
715(eval-and-compile
716 (defconst reftex-tmp
717 '((const :tag "on" t)
718 (const :tag "off" nil)
719 (string :tag "Selected label types"))))
720
721(defcustom reftex-label-menu-flags '(t t nil nil nil nil t nil)
722 "List of flags governing the label menu makeup.
a7ec1775
RS
723The flags are:
724
725TABLE-OF-CONTENTS Show the labels embedded in a table of context.
726SECTION-NUMBERS Include section numbers (like 4.1.3) in table of contents.
c52bdfca 727COUNTERS Show counters. This just numbers the labels in the menu.
a7ec1775 728NO-CONTEXT Non-nil means do NOT show the short context.
c52bdfca 729FOLLOW Follow full context in other window.
206c6f82 730SHOW-COMMENTED Show labels from regions which are commented out.
be456a1d 731MATCH-IN-TOC Obsolete flag.
29d593f8 732SHOW FILES Show begin and end of included files.
a7ec1775
RS
733
734Each of these flags can be set to t or nil, or to a string of type letters
c52bdfca
RS
735indicating the label types for which it should be true. These strings work
736like character classes in regular expressions. Thus, setting one of the
a7ec1775 737flags to \"sf\" makes the flag true for section and figure labels, nil
29d593f8 738for everything else. Setting it to \"^sf\" makes it the other way round.
2faef409
RS
739The available label types are: s (section), f (figure), t (table), i (item),
740e (equation), n (footnote), plus any definitions in `reftex-label-alist'.
a7ec1775
RS
741
742Most options can also be switched from the label menu itself - so if you
743decide here to not have a table of contents in the label menu, you can still
744get one interactively during selection from the label menu."
745 :group 'reftex-referencing-labels
396e0b08
KH
746 :type
747 `(list
748 (choice :tag "Embed in table of contents " ,@reftex-tmp)
749 (choice :tag "Show section numbers " ,@reftex-tmp)
750 (choice :tag "Show individual counters " ,@reftex-tmp)
751 (choice :tag "Hide short context " ,@reftex-tmp)
752 (choice :tag "Follow context in other window " ,@reftex-tmp)
753 (choice :tag "Show commented labels " ,@reftex-tmp)
be456a1d 754 (choice :tag "Obsolete flag, Don't use. " ,@reftex-tmp)
396e0b08
KH
755 (choice :tag "Show begin/end of included files" ,@reftex-tmp)))
756
2faef409
RS
757(defcustom reftex-vref-is-default nil
758 "*Non-nil means, the varioref macro \\vref is used as default.
759In the selection buffer, the `v' key toggles the reference macro between
760`\\ref' and `\\vref'. The value of this variable determines the default
761which is active when entering the selection process.
762Instead of nil or t, this may also be a string of type letters indicating
763the label types for which it should be true."
764 :group 'reftex-referencing-labels
765 :type `(choice :tag "\\vref is default macro" ,@reftex-tmp))
766
396e0b08
KH
767(defcustom reftex-level-indent 2
768 "*Number of spaces to be used for indentation per section level."
769 :group 'reftex-referencing-labels
b849548d 770 :type 'integer)
396e0b08 771
a7ec1775 772(defcustom reftex-guess-label-type t
c52bdfca 773 "*Non-nil means, `reftex-reference' will try to guess the label type.
a7ec1775 774To do that, RefTeX will look at the word before the cursor and compare it with
c52bdfca 775the words given in `reftex-label-alist'. When it finds a match, RefTeX will
a7ec1775 776immediately offer the correct label menu - otherwise it will prompt you for
c52bdfca 777a label type. If you set this variable to nil, RefTeX will always prompt."
a7ec1775 778 :group 'reftex-referencing-labels
b849548d 779 :type 'boolean)
a7ec1775 780
2faef409
RS
781(defcustom reftex-format-ref-function nil
782 "Function which produces the string to insert as a reference.
783Normally should be nil, because the format to insert a reference can
784already be specified in `reftex-label-alist'.
785The function will be called with two arguments, the LABEL and the DEFAULT
786FORMAT, which normally is `~\ref{%s}'. The function should return the
787string to insert into the buffer."
788 :group 'reftex-referencing-labels
789 :type 'function)
790
b849548d
CD
791(defcustom reftex-select-label-mode-hook nil
792 "Mode hook for reftex-select-label-mode."
793 :group 'reftex-referencing-labels
794 :type 'hook)
795
a7ec1775
RS
796;; BibteX citation configuration ----------------------------------------
797
798(defgroup reftex-citation-support nil
c52bdfca 799 "Support for referencing bibliographic data with BibTeX."
a7ec1775
RS
800 :group 'reftex)
801
802(defcustom reftex-bibpath-environment-variables '("BIBINPUTS" "TEXBIB")
b849548d
CD
803 "*List of env vars which might contain the path to BibTeX database files.
804Directories ending in `//' or `!!' will be expanded recursively when necessary
805to find files."
a7ec1775
RS
806 :group 'reftex-citation-support
807 :set 'reftex-set-dirty
808 :type '(repeat (string :tag "Environment variable")))
809
b849548d
CD
810(defvar reftex-bibfile-ignore-list nil) ; compatibility
811(defcustom reftex-bibfile-ignore-regexps nil
812 "*List of regular expressions to exclude files in \\bibliography{..}.
813File names matched by these regexps will not be parsed by RefTeX.
a7ec1775
RS
814Intended for files which contain only `@string' macro definitions and the
815like, which are ignored by RefTeX anyway."
816 :group 'reftex-citation-support
817 :set 'reftex-set-dirty
b849548d 818 :type '(repeat (regexp)))
a7ec1775 819
2faef409 820(defcustom reftex-default-bibliography nil
a6611c0d 821 "*List of BibTeX database files which should be used if none are specified.
2faef409
RS
822When `reftex-citation' is called from a document which has neither a
823`\bibliography{..}' statement nor a `thebibliography' environment,
824RefTeX will scan these files instead. Intended for using
825`reftex-citation' in non-LaTeX files."
826 :group 'reftex-citation-support
827 :type '(repeat (file)))
828
a7ec1775
RS
829(defcustom reftex-sort-bibtex-matches 'reverse-year
830 "*Sorting of the entries found in BibTeX databases by reftex-citation.
831Possible values:
832nil Do not sort entries.
833'author Sort entries by author name.
834'year Sort entries by increasing year.
835'reverse-year Sort entries by decreasing year."
836 :group 'reftex-citation-support
837 :type '(choice (const :tag "not" nil)
396e0b08
KH
838 (const :tag "by author" author)
839 (const :tag "by year" year)
840 (const :tag "by year, reversed" reverse-year)))
a7ec1775 841
206c6f82 842(defcustom reftex-cite-format 'default
396e0b08 843 "*The format of citations to be inserted into the buffer.
206c6f82
RS
844It can be a string or an alist. In the simplest case this is just
845the string \"\\cite{%l}\", which is also the default. See the
846definition of `reftex-cite-format-builtin' for more complex examples.
847
848If `reftex-cite-format' is a string, it will be used as the format.
849In the format, the following percent escapes will be expanded.
850
851%l The BibTeX label of the citation.
852%a List of author names, see also `reftex-cite-punctuation.
853%2a Like %a, but abbreviate more than 2 authors like Jones et al.
854%A First author name only.
855%e Works like %a, but on list of editor names. (%2e and %E work a well)
856
857It is also possible to access all other BibTeX database fields:
858%b booktitle %c chapter %d edition %h howpublished
859%i institution %j journal %k key %m month
860%n number %o organization %p pages %P first page
861%r address %s school %u publisher %t title
b849548d
CD
862%v volume %y year
863%B booktitle, abbreviated %T title, abbreviated
864
865Usually, only %l is needed. The other stuff is mainly for the echo area
866display, and for (setq reftex-comment-citations t).
206c6f82 867
b849548d
CD
868%< as a special operator kills punctuation and space around it after the
869string has been formatted.
206c6f82 870
b849548d 871Beware that all this only works with BibTeX database files. When
2faef409
RS
872citations are made from the \\bibitems in an explicit thebibliography
873environment, only %l is available.
874
206c6f82
RS
875If `reftex-cite-format' is an alist of characters and strings, the user
876will be prompted for a character to select one of the possible format
877strings.
a7ec1775 878 In order to configure this variable, you can either set
c52bdfca 879`reftex-cite-format' directly yourself or set it to the SYMBOL of one of
206c6f82 880the predefined styles (see `reftex-cite-format-builtin'). E.g.:
b849548d 881(setq reftex-cite-format 'natbib)"
396e0b08
KH
882 :group 'reftex-citation-support
883 :type
884 `(choice
885 :format "%{%t%}: \n%[Value Menu%] %v"
886 (radio :tag "Symbolic Builtins"
887 :indent 4
888 :value default
889 ,@(mapcar
890 (function
891 (lambda (x)
892 (list 'const ':tag (concat (symbol-name (nth 0 x))
893 ": " (nth 1 x))
894 (nth 0 x))))
895 reftex-cite-format-builtin))
896 (string :tag "format string" "\\cite{%l}")
897 (repeat :tag "key-ed format strings"
898 :value ((?\r . "\\cite{%l}")
899 (?t . "\\cite{%l}") (?p . "\\cite{%l}"))
900 (cons (character :tag "Key character" ?\r)
901 (string :tag "Format string" "")))))
206c6f82
RS
902
903(defcustom reftex-comment-citations nil
396e0b08 904 "*Non-nil means add a comment for each citation describing the full entry.
206c6f82
RS
905The comment is formatted according to `reftex-cite-comment-format'."
906 :group 'reftex-citation-support
b849548d 907 :type 'boolean)
206c6f82 908
396e0b08 909(defcustom reftex-cite-comment-format
b849548d
CD
910 "%% %2a %y, %j %v, %P, %b, %e, %u, %s %<\n"
911 "Citation format used for commented citations. Must NOT contain %l.
912See the variable `reftex-cite-format' for possible percent escapes."
913 :group 'reftex-citation-support
914 :type 'string)
915
916(defcustom reftex-cite-view-format
917 "%2a %y, %T, %B, %j %v:%P, %s %<"
918 "Citation format used to display citation info in the message area.
919Must NOT contain %l. See the variable `reftex-cite-format' for
920possible percent escapes."
206c6f82 921 :group 'reftex-citation-support
b849548d
CD
922 :group 'reftex-viewing-cross-references-and-citations
923 :type 'string)
206c6f82
RS
924
925(defcustom reftex-cite-punctuation '(", " " \\& " " {\\it et al.}")
926 "Punctuation for formatting of name lists in citations.
927This is a list of 3 strings.
9281. normal names separator, like \", \" in Jones, Brown and Miller
9292. final names separator, like \" and \" in Jones, Brown and Miller
2faef409 9303. The \"et al\" string, like \" {\\it et al.}\" in Jones {\\it et al.}"
396e0b08 931 :group 'reftex-citation-support
206c6f82 932 :type '(list
396e0b08
KH
933 (string :tag "Separator for names ")
934 (string :tag "Separator for last name in list")
935 (string :tag "string used as et al. ")))
a7ec1775 936
2faef409
RS
937(defcustom reftex-format-cite-function nil
938 "Function which produces the string to insert as a citation.
939Normally should be nil, because the format to insert a reference can
940already be specified in `reftex-cite-format'.
941The function will be called with two arguments, the CITATION KEY and the
942DEFAULT FORMAT, which is taken from `reftex-cite-format'. The function
943should return the string to insert into the buffer."
944 :group 'reftex-citation-support
945 :type 'function)
6b94c6ad 946
b849548d
CD
947(defcustom reftex-select-bib-mode-hook nil
948 "Mode hook for reftex-select-bib-mode."
949 :group 'reftex-citation-support
950 :type 'hook)
951
a7ec1775
RS
952;; Table of contents configuration --------------------------------------
953
954(defgroup reftex-table-of-contents-browser nil
955 "A multifile table of contents browser."
956 :group 'reftex)
957
958(defcustom reftex-toc-follow-mode nil
396e0b08 959 "*Non-nil means, point in *toc* buffer will cause other window to follow.
a7ec1775
RS
960The other window will show the corresponding part of the document.
961This flag can be toggled from within the *toc* buffer with the `f' key."
962 :group 'reftex-table-of-contents-browser
b849548d
CD
963 :type 'boolean)
964
965(defcustom reftex-revisit-to-follow nil
966 "*Non-nil means, follow-mode will revisit files if necessary.
967When nil, follow-mode will be suspended for stuff in unvisited files."
968 :group 'reftex-table-of-contents-browser
969 :group 'reftex-referencing-labels
970 :type 'boolean)
971
972(defcustom reftex-toc-mode-hook nil
973 "Mode hook for reftex-toc-mode."
974 :group 'reftex-table-of-contents-browser
975 :type 'hook)
976
977;; Viewing Cross References and Citations
978(defgroup reftex-viewing-cross-references-and-citations nil
979 "Displaying cross references and citations."
980 :group 'reftex)
981
982(defcustom reftex-auto-view-crossref t
983 "*Non-nil means, initially turn automatic viewing of crossref info on.
a6611c0d
CD
984Automatic viewing of crossref info normally uses the echo area.
985Whenever point is on the argument of a \\ref or \\cite macro, and no
986other message is being displayed, the echo area will display
987information about that cross reference. You can also set the variable
988to the symbol `window'. In this case a small temporary window is
989used for the display.
b849548d
CD
990This feature can be turned on and of from the menu
991(Ref->Options->Crossref Viewing)."
992 :group 'reftex-viewing-cross-references-and-citations
a6611c0d
CD
993 :type '(choice (const :tag "off" nil)
994 (const :tag "in Echo Area" t)
995 (const :tag "in Other Window" window)))
b849548d
CD
996
997(defcustom reftex-idle-time 1.2
998 "*Time (secs) Emacs has to be idle before automatic crossref display is done."
999 :group 'reftex-viewing-cross-references-and-citations
1000 :type 'number)
1001
1002(defcustom reftex-revisit-to-echo nil
1003 "*Non-nil means, automatic citation display will revisit files if necessary.
1004When nil, citation display in echo area will only be active for cached
1005entries and for BibTeX database files with live associated buffers."
1006 :group 'reftex-viewing-cross-references-and-citations
1007 :type 'boolean)
1008
1009(defcustom reftex-cache-cite-echo t
1010 "*Non-nil means, the information displayed in the echo area for cite macros
1011is cached and even saved along with the parsing information. The cache
1012survives document scans. In order to clear it, use M-x reftex-reset-mode."
1013 :group 'reftex-viewing-cross-references-and-citations
1014 :type 'boolean)
1015
1016(defcustom reftex-display-copied-context-hook nil
1017 "Normal Hook which is run before context is displayed anywhere. Designed
1018for X-Symbol, but may have other uses as well."
1019 :group 'reftex-viewing-cross-references-and-citations
1020 :group 'reftex-referencing-labels
1021 :type 'hook)
a7ec1775 1022
396e0b08
KH
1023;; Tuning the parser ----------------------------------------------------
1024
1025(defgroup reftex-optimizations-for-large-documents nil
1026 "Configuration of parser speed and memory usage."
1027 :group 'reftex)
1028
1029(defcustom reftex-keep-temporary-buffers 1
1030 "*Non-nil means, keep buffers created for parsing and lookup.
1031RefTeX sometimes needs to visit files related to the current document.
1032We distinguish files visited for
1033PARSING: Parts of a multifile document loaded when (re)-parsing the document.
1034LOOKUP: BibTeX database files and TeX files loaded to find a reference,
1035 to display label context, etc.
1036The created buffers can be kept for later use, or be thrown away immediately
1037after use, depending on the value of this variable:
1038
1039nil Throw away as much as possible.
1040t Keep everything.
10411 Throw away buffers created for parsing, but keep the ones created
1042 for lookup.
1043
1044If a buffer is to be kept, the file is visited normally (which is potentially
1045slow but will happen only once).
1046If a buffer is to be thrown away, the initialization of the buffer depends
1047upon the variable `reftex-initialize-temporary-buffers'."
b849548d 1048 :group 'reftex-optimizations-for-large-documents
396e0b08
KH
1049 :type '(choice
1050 (const :tag "Throw away everything" nil)
1051 (const :tag "Keep everything" t)
1052 (const :tag "Keep lookup buffers only" 1)))
1053
1054(defcustom reftex-initialize-temporary-buffers nil
1055 "*Non-nil means do initializations even when visiting file temporarily.
1056When nil, RefTeX may turn off find-file hooks and other stuff to briefly
1057visit a file.
1058When t, the full default initializations are done (find-file-hook etc.).
1059Instead of t or nil, this variable may also be a list of hook functions to
1060do a minimal initialization."
b849548d 1061 :group 'reftex-optimizations-for-large-documents
396e0b08
KH
1062 :type '(choice
1063 (const :tag "Read files literally" nil)
1064 (const :tag "Fully initialize buffers" t)
1065 (repeat :tag "Hook functions" :value (nil)
1066 (function-item))))
1067
b849548d 1068(defcustom reftex-no-include-regexps '("\\.pstex_t\\'")
2faef409
RS
1069 "*List of regular expressions to exclude certain input files from parsing.
1070If the name of a file included via \\include or \\input is matched by any
1071of the regular expressions in this list, that file is not parsed by RefTeX."
1072 :group 'reftex-optimizations-for-large-documents
1073 :type '(repeat (regexp)))
1074
396e0b08
KH
1075(defcustom reftex-enable-partial-scans nil
1076 "*Non-nil means, re-parse only 1 file when asked to re-parse.
1077Re-parsing is normally requested with a `C-u' prefix to many RefTeX commands,
1078or with the `r' key in menus. When this option is t in a multifile document,
1079we will only parse the current buffer, or the file associated with the label
1080or section heading near point in a menu. Requesting re-parsing of an entire
1081multifile document then requires a `C-u C-u' prefix or the capital `R' key
1082in menus."
1083 :group 'reftex-optimizations-for-large-documents
1084 :type 'boolean)
1085
2faef409
RS
1086(defcustom reftex-allow-automatic-rescan t
1087 "*Non-nil means, RefTeX may rescan the document when this seems necessary.
1088Currently this applies only to rescanning after label insertion, when
1089the new label cannot be inserted correctly into the internal label
1090list."
1091 :group 'reftex-optimizations-for-large-documents
1092 :type 'boolean)
1093
396e0b08
KH
1094(defcustom reftex-save-parse-info nil
1095 "*Non-nil means, save information gathered with parsing in a file.
1096The file MASTER.rel in the same directory as MASTER.tex is used to save the
1097information. When this variable is t,
1098- accessing the parsing information for the first time in an editing session
1099 will read that file (if available) instead of parsing the document.
b849548d
CD
1100- exiting Emacs or killing a buffer in reftex-mode will cause a new version
1101 of the file to be written."
396e0b08
KH
1102 :group 'reftex-optimizations-for-large-documents
1103 :type 'boolean)
1104
2faef409
RS
1105(defcustom reftex-use-multiple-selection-buffers nil
1106 "*Non-nil means use a separate selection buffer for each label type.
1107These buffers are kept from one selection to the next and need not to be
1108created for each use - so the menu generally comes up faster. The
1109selection buffers will be erased (and therefore updated) automatically
1110when new labels in its category are added. See the variable
1111`reftex-auto-update-selection-buffers'."
1112 :group 'reftex-optimizations-for-large-documents
b849548d 1113 :group 'reftex-referencing-labels
2faef409
RS
1114 :type 'boolean)
1115
1116(defcustom reftex-auto-update-selection-buffers t
1117 "*Non-nil means, selection buffers will be updated automatically.
1118When a new label is defined with `reftex-label', all selection buffers
1119associated with that label category are emptied, in order to force an
1120update upon next use. When nil, the buffers are left alone and have to be
1121updated by hand, with the `g' key from the label selection process.
1122The value of this variable will only have any effect when
1123`reftex-use-multiple-selection-buffers' is non-nil."
1124 :group 'reftex-optimizations-for-large-documents
b849548d 1125 :group 'reftex-referencing-labels
2faef409
RS
1126 :type 'boolean)
1127
6b94c6ad
CD
1128;; Fontification and Faces ----------------------------------------------
1129
1130(defgroup reftex-fontification-configurations nil
1131 "Options concerning the faces used in RefTeX."
1132 :group 'reftex)
1133
1134(defcustom reftex-use-fonts t
1135 "*Non-nil means, use fonts in *toc* and selection buffers.
b849548d
CD
1136Font-lock must be loaded as well to actually get fontified display.
1137When changing this option, a rescan may be necessary to activate the change."
6b94c6ad 1138 :group 'reftex-fontification-configurations
b849548d 1139 :type 'boolean)
6b94c6ad
CD
1140
1141(defcustom reftex-refontify-context 1
1142 "*Non-nil means, re-fontify the context in the label menu with font-lock.
1143This slightly slows down the creation of the label menu. It is only necessary
1144when you definitely want the context fontified.
1145
1146This option may have 3 different values:
1147nil Never refontify.
1148t Always refontify.
b849548d 11491 Refontify when absolutely necessary, e.g. when old versions of X-Symbol.
6b94c6ad
CD
1150The option is ignored when `reftex-use-fonts' is nil."
1151 :group 'reftex-fontification-configurations
b849548d 1152 :group 'reftex-referencing-labels
6b94c6ad
CD
1153 :type '(choice
1154 (const :tag "Never" nil)
1155 (const :tag "Always" t)
1156 (const :tag "When necessary" 1)))
1157
1158(defcustom reftex-highlight-selection 'cursor
1159 "*Non-nil mean, highlight selected text in selection and *toc* buffers.
1160Normally, the text near the cursor is the selected text, and it is
1161highlighted. This is the entry most keys in the selction and *toc*
1162buffers act on. However, if you mainly use the mouse to select an
1163item, you may find it nice to have mouse-triggered highlighting
1164instead or as well. The variable may have one of these values:
1165
1166 nil No highlighting.
1167 cursor Highlighting is cursor driven.
1168 mouse Highlighting is mouse driven.
b849548d
CD
1169 both Both cursor and mouse trigger highlighting.
1170
1171Changing this variable requires to rebuild the selection and *toc* buffers
1172to become effective (keys `g' or `r')."
6b94c6ad
CD
1173 :group 'reftex-fontification-configurations
1174 :type '(choice
1175 (const :tag "Never" nil)
1176 (const :tag "Cursor driven" cursor)
1177 (const :tag "Mouse driven" mouse)
1178 (const :tag "Mouse and Cursor driven." both)))
1179
1180(defcustom reftex-cursor-selected-face 'highlight
1181 "Face name to highlight cursor selected item in toc and selection buffers.
1182See also the variable `reftex-highlight-selection'."
1183 :group 'reftex-fontification-configurations
1184 :type 'symbol)
1185(defcustom reftex-mouse-selected-face 'secondary-selection
1186 "Face name to highlight mouse selected item in toc and selection buffers.
1187See also the variable `reftex-highlight-selection'."
1188 :group 'reftex-fontification-configurations
1189 :type 'symbol)
1190(defcustom reftex-file-boundary-face 'font-lock-comment-face
1191 "Face name for file boundaries in selection buffer."
1192 :group 'reftex-fontification-configurations
1193 :type 'symbol)
1194(defcustom reftex-label-face 'font-lock-constant-face
1195 "Face name for labels in selection buffer."
1196 :group 'reftex-fontification-configurations
1197 :type 'symbol)
1198(defcustom reftex-section-heading-face 'font-lock-function-name-face
1199 "Face name for section headings in toc and selection buffers."
1200 :group 'reftex-fontification-configurations
1201 :type 'symbol)
1202(defcustom reftex-toc-header-face 'font-lock-comment-face
1203 "Face name for the header of a toc buffer."
1204 :group 'reftex-fontification-configurations
1205 :type 'symbol)
1206(defcustom reftex-bib-author-face 'font-lock-keyword-face
1207 "Face name for author names in bib selection buffer."
1208 :group 'reftex-fontification-configurations
1209 :type 'symbol)
1210(defcustom reftex-bib-year-face 'font-lock-comment-face
1211 "Face name for year in bib selection buffer."
1212 :group 'reftex-fontification-configurations
1213 :type 'symbol)
1214(defcustom reftex-bib-title-face 'font-lock-function-name-face
1215 "Face name for article title in bib selection buffer."
1216 :group 'reftex-fontification-configurations
1217 :type 'symbol)
1218(defcustom reftex-bib-extra-face 'font-lock-comment-face
1219 "Face name for bibliographic information in bib selection buffer."
1220 :group 'reftex-fontification-configurations
1221 :type 'symbol)
1222
b849548d
CD
1223(defcustom reftex-pre-refontification-functions nil
1224 "X-Symbol specific hook.
1225Functions get two arguments, the buffer from where the command started and a
1226symbol indicating in what context the hook is called."
1227 :group 'reftex-fontification-configurations
1228 :type 'hook)
1229
a7ec1775
RS
1230;; Miscellaneous configurations -----------------------------------------
1231
1232(defgroup reftex-miscellaneous-configurations nil
c52bdfca 1233 "Collection of further configurations."
a7ec1775
RS
1234 :group 'reftex)
1235
1236(defcustom reftex-extra-bindings nil
1237 "Non-nil means, make additional key bindings on startup.
c52bdfca 1238These extra bindings are located in the users `C-c letter' map."
a7ec1775 1239 :group 'reftex-miscellaneous-configurations
b849548d 1240 :type 'boolean)
a7ec1775 1241
c52bdfca 1242(defcustom reftex-plug-into-AUCTeX nil
396e0b08 1243 "*Plug-in flags for AUCTeX interface.
b849548d
CD
1244This variable is a list of 4 boolean flags. When a flag is non-nil,
1245RefTeX will
c52bdfca 1246
b849548d
CD
1247 - supply labels in new sections and environments (flag 1)
1248 - supply arguments for macros like `\\label'. (flag 2)
1249 - supply arguments for macros like `\\ref'. (flag 3)
1250 - supply arguments for macros like `\\cite'. (flag 4)
c52bdfca
RS
1251
1252You may also set the variable itself to t or nil in order to turn all
1253plug-ins on or off, respectively.
b849548d
CD
1254\\<LaTeX-mode-map>Supplying labels in new sections and environments aplies when creating
1255sections with \\[LaTeX-section] and environments with \\[LaTeX-environment].
1256Supplying macro arguments applies when you insert such a macro interactively
1257with \\[TeX-insert-macro].
c52bdfca
RS
1258See the AUCTeX documentation for more information.
1259RefTeX uses `fset' to take over the function calls. Changing the variable
1260may require a restart of Emacs in order to become effective."
1261 :group 'reftex-miscellaneous-configurations
b849548d
CD
1262 :group 'LaTeX
1263 :type '(choice
1264 (const :tag "No plug-ins" nil)
1265 (const :tag "All possible plug-ins" t)
1266 (list
1267 :tag "Individual choice"
1268 :value (t t t t)
1269 (boolean :tag "supply label in new sections and environments")
1270 (boolean :tag "supply argument for macros like `\\label' ")
1271 (boolean :tag "supply argument for macros like `\\ref' ")
1272 (boolean :tag "supply argument for macros like `\\cite' ")
1273 )))
1274
1275(defcustom reftex-allow-detached-macro-args nil
1276 "*Non-nil means, allow arguments of macros to be detached by whitespace.
1277When this is t, `aaa' will be considered as argument of \\bb in the following
1278construct: \\bbb [xxx] {aaa}."
1279 :group 'texmathp
1280 :type 'boolean)
396e0b08 1281
2faef409 1282
396e0b08
KH
1283(defcustom reftex-load-hook nil
1284 "Hook which is being run when loading reftex.el."
1285 :group 'reftex-miscellaneous-configurations
1286 :type 'hook)
a7ec1775 1287
396e0b08
KH
1288(defcustom reftex-mode-hook nil
1289 "Hook which is being run when turning on RefTeX mode."
a7ec1775 1290 :group 'reftex-miscellaneous-configurations
396e0b08 1291 :type 'hook)
a7ec1775 1292
b849548d 1293;;; =========================================================================
a7ec1775
RS
1294;;;
1295;;; Define the formal stuff for a minor mode named RefTeX.
1296;;;
1297
a6611c0d
CD
1298(defconst reftex-version "RefTeX version 3.38"
1299 "Version string for RefTeX.")
baec1250 1300
a7ec1775 1301(defvar reftex-mode nil
b849548d 1302 "Determines if RefTeX mode is active.")
a7ec1775
RS
1303(make-variable-buffer-local 'reftex-mode)
1304
1305(defvar reftex-mode-map (make-sparse-keymap)
b849548d 1306 "Keymap for RefTeX mode.")
a7ec1775
RS
1307
1308(defvar reftex-mode-menu nil)
1309
1310;;;###autoload
1311(defun turn-on-reftex ()
b849548d 1312 "Turn on RefTeX mode."
a7ec1775
RS
1313 (reftex-mode t))
1314
1315;;;###autoload
1316(defun reftex-mode (&optional arg)
fba437e6 1317 "Minor mode with distinct support for \\label, \\ref and \\cite in LaTeX.
a7ec1775
RS
1318
1319Labels can be created with `\\[reftex-label]' and referenced with `\\[reftex-reference]'.
1320When referencing, you get a menu with all labels of a given type and
c52bdfca 1321context of the label definition. The selected label is inserted as a
fba437e6 1322\\ref macro.
a7ec1775 1323
396e0b08 1324Citations can be made with `\\[reftex-citation]' which will use a regular expression
a7ec1775 1325to pull out a *formatted* list of articles from your BibTeX
c52bdfca 1326database. The selected citation is inserted as a \\cite macro.
a7ec1775
RS
1327
1328A Table of Contents of the entire (multifile) document with browsing
1329capabilities is available with `\\[reftex-toc]'.
1330
c52bdfca 1331Most command have help available on the fly. This help is accessed by
a7ec1775
RS
1332pressing `?' to any prompt mentioning this feature.
1333
396e0b08
KH
1334Extensive documentation about RefTeX is in the file header of `reftex.el'.
1335You can view this information with `\\[reftex-show-commentary]'.
c52bdfca 1336
a7ec1775 1337\\{reftex-mode-map}
396e0b08
KH
1338Under X, these and other functions will also be available as `Ref' menu
1339on the menu bar.
a7ec1775
RS
1340
1341------------------------------------------------------------------------------"
1342
1343 (interactive "P")
1344 (setq reftex-mode (not (or (and (null arg) reftex-mode)
1345 (<= (prefix-numeric-value arg) 0))))
1346
1347 ; Add or remove the menu, and run the hook
1348 (if reftex-mode
1349 (progn
396e0b08 1350 (easy-menu-add reftex-mode-menu)
b849548d
CD
1351 (and reftex-plug-into-AUCTeX
1352 (reftex-plug-into-AUCTeX))
396e0b08 1353 (run-hooks 'reftex-mode-hook))
a7ec1775 1354 (easy-menu-remove reftex-mode-menu)))
396e0b08 1355
b849548d
CD
1356(if (fboundp 'add-minor-mode)
1357 ;; Use it so that we get the extras
1358 (progn
1359 (put 'reftex-mode ':included '(memq major-mode '(latex-mode tex-mode)))
1360 (put 'reftex-mode ':menu-tag "RefTeX Mode")
1361 (add-minor-mode 'reftex-mode " Ref" reftex-mode-map))
1362 ;; The standard way
1363 (unless (assoc 'reftex-mode minor-mode-alist)
396e0b08 1364 (push '(reftex-mode " Ref") minor-mode-alist))
b849548d
CD
1365 (unless (assoc 'reftex-mode minor-mode-map-alist)
1366 (push (cons 'reftex-mode reftex-mode-map) minor-mode-map-alist)))
a7ec1775 1367
b849548d 1368;;; =========================================================================
c52bdfca
RS
1369;;;
1370;;; Silence warnings about variables in other packages.
1371(defvar TeX-master)
b849548d 1372(defvar LaTeX-section-hook)
c52bdfca
RS
1373(defvar LaTeX-label-function)
1374(defvar tex-main-file)
1375(defvar outline-minor-mode)
a6611c0d 1376(defvar font-lock-mode)
2faef409
RS
1377(defvar font-lock-fontify-region-function)
1378(defvar font-lock-syntactic-keywords)
c52bdfca 1379
b849548d 1380;;; =========================================================================
a7ec1775 1381;;;
b849548d 1382;;; Multibuffer Variables
a7ec1775 1383;;;
b849548d 1384;;; Technical notes: These work as follows: We keep just one list
a7ec1775 1385;;; of labels for each master file - this can save a lot of memory.
c52bdfca 1386;;; `reftex-master-index-list' is an alist which connects the true file name
a7ec1775 1387;;; of each master file with the symbols holding the information on that
c52bdfca 1388;;; document. Each buffer has local variables which point to these symbols.
a7ec1775 1389
a7ec1775
RS
1390;; List of variables which handle the multifile stuff.
1391;; This list is used to tie, untie, and reset these symbols.
1392(defconst reftex-multifile-symbols
396e0b08 1393 '(reftex-docstruct-symbol))
a7ec1775 1394
c52bdfca 1395;; Alist connecting master file names with the corresponding lisp symbols.
a7ec1775
RS
1396(defvar reftex-master-index-list nil)
1397
c52bdfca 1398;; Last index used for a master file.
a7ec1775
RS
1399(defvar reftex-multifile-index 0)
1400
a7ec1775 1401;; Variable holding the symbol with the label list of the document.
396e0b08
KH
1402(defvar reftex-docstruct-symbol nil)
1403(make-variable-buffer-local 'reftex-docstruct-symbol)
a7ec1775
RS
1404
1405(defun reftex-next-multifile-index ()
1406 ;; Return the next free index for multifile symbols.
396e0b08 1407 (incf reftex-multifile-index))
a7ec1775
RS
1408
1409(defun reftex-tie-multifile-symbols ()
1410 ;; Tie the buffer-local symbols to globals connected with the master file.
1411 ;; If the symbols for the current master file do not exist, they are created.
1412
1413 (let* ((master (file-truename (reftex-TeX-master-file)))
1414 (index (assoc master reftex-master-index-list))
1415 (symlist reftex-multifile-symbols)
b849548d 1416 symbol symname newflag)
c52bdfca 1417 ;; Find the correct index.
a7ec1775
RS
1418 (if index
1419 ;; symbols do exist
1420 (setq index (cdr index))
c52bdfca 1421 ;; Get a new index and add info to the alist.
a7ec1775 1422 (setq index (reftex-next-multifile-index)
396e0b08
KH
1423 newflag t)
1424 (push (cons master index) reftex-master-index-list))
a7ec1775 1425
c52bdfca 1426 ;; Get/create symbols and tie them.
a7ec1775
RS
1427 (while symlist
1428 (setq symbol (car symlist)
1429 symlist (cdr symlist)
1430 symname (symbol-name symbol))
1431 (set symbol (intern (concat symname "-" (int-to-string index))))
2faef409 1432 (put (symbol-value symbol) ':master-index index)
c52bdfca 1433 ;; Initialize if new symbols.
a7ec1775
RS
1434 (if newflag (set (symbol-value symbol) nil)))
1435
c52bdfca 1436 ;; Return t if the symbols did already exist, nil when we've made them.
a7ec1775
RS
1437 (not newflag)))
1438
1439(defun reftex-untie-multifile-symbols ()
1440 ;; Remove ties from multifile symbols, so that next use makes new ones.
1441 (let ((symlist reftex-multifile-symbols)
1442 (symbol nil))
1443 (while symlist
1444 (setq symbol (car symlist)
1445 symlist (cdr symlist))
1446 (set symbol nil))))
1447
1448(defun reftex-TeX-master-file ()
1449 ;; Return the name of the master file associated with the current buffer.
1450 ;; When AUCTeX is loaded, we will use it's more sophisticated method.
025bb635
RS
1451 ;; We also support the default TeX and LaTeX modes by checking for a
1452 ;; variable tex-main-file.
a7ec1775
RS
1453 (let
1454 ((master
1455 (cond
c52bdfca 1456 ((fboundp 'TeX-master-file) ; AUCTeX is loaded. Use its mechanism.
a7ec1775
RS
1457 (TeX-master-file t))
1458 ((boundp 'TeX-master) ; The variable is defined - lets use it.
1459 (cond
1460 ((eq TeX-master t)
1461 (buffer-file-name))
1462 ((eq TeX-master 'shared)
1463 (setq TeX-master (read-file-name "Master file: "
1464 nil nil t nil)))
1465 (TeX-master)
1466 (t
1467 (setq TeX-master (read-file-name "Master file: "
1468 nil nil t nil)))))
1469 ((boundp 'tex-main-file)
c52bdfca 1470 ;; This is the variable from the default TeX modes.
a7ec1775
RS
1471 (cond
1472 ((stringp tex-main-file)
1473 ;; ok, this must be it
1474 tex-main-file)
1475 (t
c52bdfca 1476 ;; In this case, the buffer is its own master.
a7ec1775
RS
1477 (buffer-file-name))))
1478 (t
c52bdfca 1479 ;; Know nothing about master file. Assume this is a master file.
a7ec1775
RS
1480 (buffer-file-name)))))
1481 (cond
1482 ((null master)
a6611c0d 1483 (error "Need a filename for this buffer, please save it first"))
a7ec1775
RS
1484 ((or (file-exists-p (concat master ".tex"))
1485 (reftex-get-buffer-visiting (concat master ".tex")))
1486 ;; Ahh, an extra .tex was missing...
1487 (setq master (concat master ".tex")))
a6611c0d
CD
1488 ((or (file-exists-p master)
1489 (reftex-get-buffer-visiting master))
1490 ;; We either see the file, or have a buffer on it. OK.
1491 )
a7ec1775 1492 (t
b849548d 1493 ;; Use buffer file name.
2faef409 1494 (buffer-file-name)))
a7ec1775
RS
1495 (expand-file-name master)))
1496
b849548d
CD
1497;;; =========================================================================
1498;;;
1499;;; Functions to parse the buffer and to create and reference labels.
1500
1501;; The following constants are derived from `reftex-label-alist'.
1502
1503;; Prompt used for label type queries directed to the user.
1504(defconst reftex-type-query-prompt nil)
1505
1506;; Help string for label type queries.
1507(defconst reftex-type-query-help nil)
1508
1509;; Alist relating label type to reference format.
1510(defconst reftex-typekey-to-format-alist nil)
1511
1512;; Alist relating label type to label affix.
1513(defconst reftex-typekey-to-prefix-alist nil)
1514
1515;; Alist relating environments or macros to label type and context regexp.
1516(defconst reftex-env-or-mac-alist nil)
1517
1518;; List of macros carrying a label.
1519(defconst reftex-label-mac-list nil)
1520
1521;; List of environments carrying a label.
1522(defconst reftex-label-env-list nil)
1523
1524;; List of all typekey letters in use.
1525(defconst reftex-typekey-list nil)
1526
1527;; Alist relating magic words to a label type.
1528(defconst reftex-words-to-typekey-alist nil)
1529
1530;; The last list-of-labels entry used in a reference.
1531(defvar reftex-last-used-reference (list nil nil nil nil))
1532
1533;; The message when follow-mode is suspended
1534(defconst reftex-no-follow-message
1535 "No follow-mode into unvisited file. Press SPC to visit it.")
1536(defconst reftex-no-info-message
1537 "%s: info not available, use `\\[reftex-view-crossref]' to get it.")
1538
1539;; The regular expression used to abbreviate words.
1540(defconst reftex-abbrev-regexp
1541 (concat
1542 "\\`\\("
1543 (make-string (nth 0 reftex-abbrev-parameters) ?.)
1544 "[" (nth 2 reftex-abbrev-parameters) "]*"
1545 "\\)"
1546 "[" (nth 3 reftex-abbrev-parameters) "]"
1547 (make-string (1- (nth 1 reftex-abbrev-parameters)) ?.)))
1548
1549;; Global variables used for communication between functions.
1550(defvar reftex-default-context-position nil)
1551(defvar reftex-location-start nil)
1552(defvar reftex-call-back-to-this-buffer nil)
1553(defvar reftex-select-return-marker (make-marker))
1554(defvar reftex-active-toc nil)
1555(defvar reftex-tex-path nil)
1556(defvar reftex-bib-path nil)
1557(defvar reftex-last-follow-point nil)
1558(defvar reftex-latex-syntax-table nil)
1559(defvar reftex-prefix nil)
1560(defvar reftex-section-levels-all nil)
1561(defvar reftex-buffers-with-changed-invisibility nil)
1562
1563;; List of buffers created temporarily for lookup, which should be killed.
1564(defvar reftex-buffers-to-kill nil)
1565
1566;; Regexp to find anything.
1567(defvar reftex-section-regexp nil)
1568(defvar reftex-section-or-include-regexp nil)
1569(defvar reftex-everything-regexp nil)
1570(defvar reftex-find-label-regexp-format nil)
1571(defvar reftex-find-label-regexp-format2 nil)
1572
1573;;; The parser functions -----------------------------------------------------
1574
1575(defvar reftex-memory nil
1576 "Memorizes old variable values to indicate changes in these variables.")
1577
1578(defun reftex-access-scan-info (&optional rescan file)
1579 "Ensure access to the scanning info for the current file."
1580 ;; When the multifile symbols are not yet tied,
1581 ;; tie them. When they are empty or RESCAN is non-nil, scan the document.
1582 ;; But, when RESCAN is -1, don't rescan even if docstruct is empty.
1583 ;; When FILE is non-nil, parse only from that file.
1584
1585 ;; Make sure we have the symbols tied
1586 (if (eq reftex-docstruct-symbol nil)
1587 ;; Symbols are not yet tied: Tie them.
1588 (reftex-tie-multifile-symbols))
1589
1590 (reftex-ensure-compiled-variables)
1591
1592 (when (or (null (symbol-value reftex-docstruct-symbol))
1593 (member rescan '(t 1 (4) (16))))
1594 ;; The docstruct will change: Remove selection buffers.
1595 (save-excursion
1596 (reftex-erase-all-selection-buffers)))
1597
1598 (if (and (null (symbol-value reftex-docstruct-symbol))
1599 (not (member rescan '(t 1 (4) (16))))
1600 reftex-save-parse-info)
1601 ;; Try to read the stuff from a file
1602 (reftex-access-parse-file 'read))
1603
1604 (cond
1605 ((equal rescan -1)) ;; We are not allowed to scan.
1606 ((not (symbol-value reftex-docstruct-symbol))
1607 ;; Scan the whole document
1608 (reftex-do-parse 1 file))
1609 ((member rescan '(t 1 (4) (16)))
1610 ;; Scan whatever was required by the caller.
1611 (reftex-do-parse rescan file))))
1612
396e0b08
KH
1613(defun reftex-parse-one ()
1614 "Re-parse this file."
a7ec1775 1615 (interactive)
396e0b08
KH
1616 (let ((reftex-enable-partial-scans t))
1617 (reftex-access-scan-info '(4))))
a7ec1775 1618
396e0b08
KH
1619(defun reftex-parse-all ()
1620 "Re-parse entire document."
1621 (interactive)
1622 (reftex-access-scan-info '(16)))
1623
396e0b08 1624(defun reftex-do-parse (rescan &optional file)
b849548d 1625 "Do a document rescan. When allowed, do only a partial scan from FILE."
396e0b08
KH
1626
1627 ;; Normalize the rescan argument
1628 (setq rescan (cond ((eq rescan t) t)
1629 ((eq rescan 1) 1)
1630 ((equal rescan '(4)) t)
1631 ((equal rescan '(16)) 1)
1632 (t 1)))
1633
1634 ;; Partial scans only when allowed
1635 (unless reftex-enable-partial-scans
1636 (setq rescan 1))
1637
1638 ;; Do the scanning.
1639
1640 (let* ((old-list (symbol-value reftex-docstruct-symbol))
1641 (master (reftex-TeX-master-file))
b849548d 1642 (true-master (file-truename master))
396e0b08
KH
1643 (master-dir (file-name-as-directory (file-name-directory master)))
1644 (file (or file (buffer-file-name)))
b849548d
CD
1645 (true-file (file-truename file))
1646 (bibview-cache (assq 'bibview-cache old-list))
2faef409 1647 from-file appendix docstruct tmp)
396e0b08
KH
1648
1649 ;; Make sure replacement is really an option here
1650 (when (and (eq rescan t)
1651 (not (and (member (list 'bof file) old-list)
1652 (member (list 'eof file) old-list))))
b849548d 1653 ;; Scan whole document because no such file section exists
396e0b08 1654 (setq rescan 1))
b849548d
CD
1655 (when (string= true-file true-master)
1656 ;; Scan whole document because this file is the master
396e0b08
KH
1657 (setq rescan 1))
1658
1659 ;; From which file do we start?
1660 (setq from-file
1661 (cond ((eq rescan t) (or file master))
1662 ((eq rescan 1) master)
b849548d 1663 (t (error "This should not happen (reftex-do-parse)"))))
396e0b08
KH
1664
1665 ;; Find active toc entry and initialize section-numbers
2faef409
RS
1666 (setq reftex-active-toc (reftex-last-assoc-before-elt
1667 'toc (list 'bof from-file) old-list)
1668 appendix (reftex-last-assoc-before-elt
1669 'appendix (list 'bof from-file) old-list))
1670
1671 (reftex-init-section-numbers reftex-active-toc appendix)
396e0b08
KH
1672
1673 (if (eq rescan 1)
1674 (message "Scanning entire document...")
1675 (message "Scanning document from %s..." from-file))
1676
1677 (save-window-excursion
1678 (save-excursion
1679 (unwind-protect
1680 (setq docstruct
1681 (reftex-parse-from-file
1682 from-file docstruct master-dir))
1683 (reftex-kill-temporary-buffers))))
1684
1685 (message "Scanning document... done")
1686
1687 ;; Turn the list around.
1688 (setq docstruct (nreverse docstruct))
1689
1690 ;; Set or insert
1691 (setq docstruct (reftex-replace-label-list-segment
1692 old-list docstruct (eq rescan 1)))
1693
1694 ;; Add all missing information
1695 (unless (assq 'label-numbers docstruct)
1696 (push (cons 'label-numbers nil) docstruct))
1697 (unless (assq 'master-dir docstruct)
1698 (push (cons 'master-dir master-dir) docstruct))
b849548d
CD
1699 (unless (assq 'bibview-cache docstruct)
1700 (push (cons 'bibview-cache (cdr bibview-cache)) docstruct))
396e0b08
KH
1701 (let* ((bof1 (memq (assq 'bof docstruct) docstruct))
1702 (bof2 (assq 'bof (cdr bof1)))
1703 (is-multi (not (not (and bof1 bof2))))
1704 (entry (or (assq 'is-multi docstruct)
1705 (car (push (list 'is-multi is-multi) docstruct)))))
1706 (setcdr entry (cons is-multi nil)))
1707 (unless (assq 'xr docstruct)
1708 (let* ((allxr (reftex-all-assq 'xr-doc docstruct))
2faef409
RS
1709 (alist (mapcar
1710 (function
1711 (lambda (x)
396e0b08
KH
1712 (if (setq tmp (reftex-find-tex-file (nth 2 x)
1713 master-dir))
1714 (cons (nth 1 x) tmp)
1715 (message "Can't find external document %s"
2faef409
RS
1716 (nth 2 x))
1717 nil)))
396e0b08 1718 allxr))
b849548d
CD
1719 (alist (delq nil alist))
1720 (allprefix (delq nil (mapcar 'car alist)))
2faef409
RS
1721 (regexp (if allprefix
1722 (concat "\\`\\("
1723 (mapconcat 'identity allprefix "\\|")
1724 "\\)")
1725 "\\\\\\\\\\\\"))) ; this will never match
396e0b08
KH
1726 (push (list 'xr alist regexp) docstruct)))
1727
1728 (set reftex-docstruct-symbol docstruct)
b849548d 1729 (put reftex-docstruct-symbol 'modified t)))
396e0b08
KH
1730
1731(defun reftex-parse-from-file (file docstruct master-dir)
1732 ;; Scan the buffer for labels and save them in a list.
1733 (let ((regexp reftex-everything-regexp)
1734 (bound 0)
2faef409 1735 file-found tmp include-file
396e0b08
KH
1736 (level 1)
1737 (highest-level 100)
b849548d 1738 toc-entry next-buf buf)
396e0b08
KH
1739
1740 (catch 'exit
1741 (setq file-found (reftex-find-tex-file file master-dir))
b849548d
CD
1742 (if (and (not file-found)
1743 (setq buf (reftex-get-buffer-visiting file)))
1744 (setq file-found (buffer-file-name buf)))
1745
396e0b08
KH
1746 (unless file-found
1747 (push (list 'file-error file) docstruct)
1748 (throw 'exit nil))
1749
1750 (save-excursion
1751
1752 (message "Scanning file %s" file)
1753 (set-buffer
1754 (setq next-buf
1755 (reftex-get-file-buffer-force
1756 file-found
1757 (not (eq t reftex-keep-temporary-buffers)))))
1758
1759 ;; Begin of file mark
1760 (setq file (buffer-file-name))
1761 (push (list 'bof file) docstruct)
1762
1763 (save-excursion
1764 (save-restriction
1765 (widen)
1766 (goto-char 1)
1767
1768 (while (re-search-forward regexp nil t)
1769
1770 (cond
1771
1772 ((match-end 1)
1773 ;; It is a label
1774 (push (reftex-label-info (reftex-match-string 1) file bound)
1775 docstruct))
1776
1777 ((match-end 3)
1778 ;; It is a section
1779 (setq bound (point))
1780
1781 ;; Insert in List
1782 (setq toc-entry (reftex-section-info file))
1783 (setq level (nth 5 toc-entry))
1784 (setq highest-level (min highest-level level))
1785 (if (= level highest-level)
1786 (message
1787 "Scanning %s %s ..."
b849548d 1788 (car (rassoc level reftex-section-levels))
396e0b08
KH
1789 (nth 6 toc-entry)))
1790
1791 (push toc-entry docstruct)
1792 (setq reftex-active-toc toc-entry))
1793
1794 ((match-end 7)
1795 ;; It's an include or input
2faef409 1796 (setq include-file (reftex-match-string 7))
b849548d
CD
1797 ;; Test if this file should be ignored
1798 (unless (delq nil (mapcar
1799 (lambda (x) (string-match x include-file))
1800 reftex-no-include-regexps))
2faef409
RS
1801 ;; Parse it
1802 (setq docstruct
1803 (reftex-parse-from-file
1804 include-file
1805 docstruct master-dir))))
1806
1807 ((match-end 9)
1808 ;; Appendix starts here
1809 (reftex-init-section-numbers nil t)
1810 (push (cons 'appendix t) docstruct))
1811
1812 ((match-end 10)
396e0b08
KH
1813 ;; A macro with label
1814 (save-excursion
2faef409
RS
1815 (let* ((mac (reftex-match-string 10))
1816 (label (progn (goto-char (match-end 10))
396e0b08
KH
1817 (save-match-data
1818 (reftex-no-props
1819 (reftex-nth-arg-wrapper
1820 mac)))))
b849548d
CD
1821 (typekey (nth 1 (assoc mac reftex-env-or-mac-alist)))
1822 (entry (progn (if typekey
1823 ;; A typing macro
1824 (goto-char (match-end 0))
1825 ;; A newtral macro
1826 (goto-char (match-end 10))
1827 (reftex-move-over-touching-args))
1828 (reftex-label-info
1829 label file bound nil nil))))
396e0b08
KH
1830 (push entry docstruct))))
1831 (t (error "This should not happen (reftex-parse-from-file)")))
1832 )
1833
396e0b08
KH
1834 ;; Find bibliography statement
1835 (when (setq tmp (reftex-locate-bibliography-files master-dir))
1836 (push (cons 'bib tmp) docstruct))
1837
2faef409
RS
1838 (goto-char 1)
1839 (when (re-search-forward
1840 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\begin{thebibliography}" nil t)
1841 (push (cons 'thebib file) docstruct))
1842
396e0b08
KH
1843 ;; Find external document specifications
1844 (goto-char 1)
1845 (while (re-search-forward "[\n\r][ \t]*\\\\externaldocument\\(\\[\\([^]]*\\)\\]\\)?{\\([^}]+\\)}" nil t)
2faef409 1846 (push (list 'xr-doc (reftex-match-string 2)
396e0b08
KH
1847 (reftex-match-string 3))
1848 docstruct))
1849
1850 ;; End of file mark
1851 (push (list 'eof file) docstruct))))
1852
1853 ;; Kill the scanned buffer
1854 (reftex-kill-temporary-buffers next-buf))
1855
1856 ;; Return the list
1857 docstruct))
1858
1859(defun reftex-locate-bibliography-files (master-dir)
2faef409 1860 ;; Scan buffer for bibliography macro and return file list.
b849548d 1861 (let (files)
396e0b08
KH
1862 (save-excursion
1863 (goto-char (point-min))
b849548d
CD
1864 (when (re-search-forward
1865 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\bibliography{[ \t]*\\([^}]+\\)" nil t)
1866 (setq files (split-string (reftex-match-string 2)
1867 "[ \t\n\r]*,[ \t\n\r]*"))
1868 (setq files
1869 (mapcar
1870 (lambda (x)
1871 (if (or (member x reftex-bibfile-ignore-list)
1872 (delq nil (mapcar (lambda (re) (string-match re x))
1873 reftex-bibfile-ignore-regexps)))
1874 ;; excluded file
1875 nil
1876 ;; find the file
1877 (reftex-find-bib-file
1878 (if (string-match "\\.bib\\'" x) x (concat x ".bib"))
1879 master-dir)))
1880 files))
1881 (delq nil files)))))
396e0b08
KH
1882
1883(defun reftex-replace-label-list-segment (old insert &optional entirely)
1884 ;; Replace the segment in OLD which corresponds to INSERT.
1885 ;; Works with side effects, directly changes old.
1886 ;; If entirely is t, just return INSERT.
1887 ;; This function also makes sure the old toc markers do not point anywhere.
1888
1889 (cond
1890 (entirely
1891 (reftex-silence-toc-markers old (length old))
1892 insert)
1893 (t (let* ((new old)
1894 (file (nth 1 (car insert)))
1895 (eof-list (member (list 'eof file) old))
1896 (bof-list (member (list 'bof file) old))
1897 n)
1898 (if (not (and bof-list eof-list))
1899 (error "Cannot splice")
1900 ;; Splice
1901 (reftex-silence-toc-markers bof-list (- (length bof-list)
1902 (length eof-list)))
1903 (setq n (- (length old) (length bof-list)))
1904 (setcdr (nthcdr n new) (cdr insert))
1905 (setcdr (nthcdr (1- (length new)) new) (cdr eof-list)))
1906 new))))
1907
1908(defun reftex-silence-toc-markers (list n)
b849548d 1909 ;; Set all toc markers in the first N entries in list to nil
396e0b08
KH
1910 (while (and list (> (decf n) -1))
1911 (and (eq (car (car list)) 'toc)
1912 (markerp (nth 4 (car list)))
1913 (set-marker (nth 4 (car list)) nil))
1914 (pop list)))
1915
1916(defun reftex-access-parse-file (action)
b849548d
CD
1917 "Perform ACTION on the parse file (the .rel file).
1918Valid actions are: readable, restore, read, kill, write."
396e0b08 1919 (let* ((list (symbol-value reftex-docstruct-symbol))
b849548d 1920 (docstruct-symbol reftex-docstruct-symbol)
396e0b08
KH
1921 (master (reftex-TeX-master-file))
1922 (enable-local-variables nil)
1923 (file (if (string-match "\\.[a-zA-Z]+\\'" master)
1924 (concat (substring master 0 (match-beginning 0)) ".rel")
1925 (concat master ".rel"))))
1926 (cond
1927 ((eq action 'readable)
1928 (file-readable-p file))
1929 ((eq action 'restore)
b849548d 1930 (put reftex-docstruct-symbol 'modified nil)
396e0b08
KH
1931 (if (eq reftex-docstruct-symbol nil)
1932 ;; Symbols are not yet tied: Tie them.
1933 (reftex-tie-multifile-symbols))
1934 (if (file-exists-p file)
1935 ;; load the file and return t for success
b849548d
CD
1936 (condition-case nil
1937 (progn (load-file file) t)
1938 (error (set reftex-docstruct-symbol nil)
1939 (error "Error while loading file %s" file)))
1940 ;; Throw an exception if the file does not exist
2faef409 1941 (error "No restore file %s" file)))
396e0b08 1942 ((eq action 'read)
b849548d 1943 (put reftex-docstruct-symbol 'modified nil)
396e0b08
KH
1944 (if (file-exists-p file)
1945 ;; load the file and return t for success
b849548d
CD
1946 (condition-case nil
1947 (progn (load-file file) t)
1948 (error (message "Error while loading file %s" file)
1949 (set reftex-docstruct-symbol nil)
1950 nil))
2faef409 1951 ;; return nil for failure, but no exception
396e0b08 1952 nil))
b849548d
CD
1953 ((eq action 'kill)
1954 ;; Remove the file
1955 (when (and (file-exists-p file) (file-writable-p file))
1956 (message "Unlinking file %s" file)
1957 (delete-file file)))
396e0b08 1958 (t
b849548d 1959 (put docstruct-symbol 'modified nil)
396e0b08
KH
1960 (save-excursion
1961 (if (file-writable-p file)
1962 (progn
1963 (message "Writing parse file %s" (abbreviate-file-name file))
1964 (find-file file)
1965 (erase-buffer)
1966 (insert (format ";; RefTeX parse info file\n"))
1967 (insert (format ";; File: %s\n" master))
396e0b08
KH
1968 (insert (format ";; User: %s (%s)\n\n"
1969 (user-login-name) (user-full-name)))
1970 (insert "(set reftex-docstruct-symbol '(\n\n")
1971 (let ((standard-output (current-buffer)))
1972 (mapcar
1973 (function
1974 (lambda (x)
1975 (cond ((eq (car x) 'toc)
1976 ;; A toc entry. Do not save the marker.
1977 ;; Save the markers position at position 8
1978 (print (list 'toc "toc" (nth 2 x) (nth 3 x)
1979 nil (nth 5 x) (nth 6 x) (nth 7 x)
1980 (or (and (markerp (nth 4 x))
1981 (marker-position (nth 4 x)))
1982 (nth 8 x)))))
1983 (t (print x)))))
1984 list))
b849548d 1985 (insert "))\n\n")
396e0b08
KH
1986 (save-buffer 0)
1987 (kill-buffer (current-buffer)))
1988 (error "Cannot write to file %s" file)))
1989 t))))
1990
b849548d
CD
1991(defun reftex-kill-buffer-hook ()
1992 "Save RefTeX's parse file for this buffer if the information has changed."
1993 ;; Save the parsing information if it was modified.
1994 ;; This function should be installed in `kill-buffer-hook'.
1995 ;; We are careful to make sure nothing goes wring in this function.
1996 (when (and (boundp 'reftex-mode) reftex-mode
1997 (boundp 'reftex-save-parse-info) reftex-save-parse-info
1998 (boundp 'reftex-docstruct-symbol) reftex-docstruct-symbol
1999 (symbol-value reftex-docstruct-symbol)
2000 (get reftex-docstruct-symbol 'modified))
2001 ;; Write the file.
2002 (condition-case nil
2003 (reftex-access-parse-file 'write)
2004 (error nil))))
396e0b08 2005
b849548d
CD
2006(defun reftex-kill-emacs-hook ()
2007 "Call `reftex-kill-buffer-hook' on all buffers."
2008 ;; This function should be installed in `kill-emacs-hook'.
2009 (save-excursion
2010 (mapcar (lambda (buf)
2011 (set-buffer buf)
2012 (reftex-kill-buffer-hook))
2013 (buffer-list))))
a7ec1775 2014
b849548d
CD
2015(defun reftex-section-info (file)
2016 ;; Return a section entry for the current match.
2017 ;; Carefull: This function expects the match-data to be still in place!
2018 (let* ((marker (set-marker (make-marker) (1- (match-beginning 3))))
2019 (macro (reftex-match-string 3))
2020 (star (= ?* (char-after (match-end 3))))
2021 (level (cdr (assoc macro reftex-section-levels-all)))
2022 (section-number (reftex-section-number level star))
2023 (text1 (save-match-data (save-excursion (reftex-context-substring))))
2024 (literal (buffer-substring-no-properties
2025 (1- (match-beginning 3))
2026 (min (point-max) (+ (match-end 0) (length text1) 1))))
2027 ;; Literal can be too short since text1 too short. No big problem.
2028 (text (reftex-nicify-text text1)))
a7ec1775 2029
b849548d
CD
2030 ;; Add section number and indentation
2031 (setq text
2032 (concat
2033 (make-string (* reftex-level-indent level) ?\ )
2034 (if (nth 1 reftex-label-menu-flags) ; section number flag
2035 (concat section-number " "))
2036 text))
2037 (list 'toc "toc" text file marker level section-number
2038 literal (marker-position marker))))
2faef409 2039
b849548d
CD
2040(defun reftex-label-info-update (cell)
2041 ;; Update information about just one label in a different file.
2042 ;; CELL contains the old info list
2043 (let* ((label (nth 0 cell))
2044 (typekey (nth 1 cell))
2045 ;; (text (nth 2 cell))
2046 (file (nth 3 cell))
2047 (comment (nth 4 cell))
2048 (note (nth 5 cell))
2049 (buf (reftex-get-file-buffer-force
2050 file (not (eq t reftex-keep-temporary-buffers)))))
2051 (if (not buf)
2052 (list label typekey "" file comment "LOST LABEL. RESCAN TO FIX.")
2053 (save-excursion
2054 (set-buffer buf)
2055 (save-restriction
2056 (widen)
2057 (goto-char 1)
2faef409 2058
b849548d
CD
2059 (if (or (re-search-forward
2060 (format reftex-find-label-regexp-format
2061 (regexp-quote label)) nil t)
2062 (re-search-forward
2063 (format reftex-find-label-regexp-format2
2064 (regexp-quote label)) nil t))
2faef409 2065
b849548d
CD
2066 (progn
2067 (backward-char 1)
2068 (append (reftex-label-info label file) (list note)))
2069 (list label typekey "" file "LOST LABEL. RESCAN TO FIX.")))))))
2faef409 2070
b849548d
CD
2071(defun reftex-label-info (label &optional file bound derive env-or-mac)
2072 ;; Return info list on LABEL at point.
2073 (let* ((env-or-mac (or env-or-mac (reftex-label-location bound)))
2074 (typekey (nth 1 (assoc env-or-mac reftex-env-or-mac-alist)))
2075 (file (or file (buffer-file-name)))
2076 (parse (if (reftex-typekey-check
2077 typekey reftex-use-text-after-label-as-context)
2078 nil
2079 (nth 2 (assoc env-or-mac reftex-env-or-mac-alist))))
2080 (text (reftex-short-context env-or-mac parse reftex-location-start
2081 derive))
2082 (in-comment (reftex-in-comment)))
2083 (list label typekey text file in-comment)))
2faef409 2084
b849548d
CD
2085(defun reftex-in-comment ()
2086 (save-excursion
2087 (skip-chars-backward "^%\n\r")
2088 (eq (preceding-char) ?%)))
a7ec1775 2089
b849548d
CD
2090(defun reftex-short-context (env parse &optional bound derive)
2091 ;; Get about one line of useful context for the label definition at point.
a7ec1775 2092
b849548d
CD
2093 (if (consp parse)
2094 (setq parse (if derive (cdr parse) (car parse))))
a7ec1775 2095
b849548d 2096 (reftex-nicify-text
a7ec1775 2097
b849548d 2098 (cond
a7ec1775 2099
b849548d
CD
2100 ((null parse)
2101 (save-excursion
2102 (reftex-context-substring)))
a7ec1775 2103
b849548d
CD
2104 ((eq parse t)
2105 (if (string= env "section")
2106 ;; special treatment for section labels
2107 (save-excursion
2108 (if (and (re-search-backward reftex-section-or-include-regexp
2109 (point-min) t)
2110 (match-end 2))
2111 (progn
2112 (goto-char (match-end 0))
2113 (reftex-context-substring))
2114 (if reftex-active-toc
2115 (progn
2116 (string-match "{\\([^}]*\\)" (nth 7 reftex-active-toc))
2117 (match-string 1 (nth 7 reftex-active-toc)))
2118 "SECTION HEADING NOT FOUND")))
2119 (save-excursion
2120 (goto-char reftex-default-context-position)
2121 (unless (eq (string-to-char env) ?\\)
2122 (reftex-move-over-touching-args))
2123 (reftex-context-substring))))
a7ec1775 2124
b849548d
CD
2125 ((stringp parse)
2126 (save-excursion
2127 (if (re-search-backward parse bound t)
2128 (progn
2129 (goto-char (match-end 0))
2130 (reftex-context-substring))
2131 "NO MATCH FOR CONTEXT REGEXP")))
a7ec1775 2132
b849548d
CD
2133 ((integerp parse)
2134 (or (save-excursion
2135 (goto-char reftex-default-context-position)
2136 (reftex-nth-arg
2137 parse
2138 (nth 6 (assoc env reftex-env-or-mac-alist))))
2139 ""))
a7ec1775 2140
b849548d
CD
2141 ((fboundp parse)
2142 ;; A hook function. Call it.
2143 (save-excursion
2144 (condition-case error-var
2145 (funcall parse env)
2146 (error (format "HOOK ERROR: %s" (cdr error-var))))))
2147 (t
2148 "ILLEGAL VALUE OF PARSE"))))
a7ec1775 2149
b849548d
CD
2150(defun reftex-nicify-text (text)
2151 ;; Make TEXT nice for inclusion as context into label menu
2152 ;; remove line breaks and extra white space
2153 (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text)
2154 (setq text (replace-match " " nil t text)))
2155 ;; cut before the next `\end{' or `\item' or `\\'
2156 (if (string-match "\\(\\\\end{\\|\\\\item\\|\\\\\\\\\\).*" text)
2157 (setq text (replace-match "" nil t text)))
2158 ;; kill the embedded label
2159 (if (string-match "\\\\label{[^}]*}" text)
2160 (setq text (replace-match "" nil t text)))
2161 ;; remove leading garbage
2162 (if (string-match "\\`[ }]+" text)
2163 (setq text (replace-match "" nil t text)))
2164 ;; limit length
2165 (cond
2166 ((> (length text) 100) (substring text 0 100))
2167 ((= (length text) 0) (make-string 1 ?\ ))
2168 (t text)))
a7ec1775 2169
b849548d
CD
2170(defun reftex-where-am-I ()
2171 ;; Return the docstruct entry above point. Actually returns a cons
2172 ;; cell in which the cdr is a flag indicating if the information is
2173 ;; exact (t) or approximate (nil).
a7ec1775 2174
b849548d
CD
2175 (let ((docstruct (symbol-value reftex-docstruct-symbol))
2176 (cnt 0) rtn
2177 found)
2178 (save-excursion
2179 (while (not rtn)
2180 (incf cnt)
2181 (setq found (re-search-backward reftex-everything-regexp nil t))
2182 (setq rtn
2183 (cond
2184 ((not found)
2185 ;; no match
2186 (or
2187 (car (member (list 'bof (buffer-file-name)) docstruct))
2188 (not (setq cnt 2))
2189 (assq 'bof docstruct) ;; for safety reasons
2190 'corrupted))
2191 ((match-end 1)
2192 ;; Label
2193 (assoc (reftex-match-string 1)
2194 (symbol-value reftex-docstruct-symbol)))
2195 ((match-end 3)
2196 ;; Section
2197 (goto-char (1- (match-beginning 3)))
2198 (let* ((list (member (list 'bof (buffer-file-name))
2199 docstruct))
2200 (endelt (car (member (list 'eof (buffer-file-name))
2201 list)))
2202 rtn1)
2203 (while (and list (not (eq endelt (car list))))
2204 (if (and (eq (car (car list)) 'toc)
2205 (string= (buffer-file-name)
2206 (nth 3 (car list))))
2207 (cond
2208 ((equal (point)
2209 (or (and (markerp (nth 4 (car list)))
2210 (marker-position (nth 4 (car list))))
2211 (nth 8 (car list))))
2212 ;; Fits with marker position or recorded position
2213 (setq rtn1 (car list) list nil))
2214 ((looking-at (reftex-make-regexp-allow-for-ctrl-m
2215 (nth 7 (car list))))
2216 ;; Same title
2217 (setq rtn1 (car list) list nil cnt 2))))
2218 (pop list))
2219 rtn1))
2220 ((match-end 7)
2221 ;; Input or include...
2222 (car
2223 (member (list 'eof (reftex-find-tex-file
2224 (reftex-match-string 7)
2225 (cdr (assq 'master-dir docstruct))))
2226 docstruct)))
2227 ((match-end 9)
2228 (assq 'appendix (symbol-value reftex-docstruct-symbol)))
2229 ((match-end 10)
2230 (save-excursion
2231 (goto-char (match-end 10))
2232 (assoc (reftex-no-props
2233 (reftex-nth-arg-wrapper
2234 (reftex-match-string 10)))
2235 (symbol-value reftex-docstruct-symbol))))
2236 (t
2237 (error "This should not happen (reftex-where-am-I)"))))))
2238 (cons rtn (eq cnt 1))))
206c6f82 2239
a7ec1775 2240(defun reftex-label-location (&optional bound)
b849548d
CD
2241 "Return the environment or macro which determines the label type at point.
2242If optional BOUND is an integer, limit backward searches to that point."
a7ec1775
RS
2243
2244 (let* ((loc1 (reftex-what-macro reftex-label-mac-list bound))
2245 (loc2 (reftex-what-environment reftex-label-env-list bound))
2246 (p1 (or (cdr loc1) 0))
2247 (p2 (or (cdr loc2) 0)))
2248
2249 (setq reftex-location-start (max p1 p2))
396e0b08 2250 (if (>= p1 p2)
a7ec1775 2251 (progn
396e0b08
KH
2252 (setq reftex-default-context-position (+ p1 (length (car loc1))))
2253 (or (car loc1) "section"))
2254 (setq reftex-default-context-position (+ p2 8 (length (car loc2))))
a7ec1775
RS
2255 (or (car loc2) "section"))))
2256
b849548d
CD
2257(defun reftex-parse-args (macro)
2258 ;; Return a list of macro name, nargs, arg-nr which is label and a list of
2259 ;; optional argument indices.
2260 (if (string-match "[[{]\\*?[]}]" macro)
2261 (progn
2262 (let ((must-match (substring macro 0 (match-beginning 0)))
2263 (args (substring macro (match-beginning 0)))
2264 opt-list nlabel (cnt 0))
2265 (while (string-match "\\`[[{]\\(\\*\\)?[]}]" args)
2266 (incf cnt)
2267 (when (eq ?\[ (string-to-char args))
2268 (push cnt opt-list))
2269 (when (and (match-end 1)
2270 (not nlabel))
2271 (setq nlabel cnt))
2272 (setq args (substring args (match-end 0))))
2273 (list must-match cnt nlabel opt-list)))
2274 nil))
396e0b08 2275
b849548d
CD
2276(defsubst reftex-move-to-next-arg (&optional ignore)
2277 ;; Assuming that we are at the end of a macro name or a macro argument,
2278 ;; move forward to the opening parenthesis of the next argument.
2279 ;; This function understands the splitting of macros over several lines
2280 ;; in TeX.
206c6f82 2281 (cond
b849548d
CD
2282 ;; Just to be quick:
2283 ((memq (following-char) '(?\[ ?\{)))
2284 ;; Do a search
2285 ((and reftex-allow-detached-macro-args
2286 (looking-at "[ \t]*[\n\r]?\\([ \t]*%[^\n\r]*[\n\r]\\)*[ \t]*[[{]"))
2287 (goto-char (1- (match-end 0)))
2288 t)
2289 (t nil)))
a7ec1775 2290
b849548d
CD
2291(defsubst reftex-move-to-previous-arg (&optional bound)
2292 ;; Assuming that we are in front of a macro argument,
2293 ;; move backward to the closing parenthesis of the previous argument.
2294 ;; This function understands the splitting of macros over several lines
2295 ;; in TeX.
2296 (cond
2297 ;; Just to be quick:
2298 ((memq (preceding-char) '(?\] ?\})))
2299 ;; Do a search
2300 ((and reftex-allow-detached-macro-args
2301 (re-search-backward
2302 "[]}][ \t]*[\n\r]?\\([ \t]*%[^\n\r]*[\n\r]\\)*[ \t]*\\=" bound t))
2303 (goto-char (1+ (match-beginning 0)))
2304 t)
2305 (t nil)))
206c6f82 2306
b849548d
CD
2307(defun reftex-nth-arg-wrapper (key)
2308 (let ((entry (assoc key reftex-env-or-mac-alist)))
2309 (reftex-nth-arg (nth 5 entry) (nth 6 entry))))
2faef409 2310
b849548d
CD
2311(defun reftex-nth-arg (n &optional opt-args)
2312 ;; Return the nth following {} or [] parentheses content.
2313 ;; OPT-ARGS is a list of argument numbers which are optional.
a7ec1775 2314
b849548d
CD
2315 ;; If we are sitting at a macro start, skip to end of macro name.
2316 (and (eq (following-char) ?\\) (skip-chars-forward "a-zA-Z*\\\\"))
29d593f8 2317
b849548d
CD
2318 (if (= n 1000)
2319 ;; Special case: Skip all touching arguments
2320 (progn
2321 (reftex-move-over-touching-args)
2322 (reftex-context-substring))
29d593f8 2323
b849548d
CD
2324 ;; Do the real thing.
2325 (let ((cnt 1))
2326
2327 (when (reftex-move-to-next-arg)
2328
2329 (while (< cnt n)
2330 (while (and (member cnt opt-args)
2331 (eq (following-char) ?\{))
2332 (incf cnt))
2333 (when (< cnt n)
2334 (unless (and (condition-case nil
2335 (or (forward-list 1) t)
2336 (error nil))
2337 (reftex-move-to-next-arg)
2338 (incf cnt))
2339 (setq cnt 1000))))
29d593f8 2340
b849548d
CD
2341 (while (and (memq cnt opt-args)
2342 (eq (following-char) ?\{))
2343 (incf cnt)))
2344 (if (and (= n cnt)
2345 (> (skip-chars-forward "{\\[") 0))
2346 (reftex-context-substring)
2347 nil))))
29d593f8 2348
b849548d
CD
2349(defun reftex-move-over-touching-args ()
2350 (condition-case nil
2351 (while (memq (following-char) '(?\[ ?\{))
2352 (forward-list 1))
2353 (error nil)))
a7ec1775 2354
b849548d
CD
2355(defun reftex-context-substring ()
2356 ;; Return up to 100 chars from point
2357 ;; When point is just after a { or [, limit string to matching parenthesis
2358 (cond
2359 ((or (= (preceding-char) ?\{)
2360 (= (preceding-char) ?\[))
2361 ;; Inside a list - get only the list.
2362 (buffer-substring-no-properties
2363 (point)
2364 (min (+ (point) 150)
2365 (point-max)
2366 (condition-case nil
2367 (progn
2368 (up-list 1)
2369 (1- (point)))
2370 (error (point-max))))))
2371 (t
2372 ;; no list - just grab 100 characters
2373 (buffer-substring-no-properties (point)
2374 (min (+ (point) 150) (point-max))))))
a7ec1775 2375
b849548d
CD
2376;; Variable holding the vector with section numbers
2377(defvar reftex-section-numbers [0 0 0 0 0 0 0 0])
2378
2379(defun reftex-init-section-numbers (&optional toc-entry appendix)
2380 ;; Initialize the section numbers with zeros or with what is found
2381 ;; in the toc entry.
2382 (let* ((level (or (nth 5 toc-entry) -1))
2383 (numbers (nreverse (split-string (or (nth 6 toc-entry) "") "\\.")))
2384 (depth (1- (length reftex-section-numbers)))
2385 (i depth) number-string)
2386 (while (>= i 0)
2387 (if (> i level)
2388 (aset reftex-section-numbers i 0)
2389 (setq number-string (or (car numbers) "0"))
2390 (if (string-match "\\`[A-Z]\\'" number-string)
2391 (aset reftex-section-numbers i
2392 (- (string-to-char number-string) ?A -1))
2393 (aset reftex-section-numbers i (string-to-int number-string)))
2394 (pop numbers))
2395 (decf i)))
2396 (put 'reftex-section-numbers 'appendix appendix))
2397
2398(defun reftex-section-number (&optional level star)
2399 ;; Return a string with the current section number.
2400 ;; When LEVEL is non-nil, increase section numbers on that level.
2401 (let* ((depth (1- (length reftex-section-numbers))) idx n (string "")
2402 (appendix (get 'reftex-section-numbers 'appendix)))
2403 (when level
2404 (when (and (> level -1) (not star))
2405 (aset reftex-section-numbers
2406 level (1+ (aref reftex-section-numbers level))))
2407 (setq idx (1+ level))
2408 (when (not star)
2409 (while (<= idx depth)
2410 (aset reftex-section-numbers idx 0)
2411 (incf idx))))
2412 (setq idx 0)
2413 (while (<= idx depth)
2414 (setq n (aref reftex-section-numbers idx))
2415 (setq string (concat string (if (not (string= string "")) "." "")
2416 (int-to-string n)))
2417 (incf idx))
2418 (save-match-data
2419 (if (string-match "\\`\\([@0]\\.\\)+" string)
2420 (setq string (replace-match "" nil nil string)))
2421 (if (string-match "\\(\\.0\\)+\\'" string)
2422 (setq string (replace-match "" nil nil string)))
2423 (if (and appendix
2424 (string-match "\\`[0-9]+" string))
2425 (setq string
2426 (concat
2427 (char-to-string
2428 (1- (+ ?A (string-to-int (match-string 0 string)))))
2429 (substring string (match-end 0))))))
2430 (if star
2431 (concat (make-string (1- (length string)) ?\ ) "*")
2432 string)))
2433
2434(defun reftex-is-multi ()
2435 ;; Tell if this is a multifile document. When not sure, say yes.
2436 (let ((entry (assq 'is-multi (symbol-value reftex-docstruct-symbol))))
2437 (if entry
2438 (nth 1 entry)
2439 t)))
2440
2441(defun reftex-typekey-check (typekey conf-variable &optional n)
2442 ;; Check if CONF-VARIABLE is true or contains TYPEKEY
2443 (and n (setq conf-variable (nth n conf-variable)))
2444 (or (eq conf-variable t)
2445 (and (stringp conf-variable)
2446 (string-match (concat "[" conf-variable "]") typekey))))
2447
2448(defun reftex-all-document-files (&optional relative)
2449 "Return a list of all files belonging to the current document.
2450When RELATIVE is non-nil, give file names relative to directory
2451of master file."
2452 (let* ((all (symbol-value reftex-docstruct-symbol))
2453 (master-dir (file-name-directory (reftex-TeX-master-file)))
2454 (re (concat "\\`" (regexp-quote master-dir)))
2455 file-list tmp file)
2456 (while (setq tmp (assoc 'bof all))
2457 (setq file (nth 1 tmp)
2458 all (cdr (memq tmp all)))
2459 (and relative
2460 (string-match re file)
2461 (setq file (substring file (match-end 0))))
2462 (push file file-list))
2463 (nreverse file-list)))
2464
2465;;; Creating labels ---------------------------------------------------------
2466
2467(defun reftex-label (&optional environment no-insert)
2468 "Insert a unique label. Return the label.
2469If ENVIRONMENT is given, don't bother to find out yourself.
2470If NO-INSERT is non-nil, do not insert label into buffer.
2471With prefix arg, force to rescan document first.
2472When you are prompted to enter or confirm a label, and you reply with
2473just the prefix or an empty string, no label at all will be inserted.
2474A new label is also recorded into the label list.
2475This function is controlled by the settings of reftex-insert-label-flags."
2476
2477 (interactive)
2478
2479 ;; Ensure access to scanning info and rescan buffer if prefix are is '(4).
2480 (reftex-access-scan-info current-prefix-arg)
2481
2482 ;; Find out what kind of environment this is and abort if necessary.
2483 (if (or (not environment)
2484 (not (assoc environment reftex-env-or-mac-alist)))
2485 (setq environment (reftex-label-location)))
2486 (unless environment
2487 (error "Can't figure out what kind of label should be inserted"))
2488
2489 ;; Ok, go ahead.
2490 (catch 'exit
2491 (let* ((entry (assoc environment reftex-env-or-mac-alist))
2492 (typekey (nth 1 entry))
2493 (format (nth 3 entry))
2494 (macro-cell (reftex-what-macro 1))
2495 (entry1 (assoc (car macro-cell) reftex-env-or-mac-alist))
2496 label naked prefix valid default force-prompt rescan-is-useful)
2497 (when (and (or (nth 5 entry) (nth 5 entry1))
2498 (memq (preceding-char) '(?\[ ?\{)))
2499 ;; This is an argument of a label macro. Insert naked label.
2500 (setq naked t format "%s"))
2501
2502 (setq prefix (or (cdr (assoc typekey reftex-typekey-to-prefix-alist))
2503 (concat typekey "-")))
2504 ;; Replace any escapes in the prefix
2505 (setq prefix (reftex-replace-prefix-escapes prefix))
2506
2507 ;; Make a default label.
2508 (cond
2509
2510 ((reftex-typekey-check typekey (nth 0 reftex-insert-label-flags))
2511 ;; Derive a label from context.
2512 (setq reftex-active-toc (reftex-last-assoc-before-elt
2513 'toc (car (reftex-where-am-I))
2514 (symbol-value reftex-docstruct-symbol)))
2515 (setq default (reftex-no-props
2516 (nth 2 (reftex-label-info " " nil nil t))))
2517 ;; Catch the cases where the is actually no context available.
2518 (if (or (string-match "NO MATCH FOR CONTEXT REGEXP" default)
2519 (string-match "ILLEGAL VALUE OF PARSE" default)
2520 (string-match "SECTION HEADING NOT FOUND" default)
2521 (string-match "HOOK ERROR" default)
2522 (string-match "^[ \t]*$" default))
2523 (setq default prefix
2524 force-prompt t) ; need to prompt
2525 (setq default
2526 (concat prefix
2527 (funcall reftex-string-to-label-function default)))
2528
2529 ;; Make it unique.
2530 (setq default (reftex-uniquify-label default nil "-"))))
2531
2532 ((reftex-typekey-check typekey (nth 1 reftex-insert-label-flags))
2533 ;; Minimal default: the user will be prompted.
2534 (setq default prefix))
2535
2536 (t
2537 ;; Make an automatic label.
2538 (setq default (reftex-uniquify-label prefix t))))
2539
2540 ;; Should we ask the user?
2541 (if (or (reftex-typekey-check typekey
2542 (nth 1 reftex-insert-label-flags)) ; prompt
2543 force-prompt)
2544
2545 (while (not valid)
2546 ;; iterate until we get a legal label
2547
2548 (setq label (read-string
2549 (if naked "Naked Label: " "Label: ")
2550 default))
2551
2552 ;; Lets make sure that this is a legal label
2553 (cond
2554
2555 ((string-match (concat "\\`\\(" (regexp-quote prefix)
2556 "\\)?[ \t]*\\'")
2557 label)
2558 ;; No label at all, please
2559 (message "No label inserted.")
2560 (throw 'exit nil))
2561
2562 ;; Test if label contains strange characters
2563 ((string-match reftex-label-illegal-re label)
2564 (message "Label \"%s\" contains illegal characters" label)
2565 (ding)
2566 (sit-for 2))
2567
2568 ;; Look it up in the label list
2569 ((setq entry (assoc label
2570 (symbol-value reftex-docstruct-symbol)))
2571 (ding)
2572 (if (y-or-n-p
2573 (format "Label '%s' exists. Use anyway? " label))
2574 (setq valid t)))
2575
2576 ;; Label is ok
2577 (t
2578 (setq valid t))))
2579 (setq label default))
2580
2581 ;; Insert the label into the label list
2582 (let* ((here-I-am-info
2583 (save-excursion
2584 (if (and (or naked no-insert)
2585 (integerp (cdr macro-cell)))
2586 (goto-char (cdr macro-cell)))
2587 (reftex-where-am-I)))
2588 (here-I-am (car here-I-am-info))
2589 (note (if (cdr here-I-am-info)
2590 ""
2591 "POSITION UNCERTAIN. RESCAN TO FIX."))
2592 (file (buffer-file-name))
2593 (text nil)
2594 (tail (memq here-I-am (symbol-value reftex-docstruct-symbol))))
2595
2596 (or (cdr here-I-am-info) (setq rescan-is-useful t))
2597
2598 (when tail
2599 (push (list label typekey text file nil note) (cdr tail))
2600 (put reftex-docstruct-symbol 'modified t)))
2601
2602 ;; Insert the label into the buffer
2603 (unless no-insert
2604 (insert
2605 (if reftex-format-label-function
2606 (funcall reftex-format-label-function label format)
2607 (format format label)))
2608 (if (and reftex-plug-into-AUCTeX
2609 (fboundp 'LaTeX-add-labels))
2610 ;; Tell AUCTeX about this
2611 (LaTeX-add-labels label)))
2612
2613 ;; Delete the corresponding selection buffers to force update on next use.
2614 (when reftex-auto-update-selection-buffers
2615 (reftex-erase-buffer (reftex-make-selection-buffer-name typekey))
2616 (reftex-erase-buffer (reftex-make-selection-buffer-name " ")))
2617
2618 (when (and rescan-is-useful reftex-allow-automatic-rescan)
2619 (reftex-parse-one))
2620
2621 ;; return value of the function is the label
2622 label)))
2623
2624(defun reftex-string-to-label (string)
2625 "Convert a string (a sentence) to a label.
2626Uses `reftex-derive-label-parameters' and `reftex-label-illegal-re'. It
2627also applies `reftex-translate-to-ascii-function' to the string."
2628 (when (and reftex-translate-to-ascii-function
2629 (fboundp reftex-translate-to-ascii-function))
2630 (setq string (funcall reftex-translate-to-ascii-function string)))
2631 (apply 'reftex-convert-string string
2632 "[-~ \t\n\r,;]+" reftex-label-illegal-re nil nil
2633 reftex-derive-label-parameters))
2634
2635(defun reftex-abbreviate-title (string)
2636 (reftex-convert-string string "[-~ \t\n\r,;]" nil t t
2637 5 40 nil 1 " " (nth 5 reftex-derive-label-parameters)))
2638
2639(defun reftex-convert-string (string split-re illegal-re dot keep-fp
2640 nwords maxchar illegal abbrev sep
2641 ignore-words &optional downcase)
2642 "Convert a string (a sentence) to something shorter.
2643SPLIT-RE is the regular expression used to split the string into words.
2644ILLEGAL-RE matches characters which are illegal in the final string.
2645DOT t means add dots to abbreviated words.
2646KEEP-FP t means to keep a final punctuation when applicable.
2647NWORDS Number of words to use.
2648MAXCHAR Maximum number of characters in the final string.
2649ILLEGAL nil: Throw away any words containing stuff matched with ILLEGAL-RE.
2650 t: Throw away only the matched part, not the whole word.
2651ABBREV nil: Never abbreviate words.
2652 t: Always abbreviate words (see `reftex-abbrev-parameters').
2653 not t and not nil: Abbreviate words if necessary to shorten
2654 string below MAXCHAR.
2655SEP String separating different words in the output string.
2656IGNORE-WORDS List of words which should be removed from the string."
2657
2658 (let* ((words0 (split-string string (or split-re "[ \t\n\r]")))
a6611c0d 2659 (reftex-label-illegal-re (or illegal-re "\000"))
b849548d
CD
2660 words word)
2661
2662 ;; Remove words from the ignore list or with funny characters
2663 (while (setq word (pop words0))
2664 (if downcase (setq word (downcase word)))
2665 (cond
2666 ((member (downcase word) ignore-words))
a6611c0d 2667 ((string-match reftex-label-illegal-re word)
b849548d 2668 (when illegal
a6611c0d 2669 (while (string-match reftex-label-illegal-re word)
b849548d
CD
2670 (setq word (replace-match "" nil nil word)))
2671 (push word words)))
2672 (t
2673 (push word words))))
2674 (setq words (nreverse words))
2675
2676 ;; Restrict number of words
2677 (if (> (length words) nwords)
2678 (setcdr (nthcdr (1- nwords) words) nil))
2679
2680 ;; First, try to use all words
2681 (setq string (mapconcat 'identity words sep))
2682
2683 ;; Abbreviate words if enforced by user settings or string length
2684 (if (or (eq t abbrev)
2685 (and abbrev
2686 (> (length string) maxchar)))
2687 (setq words
2688 (mapcar
2689 (function
2690 (lambda (w) (if (string-match reftex-abbrev-regexp w)
2691 (if dot
2692 (concat (match-string 1 w) ".")
2693 (match-string 1 w))
2694 w)))
2695 words)
2696 string (mapconcat 'identity words sep)))
2697
2698 ;; Shorten if still to long
2699 (setq string
2700 (if (> (length string) maxchar)
2701 (substring string 0 maxchar)
2702 string))
2703
2704 ;; Delete the final punctuation, if any
2705 (if (and (not keep-fp) (string-match "\\s.+\\'" string))
2706 (setq string (replace-match "" nil nil string)))
2707 string))
2708
a6611c0d
CD
2709(defun reftex-latin1-to-ascii (string)
2710 ;; Translate the upper 127 chars in the ISO1 charset to ASCII equivalents
2711 (let ((tab "@@@@@@@@@@@@@@@@@@'@@@@@@@@@@@@@ icLxY|S\"ca<--R-o|23'uq..1o>423?AAAAAAACEEEEIIIIDNOOOOOXOUUUUYP3aaaaaaaceeeeiiiidnooooo:ouuuuypy") c)
2712 (loop for i from 0 to (1- (length string)) do
2713 (setq c (aref string i))
2714 (cond ((and (> c 127) (< c 256)) ; 8 bit Latin-1
2715 (aset string i (aref tab (- c 128))))
2716 ((and (> c 2175) (< c 2304)) ; Mule Latin-1,
2717 (aset string i (aref tab (- c 2176)))))) ; Std. Emacs only
2718 string))
2719
b849548d
CD
2720(defun reftex-replace-prefix-escapes (prefix)
2721 ;; Replace %escapes in a label prefix
2722 (save-match-data
2723 (let (letter (num 0) replace)
2724 (while (string-match "\\%\\([a-zA-Z]\\)" prefix num)
2725 (setq letter (match-string 1 prefix))
2726 (setq replace
2727 (cond
2728 ((equal letter "f")
2729 (file-name-sans-extension
2730 (file-name-nondirectory (buffer-file-name))))
2731 ((equal letter "F")
2732 (let ((masterdir (file-name-directory (reftex-TeX-master-file)))
2733 (file (file-name-sans-extension (buffer-file-name))))
2734 (if (string-match (concat "\\`" (regexp-quote masterdir))
2735 file)
2736 (substring file (length masterdir))
2737 file)))
2738 ((equal letter "u")
2739 (or (user-login-name) ""))
2740 (t "")))
2741 (setq num (1- (+ (match-beginning 1) (length replace)))
2742 prefix (replace-match replace nil nil prefix)))
2743 prefix)))
2744
2745(defun reftex-uniquify-label (label &optional force separator)
2746 ;; Make label unique by appending a number.
2747 ;; Optional FORCE means, force appending a number, even if label is unique.
2748 ;; Optional SEPARATOR is a string to stick between label and number.
2749
2750 ;; Ensure access to scanning info
2751 (reftex-access-scan-info)
2752
2753 (cond
2754 ((and (not force)
2755 (not (assoc label (symbol-value reftex-docstruct-symbol))))
2756 label)
2757 (t
2758 (let* ((label-numbers (assq 'label-numbers
2759 (symbol-value reftex-docstruct-symbol)))
2760 (label-numbers-alist (cdr label-numbers))
2761 (cell (or (assoc label label-numbers-alist)
2762 (car (setcdr label-numbers
2763 (cons (cons label 0)
2764 label-numbers-alist)))))
2765 (num (1+ (cdr cell)))
2766 (sep (or separator "")))
2767 (while (assoc (concat label sep (int-to-string num))
2768 (symbol-value reftex-docstruct-symbol))
2769 (incf num))
2770 (setcdr cell num)
2771 (concat label sep (int-to-string num))))))
2772
2773;;; Referencing labels ------------------------------------------------------
2774
2775;; Help string for the reference label menu
2776(defconst reftex-select-label-prompt
2777 "Select: [n]ext [p]revious [r]escan [ ]context e[x]tern [q]uit RET [?]HELP+more")
2778
2779(defconst reftex-select-label-help
2780 " n / p Go to next/previous label (Cursor motion works as well)
2781 C-c C-n/p Go to next/previous section heading.
2782 b / l Jump back to previous selection / Reuse last referenced label
2783 C-s / C-r Search forward/backward. Use repeated C-s/C-r as in isearch.
2784 g / s Update menu / Switch label type
2785 r / R Reparse document / Reparse entire document
2786 x Switch to label menu of external document (with LaTeX package `xr')
2787 t i c # % Toggle: [i]ncl. file borders, [t]able of contents, [c]ontext
2788 [#] label counters, [%] labels in comments
2789 SPC / f Show full context in other window / Toggle follow mode
2790 v / . Toggle \\ref <-> \\vref / Show insertion point in other window
2791 TAB Enter a label with completion
2792 q / RET Quit without referencing / Accept current label (also on mouse-2)")
2793
2794(defvar reftex-select-label-map nil
2795 "Keymap used for *RefTeX Select* buffer, when selecting a label.
2796This keymap can be used to configure the label selection process which is
2797started with the command \\[reftex-reference].")
2798
2799(defun reftex-select-label-mode ()
2800 "Major mode for selecting a label in a LaTeX document.
2801This buffer was created with RefTeX.
2802It only has a meaningful keymap when you are in the middle of a
2803selection process.
2804To select a label, move the cursor to it and press RET.
2805Press `?' for a summary of important key bindings.
2806
2807During a selection process, these are the local bindings.
2808
2809\\{reftex-select-label-map}"
2810
2811 (interactive)
2812 (kill-all-local-variables)
2813 (make-local-hook 'pre-command-hook)
2814 (make-local-hook 'post-command-hook)
2815 (setq major-mode 'reftex-select-label-mode
2816 mode-name "RefTeX Select Label")
2817 (when (syntax-table-p reftex-latex-syntax-table)
2818 (set-syntax-table reftex-latex-syntax-table))
2819 ;; We do not set a local map - reftex-select-item does this.
2820 (run-hooks 'reftex-select-label-mode-hook))
2821
2822(defun reftex-reference (&optional type no-insert cut)
2823 "Make a LaTeX reference. Look only for labels of a certain TYPE.
2824With prefix arg, force to rescan buffer for labels. This should only be
2825necessary if you have recently entered labels yourself without using
2826reftex-label. Rescanning of the buffer can also be requested from the
2827label selection menu.
2828The function returns the selected label or nil.
2829If NO-INSERT is non-nil, do not insert \\ref command, just return label.
2830When called with 2 C-u prefix args, disable magic word recognition."
2831
2832 (interactive)
2833
2834 ;; check for active recursive edits
2835 (reftex-check-recursive-edit)
a7ec1775
RS
2836
2837 ;; Ensure access to scanning info and rescan buffer if prefix are is '(4)
2838 (reftex-access-scan-info current-prefix-arg)
2839
396e0b08
KH
2840 (unless type
2841 ;; guess type from context
2842 (if (and reftex-guess-label-type
2faef409
RS
2843 (setq type (reftex-guess-label-type)))
2844 (setq cut (cdr type)
2845 type (car type))
396e0b08 2846 (setq type (reftex-query-label-type))))
a7ec1775 2847
2faef409
RS
2848 (let* ((varioref (if (reftex-typekey-check
2849 type reftex-vref-is-default)
2850 "\\vref" "\\ref"))
2851 (form "\\ref{%s}")
2852 label pair)
a7ec1775
RS
2853
2854 ;; Have the user select a label
29d593f8 2855 (set-marker reftex-select-return-marker (point))
2faef409
RS
2856 (setq pair (save-excursion
2857 (reftex-offer-label-menu type)))
b849548d 2858 (reftex-ensure-compiled-variables)
29d593f8 2859 (set-marker reftex-select-return-marker nil)
2faef409
RS
2860 (setq label (car pair)
2861 type (cdr pair)
2862 form (or (cdr (assoc type reftex-typekey-to-format-alist))
2863 form))
a7ec1775
RS
2864
2865 (if (and label
2866 (not no-insert))
2867 (progn
2faef409
RS
2868 (if cut (backward-delete-char cut))
2869
2870 ;; remove ~ if we do already have a space
2871 (when (and (= ?~ (string-to-char form))
a6611c0d 2872 (member (preceding-char) '(?\ ?\t ?\n)))
2faef409
RS
2873 (setq form (substring form 1)))
2874 ;; do we need to switch from \ref to \vref?
2875 (when (string= varioref "\\vref")
2876 (while (string-match "\\\\ref{" form)
2877 (setq form (replace-match "\\vref{" t t form))))
a7ec1775 2878 ;; ok, insert the reference
2faef409
RS
2879 (insert
2880 (if reftex-format-ref-function
2881 (funcall reftex-format-ref-function label form)
2882 (format form label label)))
396e0b08
KH
2883 (message ""))
2884 (message "Quit"))
2885 ;; return the label
2886 label))
a7ec1775 2887
2faef409 2888(defun reftex-guess-label-type ()
b849548d 2889 ;; Examine context to guess what a \ref might want to reference.
2faef409
RS
2890 (let ((words reftex-words-to-typekey-alist)
2891 (case-fold-search t)
2892 (bound (max (point-min) (- (point) 35)))
2893 matched cell)
2894 (save-excursion
2895 (while (and (setq cell (pop words))
2896 (not (setq matched
2897 (re-search-backward (car cell) bound t))))))
2898 (if matched
2899 (cons (cdr cell) (- (match-end 0) (match-end 1)))
2900 nil)))
2901
a7ec1775 2902(defun reftex-offer-label-menu (typekey)
2faef409 2903 ;; Offer a menu with the appropriate labels. Return (label . typekey).
a7ec1775 2904 (let* ((buf (current-buffer))
396e0b08
KH
2905 (xr-data (assq 'xr (symbol-value reftex-docstruct-symbol)))
2906 (xr-alist (cons (cons "" (buffer-file-name)) (nth 1 xr-data)))
2907 (xr-index 0)
2908 (here-I-am (car (reftex-where-am-I)))
2faef409 2909 (here-I-am1 here-I-am)
a7ec1775 2910 (toc (reftex-typekey-check typekey reftex-label-menu-flags 0))
396e0b08 2911 (files (reftex-typekey-check typekey reftex-label-menu-flags 7))
a7ec1775
RS
2912 (context (not (reftex-typekey-check
2913 typekey reftex-label-menu-flags 3)))
2914 (counter (reftex-typekey-check
2915 typekey reftex-label-menu-flags 2))
2916 (follow (reftex-typekey-check
2917 typekey reftex-label-menu-flags 4))
396e0b08 2918 (commented (nth 5 reftex-label-menu-flags))
396e0b08 2919 (prefix "")
2faef409
RS
2920 selection-buffers
2921 offset rtn key data last-data entry)
a7ec1775 2922
a7ec1775
RS
2923 (setq entry (cons nil nil))
2924
2925 (unwind-protect
2926 (catch 'exit
2927 (while t
2928 (save-window-excursion
2faef409 2929 (delete-other-windows)
b849548d
CD
2930 (setq reftex-call-back-to-this-buffer buf
2931 reftex-latex-syntax-table (syntax-table))
29d593f8
KH
2932 (let ((default-major-mode 'reftex-select-label-mode))
2933 (if reftex-use-multiple-selection-buffers
2934 (switch-to-buffer-other-window
2935 (save-excursion
2936 (set-buffer buf)
2937 (reftex-make-selection-buffer-name typekey)))
2938 (switch-to-buffer-other-window "*RefTeX Select*")
2939 (reftex-erase-buffer)))
2940 (unless (eq major-mode 'reftex-select-label-mode)
2941 (reftex-select-label-mode))
2faef409 2942 (add-to-list 'selection-buffers (current-buffer))
a7ec1775 2943 (setq truncate-lines t)
396e0b08
KH
2944 (setq mode-line-format
2945 (list "---- " 'mode-line-buffer-identification
2faef409 2946 " " 'varioref
396e0b08
KH
2947 " " (abbreviate-file-name
2948 (buffer-file-name buf))
2949 " -%-"))
2faef409
RS
2950 (cond
2951 ((= 0 (buffer-size))
29d593f8
KH
2952 (let ((buffer-read-only nil))
2953 (setq offset (reftex-make-and-insert-label-list
2954 typekey buf toc files context counter commented
2955 (or here-I-am offset) prefix))))
2faef409
RS
2956 (here-I-am
2957 (setq offset (reftex-get-offset buf here-I-am typekey)))
2958 (t (setq offset t)))
29d593f8 2959 (setq buffer-read-only t)
2faef409
RS
2960 (setq offset (or offset t))
2961
396e0b08 2962 (setq here-I-am nil) ; turn off determination of offset
a7ec1775
RS
2963 (setq rtn
2964 (reftex-select-item
396e0b08 2965 reftex-select-label-prompt
206c6f82 2966 reftex-select-label-help
2faef409 2967 reftex-select-label-map
a7ec1775 2968 offset
be456a1d 2969 'reftex-select-label-callback follow))
2faef409
RS
2970 (setq key (car rtn)
2971 data (nth 1 rtn)
2972 last-data (nth 2 rtn)
2973 offset t)
396e0b08 2974 (unless key (throw 'exit nil))
a7ec1775 2975 (cond
2faef409
RS
2976 ((eq key ?g)
2977 ;; update buffer
29d593f8 2978 (reftex-erase-buffer))
206c6f82 2979 ((or (eq key ?r)
2faef409 2980 (eq key ?R))
a7ec1775 2981 ;; rescan buffer
29d593f8 2982 (reftex-erase-buffer)
b849548d 2983 (reftex-reparse-document buf last-data key))
206c6f82 2984 ((eq key ?c)
a7ec1775 2985 ;; toggle context mode
29d593f8 2986 (reftex-erase-buffer)
a7ec1775 2987 (setq context (not context)))
206c6f82 2988 ((eq key ?s)
a7ec1775 2989 ;; switch type
2faef409 2990 (setq here-I-am here-I-am1)
a7ec1775 2991 (setq typekey (reftex-query-label-type)))
206c6f82 2992 ((eq key ?t)
2faef409 2993 ;; toggle table of contents display
29d593f8 2994 (reftex-erase-buffer)
a7ec1775 2995 (setq toc (not toc)))
396e0b08
KH
2996 ((eq key ?i)
2997 ;; toggle display of included file borders
29d593f8 2998 (reftex-erase-buffer)
396e0b08 2999 (setq files (not files)))
206c6f82 3000 ((eq key ?#)
a7ec1775 3001 ;; toggle counter display
29d593f8 3002 (reftex-erase-buffer)
a7ec1775 3003 (setq counter (not counter)))
396e0b08
KH
3004 ((eq key ?%)
3005 ;; toggle display of commented labels
29d593f8 3006 (reftex-erase-buffer)
396e0b08 3007 (setq commented (not commented)))
206c6f82 3008 ((eq key ?l)
a7ec1775
RS
3009 ;; reuse the last referenced label again
3010 (setq entry reftex-last-used-reference)
3011 (throw 'exit t))
396e0b08
KH
3012 ((eq key ?x)
3013 ;; select an external document
3014 (setq xr-index (reftex-select-external-document
3015 xr-alist xr-index))
3016 (setq buf (or (reftex-get-file-buffer-force
baec1250 3017 (cdr (nth xr-index xr-alist)))
396e0b08 3018 (error "Cannot switch document"))
2faef409
RS
3019 prefix (or (car (nth xr-index xr-alist)) ""))
3020 (set-buffer buf)
3021 (reftex-access-scan-info))
3022 ((stringp key)
3023 (setq entry
3024 (or (assoc key (symbol-value reftex-docstruct-symbol))
3025 (list key typekey)))
3026 (throw 'exit t))
a7ec1775
RS
3027 (t
3028 (set-buffer buf)
2faef409 3029 (if data
396e0b08 3030 (progn
2faef409 3031 (setq entry data)
396e0b08
KH
3032 (setq reftex-last-used-reference entry))
3033 (setq entry nil))
a7ec1775 3034 (throw 'exit t))))))
b849548d
CD
3035 (save-excursion
3036 (while reftex-buffers-with-changed-invisibility
3037 (set-buffer (car (car reftex-buffers-with-changed-invisibility)))
3038 (setq buffer-invisibility-spec
3039 (cdr (pop reftex-buffers-with-changed-invisibility)))))
2faef409
RS
3040 (mapcar (function (lambda (buf)
3041 (and (buffer-live-p buf)
b849548d 3042 (bury-buffer buf))))
2faef409 3043 selection-buffers)
a7ec1775 3044 (reftex-kill-temporary-buffers))
396e0b08 3045 (cons (if (nth 0 entry) (concat prefix (nth 0 entry)) nil)
2faef409 3046 (nth 1 entry))))
396e0b08 3047
b849548d
CD
3048(defun reftex-select-external-document (xr-alist xr-index)
3049 ;; Return index of an external document.
3050 (let* ((len (length xr-alist)) (highest (1- (+ ?0 len)))
3051 (prompt (format "[%c-%c] Select TAB: Read prefix with completion"
3052 ?0 highest))
3053 key prefix)
3054 (cond
3055 ((= len 1)
3056 (message "No external documents available")
3057 (ding) (sit-for 1) 0)
3058 ((= len 2)
3059 (- 1 xr-index))
3060 (t
3061 (save-excursion
3062 (let* ((length (apply 'max (mapcar
3063 (lambda(x) (length (car x))) xr-alist)))
3064 (fmt (format " [%%c] %%-%ds %%s\n" length))
3065 (n (1- ?0)))
3066 (setq key
3067 (reftex-select-with-char
3068 prompt
3069 (concat
3070 "SELECT EXTERNAL DOCUMENT\n------------------------\n"
3071 (mapconcat
3072 (function
3073 (lambda (x)
3074 (format fmt (incf n) (or (car x) "")
3075 (abbreviate-file-name (cdr x)))))
3076 xr-alist ""))
3077 nil t))
3078 (cond
3079 ((and (>= key ?0) (<= key highest)) (- key ?0))
3080 ((= key ?\C-i)
3081 (setq prefix (completing-read "Prefix: " xr-alist nil t))
3082 (- len (length (memq (assoc prefix xr-alist) xr-alist))))
3083 (t (error "Illegal document selection [%c]" key)))))))))
3084
3085(defun reftex-reparse-document (&optional buffer data key)
3086 ;; Rescan the document.
3087 (save-window-excursion
3088 (save-excursion
3089 (if buffer
3090 (if (not (bufferp buffer))
3091 (error "No such buffer %s" (buffer-name buffer))
3092 (set-buffer buffer)))
3093 (let ((arg (if (eq key ?R) '(16) '(4)))
3094 (file (nth 3 data)))
3095 (reftex-access-scan-info arg file)))))
a7ec1775 3096
b849548d
CD
3097(defun reftex-make-selection-buffer-name (type &optional index)
3098 ;; Make unique name for a selection buffer.
3099 (format " *RefTeX[%s][%d]*"
3100 type (or index (get reftex-docstruct-symbol ':master-index) 0)))
206c6f82 3101
b849548d
CD
3102(defun reftex-get-offset (buf here-am-I typekey)
3103 ;; Find the correct offset data, like make-and-insert would, but faster.
3104 (save-excursion
3105 (set-buffer buf)
3106 (reftex-access-scan-info)
3107 (let* ((rest (memq here-am-I (symbol-value reftex-docstruct-symbol)))
3108 entry)
3109 (while (and (setq entry (pop rest))
3110 (not (and (stringp (car entry))
3111 (equal typekey (nth 1 entry))))))
3112 entry)))
a7ec1775 3113
b849548d
CD
3114(defun reftex-make-and-insert-label-list
3115 (typekey0 buf toc files context counter show-commented here-I-am xr-prefix)
3116 ;; Insert a menu of all labels in buffer BUF into current buffer.
3117 ;; Return the data property of the entry corresponding to HERE-I-AM.
3118 (let* ((font (reftex-use-fonts))
3119 (cnt 0)
3120 (index -1)
3121 (toc-indent " ")
3122 (label-indent
3123 (concat "> "
3124 (if toc (make-string (* 7 reftex-level-indent) ?\ ) "")))
3125 (context-indent
3126 (concat ". "
3127 (if toc (make-string (* 7 reftex-level-indent) ?\ ) "")))
3128 (mouse-face
3129 (if (memq reftex-highlight-selection '(mouse both))
3130 reftex-mouse-selected-face
3131 nil))
3132 (label-face (reftex-verified-face reftex-label-face
3133 'font-lock-constant-face
3134 'font-lock-reference-face))
3135 all cell text label typekey note comment master-dir-re
3136 offset from to docstruct-symbol)
a7ec1775 3137
b849548d 3138 (message "Creating Selection Buffer...")
a7ec1775 3139
b849548d
CD
3140 ;; Pop to buffer buf to get the correct buffer-local variables
3141 (save-excursion
3142 (set-buffer buf)
a7ec1775 3143
b849548d
CD
3144 ;; Ensure access to scanning info
3145 (reftex-access-scan-info)
206c6f82 3146
b849548d
CD
3147 (setq docstruct-symbol reftex-docstruct-symbol
3148 all (symbol-value reftex-docstruct-symbol)
3149 reftex-active-toc nil
3150 master-dir-re
3151 (concat "\\`" (regexp-quote
3152 (file-name-directory (reftex-TeX-master-file))))))
206c6f82 3153
b849548d
CD
3154 (set (make-local-variable 'reftex-docstruct-symbol) docstruct-symbol)
3155 (set (make-local-variable 'reftex-prefix)
3156 (cdr (assoc typekey0 reftex-typekey-to-prefix-alist)))
3157 (if (equal reftex-prefix " ") (setq reftex-prefix nil))
a7ec1775 3158
b849548d
CD
3159 ;; Walk the docstruct and insert the appropriate stuff
3160 (while (setq cell (pop all))
396e0b08 3161
b849548d
CD
3162 (incf index)
3163 (setq from (point))
396e0b08 3164
b849548d 3165 (if (eq cell here-I-am) (setq offset 'attention))
396e0b08 3166
b849548d 3167 (cond
396e0b08 3168
b849548d
CD
3169 ((memq (car cell) '(bib thebib label-numbers appendix
3170 master-dir bibview-cache is-multi xr xr-doc)))
3171 ;; These are currently ignored
396e0b08 3172
b849548d
CD
3173 ((memq (car cell) '(bof eof file-error))
3174 ;; Beginning or end of a file
3175 (when files
3176 (insert
3177 " File " (if (string-match master-dir-re (nth 1 cell))
3178 (substring (nth 1 cell) (match-end 0))
3179 (nth 1 cell))
3180 (cond ((eq (car cell) 'bof) " starts here\n")
3181 ((eq (car cell) 'eof) " ends here\n")
3182 ((eq (car cell) 'file-error) " was not found\n")))
3183 (when font
3184 (put-text-property from (point)
3185 'face reftex-file-boundary-face))))
396e0b08 3186
b849548d
CD
3187 ((eq (car cell) 'toc)
3188 ;; a table of contents entry
3189 (when toc
3190 (setq reftex-active-toc cell)
3191 (insert (concat toc-indent (nth 2 cell) "\n"))
3192 (setq to (point))
3193 (when font
3194 (put-text-property from to
3195 'face reftex-section-heading-face))
3196 (goto-char to)))
396e0b08 3197
b849548d
CD
3198 ((stringp (car cell))
3199 ;; a label
3200 (when (null (nth 2 cell))
3201 ;; No context yet. Quick update.
3202 (setcdr cell (cdr (reftex-label-info-update cell)))
3203 (put docstruct-symbol 'modified t))
396e0b08 3204
b849548d
CD
3205 (setq label (car cell)
3206 typekey (nth 1 cell)
3207 text (nth 2 cell)
3208 comment (nth 4 cell)
3209 note (nth 5 cell))
396e0b08 3210
b849548d
CD
3211 (when (and (or (string= typekey typekey0) (string= typekey0 " "))
3212 (or show-commented (null comment)))
396e0b08 3213
b849548d
CD
3214 ;; Yes we want this one
3215 (incf cnt)
3216 (if (eq offset 'attention) (setq offset cell))
396e0b08 3217
b849548d
CD
3218 (setq label (concat xr-prefix label))
3219 (when comment (setq label (concat "% " label)))
3220 (insert label-indent label)
3221 (when font
3222 (setq to (point))
3223 (put-text-property
3224 (- (point) (length label)) to
3225 'face (if comment
3226 'font-lock-comment-face
3227 label-face))
3228 (goto-char to))
206c6f82 3229
b849548d
CD
3230 (insert (if counter (format " (%d) " cnt) "")
3231 (if comment " LABEL IS COMMENTED OUT " "")
3232 (if (stringp note) (concat " " note) "")
3233 "\n")
3234 (setq to (point))
a7ec1775 3235
b849548d
CD
3236 (when context
3237 (insert context-indent text "\n")
3238 (setq to (point)))
3239 (put-text-property from to ':data cell)
3240 (when mouse-face
3241 (put-text-property from (1- to)
3242 'mouse-face mouse-face))
3243 (goto-char to)))))
206c6f82 3244
b849548d
CD
3245 (when (reftex-refontify)
3246 (reftex-fontify-select-label-buffer buf))
3247 (run-hooks 'reftex-display-copied-context-hook)
3248 offset))
3249
3250(defun reftex-query-label-type ()
3251 ;; Ask for label type
3252 (let ((key (reftex-select-with-char
3253 reftex-type-query-prompt reftex-type-query-help 3)))
3254 (unless (member (char-to-string key) reftex-typekey-list)
3255 (error "No such label type: %s" (char-to-string key)))
3256 (char-to-string key)))
a7ec1775 3257
2faef409 3258(defun reftex-select-label-callback (data forward no-revisit)
a7ec1775
RS
3259 ;; Callback function called from the label selection in order to
3260 ;; show context in another window
3261 (let* ((this-window (selected-window))
2faef409 3262 label file buffer re found)
a7ec1775
RS
3263 ;; pop to original buffer in order to get correct variables
3264 (catch 'exit
2faef409
RS
3265 (setq label (nth 0 data)
3266 file (nth 3 data))
a7ec1775 3267
b849548d
CD
3268 ;; goto the file in another window
3269 (setq buffer
3270 (if no-revisit
3271 (reftex-get-buffer-visiting file)
3272 (reftex-get-file-buffer-force
3273 file (not reftex-keep-temporary-buffers))))
3274 (if buffer
3275 ;; good - the file is available
3276 (switch-to-buffer-other-window buffer)
3277 ;; we have got a problem here. The file does not exist.
3278 ;; Let' get out of here..
3279 ;; (ding)
3280 (message reftex-no-follow-message)
3281 (throw 'exit nil))
396e0b08 3282
b849548d
CD
3283 ;; search for that label
3284 (setq re (format reftex-find-label-regexp-format (regexp-quote label)))
3285 (setq found
3286 (if forward
3287 (re-search-forward re nil t)
3288 (re-search-backward re nil t)))
3289 (unless found
3290 (goto-char (point-min))
3291 (unless (re-search-forward re nil t)
3292 ;; Ooops. Must be in a macro with distributed args.
3293 (re-search-forward (format reftex-find-label-regexp-format2
3294 (regexp-quote label)) nil t)))
3295 (when (match-end 3)
3296 (setq reftex-latex-syntax-table (syntax-table))
3297 (reftex-highlight 0 (match-beginning 3) (match-end 3))
3298 (reftex-show-entry (match-beginning 3) (match-end 3))
a6611c0d 3299 (recenter '(4)))
b849548d 3300 (select-window this-window))))
a7ec1775 3301
b849548d
CD
3302(defun reftex-pop-to-label (label file-list &optional mark-to-kill highlight)
3303 ;; Find LABEL in any file in FILE-LIST in another window.
3304 ;; If mark-to-kill is non-nil, mark new buffer for killing.
3305 ;; If HIGHLIGHT is non-nil, highlight the label definition.
3306 (let* ((re1 (format reftex-find-label-regexp-format (regexp-quote label)))
3307 (re2 (format reftex-find-label-regexp-format2 (regexp-quote label)))
3308 (re-list (list re1 re2)) re
3309 (file-list-1 file-list)
3310 file buf)
3311 (catch 'exit
3312 (while (setq re (pop re-list))
3313 (setq file-list file-list-1)
3314 (while (setq file (pop file-list))
3315 (unless (setq buf (reftex-get-file-buffer-force file mark-to-kill))
3316 (error "No such file %s" file))
3317 (set-buffer buf)
3318 (widen)
3319 (goto-char (point-min))
3320 (when (re-search-forward re nil t)
3321 (switch-to-buffer-other-window buf)
3322 (goto-char (match-beginning 0))
a6611c0d 3323 (recenter '(4))
b849548d
CD
3324 (if highlight
3325 (reftex-highlight 0 (match-beginning 3) (match-end 3)))
3326 (throw 'exit (selected-window)))))
3327 (error "Label %s not found" label))))
396e0b08
KH
3328
3329(defun reftex-show-entry (beg-hlt end-hlt)
b849548d
CD
3330 ;; Show entry if point is hidden
3331 (let* ((n (/ (window-height) 2))
396e0b08
KH
3332 (beg (save-excursion
3333 (re-search-backward "[\n\r]" nil 1 n) (point)))
3334 (end (save-excursion
3335 (re-search-forward "[\n\r]" nil 1 n) (point))))
b849548d
CD
3336 (cond
3337 ((and (boundp 'buffer-invisibility-spec) buffer-invisibility-spec
3338 (get-char-property (1+ beg-hlt) 'invisible))
3339 ;; Invisible with text properties. That is easy to change.
3340 (push (cons (current-buffer) buffer-invisibility-spec)
3341 reftex-buffers-with-changed-invisibility)
3342 (setq buffer-invisibility-spec nil))
3343 ((string-match "\r" (buffer-substring beg end))
3344 ;; Invisible with selective display. We need to copy it.
3345 (let ((string (buffer-substring-no-properties beg end)))
3346 (switch-to-buffer "*RefTeX Context Copy*")
3347 (setq buffer-read-only nil)
3348 (erase-buffer)
3349 (insert string)
3350 (subst-char-in-region (point-min) (point-max) ?\r ?\n t)
3351 (goto-char (- beg-hlt beg))
3352 (reftex-highlight 0 (1+ (- beg-hlt beg)) (1+ (- end-hlt beg)))
3353 (if (reftex-refontify)
3354 (when (or (not (eq major-mode 'latex-mode))
3355 (not font-lock-mode))
3356 (latex-mode)
3357 (run-hook-with-args
3358 'reftex-pre-refontification-functions
3359 reftex-call-back-to-this-buffer 'reftex-hidden)
3360 (turn-on-font-lock))
3361 (when (or (not (eq major-mode 'fundamental-mode))
3362 font-lock-mode)
3363 (fundamental-mode)))
3364 (run-hooks 'reftex-display-copied-context-hook)
3365 (setq buffer-read-only t))))))
3366
3367;;; =========================================================================
a7ec1775 3368;;;
396e0b08 3369;;; Table of contents
a7ec1775
RS
3370
3371;; We keep at most one *toc* buffer - it is easy to make them
3372
2faef409
RS
3373(defvar reftex-toc-map (make-sparse-keymap)
3374 "Keymap used for *toc* buffer.")
3375
29d593f8
KH
3376(defun reftex-toc-mode ()
3377 "Major mode for managing Table of Contents for LaTeX files.
3378This buffer was created with RefTeX.
3379Press `?' for a summary of important key bindings.
3380
3381Here are all local bindings.
3382
3383\\{reftex-toc-map}"
3384 (interactive)
3385 (kill-all-local-variables)
3386 (setq major-mode 'reftex-toc-mode
3387 mode-name "RefTeX Table of Contents")
3388 (use-local-map reftex-toc-map)
3389 (set (make-local-variable 'revert-buffer-function) 'reftex-toc-revert)
3390 (setq truncate-lines t)
3391 (make-local-hook 'post-command-hook)
3392 (make-local-hook 'pre-command-hook)
3393 (make-local-variable 'reftex-last-follow-point)
3394 (add-hook 'post-command-hook 'reftex-toc-post-command-hook nil t)
3395 (add-hook 'pre-command-hook 'reftex-toc-pre-command-hook nil t)
3396 (run-hooks 'reftex-toc-mode-hook))
3397
a7ec1775
RS
3398(defvar reftex-last-toc-master nil
3399 "Stores the name of the tex file that `reftex-toc' was last run on.")
3400
3401(defvar reftex-last-toc-file nil
c52bdfca 3402 "Stores the file name from which `reftex-toc' was called. For redo command.")
a7ec1775 3403
206c6f82
RS
3404(defvar reftex-last-window-height nil)
3405
a7ec1775
RS
3406(defvar reftex-toc-return-marker (make-marker)
3407 "Marker which makes it possible to return from toc to old position.")
3408
206c6f82
RS
3409(defconst reftex-toc-help
3410" AVAILABLE KEYS IN TOC BUFFER
3411 ============================
2faef409 3412n / p next-line / previous-line
206c6f82
RS
3413SPC Show the corresponding section of the LaTeX document.
3414TAB Goto the section.
3415RET Goto the section and hide the *toc* buffer (also on mouse-2).
3416q / Q Hide/Kill *toc* buffer, return to position of last reftex-toc command.
2faef409
RS
3417f / g Toggle follow mode on and off / Refresh *toc* buffer.
3418r / R Reparse the LaTeX document / Reparse entire LaTeX document.
b849548d 3419. In other window, show position from where `reftex-toc' was called.
396e0b08 3420x Switch to TOC of external document (with LaTeX package `xr').")
206c6f82 3421
a7ec1775
RS
3422(defun reftex-toc ()
3423 "Show the table of contents for the current document.
a7ec1775
RS
3424When called with a raw C-u prefix, rescan the document first."
3425
3426 (interactive)
3427
206c6f82 3428 (if (or (not (string= reftex-last-toc-master (reftex-TeX-master-file)))
396e0b08 3429 current-prefix-arg)
29d593f8 3430 (reftex-erase-buffer "*toc*"))
a7ec1775
RS
3431
3432 (setq reftex-last-toc-file (buffer-file-name))
3433 (setq reftex-last-toc-master (reftex-TeX-master-file))
3434
3435 (set-marker reftex-toc-return-marker (point))
3436
206c6f82 3437 ;; If follow mode is active, arrange to delay it one command
a7ec1775
RS
3438 (if reftex-toc-follow-mode
3439 (setq reftex-toc-follow-mode 1))
3440
a7ec1775
RS
3441 ;; Ensure access to scanning info and rescan buffer if prefix are is '(4)
3442 (reftex-access-scan-info current-prefix-arg)
3443
396e0b08
KH
3444 (let* ((all (symbol-value reftex-docstruct-symbol))
3445 (xr-data (assq 'xr all))
3446 (xr-alist (cons (cons "" (buffer-file-name)) (nth 1 xr-data)))
a7ec1775 3447 (where (reftex-nearest-section))
6b94c6ad
CD
3448 (mouse-face
3449 (if (memq reftex-highlight-selection '(mouse both))
3450 reftex-mouse-selected-face
3451 nil))
b849548d 3452 (fontify (reftex-use-fonts))
29d593f8 3453 toc1 cell startpos)
a7ec1775 3454
206c6f82
RS
3455 (if (get-buffer-window "*toc*")
3456 (select-window (get-buffer-window "*toc*"))
2faef409
RS
3457 (when (< (window-height) (* 2 window-min-height))
3458 (delete-other-windows))
206c6f82 3459 (setq reftex-last-window-height (window-height)) ; remember
2faef409 3460 (split-window)
29d593f8
KH
3461 (let ((default-major-mode 'reftex-toc-mode))
3462 (switch-to-buffer "*toc*")))
3463
3464 (or (eq major-mode 'reftex-toc-mode) (reftex-toc-mode))
a7ec1775
RS
3465
3466 (cond
3467 ;; buffer is empty - fill it with the table of contents
3468 ((= (buffer-size) 0)
2faef409 3469 (message "Building *toc* buffer...")
a7ec1775 3470
29d593f8 3471 (setq buffer-read-only nil)
a7ec1775
RS
3472 (insert (format
3473"TABLE-OF-CONTENTS on %s
396e0b08 3474SPC=view TAB=goto RET=goto+hide [q]uit [r]escan [f]ollow-mode e[x]tern [?]Help
a7ec1775
RS
3475-------------------------------------------------------------------------------
3476" (abbreviate-file-name reftex-last-toc-master)))
3477 (setq startpos (point))
3478
3479 (if (reftex-use-fonts)
6b94c6ad 3480 (put-text-property 1 (point) 'face reftex-toc-header-face))
a7ec1775 3481 (put-text-property 1 (point) 'intangible t)
396e0b08 3482 (put-text-property 1 2 'xr-alist xr-alist)
a7ec1775
RS
3483
3484 (while all
3485 (setq cell (car all)
3486 all (cdr all))
396e0b08
KH
3487 (when (eq (car cell) 'toc)
3488 (setq toc1 (concat (nth 2 cell) "\n"))
3489 (put-text-property 0 (length toc1) 'toc cell toc1)
b849548d
CD
3490 (when fontify
3491 (put-text-property 0 (length toc1)
3492 'face reftex-section-heading-face toc1))
29d593f8
KH
3493 (when mouse-face
3494 (put-text-property 0 (1- (length toc1))
3495 'mouse-face mouse-face toc1))
396e0b08 3496 (insert toc1)))
a7ec1775
RS
3497
3498 (backward-delete-char 1)
3499
b849548d 3500 (run-hooks 'reftex-display-copied-context-hook)
2faef409 3501 (message "Building *toc* buffer...done.")
a7ec1775
RS
3502 (setq buffer-read-only t))
3503 (t
3504 (goto-line 3)
3505 (beginning-of-line)
3506 (setq startpos (point))))
3507
3508 ;; Find the correct section
3509 (goto-char (point-max))
3510 (beginning-of-line)
3511 (while (and (> (point) startpos)
396e0b08 3512 (not (eq (get-text-property (point) 'toc) where)))
29d593f8
KH
3513 (beginning-of-line 0))
3514 (setq reftex-last-follow-point (point))))
a7ec1775
RS
3515
3516(defun reftex-nearest-section ()
3517 ;; Return (file . find) of nearest section command
396e0b08
KH
3518 (let* ((here-I-am (car (reftex-where-am-I))))
3519 (reftex-last-assoc-before-elt
3520 'toc here-I-am (symbol-value reftex-docstruct-symbol))))
a7ec1775
RS
3521
3522(defun reftex-toc-pre-command-hook ()
3523 ;; used as pre command hook in *toc* buffer
3524 (reftex-unhighlight 0)
3525 (reftex-unhighlight 1))
3526
3527(defun reftex-toc-post-command-hook ()
3528 ;; used in the post-command-hook for the *toc* buffer
3529 (and (> (point) 1)
29d593f8 3530 (memq reftex-highlight-selection '(cursor both))
a7ec1775 3531 (save-excursion
396e0b08
KH
3532 (reftex-highlight 1
3533 (progn (beginning-of-line) (point))
3534 (progn (end-of-line) (point)))))
a7ec1775
RS
3535 (cond
3536 ((integerp reftex-toc-follow-mode)
3537 ;; remove delayed action
3538 (setq reftex-toc-follow-mode t))
29d593f8
KH
3539 ((and reftex-toc-follow-mode
3540 (not (equal reftex-last-follow-point (point))))
a7ec1775 3541 ;; show context in other window
29d593f8 3542 (setq reftex-last-follow-point (point))
a7ec1775 3543 (condition-case nil
2faef409
RS
3544 (reftex-toc-visit-line nil (not reftex-revisit-to-follow))
3545 (error t)))))
206c6f82 3546
206c6f82 3547(defun reftex-re-enlarge ()
b849548d 3548 ;; Enlarge windiw to a remembered size
396e0b08
KH
3549 (enlarge-window
3550 (max 0 (- (or reftex-last-window-height (window-height))
3551 (window-height)))))
206c6f82
RS
3552
3553(defun reftex-toc-show-help ()
b849548d 3554 "Show a summary of special key bindings."
206c6f82
RS
3555 (interactive)
3556 (with-output-to-temp-buffer "*RefTeX Help*"
3557 (princ reftex-toc-help))
3558 ;; If follow mode is active, arrange to delay it one command
3559 (if reftex-toc-follow-mode
3560 (setq reftex-toc-follow-mode 1)))
a7ec1775
RS
3561
3562(defun reftex-toc-toggle-follow ()
b849548d 3563 "Toggle toc-follow mode. (It is not really a mode, just a flag)."
a7ec1775 3564 (interactive)
b849548d 3565 (setq reftex-last-follow-point -1)
a7ec1775
RS
3566 (setq reftex-toc-follow-mode (not reftex-toc-follow-mode)))
3567(defun reftex-toc-view-line ()
3568 "View document location in other window."
3569 (interactive)
3570 (reftex-toc-visit-line))
29d593f8
KH
3571(defun reftex-toc-mouse-view-line (ev)
3572 "View document location in other window."
3573 (interactive "e")
3574 (mouse-set-point ev)
3575 (reftex-toc-visit-line))
a7ec1775 3576(defun reftex-toc-goto-line-and-hide ()
c52bdfca 3577 "Go to document location in other window. Hide the *toc* window."
a7ec1775
RS
3578 (interactive)
3579 (reftex-toc-visit-line 'hide))
206c6f82
RS
3580(defun reftex-toc-goto-line ()
3581 "Go to document location in other window. Hide the *toc* window."
3582 (interactive)
3583 (reftex-toc-visit-line t))
3584(defun reftex-toc-mouse-goto-line-and-hide (ev)
3585 "Go to document location in other window. Hide the *toc* window."
3586 (interactive "e")
3587 (mouse-set-point ev)
3588 (reftex-toc-visit-line 'hide))
b849548d
CD
3589(defun reftex-toc-show-insertion-point ()
3590 (interactive)
3591 (let ((this-window (selected-window)))
3592 (unwind-protect
3593 (progn
3594 (switch-to-buffer-other-window
3595 (marker-buffer reftex-toc-return-marker))
3596 (goto-char (marker-position reftex-toc-return-marker))
a6611c0d 3597 (recenter '(4)))
b849548d 3598 (select-window this-window))))
a7ec1775
RS
3599(defun reftex-toc-quit ()
3600 "Hide the *toc* window and do not move point."
3601 (interactive)
206c6f82 3602 (or (one-window-p) (delete-window))
a7ec1775 3603 (switch-to-buffer (marker-buffer reftex-toc-return-marker))
206c6f82 3604 (reftex-re-enlarge)
396e0b08 3605 (goto-char (or (marker-position reftex-toc-return-marker) (point))))
a7ec1775
RS
3606(defun reftex-toc-quit-and-kill ()
3607 "Kill the *toc* buffer."
3608 (interactive)
3609 (kill-buffer "*toc*")
206c6f82 3610 (or (one-window-p) (delete-window))
a7ec1775 3611 (switch-to-buffer (marker-buffer reftex-toc-return-marker))
206c6f82 3612 (reftex-re-enlarge)
a7ec1775 3613 (goto-char (marker-position reftex-toc-return-marker)))
2faef409
RS
3614(defun reftex-toc-rescan (&rest ignore)
3615 "Regenerate the *toc* buffer by reparsing file of section at point."
396e0b08
KH
3616 (interactive)
3617 (if reftex-enable-partial-scans
3618 (let ((file (nth 3 (get-text-property (point) 'toc))))
3619 (if (not file)
a6611c0d 3620 (error "Don't know which file to rescan. Try `R'")
396e0b08
KH
3621 (switch-to-buffer-other-window
3622 (reftex-get-file-buffer-force file))
3623 (setq current-prefix-arg '(4))
3624 (reftex-toc)))
2faef409 3625 (reftex-toc-Rescan))
396e0b08 3626 (reftex-kill-temporary-buffers))
2faef409 3627(defun reftex-toc-Rescan (&rest ignore)
396e0b08 3628 "Regenerate the *toc* buffer by reparsing the entire document."
a7ec1775 3629 (interactive)
206c6f82
RS
3630 (switch-to-buffer-other-window
3631 (reftex-get-file-buffer-force reftex-last-toc-file))
396e0b08 3632 (setq current-prefix-arg '(16))
a7ec1775 3633 (reftex-toc))
2faef409
RS
3634(defun reftex-toc-revert (&rest ignore)
3635 "Regenerate the *toc* from the internal lists."
3636 (interactive)
3637 (switch-to-buffer-other-window
3638 (reftex-get-file-buffer-force reftex-last-toc-file))
29d593f8 3639 (reftex-erase-buffer "*toc*")
2faef409
RS
3640 (setq current-prefix-arg nil)
3641 (reftex-toc))
396e0b08
KH
3642(defun reftex-toc-external (&rest ignore)
3643 "Switch to table of contents of an external document."
3644 (interactive)
2faef409
RS
3645 (let* ((old-buf (current-buffer))
3646 (xr-alist (get-text-property 1 'xr-alist))
396e0b08
KH
3647 (xr-index (reftex-select-external-document
3648 xr-alist 0)))
3649 (switch-to-buffer-other-window (or (reftex-get-file-buffer-force
3650 (cdr (nth xr-index xr-alist)))
3651 (error "Cannot switch document")))
2faef409
RS
3652 (reftex-toc)
3653 (if (equal old-buf (current-buffer))
3654 (message "")
3655 (message "Switched document"))))
a7ec1775 3656
2faef409 3657(defun reftex-toc-visit-line (&optional final no-revisit)
a7ec1775
RS
3658 ;; Visit the tex file corresponding to the toc entry on the current line.
3659 ;; If FINAL is t, stay there
3660 ;; If FINAL is 'hide, hide the *toc* window.
396e0b08
KH
3661 ;; Otherwise, move cursor back into *toc* window.
3662 ;; This function is pretty clever about finding back a section heading,
3663 ;; even if the buffer is not live, or things like outline, x-symbol etc.
3664 ;; have been active.
3665
3666 (let* ((toc (get-text-property (point) 'toc))
3667 (file (nth 3 toc))
3668 (marker (nth 4 toc))
3669 (level (nth 5 toc))
3670 (literal (nth 7 toc))
3671 (emergency-point (nth 8 toc))
3672 (toc-window (selected-window))
3673 show-window show-buffer match)
3674
3675 (unless toc (error "Don't know which toc line to visit"))
3676
3677 (setq match
3678 (cond
3679 ((and (markerp marker) (marker-buffer marker))
3680 ;; Buffer is still live and we have the marker. Should be easy.
3681 (switch-to-buffer-other-window (marker-buffer marker))
3682 (goto-char (marker-position marker))
3683 (or (looking-at (regexp-quote literal))
3684 (looking-at (reftex-make-regexp-allow-for-ctrl-m literal))
2faef409 3685 (looking-at (reftex-make-desperate-section-regexp literal))
396e0b08
KH
3686 (looking-at (concat "\\\\"
3687 (regexp-quote
b849548d
CD
3688 (car (rassq level
3689 reftex-section-levels-all)))
396e0b08 3690 "[[{]"))))
2faef409 3691 ((or (not no-revisit)
b849548d 3692 (reftex-get-buffer-visiting file))
396e0b08
KH
3693 ;; Marker is lost. Use the backup method.
3694 (switch-to-buffer-other-window
3695 (reftex-get-file-buffer-force file nil))
3696 (goto-char (or emergency-point (point-min)))
3697 (or (looking-at (regexp-quote literal))
3698 (let ((pos (point)))
3699 (re-search-backward "\\`\\|[\r\n][ \t]*[\r\n]" nil t)
3700 (or (reftex-nearest-match (regexp-quote literal) pos)
3701 (reftex-nearest-match
3702 (reftex-make-regexp-allow-for-ctrl-m literal) pos)
3703 (reftex-nearest-match
2faef409 3704 (reftex-make-desperate-section-regexp literal) pos)))))
b849548d 3705 (t (message reftex-no-follow-message) nil)
396e0b08
KH
3706 ))
3707
3708 (setq show-window (selected-window)
3709 show-buffer (current-buffer))
3710
3711 (unless match
3712 (select-window toc-window)
3713 (error "Cannot find line"))
3714
3715 (goto-char (match-beginning 0))
a7ec1775 3716 (recenter 1)
396e0b08 3717 (reftex-highlight 0 (match-beginning 0) (match-end 0) (current-buffer))
a7ec1775
RS
3718
3719 (select-window toc-window)
3720
3721 ;; use the `final' parameter to decide what to do next
3722 (cond
206c6f82 3723 ((eq final t)
a7ec1775
RS
3724 (reftex-unhighlight 0)
3725 (select-window show-window))
3726 ((eq final 'hide)
3727 (reftex-unhighlight 0)
206c6f82
RS
3728 (or (one-window-p) (delete-window))
3729 (switch-to-buffer show-buffer)
3730 (reftex-re-enlarge))
a7ec1775
RS
3731 (t nil))))
3732
b849548d
CD
3733(defun reftex-make-desperate-section-regexp (old)
3734 ;; Return a regexp which will still match a section statement even if
3735 ;; x-symbol or isotex or the like have been at work in the mean time.
3736 (let* ((n (1+ (string-match "[[{]" old)))
3737 (new (regexp-quote (substring old 0 (1+ (string-match "[[{]" old)))))
3738 (old (substring old n)))
3739 (while (string-match
3740 "\\([\r\n]\\)\\|\\(\\`\\|[ \t\n\r]\\)\\([a-zA-Z0-9]+\\)\\([ \t\n\r]\\|}\\'\\)"
3741 old)
3742 (if (match-beginning 1)
3743 (setq new (concat new "[^\n\r]*[\n\r]"))
3744 (setq new (concat new "[^\n\r]*" (match-string 3 old))))
3745 (setq old (substring old (match-end 0))))
3746 new))
3747
3748;;; =========================================================================
a7ec1775
RS
3749;;;
3750;;; BibTeX citations.
3751
3752;; Variables and constants
3753
a7ec1775
RS
3754;; The history list of regular expressions used for citations
3755(defvar reftex-cite-regexp-hist nil)
3756
206c6f82
RS
3757;; Prompt and help string for citation selection
3758(defconst reftex-citation-prompt
3759 "Select: [n]ext [p]revious [r]estrict [ ]full_entry [q]uit RET [?]Help+more")
3760
a7ec1775 3761(defconst reftex-citation-help
2faef409 3762 " n / p Go to next/previous entry (Cursor motion works as well).
206c6f82 3763 C-s / C-r Search forward/backward. Use repeated C-s/C-r as in isearch.
2faef409 3764 g / r Start over with new regexp / Refine with additional regexp.
206c6f82
RS
3765 SPC Show full database entry in other window.
3766 f Toggle follow mode: Other window will follow with full db entry.
29d593f8 3767 . Show insertion point.
206c6f82 3768 q Quit without inserting \\cite macro into buffer.
2faef409 3769 TAB Enter citation key with completion.
29d593f8 3770 RET Accept current entry (also on mouse-2)
b849548d 3771 a / A Put all entries into single \cite / into many cite commands.")
a7ec1775 3772
2faef409
RS
3773(defvar reftex-select-bib-map nil
3774 "Keymap used for *RefTeX Select* buffer, when selecting a BibTeX entry.
3775This keymap can be used to configure the BibTeX selection process which is
3776started with the command \\[reftex-citation].")
3777
29d593f8
KH
3778(defun reftex-select-bib-mode ()
3779 "Major mode for selecting a citation key in a LaTeX document.
3780This buffer was created with RefTeX.
3781It only has a meaningful keymap when you are in the middle of a
3782selection process.
3783In order to select a citation, move the cursor to it and press RET.
3784Press `?' for a summary of important key bindings.
3785
3786During a selection process, these are the local bindings.
3787
3788\\{reftex-select-label-map}"
3789 (interactive)
3790 (kill-all-local-variables)
3791 (make-local-hook 'pre-command-hook)
3792 (make-local-hook 'post-command-hook)
3793 (setq major-mode 'reftex-select-bib-mode
3794 mode-name "RefTeX Select Bib")
3795 ;; We do not set a local map - reftex-select-item does this.
3796 (run-hooks 'reftex-select-bib-mode-hook))
3797
a7ec1775
RS
3798;; Find bibtex files
3799
3800(defun reftex-get-bibfile-list ()
396e0b08
KH
3801 ;; Return list of bibfiles for current document.
3802 ;; When using the chapterbib or bibunits package you should either
3803 ;; use the same database files everywhere, or separate parts using
3804 ;; different databases into different files (included into the mater file).
3805 ;; Then this function will return the applicable database files.
a7ec1775
RS
3806
3807 ;; Ensure access to scanning info
3808 (reftex-access-scan-info)
396e0b08
KH
3809 (or
3810 ;; Try inside this file (and its includes)
3811 (cdr (reftex-last-assoc-before-elt
3812 'bib (list 'eof (buffer-file-name))
3813 (member (list 'bof (buffer-file-name))
3814 (symbol-value reftex-docstruct-symbol))))
3815 ;; Try after the beginning of this file
3816 (cdr (assq 'bib (member (list 'bof (buffer-file-name))
3817 (symbol-value reftex-docstruct-symbol))))
3818 ;; Anywhere in the entire document
3819 (cdr (assq 'bib (symbol-value reftex-docstruct-symbol)))
2faef409 3820 (error "\\bibliography statement missing or .bib files not found.")))
396e0b08 3821
a7ec1775
RS
3822;; Find a certain reference in any of the BibTeX files.
3823
b849548d
CD
3824(defun reftex-pop-to-bibtex-entry (key file-list &optional mark-to-kill
3825 highlight item return)
a7ec1775 3826 ;; Find BibTeX KEY in any file in FILE-LIST in another window.
2faef409
RS
3827 ;; If MARK-TO-KILL is non-nil, mark new buffer to kill.
3828 ;; If HIGHLIGHT is non-nil, highlight the match.
3829 ;; If ITEM in non-nil, search for bibitem instead of database entry.
a6611c0d 3830 ;; If RETURN is non-nil, just return the entry.
2faef409
RS
3831
3832 (let* ((re
3833 (if item
3834 (concat "\\\\bibitem\\(\\[[^]]*\\]\\)?{" (regexp-quote key) "}")
b849548d
CD
3835 (concat "@[a-zA-Z]+[ \t\n\r]*[{(][ \t\n\r]*" (regexp-quote key)
3836 "[, \t\r\n}]")))
a7ec1775
RS
3837 (window-conf (current-window-configuration))
3838 file buf)
2faef409 3839
a7ec1775
RS
3840 (catch 'exit
3841 (switch-to-buffer-other-window (current-buffer))
3842 (while file-list
3843 (setq file (car file-list)
3844 file-list (cdr file-list))
396e0b08
KH
3845 (unless (setq buf (reftex-get-file-buffer-force file mark-to-kill))
3846 (error "No such file %s" file))
a7ec1775
RS
3847 (switch-to-buffer buf)
3848 (widen)
396e0b08
KH
3849 (goto-char (point-min))
3850 (when (re-search-forward re nil t)
3851 (goto-char (match-beginning 0))
b849548d
CD
3852 (when return
3853 ;; Just return the relevant entry
a6611c0d
CD
3854 (if item (goto-char (match-end 0)))
3855 (setq return (buffer-substring
3856 (point) (reftex-end-of-bib-entry item)))
b849548d
CD
3857 (set-window-configuration window-conf)
3858 (throw 'exit return))
396e0b08
KH
3859 (recenter 0)
3860 (if highlight
3861 (reftex-highlight 0 (match-beginning 0) (match-end 0)))
3862 (throw 'exit (selected-window))))
a7ec1775 3863 (set-window-configuration window-conf)
2faef409 3864 (if item
b849548d
CD
3865 (error "No \\bibitem with citation key %s" key)
3866 (error "No BibTeX entry with citation key %s" key)))))
a7ec1775 3867
a6611c0d
CD
3868(defun reftex-end-of-bib-entry (item)
3869 (save-excursion
3870 (condition-case nil
3871 (if item
3872 (progn (end-of-line)
3873 (re-search-forward
3874 "\\\\bibitem\\|\\end{thebibliography}")
3875 (1- (match-beginning 0)))
3876 (progn (forward-list 1) (point)))
3877 (error (min (point-max) (+ 300 (point)))))))
3878
a7ec1775
RS
3879;; Parse bibtex buffers
3880
b849548d 3881(defun reftex-extract-bib-entries (buffers)
a7ec1775
RS
3882 ;; Extract bib entries which match regexps from BUFFERS.
3883 ;; BUFFERS is a list of buffers or file names.
3884 ;; Return list with entries."
3885 (let* (re-list first-re rest-re
a7ec1775
RS
3886 (buffer-list (if (listp buffers) buffers (list buffers)))
3887 found-list entry buffer1 buffer alist
3888 key-point start-point end-point)
3889
b849548d
CD
3890 ;; Read a regexp, completing on known citation keys.
3891 (setq re-list
3892 (split-string
3893 (completing-read
3894 "RegExp [ && RegExp...]: "
3895 (if (fboundp 'LaTeX-bibitem-list)
3896 (LaTeX-bibitem-list)
3897 (cdr (assoc 'bibview-cache
3898 (symbol-value reftex-docstruct-symbol))))
3899 nil nil nil 'reftex-cite-regexp-hist)
3900 "[ \t]*&&[ \t]*"))
a7ec1775
RS
3901
3902 (setq first-re (car re-list) ; We'll use the first re to find things,
2faef409 3903 rest-re (cdr re-list)) ; the others to narrow down.
a7ec1775
RS
3904 (if (string-match "\\`[ \t]*\\'" first-re)
3905 (error "Empty regular expression"))
3906
3907 (save-excursion
3908 (save-window-excursion
3909
396e0b08 3910 ;; Walk through all bibtex files
a7ec1775
RS
3911 (while buffer-list
3912 (setq buffer (car buffer-list)
3913 buffer-list (cdr buffer-list))
3914 (if (and (bufferp buffer)
3915 (buffer-live-p buffer))
3916 (setq buffer1 buffer)
3917 (setq buffer1 (reftex-get-file-buffer-force
3918 buffer (not reftex-keep-temporary-buffers))))
3919 (if (not buffer1)
3920 (error "Cannot find BibTeX file %s" buffer)
3921 (message "Scanning bibliography database %s" buffer1))
3922
3923 (set-buffer buffer1)
396e0b08
KH
3924 (save-excursion
3925 (goto-char (point-min))
3926 (while (re-search-forward first-re nil t)
3927 (catch 'search-again
3928 (setq key-point (point))
3929 (unless (re-search-backward
3930 "\\(\\`\\|[\n\r]\\)[ \t]*@\\([a-zA-Z]+\\)[ \t\n\r]*[{(]" nil t)
3931 (throw 'search-again nil))
3932 (setq start-point (point))
3933 (goto-char (match-end 0))
3934 (condition-case nil
3935 (up-list 1)
3936 (error (goto-char key-point)
3937 (throw 'search-again nil)))
3938 (setq end-point (point))
3939
3940 ;; Ignore @string, @comment and @c entries or things
3941 ;; outside entries
3942 (when (or (string= (downcase (match-string 2)) "string")
3943 (string= (downcase (match-string 2)) "comment")
3944 (string= (downcase (match-string 2)) "c")
3945 (< (point) key-point)) ; this means match not in {}
3946 (goto-char key-point)
3947 (throw 'search-again nil))
3948
3949 ;; Well, we have got a match
3950 (setq entry (concat
3951 (buffer-substring start-point (point)) "\n"))
3952
3953 ;; Check if other regexp match as well
3954 (setq re-list rest-re)
3955 (while re-list
3956 (unless (string-match (car re-list) entry)
3957 ;; nope - move on
3958 (throw 'search-again nil))
3959 (pop re-list))
3960
3961 (setq alist (reftex-parse-bibtex-entry
3962 nil start-point end-point))
3963 (push (cons "&entry" entry) alist)
3964
3965 ;; check for crossref entries
3966 (if (assoc "crossref" alist)
3967 (setq alist
3968 (append
3969 alist (reftex-get-crossref-alist alist))))
3970
3971 ;; format the entry
3972 (push (cons "&formatted" (reftex-format-bib-entry alist))
3973 alist)
3974
b849548d
CD
3975 ;; make key the first element
3976 (push (reftex-get-bib-field "&key" alist) alist)
3977
396e0b08
KH
3978 ;; add it to the list
3979 (push alist found-list))))
a7ec1775
RS
3980 (reftex-kill-temporary-buffers))))
3981 (setq found-list (nreverse found-list))
396e0b08 3982
a7ec1775 3983 ;; Sorting
396e0b08 3984 (cond
a7ec1775
RS
3985 ((eq 'author reftex-sort-bibtex-matches)
3986 (sort found-list 'reftex-bib-sort-author))
3987 ((eq 'year reftex-sort-bibtex-matches)
3988 (sort found-list 'reftex-bib-sort-year))
3989 ((eq 'reverse-year reftex-sort-bibtex-matches)
3990 (sort found-list 'reftex-bib-sort-year-reverse))
3991 (t found-list))))
3992
3993(defun reftex-bib-sort-author (e1 e2)
206c6f82 3994 (let ((al1 (reftex-get-bib-names "author" e1))
396e0b08 3995 (al2 (reftex-get-bib-names "author" e2)))
a7ec1775 3996 (while (and al1 al2 (string= (car al1) (car al2)))
396e0b08
KH
3997 (pop al1)
3998 (pop al2))
a7ec1775 3999 (if (and (stringp (car al1))
396e0b08
KH
4000 (stringp (car al2)))
4001 (string< (car al1) (car al2))
a7ec1775
RS
4002 (not (stringp (car al1))))))
4003
4004(defun reftex-bib-sort-year (e1 e2)
4005 (< (string-to-int (cdr (assoc "year" e1)))
4006 (string-to-int (cdr (assoc "year" e2)))))
4007
4008(defun reftex-bib-sort-year-reverse (e1 e2)
4009 (> (string-to-int (or (cdr (assoc "year" e1)) "0"))
4010 (string-to-int (or (cdr (assoc "year" e2)) "0"))))
4011
4012(defun reftex-get-crossref-alist (entry)
4013 ;; return the alist from a crossref entry
4014 (let ((crkey (cdr (assoc "crossref" entry)))
4015 start)
4016 (save-excursion
4017 (save-restriction
4018 (widen)
4019 (if (re-search-forward
396e0b08
KH
4020 (concat "@\\w+[{(][ \t\n\r]*" (regexp-quote crkey)
4021 "[ \t\n\r]*,") nil t)
a7ec1775
RS
4022 (progn
4023 (setq start (match-beginning 0))
4024 (condition-case nil
4025 (up-list 1)
206c6f82 4026 (error nil))
a7ec1775
RS
4027 (reftex-parse-bibtex-entry nil start (point)))
4028 nil)))))
4029
2faef409
RS
4030;; Parse the thebibliography environment
4031(defun reftex-extract-bib-entries-from-thebibliography (file)
4032 ;; Extract bib-entries from the \begin{thebibliography} environment.
4033 ;; Parsing is not as good as for the BibTeX database stuff.
4034 ;; The environment should be located in file FILE.
4035
4036 (let* (start end buf entries re re-list)
4037 (unless file
4038 (error "Need file name to find thebibliography environment"))
4039 (setq buf (reftex-get-file-buffer-force
4040 file (not reftex-keep-temporary-buffers)))
4041 (unless buf
4042 (error "No such file %s" file))
4043 (message "Scanning thebibliography environment in %s" file)
4044
4045 (save-excursion
4046 (set-buffer buf)
4047 (save-restriction
4048 (widen)
4049 (goto-char (point-min))
4050 (if (re-search-forward
4051 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\begin{thebibliography}" nil t)
4052 (progn
4053 (beginning-of-line 2)
4054 (setq start (point))))
4055 (if (re-search-forward
4056 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\end{thebibliography}" nil t)
4057 (progn
4058 (beginning-of-line 1)
4059 (setq end (point))))
b849548d 4060 (when (and start end)
2faef409
RS
4061 (setq entries
4062 (mapcar 'reftex-parse-bibitem
4063 (delete ""
4064 (split-string
4065 (buffer-substring-no-properties start end)
4066 "[ \t\n\r]*\\\\bibitem\\(\\[[^]]*]\\)*")))))))
4067 (unless entries
4068 (error "No bibitems found"))
4069
4070 (setq re-list (split-string
4071 (read-string "RegExp [ && RegExp...]: "
4072 nil 'reftex-cite-regexp-hist)
4073 "[ \t]*&&[ \t]*"))
4074 (if (string-match "\\`[ \t]*\\'" (car re-list))
4075 (error "Empty regular expression"))
4076
4077 (while (and (setq re (pop re-list)) entries)
4078 (setq entries
b849548d
CD
4079 (delq nil (mapcar
4080 (function
4081 (lambda (x)
4082 (if (string-match re (cdr (assoc "&entry" x)))
4083 x nil)))
4084 entries))))
2faef409
RS
4085 (setq entries
4086 (mapcar
2faef409 4087 (lambda (x)
b849548d
CD
4088 (push (cons "&formatted" (reftex-format-bibitem x)) x)
4089 (push (reftex-get-bib-field "&key" x) x)
4090 x)
2faef409
RS
4091 entries))
4092
4093 entries))
4094
a7ec1775
RS
4095;; Parse and format individual entries
4096
206c6f82 4097(defun reftex-get-bib-names (field entry)
2faef409 4098 ;; Return a list with the author or editor names in ENTRY
206c6f82
RS
4099 (let ((names (reftex-get-bib-field field entry)))
4100 (if (equal "" names)
4101 (setq names (reftex-get-bib-field "editor" entry)))
4102 (while (string-match "\\band\\b[ \t]*" names)
4103 (setq names (replace-match "\n" nil t names)))
4104 (while (string-match "[\\.a-zA-Z\\-]+\\.[ \t]*\\|,.*\\|[{}]+" names)
4105 (setq names (replace-match "" nil t names)))
4106 (while (string-match "^[ \t]+\\|[ \t]+$" names)
4107 (setq names (replace-match "" nil t names)))
4108 (while (string-match "[ \t][ \t]+" names)
4109 (setq names (replace-match " " nil t names)))
396e0b08 4110 (split-string names "\n")))
a7ec1775
RS
4111
4112(defun reftex-parse-bibtex-entry (entry &optional from to)
4113 (let (alist key start field)
4114 (save-excursion
4115 (save-restriction
4116 (if entry
4117 (progn
b849548d 4118 (set-buffer (get-buffer-create " *RefTeX-scratch*"))
a7ec1775
RS
4119 (fundamental-mode)
4120 (erase-buffer)
4121 (insert entry))
4122 (widen)
4123 (narrow-to-region from to))
4124 (goto-char (point-min))
4125
396e0b08 4126 (if (re-search-forward
c52bdfca 4127 "@\\(\\w+\\)[ \t\n\r]*[{(][ \t\n\r]*\\([^ \t\n\r,]+\\)" nil t)
a7ec1775
RS
4128 (setq alist
4129 (list
396e0b08
KH
4130 (cons "&type" (downcase (reftex-match-string 1)))
4131 (cons "&key" (reftex-match-string 2)))))
a7ec1775 4132 (while (re-search-forward "\\(\\w+\\)[ \t\n\r]*=[ \t\n\r]*" nil t)
396e0b08 4133 (setq key (downcase (reftex-match-string 1)))
a7ec1775
RS
4134 (cond
4135 ((= (following-char) ?{)
4136 (forward-char 1)
4137 (setq start (point))
4138 (condition-case nil
4139 (up-list 1)
206c6f82 4140 (error nil)))
a7ec1775
RS
4141 ((= (following-char) ?\")
4142 (forward-char 1)
4143 (setq start (point))
4144 (while (and (search-forward "\"" nil t)
4145 (= ?\\ (char-after (- (point) 2))))))
4146 (t
4147 (setq start (point))
b849548d 4148 (re-search-forward "[ \t]*[\n\r,}]" nil 1)))
a7ec1775 4149 (setq field (buffer-substring-no-properties start (1- (point))))
2faef409 4150 ;; remove extra whitespace
a7ec1775
RS
4151 (while (string-match "[\n\t\r]\\|[ \t][ \t]+" field)
4152 (setq field (replace-match " " nil t field)))
4153 ;; remove leading garbage
4154 (if (string-match "^[ \t{]+" field)
4155 (setq field (replace-match "" nil t field)))
4156 ;; remove trailing garbage
4157 (if (string-match "[ \t}]+$" field)
4158 (setq field (replace-match "" nil t field)))
396e0b08
KH
4159 (push (cons key field) alist))))
4160 alist))
a7ec1775 4161
b849548d 4162(defun reftex-get-bib-field (fieldname entry &optional format)
a7ec1775 4163 ;; Extract the field FIELDNAME from an ENTRY
b849548d
CD
4164 (let ((cell (assoc fieldname entry)))
4165 (if cell
4166 (if format
4167 (format format (cdr cell))
4168 (cdr cell))
4169 "")))
a7ec1775
RS
4170
4171(defun reftex-format-bib-entry (entry)
4172 ;; Format a BibTeX ENTRY so that it is nice to look at
4173 (let*
396e0b08 4174 ((auth-list (reftex-get-bib-names "author" entry))
2faef409 4175 (authors (mapconcat 'identity auth-list ", "))
a7ec1775
RS
4176 (year (reftex-get-bib-field "year" entry))
4177 (title (reftex-get-bib-field "title" entry))
4178 (type (reftex-get-bib-field "&type" entry))
4179 (key (reftex-get-bib-field "&key" entry))
4180 (extra
4181 (cond
4182 ((equal type "article")
4183 (concat (reftex-get-bib-field "journal" entry) " "
4184 (reftex-get-bib-field "volume" entry) ", "
4185 (reftex-get-bib-field "pages" entry)))
4186 ((equal type "book")
4187 (concat "book (" (reftex-get-bib-field "publisher" entry) ")"))
4188 ((equal type "phdthesis")
4189 (concat "PhD: " (reftex-get-bib-field "school" entry)))
4190 ((equal type "mastersthesis")
4191 (concat "Master: " (reftex-get-bib-field "school" entry)))
4192 ((equal type "inbook")
4193 (concat "Chap: " (reftex-get-bib-field "chapter" entry)
4194 ", pp. " (reftex-get-bib-field "pages" entry)))
4195 ((or (equal type "conference")
4196 (equal type "incollection")
4197 (equal type "inproceedings"))
b849548d 4198 (reftex-get-bib-field "booktitle" entry "in: %s"))
a7ec1775 4199 (t ""))))
396e0b08
KH
4200 (setq authors (reftex-truncate authors 30 t t))
4201 (when (reftex-use-fonts)
b849548d
CD
4202 (put-text-property 0 (length key) 'face
4203 (reftex-verified-face reftex-label-face
4204 'font-lock-constant-face
4205 'font-lock-reference-face)
4206 key)
6b94c6ad 4207 (put-text-property 0 (length authors) 'face reftex-bib-author-face
396e0b08 4208 authors)
6b94c6ad
CD
4209 (put-text-property 0 (length year) 'face reftex-bib-year-face
4210 year)
4211 (put-text-property 0 (length title) 'face reftex-bib-title-face
396e0b08 4212 title)
6b94c6ad 4213 (put-text-property 0 (length extra) 'face reftex-bib-extra-face
396e0b08
KH
4214 extra))
4215 (concat key "\n " authors " " year " " extra "\n " title "\n\n")))
a7ec1775 4216
2faef409
RS
4217(defun reftex-parse-bibitem (item)
4218 ;; Parse a \bibitem entry
4219 (let ((key "") (text ""))
4220 (when (string-match "\\`{\\([^}]+\\)}\\([\001-\255]*\\)" item)
4221 (setq key (match-string 1 item)
4222 text (match-string 2 item)))
4223 ;; Clean up the text a little bit
4224 (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text)
4225 (setq text (replace-match " " nil t text)))
4226 (if (string-match "\\`[ \t]+" text)
4227 (setq text (replace-match "" nil t text)))
4228 (list
4229 (cons "&key" key)
4230 (cons "&text" text)
4231 (cons "&entry" (concat key " " text)))))
4232
4233(defun reftex-format-bibitem (item)
4234 ;; Format a \bibitem entry so that it is (relatively) nice to look at.
4235 (let ((text (reftex-get-bib-field "&text" item))
4236 (key (reftex-get-bib-field "&key" item))
4237 (lines nil))
4238
4239 ;; Wrap the text into several lines.
4240 (while (and (> (length text) 70)
4241 (string-match " " (substring text 60)))
4242 (push (substring text 0 (+ 60 (match-beginning 0))) lines)
4243 (setq text (substring text (+ 61 (match-beginning 0)))))
4244 (push text lines)
4245 (setq text (mapconcat 'identity (nreverse lines) "\n "))
4246
4247 (when (reftex-use-fonts)
6b94c6ad 4248 (put-text-property 0 (length text) 'face reftex-bib-author-face text))
2faef409
RS
4249 (concat key "\n " text "\n\n")))
4250
a7ec1775
RS
4251;; Make a citation
4252
b849548d 4253;;;###autoload
396e0b08 4254(defun reftex-citation (&optional no-insert)
c52bdfca 4255 "Make a citation using BibTeX database files.
a7ec1775
RS
4256After asking for a Regular Expression, it scans the buffers with
4257bibtex entries (taken from the \\bibliography command) and offers the
c52bdfca
RS
4258matching entries for selection. The selected entry is formated according
4259to `reftex-cite-format' and inserted into the buffer.
a7ec1775 4260If NO-INSERT is non-nil, nothing is inserted, only the selected key returned.
c52bdfca
RS
4261The regular expression uses an expanded syntax: && is interpreted as `and'.
4262Thus, `aaaa&&bbb' matches entries which contain both `aaaa' and `bbb'.
b849548d 4263While entering the regexp, completion on knows citation keys is possible.
fba437e6 4264When this function is called with point inside the braces of a \\cite
c52bdfca 4265command, it will add another key, ignoring the value of `reftex-cite-format'.
a7ec1775 4266When called with a numeric prefix, that many citations will be made and all
fba437e6 4267put into the same \\cite command.
b849548d 4268When called with just or two C-u as prefix, enforces rescan of buffer for
a7ec1775
RS
4269bibliography statement (e.g. if it was changed)."
4270
396e0b08 4271 (interactive)
a7ec1775
RS
4272
4273 ;; check for recursive edit
4274 (reftex-check-recursive-edit)
4275
b849548d
CD
4276 ;; This function may also be called outside reftex-mode.
4277 ;; Thus look for the scanning info only if in reftex-mode.
4278
4279 (when reftex-mode
4280 (reftex-access-scan-info current-prefix-arg))
396e0b08
KH
4281
4282 ;; Call reftex-do-citation, but protected
4283 (unwind-protect
4284 (reftex-do-citation current-prefix-arg no-insert)
4285 (reftex-kill-temporary-buffers)))
a7ec1775 4286
396e0b08
KH
4287(defun reftex-do-citation (&optional arg no-insert)
4288 ;; This really does the work of reftex-citation.
4289
b849548d
CD
4290 (let* ((format (reftex-figure-out-cite-format arg no-insert))
4291 (docstruct-symbol reftex-docstruct-symbol)
4292 (selected-entries (reftex-offer-bib-menu))
4293 (insert-entries selected-entries)
4294 entry string cite-view)
4295
4296 (unless selected-entries (error "Quit"))
4297
4298 (if (stringp selected-entries)
4299 ;; Nonexistent entry
4300 (setq selected-entries nil
4301 insert-entries (list (list selected-entries
4302 (cons "&key" selected-entries))))
4303 ;; It makes sense to compute the cite-view strings.
4304 (setq cite-view t))
4305
4306 (when (eq (car selected-entries) 'concat)
4307 ;; All keys go into a single command - we need to trick a little
4308 (pop selected-entries)
4309 (let ((concat-keys (mapconcat 'car selected-entries ",")))
4310 (setq insert-entries
4311 (list (list concat-keys (cons "&key" concat-keys))))))
4312
4313 (unless no-insert
4314
4315 ;; We shall insert this into the buffer...
4316 (message "Formatting...")
4317
4318 (while (setq entry (pop insert-entries))
4319 ;; Format the citation and insert it
4320 (setq string (if reftex-format-cite-function
4321 (funcall reftex-format-cite-function
4322 (reftex-get-bib-field "&key" entry)
4323 format)
4324 (reftex-format-citation entry format)))
4325 (insert string))
4326
4327 ;; Reposition cursor?
4328 (when (string-match "\\?" string)
4329 (search-backward "?")
4330 (delete-char 1))
4331
4332 ;; Tell AUCTeX
a6611c0d
CD
4333 (when (and reftex-mode
4334 (fboundp 'LaTeX-add-bibitems)
4335 reftex-plug-into-AUCTeX)
b849548d
CD
4336 (apply 'LaTeX-add-bibitems (mapcar 'car selected-entries)))
4337
4338 ;; Produce the cite-view strings
a6611c0d 4339 (when (and reftex-mode reftex-cache-cite-echo cite-view)
b849548d
CD
4340 (mapcar (lambda (entry)
4341 (reftex-make-cite-echo-string entry docstruct-symbol))
4342 selected-entries))
4343
4344 (message ""))
4345
4346 (set-marker reftex-select-return-marker nil)
4347 (reftex-kill-buffer "*RefTeX Select*")
4348
4349 ;; Check if the prefix arg was numeric, and call recursively
4350 (when (integerp arg)
4351 (if (> arg 1)
4352 (progn
4353 (skip-chars-backward "}")
4354 (decf arg)
4355 (reftex-do-citation arg))
4356 (forward-char 1)))
4357
4358 ;; Return the citation key
4359 (car (car selected-entries))))
4360
4361(defun reftex-figure-out-cite-format (arg no-insert)
396e0b08 4362 ;; Check if there is already a cite command at point and change cite format
a7ec1775 4363 ;; in order to only add another reference in the same cite command.
b849548d
CD
4364 (let ((macro (car (reftex-what-macro 1)))
4365 (cite-format-value (reftex-get-cite-format))
4366 key format)
4367 (cond
4368 (no-insert
4369 ;; Format does not really matter because nothing will be inserted.
4370 (setq format "%l"))
4371
4372 ((and (stringp macro)
4373 (string-match "\\`\\\\cite\\|cite\\'" macro))
4374 ;; We are already inside a cite macro
4375 (if (or (not arg) (not (listp arg)))
4376 (setq format
4377 (concat
4378 (if (member (preceding-char) '(?\{ ?,)) "" ",")
4379 "%l"
4380 (if (member (following-char) '(?\} ?,)) "" ",")))
4381 (setq format "%l")))
4382 (t
4383 ;; Figure out the correct format
206c6f82 4384 (setq format
b849548d
CD
4385 (if (and (symbolp cite-format-value)
4386 (assq cite-format-value reftex-cite-format-builtin))
4387 (nth 2 (assq cite-format-value reftex-cite-format-builtin))
4388 cite-format-value))
4389 (when (listp format)
4390 (setq key
4391 (reftex-select-with-char
4392 "" (concat "SELECT A CITATION FORMAT\n\n"
4393 (mapconcat
4394 (lambda (x)
4395 (format "[%c] %s %s" (car x)
4396 (if (> (car x) 31) " " "")
4397 (cdr x)))
4398 format "\n"))))
4399 (if (assq key format)
4400 (setq format (cdr (assq key format)))
4401 (error "No citation format associated with key `%c'" key)))))
4402 format))
4403
4404(defun reftex-get-cite-format ()
4405 ;; Return the current citation format. Either the document-local value in
4406 ;; reftex-cite-format-symbol, or the global value in reftex-cite-format.
4407 (if (and reftex-docstruct-symbol
4408 (symbolp reftex-docstruct-symbol)
4409 (get reftex-docstruct-symbol 'reftex-cite-format))
4410 (get reftex-docstruct-symbol 'reftex-cite-format)
4411 reftex-cite-format))
4412
4413(defun reftex-offer-bib-menu ()
4414 ;; Offer bib menu and return list of selected items
4415
4416 (let (found-list rtn key data selected-entries)
4417
4418 (while
4419 (not
4420 (catch 'done
4421 ;; Scan bibtex files
4422 (setq found-list
4423 (cond
4424 ((assq 'bib (symbol-value reftex-docstruct-symbol))
4425 ;; using BibTeX database files.
4426 (reftex-extract-bib-entries (reftex-get-bibfile-list)))
4427 ((assq 'thebib (symbol-value reftex-docstruct-symbol))
4428 ;; using thebibliography environment.
4429 (reftex-extract-bib-entries-from-thebibliography
4430 (cdr (assq 'thebib (symbol-value reftex-docstruct-symbol)))))
4431 (reftex-default-bibliography
4432 (message "Using default bibliography")
4433 (reftex-extract-bib-entries reftex-default-bibliography))
4434 (t (error "No valid bibliography in this document, and no default available"))))
4435
4436 (unless found-list
4437 (error "Sorry, no matches found"))
4438
4439 ;; Remember where we came from
4440 (setq reftex-call-back-to-this-buffer (current-buffer))
4441 (set-marker reftex-select-return-marker (point))
4442
4443 ;; Offer selection
4444 (save-window-excursion
4445 (delete-other-windows)
4446 (let ((default-major-mode 'reftex-select-bib-mode))
4447 (reftex-kill-buffer "*RefTeX Select*")
4448 (switch-to-buffer-other-window "*RefTeX Select*")
4449 (unless (eq major-mode 'reftex-select-bib-mode)
4450 (reftex-select-bib-mode))
4451 (let ((buffer-read-only nil))
4452 (erase-buffer)
4453 (reftex-insert-bib-matches found-list)))
4454 (setq buffer-read-only t)
4455 (if (= 0 (buffer-size))
4456 (error "Sorry, no matches found"))
4457 (setq truncate-lines t)
4458 (goto-char 1)
4459 (while t
4460 (setq rtn
4461 (reftex-select-item
4462 reftex-citation-prompt
4463 reftex-citation-help
4464 reftex-select-bib-map
4465 nil
4466 'reftex-bibtex-selection-callback nil))
4467 (setq key (car rtn)
4468 data (nth 1 rtn))
4469 (unless key (throw 'done t))
4470 (cond
4471 ((eq key ?g)
4472 ;; Start over
4473 (throw 'done nil))
4474 ((eq key ?r)
4475 ;; Restrict with new regular expression
4476 (setq found-list (reftex-restrict-bib-matches found-list))
4477 (let ((buffer-read-only nil))
4478 (erase-buffer)
4479 (reftex-insert-bib-matches found-list))
4480 (goto-char 1))
4481 ((eq key ?A)
4482 ;; Take all
4483 (setq selected-entries found-list)
4484 (throw 'done t))
4485 ((eq key ?a)
4486 ;; Take all
4487 (setq selected-entries (cons 'concat found-list))
4488 (throw 'done t))
4489 ((or (eq key ?\C-m)
4490 (eq key 'return))
4491 ;; Take selected
4492 (setq selected-entries (if data (list data) nil))
4493 (throw 'done t))
4494 ((stringp key)
4495 ;; Got this one with completion
4496 (setq selected-entries key)
4497 (throw 'done t))
4498 (t
4499 (ding))))))))
4500 selected-entries))
4501
4502(defun reftex-restrict-bib-matches (found-list)
4503 ;; Limit FOUND-LIST with more regular expressions
4504 (let ((re-list (split-string (read-string
4505 "RegExp [ && RegExp...]: "
4506 nil 'reftex-cite-regexp-hist)
4507 "[ \t]*&&[ \t]*"))
4508 (found-list-r found-list)
4509 re)
4510 (while (setq re (pop re-list))
4511 (setq found-list-r
4512 (delq nil
4513 (mapcar
4514 (lambda (x)
4515 (if (string-match
4516 re (cdr (assoc "&entry" x)))
4517 x
4518 nil))
4519 found-list-r))))
4520 (if found-list-r
4521 found-list-r
4522 (ding)
4523 found-list)))
396e0b08 4524
206c6f82
RS
4525(defun reftex-insert-bib-matches (list)
4526 ;; Insert the bib matches and number them correctly
6b94c6ad
CD
4527 (let ((mouse-face
4528 (if (memq reftex-highlight-selection '(mouse both))
4529 reftex-mouse-selected-face
4530 nil))
4531 tmp len)
2faef409
RS
4532 (mapcar
4533 (function
4534 (lambda (x)
29d593f8
KH
4535 (setq tmp (cdr (assoc "&formatted" x))
4536 len (length tmp))
4537 (put-text-property 0 len ':data x tmp)
4538 (put-text-property 0 (1- len) 'mouse-face mouse-face tmp)
2faef409 4539 (insert tmp)))
b849548d
CD
4540 list))
4541 (run-hooks 'reftex-display-copied-context-hook))
206c6f82
RS
4542
4543(defun reftex-format-names (namelist n)
206c6f82
RS
4544 (let (last (len (length namelist)))
4545 (cond
b849548d 4546 ((< len 1) "")
206c6f82
RS
4547 ((= 1 len) (car namelist))
4548 ((> len n) (concat (car namelist) (nth 2 reftex-cite-punctuation)))
4549 (t
4550 (setq n (min len n)
396e0b08 4551 last (nth (1- n) namelist))
206c6f82
RS
4552 (setcdr (nthcdr (- n 2) namelist) nil)
4553 (concat
4554 (mapconcat 'identity namelist (nth 0 reftex-cite-punctuation))
4555 (nth 1 reftex-cite-punctuation)
4556 last)))))
4557
4558(defun reftex-format-citation (entry format)
a7ec1775 4559 ;; Format a citation from the info in the BibTeX ENTRY
a7ec1775 4560
396e0b08 4561 (unless (stringp format) (setq format "\\cite{%l}"))
206c6f82
RS
4562
4563 (if (and reftex-comment-citations
396e0b08 4564 (string-match "%l" reftex-cite-comment-format))
2faef409 4565 (error "reftex-cite-comment-format contains illegal %%l"))
206c6f82 4566
396e0b08
KH
4567 (while (string-match
4568 "\\(\\`\\|[^%]\\)\\(\\(%\\([0-9]*\\)\\([a-zA-Z]\\)\\)[.,;: ]*\\)"
4569 format)
206c6f82 4570 (let ((n (string-to-int (match-string 4 format)))
396e0b08
KH
4571 (l (string-to-char (match-string 5 format)))
4572 rpl b e)
206c6f82 4573 (save-match-data
396e0b08
KH
4574 (setq rpl
4575 (cond
4576 ((= l ?l) (concat
4577 (reftex-get-bib-field "&key" entry)
4578 (if reftex-comment-citations
4579 reftex-cite-comment-format
4580 "")))
4581 ((= l ?a) (reftex-format-names
4582 (reftex-get-bib-names "author" entry)
4583 (or n 2)))
4584 ((= l ?A) (car (reftex-get-bib-names "author" entry)))
b849548d
CD
4585 ((= l ?b) (reftex-get-bib-field "booktitle" entry "in: %s"))
4586 ((= l ?B) (reftex-abbreviate-title
4587 (reftex-get-bib-field "booktitle" entry "in: %s")))
396e0b08
KH
4588 ((= l ?c) (reftex-get-bib-field "chapter" entry))
4589 ((= l ?d) (reftex-get-bib-field "edition" entry))
4590 ((= l ?e) (reftex-format-names
4591 (reftex-get-bib-names "editor" entry)
4592 (or n 2)))
4593 ((= l ?E) (car (reftex-get-bib-names "editor" entry)))
4594 ((= l ?h) (reftex-get-bib-field "howpublished" entry))
4595 ((= l ?i) (reftex-get-bib-field "institution" entry))
4596 ((= l ?j) (reftex-get-bib-field "journal" entry))
4597 ((= l ?k) (reftex-get-bib-field "key" entry))
4598 ((= l ?m) (reftex-get-bib-field "month" entry))
4599 ((= l ?n) (reftex-get-bib-field "number" entry))
4600 ((= l ?o) (reftex-get-bib-field "organization" entry))
4601 ((= l ?p) (reftex-get-bib-field "pages" entry))
4602 ((= l ?P) (car (split-string
4603 (reftex-get-bib-field "pages" entry)
4604 "[- .]+")))
4605 ((= l ?s) (reftex-get-bib-field "school" entry))
4606 ((= l ?u) (reftex-get-bib-field "publisher" entry))
4607 ((= l ?r) (reftex-get-bib-field "address" entry))
4608 ((= l ?t) (reftex-get-bib-field "title" entry))
b849548d
CD
4609 ((= l ?T) (reftex-abbreviate-title
4610 (reftex-get-bib-field "title" entry)))
396e0b08
KH
4611 ((= l ?v) (reftex-get-bib-field "volume" entry))
4612 ((= l ?y) (reftex-get-bib-field "year" entry)))))
206c6f82
RS
4613
4614 (if (string= rpl "")
396e0b08
KH
4615 (setq b (match-beginning 2) e (match-end 2))
4616 (setq b (match-beginning 3) e (match-end 3)))
206c6f82
RS
4617 (setq format (concat (substring format 0 b) rpl (substring format e)))))
4618 (while (string-match "%%" format)
4619 (setq format (replace-match "%" t t format)))
4620 (while (string-match "[ ,.;:]*%<" format)
4621 (setq format (replace-match "" t t format)))
4622 format)
a7ec1775 4623
2faef409 4624(defun reftex-bibtex-selection-callback (data ignore no-revisit)
a7ec1775 4625 ;; Callback function to be called from the BibTeX selection, in
c52bdfca 4626 ;; order to display context. This function is relatively slow and not
2faef409 4627 ;; recommended for follow mode. It works OK for individual lookups.
a7ec1775 4628 (let ((win (selected-window))
2faef409
RS
4629 (key (reftex-get-bib-field "&key" data))
4630 bibfile-list item tmp)
4631
4632 (catch 'exit
4633 (save-excursion
4634 (set-buffer reftex-call-back-to-this-buffer)
4635 (cond
4636 ((assq 'bib (symbol-value reftex-docstruct-symbol))
4637 (setq bibfile-list (reftex-get-bibfile-list)))
4638 ((setq tmp (assq 'thebib (symbol-value reftex-docstruct-symbol)))
4639 (setq bibfile-list (list (cdr tmp))
4640 item t))
4641 (reftex-default-bibliography
4642 (setq bibfile-list reftex-default-bibliography))
4643 (t (ding) (throw 'exit))))
4644
4645 (when no-revisit
b849548d 4646 (setq bibfile-list (reftex-visited-files bibfile-list)))
2faef409 4647
b849548d
CD
4648 (condition-case nil
4649 (reftex-pop-to-bibtex-entry
4650 key bibfile-list (not reftex-keep-temporary-buffers) t item)
4651 (error (ding))))
4652
a7ec1775
RS
4653 (select-window win)))
4654
b849548d 4655;;; =========================================================================
a7ec1775
RS
4656;;;
4657;;; Here is the routine used for selection
4658
4659;; Marker for return point from recursive edit
4660(defvar reftex-recursive-edit-marker (make-marker))
4661
2faef409
RS
4662(defvar reftex-last-data nil)
4663(defvar reftex-last-line nil)
4664
a7ec1775 4665(defun reftex-check-recursive-edit ()
c52bdfca 4666 ;; Check if we are already in a recursive edit. Abort with helpful
a7ec1775
RS
4667 ;; message if so.
4668 (if (marker-position reftex-recursive-edit-marker)
4669 (error
4670 (substitute-command-keys
29d593f8 4671 "In unfinished selection process. Finish, or abort with \\[abort-recursive-edit]."))))
a7ec1775 4672
2faef409
RS
4673(defun reftex-select-item (prompt help-string keymap
4674 &optional offset
be456a1d 4675 call-back cb-flag)
2faef409
RS
4676;; Select an item, using PROMPT. The function returns a key indicating
4677;; an exit status, along with a data structure indicating which item was
4678;; selected.
4679;; HELP-STRING contains help. KEYMAP is a keymap with the available
4680;; selection commands.
4681;; OFFSET can be a label list item which will be selected at start.
4682;; When it is t, point will start out at the beginning of the buffer.
4683;; Any other value will cause restart where last selection left off.
4684;; When CALL-BACK is given, it is a function which is called with the index
4685;; of the element.
4686;; CB-FLAG is the initial value of that flag.
2faef409 4687
5ff44b47 4688 (let* (ev data last-data callback-fwd (selection-buffer (current-buffer)))
206c6f82 4689
a7ec1775 4690 (setq ev
29d593f8 4691 (catch 'myexit
a7ec1775 4692 (save-window-excursion
a7ec1775 4693 (setq truncate-lines t)
a7ec1775 4694
2faef409
RS
4695 ;; Find a good starting point
4696 (cond
4697 (offset
4698 (goto-char
4699 (or (and (listp offset)
4700 (text-property-any (point-min) (point-max)
4701 ':data offset))
4702 (and (local-variable-p 'reftex-last-data (current-buffer))
4703 (boundp 'reftex-last-data)
4704 (listp reftex-last-data)
4705 (text-property-any (point-min) (point-max)
4706 ':data reftex-last-data))
4707 (and (local-variable-p 'reftex-last-line (current-buffer))
4708 (boundp 'reftex-last-line)
4709 (integerp reftex-last-line)
4710 (progn (goto-line reftex-last-line) (point)))
4711 (point-min))))
4712 (t (goto-char (point-min))))
4713 (beginning-of-line 1)
29d593f8 4714 (set (make-local-variable 'reftex-last-follow-point) (point))
a7ec1775 4715
2faef409
RS
4716 (unwind-protect
4717 (progn
4718 (use-local-map keymap)
29d593f8
KH
4719 (add-hook 'pre-command-hook 'reftex-select-pre-command-hook nil t)
4720 (add-hook 'post-command-hook 'reftex-select-post-command-hook nil t)
4721 (princ prompt)
4722 (set-marker reftex-recursive-edit-marker (point))
b849548d 4723 ;; XEmacs does not run post-command-hook here
a6611c0d 4724 (and (featurep 'xemacs) (run-hooks 'post-command-hook))
29d593f8
KH
4725 (recursive-edit))
4726
5ff44b47
CD
4727 (set-marker reftex-recursive-edit-marker nil)
4728 (save-excursion
4729 (set-buffer selection-buffer)
4730 (use-local-map nil)
4731 (remove-hook 'pre-command-hook 'reftex-select-pre-command-hook t)
4732 (remove-hook 'post-command-hook
4733 'reftex-select-post-command-hook t))))))
2faef409
RS
4734
4735 (set (make-local-variable 'reftex-last-line)
4736 (+ (count-lines (point-min) (point)) (if (bolp) 1 0)))
4737 (set (make-local-variable 'reftex-last-data) last-data)
29d593f8 4738 (reftex-kill-buffer "*RefTeX Help*")
b849548d 4739 (setq callback-fwd (not callback-fwd)) ;; ;-)))
a7ec1775 4740 (message "")
2faef409
RS
4741 (list ev data last-data)))
4742
4743;; The following variables are all bound dynamically in `reftex-select-item'.
4744;; The defvars are here only to silence the byte compiler.
4745
2faef409
RS
4746(defvar found-list)
4747(defvar cb-flag)
4748(defvar data)
29d593f8
KH
4749(defvar prompt)
4750(defvar last-data)
2faef409
RS
4751(defvar call-back)
4752(defvar help-string)
2faef409
RS
4753(defvar callback-fwd)
4754(defvar varioref)
2faef409
RS
4755
4756;; The selection commands
4757
29d593f8
KH
4758(defun reftex-select-pre-command-hook ()
4759 (reftex-unhighlight 1)
4760 (reftex-unhighlight 0))
4761
4762(defun reftex-select-post-command-hook ()
4763 (let (b e)
4764 (setq data (get-text-property (point) ':data))
4765 (setq last-data (or data last-data))
4766
4767 (when (and data cb-flag
4768 (not (equal reftex-last-follow-point (point))))
4769 (setq reftex-last-follow-point (point))
4770 (funcall call-back data callback-fwd
4771 (not reftex-revisit-to-follow)))
4772 (if data
4773 (setq b (or (previous-single-property-change
4774 (1+ (point)) ':data)
4775 (point-min))
4776 e (or (next-single-property-change
4777 (point) ':data)
4778 (point-max)))
4779 (setq b (point) e (point)))
4780 (and (memq reftex-highlight-selection '(cursor both))
4781 (reftex-highlight 1 b e))
4782 (if (or (not (pos-visible-in-window-p b))
4783 (not (pos-visible-in-window-p e)))
a6611c0d 4784 (recenter '(4)))
b849548d 4785 (unless (current-message)
29d593f8
KH
4786 (princ prompt))))
4787
4788(defun reftex-select-next (&optional arg)
b849548d 4789 "Move to next selectable item."
29d593f8 4790 (interactive "p")
2faef409
RS
4791 (setq callback-fwd t)
4792 (or (eobp) (forward-char 1))
29d593f8 4793 (re-search-forward "^[^. \t\n\r]" nil t arg)
2faef409 4794 (beginning-of-line 1))
29d593f8 4795(defun reftex-select-previous (&optional arg)
b849548d 4796 "Move to previous selectable item."
29d593f8 4797 (interactive "p")
2faef409 4798 (setq callback-fwd nil)
29d593f8
KH
4799 (re-search-backward "^[^. \t\n\r]" nil t arg))
4800(defun reftex-select-next-heading (&optional arg)
b849548d 4801 "Move to next table of contentes line."
29d593f8 4802 (interactive "p")
2faef409 4803 (end-of-line)
29d593f8 4804 (re-search-forward "^ " nil t arg)
2faef409 4805 (beginning-of-line))
29d593f8 4806(defun reftex-select-previous-heading (&optional arg)
b849548d 4807 "Move to previous table of contentes line."
29d593f8
KH
4808 (interactive "p")
4809 (re-search-backward "^ " nil t arg))
2faef409 4810(defun reftex-select-quit ()
b849548d 4811 "Abort selection process."
2faef409 4812 (interactive)
29d593f8
KH
4813 (throw 'myexit nil))
4814(defun reftex-select-keyboard-quit ()
b849548d 4815 "Abort selection process."
29d593f8
KH
4816 (interactive)
4817 (throw 'exit t))
2faef409 4818(defun reftex-select-jump-to-previous ()
b849548d 4819 "Jump back to where previous selection process left off."
2faef409
RS
4820 (interactive)
4821 (let (pos)
4822 (cond
4823 ((and (local-variable-p 'reftex-last-data (current-buffer))
4824 reftex-last-data
4825 (setq pos (text-property-any (point-min) (point-max)
4826 ':data reftex-last-data)))
4827 (goto-char pos))
4828 ((and (local-variable-p 'reftex-last-line (current-buffer))
4829 (integerp reftex-last-line))
4830 (goto-line reftex-last-line))
4831 (t (ding)))))
4832(defun reftex-select-toggle-follow ()
b849548d 4833 "Toggle follow mode: Other window follows with full context."
2faef409 4834 (interactive)
b849548d 4835 (setq reftex-last-follow-point -1)
2faef409
RS
4836 (setq cb-flag (not cb-flag)))
4837(defun reftex-select-toggle-varioref ()
b849548d 4838 "Toggle the macro used for referencing the label between \\ref and \\vref."
2faef409
RS
4839 (interactive)
4840 (if (string= varioref "\\ref")
4841 (setq varioref "\\vref")
4842 (setq varioref "\\ref"))
4843 (force-mode-line-update))
29d593f8 4844(defun reftex-select-show-insertion-point ()
b849548d 4845 "Show the point from where selection was started in another window."
29d593f8
KH
4846 (interactive)
4847 (let ((this-window (selected-window)))
4848 (unwind-protect
4849 (progn
4850 (switch-to-buffer-other-window
4851 (marker-buffer reftex-select-return-marker))
4852 (goto-char (marker-position reftex-select-return-marker))
a6611c0d 4853 (recenter '(4)))
29d593f8 4854 (select-window this-window))))
2faef409 4855(defun reftex-select-callback ()
b849548d 4856 "Show full context in another window."
2faef409
RS
4857 (interactive)
4858 (if data (funcall call-back data callback-fwd nil) (ding)))
4859(defun reftex-select-accept ()
b849548d 4860 "Accept the currently selected item."
2faef409 4861 (interactive)
29d593f8
KH
4862 (throw 'myexit 'return))
4863(defun reftex-select-mouse-accept (ev)
b849548d 4864 "Accept the item at the mouse click."
29d593f8
KH
4865 (interactive "e")
4866 (mouse-set-point ev)
4867 (setq data (get-text-property (point) ':data))
4868 (setq last-data (or data last-data))
4869 (throw 'myexit 'return))
2faef409 4870(defun reftex-select-read-label ()
b849548d 4871 "Use minibuffer to read a label to reference, with completion."
2faef409
RS
4872 (interactive)
4873 (let ((label (completing-read
4874 "Label: " (symbol-value reftex-docstruct-symbol)
4875 nil nil reftex-prefix)))
4876 (unless (or (equal label "") (equal label reftex-prefix))
29d593f8 4877 (throw 'myexit label))))
2faef409 4878(defun reftex-select-read-cite ()
b849548d 4879 "Use minibuffer to read a citation key with completion."
2faef409 4880 (interactive)
b849548d
CD
4881 (let* ((key (completing-read "Citation key: " found-list))
4882 (entry (assoc key found-list)))
4883 (cond
4884 ((or (null key) (equal key "")))
4885 (entry
4886 (setq data entry)
4887 (setq last-data data)
4888 (throw 'myexit 'return))
4889 (t (throw 'myexit key)))))
2faef409 4890(defun reftex-select-help ()
b849548d 4891 "Display a summary of the special key bindings."
2faef409
RS
4892 (interactive)
4893 (with-output-to-temp-buffer "*RefTeX Help*"
4894 (princ help-string))
29d593f8 4895 (reftex-enlarge-to-fit "*RefTeX Help*" t))
a7ec1775 4896
b849548d 4897;;; =========================================================================
a7ec1775
RS
4898;;;
4899;;; View cross references
4900
a6611c0d 4901(defun reftex-view-crossref (&optional arg how)
fba437e6
RS
4902 "View cross reference of \\ref or \\cite macro at point.
4903If the macro at point is a \\ref, show the corresponding label definition.
2faef409 4904If it is a \\cite, show the BibTeX database entry or the \\bibitem.
a6611c0d
CD
4905To cope with the plethora of variations in packages, this
4906function assumes any macro either starting with or ending in `ref' or
4907`cite' to contain cross references.
2faef409
RS
4908When the LaTeX package `xr' is being used, this command will also view
4909crossreferences in external documents. However, this works correctly only
4910when the \\externaldocument macros are used with the optional label prefix
4911argument.
4912With one or two C-u prefixes, enforce rescanning of the document.
a6611c0d
CD
4913With argument 2, select the window showing the cross reference.
4914When HOW is 'echo, call the corresponding echo function.
4915When HOW is 'tmp-window, make the pop-up window as small as possible and
4916arrange for its removal before the next command."
a7ec1775
RS
4917
4918 (interactive "P")
4919
4920 ;; See where we are.
a6611c0d
CD
4921 (let* ((macro (car (reftex-what-macro 1)))
4922 (key (reftex-this-word "^{}%\n\r,")))
396e0b08 4923
b849548d
CD
4924 (setq reftex-call-back-to-this-buffer (current-buffer))
4925
a6611c0d
CD
4926 (if (and macro
4927 (string-match "\\`\\\\cite\\|\\`\\\\ref\\|cite\\'\\|ref\\'"
4928 macro))
4929 (and (setq macro (match-string 0 macro))
4930 (string-match "\\`\\\\" macro)
4931 (setq macro (substring macro 1)))
4932 (setq macro nil))
4933
4934 (if (or (null macro) (reftex-in-comment))
b849548d 4935 (error "No cross reference to display"))
a7ec1775 4936
a6611c0d
CD
4937 (if (eq how 'tmp-window)
4938 ;; Remember the window configuration
4939 (put 'reftex-auto-view-crossref 'last-window-conf
4940 (current-window-configuration)))
4941 (cond
4942 ((string= macro "cite")
4943 (reftex-view-cr-cite arg key how))
4944 ((string= macro "ref")
4945 (reftex-view-cr-ref arg key how))
4946 (t
4947 (error "Cannot display crossref\n")))))
4948
4949(defun reftex-view-cr-cite (arg key how)
4950 ;; View crossreference of a ref cite. HOW can have the values
4951 ;; nil: Show in another window.
4952 ;; echo: Show one-line info in echo area.
4953 ;; tmp-window: Show in small window and arrange for window to disappear.
a7ec1775 4954
a6611c0d
CD
4955 ;; Ensure access to scanning info
4956 (reftex-access-scan-info (or arg current-prefix-arg))
4957
4958 (let (files size item (pos (point)) (win (selected-window)) pop-win)
4959 ;; Find the citation mode and the file list
4960 (cond
4961 ((assq 'bib (symbol-value reftex-docstruct-symbol))
4962 (setq item nil
4963 files (reftex-get-bibfile-list)))
4964 ((assq 'thebib (symbol-value reftex-docstruct-symbol))
4965 (setq item t
4966 files (list (cdr (assq 'thebib
4967 (symbol-value reftex-docstruct-symbol))))))
4968 (reftex-default-bibliography
4969 (setq item nil
4970 files reftex-default-bibliography))
4971 (how) ;; don't throw for special display
4972 (t (error "Cannot display crossref")))
4973
4974 (if (eq how 'echo)
4975 ;; Display in Echo area
4976 (reftex-echo-cite key files item)
4977 ;; Display in a window
4978 (if (not (eq how 'tmp-window))
4979 ;; Normal display
4980 (reftex-pop-to-bibtex-entry key files nil t item)
4981 ;; A temporary window
4982 (condition-case nil
4983 (reftex-pop-to-bibtex-entry key files nil t item)
4984 (error (goto-char pos)
4985 (message "cite: no such citation key %s" key)
4986 (error "")))
4987 ;; Resize the window
4988 (setq size (max 1 (count-lines (point)
4989 (reftex-end-of-bib-entry item))))
4990 (let ((window-min-height 2))
4991 (shrink-window (1- (- (window-height) size)))
4992 (recenter 0))
4993 ;; Arrange restoration
4994 (add-hook 'pre-command-hook 'reftex-restore-window-conf))
4995
4996 ;; Normal display in other window
b849548d 4997 (add-hook 'pre-command-hook 'reftex-highlight-shall-die)
a6611c0d
CD
4998 (setq pop-win (selected-window))
4999 (select-window win)
5000 (goto-char pos)
5001 (when (equal arg 2)
5002 (select-window pop-win)))))
5003
5004(defun reftex-view-cr-ref (arg label how)
5005 ;; View crossreference of a ref macro. HOW can have the values
5006 ;; nil: Show in another window.
5007 ;; echo: Show one-line info in echo area.
5008 ;; tmp-window: Show in small window and arrange for window to disappear.
5009
5010 ;; Ensure access to scanning info
5011 (reftex-access-scan-info (or arg current-prefix-arg))
5012
5013 (let* ((xr-data (assoc 'xr (symbol-value reftex-docstruct-symbol)))
5014 (xr-re (nth 2 xr-data))
5015 (entry (assoc label (symbol-value reftex-docstruct-symbol)))
5016 (win (selected-window)) pop-win (pos (point)))
5017
5018 (if (and (not entry) (stringp label) xr-re (string-match xr-re label))
5019 ;; Label is defined in external document
5020 (save-excursion
5021 (save-match-data
5022 (set-buffer
5023 (or (reftex-get-file-buffer-force
5024 (cdr (assoc (match-string 1 label) (nth 1
5025 xr-data))))
5026 (error "Problem with external label %s" label))))
5027 (setq label (substring label (match-end 1)))
5028 (reftex-access-scan-info)
5029 (setq entry
5030 (assoc label (symbol-value reftex-docstruct-symbol)))))
5031 (if (eq how 'echo)
5032 (reftex-echo-ref label entry (symbol-value reftex-docstruct-symbol))
5033 (unless entry
5034 (message "Label %s not known - reparse document might help" label))
5035
5036 (reftex-pop-to-label label (list (nth 3 entry)) nil t)
5037 (add-hook 'pre-command-hook 'reftex-highlight-shall-die)
5038
5039 (when (eq how 'tmp-window)
5040 ;; Resize window and arrange restauration
5041 (shrink-window (1- (- (window-height) 9)))
5042 (recenter '(4))
5043 (add-hook 'pre-command-hook 'reftex-restore-window-conf))
5044 (setq pop-win (selected-window))
5045 (select-window win)
5046 (goto-char pos)
5047 (when (equal arg 2)
5048 (select-window pop-win)))))
a7ec1775
RS
5049
5050(defun reftex-mouse-view-crossref (ev)
fba437e6
RS
5051 "View cross reference of \\ref or \\cite macro where you click.
5052If the macro at point is a \\ref, show the corresponding label definition.
5053If it is a \\cite, show the BibTeX database entry.
a7ec1775 5054If there is no such macro at point, search forward to find one.
a7ec1775
RS
5055With argument, actually select the window showing the cross reference."
5056 (interactive "e")
5057 (mouse-set-point ev)
5058 (reftex-view-crossref current-prefix-arg))
5059
b849548d
CD
5060(defvar reftex-auto-view-crossref-timer nil
5061 "The timer used for auto-view-crossref.")
5062
5063(defun reftex-view-crossref-when-idle ()
a6611c0d 5064 ;; Display info about crossref at point in echo area or a window.
b849548d
CD
5065 ;; This function was desigend to work with an idle timer.
5066 ;; We try to get out of here as quickly as possible if the call is useless.
5067 (and reftex-mode
5068 ;; Quick precheck if this might be a relevant spot
a6611c0d 5069 ;; FIXME: failes with backslash in comment
b849548d
CD
5070 (save-excursion
5071 (search-backward "\\" nil t)
5072 (looking-at "\\\\[a-zA-Z]*\\(cite\\|ref\\)"))
a6611c0d
CD
5073 ;; Make sure message area is free if we need it.
5074 (or (eq reftex-auto-view-crossref 'window) (not (current-message)))
5075 ;; Make sure we are not already displaying this one
5076 (not (memq last-command '(reftex-view-crossref
5077 reftex-mouse-view-crossref)))
b849548d
CD
5078 (condition-case nil
5079 (let ((current-prefix-arg nil))
a6611c0d
CD
5080 (cond
5081 ((eq reftex-auto-view-crossref t)
5082 (reftex-view-crossref -1 'echo))
5083 ((eq reftex-auto-view-crossref 'window)
5084 (reftex-view-crossref -1 'tmp-window))
5085 (t nil)))
5086 (error nil))))
5087
5088(defun reftex-restore-window-conf ()
5089 (set-window-configuration (get 'reftex-auto-view-crossref 'last-window-conf))
5090 (put 'reftex-auto-view-crossref 'last-window-conf nil)
5091 (remove-hook 'pre-command-hook 'reftex-restore-window-conf))
b849548d
CD
5092
5093(defun reftex-echo-ref (label entry docstruct)
5094 ;; Display crossref info in echo area.
5095 (cond
5096 ((null docstruct)
5097 (message (substitute-command-keys (format reftex-no-info-message "ref"))))
5098 ((null entry)
5099 (message "ref: unknown label: %s" label))
5100 (t
5101 (when (stringp (nth 2 entry))
5102 (message "ref(%s): %s" (nth 1 entry) (nth 2 entry)))
5103 (let ((buf (get-buffer " *Echo Area*")))
5104 (when buf
5105 (save-excursion
5106 (set-buffer buf)
5107 (run-hooks 'reftex-display-copied-context-hook)))))))
5108
a6611c0d 5109(defun reftex-echo-cite (key files item)
b849548d 5110 ;; Display citation info in echo area.
a6611c0d 5111 (let* ((cache (assq 'bibview-cache (symbol-value reftex-docstruct-symbol)))
b849548d 5112 (cache-entry (assoc key (cdr cache)))
a6611c0d 5113 entry string buf (all-files files))
b849548d
CD
5114
5115 (if (and reftex-cache-cite-echo cache-entry)
5116 ;; We can just use the cache
5117 (setq string (cdr cache-entry))
5118
5119 ;; Need to look in the database
5120 (unless reftex-revisit-to-echo
a6611c0d 5121 (setq files (reftex-visited-files files)))
b849548d
CD
5122
5123 (setq entry
5124 (condition-case nil
5125 (save-excursion
5126 (reftex-pop-to-bibtex-entry key files nil nil item t))
5127 (error
a6611c0d 5128 (if (and files (= (length all-files) (length files)))
b849548d
CD
5129 (message "cite: no such database entry: %s" key)
5130 (message (substitute-command-keys
5131 (format reftex-no-info-message "cite"))))
5132 nil)))
5133 (when entry
a6611c0d
CD
5134 (if item
5135 (setq string (reftex-nicify-text entry))
5136 (setq string (reftex-make-cite-echo-string
5137 (reftex-parse-bibtex-entry entry)
5138 reftex-docstruct-symbol)))))
b849548d
CD
5139 (unless (or (null string) (equal string ""))
5140 (message "cite: %s" string))
5141 (when (setq buf (get-buffer " *Echo Area*"))
5142 (save-excursion
5143 (set-buffer buf)
5144 (run-hooks 'reftex-display-copied-context-hook)))))
5145
5146(defun reftex-make-cite-echo-string (entry docstruct-symbol)
5147 ;; Format a bibtex entry for the echo area and cache the result.
5148 (let* ((key (reftex-get-bib-field "&key" entry))
5149 (string
5150 (let* ((reftex-cite-punctuation '(" " " & " " etal.")))
5151 (reftex-format-citation entry reftex-cite-view-format)))
5152 (cache (assq 'bibview-cache (symbol-value docstruct-symbol)))
5153 (cache-entry (assoc key (cdr cache))))
5154 (unless cache
5155 ;; This docstruct has no cache - make one.
5156 (set docstruct-symbol (cons (cons 'bibview-cache nil)
5157 (symbol-value docstruct-symbol))))
5158 (when reftex-cache-cite-echo
5159 (setq key (copy-sequence key))
5160 (set-text-properties 0 (length key) nil key)
5161 (set-text-properties 0 (length string) nil string)
5162 (if cache-entry
5163 (unless (string= (cdr cache-entry) string)
5164 (setcdr cache-entry string)
5165 (put reftex-docstruct-symbol 'modified t))
5166 (push (cons key string) (cdr cache))
5167 (put reftex-docstruct-symbol 'modified t)))
5168 string))
5169
5170(defvar reftex-use-itimer-in-xemacs nil
5171 "*Non-nil means use the idle timers in XEmacs for crossref display.
5172Currently, idle timer restart is broken and we use the post-command-hook.")
5173
5174(defun reftex-toggle-auto-view-crossref ()
5175 "Toggle the automatic display of crossref information in the echo area.
5176When active, leaving point idle in the argument of a \\ref or \\cite macro
5177will display info in the echo area."
5178 (interactive)
5179 (if reftex-auto-view-crossref-timer
5180 (progn
5181 (if (featurep 'xemacs)
5182 (if reftex-use-itimer-in-xemacs
5183 (delete-itimer reftex-auto-view-crossref-timer)
5184 (remove-hook 'post-command-hook 'reftex-start-itimer-once))
5185 (cancel-timer reftex-auto-view-crossref-timer))
5186 (setq reftex-auto-view-crossref-timer nil)
5187 (message "Automatic display of crossref information was turned off"))
5188 (setq reftex-auto-view-crossref-timer
5189 (if (featurep 'xemacs)
5190 (if reftex-use-itimer-in-xemacs
5191 (start-itimer "RefTeX Idle Timer"
5192 'reftex-view-crossref-when-idle
5193 reftex-idle-time reftex-idle-time t)
5194 (add-hook 'post-command-hook 'reftex-start-itimer-once)
5195 nil)
5196 (run-with-idle-timer
5197 reftex-idle-time t 'reftex-view-crossref-when-idle)))
5198 (message "Automatic display of crossref information was turned on")))
5199
5200(defun reftex-start-itimer-once ()
5201 (and reftex-mode
5202 (not (itimer-live-p reftex-auto-view-crossref-timer))
5203 (setq reftex-auto-view-crossref-timer
5204 (start-itimer "RefTeX Idle Timer"
5205 'reftex-view-crossref-when-idle
5206 reftex-idle-time nil t))))
5207
5208;;; =========================================================================
a7ec1775
RS
5209;;;
5210;;; Functions that check out the surroundings
5211
5212(defun reftex-what-macro (which &optional bound)
5213 ;; Find out if point is within the arguments of any TeX-macro.
c52bdfca 5214 ;; The return value is either ("\\macro" . (point)) or a list of them.
a7ec1775
RS
5215
5216 ;; If WHICH is nil, immediately return nil.
b849548d 5217 ;; If WHICH is 1, return innermost enclosing macro.
a7ec1775
RS
5218 ;; If WHICH is t, return list of all macros enclosing point.
5219 ;; If WHICH is a list of macros, look only for those macros and return the
5220 ;; name of the first macro in this list found to enclose point.
5221 ;; If the optional BOUND is an integer, bound backwards directed
c52bdfca 5222 ;; searches to this point. If it is nil, limit to nearest \section -
a7ec1775
RS
5223 ;; like statement.
5224
5225 ;; This function is pretty stable, but can be fooled if the text contains
c52bdfca
RS
5226 ;; things like \macro{aa}{bb} where \macro is defined to take only one
5227 ;; argument. As RefTeX cannot know this, the string "bb" would still be
5228 ;; considered an argument of macro \macro.
a7ec1775 5229
b849548d 5230 (unless reftex-section-regexp (reftex-compile-variables))
a7ec1775
RS
5231 (catch 'exit
5232 (if (null which) (throw 'exit nil))
5233 (let ((bound (or bound (save-excursion (re-search-backward
5234 reftex-section-regexp nil 1)
5235 (point))))
396e0b08 5236 pos cmd-list cmd cnt cnt-opt entry)
a7ec1775
RS
5237 (save-restriction
5238 (save-excursion
5239 (narrow-to-region (max 1 bound) (point-max))
5240 ;; move back out of the current parenthesis
5241 (while (condition-case nil
5242 (progn (up-list -1) t)
5243 (error nil))
396e0b08 5244 (setq cnt 1 cnt-opt 0)
a7ec1775 5245 ;; move back over any touching sexps
396e0b08
KH
5246 (while (and (reftex-move-to-previous-arg bound)
5247 (condition-case nil
5248 (progn (backward-sexp) t)
5249 (error nil)))
5250 (if (eq (following-char) ?\[) (incf cnt-opt))
5251 (incf cnt))
a7ec1775 5252 (setq pos (point))
396e0b08
KH
5253 (when (and (or (= (following-char) ?\[)
5254 (= (following-char) ?\{))
5255 (re-search-backward "\\\\[*a-zA-Z]+\\=" nil t))
5256 (setq cmd (reftex-match-string 0))
5257 (when (looking-at "\\\\begin{[^}]*}")
5258 (setq cmd (reftex-match-string 0)
5259 cnt (1- cnt)))
5260 ;; This does ignore optional arguments. Very hard to fix.
5261 (when (setq entry (assoc cmd reftex-env-or-mac-alist))
5262 (if (> cnt (or (nth 4 entry) 100))
5263 (setq cmd nil)))
5264 (cond
5265 ((null cmd))
5266 ((eq t which)
5267 (push (cons cmd (point)) cmd-list))
b849548d 5268 ((or (eq 1 which) (member cmd which))
396e0b08 5269 (throw 'exit (cons cmd (point))))))
a7ec1775
RS
5270 (goto-char pos)))
5271 (nreverse cmd-list)))))
5272
5273(defun reftex-what-environment (which &optional bound)
5274 ;; Find out if point is inside a LaTeX environment.
c52bdfca 5275 ;; The return value is (e.g.) either ("equation" . (point)) or a list of
a7ec1775
RS
5276 ;; them.
5277
5278 ;; If WHICH is nil, immediately return nil.
b849548d 5279 ;; If WHICH is 1, return innermost enclosing environment.
a7ec1775
RS
5280 ;; If WHICH is t, return list of all environments enclosing point.
5281 ;; If WHICH is a list of environments, look only for those environments and
5282 ;; return the name of the first environment in this list found to enclose
5283 ;; point.
5284
b849548d
CD
5285 ;; If the optional BOUND is an integer, bound backwards directed searches to
5286 ;; this point. If it is nil, limit to nearest \section - like statement.
5287
a6611c0d 5288 (unless reftex-section-regexp (reftex-compile-variables))
b849548d
CD
5289 (catch 'exit
5290 (save-excursion
5291 (if (null which) (throw 'exit nil))
5292 (let ((bound (or bound (save-excursion (re-search-backward
5293 reftex-section-regexp nil 1)
5294 (point))))
5295 env-list end-list env)
5296 (while (re-search-backward "\\\\\\(begin\\|end\\){\\([^}]+\\)}"
5297 bound t)
5298 (setq env (buffer-substring-no-properties
5299 (match-beginning 2) (match-end 2)))
5300 (cond
5301 ((string= (match-string 1) "end")
5302 (add-to-list 'end-list env))
5303 ((member env end-list)
5304 (setq end-list (delete env end-list)))
5305 ((eq t which)
5306 (push (cons env (point)) env-list))
5307 ((or (eq 1 which) (member env which))
5308 (throw 'exit (cons env (point))))))
5309 (nreverse env-list)))))
5310
5311;;; =========================================================================
5312;;;
5313;;; Finding files
5314
5315(defun reftex-find-tex-file (file master-dir &optional die)
5316 ;; Find FILE in MASTER-DIR or on reftex-tex-path.
5317 ;; FILE may be given with or without the .tex extension.
5318 (let ((rec-values '(nil t)) path file1 old-path)
a6611c0d
CD
5319 (if (file-name-absolute-p file)
5320 (if (file-regular-p (concat file ".tex"))
5321 (setq file1 (concat file ".tex"))
5322 (if (file-regular-p file) (setq file1 file)))
b849548d 5323 (while (and (null file1) rec-values)
a6611c0d 5324 (setq path (reftex-access-search-path
b849548d
CD
5325 "tex" (pop rec-values) master-dir file))
5326 (if (or (null old-path)
5327 (not (eq old-path path)))
5328 (setq old-path path
5329 path (cons master-dir path)
5330 file1 (or (reftex-find-file-on-path
5331 (concat file ".tex") path master-dir)
5332 (reftex-find-file-on-path file path master-dir))))))
5333 (cond (file1 file1)
5334 (die (error "No such file: %s" file) nil)
5335 (t (message "No such file: %s (ignored)" file) nil))))
5336
5337(defun reftex-find-bib-file (file master-dir &optional die)
5338 ;; Find FILE in MASTER-DIR or on reftex-bib-path
5339 (let ((rec-values '(nil t)) path file1 old-path)
a6611c0d
CD
5340 (if (file-name-absolute-p file)
5341 (if (file-regular-p file) (setq file1 file))
b849548d
CD
5342 (while (and (null file1) rec-values)
5343 (setq path (reftex-access-search-path
5344 "bib" (pop rec-values) master-dir file))
5345 (if (or (null old-path)
5346 (not (eq old-path path)))
5347 (setq old-path path
5348 path (cons master-dir path)
5349 file1 (reftex-find-file-on-path file path master-dir)))))
5350 (cond (file1 file1)
5351 (die (error "No such file: %s" file) nil)
5352 (t (message "No such file: %s (ignored)" file) nil))))
5353
5354(defun reftex-access-search-path (which &optional recurse master-dir file)
5355 ;; Access path from environment variables. WHICH is either "tex" or "bib".
5356 ;; When RECURSE is t, expand path elements ending in `//' recursively.
5357 ;; Relative path elements are left as they are. However, relative recursive
5358 ;; elements are expanded with MASTER-DIR as default directory.
5359 ;; The expanded path is cached for the next search.
5360 ;; FILE is just for the progress message.
5361 ;; Returns the derived path.
5362 (let* ((pathvar (intern (concat "reftex-" which "-path"))))
5363 (when (null (get pathvar 'status))
5364 ;; Get basic path from environment
5365 (let ((env-vars (if (equal which "tex") (list "TEXINPUTS")
5366 reftex-bibpath-environment-variables)))
5367 (set pathvar (reftex-parse-colon-path
5368 (mapconcat (lambda(x) (or (getenv x) ""))
5369 env-vars path-separator))))
5370 (put pathvar 'status 'split)
5371 ;; Check if we have recursive elements
5372 (let ((path (symbol-value pathvar)) dir rec)
5373 (while (setq dir (pop path))
5374 (when (string= (substring dir -2) "//")
5375 (if (file-name-absolute-p dir)
5376 (setq rec (or rec 'absolute))
5377 (setq rec 'relative))))
5378 (put pathvar 'rec-type rec)))
5379
5380 (if recurse
5381 ;; Return the recursive expansion of the path
5382 (cond
5383 ((not (get pathvar 'rec-type))
5384 ;; Path does not contain recursive elements - use simple path
5385 (symbol-value pathvar))
5386 ((or (not (get pathvar 'recursive-path))
5387 (and (eq (get pathvar 'rec-type) 'relative)
5388 (not (equal master-dir (get pathvar 'master-dir)))))
5389 ;; Either: We don't have a recursive expansion yet.
5390 ;; or: Relative recursive path elements need to be expanded
5391 ;; relative to new default directory
5392 (message "Expanding search path to find %s file: %s ..." which file)
5393 (put pathvar 'recursive-path
5394 (reftex-expand-path (symbol-value pathvar) master-dir))
5395 (put pathvar 'master-dir master-dir)
5396 (get pathvar 'recursive-path))
5397 (t
5398 ;; Recursive path computed earlier is still OK.
5399 (get pathvar 'recursive-path)))
5400 ;; The simple path was requested
5401 (symbol-value pathvar))))
5402
5403(defun reftex-find-file-on-path (file path &optional def-dir)
5404 ;; Find FILE along the directory list PATH.
5405 ;; DEF-DIR is the default directory for expanding relative path elements.
5406 (catch 'exit
5407 (when (file-name-absolute-p file)
a6611c0d 5408 (if (file-regular-p file)
b849548d
CD
5409 (throw 'exit file)
5410 (throw 'exit nil)))
5411 (let* ((thepath path) file1 dir )
5412 (while (setq dir (pop thepath))
5413 (when (string= (substring dir -2) "//")
5414 (setq dir (substring dir 0 -1)))
5415 (setq file1 (expand-file-name file (expand-file-name dir def-dir)))
a6611c0d 5416 (if (file-regular-p file1)
b849548d
CD
5417 (throw 'exit file1)))
5418 ;; No such file
5419 nil)))
5420
5421(defun reftex-parse-colon-path (path)
5422 ;; Like parse-colon-parse, but // or /~ are left alone.
5423 ;; Trailing ! or !! will be converted into `//' (emTeX convention)
5424 (mapcar
5425 (lambda (dir)
5426 (if (string-match "\\(//+\\|/*!+\\)\\'" dir)
5427 (setq dir (replace-match "//" t t dir)))
5428 (file-name-as-directory dir))
5429 (delete "" (split-string path (concat path-separator "+")))))
5430
5431(defun reftex-expand-path (path &optional default-dir)
5432 ;; Expand parts of path ending in `//' recursively into directory list.
5433 ;; Relative recursive path elements are expanded relative to DEFAULT-DIR.
5434 (let (path1 dir recursive)
5435 (while (setq dir (pop path))
5436 (if (setq recursive (string= (substring dir -2) "//"))
5437 (setq dir (substring dir 0 -1)))
5438 (if (and recursive
5439 (not (file-name-absolute-p dir)))
5440 (setq dir (expand-file-name dir default-dir)))
5441 (if recursive
5442 ;; Expand recursively
5443 (setq path1 (append (reftex-recursive-directory-list dir) path1))
5444 ;; Keep unchanged
5445 (push dir path1)))
5446 (nreverse path1)))
a7ec1775 5447
b849548d
CD
5448(defun reftex-recursive-directory-list (dir)
5449 ;; Return a list of all directories below DIR, including DIR itself
5450 (let ((path (list dir)) path1 file files)
5451 (while (setq dir (pop path))
5452 (when (file-directory-p dir)
5453 (setq files (nreverse (directory-files dir t "[^.]")))
5454 (while (setq file (pop files))
5455 (if (file-directory-p file)
5456 (push (file-name-as-directory file) path)))
5457 (push dir path1)))
5458 path1))
a7ec1775 5459
b849548d
CD
5460;;; =========================================================================
5461;;;
5462;;; Some generally useful functions
a7ec1775
RS
5463
5464(defun reftex-no-props (string)
5465 ;; Return STRING with all text properties removed
5466 (and (stringp string)
5467 (set-text-properties 0 (length string) nil string))
5468 string)
5469
396e0b08
KH
5470(defun reftex-match-string (n)
5471 ;; Match string without properties
5472 (when (match-beginning n)
5473 (buffer-substring-no-properties (match-beginning n) (match-end n))))
5474
2faef409 5475(defun reftex-kill-buffer (buffer)
29d593f8 5476 ;; Kill buffer if it exists.
2faef409
RS
5477 (and (setq buffer (get-buffer buffer))
5478 (kill-buffer buffer)))
5479
29d593f8
KH
5480(defun reftex-erase-buffer (&optional buffer)
5481 ;; Erase BUFFER if it exists. BUFFER defaults to current buffer.
5482 ;; This even erases read-only buffers.
5483 (cond
5484 ((null buffer)
5485 ;; erase current buffer
5486 (let ((buffer-read-only nil)) (erase-buffer)))
5487 ((setq buffer (get-buffer buffer))
5488 ;; buffer exists
5489 (save-excursion
5490 (set-buffer buffer)
5491 (let ((buffer-read-only nil)) (erase-buffer))))))
2faef409 5492
396e0b08
KH
5493(defun reftex-this-word (&optional class)
5494 ;; Grab the word around point.
5495 (setq class (or class "-a-zA-Z0-9:_/.*;|"))
5496 (save-excursion
5497 (buffer-substring-no-properties
5498 (progn (skip-chars-backward class) (point))
5499 (progn (skip-chars-forward class) (point)))))
5500
b849548d
CD
5501(defun reftex-all-assq (key list)
5502 ;; Return a list of all associations of KEY in LIST. Comparison with eq.
5503 (let (rtn)
5504 (while (setq list (memq (assq key list) list))
5505 (push (car list) rtn)
5506 (pop list))
5507 (nreverse rtn)))
5508
5509(defun reftex-all-assoc-string (key list)
5510 ;; Return a list of all associations of KEY in LIST. Comparison with string=.
5511 (let (rtn)
5512 (while list
5513 (if (string= (car (car list)) key)
5514 (push (car list) rtn))
5515 (pop list))
5516 (nreverse rtn)))
5517
5518(defun reftex-last-assoc-before-elt (key elt list)
5519 ;; Find the last association of KEY in LIST before or at ELT
5520 ;; ELT is found in LIST with equal, not eq.
5521 ;; Returns nil when either KEY or elt are not found in LIST.
5522 ;; On success, returns the association.
5523 (let* ((elt (car (member elt list))) ass last-ass)
5524
5525 (while (and (setq ass (assoc key list))
5526 (setq list (memq ass list))
5527 (memq elt list))
5528 (setq last-ass ass
5529 list (cdr list)))
5530 last-ass))
5531
baec1250 5532(defvar enable-multibyte-characters)
396e0b08
KH
5533(defun reftex-truncate (string ncols &optional ellipses padding)
5534 ;; Truncate a string to NCHAR characters.
5535 ;; Works fast with ASCII and correctly with Mule characters.
5536 ;; When ELLIPSES is non-nil, put three dots at the end of the string.
b849548d 5537 ;; When padding is non-nil, fills with white space to NCOLS characters.
396e0b08
KH
5538 (setq string
5539 (cond
5540 ((and (boundp 'enable-multibyte-characters)
b849548d 5541 enable-multibyte-characters
a6611c0d 5542 (fboundp 'string-width)
b849548d 5543 (fboundp 'truncate-string-to-width))
396e0b08
KH
5544 (if (<= (string-width string) ncols)
5545 string
5546 (if ellipses
5547 (concat (truncate-string-to-width string (- ncols 3)) "...")
5548 (truncate-string-to-width string ncols))))
5549 (t
5550 (if (<= (length string) ncols)
5551 string
5552 (if ellipses
5553 (concat (substring string 0 (- ncols 3)) "...")
5554 (substring string 0 ncols))))))
5555 (if padding
5556 (format (format "%%-%ds" ncols) string)
5557 string))
5558
b849548d
CD
5559(defun reftex-nearest-match (regexp &optional pos)
5560 ;; Find the nearest match of REGEXP. Set the match data.
5561 ;; If POS is given, calculate distances relative to it.
5562 ;; Return nil if there is no match.
5563 (let ((start (point)) (pos (or pos (point))) match1 match2 match)
5564 (goto-char start)
5565 (when (re-search-backward regexp nil t)
5566 (setq match1 (match-data)))
5567 (goto-char start)
5568 (when (re-search-forward regexp nil t)
5569 (setq match2 (match-data)))
5570 (goto-char start)
5571 (setq match
5572 (cond
5573 ((not match1) match2)
5574 ((not match2) match1)
5575 ((< (abs (- pos (car match1))) (abs (- pos (car match2)))) match1)
5576 (t match2)))
5577 (if match (progn (set-match-data match) t) nil)))
5578
5579(defun reftex-auto-mode-alist ()
5580 ;; Return an `auto-mode-alist' with only the .gz (etc) thingies.
5581 ;; Stolen from gnus nnheader.
5582 (let ((alist auto-mode-alist)
5583 out)
5584 (while alist
5585 (when (listp (cdr (car alist)))
5586 (push (car alist) out))
5587 (pop alist))
5588 (nreverse out)))
5589
5590(defun reftex-enlarge-to-fit (buf2 &optional keep-current)
5591 ;; Enlarge other window displaying buffer to show whole buffer if possible.
5592 ;; If KEEP-CURRENT in non-nil, current buffer must remain visible.
5593 (let* ((win1 (selected-window))
5594 (buf1 (current-buffer))
5595 (win2 (get-buffer-window buf2)))
5596 (when win2
5597 (select-window win2)
5598 (unless (and (pos-visible-in-window-p 1)
5599 (pos-visible-in-window-p (point-max)))
5600 (enlarge-window (1+ (- (count-lines 1 (point-max))
5601 (window-height))))))
5602 (cond
5603 ((window-live-p win1) (select-window win1))
5604 (keep-current
5605 ;; we must have the old buffer!
5606 (switch-to-buffer-other-window buf1)
5607 (shrink-window (- (window-height) window-min-height))))))
5608
5609(defun reftex-select-with-char (prompt help-string &optional delay-time scroll)
5610 ;; Offer to select something with PROMPT and, after DELAY-TIME seconds,
5611 ;; also with HELP-STRING.
5612 ;; When SCROLL is non-nil, use SPC and DEL to scroll help window.
5613 (let ((char ?\?))
5614 (save-window-excursion
5615 (catch 'exit
5616 (message (concat prompt " (?=Help)"))
5617 (when (or (sit-for (or delay-time 0))
5618 (= ?\? (setq char (read-char-exclusive))))
5619 (with-output-to-temp-buffer " *RefTeX Help*"
5620 (princ help-string))
5621 (reftex-enlarge-to-fit " *RefTeX Help*")
5622 (select-window (get-buffer-window " *RefTeX Help*"))
5623 (setq truncate-lines t))
5624 (setq prompt (concat prompt (if scroll " (SPC/DEL=Scroll)" "")))
5625 (message prompt)
5626 (and (equal char ?\?) (setq char (read-char-exclusive)))
5627 (while t
5628 (cond ((equal char ?\C-g) (keyboard-quit))
5629 ((equal char ?\?))
5630 ((and scroll (equal char ?\ ))
5631 (condition-case nil (scroll-up) (error nil))
5632 (message prompt))
5633 ((and scroll (equal char ?\C-? ))
5634 (condition-case nil (scroll-down) (error nil))
5635 (message prompt))
5636 (t (throw 'exit char)))
5637 (setq char (read-char-exclusive)))))))
5638
5639(defun reftex-make-regexp-allow-for-ctrl-m (string)
5640 ;; convert STRING into a regexp, allowing ^M for \n and vice versa
5641 (let ((start -2))
5642 (setq string (regexp-quote string))
5643 (while (setq start (string-match "[\n\r]" string (+ 3 start)))
5644 (setq string (replace-match "[\n\r]" nil t string)))
5645 string))
5646
5647(defun reftex-get-buffer-visiting (file)
5648 ;; return a buffer visiting FILE
5649 (cond
5650 ((boundp 'find-file-compare-truenames) ; XEmacs
5651 (let ((find-file-compare-truenames t))
5652 (get-file-buffer file)))
5653 ((fboundp 'find-buffer-visiting) ; Emacs
5654 (find-buffer-visiting file))
5655 (t (error "This should not happen (reftex-get-buffer-visiting)"))))
5656
5657;; Define `current-message' for compatibility with XEmacs prior to 20.4
5658(defvar message-stack)
5659(if (and (featurep 'xemacs)
5660 (not (fboundp 'current-message)))
5661 (defun current-message (&optional frame)
5662 (cdr (car message-stack))))
5663
5664(defun reftex-visited-files (list)
5665 ;; Takes a list of filenames and returns the buffers of those already visited
5666 (delq nil (mapcar (lambda (x) (if (reftex-get-buffer-visiting x) x nil))
5667 list)))
5668
5669(defun reftex-get-file-buffer-force (file &optional mark-to-kill)
5670 ;; Return a buffer visiting file. Make one, if necessary.
5671 ;; If neither such a buffer nor the file exist, return nil.
5672 ;; If MARK-TO-KILL is t and there is no live buffer, visit the file with
5673 ;; initializations according to `reftex-initialize-temporary-buffers',
5674 ;; and mark the buffer to be killed after use.
5675
5676 (let ((buf (reftex-get-buffer-visiting file)))
5677
5678 (cond (buf
5679 ;; We have it already as a buffer - just return it
5680 buf)
5681
5682 ((file-readable-p file)
5683 ;; At least there is such a file and we can read it.
5684
5685 (if (or (not mark-to-kill)
5686 (eq t reftex-initialize-temporary-buffers))
5687
5688 ;; Visit the file with full magic
5689 (setq buf (find-file-noselect file))
5690
5691 ;; Else: Visit the file just briefly, without or
5692 ;; with limited Magic
5693
5694 ;; The magic goes away
5695 (let ((format-alist nil)
5696 (auto-mode-alist (reftex-auto-mode-alist))
5697 (default-major-mode 'fundamental-mode)
5698 (enable-local-variables nil)
5699 (after-insert-file-functions nil))
5700 (setq buf (find-file-noselect file)))
5701
5702 ;; Is there a hook to run?
5703 (when (listp reftex-initialize-temporary-buffers)
5704 (save-excursion
5705 (set-buffer buf)
5706 (run-hooks 'reftex-initialize-temporary-buffers))))
5707
5708 ;; Lets see if we got a license to kill :-|
5709 (and mark-to-kill
5710 (add-to-list 'reftex-buffers-to-kill buf))
5711
5712 ;; Return the new buffer
5713 buf)
5714
5715 ;; If no such file exists, return nil
5716 (t nil))))
5717
5718(defun reftex-kill-temporary-buffers (&optional buffer)
5719 ;; Kill all buffers in the list reftex-kill-temporary-buffers.
5720 (cond
5721 (buffer
5722 (when (member buffer reftex-buffers-to-kill)
5723 (kill-buffer buffer)
5724 (setq reftex-buffers-to-kill
5725 (delete buffer reftex-buffers-to-kill))))
5726 (t
5727 (while (setq buffer (pop reftex-buffers-to-kill))
5728 (when (bufferp buffer)
5729 (and (buffer-modified-p buffer)
5730 (y-or-n-p (format "Save file %s? "
5731 (buffer-file-name buffer)))
5732 (save-excursion
5733 (set-buffer buffer)
5734 (save-buffer)))
5735 (kill-buffer buffer))
5736 (pop reftex-buffers-to-kill)))))
5737
5738(defun reftex-splice-symbols-into-list (list alist)
5739 ;; Splice the association in ALIST of any symbols in LIST into the list.
5740 ;; Return new list.
5741 (let (rtn tmp)
5742 (while list
5743 (while (and (not (null (car list))) ;; keep list elements nil
5744 (symbolp (car list)))
5745 (setq tmp (car list))
5746 (cond
5747 ((assoc tmp alist)
5748 (setq list (append (nth 2 (assoc tmp alist)) (cdr list))))
5749 (t
5750 (error "Cannot treat symbol %s in reftex-label-alist"
5751 (symbol-name tmp)))))
5752 (push (pop list) rtn))
5753 (nreverse rtn)))
5754
5755(defun reftex-uniquify-by-car (alist &optional keep-list)
5756 ;; Return a list of all elements in ALIST, but each car only once.
5757 ;; Elements of KEEP-LIST are not removed even if duplicate.
5758 (let (new elm)
5759 (while alist
5760 (setq elm (pop alist))
5761 (if (or (member (car elm) keep-list)
5762 (not (assoc (car elm) new)))
5763 (push elm new)))
5764 (nreverse new)))
5765
5766;;; =========================================================================
5767;;;
5768;;; Fontification and Highlighting
5769
5770(defun reftex-use-fonts ()
5771 ;; Return t if we can and want to use fonts.
5772 (and window-system
5773 reftex-use-fonts
5774 (featurep 'font-lock)))
5775
5776(defun reftex-refontify ()
5777 ;; Return t if we need to refontify context
5778 (and (reftex-use-fonts)
5779 (or (eq t reftex-refontify-context)
5780 (and (eq 1 reftex-refontify-context)
5781 ;; Test of we use the font-lock version of x-symbol
5782 (and (featurep 'x-symbol-tex) (not (boundp 'x-symbol-mode)))))))
5783
5784(defun reftex-fontify-select-label-buffer (parent-buffer)
5785 ;; Fontify the `*RefTeX Select*' buffer. Buffer is temporarily renamed to
5786 ;; start with none-SPC char, beacuse Font-Lock otherwise refuses operation.
5787 (run-hook-with-args 'reftex-pre-refontification-functions
5788 parent-buffer 'reftex-ref)
5789 (let* ((oldname (buffer-name))
5790 (newname (concat "Fontify-me-" oldname)))
5791 (unwind-protect
5792 (progn
5793 ;; Rename buffer temporarily to start w/o space (because of font-lock)
5794 (rename-buffer newname t)
5795 (cond
5796 ((fboundp 'font-lock-default-fontify-region)
5797 ;; Good: we have the indirection functions
5798 (set (make-local-variable 'font-lock-fontify-region-function)
5799 'reftex-select-font-lock-fontify-region)
5800 (let ((major-mode 'latex-mode))
5801 (font-lock-mode 1)))
5802 ((fboundp 'font-lock-set-defaults-1)
5803 ;; Looks like the XEmacs font-lock stuff.
5804 ;; FIXME: this is still kind of a hack.
5805 (set (make-local-variable 'font-lock-keywords) nil)
5806 (let ((major-mode 'latex-mode)
5807 (font-lock-defaults-computed nil))
5808 (font-lock-set-defaults-1)
5809 (reftex-select-font-lock-fontify-region (point-min) (point-max))))
5810 (t
5811 ;; Oops?
5812 (message "Sorry: cannot refontify RefTeX Select buffer."))))
5813 (rename-buffer oldname))))
5814
5815(defun reftex-select-font-lock-fontify-region (beg end &optional loudly)
5816 ;; Fontify a region, but only lines starting with a dot.
5817 (let ((func (if (fboundp 'font-lock-default-fontify-region)
5818 'font-lock-default-fontify-region
5819 'font-lock-fontify-region))
5820 beg1 end1)
5821 (goto-char beg)
5822 (while (re-search-forward "^\\." end t)
5823 (setq beg1 (point) end1 (progn (skip-chars-forward "^\n") (point)))
5824 (funcall func beg1 end1 nil)
5825 (goto-char end1))))
5826
5827(defun reftex-select-font-lock-unfontify (&rest ignore) t)
396e0b08 5828
b849548d
CD
5829(defun reftex-verified-face (&rest faces)
5830 ;; Return the first valid face in FACES, or nil if none is valid.
5831 ;; Also, when finding a nil element in FACES, return nil. This
5832 ;; function is just a safety net to catch name changes of builtin
5833 ;; fonts. Currently it is only used for reftex-label-face, which has
5834 ;; as default font-lock-reference-face, which was recently renamed
5835 ;; to font-lock-constant-face.
5836 (let (face)
5837 (catch 'exit
5838 (while (setq face (pop faces))
5839 (if (featurep 'xemacs)
5840 (if (find-face face) (throw 'exit face))
5841 (if (facep face) (throw 'exit face)))))))
396e0b08 5842
b849548d
CD
5843;; Highlighting uses overlays. For XEmacs, we need the emulation.
5844(if (featurep 'xemacs) (require 'overlay))
5845
5846;; We keep a vector with several different overlays to do our highlighting.
5847(defvar reftex-highlight-overlays [nil nil])
5848
5849;; Initialize the overlays
5850(aset reftex-highlight-overlays 0 (make-overlay 1 1))
5851(overlay-put (aref reftex-highlight-overlays 0)
5852 'face 'highlight)
5853(aset reftex-highlight-overlays 1 (make-overlay 1 1))
5854(overlay-put (aref reftex-highlight-overlays 1)
5855 'face reftex-cursor-selected-face)
5856
5857;; Two functions for activating and deactivation highlight overlays
5858(defun reftex-highlight (index begin end &optional buffer)
5859 "Highlight a region with overlay INDEX."
5860 (move-overlay (aref reftex-highlight-overlays index)
5861 begin end (or buffer (current-buffer))))
5862(defun reftex-unhighlight (index)
5863 "Detach overlay INDEX."
5864 (delete-overlay (aref reftex-highlight-overlays index)))
5865
5866(defun reftex-highlight-shall-die ()
5867 ;; Function used in pre-command-hook to remove highlights.
5868 (remove-hook 'pre-command-hook 'reftex-highlight-shall-die)
5869 (reftex-unhighlight 0))
5870
5871;;; =========================================================================
5872;;;
5873;;; Functions to compile the tables, reset the mode etc.
2faef409 5874
b849548d
CD
5875;; A list of all variables in the cache.
5876;; The cache is used to save the compiled versions of some variables.
5877(defconst reftex-cache-variables
5878 '(reftex-memory ;; This MUST ALWAYS be the first!
5879 reftex-env-or-mac-alist reftex-everything-regexp
5880 reftex-find-label-regexp-format reftex-find-label-regexp-format2
5881 reftex-label-env-list reftex-label-mac-list
5882 reftex-section-or-include-regexp reftex-section-levels-all
5883 reftex-section-regexp reftex-type-query-help
5884 reftex-type-query-prompt reftex-typekey-list
5885 reftex-typekey-to-format-alist reftex-typekey-to-prefix-alist
5886 reftex-words-to-typekey-alist))
5887
5888(defun reftex-ensure-compiled-variables ()
5889 ;; Recompile the label alist when necessary
5890 (let* ((mem reftex-memory)
5891 (cache (get reftex-docstruct-symbol 'reftex-cache))
5892 (cmem (car cache))
5893 (alist reftex-label-alist)
5894 (levels (get reftex-docstruct-symbol 'reftex-section-levels))
5895 (style (get reftex-docstruct-symbol 'reftex-label-alist-style))
5896 (default reftex-default-label-alist-entries))
396e0b08 5897 (cond
b849548d
CD
5898 (reftex-tables-dirty (reftex-compile-variables))
5899 ((and (eq alist (nth 0 mem))
5900 (eq levels (nth 1 mem))
5901 (eq style (nth 2 mem))
5902 (eq default (nth 3 mem)))) ;; everything is OK
5903 ((and (eq alist (nth 0 cmem))
5904 (eq levels (nth 1 cmem))
5905 (eq style (nth 2 cmem))
5906 (eq default (nth 2 cmem)))
5907 ;; restore the cache
5908 (message "Restoring cache")
5909 (mapcar (lambda (sym) (set sym (pop cache))) reftex-cache-variables))
5910 (t (reftex-compile-variables)))))
396e0b08 5911
b849548d
CD
5912(defun reftex-reset-mode ()
5913 "Reset RefTeX Mode.
5914This will re-compile the configuration information and remove all
5915current scanning information and the parse file to enforce a rescan
5916on next use."
5917 (interactive)
a7ec1775 5918
b849548d
CD
5919 ;; Reset the file search path variables
5920 (loop for prop in '(status master-dir recursive-path rec-type) do
5921 (put 'reftex-tex-path prop nil)
5922 (put 'reftex-bib-path prop nil))
396e0b08 5923
b849548d
CD
5924 ;; Kill temporary buffers associated with RefTeX - just in case they
5925 ;; were not cleaned up properly
5926 (save-excursion
5927 (let ((buffer-list '("*RefTeX Help*" "*RefTeX Select*"
5928 "*Duplicate Labels*" "*toc*" " *RefTeX-scratch*"))
5929 buf)
5930 (while (setq buf (pop buffer-list))
5931 (if (get-buffer buf)
5932 (kill-buffer buf))))
5933 (reftex-erase-all-selection-buffers))
396e0b08 5934
b849548d
CD
5935 ;; Make sure the current document will be rescanned soon.
5936 (reftex-reset-scanning-information)
a7ec1775 5937
b849548d
CD
5938 ;; Remove any parse info file
5939 (reftex-access-parse-file 'kill)
396e0b08 5940
b849548d
CD
5941 ;; Plug functions into AUCTeX if the user option says so.
5942 (and reftex-plug-into-AUCTeX
5943 (reftex-plug-into-AUCTeX))
a7ec1775 5944
b849548d 5945 (reftex-compile-variables))
a7ec1775 5946
b849548d
CD
5947(defun reftex-reset-scanning-information ()
5948 "Reset the symbols containing information from buffer scanning.
5949This enforces rescanning the buffer on next use."
5950 (if (string= reftex-last-toc-master (reftex-TeX-master-file))
5951 (reftex-erase-buffer "*toc*"))
5952 (let ((symlist reftex-multifile-symbols)
5953 symbol)
5954 (while symlist
5955 (setq symbol (car symlist)
5956 symlist (cdr symlist))
5957 (if (and (symbolp (symbol-value symbol))
5958 (not (null (symbol-value symbol))))
5959 (set (symbol-value symbol) nil)))))
a7ec1775 5960
b849548d
CD
5961(defun reftex-erase-all-selection-buffers ()
5962 ;; Remove all selection buffers associated with current document.
5963 (mapcar
5964 (lambda (type)
5965 (reftex-erase-buffer (reftex-make-selection-buffer-name type)))
5966 reftex-typekey-list))
396e0b08 5967
b849548d
CD
5968(defun reftex-compile-variables ()
5969 ;; Compile the information in reftex-label-alist & Co.
396e0b08 5970
b849548d 5971 (message "Compiling label environment definitions...")
396e0b08 5972
b849548d
CD
5973 ;; Update AUCTeX style information
5974 (when (and (featurep 'tex-site) (fboundp 'TeX-update-style))
5975 (condition-case nil (TeX-update-style) (error nil)))
396e0b08 5976
b849548d
CD
5977 ;; Record that we have done this, and what we have used.
5978 (setq reftex-tables-dirty nil)
5979 (setq reftex-memory
5980 (list reftex-label-alist
5981 (get reftex-docstruct-symbol 'reftex-section-levels)
5982 (get reftex-docstruct-symbol 'reftex-label-alist-style)
5983 reftex-default-label-alist-entries))
5984
5985 ;; Compile information in reftex-label-alist
5986 (let ((all (reftex-uniquify-by-car
5987 (reftex-splice-symbols-into-list
5988 (append reftex-label-alist
5989 (get reftex-docstruct-symbol 'reftex-label-alist-style)
5990 reftex-default-label-alist-entries)
5991 reftex-label-alist-builtin)
5992 '(nil)))
5993 entry env-or-mac typekeychar typekey prefix context word
5994 fmt reffmt labelfmt wordlist qh-list macros-with-labels
5995 nargs nlabel opt-args cell sum i)
5996
5997 (setq reftex-words-to-typekey-alist nil
5998 reftex-typekey-list nil
5999 reftex-typekey-to-format-alist nil
6000 reftex-typekey-to-prefix-alist nil
6001 reftex-env-or-mac-alist nil
6002 reftex-label-env-list nil
6003 reftex-label-mac-list nil)
6004 (while all
6005 (catch 'next-entry
6006 (setq entry (car all)
6007 env-or-mac (car entry)
6008 entry (cdr entry)
6009 all (cdr all))
6010 (if (null env-or-mac)
6011 (setq env-or-mac ""))
6012 (if (stringp (car entry))
6013 ;; This is before version 2.00 - convert entry to new format
6014 ;; This is just to keep old users happy
6015 (setq entry (cons (string-to-char (car entry))
6016 (cons (concat (car entry) ":")
6017 (cdr entry)))))
6018 (setq typekeychar (nth 0 entry)
6019 typekey (if typekeychar (char-to-string typekeychar) nil)
6020 prefix (nth 1 entry)
6021 fmt (nth 2 entry)
6022 context (nth 3 entry)
6023 wordlist (nth 4 entry))
6024 (if (stringp wordlist)
6025 ;; This is before version 2.04 - convert to new format
6026 (setq wordlist (nthcdr 4 entry)))
6027
6028 (if (and (stringp fmt)
6029 (string-match "@" fmt))
6030 ;; Special syntax for specifying a label format
6031 (setq fmt (split-string fmt "@+"))
6032 (setq fmt (list "\\label{%s}" fmt)))
6033 (setq labelfmt (car fmt)
6034 reffmt (nth 1 fmt))
6035 ;; Note a new typekey
6036 (if typekey
6037 (add-to-list 'reftex-typekey-list typekey))
6038 (if (and typekey prefix
6039 (not (assoc typekey reftex-typekey-to-prefix-alist)))
6040 (add-to-list 'reftex-typekey-to-prefix-alist
6041 (cons typekey prefix)))
6042 ;; Check if this is a macro or environment
6043 (cond
6044 ((string-match "\\`\\\\" env-or-mac)
6045 ;; It's a macro
6046 (let ((result (reftex-parse-args env-or-mac)))
6047 (setq env-or-mac (or (first result) env-or-mac)
6048 nargs (second result)
6049 nlabel (third result)
6050 opt-args (fourth result))
6051 (if nlabel (add-to-list 'macros-with-labels env-or-mac)))
6052 (if typekey (add-to-list 'reftex-label-mac-list env-or-mac)))
6053 (t
6054 ;; It's an environment
6055 (setq nargs nil nlabel nil opt-args nil)
6056 (cond ((string= env-or-mac "any"))
6057 ((string= env-or-mac ""))
6058 ((string= env-or-mac "section"))
6059 (t
6060 (add-to-list 'reftex-label-env-list env-or-mac)))))
6061 ;; Translate some special context cases
6062 (when (assq context reftex-default-context-regexps)
6063 (setq context
6064 (format
6065 (cdr (assq context reftex-default-context-regexps))
6066 (regexp-quote env-or-mac))))
6067 ;; See if this is the first format for this typekey
6068 (and reffmt
6069 (not (assoc typekey reftex-typekey-to-format-alist))
6070 (push (cons typekey reffmt) reftex-typekey-to-format-alist))
6071 ;; See if this is the first definition for this env-or-mac
6072 (and (not (string= env-or-mac "any"))
6073 (not (string= env-or-mac ""))
6074 (not (assoc env-or-mac reftex-env-or-mac-alist))
6075 (push (list env-or-mac typekey context labelfmt
6076 nargs nlabel opt-args)
6077 reftex-env-or-mac-alist))
6078 ;; Are the magic words regular expressions? Quote normal words.
6079 (if (eq (car wordlist) 'regexp)
6080 (setq wordlist (cdr wordlist))
6081 (setq wordlist (mapcar 'regexp-quote wordlist)))
6082 ;; Remember the first association of each word.
6083 (while (stringp (setq word (pop wordlist)))
6084 (or (assoc word reftex-words-to-typekey-alist)
6085 (push (cons word typekey) reftex-words-to-typekey-alist)))
6086 (cond
6087 ((string= "" env-or-mac) nil)
6088 ((setq cell (assoc typekey qh-list))
6089 (push env-or-mac (cdr cell)))
6090 (typekey
6091 (push (list typekey env-or-mac) qh-list)))))
396e0b08 6092
b849548d
CD
6093 (setq reftex-typekey-to-prefix-alist
6094 (nreverse reftex-typekey-to-prefix-alist))
396e0b08 6095
b849548d
CD
6096 ;; Prepare the typekey query prompt and help string.
6097 (setq qh-list
6098 (sort qh-list (function
6099 (lambda (x1 x2) (string< (car x1) (car x2))))))
6100 (setq reftex-type-query-prompt
6101 (concat "Label type: ["
6102 (mapconcat (function (lambda(x) (format "%s" (car x))))
6103 qh-list "")
6104 "]"))
6105 ;; In the help string, we need to wrap lines...
6106 (setq reftex-type-query-help
6107 (concat
6108 "SELECT A LABEL TYPE:\n--------------------\n"
6109 (mapconcat
6110 (lambda(x)
6111 (setq sum 0)
6112 (format " [%s] %s"
6113 (car x)
6114 (mapconcat (lambda(env)
6115 (setq sum (+ sum (length env)))
6116 (if (< sum 60)
6117 env
6118 (setq sum 0)
6119 (concat "\n " env)))
6120 (cdr x) " ")))
6121 qh-list "\n")))
6122
6123 ;; Convert magic words to regular expressions. We make regular expressions
6124 ;; which allow for some chars from the ref format to be in the buffer.
6125 ;; These characters will be seen and removed.
6126 (setq reftex-words-to-typekey-alist
6127 (mapcar
6128 (lambda (x)
6129 (setq word (car x)
6130 typekey (cdr x)
6131 fmt (cdr (assoc typekey reftex-typekey-to-format-alist)))
6132 (setq word (concat "\\W\\(" word "[ \t\n\r]*\\)\\("))
6133 (setq i 0)
6134 (while (and (< i 10) ; maximum number of format chars allowed
6135 (< i (length fmt))
6136 (not (member (aref fmt i) '(?%))))
6137 (setq word (concat word "\\|" (regexp-quote
6138 (substring fmt 0 (1+ i)))))
6139 (incf i))
6140 (cons (concat word "\\)\\=") typekey))
6141 (nreverse reftex-words-to-typekey-alist)))
396e0b08 6142
b849548d
CD
6143 ;; Make the full list of section levels
6144 (setq reftex-section-levels-all
6145 (append (get reftex-docstruct-symbol 'reftex-section-levels)
6146 reftex-section-levels))
396e0b08 6147
b849548d
CD
6148 ;; Calculate the regular expressions
6149 (let* ((wbol "\\(\\`\\|[\n\r]\\)[ \t]*")
6150 (label-re "\\\\label{\\([^}]*\\)}")
6151 (include-re (concat wbol "\\\\\\(include\\|input\\)[{ \t]+\\([^} \t\n\r]+\\)"))
6152 (section-re
6153 (concat wbol "\\\\\\("
6154 (mapconcat 'car reftex-section-levels-all "\\|")
6155 "\\)\\*?\\(\\[[^]]*\\]\\)?{"))
6156 (appendix-re (concat wbol "\\(\\\\appendix\\)"))
6157 (macro-re
6158 (if macros-with-labels
6159 (concat "\\("
6160 (mapconcat 'regexp-quote macros-with-labels "\\|")
6161 "\\)[[{]")
6162 ""))
6163 (find-label-re-format
6164 (concat "\\("
6165 (mapconcat 'regexp-quote (append '("\\label")
6166 macros-with-labels) "\\|")
6167 "\\)\\([[{][^]}]*[]}]\\)*[[{]\\(%s\\)[]}]")))
6168 (setq reftex-section-regexp section-re
6169 reftex-section-or-include-regexp
6170 (concat section-re "\\|" include-re)
6171 reftex-everything-regexp
6172 (concat label-re "\\|" section-re "\\|" include-re
6173 "\\|" appendix-re
6174 (if macros-with-labels "\\|" "") macro-re)
6175 reftex-find-label-regexp-format find-label-re-format
6176 reftex-find-label-regexp-format2
6177 "\\([]} \t\n\r]\\)\\([[{]\\)\\(%s\\)[]}]")
6178 (message "Compiling label environment definitions...done")))
6179 (put reftex-docstruct-symbol 'reftex-cache
6180 (mapcar 'symbol-value reftex-cache-variables)))
396e0b08 6181
b849548d
CD
6182;;; =========================================================================
6183;;;
6184;;; Operations on entire Multifile documents
396e0b08 6185
b849548d
CD
6186(defun reftex-create-tags-file ()
6187 "Create TAGS file by running `etags' on the current document.
6188The TAGS file is also immediately visited with `visit-tags-table'."
6189 (interactive)
6190 (reftex-access-scan-info current-prefix-arg)
6191 (let* ((master (reftex-TeX-master-file))
6192 (files (reftex-all-document-files))
6193 (cmd (format "etags %s" (mapconcat 'identity files " "))))
6194 (save-excursion
6195 (set-buffer (reftex-get-buffer-visiting master))
6196 (message "Running etags to create TAGS file...")
6197 (shell-command cmd)
6198 (visit-tags-table "TAGS"))))
a7ec1775 6199
b849548d
CD
6200;; History of grep commands.
6201(defvar reftex-grep-history nil)
6202(defvar reftex-grep-command "grep -n "
6203 "Last grep command used in \\[reftex-grep-document]; default for next grep.")
a7ec1775 6204
b849548d
CD
6205(defun reftex-grep-document (grep-cmd)
6206 "Run grep query through all files related to this document.
6207With prefix arg, force to rescan document.
a6611c0d 6208No active TAGS table is required."
a7ec1775 6209
b849548d
CD
6210 (interactive
6211 (list (read-from-minibuffer "Run grep on document (like this): "
6212 reftex-grep-command nil nil
6213 'reftex-grep-history)))
6214 (reftex-access-scan-info current-prefix-arg)
6215 (let* ((files (reftex-all-document-files t))
6216 (cmd (format
6217 "%s %s" grep-cmd
6218 (mapconcat 'identity files " "))))
6219 (grep cmd)))
396e0b08 6220
b849548d
CD
6221(defun reftex-search-document (&optional regexp)
6222 "Regexp search through all files of the current TeX document.
6223Starts always in the master file. Stops when a match is found.
6224To continue searching for next match, use command \\[tags-loop-continue].
a6611c0d 6225No active TAGS table is required."
b849548d
CD
6226 (interactive)
6227 (let ((default (reftex-this-word)))
6228 (unless regexp
6229 (setq regexp (read-string (format "Search regexp in document [%s]: "
6230 default))))
6231 (if (string= regexp "") (setq regexp (regexp-quote default)))
a7ec1775 6232
b849548d
CD
6233 (reftex-access-scan-info current-prefix-arg)
6234 (tags-search regexp (list 'reftex-all-document-files))))
2faef409 6235
b849548d
CD
6236(defun reftex-query-replace-document (&optional from to delimited)
6237 "Run a query-replace-regexp of FROM with TO over the entire TeX document.
6238Third arg DELIMITED (prefix arg) means replace only word-delimited matches.
6239If you exit (\\[keyboard-quit] or ESC), you can resume the query replace
6240with the command \\[tags-loop-continue].
a6611c0d 6241No active TAGS table is required."
b849548d
CD
6242 (interactive)
6243 (let ((default (reftex-this-word)))
6244 (unless from
6245 (setq from (read-string (format "Replace regexp in document [%s]: "
6246 default)))
6247 (if (string= from "") (setq from (regexp-quote default))))
6248 (unless to
6249 (setq to (read-string (format "Replace regexp %s with: " from))))
6250 (reftex-access-scan-info current-prefix-arg)
6251 (tags-query-replace from to (or delimited current-prefix-arg)
6252 (list 'reftex-all-document-files))))
2faef409 6253
b849548d
CD
6254(defun reftex-find-duplicate-labels ()
6255 "Produce a list of all duplicate labels in the document."
a7ec1775 6256
b849548d 6257 (interactive)
a7ec1775 6258
b849548d
CD
6259 ;; Rescan the document to make sure
6260 (reftex-access-scan-info t)
a7ec1775 6261
b849548d
CD
6262 (let ((master (reftex-TeX-master-file))
6263 (cnt 0)
6264 (dlist
6265 (mapcar
6266 (function
6267 (lambda (x)
6268 (let (x1)
6269 (cond
6270 ((memq (car x)
6271 '(toc bof eof bib thebib label-numbers xr xr-doc
6272 master-dir file-error bibview-cache appendix
6273 is-multi))
6274 nil)
6275 (t
6276 (setq x1 (reftex-all-assoc-string
6277 (car x) (symbol-value reftex-docstruct-symbol)))
6278 (if (< 1 (length x1))
6279 (append (list (car x))
6280 (mapcar (function
6281 (lambda(x)
6282 (abbreviate-file-name (nth 3 x))))
6283 x1))
6284 (list nil)))))))
6285 (reftex-uniquify-by-car (symbol-value reftex-docstruct-symbol)))))
a7ec1775 6286
b849548d
CD
6287 (setq dlist (reftex-uniquify-by-car dlist))
6288 (if (null dlist) (error "No duplicate labels in document"))
6289 (switch-to-buffer-other-window "*Duplicate Labels*")
6290 (make-local-variable 'TeX-master)
6291 (setq TeX-master master)
6292 (erase-buffer)
6293 (insert " MULTIPLE LABELS IN CURRENT DOCUMENT:\n")
6294 (insert
6295 " Move point to label and type `r' to run a query-replace on the label\n"
6296 " and its references. Type `q' to exit this buffer.\n\n")
6297 (insert " LABEL FILE\n")
6298 (insert " -------------------------------------------------------------\n")
6299 (use-local-map (make-sparse-keymap))
6300 (local-set-key [?q] (function
6301 (lambda () "Kill this buffer." (interactive)
6302 (kill-buffer (current-buffer)) (delete-window))))
6303 (local-set-key [?r] 'reftex-change-label)
6304 (while dlist
6305 (when (and (car (car dlist))
6306 (cdr (car dlist)))
6307 (incf cnt)
6308 (insert (mapconcat 'identity (car dlist) "\n ") "\n"))
6309 (pop dlist))
6310 (goto-char (point-min))
6311 (when (= cnt 0)
6312 (kill-buffer (current-buffer))
6313 (delete-window)
6314 (message "Document does not contain duplicate labels."))))
a7ec1775 6315
b849548d
CD
6316(defun reftex-change-label (&optional from to)
6317 "Query replace FROM with TO in all \\label and \\ref commands.
6318Works on the entire multifile document.
6319If you exit (\\[keyboard-quit] or ESC), you can resume the query replace
6320with the command \\[tags-loop-continue].
a6611c0d 6321No active TAGS table is required."
b849548d
CD
6322 (interactive)
6323 (let ((default (reftex-this-word "-a-zA-Z0-9_*.:")))
6324 (unless from
6325 (setq from (read-string (format "Replace label globally [%s]: "
6326 default))))
6327 (if (string= from "") (setq from default))
6328 (unless to
6329 (setq to (read-string (format "Replace label %s with: "
6330 from))))
6331 (reftex-query-replace-document
6332 (concat "\\\\\\(label\\|[a-z]*ref\\){" (regexp-quote from) "}")
6333 (format "\\\\\\1{%s}" to))))
a7ec1775 6334
b849548d
CD
6335(defun reftex-renumber-simple-labels ()
6336 "Renumber all simple labels in the document to make them sequentially.
6337Simple labels are the ones created by RefTeX, consisting only of the
6338prefix and a number. After the command completes, all these labels will
6339have sequential numbers throughout the document. Any references to
6340the labels will be changed as well. For this, RefTeX looks at the
6341arguments of any macros which either start or end in the string `ref'.
6342This command should be used with care, in particular in multifile
6343documents. You should not use it if another document refers to this
6344one with the `xr' package."
a7ec1775 6345 (interactive)
b849548d
CD
6346 ;; Resan the entire document
6347 (reftex-access-scan-info 1)
6348 ;; Get some insurance
6349 (if (and (reftex-is-multi)
6350 (not (yes-or-no-p "Replacing all simple labels in multiple files is risky. Continue? ")))
6351 (error "Abort"))
6352 ;; Make the translation list
6353 (let* ((re-core (concat "\\("
6354 (mapconcat 'cdr reftex-typekey-to-prefix-alist "\\|")
6355 "\\)"))
6356 (label-re (concat "\\`" re-core "\\([0-9]+\\)\\'"))
6357 (search-re (concat "{\\(" re-core "\\([0-9]+\\)\\)}"))
6358 (error-fmt "Undefined label or reference %s. Ignore and continue? ")
6359 (label-numbers-alist (mapcar (lambda (x) (cons (cdr x) 0))
6360 reftex-typekey-to-prefix-alist))
6361 (files (reftex-all-document-files))
6362 (list (symbol-value reftex-docstruct-symbol))
6363 translate-alist n entry label new-label nr-cell changed-sequence)
6364
6365 (while (setq entry (pop list))
6366 (when (and (stringp (car entry))
6367 (string-match label-re (car entry)))
6368 (setq label (car entry)
6369 nr-cell (assoc (match-string 1 (car entry))
6370 label-numbers-alist))
6371 (if (assoc label translate-alist)
6372 (error "Duplicate label %s" label))
6373 (setq new-label (concat (match-string 1 (car entry))
6374 (incf (cdr nr-cell))))
6375 (push (cons label new-label) translate-alist)
6376 (or (string= label new-label) (setq changed-sequence t))))
6377
6378 (unless changed-sequence
6379 (error "Simple labels are already in correct sequence"))
6380
6381 ;; Save all document buffers before this operation
6382 (reftex-save-all-document-buffers)
6383
6384 ;; First test to check for erros
6385 (setq n (reftex-translate
6386 files search-re translate-alist error-fmt 'test))
6387
6388 ;; Now the real thing.
6389 (if (yes-or-no-p
6390 (format "Replace %d items at %d places in %d files? "
6391 (length translate-alist) n (length files)))
6392 (progn
6393 (let ((inhibit-quit t)) ;; Do not disturb...
6394 (reftex-translate
6395 files search-re translate-alist error-fmt nil)
6396 (setq quit-flag nil))
6397 (if (and (reftex-is-multi)
6398 (yes-or-no-p "Save entire document? "))
6399 (reftex-save-all-document-buffers))
6400 ;; Rescan again...
6401 (reftex-access-scan-info 1)
6402 (message "Done replacing simple labels."))
6403 (message "No replacements done"))))
6404
6405(defun reftex-translate (files search-re translate-alist error-fmt test)
6406 ;; In FILES, look for SEARCH-RE and replace match 1 of it with
6407 ;; its association in TRANSLATE-ALSIT.
6408 ;; If we do not find an association and TEST is non-nil, query
6409 ;; to ignore the problematic string.
6410 ;; If TEST is nil, it is ignored without query.
6411 ;; Return the number of replacements.
6412 (let ((n 0) file label match-data buf macro pos cell)
6413 (while (setq file (pop files))
6414 (setq buf (reftex-get-file-buffer-force file))
6415 (unless buf
6416 (error "No such file %s" file))
6417 (set-buffer buf)
6418 (save-excursion
6419 (save-restriction
6420 (widen)
6421 (goto-char (point-min))
6422 (while (re-search-forward search-re nil t)
6423 (save-excursion
6424 (backward-char)
6425 (setq label (reftex-match-string 1)
6426 cell (assoc label translate-alist)
6427 match-data (match-data)
6428 macro (reftex-what-macro 1)
6429 pos (cdr macro))
6430 (goto-char (or pos (point)))
6431 (when (and macro
6432 (or (looking-at "\\\\ref")
6433 (looking-at "\\\\[a-zA-Z]*ref[^a-zA-Z]")
6434 (looking-at "\\\\ref[a-zA-Z]*[^a-zA-Z]")
6435 (looking-at (format
6436 reftex-find-label-regexp-format
6437 (regexp-quote label)))))
6438 ;; OK, we should replace it.
6439 (set-match-data match-data)
6440 (cond
6441 ((and test (not cell))
6442 ;; We've got a problem
6443 (unwind-protect
6444 (progn
6445 (reftex-highlight 1 (match-beginning 0) (match-end 0))
6446 (ding)
6447 (or (y-or-n-p (format error-fmt label))
6448 (error "Abort")))
6449 (reftex-unhighlight 1)))
6450 ((and test cell)
6451 (incf n))
6452 ((and (not test) cell)
6453 ;; Replace
6454 (goto-char (match-beginning 1))
6455 (delete-region (match-beginning 1) (match-end 1))
6456 (insert (cdr cell)))
6457 (t nil))))))))
6458 n))
a7ec1775 6459
b849548d
CD
6460(defun reftex-save-all-document-buffers ()
6461 "Save all documents associated with the current document.
6462The function is useful after a global action like replacing or renumbering
6463labels."
6464 (interactive)
6465 (let ((files (reftex-all-document-files))
6466 file buffer)
6467 (save-excursion
6468 (while (setq file (pop files))
6469 (setq buffer (reftex-get-buffer-visiting file))
6470 (when buffer
6471 (set-buffer buffer)
6472 (save-buffer))))))
c52bdfca 6473
b849548d
CD
6474;;; =========================================================================
6475;;;
6476;;; AUCTeX Interface
a7ec1775 6477
b849548d
CD
6478(defun reftex-plug-flag (which)
6479 ;; Tell if a certain flag is set in reftex-plug-into-AUCTeX
6480 (or (eq t reftex-plug-into-AUCTeX)
6481 (and (listp reftex-plug-into-AUCTeX)
6482 (nth which reftex-plug-into-AUCTeX))))
a7ec1775 6483
b849548d
CD
6484(defun reftex-arg-label (optional &optional prompt definition)
6485 "Use `reftex-label', `reftex-reference' or AUCTeX's code to insert label arg.
6486What is being used depends upon `reftex-plug-into-AUCTeX'."
6487 (let (label)
6488 (cond
6489 ((and definition (reftex-plug-flag 1))
6490 ;; Create a new label, with a temporary brace for `reftex-what-macro'
6491 (unwind-protect
6492 (progn (insert "{") (setq label (or (reftex-label nil t) "")))
6493 (delete-backward-char 1)))
6494 ((and (not definition) (reftex-plug-flag 2))
6495 ;; Reference a label with RefTeX
6496 (setq label (reftex-reference nil t)))
6497 (t
6498 ;; AUCTeX's default mechanism
6499 (setq label (completing-read (TeX-argument-prompt optional prompt "Key")
6500 (LaTeX-label-list)))))
6501 (if (and definition (not (string-equal "" label)))
6502 (LaTeX-add-labels label))
6503 (TeX-argument-insert label optional optional)))
2faef409 6504
b849548d
CD
6505(defun reftex-arg-cite (optional &optional prompt definition)
6506 "Use `reftex-citation' or AUCTeX's code to insert a cite-key macro argument.
6507What is being used depends upon `reftex-plug-into-AUCTeX'."
6508 (let (items)
6509 (cond
6510 ((and (not definition) (reftex-plug-flag 3))
6511 (setq items (list (or (reftex-citation t) ""))))
6512 (t
6513 (setq prompt (concat (if optional "(Optional) " "")
6514 (if prompt prompt "Add key")
6515 ": (default none) "))
6516 (setq items (multi-prompt "," t prompt (LaTeX-bibitem-list)))))
6517 (apply 'LaTeX-add-bibitems items)
6518 (TeX-argument-insert (mapconcat 'identity items ",") optional optional)))
a7ec1775 6519
b849548d
CD
6520(defun reftex-plug-into-AUCTeX ()
6521 ;; Replace AUCTeX functions with RefTeX functions.
6522 ;; Which functions are replaced is controlled by the variable
6523 ;; `reftex-plug-into-AUCTeX'.
6524
6525 (if (reftex-plug-flag 0)
6526 (setq LaTeX-label-function 'reftex-label)
6527 (setq LaTeX-label-function nil))
a7ec1775 6528
b849548d
CD
6529 (if (and (or (reftex-plug-flag 1) (reftex-plug-flag 2))
6530 (fboundp 'TeX-arg-label))
6531 (fset 'TeX-arg-label 'reftex-arg-label))
a7ec1775 6532
b849548d
CD
6533 (if (and (reftex-plug-flag 3)
6534 (fboundp 'TeX-arg-cite))
6535 (fset 'TeX-arg-cite 'reftex-arg-cite)))
396e0b08 6536
b849548d
CD
6537(defun reftex-toggle-plug-into-AUCTeX ()
6538 "Toggle Interface between AUCTeX and RefTeX on and off."
6539 (interactive)
6540 (unless (and (featurep 'tex-site) (featurep 'latex))
6541 (error "AUCTeX's LaTeX mode does not seem to be loaded."))
6542 (setq reftex-plug-into-AUCTeX (not reftex-plug-into-AUCTeX))
6543 (reftex-plug-into-AUCTeX)
6544 (if reftex-plug-into-AUCTeX
6545 (message "RefTeX has been plugged into AUCTeX.")
6546 (message "RefTeX no longer interacts with AUCTeX.")))
a7ec1775 6547
b849548d
CD
6548(defun reftex-add-label-environments (entry-list)
6549 "Add label environment descriptions to `reftex-label-alist-style'.
6550The format of ENTRY-LIST is exactly like `reftex-label-alist'. See there
6551for details.
6552This function makes it possible to support RefTeX from AUCTeX style files.
6553The entries in ENTRY-LIST will be processed after the user settings in
6554`reftex-label-alist', and before the defaults (specified in
6555`reftex-default-label-alist-entries'). Any changes made to
6556`reftex-label-alist-style' will raise a flag to the effect that
6557the label information is recompiled on next use."
6558 (unless reftex-docstruct-symbol
6559 (reftex-tie-multifile-symbols))
6560 (when (and reftex-docstruct-symbol
6561 (symbolp reftex-docstruct-symbol))
6562 (let ((list (get reftex-docstruct-symbol 'reftex-label-alist-style))
6563 entry changed)
6564 (while entry-list
6565 (setq entry (pop entry-list))
6566 (unless (member entry list)
6567 (setq reftex-tables-dirty t
6568 changed t)
6569 (push entry list)))
6570 (when changed
6571 (put reftex-docstruct-symbol 'reftex-label-alist-style list)))))
6572(defalias 'reftex-add-to-label-alist 'reftex-add-label-environments)
6573
6574(defun reftex-add-section-levels (entry-list)
6575 "Add entries to the value of `reftex-section-levels'.
6576The added values are kept local to the current document. The format
6577of ENTRY-LIST is a list of cons cells (\"MACRONAME\" . LEVEL). See
6578`reftex-section-levels' for an example."
6579 (unless reftex-docstruct-symbol
6580 (reftex-tie-multifile-symbols))
6581 (when (and reftex-docstruct-symbol
6582 (symbolp reftex-docstruct-symbol))
6583 (let ((list (get reftex-docstruct-symbol 'reftex-section-levels))
6584 entry changed)
6585 (while entry-list
6586 (setq entry (pop entry-list))
6587 (unless (member entry list)
6588 (setq reftex-tables-dirty t
6589 changed t)
6590 (push entry list)))
6591 (when changed
6592 (put reftex-docstruct-symbol 'reftex-section-levels list)))))
6593
6594(defun reftex-set-cite-format (value)
6595 "Set the document-local value of `reftex-cite-format'.
6596When such a value exists, it overwrites the setting given with
6597`reftex-cite-format'. See the documentation of `reftex-cite-format'
6598for possible values. This function should be used from AUCTeX style files."
6599 (unless reftex-docstruct-symbol
6600 (reftex-tie-multifile-symbols))
6601 (when (and reftex-docstruct-symbol
6602 (symbolp reftex-docstruct-symbol))
6603 (put reftex-docstruct-symbol 'reftex-cite-format value)))
6604
6605(defun reftex-notice-new-section ()
6606 "Hook to handshake with RefTeX after a new section has been inserted."
6607 ;; Add a new section to the docstruct list and renumber the
6608 ;; following sections. This hook has to be called immediately after
6609 ;; the new section was inserted into the buffer, and before the
6610 ;; section label is created.
2faef409 6611
b849548d
CD
6612 (condition-case nil
6613 (catch 'exit
6614 (unless reftex-mode (throw 'exit nil))
6615 (reftex-access-scan-info)
6616 (let* ((docstruct (symbol-value reftex-docstruct-symbol))
6617 here-am-I appendix tail toc-entry star level
6618 section-number context)
a7ec1775 6619
b849548d
CD
6620 (save-excursion
6621 (when (re-search-backward reftex-section-regexp nil t)
6622
6623 ;; Find where we are
6624 (setq here-am-I (reftex-where-am-I))
6625 (unless (cdr here-am-I) (throw 'exit nil))
6626 (setq reftex-active-toc (reftex-last-assoc-before-elt
6627 'toc (car here-am-I) docstruct)
6628 appendix (reftex-last-assoc-before-elt
6629 'appendix (car here-am-I) docstruct))
6630
6631 ;; Initialize section numbers
6632 (if (eq (car (car here-am-I)) 'appendix)
6633 (reftex-init-section-numbers nil t)
6634 (reftex-init-section-numbers reftex-active-toc appendix))
6635
6636 ;; Match the section command
6637 (when (and (re-search-forward reftex-everything-regexp nil t)
6638 (match-end 3))
6639 (setq star (= ?* (char-after (match-end 3)))
6640 toc-entry (reftex-section-info (buffer-file-name))
6641 level (nth 5 toc-entry)
6642 tail (memq (car here-am-I)
6643 (symbol-value reftex-docstruct-symbol)))
6644 (if tail
6645 ;; Insert the section info
6646 (push toc-entry (cdr tail))
6647 (throw 'exit nil))
6648
6649 ;; We are done unless we use section numbers
6650 (unless (nth 1 reftex-label-menu-flags) (throw 'exit nil))
6651
6652 ;; Update the remaining toc items
6653 (setq tail (cdr tail))
6654 (while (and (setq tail (memq (assq 'toc (cdr tail)) tail))
6655 (setq toc-entry (car tail))
6656 (>= (nth 5 toc-entry) level))
6657 (setq section-number
6658 (reftex-section-number (nth 5 toc-entry) star)
6659 context (nth 2 toc-entry))
6660 (when (string-match "\\`\\([ \t]*\\)\\([.0-9A-Z]+\\)\\(.*\\)"
6661 context)
6662 (when (and (not appendix)
6663 (>= (string-to-char (match-string 2)) ?A))
6664 ;; Just entered the appendex. Get out.
6665 (throw 'exit nil))
6666
6667 ;; Change the section number.
6668 (setf (nth 2 toc-entry)
6669 (concat (match-string 1 context)
6670 section-number
6671 (match-string 3 context))))))))))
6672 (error nil))
6673 )
6674
6675;;; =========================================================================
6676;;;
6677;;; Keybindings
a7ec1775 6678
b849548d
CD
6679;; The default bindings in the mode map.
6680(loop for x in
6681 '(("\C-c=" . reftex-toc)
6682 ("\C-c(" . reftex-label)
6683 ("\C-c)" . reftex-reference)
6684 ("\C-c[" . reftex-citation)
6685 ("\C-c&" . reftex-view-crossref))
6686 do (define-key reftex-mode-map (car x) (cdr x)))
a7ec1775 6687
1c0dde84 6688;; Bind `reftex-mouse-view-crossref' only when the key is still free
b849548d 6689(if (featurep 'xemacs)
1c0dde84
CD
6690 (unless (key-binding [(shift button2)])
6691 (define-key reftex-mode-map [(shift button2)]
6692 'reftex-mouse-view-crossref))
6693 (unless (key-binding [(shift mouse-2)])
6694 (define-key reftex-mode-map [(shift mouse-2)]
6695 'reftex-mouse-view-crossref)))
6696
a7ec1775 6697;; If the user requests so, she can have a few more bindings:
b849548d
CD
6698(when reftex-extra-bindings
6699 (loop for x in
6700 '(("\C-ct" . reftex-toc)
6701 ("\C-cl" . reftex-label)
6702 ("\C-cr" . reftex-reference)
6703 ("\C-cc" . reftex-citation)
6704 ("\C-cv" . reftex-view-crossref)
6705 ("\C-cg" . reftex-grep-document)
6706 ("\C-cs" . reftex-search-document))
6707 do (define-key reftex-mode-map (car x) (cdr x))))
6708
6709;; Common bindings in reftex-select-label-map and reftex-select-bib-map
2faef409 6710(let ((map (make-sparse-keymap)))
2faef409
RS
6711 (substitute-key-definition
6712 'next-line 'reftex-select-next map global-map)
6713 (substitute-key-definition
6714 'previous-line 'reftex-select-previous map global-map)
6715 (substitute-key-definition
29d593f8 6716 'keyboard-quit 'reftex-select-keyboard-quit map global-map)
2faef409
RS
6717 (substitute-key-definition
6718 'newline 'reftex-select-accept map global-map)
29d593f8 6719
b849548d
CD
6720 (loop for x in
6721 '((" " . reftex-select-callback)
6722 ("n" . reftex-select-next)
6723 ([(down)] . reftex-select-next)
6724 ("p" . reftex-select-previous)
6725 ([(up)] . reftex-select-previous)
6726 ("f" . reftex-select-toggle-follow)
6727 ("\C-m" . reftex-select-accept)
6728 ([(return)] . reftex-select-accept)
6729 ("q" . reftex-select-quit)
6730 ("." . reftex-select-show-insertion-point)
6731 ("?" . reftex-select-help))
6732 do (define-key map (car x) (cdr x)))
6733
6734 ;; The mouse-2 binding
6735 (if (featurep 'xemacs)
6736 (define-key map [(button2)] 'reftex-select-mouse-accept)
6737 (define-key map [(mouse-2)] 'reftex-select-mouse-accept))
6738
6739 ;; Digit arguments
29d593f8
KH
6740 (loop for key across "0123456789" do
6741 (define-key map (vector (list key)) 'digit-argument))
6742 (define-key map "-" 'negative-argument)
2faef409 6743
b849548d 6744 ;; Make two maps
2faef409 6745 (setq reftex-select-label-map map)
b849548d
CD
6746 (setq reftex-select-bib-map (copy-keymap map)))
6747
6748;; Specific bindings in reftex-select-label-map
6749(loop for key across "cgilrRstx#%" do
6750 (define-key reftex-select-label-map (vector (list key))
6751 (list 'lambda '()
6752 "Press `?' during selection to find out about this key."
6753 '(interactive) (list 'throw '(quote myexit) key))))
6754
6755(loop for x in
6756 '(("b" . reftex-select-jump-to-previous)
6757 ("v" . reftex-select-toggle-varioref)
6758 ([(tab)] . reftex-select-read-label)
6759 ("\C-i" . reftex-select-read-label)
6760 ("\C-c\C-n" . reftex-select-next-heading)
6761 ("\C-c\C-p" . reftex-select-previous-heading))
6762 do
6763 (define-key reftex-select-label-map (car x) (cdr x)))
6764
6765;; Specific bindings in reftex-select-bib-map
6766(loop for key across "grRaA" do
6767 (define-key reftex-select-bib-map (vector (list key))
6768 (list 'lambda '()
6769 "Press `?' during selection to find out about this key."
6770 '(interactive) (list 'throw '(quote myexit) key))))
6771
6772(loop for x in
6773 '(("\C-i" . reftex-select-read-cite)
6774 ([(tab)] . reftex-select-read-cite))
6775 do (define-key reftex-select-bib-map (car x) (cdr x)))
6776
2faef409 6777;; Table of Contents map
b849548d
CD
6778(if (featurep 'xemacs)
6779 (define-key reftex-toc-map [(button2)] 'reftex-toc-mouse-goto-line-and-hide)
6780 (define-key reftex-toc-map [(mouse-2)] 'reftex-toc-mouse-goto-line-and-hide))
6781
6782(loop for x in
6783 '(("n" . next-line)
6784 ("p" . previous-line)
6785 ("?" . reftex-toc-show-help)
6786 (" " . reftex-toc-view-line)
6787 ("\C-m" . reftex-toc-goto-line-and-hide)
6788 ("\C-i" . reftex-toc-goto-line)
6789 ("r" . reftex-toc-rescan)
6790 ("R" . reftex-toc-Rescan)
6791 ("g" . revert-buffer)
6792 ("q" . reftex-toc-quit)
6793 ("Q" . reftex-toc-quit-and-kill)
6794 ("f" . reftex-toc-toggle-follow)
6795 ("x" . reftex-toc-external)
6796 ("." . reftex-toc-show-insertion-point))
6797 do (define-key reftex-toc-map (car x) (cdr x)))
6798
6799(loop for key across "0123456789" do
6800 (define-key reftex-toc-map (vector (list key)) 'digit-argument))
6801(define-key reftex-toc-map "-" 'negative-argument)
2faef409 6802
b849548d
CD
6803;;; =========================================================================
6804;;;
6805;;; Menu
a7ec1775
RS
6806
6807;; Define a menu for the menu bar if Emacs is running under X
6808
6809(require 'easymenu)
6810
396e0b08 6811(easy-menu-define
a7ec1775
RS
6812 reftex-mode-menu reftex-mode-map
6813 "Menu used in RefTeX mode"
396e0b08 6814 `("Ref"
206c6f82 6815 ["Table of Contents" reftex-toc t]
b849548d 6816 "---"
206c6f82
RS
6817 ["\\label" reftex-label t]
6818 ["\\ref" reftex-reference t]
6819 ["\\cite" reftex-citation t]
396e0b08 6820 ["View Crossref" reftex-view-crossref t]
b849548d 6821 "---"
396e0b08
KH
6822 ("Parse Document"
6823 ["Only this File" reftex-parse-one t]
6824 ["Entire Document" reftex-parse-all (reftex-is-multi)]
baec1250 6825 ["Save to File" (reftex-access-parse-file 'write)
396e0b08 6826 (> (length (symbol-value reftex-docstruct-symbol)) 0)]
2faef409 6827 ["Restore from File" (reftex-access-parse-file 'restore) t]
396e0b08
KH
6828 "---"
6829 ["Reset RefTeX Mode" reftex-reset-mode t])
2faef409 6830 ("Global Actions"
baec1250
KH
6831 ["Search Whole Document" reftex-search-document t]
6832 ["Replace in Document" reftex-query-replace-document t]
6833 ["Grep on Document" reftex-grep-document t]
b849548d 6834 "---"
baec1250 6835 ["Create TAGS File" reftex-create-tags-file t]
b849548d 6836 "---"
baec1250 6837 ["Find Duplicate Labels" reftex-find-duplicate-labels t]
2faef409 6838 ["Change Label and Refs" reftex-change-label t]
b849548d 6839 ["Renumber Simple Labels" reftex-renumber-simple-labels t]
2faef409
RS
6840 "---"
6841 ["Save document" reftex-save-all-document-buffers t])
6842 "---"
b849548d
CD
6843 ("Options"
6844 ("Table of Contents"
6845 ["Follow Mode" (setq reftex-toc-follow-mode (not reftex-toc-follow-mode))
6846 :style toggle :selected reftex-toc-follow-mode]
6847 ["Follow Mode may visit files"
6848 (setq reftex-revisit-to-follow (not reftex-revisit-to-follow))
6849 :style toggle :selected reftex-revisit-to-follow])
6850 ("References"
6851 ["Guess Label Type"
6852 (setq reftex-guess-label-type (not reftex-guess-label-type))
6853 :style toggle :selected reftex-guess-label-type]
6854 ["Use `\\vref' by Default"
6855 (setq reftex-vref-is-default (not reftex-vref-is-default))
6856 :style toggle :selected reftex-vref-is-default]
6857 "---"
6858 "Selection Buffers"
6859 ["Use Multiple Buffers"
6860 (setq reftex-use-multiple-selection-buffers
6861 (not reftex-use-multiple-selection-buffers))
6862 :style toggle :selected reftex-use-multiple-selection-buffers]
6863 ["Auto Update Buffers"
6864 (setq reftex-auto-update-selection-buffers
6865 (not reftex-auto-update-selection-buffers))
6866 :style toggle :selected reftex-auto-update-selection-buffers])
6867 ("Citations"
6868 "Citation Style"
6869 ,@(mapcar
6870 (function
6871 (lambda (x)
6872 (vector
6873 (capitalize (symbol-name (car x)))
6874 (list 'reftex-set-cite-format (list 'quote (car x)))
6875 ':style 'radio ':selected
6876 (list 'eq (list 'reftex-get-cite-format) (list 'quote (car x))))))
baec1250 6877 reftex-cite-format-builtin)
b849548d
CD
6878 "---"
6879 "Bibinfo in Comments"
6880 ["Attach Comments"
6881 (setq reftex-comment-citations (not reftex-comment-citations))
6882 :style toggle :selected reftex-comment-citations]
6883 "---"
6884 "Sort Database Matches"
6885 ["by Author" (setq reftex-sort-bibtex-matches 'author)
6886 :style radio :selected (eq reftex-sort-bibtex-matches 'author)]
6887 ["by Year" (setq reftex-sort-bibtex-matches 'year)
6888 :style radio :selected (eq reftex-sort-bibtex-matches 'year)]
6889 ["by Year, reversed" (setq reftex-sort-bibtex-matches 'reverse-year)
6890 :style radio :selected (eq reftex-sort-bibtex-matches 'reverse-year)]
6891 ["Not" (setq reftex-sort-bibtex-matches nil)
6892 :style radio :selected (eq reftex-sort-bibtex-matches nil)])
6893 ("Crossref Viewing"
a6611c0d 6894 ["Automatic Info" reftex-toggle-auto-view-crossref
b849548d 6895 :style toggle :selected reftex-auto-view-crossref-timer]
a6611c0d
CD
6896 ["...in Echo Area" (setq reftex-auto-view-crossref t)
6897 :style radio :selected (eq reftex-auto-view-crossref t)]
6898 ["...in Other Window" (setq reftex-auto-view-crossref 'window)
6899 :style radio :selected (eq reftex-auto-view-crossref 'window)]
6900 "---"
b849548d
CD
6901 ["Crossref Echo may visit files"
6902 (setq reftex-revisit-to-echo (not reftex-revisit-to-echo))
6903 :style toggle :selected reftex-revisit-to-echo]
6904 ["Cache Echo strings for \cite"
6905 (setq reftex-cache-cite-echo (not reftex-cache-cite-echo))
6906 :style toggle :selected reftex-cache-cite-echo])
6907 ("Parser"
6908 "Document Scans"
6909 ["Partial Scans"
6910 (setq reftex-enable-partial-scans (not reftex-enable-partial-scans))
6911 :style toggle :selected reftex-enable-partial-scans]
6912 ["Auto-Save Parse Info"
6913 (setq reftex-save-parse-info (not reftex-save-parse-info))
6914 :style toggle :selected reftex-save-parse-info]
6915 ["Automatic Rescans"
6916 (setq reftex-allow-automatic-rescan (not reftex-allow-automatic-rescan))
6917 :style toggle :selected reftex-allow-automatic-rescan]
6918 "---"
6919 "Temporary Buffers"
6920 ["Keep Buffers"
6921 (setq reftex-keep-temporary-buffers (not reftex-keep-temporary-buffers))
6922 :style toggle :selected reftex-keep-temporary-buffers]
6923 ["Initialize when Visiting"
6924 (setq reftex-initialize-temporary-buffers
6925 (not reftex-initialize-temporary-buffers))
6926 :style toggle :selected reftex-initialize-temporary-buffers])
6927 ("AUC TeX"
6928 ["Plug into AUC TeX" reftex-toggle-plug-into-AUCTeX
6929 :style toggle :selected reftex-plug-into-AUCTeX])
6930 ("Fontification"
6931 ["Use Fontification" (setq reftex-use-fonts (not reftex-use-fonts))
6932 :style toggle :selected reftex-use-fonts]
6933 ["Fontify Context Display" (setq reftex-refontify-context
6934 (not (reftex-refontify)))
6935 :style toggle :selected (reftex-refontify)]))
6936 ;;"---"
2faef409
RS
6937 ("Customize"
6938 ["Browse RefTeX group" reftex-customize t]
6939 "---"
6940 ["Build Full Customize Menu" reftex-create-customize-menu
6941 (fboundp 'customize-menu-create)])
b849548d 6942 "---"
2faef409
RS
6943 ("Documentation"
6944 ["Info" reftex-info t]
6945 ["Commentary" reftex-show-commentary t])))
a7ec1775 6946
b849548d
CD
6947(defun reftex-customize ()
6948 "Call the customize function with reftex as argument."
6949 (interactive)
6950 (customize-browse 'reftex))
6951
6952(defun reftex-create-customize-menu ()
6953 "Create a full customization menu for RefTeX, insert it into the menu."
6954 (interactive)
6955 (if (fboundp 'customize-menu-create)
6956 (progn
6957 (easy-menu-change
6958 '("Ref") "Customize"
6959 `(["Browse RefTeX group" reftex-customize t]
6960 "---"
6961 ,(customize-menu-create 'reftex)
6962 ["Set" Custom-set t]
6963 ["Save" Custom-save t]
6964 ["Reset to Current" Custom-reset-current t]
6965 ["Reset to Saved" Custom-reset-saved t]
6966 ["Reset to Standard Settings" Custom-reset-standard t]))
6967 (message "\"Ref\"-menu now contains full customization menu"))
6968 (error "Cannot expand menu (outdated version of cus-edit.el)")))
6969
6970(defun reftex-show-commentary ()
6971 "Use the finder to view the file documentation from `reftex.el'."
6972 (interactive)
6973 (require 'finder)
6974 (finder-commentary "reftex.el"))
6975
6976(defun reftex-info ()
6977 "Read documentation for RefTeX in the info system."
6978 (interactive)
6979 (require 'info)
6980 (Info-goto-node "(reftex)"))
6981
6982;; Support for \label and \ref --------------------------------------
6983
6984;;; Install the kill-buffer and kill-emacs hooks ------------------------------
6985
6986(add-hook 'kill-buffer-hook 'reftex-kill-buffer-hook)
6987(add-hook 'kill-emacs-hook 'reftex-kill-emacs-hook)
6988
6989;;; Install the idle timer if requested ---------------------------------------
6990
6991(and reftex-auto-view-crossref
6992 (not reftex-auto-view-crossref-timer)
6993 (reftex-toggle-auto-view-crossref))
6994
a7ec1775
RS
6995;;; Run Hook ------------------------------------------------------------------
6996
6997(run-hooks 'reftex-load-hook)
6998
6999;;; That's it! ----------------------------------------------------------------
7000
6b94c6ad 7001(setq reftex-tables-dirty t) ; in case this file is evaluated by hand
396e0b08
KH
7002(provide 'reftex)
7003
a7ec1775
RS
7004;;;============================================================================
7005
c52bdfca 7006;;; reftex.el ends here
b849548d 7007