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