]> code.delx.au - gnu-emacs/blob - lisp/textmodes/reftex.el
Comment fix.
[gnu-emacs] / lisp / textmodes / reftex.el
1 ;;; reftex.el --- Minor mode for doing \label, \ref and \cite in LaTeX
2 ;; Copyright (c) 1997, 1998 Free Software Foundation, Inc.
3
4 ;; Author: Carsten Dominik <dominik@strw.LeidenUniv.nl>
5 ;; Keywords: tex
6
7 ;; This file is part of GNU Emacs.
8
9 ;; GNU Emacs is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13
14 ;; GNU Emacs is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs; see the file COPYING. If not, write to the
21 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
23
24 ;;---------------------------------------------------------------------------
25 ;;
26 ;;; Commentary:
27 ;;
28 ;; RefTeX is a minor mode with distinct support for \ref, \label, and \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.
34 ;;
35 ;;
36 ;; INSTALLATION
37 ;; ------------
38 ;;
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.
44 ;;
45 ;; To turn RefTeX Mode on and off in a buffer, use `M-x reftex-mode'.
46 ;;
47 ;; To turn on RefTeX Mode for all LaTeX files, add the following lines
48 ;; to your .emacs file:
49 ;;
50 ;; (add-hook 'LaTeX-mode-hook 'turn-on-reftex) ; AUCTeX LaTeX mode
51 ;; (add-hook 'latex-mode-hook 'turn-on-reftex) ; Emacs latex mode
52 ;;
53 ;;
54 ;; DOCUMENTATION
55 ;; -------------
56 ;;
57 ;; See below for a short summary of how to use RefTeX.
58 ;;
59 ;; There is an extensive texinfo document describing RefTeX in detail.
60 ;; One way to view this documentation is `M-x reftex-info RET'.
61 ;;
62 ;; The documentation in various formats is also available at
63 ;;
64 ;; http://www.strw.leidenuniv.nl/~dominik/Tools/
65 ;;
66 ;;---------------------------------------------------------------------------
67 ;;
68 ;; RefTeX in a Nutshell
69 ;; ====================
70 ;;
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.
75 ;;
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
80 ;; have defined yourself (variable `reftex-label-alist').
81 ;;
82 ;; Creating Labels
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)
89 ;; This is configurable with the variable `reftex-insert-label-flags'.
90 ;;
91 ;; Referencing Labels
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.
96 ;;
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
103 ;; variable `reftex-cite-format').
104 ;;
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.
114 ;;
115 ;; 5. Multifile Documents
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').
119 ;;
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.
127 ;;
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)
135 ;;
136 ;;---------------------------------------------------------------------------
137 ;;
138 ;; AUTHOR
139 ;; ======
140 ;;
141 ;; Carsten Dominik <dominik@strw.LeidenUniv.nl>
142 ;;
143 ;; with contributions from Stephen Eglen
144 ;;
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
148 ;;
149 ;; http://www.strw.leidenuniv.nl/~dominik/Tools/
150 ;;
151 ;; THANKS TO:
152 ;; ---------
153 ;; Thanks to the people on the Net who have used RefTeX and helped
154 ;; developing it with their reports. In particular thanks to
155 ;;
156 ;; Fran Burstall, Alastair Burt, Soren Dayton, Stephen Eglen,
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.
161 ;;
162 ;; Finally thanks to Uwe Bolick who first got me (some years ago) into
163 ;; supporting LaTeX labels and references with an editor (which was
164 ;; MicroEmacs at the time).
165 ;;
166 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
167 ;;
168 ;;;;;;
169 \f
170 ;;; Code:
171
172 (eval-when-compile (require 'cl))
173
174 ;; Stuff that needs to be there when we use defcustom
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
185 ;;; ======================================================================
186 ;;;
187 ;;; Configuration Section
188
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"
212 (("\\endnote[]{}" ?n nil nil 2 (regexp "Endnotes?"))))
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
231 (sidecap "CSfigure and SCtable"
232 (("SCfigure" ?f nil nil caption)
233 ("SCtable" ?t nil nil caption)))
234
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)
249 (regexp "parts?" "chapters?" "chap\\." "sections?" "sect?\\."
250 "paragraphs?" "par\\."
251 "\\\\S" "\247" "Teile?" "Kapitel" "Kap\\." "Abschnitte?"
252 "appendi\\(x\\|ces\\)" "App\\." "Anh\"?ange?" "Anh\\."))
253
254 ("enumerate" ?i "item:" "~\\ref{%s}" item
255 (regexp "items?" "Punkte?"))
256
257 ("equation" ?e "eq:" "~(\\ref{%s})" t
258 (regexp "equations?" "eqs?\\." "eqn\\." "Gleichung\\(en\\)?" "Gl\\."))
259 ("eqnarray" ?e "eq:" nil eqnarray-like)
260
261 ("figure" ?f "fig:" "~\\ref{%s}" caption
262 (regexp "figure?[sn]?" "figs?\\." "Abbildung\\(en\\)?" "Abb\\."))
263 ("figure*" ?f nil nil caption)
264
265 ("table" ?t "tab:" "~\\ref{%s}" caption
266 (regexp "tables?" "tab\\." "Tabellen?"))
267 ("table*" ?t nil nil caption)
268
269 ("\\footnote[]{}" ?n "note:" "~\\ref{%s}" 2
270 (regexp "footnotes?" "notes?" "Anmerkung\\(en\\)?" "Anm\\."))
271
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 ))
277
278 )
279 "The default label environment descriptions.
280 Lower-case symbols correspond to a style file of the same name in the LaTeX
281 distribution. Mixed-case symbols are convenience aliases.")
282
283 (defconst reftex-cite-format-builtin
284 '((default "Default macro \\cite{%l}"
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}")
293 (?s . "\\citep[see][]{%l}")
294 (?a . "\\citeauthor{%l}")
295 (?A . "\\citeauthor*{%l}")
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}")
314 (?y . "\\citeyear{%l}")))
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 %<)")
325 )
326 "Builtin versions of the citation format.
327 The 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
333 ;; Configuration Variables and User Options for RefTeX ------------------
334
335 (defgroup reftex nil
336 "LaTeX label and citation support."
337 :tag "RefTeX"
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")
341 :link '(custom-manual "(reftex)Top")
342 :prefix "reftex-"
343 :group 'tex)
344
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.
353 This helps to keep the window configuration, but makes the *toc* small.
354 When nil, all other windows except the selected one will be deleted, so
355 that 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.
361 This 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.
367 Context will only be shown when labels are visible as well.
368 This 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.
374 This 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.
380 The other window will show the corresponding part of the document.
381 This 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.
387 When 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
399 (defgroup reftex-label-support nil
400 "Support for creation, insertion and referencing of labels in LaTeX."
401 :group 'reftex)
402
403 (defgroup reftex-defining-label-environments nil
404 "Definition of environments and macros to do with label."
405 :group 'reftex-label-support)
406
407 (defcustom reftex-default-label-alist-entries
408 '(amsmath endnotes fancybox floatfig longtable picinpar
409 rotating sidecap subfigure supertab wrapfig LaTeX)
410 "Default label alist specifications. LaTeX should be the last entry.
411 This list describes the default label environments RefTeX should always use.
412 It is probably a mistake to remove the LaTeX symbol from this list.
413
414 The options include:
415 LaTeX The standard LaTeX environments.
416 Sideways The sidewaysfigure and sidewaystable environments.
417 AMSTeX The math environments in the AMS-LaTeX amsmath package.
418
419 For the full list of options, try
420
421 M-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)
431 (list 'const :tag (concat (symbol-name (nth 0 x))
432 ": " (nth 1 x))
433 (nth 0 x))))
434 reftex-label-alist-builtin)))
435
436 (defcustom reftex-label-alist nil
437 "Alist with information on environments for \\label-\\ref use.
438
439 This docstring is easier to understand after reading the configuration
440 examples in `reftex.el'. Looking at the builtin defaults in the constant
441 `reftex-label-alist-builtin' may also be instructive.
442
443 Set this variable to define additions and changes to the default. The only
444 things you MUST NOT change is that `?s' is the type indicator for section
445 labels, and SPC for the `any' label type. These are hard-coded at other
446 places in the code.
447
448 Each list entry describes either an environment carrying a counter for use
449 with \\label and \\ref, or a LaTeX macro defining a label as (or inside)
450 one of its arguments. The elements of each list entry are:
451
452 0. Name of the environment (like \"table\") or macro (like \"\\\\myfig\").
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.
458 Special names: `section' for section labels, `any' to define a group
459 which contains all labels.
460 This may also be nil if the entry is only meant to change some settings
461 associated with the type indicator character (see below).
462
463 1. 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').
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.
472
473 2. Label prefix string, like \"tab:\".
474 The prefix is a short string used as the start of a label. It may be the
475 empty string. The prefix may contain the following `%' escapes:
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:\").
481
482 3. Format string for reference insert in buffer. `%s' will be replaced by
483 the label.
484 When the format starts with `~', the `~' will only be inserted if
485 there is not already a whitespace before point.
486
487 4. Indication on how to find the short context.
488 - If nil, use the text following the \\label{...} macro.
489 - If t, use
490 - the section heading for section labels.
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).
494 - text after the macro name (starting with the first arg) for macros.
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.
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
499 \"\\\\\\\\caption[[{]\" will use the caption in a figure or table
500 environment.
501 \"\\\\\\\\begin{eqnarray}\\\\|\\\\\\\\\\\\\\\\\" works for eqnarrays.
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').
505 - If a function, call this function with the name of the environment/macro
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
508 throw an exception (error) when failing to find context.
509 As an example, here is a function returning the 10 chars following
510 the label macro as context:
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
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
524 5. 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
526 `reftex-reference', the label list offered will be automatically
527 restricted to labels of the correct type.
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.
531
532 If the type indicator characters of two or more entries are the same, RefTeX
533 will use
534 - the first non-nil format and prefix
535 - the magic words of all involved entries.
536
537 Any list entry may also be a symbol. If that has an association in
538 `reftex-label-alist-builtin', the cddr of that association is spliced into the
539 list. However, builtin defaults should normally be set with the variable
540 `reftex-default-label-alist-entries."
541 :group 'reftex-defining-label-environments
542 :set 'reftex-set-dirty
543 :type
544 `(repeat
545 (choice :tag "Package or Detailed "
546 :value ("" ?a nil nil nil nil)
547 (list :tag "Detailed Entry"
548 :value ("" ?a nil nil nil nil)
549 (choice :tag "Environment or \\macro "
550 (const :tag "Ignore, just use typekey" nil)
551 (string ""))
552 (choice :tag "Type specification "
553 (const :tag "unspecified, like in \\label" nil)
554 (character :tag "Char " ?a))
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}"))
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)))
572 (choice
573 :tag "Package"
574 :value AMSTeX
575 ,@(mapcar
576 (function
577 (lambda (x)
578 (list 'const :tag (concat (symbol-name (nth 0 x)))
579 (nth 0 x))))
580 reftex-label-alist-builtin)))))
581
582 ;; LaTeX section commands and level numbers
583 (defcustom reftex-section-levels
584 '(
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
596 )
597 "Commands and levels used for defining sections in the document.
598 The car of each cons cell is the name of the section macro. The cdr is a
599 number indicating its level. A negative level means the same as the
600 positive value, but the section will never get a number."
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.
613 The form (format regexp (regexp-quote environment)) is used to calculate
614 the final regular expression - so %s will be replaced with the environment
615 or macro."
616 :group 'reftex-defining-label-environments
617 :type '(repeat (cons (symbol) (regexp))))
618
619 ;; Label insertion
620
621 (defgroup reftex-making-and-inserting-labels nil
622 "Options on how to create new labels."
623 :group 'reftex-label-support)
624
625 (defcustom reftex-insert-label-flags '("s" "sft")
626 "Flags governing label insertion. First flag DERIVE, second flag PROMPT.
627
628 If DERIVE is t, RefTeX will try to derive a sensible label from context.
629 A section label for example will be derived from the section heading.
630 The conversion of the context to a legal label is governed by the
631 specifications given in `reftex-derive-label-parameters'.
632 If RefTeX fails to derive a label, it will prompt the user.
633 If DERIVE is nil, the label generated will consist of the prefix and a
634 unique number, like `eq:23'.
635
636 If PROMPT is t, the user will be prompted for a label string. The prompt will
637 already contain the prefix, and (if DERIVE is t) a default label derived from
638 context. When PROMPT is nil, the default label will be inserted without
639 query.
640
641 So the combination of DERIVE and PROMPT controls label insertion. Here is a
642 table describing all four possibilities:
643
644 DERIVE PROMPT ACTION
645 -------------------------------------------------------------------------
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.
650
651 Each flag may be set to t, nil, or a string of label type letters
652 indicating the label types for which it should be true. The strings work
653 like character classes.
654 Thus, the combination may be set differently for each label type. The
655 default settings \"s\" and \"sft\" mean: Derive section labels from headings
656 (with confirmation). Prompt for figure and table labels. Use simple labels
657 without confirmation for everything else.
658 The available label types are: s (section), f (figure), t (table), i (item),
659 e (equation), n (footnote), plus any definitions in `reftex-label-alist'."
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)
664 (string :tag "selected label types" ""))
665 (choice :tag "Prompt for label string "
666 :entry-format " %b %v"
667 (const :tag "always" t)
668 (const :tag "never" nil)
669 (string :tag "selected label types" ""))))
670
671 (defcustom reftex-string-to-label-function 'reftex-string-to-label
672 "Function to turn an arbitrary string into a legal label.
673 RefTeX's default function uses the variable `reftex-derive-label-parameters'."
674 :group 'reftex-making-and-inserting-labels
675 :type 'symbol)
676
677 (defcustom reftex-translate-to-ascii-function 'reftex-latin1-to-ascii
678 "Filter function which will process a context string before it is used
679 to derive a label from it. The intended application is to convert ISO or
680 Mule characters into something legal in labels. The default function
681 removes the accents from Latin-1 characters. X-Symbol (>=2.6) sets this
682 variable to the much more general `x-symbol-translate-to-ascii'."
683 :group 'reftex-making-and-inserting-labels
684 :type 'symbol)
685
686 (defcustom reftex-derive-label-parameters '(3 20 t 1 "-"
687 ("the" "on" "in" "off" "a" "for" "by" "of" "and" "is" "to") t)
688 "Parameters for converting a string into a label.
689 NWORDS Number of words to use.
690 MAXCHAR Maximum number of characters in a label string.
691 ILLEGAL nil: Throw away any words containing characters illegal in labels.
692 t: Throw away only the illegal characters, not the whole word.
693 ABBREV nil: Never abbreviate words.
694 t: Always abbreviate words (see `reftex-abbrev-parameters').
695 not t and not nil: Abbreviate words if necessary to shorten
696 label string below MAXCHAR.
697 SEPARATOR String separating different words in the label.
698 IGNOREWORDS List of words which should not be part of labels.
699 DOWNCASE t: Downcase words before using them."
700 :group 'reftex-making-and-inserting-labels
701 :type '(list (integer :tag "Number of words " 3)
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"
713 (string :tag ""))
714 (option (boolean :tag "Downcase words "))))
715
716 (defcustom reftex-label-illegal-re "[^-a-zA-Z0-9_+=:;,.]"
717 "Regexp matching characters not legal in labels."
718 :group 'reftex-making-and-inserting-labels
719 :type '(regexp :tag "Regular Expression"))
720
721 (defcustom reftex-abbrev-parameters '(4 2 "^aeiou" "aeiou")
722 "Parameters for abbreviation of words.
723 MIN-CHARS Minimum number of characters remaining after abbreviation.
724 MIN-KILL Minimum number of characters to remove when abbreviating words.
725 BEFORE Character class before abbrev point in word.
726 AFTER Character class after abbrev point in word."
727 :group 'reftex-making-and-inserting-labels
728 :type '(list
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")))
733
734 (defcustom reftex-format-label-function nil
735 "Function which produces the string to insert as a label definition.
736 Normally should be nil, unless you want to do something fancy.
737 The function will be called with two arguments, the LABEL and the DEFAULT
738 FORMAT, which usually is `\label{%s}'. The function should return the
739 string to insert into the buffer."
740 :group 'reftex-making-and-inserting-labels
741 :type 'function)
742
743 ;; Label referencing
744
745 (defgroup reftex-referencing-labels nil
746 "Options on how to reference labels."
747 :group 'reftex-label-support)
748
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.
757 The flags are:
758
759 TABLE-OF-CONTENTS Show the labels embedded in a table of context.
760 SECTION-NUMBERS Include section numbers (like 4.1.3) in table of contents.
761 COUNTERS Show counters. This just numbers the labels in the menu.
762 NO-CONTEXT Non-nil means do NOT show the short context.
763 FOLLOW Follow full context in other window.
764 SHOW-COMMENTED Show labels from regions which are commented out.
765 MATCH-IN-TOC Obsolete flag.
766 SHOW FILES Show begin and end of included files.
767
768 Each of these flags can be set to t or nil, or to a string of type letters
769 indicating the label types for which it should be true. These strings work
770 like character classes in regular expressions. Thus, setting one of the
771 flags to \"sf\" makes the flag true for section and figure labels, nil
772 for everything else. Setting it to \"^sf\" makes it the other way round.
773 The available label types are: s (section), f (figure), t (table), i (item),
774 e (equation), n (footnote), plus any definitions in `reftex-label-alist'.
775
776 Most options can also be switched from the label menu itself - so if you
777 decide here to not have a table of contents in the label menu, you can still
778 get one interactively during selection from the label menu."
779 :group 'reftex-referencing-labels
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)
788 (choice :tag "Obsolete flag, Don't use. " ,@reftex-tmp)
789 (choice :tag "Show begin/end of included files" ,@reftex-tmp)))
790
791 (defcustom reftex-vref-is-default nil
792 "*Non-nil means, the varioref macro \\vref is used as default.
793 In the selection buffer, the `v' key toggles the reference macro between
794 `\\ref' and `\\vref'. The value of this variable determines the default
795 which is active when entering the selection process.
796 Instead of nil or t, this may also be a string of type letters indicating
797 the label types for which it should be true."
798 :group 'reftex-referencing-labels
799 :type `(choice :tag "\\vref is default macro" ,@reftex-tmp))
800
801 (defcustom reftex-level-indent 2
802 "*Number of spaces to be used for indentation per section level."
803 :group 'reftex-referencing-labels
804 :type 'integer)
805
806 (defcustom reftex-guess-label-type t
807 "*Non-nil means, `reftex-reference' will try to guess the label type.
808 To do that, RefTeX will look at the word before the cursor and compare it with
809 the words given in `reftex-label-alist'. When it finds a match, RefTeX will
810 immediately offer the correct label menu - otherwise it will prompt you for
811 a label type. If you set this variable to nil, RefTeX will always prompt."
812 :group 'reftex-referencing-labels
813 :type 'boolean)
814
815 (defcustom reftex-format-ref-function nil
816 "Function which produces the string to insert as a reference.
817 Normally should be nil, because the format to insert a reference can
818 already be specified in `reftex-label-alist'.
819 The function will be called with two arguments, the LABEL and the DEFAULT
820 FORMAT, which normally is `~\ref{%s}'. The function should return the
821 string to insert into the buffer."
822 :group 'reftex-referencing-labels
823 :type 'function)
824
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
830 ;; BibteX citation configuration ----------------------------------------
831
832 (defgroup reftex-citation-support nil
833 "Support for referencing bibliographic data with BibTeX."
834 :group 'reftex)
835
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{..}.
839 File names matched by these regexps will not be parsed by RefTeX.
840 Intended for files which contain only `@string' macro definitions and the
841 like, which are ignored by RefTeX anyway."
842 :group 'reftex-citation-support
843 :set 'reftex-set-dirty
844 :type '(repeat (regexp)))
845
846 (defcustom reftex-default-bibliography nil
847 "*List of BibTeX database files which should be used if none are specified.
848 When `reftex-citation' is called from a document which has neither a
849 `\bibliography{..}' statement nor a `thebibliography' environment,
850 RefTeX will scan these files instead. Intended for using `reftex-citation'
851 in non-LaTeX files. The files will be searched along the BIBINPUTS or TEXBIB
852 path."
853 :group 'reftex-citation-support
854 :type '(repeat (file)))
855
856 (defcustom reftex-sort-bibtex-matches 'reverse-year
857 "*Sorting of the entries found in BibTeX databases by reftex-citation.
858 Possible values:
859 nil 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)
865 (const :tag "by author" author)
866 (const :tag "by year" year)
867 (const :tag "by year, reversed" reverse-year)))
868
869 (defcustom reftex-cite-format 'default
870 "*The format of citations to be inserted into the buffer.
871 It can be a string or an alist. In the simplest case this is just
872 the string \"\\cite{%l}\", which is also the default. See the
873 definition of `reftex-cite-format-builtin' for more complex examples.
874
875 If `reftex-cite-format' is a string, it will be used as the format.
876 In 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
884 It 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
889 %v volume %y year
890 %B booktitle, abbreviated %T title, abbreviated
891
892 Usually, only %l is needed. The other stuff is mainly for the echo area
893 display, and for (setq reftex-comment-citations t).
894
895 %< as a special operator kills punctuation and space around it after the
896 string has been formatted.
897
898 Beware that all this only works with BibTeX database files. When
899 citations are made from the \\bibitems in an explicit thebibliography
900 environment, only %l is available.
901
902 If `reftex-cite-format' is an alist of characters and strings, the user
903 will be prompted for a character to select one of the possible format
904 strings.
905 In order to configure this variable, you can either set
906 `reftex-cite-format' directly yourself or set it to the SYMBOL of one of
907 the predefined styles (see `reftex-cite-format-builtin'). E.g.:
908 (setq reftex-cite-format 'natbib)"
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)
919 (list 'const :tag (concat (symbol-name (nth 0 x))
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" "")))))
929
930 (defcustom reftex-comment-citations nil
931 "*Non-nil means add a comment for each citation describing the full entry.
932 The comment is formatted according to `reftex-cite-comment-format'."
933 :group 'reftex-citation-support
934 :type 'boolean)
935
936 (defcustom reftex-cite-comment-format
937 "%% %2a %y, %j %v, %P, %b, %e, %u, %s %<\n"
938 "Citation format used for commented citations. Must NOT contain %l.
939 See 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.
946 Must NOT contain %l. See the variable `reftex-cite-format' for
947 possible percent escapes."
948 :group 'reftex-citation-support
949 :group 'reftex-viewing-cross-references-and-citations
950 :type 'string)
951
952 (defcustom reftex-cite-punctuation '(", " " \\& " " {\\it et al.}")
953 "Punctuation for formatting of name lists in citations.
954 This is a list of 3 strings.
955 1. normal names separator, like \", \" in Jones, Brown and Miller
956 2. final names separator, like \" and \" in Jones, Brown and Miller
957 3. The \"et al\" string, like \" {\\it et al.}\" in Jones {\\it et al.}"
958 :group 'reftex-citation-support
959 :type '(list
960 (string :tag "Separator for names ")
961 (string :tag "Separator for last name in list")
962 (string :tag "string used as et al. ")))
963
964 (defcustom reftex-format-cite-function nil
965 "Function which produces the string to insert as a citation.
966 Normally should be nil, because the format to insert a reference can
967 already be specified in `reftex-cite-format'.
968 The function will be called with two arguments, the CITATION KEY and the
969 DEFAULT FORMAT, which is taken from `reftex-cite-format'. The function
970 should return the string to insert into the buffer."
971 :group 'reftex-citation-support
972 :type 'function)
973
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
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
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.
987 This is used when `reftex-view-crossref' is called with point in an
988 argument of a macro. Note that crossref viewing for citations and
989 references (both ways) is hard-coded. This variable is only to
990 configure additional structures for which crossreference viewing
991 can be useful. Each entry has the structure
992
993 (MACRO-RE SEARCH-RE HIGHLIGHT).
994
995 MACRO-RE is matched against the macro. SEARCH-RE is the regexp used
996 to search for cross references. `%s' in this regexp is replaced with
997 with the macro argument at point. HIGHLIGHT is an integer indicating
998 which 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
1004 (defcustom reftex-auto-view-crossref t
1005 "*Non-nil means, initially turn automatic viewing of crossref info on.
1006 Automatic viewing of crossref info normally uses the echo area.
1007 Whenever point is on the argument of a \\ref or \\cite macro, and no
1008 other message is being displayed, the echo area will display
1009 information about that cross reference. You can also set the variable
1010 to the symbol `window'. In this case a small temporary window is
1011 used for the display.
1012 This feature can be turned on and of from the menu
1013 (Ref->Options->Crossref Viewing)."
1014 :group 'reftex-viewing-cross-references-and-citations
1015 :type '(choice (const :tag "off" nil)
1016 (const :tag "in Echo Area" t)
1017 (const :tag "in Other Window" window)))
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.
1026 When nil, citation display in echo area will only be active for cached
1027 entries 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
1033 is cached and even saved along with the parsing information. The cache
1034 survives 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
1040 for 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)
1044
1045 ;; Finding Files --------------------------------------------------------
1046
1047 (defgroup reftex-finding-files nil
1048 "Finding files on search paths."
1049 :group 'reftex)
1050
1051 (defcustom reftex-texpath-environment-variables '("TEXINPUTS")
1052 "*List of specifications how to retrieve the search path for TeX files.
1053 Several 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.
1059 Multiple directories can be separated by the system dependent `path-separator'.
1060 Directories ending in `//' or `!!' will be expanded recursively.
1061 See 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.
1068 Several 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.
1074 Multiple directories can be separated by the system dependent `path-separator'.
1075 Directories ending in `//' or `!!' will be expanded recursively.
1076 See 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
1082 (defcustom reftex-file-extensions '(("tex" . (".tex" ".ltx"))
1083 ("bib" . (".bib")))
1084 "*Association list with file extensions for different file types.
1085 This is a list of items, each item is like: (TYPE . (DEF-EXT OTHER-EXT ...))
1086
1087 TYPE: File type like \"bib\" or \"tex\".
1088 DEF-EXT: The default extension for that file type, like \".tex\" or \".bib\".
1089 OTHER-EXT: Any number of other legal extensions for this file type.
1090
1091 When a files is searched and it does not have any of the legal extensions,
1092 we 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
1097 (defcustom reftex-search-unrecursed-path-first t
1098 "*Non-nil means, search all specified directories before trying recursion.
1099 Thus, in a path \".//:/tex/\", search first \"./\", then \"/tex/\" and then
1100 all subdirectories of \"./\". If this option is nil, the subdirectories of
1101 \"./\" are searched before \"/tex/\". This is mainly for speed - most of the
1102 time the recursive path is for the system files and not for the user files.
1103 Set this to nil if the default makes RefTeX finding files with equal names
1104 in 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.
1110 Normally, RefTeX searches the paths given in the environment variables
1111 TEXINPUTS and BIBINPUTS to find TeX files and BibTeX database files.
1112 With this option turned on, it calls an external program specified in the
1113 option `reftex-external-file-finders' instead. As a side effect,
1114 the variables `reftex-texpath-environment-variables' and
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.
1122 Each entry is a cons cell (TYPE . PROGRAM).
1123 TYPE is either \"tex\" or \"bib\". PROGRAM is the external program to use with
1124 any arguments. %f will be replaced by the name of the file to be found.
1125 Note that these commands will be executed directly, not via a shell.
1126 Only 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
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.
1139 RefTeX sometimes needs to visit files related to the current document.
1140 We distinguish files visited for
1141 PARSING: Parts of a multifile document loaded when (re)-parsing the document.
1142 LOOKUP: BibTeX database files and TeX files loaded to find a reference,
1143 to display label context, etc.
1144 The created buffers can be kept for later use, or be thrown away immediately
1145 after use, depending on the value of this variable:
1146
1147 nil Throw away as much as possible.
1148 t Keep everything.
1149 1 Throw away buffers created for parsing, but keep the ones created
1150 for lookup.
1151
1152 If a buffer is to be kept, the file is visited normally (which is potentially
1153 slow but will happen only once).
1154 If a buffer is to be thrown away, the initialization of the buffer depends
1155 upon the variable `reftex-initialize-temporary-buffers'."
1156 :group 'reftex-optimizations-for-large-documents
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.
1164 When nil, RefTeX may turn off find-file hooks and other stuff to briefly
1165 visit a file.
1166 When t, the full default initializations are done (find-file-hook etc.).
1167 Instead of t or nil, this variable may also be a list of hook functions to
1168 do a minimal initialization."
1169 :group 'reftex-optimizations-for-large-documents
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
1176 (defcustom reftex-no-include-regexps '("\\.pstex_t\\'")
1177 "*List of regular expressions to exclude certain input files from parsing.
1178 If the name of a file included via \\include or \\input is matched by any
1179 of 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
1183 (defcustom reftex-enable-partial-scans nil
1184 "*Non-nil means, re-parse only 1 file when asked to re-parse.
1185 Re-parsing is normally requested with a `C-u' prefix to many RefTeX commands,
1186 or with the `r' key in menus. When this option is t in a multifile document,
1187 we will only parse the current buffer, or the file associated with the label
1188 or section heading near point in a menu. Requesting re-parsing of an entire
1189 multifile document then requires a `C-u C-u' prefix or the capital `R' key
1190 in menus."
1191 :group 'reftex-optimizations-for-large-documents
1192 :type 'boolean)
1193
1194 (defcustom reftex-allow-automatic-rescan t
1195 "*Non-nil means, RefTeX may rescan the document when this seems necessary.
1196 Currently this applies only to rescanning after label insertion, when
1197 the new label cannot be inserted correctly into the internal label
1198 list."
1199 :group 'reftex-optimizations-for-large-documents
1200 :type 'boolean)
1201
1202 (defcustom reftex-save-parse-info nil
1203 "*Non-nil means, save information gathered with parsing in a file.
1204 The file MASTER.rel in the same directory as MASTER.tex is used to save the
1205 information. 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.
1208 - exiting Emacs or killing a buffer in reftex-mode will cause a new version
1209 of the file to be written."
1210 :group 'reftex-optimizations-for-large-documents
1211 :type 'boolean)
1212
1213 (defcustom reftex-use-multiple-selection-buffers nil
1214 "*Non-nil means use a separate selection buffer for each label type.
1215 These buffers are kept from one selection to the next and need not to be
1216 created for each use - so the menu generally comes up faster. The
1217 selection buffers will be erased (and therefore updated) automatically
1218 when new labels in its category are added. See the variable
1219 `reftex-auto-update-selection-buffers'."
1220 :group 'reftex-optimizations-for-large-documents
1221 :group 'reftex-referencing-labels
1222 :type 'boolean)
1223
1224 (defcustom reftex-auto-update-selection-buffers t
1225 "*Non-nil means, selection buffers will be updated automatically.
1226 When a new label is defined with `reftex-label', all selection buffers
1227 associated with that label category are emptied, in order to force an
1228 update upon next use. When nil, the buffers are left alone and have to be
1229 updated by hand, with the `g' key from the label selection process.
1230 The 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
1233 :group 'reftex-referencing-labels
1234 :type 'boolean)
1235
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.
1244 Font-lock must be loaded as well to actually get fontified display.
1245 When changing this option, a rescan may be necessary to activate the change."
1246 :group 'reftex-fontification-configurations
1247 :type 'boolean)
1248
1249 (defcustom reftex-refontify-context 1
1250 "*Non-nil means, re-fontify the context in the label menu with font-lock.
1251 This slightly slows down the creation of the label menu. It is only necessary
1252 when you definitely want the context fontified.
1253
1254 This option may have 3 different values:
1255 nil Never refontify.
1256 t Always refontify.
1257 1 Refontify when absolutely necessary, e.g. when old versions of X-Symbol.
1258 The option is ignored when `reftex-use-fonts' is nil."
1259 :group 'reftex-fontification-configurations
1260 :group 'reftex-referencing-labels
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.
1268 Normally, the text near the cursor is the selected text, and it is
1269 highlighted. This is the entry most keys in the selction and *toc*
1270 buffers act on. However, if you mainly use the mouse to select an
1271 item, you may find it nice to have mouse-triggered highlighting
1272 instead 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.
1277 both Both cursor and mouse trigger highlighting.
1278
1279 Changing this variable requires to rebuild the selection and *toc* buffers
1280 to become effective (keys `g' or `r')."
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.
1290 See 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.
1295 See 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
1331 (defcustom reftex-pre-refontification-functions nil
1332 "X-Symbol specific hook.
1333 Functions get two arguments, the buffer from where the command started and a
1334 symbol indicating in what context the hook is called."
1335 :group 'reftex-fontification-configurations
1336 :type 'hook)
1337
1338 ;; Miscellaneous configurations -----------------------------------------
1339
1340 (defgroup reftex-miscellaneous-configurations nil
1341 "Collection of further configurations."
1342 :group 'reftex)
1343
1344 (defcustom reftex-extra-bindings nil
1345 "Non-nil means, make additional key bindings on startup.
1346 These extra bindings are located in the users `C-c letter' map."
1347 :group 'reftex-miscellaneous-configurations
1348 :type 'boolean)
1349
1350 (defcustom reftex-plug-into-AUCTeX nil
1351 "*Plug-in flags for AUCTeX interface.
1352 This variable is a list of 4 boolean flags. When a flag is non-nil,
1353 RefTeX will
1354
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)
1359
1360 You may also set the variable itself to t or nil in order to turn all
1361 plug-ins on or off, respectively.
1362 \\<LaTeX-mode-map>Supplying labels in new sections and environments applies when creating
1363 sections with \\[LaTeX-section] and environments with \\[LaTeX-environment].
1364 Supplying macro arguments applies when you insert such a macro interactively
1365 with \\[TeX-insert-macro].
1366 See the AUCTeX documentation for more information.
1367 RefTeX uses `fset' to take over the function calls. Changing the variable
1368 may require a restart of Emacs in order to become effective."
1369 :group 'reftex-miscellaneous-configurations
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.
1385 When this is t, `aaa' will be considered as argument of \\bb in the following
1386 construct: \\bbb [xxx] {aaa}."
1387 :group 'texmathp
1388 :type 'boolean)
1389
1390
1391 (defcustom reftex-load-hook nil
1392 "Hook which is being run when loading reftex.el."
1393 :group 'reftex-miscellaneous-configurations
1394 :type 'hook)
1395
1396 (defcustom reftex-mode-hook nil
1397 "Hook which is being run when turning on RefTeX mode."
1398 :group 'reftex-miscellaneous-configurations
1399 :type 'hook)
1400
1401 ;;; =========================================================================
1402 ;;;
1403 ;;; Define the formal stuff for a minor mode named RefTeX.
1404 ;;;
1405
1406 (defconst reftex-version "RefTeX version 3.43"
1407 "Version string for RefTeX.")
1408
1409 (defvar reftex-mode nil
1410 "Determines if RefTeX mode is active.")
1411 (make-variable-buffer-local 'reftex-mode)
1412
1413 (defvar reftex-mode-map (make-sparse-keymap)
1414 "Keymap for RefTeX mode.")
1415
1416 (defvar reftex-mode-menu nil)
1417
1418 ;;;###autoload
1419 (defun turn-on-reftex ()
1420 "Turn on RefTeX mode."
1421 (reftex-mode t))
1422
1423 ;;;###autoload
1424 (defun reftex-mode (&optional arg)
1425 "Minor mode with distinct support for \\label, \\ref and \\cite in LaTeX.
1426
1427 Labels can be created with `\\[reftex-label]' and referenced with `\\[reftex-reference]'.
1428 When referencing, you get a menu with all labels of a given type and
1429 context of the label definition. The selected label is inserted as a
1430 \\ref macro.
1431
1432 Citations can be made with `\\[reftex-citation]' which will use a regular expression
1433 to pull out a *formatted* list of articles from your BibTeX
1434 database. The selected citation is inserted as a \\cite macro.
1435
1436 A Table of Contents of the entire (multifile) document with browsing
1437 capabilities is available with `\\[reftex-toc]'.
1438
1439 Most command have help available on the fly. This help is accessed by
1440 pressing `?' to any prompt mentioning this feature.
1441
1442 Extensive documentation about RefTeX is available in Info format.
1443 You can view this information with `\\[reftex-info]'.
1444
1445 \\{reftex-mode-map}
1446 Under X, these and other functions will also be available as `Ref' menu
1447 on the menu bar.
1448
1449 ------------------------------------------------------------------------------"
1450
1451 (interactive "P")
1452 (setq reftex-mode (not (or (and (null arg) reftex-mode)
1453 (<= (prefix-numeric-value arg) 0))))
1454
1455 (if reftex-mode
1456 (progn
1457 ;; Mode was turned on
1458 (easy-menu-add reftex-mode-menu)
1459 (and reftex-plug-into-AUCTeX
1460 (reftex-plug-into-AUCTeX))
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))
1465 (run-hooks 'reftex-mode-hook))
1466 ;; Mode was turned off
1467 (easy-menu-remove reftex-mode-menu)))
1468
1469 (if (fboundp 'add-minor-mode)
1470 ;; Use it so that we get the extras
1471 (progn
1472 (put 'reftex-mode :included '(memq major-mode '(latex-mode tex-mode)))
1473 (put 'reftex-mode :menu-tag "RefTeX Mode")
1474 (add-minor-mode 'reftex-mode " Ref" reftex-mode-map))
1475 ;; The standard way
1476 (unless (assoc 'reftex-mode minor-mode-alist)
1477 (push '(reftex-mode " Ref") minor-mode-alist))
1478 (unless (assoc 'reftex-mode minor-mode-map-alist)
1479 (push (cons 'reftex-mode reftex-mode-map) minor-mode-map-alist)))
1480
1481 ;;; =========================================================================
1482 ;;;
1483 ;;; Silence warnings about variables in other packages.
1484 (defvar TeX-master)
1485 (defvar LaTeX-section-hook)
1486 (defvar LaTeX-label-function)
1487 (defvar tex-main-file)
1488 (defvar outline-minor-mode)
1489 (defvar font-lock-mode)
1490 (defvar font-lock-fontify-region-function)
1491 (defvar font-lock-syntactic-keywords)
1492
1493 ;;; =========================================================================
1494 ;;;
1495 ;;; Multibuffer Variables
1496 ;;;
1497 ;;; Technical notes: These work as follows: We keep just one list
1498 ;;; of labels for each master file - this can save a lot of memory.
1499 ;;; `reftex-master-index-list' is an alist which connects the true file name
1500 ;;; of each master file with the symbols holding the information on that
1501 ;;; document. Each buffer has local variables which point to these symbols.
1502
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
1506 '(reftex-docstruct-symbol))
1507
1508 ;; Alist connecting master file names with the corresponding lisp symbols.
1509 (defvar reftex-master-index-list nil)
1510
1511 ;; Last index used for a master file.
1512 (defvar reftex-multifile-index 0)
1513
1514 ;; Variable holding the symbol with the label list of the document.
1515 (defvar reftex-docstruct-symbol nil)
1516 (make-variable-buffer-local 'reftex-docstruct-symbol)
1517
1518 (defun reftex-next-multifile-index ()
1519 ;; Return the next free index for multifile symbols.
1520 (incf reftex-multifile-index))
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)
1529 symbol symname newflag)
1530 ;; Find the correct index.
1531 (if index
1532 ;; symbols do exist
1533 (setq index (cdr index))
1534 ;; Get a new index and add info to the alist.
1535 (setq index (reftex-next-multifile-index)
1536 newflag t)
1537 (push (cons master index) reftex-master-index-list))
1538
1539 ;; Get/create symbols and tie them.
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))))
1545 (put (symbol-value symbol) :master-index index)
1546 ;; Initialize if new symbols.
1547 (if newflag (set (symbol-value symbol) nil)))
1548
1549 ;; Return t if the symbols did already exist, nil when we've made them.
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.
1563 ;; When AUCTeX is loaded, we will use its more sophisticated method.
1564 ;; We also support the default TeX and LaTeX modes by checking for a
1565 ;; variable tex-main-file.
1566 (let
1567 ((master
1568 (cond
1569 ((fboundp 'TeX-master-file) ; AUCTeX is loaded. Use its mechanism.
1570 (condition-case nil
1571 (TeX-master-file t)
1572 (error (buffer-file-name))))
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)
1585 ;; This is the variable from the default TeX modes.
1586 (cond
1587 ((stringp tex-main-file)
1588 ;; ok, this must be it
1589 tex-main-file)
1590 (t
1591 ;; In this case, the buffer is its own master.
1592 (buffer-file-name))))
1593 (t
1594 ;; Know nothing about master file. Assume this is a master file.
1595 (buffer-file-name)))))
1596 (cond
1597 ((null master)
1598 (error "Need a filename for this buffer, please save it first"))
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")))
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 )
1607 (t
1608 ;; Use buffer file name.
1609 (buffer-file-name)))
1610 (expand-file-name master)))
1611
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
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)
1667 (defvar reftex-callback-fwd t)
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)
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)
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
1707 (reftex-erase-buffer "*toc*")
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
1725 (defun reftex-parse-one ()
1726 "Re-parse this file."
1727 (interactive)
1728 (let ((reftex-enable-partial-scans t))
1729 (reftex-access-scan-info '(4))))
1730
1731 (defun reftex-parse-all ()
1732 "Re-parse entire document."
1733 (interactive)
1734 (reftex-access-scan-info '(16)))
1735
1736 (defun reftex-do-parse (rescan &optional file)
1737 "Do a document rescan. When allowed, do only a partial scan from FILE."
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))
1754 (true-master (file-truename master))
1755 (master-dir (file-name-as-directory (file-name-directory master)))
1756 (file (or file (buffer-file-name)))
1757 (true-file (file-truename file))
1758 (bibview-cache (assq 'bibview-cache old-list))
1759 from-file appendix docstruct tmp)
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))))
1765 ;; Scan whole document because no such file section exists
1766 (setq rescan 1))
1767 (when (string= true-file true-master)
1768 ;; Scan whole document because this file is the master
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)
1775 (t (error "This should not happen (reftex-do-parse)"))))
1776
1777 ;; Find active toc entry and initialize section-numbers
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)
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))
1811 (unless (assq 'bibview-cache docstruct)
1812 (push (cons 'bibview-cache (cdr bibview-cache)) docstruct))
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))
1821 (alist (mapcar
1822 (function
1823 (lambda (x)
1824 (if (setq tmp (reftex-locate-file (nth 2 x) "tex"
1825 master-dir))
1826 (cons (nth 1 x) tmp)
1827 (message "Can't find external document %s"
1828 (nth 2 x))
1829 nil)))
1830 allxr))
1831 (alist (delq nil alist))
1832 (allprefix (delq nil (mapcar 'car alist)))
1833 (regexp (if allprefix
1834 (concat "\\`\\("
1835 (mapconcat 'identity allprefix "\\|")
1836 "\\)")
1837 "\\\\\\\\\\\\"))) ; this will never match
1838 (push (list 'xr alist regexp) docstruct)))
1839
1840 (set reftex-docstruct-symbol docstruct)
1841 (put reftex-docstruct-symbol 'modified t)))
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)
1847 file-found tmp include-file
1848 (level 1)
1849 (highest-level 100)
1850 toc-entry next-buf buf)
1851
1852 (catch 'exit
1853 (setq file-found (reftex-locate-file file "tex" master-dir))
1854 (if (and (not file-found)
1855 (setq buf (reftex-get-buffer-visiting file)))
1856 (setq file-found (buffer-file-name buf)))
1857
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 ..."
1900 (car (rassoc level reftex-section-levels))
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
1908 (setq include-file (reftex-match-string 7))
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))
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)
1925 ;; A macro with label
1926 (save-excursion
1927 (let* ((mac (reftex-match-string 10))
1928 (label (progn (goto-char (match-end 10))
1929 (save-match-data
1930 (reftex-no-props
1931 (reftex-nth-arg-wrapper
1932 mac)))))
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))))
1942 (push entry docstruct))))
1943 (t (error "This should not happen (reftex-parse-from-file)")))
1944 )
1945
1946 ;; Find bibliography statement
1947 (when (setq tmp (reftex-locate-bibliography-files master-dir))
1948 (push (cons 'bib tmp) docstruct))
1949
1950 (goto-char 1)
1951 (when (re-search-forward
1952 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\begin{thebibliography}" nil t)
1953 (push (cons 'thebib file) docstruct))
1954
1955 ;; Find external document specifications
1956 (goto-char 1)
1957 (while (re-search-forward "[\n\r][ \t]*\\\\externaldocument\\(\\[\\([^]]*\\)\\]\\)?{\\([^}]+\\)}" nil t)
1958 (push (list 'xr-doc (reftex-match-string 2)
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
1971 (defun reftex-locate-bibliography-files (master-dir &optional files)
1972 ;; Scan buffer for bibliography macro and return file list.
1973
1974 (unless files
1975 (save-excursion
1976 (goto-char (point-min))
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))
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)
2034 ;; Set all toc markers in the first N entries in list to nil
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)
2042 "Perform ACTION on the parse file (the .rel file).
2043 Valid actions are: readable, restore, read, kill, write."
2044 (let* ((list (symbol-value reftex-docstruct-symbol))
2045 (docstruct-symbol reftex-docstruct-symbol)
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)
2055 (put reftex-docstruct-symbol 'modified nil)
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
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
2066 (error "No restore file %s" file)))
2067 ((eq action 'read)
2068 (put reftex-docstruct-symbol 'modified nil)
2069 (if (file-exists-p file)
2070 ;; load the file and return t for success
2071 (condition-case nil
2072 (progn
2073 (load-file file)
2074 (reftex-check-parse-consistency)
2075 t)
2076 (error (message "Error while restoring file %s" file)
2077 (set reftex-docstruct-symbol nil)
2078 nil))
2079 ;; return nil for failure, but no exception
2080 nil))
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)))
2086 (t
2087 (put docstruct-symbol 'modified nil)
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))
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))
2113 (insert "))\n\n")
2114 (save-buffer 0)
2115 (kill-buffer (current-buffer)))
2116 (error "Cannot write to file %s" file)))
2117 t))))
2118
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
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))))
2155
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))))
2164
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))
2170 (level (cdr (assoc macro reftex-section-levels-all)))
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))
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)))
2181
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))))
2191
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)
2210
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))
2217
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.")))))))
2222
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)))
2228 (parse (nth 2 (assoc env-or-mac reftex-env-or-mac-alist)))
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)))
2233
2234 (defun reftex-in-comment ()
2235 (save-excursion
2236 (skip-chars-backward "^%\n\r")
2237 (eq (preceding-char) ?%)))
2238
2239 (defun reftex-short-context (env parse &optional bound derive)
2240 ;; Get about one line of useful context for the label definition at point.
2241
2242 (if (consp parse)
2243 (setq parse (if derive (cdr parse) (car parse))))
2244
2245 (reftex-nicify-text
2246
2247 (cond
2248
2249 ((null parse)
2250 (save-excursion
2251 (reftex-context-substring)))
2252
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))))
2273
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")))
2281
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 ""))
2289
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"))))
2298
2299 (defun reftex-nicify-text (text)
2300 ;; Make TEXT nice for inclusion as context into label menu.
2301 ;; 1. remove line breaks and extra white space
2302 (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text)
2303 (setq text (replace-match " " nil t text)))
2304 ;; 2. cut before the next `\end{' or `\item' or `\\'
2305 (if (string-match "\\(\\\\end{\\|\\\\item\\|\\\\\\\\\\).*" text)
2306 (setq text (replace-match "" nil t text)))
2307 ;; 3. kill the embedded label
2308 (if (string-match "\\\\label{[^}]*}" text)
2309 (setq text (replace-match "" nil t text)))
2310 ;; 4. remove leading garbage
2311 (if (string-match "\\`[ }]+" text)
2312 (setq text (replace-match "" nil t text)))
2313 ;; 5. limit length
2314 (cond
2315 ((> (length text) 100) (substring text 0 100))
2316 ((= (length text) 0) (make-string 1 ?\ ))
2317 (t text)))
2318
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).
2323
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
2372 (member (list 'eof (reftex-locate-file
2373 (reftex-match-string 7) "tex"
2374 (cdr (assq 'master-dir docstruct))))
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))))
2388
2389 (defun reftex-label-location (&optional bound)
2390 "Return the environment or macro which determines the label type at point.
2391 If optional BOUND is an integer, limit backward searches to that point."
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))
2399 (if (>= p1 p2)
2400 (progn
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))))
2404 (or (car loc2) "section"))))
2405
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))
2424
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.
2430 (cond
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)))
2439
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)))
2455
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))))
2459
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.
2463
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*\\\\"))
2466
2467 (if (= n 1000)
2468 ;; Special case: Skip all touching arguments
2469 (progn
2470 (reftex-move-over-touching-args)
2471 (reftex-context-substring))
2472
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))))
2489
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))))
2497
2498 (defun reftex-move-over-touching-args ()
2499 (condition-case nil
2500 (while (memq (following-char) '(?\[ ?\{))
2501 (forward-list 1))
2502 (error nil)))
2503
2504 (defun reftex-context-substring ()
2505 ;; Return up to 150 chars from point
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
2521 ;; no list - just grab 150 characters
2522 (buffer-substring-no-properties (point)
2523 (min (+ (point) 150) (point-max))))))
2524
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.
2599 When RELATIVE is non-nil, give file names relative to directory
2600 of 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.
2618 If ENVIRONMENT is given, don't bother to find out yourself.
2619 If NO-INSERT is non-nil, do not insert label into buffer.
2620 With prefix arg, force to rescan document first.
2621 When you are prompted to enter or confirm a label, and you reply with
2622 just the prefix or an empty string, no label at all will be inserted.
2623 A new label is also recorded into the label list.
2624 This 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.
2775 Uses `reftex-derive-label-parameters' and `reftex-label-illegal-re'. It
2776 also 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.
2792 SPLIT-RE is the regular expression used to split the string into words.
2793 ILLEGAL-RE matches characters which are illegal in the final string.
2794 DOT t means add dots to abbreviated words.
2795 KEEP-FP t means to keep a final punctuation when applicable.
2796 NWORDS Number of words to use.
2797 MAXCHAR Maximum number of characters in the final string.
2798 ILLEGAL nil: Throw away any words containing stuff matched with ILLEGAL-RE.
2799 t: Throw away only the matched part, not the whole word.
2800 ABBREV 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.
2804 SEP String separating different words in the output string.
2805 IGNORE-WORDS List of words which should be removed from the string."
2806
2807 (let* ((words0 (split-string string (or split-re "[ \t\n\r]")))
2808 (reftex-label-illegal-re (or illegal-re "\000"))
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)) ?.)))
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))
2823 ((string-match reftex-label-illegal-re word)
2824 (when illegal
2825 (while (string-match reftex-label-illegal-re word)
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
2846 (lambda (w) (if (string-match abbrev-re w)
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
2865 (defun reftex-latin1-to-ascii (string)
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 "")))
2878
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.
2955 This keymap can be used to configure the label selection process which is
2956 started with the command \\[reftex-reference].")
2957
2958 (defun reftex-select-label-mode ()
2959 "Major mode for selecting a label in a LaTeX document.
2960 This buffer was created with RefTeX.
2961 It only has a meaningful keymap when you are in the middle of a
2962 selection process.
2963 To select a label, move the cursor to it and press RET.
2964 Press `?' for a summary of important key bindings.
2965
2966 During 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.
2983 With prefix arg, force to rescan buffer for labels. This should only be
2984 necessary if you have recently entered labels yourself without using
2985 reftex-label. Rescanning of the buffer can also be requested from the
2986 label selection menu.
2987 The function returns the selected label or nil.
2988 If NO-INSERT is non-nil, do not insert \\ref command, just return label.
2989 When 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)
2995
2996 ;; Ensure access to scanning info and rescan buffer if prefix are is '(4)
2997 (reftex-access-scan-info current-prefix-arg)
2998
2999 (unless type
3000 ;; guess type from context
3001 (if (and reftex-guess-label-type
3002 (setq type (reftex-guess-label-type)))
3003 (setq cut (cdr type)
3004 type (car type))
3005 (setq type (reftex-query-label-type))))
3006
3007 (let* ((varioref (if (reftex-typekey-check
3008 type reftex-vref-is-default)
3009 "\\vref" "\\ref"))
3010 (form "\\ref{%s}")
3011 label pair)
3012
3013 ;; Have the user select a label
3014 (set-marker reftex-select-return-marker (point))
3015 (setq pair (save-excursion
3016 (reftex-offer-label-menu type)))
3017 (reftex-ensure-compiled-variables)
3018 (set-marker reftex-select-return-marker nil)
3019 (setq label (car pair)
3020 type (cdr pair)
3021 form (or (cdr (assoc type reftex-typekey-to-format-alist))
3022 form))
3023
3024 (if (and label
3025 (not no-insert))
3026 (progn
3027 (if cut (backward-delete-char cut))
3028
3029 ;; remove ~ if we do already have a space
3030 (when (and (= ?~ (string-to-char form))
3031 (member (preceding-char) '(?\ ?\t ?\n)))
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))))
3037 ;; ok, insert the reference
3038 (insert
3039 (if reftex-format-ref-function
3040 (funcall reftex-format-ref-function label form)
3041 (format form label label)))
3042 (message ""))
3043 (message "Quit"))
3044 ;; return the label
3045 label))
3046
3047 (defun reftex-guess-label-type ()
3048 ;; Examine context to guess what a \ref might want to reference.
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
3061 (defun reftex-offer-label-menu (typekey)
3062 ;; Offer a menu with the appropriate labels. Return (label . typekey).
3063 (let* ((buf (current-buffer))
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)))
3068 (here-I-am1 here-I-am)
3069 (toc (reftex-typekey-check typekey reftex-label-menu-flags 0))
3070 (files (reftex-typekey-check typekey reftex-label-menu-flags 7))
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))
3077 (commented (nth 5 reftex-label-menu-flags))
3078 (prefix "")
3079 selection-buffers
3080 offset rtn key data last-data entry)
3081
3082 (setq entry (cons nil nil))
3083
3084 (unwind-protect
3085 (catch 'exit
3086 (while t
3087 (save-window-excursion
3088 (delete-other-windows)
3089 (setq reftex-call-back-to-this-buffer buf
3090 reftex-latex-syntax-table (syntax-table))
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))
3101 (add-to-list 'selection-buffers (current-buffer))
3102 (setq truncate-lines t)
3103 (setq mode-line-format
3104 (list "---- " 'mode-line-buffer-identification
3105 " " 'varioref
3106 " " (abbreviate-file-name
3107 (buffer-file-name buf))
3108 " -%-"))
3109 (cond
3110 ((= 0 (buffer-size))
3111 (let ((buffer-read-only nil))
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))))
3117 (here-I-am
3118 (setq offset (reftex-get-offset buf here-I-am typekey)))
3119 (t (setq offset t)))
3120 (setq buffer-read-only t)
3121 (setq offset (or offset t))
3122
3123 (setq here-I-am nil) ; turn off determination of offset
3124 (setq rtn
3125 (reftex-select-item
3126 reftex-select-label-prompt
3127 reftex-select-label-help
3128 reftex-select-label-map
3129 offset
3130 'reftex-show-label-location follow))
3131 (setq key (car rtn)
3132 data (nth 1 rtn)
3133 last-data (nth 2 rtn)
3134 offset t)
3135 (unless key (throw 'exit nil))
3136 (cond
3137 ((eq key ?g)
3138 ;; update buffer
3139 (reftex-erase-buffer))
3140 ((or (eq key ?r)
3141 (eq key ?R))
3142 ;; rescan buffer
3143 (reftex-erase-buffer)
3144 (reftex-reparse-document buf last-data key))
3145 ((eq key ?c)
3146 ;; toggle context mode
3147 (reftex-erase-buffer)
3148 (setq context (not context)))
3149 ((eq key ?s)
3150 ;; switch type
3151 (setq here-I-am here-I-am1)
3152 (setq typekey (reftex-query-label-type)))
3153 ((eq key ?t)
3154 ;; toggle table of contents display
3155 (reftex-erase-buffer)
3156 (setq toc (not toc)))
3157 ((eq key ?i)
3158 ;; toggle display of included file borders
3159 (reftex-erase-buffer)
3160 (setq files (not files)))
3161 ((eq key ?#)
3162 ;; toggle counter display
3163 (reftex-erase-buffer)
3164 (setq counter (not counter)))
3165 ((eq key ?%)
3166 ;; toggle display of commented labels
3167 (reftex-erase-buffer)
3168 (setq commented (not commented)))
3169 ((eq key ?l)
3170 ;; reuse the last referenced label again
3171 (setq entry reftex-last-used-reference)
3172 (throw 'exit t))
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
3178 (cdr (nth xr-index xr-alist)))
3179 (error "Cannot switch document"))
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))
3188 (t
3189 (set-buffer buf)
3190 (if data
3191 (progn
3192 (setq entry data)
3193 (setq reftex-last-used-reference entry))
3194 (setq entry nil))
3195 (throw 'exit t))))))
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)))))
3201 (mapcar (function (lambda (buf)
3202 (and (buffer-live-p buf)
3203 (bury-buffer buf))))
3204 selection-buffers)
3205 (reftex-kill-temporary-buffers))
3206 (cons (if (nth 0 entry) (concat prefix (nth 0 entry)) nil)
3207 (nth 1 entry))))
3208
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)))))
3257
3258 (defun reftex-make-selection-buffer-name (type &optional index)
3259 ;; Make unique name for a selection buffer.
3260 (format " *RefTeX[%s][%d]*"
3261 type (or index (get reftex-docstruct-symbol :master-index) 0)))
3262
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.
3289 ;; Return the data property of the entry corresponding to HERE-I-AM.
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.
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)
3320
3321 ;; Pop to buffer buf to get the correct buffer-local variables
3322 (save-excursion
3323 (set-buffer buf)
3324
3325 ;; Ensure access to scanning info
3326 (reftex-access-scan-info)
3327
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))))))
3334
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))
3339
3340 ;; Walk the docstruct and insert the appropriate stuff
3341 (while (setq cell (pop all))
3342
3343 (incf index)
3344 (setq from (point))
3345
3346 (if (eq cell here-I-am) (setq offset 'attention))
3347
3348 (cond
3349
3350 ((memq (car cell) '(bib thebib label-numbers appendix
3351 master-dir bibview-cache is-multi xr xr-doc)))
3352 ;; These are currently ignored
3353
3354 ((memq (car cell) '(bof eof file-error))
3355 ;; Beginning or end of a file
3356 (when files
3357 (if (eq offset 'attention) (setq offset cell))
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")))
3365 (setq to (point))
3366 (when font
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))
3373 (put-text-property from to :data cell))))
3374
3375 ((eq (car cell) 'toc)
3376 ;; a table of contents entry
3377 (when toc
3378 (if (eq offset 'attention) (setq offset cell))
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))
3385 (when toc-buffer
3386 (if mouse-face
3387 (put-text-property from (1- to)
3388 'mouse-face mouse-face))
3389 (put-text-property from to :data cell))
3390 (goto-char to)))
3391
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))
3398
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))
3404
3405 (when (and labels
3406 (or (string= typekey typekey0) (string= typekey0 " "))
3407 (or show-commented (null comment)))
3408
3409 ;; Yes we want this one
3410 (incf cnt)
3411 (if (eq offset 'attention) (setq offset cell))
3412
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))
3424
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))
3430
3431 (when context
3432 (insert context-indent text "\n")
3433 (setq to (point)))
3434 (put-text-property from to :data cell)
3435 (when mouse-face
3436 (put-text-property from (1- to)
3437 'mouse-face mouse-face))
3438 (goto-char to)))))
3439
3440 (when (reftex-refontify)
3441 ;; we need to fontify the buffer
3442 (reftex-fontify-select-label-buffer buf))
3443 (run-hooks 'reftex-display-copied-context-hook)
3444 offset))
3445
3446 (defun reftex-find-start-point (fallback &rest locations)
3447 ;; Set point to the first available LOCATION. When a LOCATION is a list,
3448 ;; search for such a :data text property. When it is an integer,
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)
3459 (setq pos (text-property-any (point-min) (point-max) :data loc))
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
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)))
3476
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.
3486 (let* ((this-window (selected-window))
3487 (errorf (if error 'error 'message))
3488 label file buffer re found)
3489
3490 (catch 'exit
3491 (setq label (nth 0 data)
3492 file (nth 3 data))
3493
3494 (unless file
3495 (funcall errorf "Unknown label - reparse might help")
3496 (throw 'exit nil))
3497
3498 ;; Goto the file in another window
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..
3509 (funcall errorf "Label %s not found" label)
3510 (throw 'exit nil))
3511
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))
3520 (unless (setq found (re-search-forward re nil t))
3521 ;; Ooops. Must be in a macro with distributed args.
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))
3530 (recenter '(4))
3531 (unless stay (select-window this-window)))
3532 (select-window this-window)
3533 (funcall errorf "Label %s not found" label))
3534 found)))
3535
3536 (defun reftex-show-entry (beg-hlt end-hlt)
3537 ;; Show entry if point is hidden
3538 (let* ((n (/ (reftex-window-height) 2))
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))))
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 ;;; =========================================================================
3575 ;;;
3576 ;;; Table of contents
3577
3578 ;; We keep at most one *toc* buffer - it is easy to make them
3579
3580 (defvar reftex-toc-map (make-sparse-keymap)
3581 "Keymap used for *toc* buffer.")
3582
3583 (defun reftex-toc-mode ()
3584 "Major mode for managing Table of Contents for LaTeX files.
3585 This buffer was created with RefTeX.
3586 Press `?' for a summary of important key bindings.
3587
3588 Here 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
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
3609 "Stores the file name from which `reftex-toc' was called. For redo command.")
3610
3611 (defvar reftex-last-window-height nil)
3612
3613 (defvar reftex-toc-return-marker (make-marker)
3614 "Marker which makes it possible to return from toc to old position.")
3615
3616 (defconst reftex-toc-help
3617 " AVAILABLE KEYS IN TOC BUFFER
3618 ============================
3619 n / p next-line / previous-line
3620 SPC Show the corresponding section of the LaTeX document.
3621 TAB Goto the section and keep the *toc* window.
3622 RET Goto the section and hide the *toc* window (also on mouse-2).
3623 q / Q Hide/Kill *toc* buffer, return to position of last reftex-toc command.
3624 l c i Toggle display of [l]abels, [c]ontext, [i]nclude file borders.
3625 f / g Toggle follow mode on and off / Refresh *toc* buffer.
3626 r / R Reparse the LaTeX document / Reparse entire LaTeX document.
3627 . In other window, show position from where `reftex-toc' was called.
3628 x Switch to TOC of external document (with LaTeX package `xr').")
3629
3630 (defun reftex-toc (&optional rebuild)
3631 "Show the table of contents for the current document.
3632 When called with a raw C-u prefix, rescan the document first."
3633
3634 (interactive)
3635
3636 (if (or (not (string= reftex-last-toc-master (reftex-TeX-master-file)))
3637 current-prefix-arg)
3638 (reftex-erase-buffer "*toc*"))
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
3645 ;; If follow mode is active, arrange to delay it one command
3646 (if reftex-toc-follow-mode
3647 (setq reftex-toc-follow-mode 1))
3648
3649 ;; Ensure access to scanning info and rescan buffer if prefix are is '(4)
3650 (reftex-access-scan-info current-prefix-arg)
3651
3652 (let* ((this-buf (current-buffer))
3653 (xr-data (assq 'xr (symbol-value reftex-docstruct-symbol)))
3654 (xr-alist (cons (cons "" (buffer-file-name)) (nth 1 xr-data)))
3655 (here-I-am (if rebuild
3656 (get 'reftex-toc :reftex-data)
3657 (car (reftex-where-am-I))))
3658 offset)
3659
3660 (if (get-buffer-window "*toc*")
3661 (select-window (get-buffer-window "*toc*"))
3662 (when (or (not reftex-toc-keep-other-windows)
3663 (< (window-height) (* 2 window-min-height)))
3664 (delete-other-windows))
3665 (setq reftex-last-window-height (window-height)) ; remember
3666 (split-window)
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))
3671
3672 (cond
3673 ((= (buffer-size) 0)
3674 ;; buffer is empty - fill it with the table of contents
3675 (message "Building *toc* buffer...")
3676
3677 (setq buffer-read-only nil)
3678 (insert (format
3679 "TABLE-OF-CONTENTS on %s
3680 SPC=view TAB=goto RET=goto+hide [q]uit [r]escan [l]abels [f]ollow [x]r [?]Help
3681 ------------------------------------------------------------------------------
3682 " (abbreviate-file-name reftex-last-toc-master)))
3683
3684 (if (reftex-use-fonts)
3685 (put-text-property 1 (point) 'face reftex-toc-header-face))
3686 (put-text-property 1 (point) 'intangible t)
3687 (put-text-property 1 2 'xr-alist xr-alist)
3688
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
3701 (run-hooks 'reftex-display-copied-context-hook)
3702 (message "Building *toc* buffer...done.")
3703 (setq buffer-read-only t))
3704 (t
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))))
3714 (put 'reftex-toc :reftex-line 3)
3715 (goto-line 3)
3716 (beginning-of-line)))
3717
3718 ;; Find the correct starting point
3719 (reftex-find-start-point (point) offset (get 'reftex-toc :reftex-line))
3720 (setq reftex-last-follow-point (point))))
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
3729 (when (get-text-property (point) :data)
3730 (put 'reftex-toc :reftex-data (get-text-property (point) :data))
3731 (and (> (point) 1)
3732 (not (get-text-property (point) 'intangible))
3733 (memq reftex-highlight-selection '(cursor both))
3734 (reftex-highlight 1
3735 (or (previous-single-property-change (1+ (point)) :data)
3736 (point-min))
3737 (or (next-single-property-change (point) :data)
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)))))
3749
3750 (defun reftex-re-enlarge ()
3751 ;; Enlarge windiw to a remembered size
3752 (enlarge-window
3753 (max 0 (- (or reftex-last-window-height (window-height))
3754 (window-height)))))
3755
3756 (defun reftex-toc-show-help ()
3757 "Show a summary of special key bindings."
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)))
3764
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))
3770 (goto-char (or (next-single-property-change (point) :data)
3771 (point))))
3772 (defun reftex-toc-previous (&optional arg)
3773 "Move to previous selectable item."
3774 (interactive "p")
3775 (setq reftex-callback-fwd nil)
3776 (goto-char (or (previous-single-property-change (point) :data)
3777 (point))))
3778 (defun reftex-toc-toggle-follow ()
3779 "Toggle follow (other window follows with context)."
3780 (interactive)
3781 (setq reftex-last-follow-point -1)
3782 (setq reftex-toc-follow-mode (not reftex-toc-follow-mode)))
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.
3796 Label 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))
3800 (defun reftex-toc-view-line ()
3801 "View document location in other window."
3802 (interactive)
3803 (reftex-toc-visit-location))
3804 (defun reftex-toc-mouse-view-line (ev)
3805 "View document location in other window."
3806 (interactive "e")
3807 (mouse-set-point ev)
3808 (reftex-toc-visit-location))
3809 (defun reftex-toc-goto-line-and-hide ()
3810 "Go to document location in other window. Hide the *toc* window."
3811 (interactive)
3812 (reftex-toc-visit-location 'hide))
3813 (defun reftex-toc-goto-line ()
3814 "Go to document location in other window. *toc* window stays."
3815 (interactive)
3816 (reftex-toc-visit-location t))
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)
3821 (reftex-toc-visit-location 'hide))
3822 (defun reftex-toc-show-calling-point ()
3823 "Show point where reftex-toc was called from."
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))
3831 (recenter '(4)))
3832 (select-window this-window))))
3833 (defun reftex-toc-quit ()
3834 "Hide the *toc* window and do not move point."
3835 (interactive)
3836 (or (one-window-p) (delete-window))
3837 (switch-to-buffer (marker-buffer reftex-toc-return-marker))
3838 (reftex-re-enlarge)
3839 (goto-char (or (marker-position reftex-toc-return-marker) (point))))
3840 (defun reftex-toc-quit-and-kill ()
3841 "Kill the *toc* buffer."
3842 (interactive)
3843 (kill-buffer "*toc*")
3844 (or (one-window-p) (delete-window))
3845 (switch-to-buffer (marker-buffer reftex-toc-return-marker))
3846 (reftex-re-enlarge)
3847 (goto-char (marker-position reftex-toc-return-marker)))
3848 (defun reftex-toc-rescan (&rest ignore)
3849 "Regenerate the *toc* buffer by reparsing file of section at point."
3850 (interactive)
3851 (if reftex-enable-partial-scans
3852 (let* ((data (get-text-property (point) :data))
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))))
3858 (if (not file)
3859 (error "Don't know which file to rescan. Try `R'")
3860 (put 'reftex-toc :reftex-line line)
3861 (switch-to-buffer-other-window
3862 (reftex-get-file-buffer-force file))
3863 (setq current-prefix-arg '(4))
3864 (reftex-toc t)))
3865 (reftex-toc-Rescan))
3866 (reftex-kill-temporary-buffers))
3867 (defun reftex-toc-Rescan (&rest ignore)
3868 "Regenerate the *toc* buffer by reparsing the entire document."
3869 (interactive)
3870 (switch-to-buffer-other-window
3871 (reftex-get-file-buffer-force reftex-last-toc-file))
3872 (setq current-prefix-arg '(16))
3873 (reftex-toc t))
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))
3879 (reftex-erase-buffer "*toc*")
3880 (setq current-prefix-arg nil)
3881 (reftex-toc t))
3882 (defun reftex-toc-external (&rest ignore)
3883 "Switch to table of contents of an external document."
3884 (interactive)
3885 (let* ((old-buf (current-buffer))
3886 (xr-alist (get-text-property 1 'xr-alist))
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")))
3892 (reftex-toc)
3893 (if (equal old-buf (current-buffer))
3894 (message "")
3895 (message "Switched document"))))
3896
3897 (defun reftex-toc-visit-location (&optional final no-revisit)
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.
3901 ;; Otherwise, move cursor back into *toc* window.
3902 ;; NO-REVISIT means don't visit files, just use live biffers.
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
3907 (let* ((toc (get-text-property (point) :data))
3908 (toc-window (selected-window))
3909 show-window show-buffer match)
3910
3911 (unless toc (error "Don't know which toc line to visit"))
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))))
3935
3936 (setq show-window (selected-window)
3937 show-buffer (current-buffer))
3938
3939 (unless match
3940 (select-window toc-window)
3941 (error "Cannot find location"))
3942
3943 (select-window toc-window)
3944
3945 ;; use the `final' parameter to decide what to do next
3946 (cond
3947 ((eq final t)
3948 (reftex-unhighlight 0)
3949 (select-window show-window))
3950 ((eq final 'hide)
3951 (reftex-unhighlight 0)
3952 (or (one-window-p) (delete-window))
3953 (switch-to-buffer show-buffer)
3954 (reftex-re-enlarge))
3955 (t nil))))
3956
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
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 ;;; =========================================================================
4015 ;;;
4016 ;;; BibTeX citations.
4017
4018 ;; Variables and constants
4019
4020 ;; The history list of regular expressions used for citations
4021 (defvar reftex-cite-regexp-hist nil)
4022
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
4027 (defconst reftex-citation-help
4028 " n / p Go to next/previous entry (Cursor motion works as well).
4029 C-s / C-r Search forward/backward. Use repeated C-s/C-r as in isearch.
4030 g / r Start over with new regexp / Refine with additional regexp.
4031 SPC Show full database entry in other window.
4032 f Toggle follow mode: Other window will follow with full db entry.
4033 . Show insertion point.
4034 q Quit without inserting \\cite macro into buffer.
4035 TAB Enter citation key with completion.
4036 RET Accept current entry (also on mouse-2)
4037 a / A Put all entries into single \cite / into many cite commands.")
4038
4039 (defvar reftex-select-bib-map nil
4040 "Keymap used for *RefTeX Select* buffer, when selecting a BibTeX entry.
4041 This keymap can be used to configure the BibTeX selection process which is
4042 started with the command \\[reftex-citation].")
4043
4044 (defun reftex-select-bib-mode ()
4045 "Major mode for selecting a citation key in a LaTeX document.
4046 This buffer was created with RefTeX.
4047 It only has a meaningful keymap when you are in the middle of a
4048 selection process.
4049 In order to select a citation, move the cursor to it and press RET.
4050 Press `?' for a summary of important key bindings.
4051
4052 During 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
4064 ;; Find bibtex files
4065
4066 (defun reftex-get-bibfile-list ()
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.
4072
4073 ;; Ensure access to scanning info
4074 (reftex-access-scan-info)
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)))
4086 (error "\\bibliography statement missing or .bib files not found")))
4087
4088 ;; Find a certain reference in any of the BibTeX files.
4089
4090 (defun reftex-pop-to-bibtex-entry (key file-list &optional mark-to-kill
4091 highlight item return)
4092 ;; Find BibTeX KEY in any file in FILE-LIST in another window.
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.
4096 ;; If RETURN is non-nil, just return the entry.
4097
4098 (let* ((re
4099 (if item
4100 (concat "\\\\bibitem\\(\\[[^]]*\\]\\)?{" (regexp-quote key) "}")
4101 (concat "@[a-zA-Z]+[ \t\n\r]*[{(][ \t\n\r]*" (regexp-quote key)
4102 "[, \t\r\n}]")))
4103 (window-conf (current-window-configuration))
4104 file buf)
4105
4106 (catch 'exit
4107 (switch-to-buffer-other-window (current-buffer))
4108 (while file-list
4109 (setq file (car file-list)
4110 file-list (cdr file-list))
4111 (unless (setq buf (reftex-get-file-buffer-force file mark-to-kill))
4112 (error "No such file %s" file))
4113 (switch-to-buffer buf)
4114 (widen)
4115 (goto-char (point-min))
4116 (when (re-search-forward re nil t)
4117 (goto-char (match-beginning 0))
4118 (when return
4119 ;; Just return the relevant entry
4120 (if item (goto-char (match-end 0)))
4121 (setq return (buffer-substring
4122 (point) (reftex-end-of-bib-entry item)))
4123 (set-window-configuration window-conf)
4124 (throw 'exit return))
4125 (recenter 0)
4126 (if highlight
4127 (reftex-highlight 0 (match-beginning 0) (match-end 0)))
4128 (throw 'exit (selected-window))))
4129 (set-window-configuration window-conf)
4130 (if item
4131 (error "No \\bibitem with citation key %s" key)
4132 (error "No BibTeX entry with citation key %s" key)))))
4133
4134 (defun reftex-end-of-bib-entry (item)
4135 (save-excursion
4136 (condition-case nil
4137 (if item
4138 (progn (end-of-line)
4139 (re-search-forward
4140 "\\\\bibitem\\|\\end{thebibliography}")
4141 (1- (match-beginning 0)))
4142 (progn (forward-list 1) (point)))
4143 (error (min (point-max) (+ 300 (point)))))))
4144
4145 ;; Parse bibtex buffers
4146
4147 (defun reftex-extract-bib-entries (buffers)
4148 ;; Extract bib entries which match regexps from BUFFERS.
4149 ;; BUFFERS is a list of buffers or file names.
4150 ;; Return list with entries."
4151 (let* (re-list first-re rest-re
4152 (buffer-list (if (listp buffers) buffers (list buffers)))
4153 found-list entry buffer1 buffer alist
4154 key-point start-point end-point)
4155
4156 ;; Read a regexp, completing on known citation keys.
4157 (setq re-list
4158 (split-string
4159 (completing-read
4160 "RegExp [ && RegExp...]: "
4161 (if reftex-mode
4162 (if (fboundp 'LaTeX-bibitem-list)
4163 (LaTeX-bibitem-list)
4164 (cdr (assoc 'bibview-cache
4165 (symbol-value reftex-docstruct-symbol))))
4166 nil)
4167 nil nil nil 'reftex-cite-regexp-hist)
4168 "[ \t]*&&[ \t]*"))
4169
4170 (setq first-re (car re-list) ; We'll use the first re to find things,
4171 rest-re (cdr re-list)) ; the others to narrow down.
4172 (if (string-match "\\`[ \t]*\\'" (or first-re ""))
4173 (error "Empty regular expression"))
4174
4175 (save-excursion
4176 (save-window-excursion
4177
4178 ;; Walk through all bibtex files
4179 (while buffer-list
4180 (setq buffer (car buffer-list)
4181 buffer-list (cdr buffer-list))
4182 (if (and (bufferp buffer)
4183 (buffer-live-p buffer))
4184 (setq buffer1 buffer)
4185 (setq buffer1 (reftex-get-file-buffer-force
4186 buffer (not reftex-keep-temporary-buffers))))
4187 (if (not buffer1)
4188 (message "No such BibTeX file %s (ignored)" buffer)
4189 (message "Scanning bibliography database %s" buffer1))
4190
4191 (set-buffer buffer1)
4192 (save-excursion
4193 (goto-char (point-min))
4194 (while (re-search-forward first-re nil t)
4195 (catch 'search-again
4196 (setq key-point (point))
4197 (unless (re-search-backward
4198 "\\(\\`\\|[\n\r]\\)[ \t]*@\\([a-zA-Z]+\\)[ \t\n\r]*[{(]" nil t)
4199 (throw 'search-again nil))
4200 (setq start-point (point))
4201 (goto-char (match-end 0))
4202 (condition-case nil
4203 (up-list 1)
4204 (error (goto-char key-point)
4205 (throw 'search-again nil)))
4206 (setq end-point (point))
4207
4208 ;; Ignore @string, @comment and @c entries or things
4209 ;; outside entries
4210 (when (or (string= (downcase (match-string 2)) "string")
4211 (string= (downcase (match-string 2)) "comment")
4212 (string= (downcase (match-string 2)) "c")
4213 (< (point) key-point)) ; this means match not in {}
4214 (goto-char key-point)
4215 (throw 'search-again nil))
4216
4217 ;; Well, we have got a match
4218 (setq entry (concat
4219 (buffer-substring start-point (point)) "\n"))
4220
4221 ;; Check if other regexp match as well
4222 (setq re-list rest-re)
4223 (while re-list
4224 (unless (string-match (car re-list) entry)
4225 ;; nope - move on
4226 (throw 'search-again nil))
4227 (pop re-list))
4228
4229 (setq alist (reftex-parse-bibtex-entry
4230 nil start-point end-point))
4231 (push (cons "&entry" entry) alist)
4232
4233 ;; check for crossref entries
4234 (if (assoc "crossref" alist)
4235 (setq alist
4236 (append
4237 alist (reftex-get-crossref-alist alist))))
4238
4239 ;; format the entry
4240 (push (cons "&formatted" (reftex-format-bib-entry alist))
4241 alist)
4242
4243 ;; make key the first element
4244 (push (reftex-get-bib-field "&key" alist) alist)
4245
4246 ;; add it to the list
4247 (push alist found-list))))
4248 (reftex-kill-temporary-buffers))))
4249 (setq found-list (nreverse found-list))
4250
4251 ;; Sorting
4252 (cond
4253 ((eq 'author reftex-sort-bibtex-matches)
4254 (sort found-list 'reftex-bib-sort-author))
4255 ((eq 'year reftex-sort-bibtex-matches)
4256 (sort found-list 'reftex-bib-sort-year))
4257 ((eq 'reverse-year reftex-sort-bibtex-matches)
4258 (sort found-list 'reftex-bib-sort-year-reverse))
4259 (t found-list))))
4260
4261 (defun reftex-bib-sort-author (e1 e2)
4262 (let ((al1 (reftex-get-bib-names "author" e1))
4263 (al2 (reftex-get-bib-names "author" e2)))
4264 (while (and al1 al2 (string= (car al1) (car al2)))
4265 (pop al1)
4266 (pop al2))
4267 (if (and (stringp (car al1))
4268 (stringp (car al2)))
4269 (string< (car al1) (car al2))
4270 (not (stringp (car al1))))))
4271
4272 (defun reftex-bib-sort-year (e1 e2)
4273 (< (string-to-int (cdr (assoc "year" e1)))
4274 (string-to-int (cdr (assoc "year" e2)))))
4275
4276 (defun reftex-bib-sort-year-reverse (e1 e2)
4277 (> (string-to-int (or (cdr (assoc "year" e1)) "0"))
4278 (string-to-int (or (cdr (assoc "year" e2)) "0"))))
4279
4280 (defun reftex-get-crossref-alist (entry)
4281 ;; return the alist from a crossref entry
4282 (let ((crkey (cdr (assoc "crossref" entry)))
4283 start)
4284 (save-excursion
4285 (save-restriction
4286 (widen)
4287 (if (re-search-forward
4288 (concat "@\\w+[{(][ \t\n\r]*" (regexp-quote crkey)
4289 "[ \t\n\r]*,") nil t)
4290 (progn
4291 (setq start (match-beginning 0))
4292 (condition-case nil
4293 (up-list 1)
4294 (error nil))
4295 (reftex-parse-bibtex-entry nil start (point)))
4296 nil)))))
4297
4298 ;; Parse the thebibliography environment
4299 (defun reftex-extract-bib-entries-from-thebibliography (file)
4300 ;; Extract bib-entries from the \begin{thebibliography} environment.
4301 ;; Parsing is not as good as for the BibTeX database stuff.
4302 ;; The environment should be located in file FILE.
4303
4304 (let* (start end buf entries re re-list)
4305 (unless file
4306 (error "Need file name to find thebibliography environment"))
4307 (setq buf (reftex-get-file-buffer-force
4308 file (not reftex-keep-temporary-buffers)))
4309 (unless buf
4310 (error "No such file %s" file))
4311 (message "Scanning thebibliography environment in %s" file)
4312
4313 (save-excursion
4314 (set-buffer buf)
4315 (save-restriction
4316 (widen)
4317 (goto-char (point-min))
4318 (if (re-search-forward
4319 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\begin{thebibliography}" nil t)
4320 (progn
4321 (beginning-of-line 2)
4322 (setq start (point))))
4323 (if (re-search-forward
4324 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\end{thebibliography}" nil t)
4325 (progn
4326 (beginning-of-line 1)
4327 (setq end (point))))
4328 (when (and start end)
4329 (setq entries
4330 (mapcar 'reftex-parse-bibitem
4331 (delete ""
4332 (split-string
4333 (buffer-substring-no-properties start end)
4334 "[ \t\n\r]*\\\\bibitem\\(\\[[^]]*]\\)*")))))))
4335 (unless entries
4336 (error "No bibitems found"))
4337
4338 (setq re-list (split-string
4339 (read-string "RegExp [ && RegExp...]: "
4340 nil 'reftex-cite-regexp-hist)
4341 "[ \t]*&&[ \t]*"))
4342 (if (string-match "\\`[ \t]*\\'" (car re-list))
4343 (error "Empty regular expression"))
4344
4345 (while (and (setq re (pop re-list)) entries)
4346 (setq entries
4347 (delq nil (mapcar
4348 (function
4349 (lambda (x)
4350 (if (string-match re (cdr (assoc "&entry" x)))
4351 x nil)))
4352 entries))))
4353 (setq entries
4354 (mapcar
4355 (lambda (x)
4356 (push (cons "&formatted" (reftex-format-bibitem x)) x)
4357 (push (reftex-get-bib-field "&key" x) x)
4358 x)
4359 entries))
4360
4361 entries))
4362
4363 ;; Parse and format individual entries
4364
4365 (defun reftex-get-bib-names (field entry)
4366 ;; Return a list with the author or editor names in ENTRY
4367 (let ((names (reftex-get-bib-field field entry)))
4368 (if (equal "" names)
4369 (setq names (reftex-get-bib-field "editor" entry)))
4370 (while (string-match "\\band\\b[ \t]*" names)
4371 (setq names (replace-match "\n" nil t names)))
4372 (while (string-match "[\\.a-zA-Z\\-]+\\.[ \t]*\\|,.*\\|[{}]+" names)
4373 (setq names (replace-match "" nil t names)))
4374 (while (string-match "^[ \t]+\\|[ \t]+$" names)
4375 (setq names (replace-match "" nil t names)))
4376 (while (string-match "[ \t][ \t]+" names)
4377 (setq names (replace-match " " nil t names)))
4378 (split-string names "\n")))
4379
4380 (defun reftex-parse-bibtex-entry (entry &optional from to)
4381 (let (alist key start field)
4382 (save-excursion
4383 (save-restriction
4384 (if entry
4385 (progn
4386 (set-buffer (get-buffer-create " *RefTeX-scratch*"))
4387 (fundamental-mode)
4388 (erase-buffer)
4389 (insert entry))
4390 (widen)
4391 (narrow-to-region from to))
4392 (goto-char (point-min))
4393
4394 (if (re-search-forward
4395 "@\\(\\w+\\)[ \t\n\r]*[{(][ \t\n\r]*\\([^ \t\n\r,]+\\)" nil t)
4396 (setq alist
4397 (list
4398 (cons "&type" (downcase (reftex-match-string 1)))
4399 (cons "&key" (reftex-match-string 2)))))
4400 (while (re-search-forward "\\(\\w+\\)[ \t\n\r]*=[ \t\n\r]*" nil t)
4401 (setq key (downcase (reftex-match-string 1)))
4402 (cond
4403 ((= (following-char) ?{)
4404 (forward-char 1)
4405 (setq start (point))
4406 (condition-case nil
4407 (up-list 1)
4408 (error nil)))
4409 ((= (following-char) ?\")
4410 (forward-char 1)
4411 (setq start (point))
4412 (while (and (search-forward "\"" nil t)
4413 (= ?\\ (char-after (- (point) 2))))))
4414 (t
4415 (setq start (point))
4416 (re-search-forward "[ \t]*[\n\r,}]" nil 1)))
4417 (setq field (buffer-substring-no-properties start (1- (point))))
4418 ;; remove extra whitespace
4419 (while (string-match "[\n\t\r]\\|[ \t][ \t]+" field)
4420 (setq field (replace-match " " nil t field)))
4421 ;; remove leading garbage
4422 (if (string-match "^[ \t{]+" field)
4423 (setq field (replace-match "" nil t field)))
4424 ;; remove trailing garbage
4425 (if (string-match "[ \t}]+$" field)
4426 (setq field (replace-match "" nil t field)))
4427 (push (cons key field) alist))))
4428 alist))
4429
4430 (defun reftex-get-bib-field (fieldname entry &optional format)
4431 ;; Extract the field FIELDNAME from an ENTRY
4432 (let ((cell (assoc fieldname entry)))
4433 (if cell
4434 (if format
4435 (format format (cdr cell))
4436 (cdr cell))
4437 "")))
4438
4439 (defun reftex-format-bib-entry (entry)
4440 ;; Format a BibTeX ENTRY so that it is nice to look at
4441 (let*
4442 ((auth-list (reftex-get-bib-names "author" entry))
4443 (authors (mapconcat 'identity auth-list ", "))
4444 (year (reftex-get-bib-field "year" entry))
4445 (title (reftex-get-bib-field "title" entry))
4446 (type (reftex-get-bib-field "&type" entry))
4447 (key (reftex-get-bib-field "&key" entry))
4448 (extra
4449 (cond
4450 ((equal type "article")
4451 (concat (reftex-get-bib-field "journal" entry) " "
4452 (reftex-get-bib-field "volume" entry) ", "
4453 (reftex-get-bib-field "pages" entry)))
4454 ((equal type "book")
4455 (concat "book (" (reftex-get-bib-field "publisher" entry) ")"))
4456 ((equal type "phdthesis")
4457 (concat "PhD: " (reftex-get-bib-field "school" entry)))
4458 ((equal type "mastersthesis")
4459 (concat "Master: " (reftex-get-bib-field "school" entry)))
4460 ((equal type "inbook")
4461 (concat "Chap: " (reftex-get-bib-field "chapter" entry)
4462 ", pp. " (reftex-get-bib-field "pages" entry)))
4463 ((or (equal type "conference")
4464 (equal type "incollection")
4465 (equal type "inproceedings"))
4466 (reftex-get-bib-field "booktitle" entry "in: %s"))
4467 (t ""))))
4468 (setq authors (reftex-truncate authors 30 t t))
4469 (when (reftex-use-fonts)
4470 (put-text-property 0 (length key) 'face
4471 (reftex-verified-face reftex-label-face
4472 'font-lock-constant-face
4473 'font-lock-reference-face)
4474 key)
4475 (put-text-property 0 (length authors) 'face reftex-bib-author-face
4476 authors)
4477 (put-text-property 0 (length year) 'face reftex-bib-year-face
4478 year)
4479 (put-text-property 0 (length title) 'face reftex-bib-title-face
4480 title)
4481 (put-text-property 0 (length extra) 'face reftex-bib-extra-face
4482 extra))
4483 (concat key "\n " authors " " year " " extra "\n " title "\n\n")))
4484
4485 (defun reftex-parse-bibitem (item)
4486 ;; Parse a \bibitem entry
4487 (let ((key "") (text ""))
4488 (when (string-match "\\`{\\([^}]+\\)}\\([\001-\255]*\\)" item)
4489 (setq key (match-string 1 item)
4490 text (match-string 2 item)))
4491 ;; Clean up the text a little bit
4492 (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text)
4493 (setq text (replace-match " " nil t text)))
4494 (if (string-match "\\`[ \t]+" text)
4495 (setq text (replace-match "" nil t text)))
4496 (list
4497 (cons "&key" key)
4498 (cons "&text" text)
4499 (cons "&entry" (concat key " " text)))))
4500
4501 (defun reftex-format-bibitem (item)
4502 ;; Format a \bibitem entry so that it is (relatively) nice to look at.
4503 (let ((text (reftex-get-bib-field "&text" item))
4504 (key (reftex-get-bib-field "&key" item))
4505 (lines nil))
4506
4507 ;; Wrap the text into several lines.
4508 (while (and (> (length text) 70)
4509 (string-match " " (substring text 60)))
4510 (push (substring text 0 (+ 60 (match-beginning 0))) lines)
4511 (setq text (substring text (+ 61 (match-beginning 0)))))
4512 (push text lines)
4513 (setq text (mapconcat 'identity (nreverse lines) "\n "))
4514
4515 (when (reftex-use-fonts)
4516 (put-text-property 0 (length text) 'face reftex-bib-author-face text))
4517 (concat key "\n " text "\n\n")))
4518
4519 ;; Make a citation
4520
4521 ;;;###autoload
4522 (defun reftex-citation (&optional no-insert)
4523 "Make a citation using BibTeX database files.
4524 After prompting for a regular expression, scans the buffers with
4525 bibtex entries (taken from the \\bibliography command) and offers the
4526 matching entries for selection. The selected entry is formated according
4527 to `reftex-cite-format' and inserted into the buffer.
4528
4529 If NO-INSERT is non-nil, nothing is inserted, only the selected key returned.
4530
4531 When called with one or two `C-u' prefixes, first rescans the document.
4532 When called with a numeric prefix, make that many citations. When
4533 called with point inside the braces of a `\cite' command, it will
4534 add another key, ignoring the value of `reftex-cite-format'.
4535
4536 The regular expression uses an expanded syntax: && is interpreted as `and'.
4537 Thus, `aaaa&&bbb' matches entries which contain both `aaaa' and `bbb'.
4538 While entering the regexp, completion on knows citation keys is possible.
4539 `=' is a good regular expression to match all entries in all files."
4540
4541 (interactive)
4542
4543 ;; check for recursive edit
4544 (reftex-check-recursive-edit)
4545
4546 ;; This function may also be called outside reftex-mode.
4547 ;; Thus look for the scanning info only if in reftex-mode.
4548
4549 (when reftex-mode
4550 (reftex-access-scan-info current-prefix-arg))
4551
4552 ;; Call reftex-do-citation, but protected
4553 (unwind-protect
4554 (reftex-do-citation current-prefix-arg no-insert)
4555 (reftex-kill-temporary-buffers)))
4556
4557 (defun reftex-do-citation (&optional arg no-insert)
4558 ;; This really does the work of reftex-citation.
4559
4560 (let* ((format (reftex-figure-out-cite-format arg no-insert))
4561 (docstruct-symbol reftex-docstruct-symbol)
4562 (selected-entries (reftex-offer-bib-menu))
4563 (insert-entries selected-entries)
4564 entry string cite-view)
4565
4566 (unless selected-entries (error "Quit"))
4567
4568 (if (stringp selected-entries)
4569 ;; Nonexistent entry
4570 (setq selected-entries nil
4571 insert-entries (list (list selected-entries
4572 (cons "&key" selected-entries))))
4573 ;; It makes sense to compute the cite-view strings.
4574 (setq cite-view t))
4575
4576 (when (eq (car selected-entries) 'concat)
4577 ;; All keys go into a single command - we need to trick a little
4578 (pop selected-entries)
4579 (let ((concat-keys (mapconcat 'car selected-entries ",")))
4580 (setq insert-entries
4581 (list (list concat-keys (cons "&key" concat-keys))))))
4582
4583 (unless no-insert
4584
4585 ;; We shall insert this into the buffer...
4586 (message "Formatting...")
4587
4588 (while (setq entry (pop insert-entries))
4589 ;; Format the citation and insert it
4590 (setq string (if reftex-format-cite-function
4591 (funcall reftex-format-cite-function
4592 (reftex-get-bib-field "&key" entry)
4593 format)
4594 (reftex-format-citation entry format)))
4595 (insert string))
4596
4597 ;; Reposition cursor?
4598 (when (string-match "\\?" string)
4599 (search-backward "?")
4600 (delete-char 1))
4601
4602 ;; Tell AUCTeX
4603 (when (and reftex-mode
4604 (fboundp 'LaTeX-add-bibitems)
4605 reftex-plug-into-AUCTeX)
4606 (apply 'LaTeX-add-bibitems (mapcar 'car selected-entries)))
4607
4608 ;; Produce the cite-view strings
4609 (when (and reftex-mode reftex-cache-cite-echo cite-view)
4610 (mapcar (lambda (entry)
4611 (reftex-make-cite-echo-string entry docstruct-symbol))
4612 selected-entries))
4613
4614 (message ""))
4615
4616 (set-marker reftex-select-return-marker nil)
4617 (reftex-kill-buffer "*RefTeX Select*")
4618
4619 ;; Check if the prefix arg was numeric, and call recursively
4620 (when (integerp arg)
4621 (if (> arg 1)
4622 (progn
4623 (skip-chars-backward "}")
4624 (decf arg)
4625 (reftex-do-citation arg))
4626 (forward-char 1)))
4627
4628 ;; Return the citation key
4629 (car (car selected-entries))))
4630
4631 (defun reftex-figure-out-cite-format (arg no-insert)
4632 ;; Check if there is already a cite command at point and change cite format
4633 ;; in order to only add another reference in the same cite command.
4634 (let ((macro (car (reftex-what-macro 1)))
4635 (cite-format-value (reftex-get-cite-format))
4636 key format)
4637 (cond
4638 (no-insert
4639 ;; Format does not really matter because nothing will be inserted.
4640 (setq format "%l"))
4641
4642 ((and (stringp macro)
4643 (string-match "\\`\\\\cite\\|cite\\'" macro))
4644 ;; We are already inside a cite macro
4645 (if (or (not arg) (not (listp arg)))
4646 (setq format
4647 (concat
4648 (if (member (preceding-char) '(?\{ ?,)) "" ",")
4649 "%l"
4650 (if (member (following-char) '(?\} ?,)) "" ",")))
4651 (setq format "%l")))
4652 (t
4653 ;; Figure out the correct format
4654 (setq format
4655 (if (and (symbolp cite-format-value)
4656 (assq cite-format-value reftex-cite-format-builtin))
4657 (nth 2 (assq cite-format-value reftex-cite-format-builtin))
4658 cite-format-value))
4659 (when (listp format)
4660 (setq key
4661 (reftex-select-with-char
4662 "" (concat "SELECT A CITATION FORMAT\n\n"
4663 (mapconcat
4664 (lambda (x)
4665 (format "[%c] %s %s" (car x)
4666 (if (> (car x) 31) " " "")
4667 (cdr x)))
4668 format "\n"))))
4669 (if (assq key format)
4670 (setq format (cdr (assq key format)))
4671 (error "No citation format associated with key `%c'" key)))))
4672 format))
4673
4674 (defun reftex-get-cite-format ()
4675 ;; Return the current citation format. Either the document-local value in
4676 ;; reftex-cite-format-symbol, or the global value in reftex-cite-format.
4677 (if (and reftex-docstruct-symbol
4678 (symbolp reftex-docstruct-symbol)
4679 (get reftex-docstruct-symbol 'reftex-cite-format))
4680 (get reftex-docstruct-symbol 'reftex-cite-format)
4681 reftex-cite-format))
4682
4683 (defun reftex-offer-bib-menu ()
4684 ;; Offer bib menu and return list of selected items
4685
4686 (let (found-list rtn key data selected-entries)
4687 (while
4688 (not
4689 (catch 'done
4690 ;; Scan bibtex files
4691 (setq found-list
4692 (cond
4693 ((assq 'bib (symbol-value reftex-docstruct-symbol))
4694 ;; using BibTeX database files.
4695 (reftex-extract-bib-entries (reftex-get-bibfile-list)))
4696 ((assq 'thebib (symbol-value reftex-docstruct-symbol))
4697 ;; using thebibliography environment.
4698 (reftex-extract-bib-entries-from-thebibliography
4699 (cdr (assq 'thebib (symbol-value reftex-docstruct-symbol)))))
4700 (reftex-default-bibliography
4701 (message "Using default bibliography")
4702 (reftex-extract-bib-entries (reftex-default-bibliography)))
4703 (t (error "No valid bibliography in this document, and no default available"))))
4704
4705 (unless found-list
4706 (error "Sorry, no matches found"))
4707
4708 ;; Remember where we came from
4709 (setq reftex-call-back-to-this-buffer (current-buffer))
4710 (set-marker reftex-select-return-marker (point))
4711
4712 ;; Offer selection
4713 (save-window-excursion
4714 (delete-other-windows)
4715 (let ((default-major-mode 'reftex-select-bib-mode))
4716 (reftex-kill-buffer "*RefTeX Select*")
4717 (switch-to-buffer-other-window "*RefTeX Select*")
4718 (unless (eq major-mode 'reftex-select-bib-mode)
4719 (reftex-select-bib-mode))
4720 (let ((buffer-read-only nil))
4721 (erase-buffer)
4722 (reftex-insert-bib-matches found-list)))
4723 (setq buffer-read-only t)
4724 (if (= 0 (buffer-size))
4725 (error "No matches found"))
4726 (setq truncate-lines t)
4727 (goto-char 1)
4728 (while t
4729 (setq rtn
4730 (reftex-select-item
4731 reftex-citation-prompt
4732 reftex-citation-help
4733 reftex-select-bib-map
4734 nil
4735 'reftex-bibtex-selection-callback nil))
4736 (setq key (car rtn)
4737 data (nth 1 rtn))
4738 (unless key (throw 'done t))
4739 (cond
4740 ((eq key ?g)
4741 ;; Start over
4742 (throw 'done nil))
4743 ((eq key ?r)
4744 ;; Restrict with new regular expression
4745 (setq found-list (reftex-restrict-bib-matches found-list))
4746 (let ((buffer-read-only nil))
4747 (erase-buffer)
4748 (reftex-insert-bib-matches found-list))
4749 (goto-char 1))
4750 ((eq key ?A)
4751 (debug)
4752 ;; Take all
4753 (setq selected-entries found-list)
4754 (throw 'done t))
4755 ((eq key ?a)
4756 ;; Take all
4757 (setq selected-entries (cons 'concat found-list))
4758 (throw 'done t))
4759 ((or (eq key ?\C-m)
4760 (eq key 'return))
4761 ;; Take selected
4762 (setq selected-entries (if data (list data) nil))
4763 (throw 'done t))
4764 ((stringp key)
4765 ;; Got this one with completion
4766 (setq selected-entries key)
4767 (throw 'done t))
4768 (t
4769 (ding))))))))
4770 selected-entries))
4771
4772 (defun reftex-restrict-bib-matches (found-list)
4773 ;; Limit FOUND-LIST with more regular expressions
4774 (let ((re-list (split-string (read-string
4775 "RegExp [ && RegExp...]: "
4776 nil 'reftex-cite-regexp-hist)
4777 "[ \t]*&&[ \t]*"))
4778 (found-list-r found-list)
4779 re)
4780 (while (setq re (pop re-list))
4781 (setq found-list-r
4782 (delq nil
4783 (mapcar
4784 (lambda (x)
4785 (if (string-match
4786 re (cdr (assoc "&entry" x)))
4787 x
4788 nil))
4789 found-list-r))))
4790 (if found-list-r
4791 found-list-r
4792 (ding)
4793 found-list)))
4794
4795 (defun reftex-insert-bib-matches (list)
4796 ;; Insert the bib matches and number them correctly
4797 (let ((mouse-face
4798 (if (memq reftex-highlight-selection '(mouse both))
4799 reftex-mouse-selected-face
4800 nil))
4801 tmp len)
4802 (mapcar
4803 (function
4804 (lambda (x)
4805 (setq tmp (cdr (assoc "&formatted" x))
4806 len (length tmp))
4807 (put-text-property 0 len :data x tmp)
4808 (put-text-property 0 (1- len) 'mouse-face mouse-face tmp)
4809 (insert tmp)))
4810 list))
4811 (run-hooks 'reftex-display-copied-context-hook))
4812
4813 (defun reftex-format-names (namelist n)
4814 (let (last (len (length namelist)))
4815 (cond
4816 ((< len 1) "")
4817 ((= 1 len) (car namelist))
4818 ((> len n) (concat (car namelist) (nth 2 reftex-cite-punctuation)))
4819 (t
4820 (setq n (min len n)
4821 last (nth (1- n) namelist))
4822 (setcdr (nthcdr (- n 2) namelist) nil)
4823 (concat
4824 (mapconcat 'identity namelist (nth 0 reftex-cite-punctuation))
4825 (nth 1 reftex-cite-punctuation)
4826 last)))))
4827
4828 (defun reftex-format-citation (entry format)
4829 ;; Format a citation from the info in the BibTeX ENTRY
4830
4831 (unless (stringp format) (setq format "\\cite{%l}"))
4832
4833 (if (and reftex-comment-citations
4834 (string-match "%l" reftex-cite-comment-format))
4835 (error "reftex-cite-comment-format contains illegal %%l"))
4836
4837 (while (string-match
4838 "\\(\\`\\|[^%]\\)\\(\\(%\\([0-9]*\\)\\([a-zA-Z]\\)\\)[.,;: ]*\\)"
4839 format)
4840 (let ((n (string-to-int (match-string 4 format)))
4841 (l (string-to-char (match-string 5 format)))
4842 rpl b e)
4843 (save-match-data
4844 (setq rpl
4845 (cond
4846 ((= l ?l) (concat
4847 (reftex-get-bib-field "&key" entry)
4848 (if reftex-comment-citations
4849 reftex-cite-comment-format
4850 "")))
4851 ((= l ?a) (reftex-format-names
4852 (reftex-get-bib-names "author" entry)
4853 (or n 2)))
4854 ((= l ?A) (car (reftex-get-bib-names "author" entry)))
4855 ((= l ?b) (reftex-get-bib-field "booktitle" entry "in: %s"))
4856 ((= l ?B) (reftex-abbreviate-title
4857 (reftex-get-bib-field "booktitle" entry "in: %s")))
4858 ((= l ?c) (reftex-get-bib-field "chapter" entry))
4859 ((= l ?d) (reftex-get-bib-field "edition" entry))
4860 ((= l ?e) (reftex-format-names
4861 (reftex-get-bib-names "editor" entry)
4862 (or n 2)))
4863 ((= l ?E) (car (reftex-get-bib-names "editor" entry)))
4864 ((= l ?h) (reftex-get-bib-field "howpublished" entry))
4865 ((= l ?i) (reftex-get-bib-field "institution" entry))
4866 ((= l ?j) (reftex-get-bib-field "journal" entry))
4867 ((= l ?k) (reftex-get-bib-field "key" entry))
4868 ((= l ?m) (reftex-get-bib-field "month" entry))
4869 ((= l ?n) (reftex-get-bib-field "number" entry))
4870 ((= l ?o) (reftex-get-bib-field "organization" entry))
4871 ((= l ?p) (reftex-get-bib-field "pages" entry))
4872 ((= l ?P) (car (split-string
4873 (reftex-get-bib-field "pages" entry)
4874 "[- .]+")))
4875 ((= l ?s) (reftex-get-bib-field "school" entry))
4876 ((= l ?u) (reftex-get-bib-field "publisher" entry))
4877 ((= l ?r) (reftex-get-bib-field "address" entry))
4878 ((= l ?t) (reftex-get-bib-field "title" entry))
4879 ((= l ?T) (reftex-abbreviate-title
4880 (reftex-get-bib-field "title" entry)))
4881 ((= l ?v) (reftex-get-bib-field "volume" entry))
4882 ((= l ?y) (reftex-get-bib-field "year" entry)))))
4883
4884 (if (string= rpl "")
4885 (setq b (match-beginning 2) e (match-end 2))
4886 (setq b (match-beginning 3) e (match-end 3)))
4887 (setq format (concat (substring format 0 b) rpl (substring format e)))))
4888 (while (string-match "%%" format)
4889 (setq format (replace-match "%" t t format)))
4890 (while (string-match "[ ,.;:]*%<" format)
4891 (setq format (replace-match "" t t format)))
4892 format)
4893
4894 (defun reftex-bibtex-selection-callback (data ignore no-revisit)
4895 ;; Callback function to be called from the BibTeX selection, in
4896 ;; order to display context. This function is relatively slow and not
4897 ;; recommended for follow mode. It works OK for individual lookups.
4898 (let ((win (selected-window))
4899 (key (reftex-get-bib-field "&key" data))
4900 bibfile-list item tmp)
4901
4902 (catch 'exit
4903 (save-excursion
4904 (set-buffer reftex-call-back-to-this-buffer)
4905 (cond
4906 ((assq 'bib (symbol-value reftex-docstruct-symbol))
4907 (setq bibfile-list (reftex-get-bibfile-list)))
4908 ((setq tmp (assq 'thebib (symbol-value reftex-docstruct-symbol)))
4909 (setq bibfile-list (list (cdr tmp))
4910 item t))
4911 (reftex-default-bibliography
4912 (setq bibfile-list (reftex-default-bibliography)))
4913 (t (ding) (throw 'exit))))
4914
4915 (when no-revisit
4916 (setq bibfile-list (reftex-visited-files bibfile-list)))
4917
4918 (condition-case nil
4919 (reftex-pop-to-bibtex-entry
4920 key bibfile-list (not reftex-keep-temporary-buffers) t item)
4921 (error (ding))))
4922
4923 (select-window win)))
4924
4925 ;;; =========================================================================
4926 ;;;
4927 ;;; Here is the routine used for selection
4928
4929 ;; Marker for return point from recursive edit
4930 (defvar reftex-recursive-edit-marker (make-marker))
4931
4932 (defvar reftex-last-data nil)
4933 (defvar reftex-last-line nil)
4934
4935 (defun reftex-check-recursive-edit ()
4936 ;; Check if we are already in a recursive edit. Abort with helpful
4937 ;; message if so.
4938 (if (marker-position reftex-recursive-edit-marker)
4939 (error
4940 (substitute-command-keys
4941 "In unfinished selection process. Finish, or abort with \\[abort-recursive-edit]"))))
4942
4943 (defun reftex-select-item (prompt help-string keymap
4944 &optional offset
4945 call-back cb-flag)
4946 ;; Select an item, using PROMPT. The function returns a key indicating
4947 ;; an exit status, along with a data structure indicating which item was
4948 ;; selected.
4949 ;; HELP-STRING contains help. KEYMAP is a keymap with the available
4950 ;; selection commands.
4951 ;; OFFSET can be a label list item which will be selected at start.
4952 ;; When it is t, point will start out at the beginning of the buffer.
4953 ;; Any other value will cause restart where last selection left off.
4954 ;; When CALL-BACK is given, it is a function which is called with the index
4955 ;; of the element.
4956 ;; CB-FLAG is the initial value of that flag.
4957
4958 (let* (ev data last-data (selection-buffer (current-buffer)))
4959
4960 (setq ev
4961 (catch 'myexit
4962 (save-window-excursion
4963 (setq truncate-lines t)
4964
4965 ;; Find a good starting point
4966 (reftex-find-start-point
4967 (point-min) offset reftex-last-data reftex-last-line)
4968 (beginning-of-line 1)
4969 (set (make-local-variable 'reftex-last-follow-point) (point))
4970
4971 (unwind-protect
4972 (progn
4973 (use-local-map keymap)
4974 (add-hook 'pre-command-hook 'reftex-select-pre-command-hook nil t)
4975 (add-hook 'post-command-hook 'reftex-select-post-command-hook nil t)
4976 (princ prompt)
4977 (set-marker reftex-recursive-edit-marker (point))
4978 ;; XEmacs does not run post-command-hook here
4979 (and (featurep 'xemacs) (run-hooks 'post-command-hook))
4980 (recursive-edit))
4981
4982 (set-marker reftex-recursive-edit-marker nil)
4983 (save-excursion
4984 (set-buffer selection-buffer)
4985 (use-local-map nil)
4986 (remove-hook 'pre-command-hook 'reftex-select-pre-command-hook t)
4987 (remove-hook 'post-command-hook
4988 'reftex-select-post-command-hook t))))))
4989
4990 (set (make-local-variable 'reftex-last-line)
4991 (+ (count-lines (point-min) (point)) (if (bolp) 1 0)))
4992 (set (make-local-variable 'reftex-last-data) last-data)
4993 (reftex-kill-buffer "*RefTeX Help*")
4994 (setq reftex-callback-fwd (not reftex-callback-fwd)) ;; ;-)))
4995 (message "")
4996 (list ev data last-data)))
4997
4998 ;; The following variables are all bound dynamically in `reftex-select-item'.
4999 ;; The defvars are here only to silence the byte compiler.
5000
5001 (defvar found-list)
5002 (defvar cb-flag)
5003 (defvar data)
5004 (defvar prompt)
5005 (defvar last-data)
5006 (defvar call-back)
5007 (defvar help-string)
5008 (defvar varioref)
5009
5010 ;; The selection commands
5011
5012 (defun reftex-select-pre-command-hook ()
5013 (reftex-unhighlight 1)
5014 (reftex-unhighlight 0))
5015
5016 (defun reftex-select-post-command-hook ()
5017 (let (b e)
5018 (setq data (get-text-property (point) :data))
5019 (setq last-data (or data last-data))
5020
5021 (when (and data cb-flag
5022 (not (equal reftex-last-follow-point (point))))
5023 (setq reftex-last-follow-point (point))
5024 (funcall call-back data reftex-callback-fwd
5025 (not reftex-revisit-to-follow)))
5026 (if data
5027 (setq b (or (previous-single-property-change
5028 (1+ (point)) :data)
5029 (point-min))
5030 e (or (next-single-property-change
5031 (point) :data)
5032 (point-max)))
5033 (setq b (point) e (point)))
5034 (and (memq reftex-highlight-selection '(cursor both))
5035 (reftex-highlight 1 b e))
5036 (if (or (not (pos-visible-in-window-p b))
5037 (not (pos-visible-in-window-p e)))
5038 (recenter '(4)))
5039 (unless (current-message)
5040 (princ prompt))))
5041
5042 (defun reftex-select-next (&optional arg)
5043 "Move to next selectable item."
5044 (interactive "p")
5045 (setq reftex-callback-fwd t)
5046 (or (eobp) (forward-char 1))
5047 (re-search-forward "^[^. \t\n\r]" nil t arg)
5048 (beginning-of-line 1))
5049 (defun reftex-select-previous (&optional arg)
5050 "Move to previous selectable item."
5051 (interactive "p")
5052 (setq reftex-callback-fwd nil)
5053 (re-search-backward "^[^. \t\n\r]" nil t arg))
5054 (defun reftex-select-next-heading (&optional arg)
5055 "Move to next table of contentes line."
5056 (interactive "p")
5057 (end-of-line)
5058 (re-search-forward "^ " nil t arg)
5059 (beginning-of-line))
5060 (defun reftex-select-previous-heading (&optional arg)
5061 "Move to previous table of contentes line."
5062 (interactive "p")
5063 (re-search-backward "^ " nil t arg))
5064 (defun reftex-select-quit ()
5065 "Abort selection process."
5066 (interactive)
5067 (throw 'myexit nil))
5068 (defun reftex-select-keyboard-quit ()
5069 "Abort selection process."
5070 (interactive)
5071 (throw 'exit t))
5072 (defun reftex-select-jump-to-previous ()
5073 "Jump back to where previous selection process left off."
5074 (interactive)
5075 (let (pos)
5076 (cond
5077 ((and (local-variable-p 'reftex-last-data (current-buffer))
5078 reftex-last-data
5079 (setq pos (text-property-any (point-min) (point-max)
5080 :data reftex-last-data)))
5081 (goto-char pos))
5082 ((and (local-variable-p 'reftex-last-line (current-buffer))
5083 (integerp reftex-last-line))
5084 (goto-line reftex-last-line))
5085 (t (ding)))))
5086 (defun reftex-select-toggle-follow ()
5087 "Toggle follow mode: Other window follows with full context."
5088 (interactive)
5089 (setq reftex-last-follow-point -1)
5090 (setq cb-flag (not cb-flag)))
5091 (defun reftex-select-toggle-varioref ()
5092 "Toggle the macro used for referencing the label between \\ref and \\vref."
5093 (interactive)
5094 (if (string= varioref "\\ref")
5095 (setq varioref "\\vref")
5096 (setq varioref "\\ref"))
5097 (force-mode-line-update))
5098 (defun reftex-select-show-insertion-point ()
5099 "Show the point from where selection was started in another window."
5100 (interactive)
5101 (let ((this-window (selected-window)))
5102 (unwind-protect
5103 (progn
5104 (switch-to-buffer-other-window
5105 (marker-buffer reftex-select-return-marker))
5106 (goto-char (marker-position reftex-select-return-marker))
5107 (recenter '(4)))
5108 (select-window this-window))))
5109 (defun reftex-select-callback ()
5110 "Show full context in another window."
5111 (interactive)
5112 (if data (funcall call-back data reftex-callback-fwd nil) (ding)))
5113 (defun reftex-select-accept ()
5114 "Accept the currently selected item."
5115 (interactive)
5116 (throw 'myexit 'return))
5117 (defun reftex-select-mouse-accept (ev)
5118 "Accept the item at the mouse click."
5119 (interactive "e")
5120 (mouse-set-point ev)
5121 (setq data (get-text-property (point) :data))
5122 (setq last-data (or data last-data))
5123 (throw 'myexit 'return))
5124 (defun reftex-select-read-label ()
5125 "Use minibuffer to read a label to reference, with completion."
5126 (interactive)
5127 (let ((label (completing-read
5128 "Label: " (symbol-value reftex-docstruct-symbol)
5129 nil nil reftex-prefix)))
5130 (unless (or (equal label "") (equal label reftex-prefix))
5131 (throw 'myexit label))))
5132 (defun reftex-select-read-cite ()
5133 "Use minibuffer to read a citation key with completion."
5134 (interactive)
5135 (let* ((key (completing-read "Citation key: " found-list))
5136 (entry (assoc key found-list)))
5137 (cond
5138 ((or (null key) (equal key "")))
5139 (entry
5140 (setq data entry)
5141 (setq last-data data)
5142 (throw 'myexit 'return))
5143 (t (throw 'myexit key)))))
5144 (defun reftex-select-help ()
5145 "Display a summary of the special key bindings."
5146 (interactive)
5147 (with-output-to-temp-buffer "*RefTeX Help*"
5148 (princ help-string))
5149 (reftex-enlarge-to-fit "*RefTeX Help*" t))
5150
5151 ;;; =========================================================================
5152 ;;;
5153 ;;; View cross references
5154
5155 (defun reftex-view-crossref (&optional arg auto-how)
5156 "View cross reference of macro at point. Point must be on the KEY
5157 argument. When at at `\ref' macro, show corresponding `\label'
5158 definition, also in external documents (`xr'). When on a label, show
5159 a locations where KEY is referenced. Subsequent calls find additional
5160 locations. When on a `\cite', show the associated `\bibitem' macro or
5161 the BibTeX database entry. When on a `\bibitem', show a `\cite' macro
5162 which uses this KEY. When on an `\index', show other locations marked
5163 by the same index entry.
5164 To define additional cross referencing items, use the option
5165 `reftex-view-crossref-extra'. See also `reftex-view-crossref-from-bibtex'.
5166 With one or two C-u prefixes, enforce rescanning of the document.
5167 With argument 2, select the window showing the cross reference.
5168 AUTO-HOW is only for the automatic crossref display and is handed through
5169 to the functions `reftex-view-cr-cite' and `reftex-view-cr-ref'."
5170
5171 (interactive "P")
5172 ;; See where we are.
5173 (let* ((macro (car (reftex-what-macro 1)))
5174 (key (reftex-this-word "^{}%\n\r,"))
5175 dw)
5176
5177 (if (or (null macro) (reftex-in-comment))
5178 (error "Not on a crossref macro argument"))
5179
5180 (setq reftex-call-back-to-this-buffer (current-buffer))
5181
5182 (cond
5183 ((string-match "\\`\\\\cite\\|cite\\*?\\'" macro)
5184 ;; A citation macro: search for bibitems or BibTeX entries
5185 (setq dw (reftex-view-cr-cite arg key auto-how)))
5186 ((string-match "\\`\\\\ref\\|ref\\*?\\'" macro)
5187 ;; A reference macro: search for labels
5188 (setq dw (reftex-view-cr-ref arg key auto-how)))
5189 (auto-how nil) ;; No further action for automatic display (speed)
5190 ((or (equal macro "\\label")
5191 (member macro reftex-macros-with-labels))
5192 ;; A label macro: search for reference macros
5193 (reftex-access-scan-info arg)
5194 (setq dw (reftex-view-regexp-match
5195 (format reftex-find-reference-format (regexp-quote key))
5196 3 nil nil)))
5197 ((equal macro "\\bibitem")
5198 ;; A bibitem macro: search for citations
5199 (reftex-access-scan-info arg)
5200 (setq dw (reftex-view-regexp-match
5201 (format reftex-find-citation-regexp-format (regexp-quote key))
5202 3 nil nil)))
5203 (t
5204 (reftex-access-scan-info arg)
5205 (catch 'exit
5206 (let ((list reftex-view-crossref-extra)
5207 entry mre action group)
5208 (while (setq entry (pop list))
5209 (setq mre (car entry)
5210 action (nth 1 entry)
5211 group (nth 2 entry))
5212 (when (string-match mre macro)
5213 (setq dw (reftex-view-regexp-match
5214 (format action key) group nil nil))
5215 (throw 'exit t))))
5216 (error "Not on a crossref macro argument"))))
5217 (if (and (eq arg 2) (windowp dw)) (select-window dw))))
5218
5219 (defun reftex-view-cr-cite (arg key how)
5220 ;; View crossreference of a ref cite. HOW can have the values
5221 ;; nil: Show in another window.
5222 ;; echo: Show one-line info in echo area.
5223 ;; tmp-window: Show in small window and arrange for window to disappear.
5224
5225 ;; Ensure access to scanning info
5226 (reftex-access-scan-info (or arg current-prefix-arg))
5227
5228 (if (eq how 'tmp-window)
5229 ;; Remember the window configuration
5230 (put 'reftex-auto-view-crossref 'last-window-conf
5231 (current-window-configuration)))
5232
5233 (let (files size item (pos (point)) (win (selected-window)) pop-win)
5234 ;; Find the citation mode and the file list
5235 (cond
5236 ((assq 'bib (symbol-value reftex-docstruct-symbol))
5237 (setq item nil
5238 files (reftex-get-bibfile-list)))
5239 ((assq 'thebib (symbol-value reftex-docstruct-symbol))
5240 (setq item t
5241 files (list (cdr (assq 'thebib
5242 (symbol-value reftex-docstruct-symbol))))))
5243 (reftex-default-bibliography
5244 (setq item nil
5245 files (reftex-default-bibliography)))
5246 (how) ;; don't throw for special display
5247 (t (error "Cannot display crossref")))
5248
5249 (if (eq how 'echo)
5250 ;; Display in Echo area
5251 (reftex-echo-cite key files item)
5252 ;; Display in a window
5253 (if (not (eq how 'tmp-window))
5254 ;; Normal display
5255 (reftex-pop-to-bibtex-entry key files nil t item)
5256 ;; A temporary window
5257 (condition-case nil
5258 (reftex-pop-to-bibtex-entry key files nil t item)
5259 (error (goto-char pos)
5260 (message "cite: no such citation key %s" key)
5261 (error "")))
5262 ;; Resize the window
5263 (setq size (max 1 (count-lines (point)
5264 (reftex-end-of-bib-entry item))))
5265 (let ((window-min-height 2))
5266 (shrink-window (1- (- (window-height) size)))
5267 (recenter 0))
5268 ;; Arrange restoration
5269 (add-hook 'pre-command-hook 'reftex-restore-window-conf))
5270
5271 ;; Normal display in other window
5272 (add-hook 'pre-command-hook 'reftex-highlight-shall-die)
5273 (setq pop-win (selected-window))
5274 (select-window win)
5275 (goto-char pos)
5276 (when (equal arg 2)
5277 (select-window pop-win)))))
5278
5279 (defun reftex-view-cr-ref (arg label how)
5280 ;; View crossreference of a ref macro. HOW can have the values
5281 ;; nil: Show in another window.
5282 ;; echo: Show one-line info in echo area.
5283 ;; tmp-window: Show in small window and arrange for window to disappear.
5284
5285 ;; Ensure access to scanning info
5286 (reftex-access-scan-info (or arg current-prefix-arg))
5287
5288 (if (eq how 'tmp-window)
5289 ;; Remember the window configuration
5290 (put 'reftex-auto-view-crossref 'last-window-conf
5291 (current-window-configuration)))
5292
5293 (let* ((xr-data (assoc 'xr (symbol-value reftex-docstruct-symbol)))
5294 (xr-re (nth 2 xr-data))
5295 (entry (assoc label (symbol-value reftex-docstruct-symbol)))
5296 (win (selected-window)) pop-win (pos (point)))
5297
5298 (if (and (not entry) (stringp label) xr-re (string-match xr-re label))
5299 ;; Label is defined in external document
5300 (save-excursion
5301 (save-match-data
5302 (set-buffer
5303 (or (reftex-get-file-buffer-force
5304 (cdr (assoc (match-string 1 label) (nth 1
5305 xr-data))))
5306 (error "Problem with external label %s" label))))
5307 (setq label (substring label (match-end 1)))
5308 (reftex-access-scan-info)
5309 (setq entry
5310 (assoc label (symbol-value reftex-docstruct-symbol)))))
5311 (if (eq how 'echo)
5312 ;; Display in echo area
5313 (reftex-echo-ref label entry (symbol-value reftex-docstruct-symbol))
5314 (let ((window-conf (current-window-configuration)))
5315 (condition-case nil
5316 (reftex-show-label-location entry t nil t t)
5317 (error (set-window-configuration window-conf)
5318 (message "ref: Label %s not found" label)
5319 (error "ref: Label %s not found" label)))) ;; 2nd is line OK
5320 (add-hook 'pre-command-hook 'reftex-highlight-shall-die)
5321
5322 (when (eq how 'tmp-window)
5323 ;; Resize window and arrange restauration
5324 (shrink-window (1- (- (window-height) 9)))
5325 (recenter '(4))
5326 (add-hook 'pre-command-hook 'reftex-restore-window-conf))
5327 (setq pop-win (selected-window))
5328 (select-window win)
5329 (goto-char pos)
5330 (when (equal arg 2)
5331 (select-window pop-win)))))
5332
5333 (defun reftex-mouse-view-crossref (ev)
5334 "View cross reference of \\ref or \\cite macro where you click.
5335 If the macro at point is a \\ref, show the corresponding label definition.
5336 If it is a \\cite, show the BibTeX database entry.
5337 If there is no such macro at point, search forward to find one.
5338 With argument, actually select the window showing the cross reference."
5339 (interactive "e")
5340 (mouse-set-point ev)
5341 (reftex-view-crossref current-prefix-arg))
5342
5343 (defvar reftex-auto-view-crossref-timer nil
5344 "The timer used for auto-view-crossref.")
5345
5346 (defun reftex-view-crossref-when-idle ()
5347 ;; Display info about crossref at point in echo area or a window.
5348 ;; This function was desigend to work with an idle timer.
5349 ;; We try to get out of here as quickly as possible if the call is useless.
5350 (and reftex-mode
5351 ;; Make sure message area is free if we need it.
5352 (or (eq reftex-auto-view-crossref 'window) (not (current-message)))
5353 ;; Make sure we are not already displaying this one
5354 (not (memq last-command '(reftex-view-crossref
5355 reftex-mouse-view-crossref)))
5356 ;; Quick precheck if this might be a relevant spot
5357 ;; FIXME: Can fail with backslash in comment
5358 (save-excursion
5359 (search-backward "\\" nil t)
5360 (looking-at "\\\\[a-zA-Z]*\\(cite\\|ref\\)"))
5361
5362 (condition-case nil
5363 (let ((current-prefix-arg nil))
5364 (cond
5365 ((eq reftex-auto-view-crossref t)
5366 (reftex-view-crossref -1 'echo))
5367 ((eq reftex-auto-view-crossref 'window)
5368 (reftex-view-crossref -1 'tmp-window))
5369 (t nil)))
5370 (error nil))))
5371
5372 (defun reftex-restore-window-conf ()
5373 (set-window-configuration (get 'reftex-auto-view-crossref 'last-window-conf))
5374 (put 'reftex-auto-view-crossref 'last-window-conf nil)
5375 (remove-hook 'pre-command-hook 'reftex-restore-window-conf))
5376
5377 (defun reftex-echo-ref (label entry docstruct)
5378 ;; Display crossref info in echo area.
5379 (cond
5380 ((null docstruct)
5381 (message (substitute-command-keys (format reftex-no-info-message "ref"))))
5382 ((null entry)
5383 (message "ref: unknown label: %s" label))
5384 (t
5385 (when (stringp (nth 2 entry))
5386 (message "ref(%s): %s" (nth 1 entry) (nth 2 entry)))
5387 (let ((buf (get-buffer " *Echo Area*")))
5388 (when buf
5389 (save-excursion
5390 (set-buffer buf)
5391 (run-hooks 'reftex-display-copied-context-hook)))))))
5392
5393 (defun reftex-echo-cite (key files item)
5394 ;; Display citation info in echo area.
5395 (let* ((cache (assq 'bibview-cache (symbol-value reftex-docstruct-symbol)))
5396 (cache-entry (assoc key (cdr cache)))
5397 entry string buf (all-files files))
5398
5399 (if (and reftex-cache-cite-echo cache-entry)
5400 ;; We can just use the cache
5401 (setq string (cdr cache-entry))
5402
5403 ;; Need to look in the database
5404 (unless reftex-revisit-to-echo
5405 (setq files (reftex-visited-files files)))
5406
5407 (setq entry
5408 (condition-case nil
5409 (save-excursion
5410 (reftex-pop-to-bibtex-entry key files nil nil item t))
5411 (error
5412 (if (and files (= (length all-files) (length files)))
5413 (message "cite: no such database entry: %s" key)
5414 (message (substitute-command-keys
5415 (format reftex-no-info-message "cite"))))
5416 nil)))
5417 (when entry
5418 (if item
5419 (setq string (reftex-nicify-text entry))
5420 (setq string (reftex-make-cite-echo-string
5421 (reftex-parse-bibtex-entry entry)
5422 reftex-docstruct-symbol)))))
5423 (unless (or (null string) (equal string ""))
5424 (message "cite: %s" string))
5425 (when (setq buf (get-buffer " *Echo Area*"))
5426 (save-excursion
5427 (set-buffer buf)
5428 (run-hooks 'reftex-display-copied-context-hook)))))
5429
5430 (defun reftex-make-cite-echo-string (entry docstruct-symbol)
5431 ;; Format a bibtex entry for the echo area and cache the result.
5432 (let* ((key (reftex-get-bib-field "&key" entry))
5433 (string
5434 (let* ((reftex-cite-punctuation '(" " " & " " etal.")))
5435 (reftex-format-citation entry reftex-cite-view-format)))
5436 (cache (assq 'bibview-cache (symbol-value docstruct-symbol)))
5437 (cache-entry (assoc key (cdr cache))))
5438 (unless cache
5439 ;; This docstruct has no cache - make one.
5440 (set docstruct-symbol (cons (cons 'bibview-cache nil)
5441 (symbol-value docstruct-symbol))))
5442 (when reftex-cache-cite-echo
5443 (setq key (copy-sequence key))
5444 (set-text-properties 0 (length key) nil key)
5445 (set-text-properties 0 (length string) nil string)
5446 (if cache-entry
5447 (unless (string= (cdr cache-entry) string)
5448 (setcdr cache-entry string)
5449 (put reftex-docstruct-symbol 'modified t))
5450 (push (cons key string) (cdr cache))
5451 (put reftex-docstruct-symbol 'modified t)))
5452 string))
5453
5454 (defvar reftex-use-itimer-in-xemacs nil
5455 "*Non-nil means use the idle timers in XEmacs for crossref display.
5456 Currently, idle timer restart is broken and we use the post-command-hook.")
5457
5458 (defun reftex-toggle-auto-view-crossref ()
5459 "Toggle the automatic display of crossref information in the echo area.
5460 When active, leaving point idle in the argument of a \\ref or \\cite macro
5461 will display info in the echo area."
5462 (interactive)
5463 (if reftex-auto-view-crossref-timer
5464 (progn
5465 (if (featurep 'xemacs)
5466 (if reftex-use-itimer-in-xemacs
5467 (delete-itimer reftex-auto-view-crossref-timer)
5468 (remove-hook 'post-command-hook 'reftex-start-itimer-once))
5469 (cancel-timer reftex-auto-view-crossref-timer))
5470 (setq reftex-auto-view-crossref-timer nil)
5471 (message "Automatic display of crossref information was turned off"))
5472 (setq reftex-auto-view-crossref-timer
5473 (if (featurep 'xemacs)
5474 (if reftex-use-itimer-in-xemacs
5475 (start-itimer "RefTeX Idle Timer"
5476 'reftex-view-crossref-when-idle
5477 reftex-idle-time reftex-idle-time t)
5478 (add-hook 'post-command-hook 'reftex-start-itimer-once)
5479 t)
5480 (run-with-idle-timer
5481 reftex-idle-time t 'reftex-view-crossref-when-idle)))
5482 (unless reftex-auto-view-crossref
5483 (setq reftex-auto-view-crossref t))
5484 (message "Automatic display of crossref information was turned on")))
5485
5486 (defun reftex-start-itimer-once ()
5487 (and reftex-mode
5488 (not (itimer-live-p reftex-auto-view-crossref-timer))
5489 (setq reftex-auto-view-crossref-timer
5490 (start-itimer "RefTeX Idle Timer"
5491 'reftex-view-crossref-when-idle
5492 reftex-idle-time nil t))))
5493
5494 (defun reftex-view-crossref-from-bibtex (&optional arg)
5495 "View location in a LaTeX document which cites the BibTeX entry at point.
5496 Since BibTeX files can be used by many LaTeX documents, this function
5497 promps upon first use for a buffer in RefTeX mode. To reset this
5498 link to a document, call the function with with a prefix arg.
5499 Calling this function several times find successive citation locations."
5500 (interactive "P")
5501 (when arg
5502 ;; Break connection to reference buffer
5503 (remprop 'reftex-bibtex-view-cite-locations :ref-buffer))
5504 (let ((ref-buffer (get 'reftex-bibtex-view-cite-locations :ref-buffer)))
5505 ;; Establish connection to reference buffer
5506 (unless ref-buffer
5507 (setq ref-buffer
5508 (save-excursion
5509 (completing-read
5510 "Reference buffer: "
5511 (delq nil
5512 (mapcar
5513 (lambda (b)
5514 (set-buffer b)
5515 (if reftex-mode (list (buffer-name b)) nil))
5516 (buffer-list)))
5517 nil t)))
5518 (put 'reftex-bibtex-view-cite-locations :ref-buffer ref-buffer))
5519 ;; Search for citations
5520 (bibtex-beginning-of-entry)
5521 (if (looking-at
5522 "@[a-zA-Z]+[ \t\n\r]*[{(][ \t\n\r]*\\([^, \t\r\n}]+\\)")
5523 (progn
5524 (goto-char (match-beginning 1))
5525 (reftex-view-regexp-match
5526 (format reftex-find-citation-regexp-format
5527 (regexp-quote (match-string 1)))
5528 3 arg ref-buffer))
5529 (error "Cannot find citation key in BibTeX entry"))))
5530
5531 (defun reftex-view-regexp-match (re &optional highlight-group new ref-buffer)
5532 ;; Search for RE in current document or in the document of REF-BUFFER.
5533 ;; Continue the search, if the same re was searched last.
5534 ;; Highlight the group HIGHLIGHT-GROUP of the match.
5535 ;; When NEW is non-nil, start a new search regardless.
5536 ;; Match point is displayed in another window.
5537 ;; Upon success, returns the window which displays the match.
5538
5539 ;;; Decide if new search or continued search
5540 (let* ((oldprop (get 'reftex-view-regexp-match :props))
5541 (newprop (list (current-buffer) re))
5542 (cont (and (not new) (equal oldprop newprop)))
5543 (cnt (if cont (get 'reftex-view-regexp-match :cnt) 0))
5544 (current-window (selected-window))
5545 (window-conf (current-window-configuration))
5546 match pop-window)
5547 (switch-to-buffer-other-window (or ref-buffer (current-buffer)))
5548 ;; Search
5549 (condition-case nil
5550 (if cont
5551 (setq match (reftex-global-search-continue))
5552 (reftex-access-scan-info)
5553 (setq match (reftex-global-search re (reftex-all-document-files))))
5554 (error nil))
5555 ;; Evaluate the match.
5556 (if match
5557 (progn
5558 (put 'reftex-view-regexp-match :props newprop)
5559 (put 'reftex-view-regexp-match :cnt (incf cnt))
5560 (reftex-highlight 0 (match-beginning highlight-group)
5561 (match-end highlight-group))
5562 (add-hook 'pre-command-hook 'reftex-highlight-shall-die)
5563 (setq pop-window (selected-window)))
5564 (remprop 'reftex-view-regexp-match :props)
5565 (or cont (set-window-configuration window-conf)))
5566 (select-window current-window)
5567 (if match
5568 (progn
5569 (message "Match Nr. %s" cnt)
5570 pop-window)
5571 (if cont
5572 (error "No further matches (total number of matches: %d)" cnt)
5573 (error "No matches")))))
5574
5575 (defvar reftex-global-search-marker (make-marker))
5576 (defun reftex-global-search (regexp file-list)
5577 ;; Start a search for REGEXP in all files of FILE-LIST
5578 (put 'reftex-global-search :file-list file-list)
5579 (put 'reftex-global-search :regexp regexp)
5580 (move-marker reftex-global-search-marker nil)
5581 (reftex-global-search-continue))
5582
5583 (defun reftex-global-search-continue ()
5584 ;; Continue a global search started with `reftex-global-search'
5585 (unless (get 'reftex-global-search :file-list)
5586 (error "No global search to continue"))
5587 (let* ((file-list (get 'reftex-global-search :file-list))
5588 (regexp (get 'reftex-global-search :regexp))
5589 (buf (or (marker-buffer reftex-global-search-marker)
5590 (reftex-get-file-buffer-force (car file-list))))
5591 (pos (or (marker-position reftex-global-search-marker) 1))
5592 file)
5593 ;; Take up starting position
5594 (unless buf (error "No such buffer %s" buf))
5595 (switch-to-buffer buf)
5596 (widen)
5597 (goto-char pos)
5598 ;; Search and switch file if necessary
5599 (if (catch 'exit
5600 (while t
5601 (when (re-search-forward regexp nil t)
5602 (move-marker reftex-global-search-marker (point))
5603 (throw 'exit t))
5604 ;; No match - goto next file
5605 (pop file-list)
5606 (or file-list (throw 'exit nil))
5607 (setq file (car file-list)
5608 buf (reftex-get-file-buffer-force file))
5609 (unless buf (error "Cannot access file %s" file))
5610 (put 'reftex-global-search :file-list file-list)
5611 (switch-to-buffer buf)
5612 (widen)
5613 (goto-char 1)))
5614 t
5615 (move-marker reftex-global-search-marker nil)
5616 (error "All files processed"))))
5617
5618 ;;; =========================================================================
5619 ;;;
5620 ;;; Functions that check out the surroundings
5621
5622 (defun reftex-what-macro (which &optional bound)
5623 ;; Find out if point is within the arguments of any TeX-macro.
5624 ;; The return value is either ("\\macro" . (point)) or a list of them.
5625
5626 ;; If WHICH is nil, immediately return nil.
5627 ;; If WHICH is 1, return innermost enclosing macro.
5628 ;; If WHICH is t, return list of all macros enclosing point.
5629 ;; If WHICH is a list of macros, look only for those macros and return the
5630 ;; name of the first macro in this list found to enclose point.
5631 ;; If the optional BOUND is an integer, bound backwards directed
5632 ;; searches to this point. If it is nil, limit to nearest \section -
5633 ;; like statement.
5634
5635 ;; This function is pretty stable, but can be fooled if the text contains
5636 ;; things like \macro{aa}{bb} where \macro is defined to take only one
5637 ;; argument. As RefTeX cannot know this, the string "bb" would still be
5638 ;; considered an argument of macro \macro.
5639
5640 (unless reftex-section-regexp (reftex-compile-variables))
5641 (catch 'exit
5642 (if (null which) (throw 'exit nil))
5643 (let ((bound (or bound (save-excursion (re-search-backward
5644 reftex-section-regexp nil 1)
5645 (point))))
5646 pos cmd-list cmd cnt cnt-opt entry)
5647 (save-restriction
5648 (save-excursion
5649 (narrow-to-region (max 1 bound) (point-max))
5650 ;; move back out of the current parenthesis
5651 (while (condition-case nil
5652 (progn (up-list -1) t)
5653 (error nil))
5654 (setq cnt 1 cnt-opt 0)
5655 ;; move back over any touching sexps
5656 (while (and (reftex-move-to-previous-arg bound)
5657 (condition-case nil
5658 (progn (backward-sexp) t)
5659 (error nil)))
5660 (if (eq (following-char) ?\[) (incf cnt-opt))
5661 (incf cnt))
5662 (setq pos (point))
5663 (when (and (or (= (following-char) ?\[)
5664 (= (following-char) ?\{))
5665 (re-search-backward "\\\\[*a-zA-Z]+\\=" nil t))
5666 (setq cmd (reftex-match-string 0))
5667 (when (looking-at "\\\\begin{[^}]*}")
5668 (setq cmd (reftex-match-string 0)
5669 cnt (1- cnt)))
5670 ;; This does ignore optional arguments. Very hard to fix.
5671 (when (setq entry (assoc cmd reftex-env-or-mac-alist))
5672 (if (> cnt (or (nth 4 entry) 100))
5673 (setq cmd nil)))
5674 (cond
5675 ((null cmd))
5676 ((eq t which)
5677 (push (cons cmd (point)) cmd-list))
5678 ((or (eq 1 which) (member cmd which))
5679 (throw 'exit (cons cmd (point))))))
5680 (goto-char pos)))
5681 (nreverse cmd-list)))))
5682
5683 (defun reftex-what-environment (which &optional bound)
5684 ;; Find out if point is inside a LaTeX environment.
5685 ;; The return value is (e.g.) either ("equation" . (point)) or a list of
5686 ;; them.
5687
5688 ;; If WHICH is nil, immediately return nil.
5689 ;; If WHICH is 1, return innermost enclosing environment.
5690 ;; If WHICH is t, return list of all environments enclosing point.
5691 ;; If WHICH is a list of environments, look only for those environments and
5692 ;; return the name of the first environment in this list found to enclose
5693 ;; point.
5694
5695 ;; If the optional BOUND is an integer, bound backwards directed searches to
5696 ;; this point. If it is nil, limit to nearest \section - like statement.
5697
5698 (unless reftex-section-regexp (reftex-compile-variables))
5699 (catch 'exit
5700 (save-excursion
5701 (if (null which) (throw 'exit nil))
5702 (let ((bound (or bound (save-excursion (re-search-backward
5703 reftex-section-regexp nil 1)
5704 (point))))
5705 env-list end-list env)
5706 (while (re-search-backward "\\\\\\(begin\\|end\\){\\([^}]+\\)}"
5707 bound t)
5708 (setq env (buffer-substring-no-properties
5709 (match-beginning 2) (match-end 2)))
5710 (cond
5711 ((string= (match-string 1) "end")
5712 (add-to-list 'end-list env))
5713 ((member env end-list)
5714 (setq end-list (delete env end-list)))
5715 ((eq t which)
5716 (push (cons env (point)) env-list))
5717 ((or (eq 1 which) (member env which))
5718 (throw 'exit (cons env (point))))))
5719 (nreverse env-list)))))
5720
5721 ;;; =========================================================================
5722 ;;;
5723 ;;; Finding files
5724
5725 (defun reftex-locate-file (file type master-dir &optional die)
5726 "Find FILE of type TYPE in MASTER-DIR or on the path associcted with TYPE.
5727 If the file does not have any of the legal extensions for TYPE,
5728 try first the default extension and only then the naked file name.
5729 When DIE is non-nil, throw an error if file not found."
5730 (let* ((rec-values (if reftex-search-unrecursed-path-first '(nil t) '(t)))
5731 (extensions (cdr (assoc type reftex-file-extensions)))
5732 (def-ext (car extensions))
5733 (ext-re (concat "\\("
5734 (mapconcat 'regexp-quote extensions "\\|")
5735 "\\)\\'"))
5736 (files (if (string-match ext-re file)
5737 (cons file nil)
5738 (cons (concat file def-ext) file)))
5739 path old-path file1)
5740 (cond
5741 ((file-name-absolute-p file)
5742 (setq file1
5743 (or
5744 (and (car files) (file-regular-p (car files)) (car files))
5745 (and (cdr files) (file-regular-p (cdr files)) (cdr files)))))
5746 ((and reftex-use-external-file-finders
5747 (assoc type reftex-external-file-finders))
5748 (setq file1 (reftex-find-file-externally file type master-dir)))
5749 (t
5750 (while (and (null file1) rec-values)
5751 (setq path (reftex-access-search-path
5752 type (pop rec-values) master-dir file))
5753 (if (or (null old-path)
5754 (not (eq old-path path)))
5755 (setq old-path path
5756 path (cons master-dir path)
5757 file1 (or (and (car files)
5758 (reftex-find-file-on-path
5759 (car files) path master-dir))
5760 (and (cdr files)
5761 (reftex-find-file-on-path
5762 (cdr files) path master-dir))))))))
5763 (cond (file1 file1)
5764 (die (error "No such file: %s" file) nil)
5765 (t (message "No such file: %s (ignored)" file) nil))))
5766
5767 (defun reftex-find-file-externally (file type &optional master-dir)
5768 ;; Use external program to find FILE.
5769 ;; The program is taken from `reftex-external-file-finders'.
5770 ;; Interprete relative path definitions starting from MASTER-DIR.
5771 (let ((default-directory (or master-dir default-directory))
5772 (prg (cdr (assoc type reftex-external-file-finders)))
5773 out)
5774 (if (string-match "%f" prg)
5775 (setq prg (replace-match file t t prg)))
5776 (setq out (apply 'reftex-process-string (split-string prg)))
5777 (if (string-match "[ \t\n]+\\'" out)
5778 (setq out (replace-match "" nil nil out)))
5779 (cond ((equal out "") nil)
5780 ((file-regular-p out) out)
5781 (t nil))))
5782
5783 (defun reftex-process-string (program &rest args)
5784 "Execute PROGRAM with arguments ARGS and return its STDOUT as a string."
5785 (with-output-to-string
5786 (with-current-buffer standard-output
5787 (apply 'call-process program nil '(t nil) nil args))))
5788
5789 (defun reftex-access-search-path (type &optional recurse master-dir file)
5790 ;; Access path from environment variables. TYPE is either "tex" or "bib".
5791 ;; When RECURSE is t, expand path elements ending in `//' recursively.
5792 ;; Relative path elements are left as they are. However, relative recursive
5793 ;; elements are expanded with MASTER-DIR as default directory.
5794 ;; The expanded path is cached for the next search.
5795 ;; FILE is just for the progress message.
5796 ;; Returns the derived path.
5797 (let* ((pathvar (intern (concat "reftex-" type "-path"))))
5798 (when (null (get pathvar 'status))
5799 ;; Get basic path
5800 (set pathvar
5801 (reftex-uniq
5802 (reftex-parse-colon-path
5803 (mapconcat
5804 (lambda(x)
5805 (if (string-match "^!" x)
5806 (apply 'reftex-process-string
5807 (split-string (substring x 1)))
5808 (or (getenv x) x)))
5809 ;; For consistency, the next line should look like this:
5810 ;; (cdr (assoc type reftex-path-environment))
5811 ;; However, historically we have separate options for the
5812 ;; environment variables, so we have to do this:
5813 (symbol-value (intern (concat "reftex-" type
5814 "path-environment-variables")))
5815 path-separator))))
5816 (put pathvar 'status 'split)
5817 ;; Check if we have recursive elements
5818 (let ((path (symbol-value pathvar)) dir rec)
5819 (while (setq dir (pop path))
5820 (when (string= (substring dir -2) "//")
5821 (if (file-name-absolute-p dir)
5822 (setq rec (or rec 'absolute))
5823 (setq rec 'relative))))
5824 (put pathvar 'rec-type rec)))
5825
5826 (if recurse
5827 ;; Return the recursive expansion of the path
5828 (cond
5829 ((not (get pathvar 'rec-type))
5830 ;; Path does not contain recursive elements - use simple path
5831 (symbol-value pathvar))
5832 ((or (not (get pathvar 'recursive-path))
5833 (and (eq (get pathvar 'rec-type) 'relative)
5834 (not (equal master-dir (get pathvar 'master-dir)))))
5835 ;; Either: We don't have a recursive expansion yet.
5836 ;; or: Relative recursive path elements need to be expanded
5837 ;; relative to new default directory
5838 (message "Expanding search path to find %s file: %s ..." type file)
5839 (put pathvar 'recursive-path
5840 (reftex-expand-path (symbol-value pathvar) master-dir))
5841 (put pathvar 'master-dir master-dir)
5842 (get pathvar 'recursive-path))
5843 (t
5844 ;; Recursive path computed earlier is still OK.
5845 (get pathvar 'recursive-path)))
5846 ;; The simple path was requested
5847 (symbol-value pathvar))))
5848
5849 (defun reftex-find-file-on-path (file path &optional def-dir)
5850 ;; Find FILE along the directory list PATH.
5851 ;; DEF-DIR is the default directory for expanding relative path elements.
5852 (catch 'exit
5853 (when (file-name-absolute-p file)
5854 (if (file-regular-p file)
5855 (throw 'exit file)
5856 (throw 'exit nil)))
5857 (let* ((thepath path) file1 dir)
5858 (while (setq dir (pop thepath))
5859 (when (string= (substring dir -2) "//")
5860 (setq dir (substring dir 0 -1)))
5861 (setq file1 (expand-file-name file (expand-file-name dir def-dir)))
5862 (if (file-regular-p file1)
5863 (throw 'exit file1)))
5864 ;; No such file
5865 nil)))
5866
5867 (defun reftex-parse-colon-path (path)
5868 ;; Like parse-colon-parse, but // or /~ are left alone.
5869 ;; Trailing ! or !! will be converted into `//' (emTeX convention)
5870 (mapcar
5871 (lambda (dir)
5872 (if (string-match "\\(//+\\|/*!+\\)\\'" dir)
5873 (setq dir (replace-match "//" t t dir)))
5874 (file-name-as-directory dir))
5875 (delete "" (split-string path (concat path-separator "+")))))
5876
5877 (defun reftex-expand-path (path &optional default-dir)
5878 ;; Expand parts of path ending in `//' recursively into directory list.
5879 ;; Relative recursive path elements are expanded relative to DEFAULT-DIR.
5880 (let (path1 dir recursive)
5881 (while (setq dir (pop path))
5882 (if (setq recursive (string= (substring dir -2) "//"))
5883 (setq dir (substring dir 0 -1)))
5884 (if (and recursive
5885 (not (file-name-absolute-p dir)))
5886 (setq dir (expand-file-name dir default-dir)))
5887 (if recursive
5888 ;; Expand recursively
5889 (setq path1 (append (reftex-recursive-directory-list dir) path1))
5890 ;; Keep unchanged
5891 (push dir path1)))
5892 (nreverse path1)))
5893
5894 (defun reftex-recursive-directory-list (dir)
5895 ;; Return a list of all directories below DIR, including DIR itself
5896 (let ((path (list dir)) path1 file files)
5897 (while (setq dir (pop path))
5898 (when (file-directory-p dir)
5899 (setq files (nreverse (directory-files dir t "[^.]")))
5900 (while (setq file (pop files))
5901 (if (file-directory-p file)
5902 (push (file-name-as-directory file) path)))
5903 (push dir path1)))
5904 path1))
5905
5906 (defun reftex-uniq (list)
5907 (let (new)
5908 (while list
5909 (or (member (car list) new)
5910 (push (car list) new))
5911 (pop list))
5912 (nreverse new)))
5913
5914 ;;; =========================================================================
5915 ;;;
5916 ;;; Some generally useful functions
5917
5918 (defun reftex-no-props (string)
5919 ;; Return STRING with all text properties removed
5920 (and (stringp string)
5921 (set-text-properties 0 (length string) nil string))
5922 string)
5923
5924 (defun reftex-match-string (n)
5925 ;; Match string without properties
5926 (when (match-beginning n)
5927 (buffer-substring-no-properties (match-beginning n) (match-end n))))
5928
5929 (defun reftex-kill-buffer (buffer)
5930 ;; Kill buffer if it exists.
5931 (and (setq buffer (get-buffer buffer))
5932 (kill-buffer buffer)))
5933
5934 (defun reftex-erase-buffer (&optional buffer)
5935 ;; Erase BUFFER if it exists. BUFFER defaults to current buffer.
5936 ;; This even erases read-only buffers.
5937 (cond
5938 ((null buffer)
5939 ;; erase current buffer
5940 (let ((buffer-read-only nil)) (erase-buffer)))
5941 ((setq buffer (get-buffer buffer))
5942 ;; buffer exists
5943 (save-excursion
5944 (set-buffer buffer)
5945 (let ((buffer-read-only nil)) (erase-buffer))))))
5946
5947 (defun reftex-this-word (&optional class)
5948 ;; Grab the word around point.
5949 (setq class (or class "-a-zA-Z0-9:_/.*;|"))
5950 (save-excursion
5951 (buffer-substring-no-properties
5952 (progn (skip-chars-backward class) (point))
5953 (progn (skip-chars-forward class) (point)))))
5954
5955 (defun reftex-all-assq (key list)
5956 ;; Return a list of all associations of KEY in LIST. Comparison with eq.
5957 (let (rtn)
5958 (while (setq list (memq (assq key list) list))
5959 (push (car list) rtn)
5960 (pop list))
5961 (nreverse rtn)))
5962
5963 (defun reftex-all-assoc-string (key list)
5964 ;; Return a list of all associations of KEY in LIST. Comparison with string=.
5965 (let (rtn)
5966 (while list
5967 (if (string= (car (car list)) key)
5968 (push (car list) rtn))
5969 (pop list))
5970 (nreverse rtn)))
5971
5972 (defun reftex-last-assoc-before-elt (key elt list)
5973 ;; Find the last association of KEY in LIST before or at ELT
5974 ;; ELT is found in LIST with equal, not eq.
5975 ;; Returns nil when either KEY or elt are not found in LIST.
5976 ;; On success, returns the association.
5977 (let* ((elt (car (member elt list))) ass last-ass)
5978
5979 (while (and (setq ass (assoc key list))
5980 (setq list (memq ass list))
5981 (memq elt list))
5982 (setq last-ass ass
5983 list (cdr list)))
5984 last-ass))
5985
5986 (defun reftex-truncate (string ncols &optional ellipses padding)
5987 ;; Truncate STRING to NCOLS characters.
5988 ;; When PADDING is non-nil, and string is shorter than NCOLS, fill with
5989 ;; white space to NCOLS characters. When ELLIPSES is non-nil and the
5990 ;; string needs to be truncated, replace last 3 characters by dots.
5991 (setq string
5992 (if (<= (length string) ncols)
5993 string
5994 (if ellipses
5995 (concat (substring string 0 (- ncols 3)) "...")
5996 (substring string 0 ncols))))
5997 (if padding
5998 (format (format "%%-%ds" ncols) string)
5999 string))
6000
6001 (defun reftex-nearest-match (regexp &optional pos)
6002 ;; Find the nearest match of REGEXP. Set the match data.
6003 ;; If POS is given, calculate distances relative to it.
6004 ;; Return nil if there is no match.
6005 (let ((start (point)) (pos (or pos (point))) match1 match2 match)
6006 (goto-char start)
6007 (when (re-search-backward regexp nil t)
6008 (setq match1 (match-data)))
6009 (goto-char start)
6010 (when (re-search-forward regexp nil t)
6011 (setq match2 (match-data)))
6012 (goto-char start)
6013 (setq match
6014 (cond
6015 ((not match1) match2)
6016 ((not match2) match1)
6017 ((< (abs (- pos (car match1))) (abs (- pos (car match2)))) match1)
6018 (t match2)))
6019 (if match (progn (set-match-data match) t) nil)))
6020
6021 (defun reftex-auto-mode-alist ()
6022 ;; Return an `auto-mode-alist' with only the .gz (etc) thingies.
6023 ;; Stolen from gnus nnheader.
6024 (let ((alist auto-mode-alist)
6025 out)
6026 (while alist
6027 (when (listp (cdr (car alist)))
6028 (push (car alist) out))
6029 (pop alist))
6030 (nreverse out)))
6031
6032 (defun reftex-window-height ()
6033 (if (fboundp 'window-displayed-height)
6034 (window-displayed-height)
6035 (window-height)))
6036
6037 (defun reftex-enlarge-to-fit (buf2 &optional keep-current)
6038 ;; Enlarge other window displaying buffer to show whole buffer if possible.
6039 ;; If KEEP-CURRENT in non-nil, current buffer must remain visible.
6040 (let* ((win1 (selected-window))
6041 (buf1 (current-buffer))
6042 (win2 (get-buffer-window buf2))) ;; Only on current frame.
6043 (when win2
6044 (select-window win2)
6045 (unless (and (pos-visible-in-window-p 1)
6046 (pos-visible-in-window-p (point-max)))
6047 (enlarge-window (1+ (- (count-lines 1 (point-max))
6048 (reftex-window-height))))))
6049 (cond
6050 ((window-live-p win1) (select-window win1))
6051 (keep-current
6052 ;; we must have the old buffer!
6053 (switch-to-buffer-other-window buf1)
6054 (shrink-window (- (window-height) window-min-height))))))
6055
6056 (defun reftex-select-with-char (prompt help-string &optional delay-time scroll)
6057 ;; Offer to select something with PROMPT and, after DELAY-TIME seconds,
6058 ;; also with HELP-STRING.
6059 ;; When SCROLL is non-nil, use SPC and DEL to scroll help window.
6060 (let ((char ?\?))
6061 (save-window-excursion
6062 (catch 'exit
6063 (message (concat prompt " (?=Help)"))
6064 (when (or (sit-for (or delay-time 0))
6065 (= ?\? (setq char (read-char-exclusive))))
6066 (reftex-kill-buffer "*RefTeX Select*")
6067 (switch-to-buffer-other-window "*RefTeX Select*")
6068 (insert help-string)
6069 (goto-char 1)
6070 (unless (and (pos-visible-in-window-p 1)
6071 (pos-visible-in-window-p (point-max)))
6072 (enlarge-window (1+ (- (count-lines 1 (point-max))
6073 (reftex-window-height)))))
6074 (setq truncate-lines t))
6075 (setq prompt (concat prompt (if scroll " (SPC/DEL=Scroll)" "")))
6076 (message prompt)
6077 (and (equal char ?\?) (setq char (read-char-exclusive)))
6078 (while t
6079 (cond ((equal char ?\C-g) (keyboard-quit))
6080 ((equal char ?\?))
6081 ((and scroll (equal char ?\ ))
6082 (condition-case nil (scroll-up) (error nil))
6083 (message prompt))
6084 ((and scroll (equal char ?\C-? ))
6085 (condition-case nil (scroll-down) (error nil))
6086 (message prompt))
6087 (t (throw 'exit char)))
6088 (setq char (read-char-exclusive)))))))
6089
6090 (defun reftex-make-regexp-allow-for-ctrl-m (string)
6091 ;; convert STRING into a regexp, allowing ^M for \n and vice versa
6092 (let ((start -2))
6093 (setq string (regexp-quote string))
6094 (while (setq start (string-match "[\n\r]" string (+ 3 start)))
6095 (setq string (replace-match "[\n\r]" nil t string)))
6096 string))
6097
6098 (defun reftex-get-buffer-visiting (file)
6099 ;; return a buffer visiting FILE
6100 (cond
6101 ((boundp 'find-file-compare-truenames) ; XEmacs
6102 (let ((find-file-compare-truenames t))
6103 (get-file-buffer file)))
6104 ((fboundp 'find-buffer-visiting) ; Emacs
6105 (find-buffer-visiting file))
6106 (t (error "This should not happen (reftex-get-buffer-visiting)"))))
6107
6108 ;; Define `current-message' for compatibility with XEmacs prior to 20.4
6109 (defvar message-stack)
6110 (if (and (featurep 'xemacs)
6111 (not (fboundp 'current-message)))
6112 (defun current-message (&optional frame)
6113 (cdr (car message-stack))))
6114
6115 (defun reftex-visited-files (list)
6116 ;; Takes a list of filenames and returns the buffers of those already visited
6117 (delq nil (mapcar (lambda (x) (if (reftex-get-buffer-visiting x) x nil))
6118 list)))
6119
6120 (defun reftex-get-file-buffer-force (file &optional mark-to-kill)
6121 ;; Return a buffer visiting file. Make one, if necessary.
6122 ;; If neither such a buffer nor the file exist, return nil.
6123 ;; If MARK-TO-KILL is t and there is no live buffer, visit the file with
6124 ;; initializations according to `reftex-initialize-temporary-buffers',
6125 ;; and mark the buffer to be killed after use.
6126
6127 (let ((buf (reftex-get-buffer-visiting file)))
6128
6129 (cond (buf
6130 ;; We have it already as a buffer - just return it
6131 buf)
6132
6133 ((file-readable-p file)
6134 ;; At least there is such a file and we can read it.
6135
6136 (if (or (not mark-to-kill)
6137 (eq t reftex-initialize-temporary-buffers))
6138
6139 ;; Visit the file with full magic
6140 (setq buf (find-file-noselect file))
6141
6142 ;; Else: Visit the file just briefly, without or
6143 ;; with limited Magic
6144
6145 ;; The magic goes away
6146 (let ((format-alist nil)
6147 (auto-mode-alist (reftex-auto-mode-alist))
6148 (default-major-mode 'fundamental-mode)
6149 (enable-local-variables nil)
6150 (after-insert-file-functions nil))
6151 (setq buf (find-file-noselect file)))
6152
6153 ;; Is there a hook to run?
6154 (when (listp reftex-initialize-temporary-buffers)
6155 (save-excursion
6156 (set-buffer buf)
6157 (run-hooks 'reftex-initialize-temporary-buffers))))
6158
6159 ;; Lets see if we got a license to kill :-|
6160 (and mark-to-kill
6161 (add-to-list 'reftex-buffers-to-kill buf))
6162
6163 ;; Return the new buffer
6164 buf)
6165
6166 ;; If no such file exists, return nil
6167 (t nil))))
6168
6169 (defun reftex-kill-temporary-buffers (&optional buffer)
6170 ;; Kill all buffers in the list reftex-kill-temporary-buffers.
6171 (cond
6172 (buffer
6173 (when (member buffer reftex-buffers-to-kill)
6174 (kill-buffer buffer)
6175 (setq reftex-buffers-to-kill
6176 (delete buffer reftex-buffers-to-kill))))
6177 (t
6178 (while (setq buffer (pop reftex-buffers-to-kill))
6179 (when (bufferp buffer)
6180 (and (buffer-modified-p buffer)
6181 (y-or-n-p (format "Save file %s? "
6182 (buffer-file-name buffer)))
6183 (save-excursion
6184 (set-buffer buffer)
6185 (save-buffer)))
6186 (kill-buffer buffer))
6187 (pop reftex-buffers-to-kill)))))
6188
6189 (defun reftex-splice-symbols-into-list (list alist)
6190 ;; Splice the association in ALIST of any symbols in LIST into the list.
6191 ;; Return new list.
6192 (let (rtn tmp)
6193 (while list
6194 (while (and (not (null (car list))) ;; keep list elements nil
6195 (symbolp (car list)))
6196 (setq tmp (car list))
6197 (cond
6198 ((assoc tmp alist)
6199 (setq list (append (nth 2 (assoc tmp alist)) (cdr list))))
6200 (t
6201 (error "Cannot treat symbol %s in reftex-label-alist"
6202 (symbol-name tmp)))))
6203 (push (pop list) rtn))
6204 (nreverse rtn)))
6205
6206 (defun reftex-uniquify-by-car (alist &optional keep-list)
6207 ;; Return a list of all elements in ALIST, but each car only once.
6208 ;; Elements of KEEP-LIST are not removed even if duplicate.
6209 (let (new elm)
6210 (while alist
6211 (setq elm (pop alist))
6212 (if (or (member (car elm) keep-list)
6213 (not (assoc (car elm) new)))
6214 (push elm new)))
6215 (nreverse new)))
6216
6217 ;;; =========================================================================
6218 ;;;
6219 ;;; Fontification and Highlighting
6220
6221 (defun reftex-use-fonts ()
6222 ;; Return t if we can and want to use fonts.
6223 (and window-system
6224 reftex-use-fonts
6225 (featurep 'font-lock)))
6226
6227 (defun reftex-refontify ()
6228 ;; Return t if we need to refontify context
6229 (and (reftex-use-fonts)
6230 (or (eq t reftex-refontify-context)
6231 (and (eq 1 reftex-refontify-context)
6232 ;; Test of we use the font-lock version of x-symbol
6233 (and (featurep 'x-symbol-tex) (not (boundp 'x-symbol-mode)))))))
6234
6235 (defun reftex-fontify-select-label-buffer (parent-buffer)
6236 ;; Fontify the `*RefTeX Select*' buffer. Buffer is temporarily renamed to
6237 ;; start with none-SPC char, beacuse Font-Lock otherwise refuses operation.
6238 (run-hook-with-args 'reftex-pre-refontification-functions
6239 parent-buffer 'reftex-ref)
6240 (let* ((oldname (buffer-name))
6241 (newname (concat "Fontify-me-" oldname)))
6242 (unwind-protect
6243 (progn
6244 ;; Rename buffer temporarily to start w/o space (because of font-lock)
6245 (rename-buffer newname t)
6246 (cond
6247 ((fboundp 'font-lock-default-fontify-region)
6248 ;; Good: we have the indirection functions
6249 (set (make-local-variable 'font-lock-fontify-region-function)
6250 'reftex-select-font-lock-fontify-region)
6251 (let ((major-mode 'latex-mode))
6252 (font-lock-mode 1)))
6253 ((fboundp 'font-lock-set-defaults-1)
6254 ;; Looks like the XEmacs font-lock stuff.
6255 ;; FIXME: this is still kind of a hack, but it works.
6256 (set (make-local-variable 'font-lock-keywords) nil)
6257 (let ((major-mode 'latex-mode)
6258 (font-lock-defaults-computed nil))
6259 (font-lock-set-defaults-1)
6260 (reftex-select-font-lock-fontify-region (point-min) (point-max))))
6261 (t
6262 ;; Oops?
6263 (message "Sorry: cannot refontify RefTeX Select buffer."))))
6264 (rename-buffer oldname))))
6265
6266 (defun reftex-select-font-lock-fontify-region (beg end &optional loudly)
6267 ;; Fontify a region, but only lines starting with a dot.
6268 (let ((func (if (fboundp 'font-lock-default-fontify-region)
6269 'font-lock-default-fontify-region
6270 'font-lock-fontify-region))
6271 beg1 end1)
6272 (goto-char beg)
6273 (while (re-search-forward "^\\." end t)
6274 (setq beg1 (point) end1 (progn (skip-chars-forward "^\n") (point)))
6275 (funcall func beg1 end1 nil)
6276 (goto-char end1))))
6277
6278 (defun reftex-select-font-lock-unfontify (&rest ignore) t)
6279
6280 (defun reftex-verified-face (&rest faces)
6281 ;; Return the first valid face in FACES, or nil if none is valid.
6282 ;; Also, when finding a nil element in FACES, return nil. This
6283 ;; function is just a safety net to catch name changes of builtin
6284 ;; fonts. Currently it is only used for reftex-label-face, which has
6285 ;; as default font-lock-reference-face, which was recently renamed
6286 ;; to font-lock-constant-face.
6287 (let (face)
6288 (catch 'exit
6289 (while (setq face (pop faces))
6290 (if (featurep 'xemacs)
6291 (if (find-face face) (throw 'exit face))
6292 (if (facep face) (throw 'exit face)))))))
6293
6294 ;; Highlighting uses overlays. For XEmacs, we need the emulation.
6295 (if (featurep 'xemacs) (require 'overlay))
6296
6297 ;; We keep a vector with several different overlays to do our highlighting.
6298 (defvar reftex-highlight-overlays [nil nil])
6299
6300 ;; Initialize the overlays
6301 (aset reftex-highlight-overlays 0 (make-overlay 1 1))
6302 (overlay-put (aref reftex-highlight-overlays 0)
6303 'face 'highlight)
6304 (aset reftex-highlight-overlays 1 (make-overlay 1 1))
6305 (overlay-put (aref reftex-highlight-overlays 1)
6306 'face reftex-cursor-selected-face)
6307
6308 ;; Two functions for activating and deactivation highlight overlays
6309 (defun reftex-highlight (index begin end &optional buffer)
6310 "Highlight a region with overlay INDEX."
6311 (move-overlay (aref reftex-highlight-overlays index)
6312 begin end (or buffer (current-buffer))))
6313 (defun reftex-unhighlight (index)
6314 "Detach overlay INDEX."
6315 (delete-overlay (aref reftex-highlight-overlays index)))
6316
6317 (defun reftex-highlight-shall-die ()
6318 ;; Function used in pre-command-hook to remove highlights.
6319 (remove-hook 'pre-command-hook 'reftex-highlight-shall-die)
6320 (reftex-unhighlight 0))
6321
6322 ;;; =========================================================================
6323 ;;;
6324 ;;; Functions to compile the tables, reset the mode etc.
6325
6326 ;; A list of all variables in the cache.
6327 ;; The cache is used to save the compiled versions of some variables.
6328 (defconst reftex-cache-variables
6329 '(reftex-memory ;; This MUST ALWAYS be the first!
6330 reftex-env-or-mac-alist reftex-everything-regexp
6331 reftex-macros-with-labels
6332 reftex-find-label-regexp-format reftex-find-label-regexp-format2
6333 reftex-label-env-list reftex-label-mac-list
6334 reftex-section-or-include-regexp reftex-section-levels-all
6335 reftex-section-regexp reftex-type-query-help
6336 reftex-type-query-prompt reftex-typekey-list
6337 reftex-typekey-to-format-alist reftex-typekey-to-prefix-alist
6338 reftex-words-to-typekey-alist))
6339
6340 (defun reftex-ensure-compiled-variables ()
6341 ;; Recompile the label alist when necessary
6342 (let* ((mem reftex-memory)
6343 (cache (get reftex-docstruct-symbol 'reftex-cache))
6344 (cmem (car cache))
6345 (alist reftex-label-alist)
6346 (levels (get reftex-docstruct-symbol 'reftex-section-levels))
6347 (style (get reftex-docstruct-symbol 'reftex-label-alist-style))
6348 (default reftex-default-label-alist-entries))
6349 (cond
6350 (reftex-tables-dirty (reftex-compile-variables))
6351 ((and (eq alist (nth 0 mem))
6352 (eq levels (nth 1 mem))
6353 (eq style (nth 2 mem))
6354 (eq default (nth 3 mem)))) ;; everything is OK
6355 ((and (eq alist (nth 0 cmem))
6356 (eq levels (nth 1 cmem))
6357 (eq style (nth 2 cmem))
6358 (eq default (nth 2 cmem)))
6359 ;; restore the cache
6360 (message "Restoring cache")
6361 (mapcar (lambda (sym) (set sym (pop cache))) reftex-cache-variables))
6362 (t (reftex-compile-variables)))))
6363
6364 (defun reftex-reset-mode ()
6365 "Reset RefTeX Mode.
6366 This will re-compile the configuration information and remove all
6367 current scanning information and the parse file to enforce a rescan
6368 on next use."
6369 (interactive)
6370
6371 ;; Reset the file search path variables
6372 (loop for prop in '(status master-dir recursive-path rec-type) do
6373 (put 'reftex-tex-path prop nil)
6374 (put 'reftex-bib-path prop nil))
6375
6376 ;; Kill temporary buffers associated with RefTeX - just in case they
6377 ;; were not cleaned up properly
6378 (save-excursion
6379 (let ((buffer-list '("*RefTeX Help*" "*RefTeX Select*"
6380 "*Duplicate Labels*" "*toc*" " *RefTeX-scratch*"))
6381 buf)
6382 (while (setq buf (pop buffer-list))
6383 (if (get-buffer buf)
6384 (kill-buffer buf))))
6385 (reftex-erase-all-selection-buffers))
6386
6387 ;; Make sure the current document will be rescanned soon.
6388 (reftex-reset-scanning-information)
6389
6390 ;; Remove any parse info file
6391 (reftex-access-parse-file 'kill)
6392
6393 ;; Plug functions into AUCTeX if the user option says so.
6394 (and reftex-plug-into-AUCTeX
6395 (reftex-plug-into-AUCTeX))
6396
6397 (reftex-compile-variables))
6398
6399 (defun reftex-reset-scanning-information ()
6400 "Reset the symbols containing information from buffer scanning.
6401 This enforces rescanning the buffer on next use."
6402 (if (string= reftex-last-toc-master (reftex-TeX-master-file))
6403 (reftex-erase-buffer "*toc*"))
6404 (let ((symlist reftex-multifile-symbols)
6405 symbol)
6406 (while symlist
6407 (setq symbol (car symlist)
6408 symlist (cdr symlist))
6409 (if (and (symbolp (symbol-value symbol))
6410 (not (null (symbol-value symbol))))
6411 (set (symbol-value symbol) nil)))))
6412
6413 (defun reftex-erase-all-selection-buffers ()
6414 ;; Remove all selection buffers associated with current document.
6415 (mapcar
6416 (lambda (type)
6417 (reftex-erase-buffer (reftex-make-selection-buffer-name type)))
6418 reftex-typekey-list))
6419
6420 (defun reftex-compile-variables ()
6421 ;; Compile the information in reftex-label-alist & Co.
6422
6423 (message "Compiling label environment definitions...")
6424
6425 ;; Update AUCTeX style information
6426 (when (and (featurep 'tex-site) (fboundp 'TeX-update-style))
6427 (condition-case nil (TeX-update-style) (error nil)))
6428
6429 ;; Record that we have done this, and what we have used.
6430 (setq reftex-tables-dirty nil)
6431 (setq reftex-memory
6432 (list reftex-label-alist
6433 (get reftex-docstruct-symbol 'reftex-section-levels)
6434 (get reftex-docstruct-symbol 'reftex-label-alist-style)
6435 reftex-default-label-alist-entries))
6436
6437 ;; Compile information in reftex-label-alist
6438 (let ((all (reftex-uniquify-by-car
6439 (reftex-splice-symbols-into-list
6440 (append reftex-label-alist
6441 (get reftex-docstruct-symbol 'reftex-label-alist-style)
6442 reftex-default-label-alist-entries)
6443 reftex-label-alist-builtin)
6444 '(nil)))
6445 entry env-or-mac typekeychar typekey prefix context word
6446 fmt reffmt labelfmt wordlist qh-list macros-with-labels
6447 nargs nlabel opt-args cell sum i)
6448
6449 (setq reftex-words-to-typekey-alist nil
6450 reftex-typekey-list nil
6451 reftex-typekey-to-format-alist nil
6452 reftex-typekey-to-prefix-alist nil
6453 reftex-env-or-mac-alist nil
6454 reftex-label-env-list nil
6455 reftex-label-mac-list nil)
6456 (while all
6457 (catch 'next-entry
6458 (setq entry (car all)
6459 env-or-mac (car entry)
6460 entry (cdr entry)
6461 all (cdr all))
6462 (if (null env-or-mac)
6463 (setq env-or-mac ""))
6464 (if (stringp (car entry))
6465 ;; This is before version 2.00 - convert entry to new format
6466 ;; This is just to keep old users happy
6467 (setq entry (cons (string-to-char (car entry))
6468 (cons (concat (car entry) ":")
6469 (cdr entry)))))
6470 (setq typekeychar (nth 0 entry)
6471 typekey (if typekeychar (char-to-string typekeychar) nil)
6472 prefix (nth 1 entry)
6473 fmt (nth 2 entry)
6474 context (nth 3 entry)
6475 wordlist (nth 4 entry))
6476 (if (stringp wordlist)
6477 ;; This is before version 2.04 - convert to new format
6478 (setq wordlist (nthcdr 4 entry)))
6479
6480 (if (and (stringp fmt)
6481 (string-match "@" fmt))
6482 ;; Special syntax for specifying a label format
6483 (setq fmt (split-string fmt "@+"))
6484 (setq fmt (list "\\label{%s}" fmt)))
6485 (setq labelfmt (car fmt)
6486 reffmt (nth 1 fmt))
6487 ;; Note a new typekey
6488 (if typekey
6489 (add-to-list 'reftex-typekey-list typekey))
6490 (if (and typekey prefix
6491 (not (assoc typekey reftex-typekey-to-prefix-alist)))
6492 (add-to-list 'reftex-typekey-to-prefix-alist
6493 (cons typekey prefix)))
6494 ;; Check if this is a macro or environment
6495 (cond
6496 ((string-match "\\`\\\\" env-or-mac)
6497 ;; It's a macro
6498 (let ((result (reftex-parse-args env-or-mac)))
6499 (setq env-or-mac (or (first result) env-or-mac)
6500 nargs (second result)
6501 nlabel (third result)
6502 opt-args (fourth result))
6503 (if nlabel (add-to-list 'macros-with-labels env-or-mac)))
6504 (if typekey (add-to-list 'reftex-label-mac-list env-or-mac)))
6505 (t
6506 ;; It's an environment
6507 (setq nargs nil nlabel nil opt-args nil)
6508 (cond ((string= env-or-mac "any"))
6509 ((string= env-or-mac ""))
6510 ((string= env-or-mac "section"))
6511 (t
6512 (add-to-list 'reftex-label-env-list env-or-mac)))))
6513 ;; Translate some special context cases
6514 (when (assq context reftex-default-context-regexps)
6515 (setq context
6516 (format
6517 (cdr (assq context reftex-default-context-regexps))
6518 (regexp-quote env-or-mac))))
6519 ;; See if this is the first format for this typekey
6520 (and reffmt
6521 (not (assoc typekey reftex-typekey-to-format-alist))
6522 (push (cons typekey reffmt) reftex-typekey-to-format-alist))
6523 ;; See if this is the first definition for this env-or-mac
6524 (and (not (string= env-or-mac "any"))
6525 (not (string= env-or-mac ""))
6526 (not (assoc env-or-mac reftex-env-or-mac-alist))
6527 (push (list env-or-mac typekey context labelfmt
6528 nargs nlabel opt-args)
6529 reftex-env-or-mac-alist))
6530 ;; Are the magic words regular expressions? Quote normal words.
6531 (if (eq (car wordlist) 'regexp)
6532 (setq wordlist (cdr wordlist))
6533 (setq wordlist (mapcar 'regexp-quote wordlist)))
6534 ;; Remember the first association of each word.
6535 (while (stringp (setq word (pop wordlist)))
6536 (or (assoc word reftex-words-to-typekey-alist)
6537 (push (cons word typekey) reftex-words-to-typekey-alist)))
6538 (cond
6539 ((string= "" env-or-mac) nil)
6540 ((setq cell (assoc typekey qh-list))
6541 (push env-or-mac (cdr cell)))
6542 (typekey
6543 (push (list typekey env-or-mac) qh-list)))))
6544
6545 (setq reftex-typekey-to-prefix-alist
6546 (nreverse reftex-typekey-to-prefix-alist))
6547
6548 ;; Prepare the typekey query prompt and help string.
6549 (setq qh-list
6550 (sort qh-list (function
6551 (lambda (x1 x2) (string< (car x1) (car x2))))))
6552 (setq reftex-type-query-prompt
6553 (concat "Label type: ["
6554 (mapconcat (function (lambda(x) (format "%s" (car x))))
6555 qh-list "")
6556 "]"))
6557 ;; In the help string, we need to wrap lines...
6558 (setq reftex-type-query-help
6559 (concat
6560 "SELECT A LABEL TYPE:\n--------------------\n"
6561 (mapconcat
6562 (lambda(x)
6563 (setq sum 0)
6564 (format " [%s] %s"
6565 (car x)
6566 (mapconcat (lambda(env)
6567 (setq sum (+ sum (length env)))
6568 (if (< sum 60)
6569 env
6570 (setq sum 0)
6571 (concat "\n " env)))
6572 (cdr x) " ")))
6573 qh-list "\n")))
6574
6575 ;; Convert magic words to regular expressions. We make regular expressions
6576 ;; which allow for some chars from the ref format to be in the buffer.
6577 ;; These characters will be seen and removed.
6578 (setq reftex-words-to-typekey-alist
6579 (mapcar
6580 (lambda (x)
6581 (setq word (car x)
6582 typekey (cdr x)
6583 fmt (cdr (assoc typekey reftex-typekey-to-format-alist)))
6584 (setq word (concat "\\W\\(" word "[ \t\n\r]*\\)\\("))
6585 (setq i 0)
6586 (while (and (< i 10) ; maximum number of format chars allowed
6587 (< i (length fmt))
6588 (not (member (aref fmt i) '(?%))))
6589 (setq word (concat word "\\|" (regexp-quote
6590 (substring fmt 0 (1+ i)))))
6591 (incf i))
6592 (cons (concat word "\\)\\=") typekey))
6593 (nreverse reftex-words-to-typekey-alist)))
6594
6595 ;; Make the full list of section levels
6596 (setq reftex-section-levels-all
6597 (append (get reftex-docstruct-symbol 'reftex-section-levels)
6598 reftex-section-levels))
6599
6600 ;; Calculate the regular expressions
6601 (let* ((wbol "\\(\\`\\|[\n\r]\\)[ \t]*")
6602 (label-re "\\\\label{\\([^}]*\\)}")
6603 (include-re (concat wbol "\\\\\\(include\\|input\\)[{ \t]+\\([^} \t\n\r]+\\)"))
6604 (section-re
6605 (concat wbol "\\\\\\("
6606 (mapconcat 'car reftex-section-levels-all "\\|")
6607 "\\)\\*?\\(\\[[^]]*\\]\\)?{"))
6608 (appendix-re (concat wbol "\\(\\\\appendix\\)"))
6609 (macro-re
6610 (if macros-with-labels
6611 (concat "\\("
6612 (mapconcat 'regexp-quote macros-with-labels "\\|")
6613 "\\)[[{]")
6614 ""))
6615 (find-label-re-format
6616 (concat "\\("
6617 (mapconcat 'regexp-quote (append '("\\label")
6618 macros-with-labels) "\\|")
6619 "\\)\\([[{][^]}]*[]}]\\)*[[{]\\(%s\\)[]}]")))
6620 (setq reftex-section-regexp section-re
6621 reftex-section-or-include-regexp
6622 (concat section-re "\\|" include-re)
6623 reftex-everything-regexp
6624 (concat label-re "\\|" section-re "\\|" include-re
6625 "\\|" appendix-re
6626 (if macros-with-labels "\\|" "") macro-re)
6627 reftex-macros-with-labels macros-with-labels
6628 reftex-find-label-regexp-format find-label-re-format
6629 reftex-find-label-regexp-format2
6630 "\\([]} \t\n\r]\\)\\([[{]\\)\\(%s\\)[]}]")
6631 (message "Compiling label environment definitions...done")))
6632 (put reftex-docstruct-symbol 'reftex-cache
6633 (mapcar 'symbol-value reftex-cache-variables)))
6634
6635 ;;; =========================================================================
6636 ;;;
6637 ;;; Operations on entire Multifile documents
6638
6639 (defun reftex-create-tags-file ()
6640 "Create TAGS file by running `etags' on the current document.
6641 The TAGS file is also immediately visited with `visit-tags-table'."
6642 (interactive)
6643 (reftex-access-scan-info current-prefix-arg)
6644 (let* ((master (reftex-TeX-master-file))
6645 (files (reftex-all-document-files))
6646 (cmd (format "etags %s" (mapconcat 'identity files " "))))
6647 (save-excursion
6648 (set-buffer (reftex-get-buffer-visiting master))
6649 (message "Running etags to create TAGS file...")
6650 (shell-command cmd)
6651 (visit-tags-table "TAGS"))))
6652
6653 ;; History of grep commands.
6654 (defvar reftex-grep-history nil)
6655 (defvar reftex-grep-command "grep -n "
6656 "Last grep command used in \\[reftex-grep-document]; default for next grep.")
6657
6658 (defun reftex-grep-document (grep-cmd)
6659 "Run grep query through all files related to this document.
6660 With prefix arg, force to rescan document.
6661 No active TAGS table is required."
6662
6663 (interactive
6664 (list (read-from-minibuffer "Run grep on document (like this): "
6665 reftex-grep-command nil nil
6666 'reftex-grep-history)))
6667 (reftex-access-scan-info current-prefix-arg)
6668 (let* ((files (reftex-all-document-files t))
6669 (cmd (format
6670 "%s %s" grep-cmd
6671 (mapconcat 'identity files " "))))
6672 (grep cmd)))
6673
6674 (defun reftex-search-document (&optional regexp)
6675 "Regexp search through all files of the current document.
6676 Starts always in the master file. Stops when a match is found.
6677 To continue searching for next match, use command \\[tags-loop-continue].
6678 No active TAGS table is required."
6679 (interactive)
6680 (let ((default (reftex-this-word)))
6681 (unless regexp
6682 (setq regexp (read-string (format "Search regexp in document [%s]: "
6683 default))))
6684 (if (string= regexp "") (setq regexp (regexp-quote default)))
6685
6686 (reftex-access-scan-info current-prefix-arg)
6687 (tags-search regexp (list 'reftex-all-document-files))))
6688
6689 (defun reftex-query-replace-document (&optional from to delimited)
6690 "Run a query-replace-regexp of FROM with TO over the entire document.
6691 Third arg DELIMITED (prefix arg) means replace only word-delimited matches.
6692 If you exit (\\[keyboard-quit] or ESC), you can resume the query replace
6693 with the command \\[tags-loop-continue].
6694 No active TAGS table is required."
6695 (interactive)
6696 (let ((default (reftex-this-word)))
6697 (unless from
6698 (setq from (read-string (format "Replace regexp in document [%s]: "
6699 default)))
6700 (if (string= from "") (setq from (regexp-quote default))))
6701 (unless to
6702 (setq to (read-string (format "Replace regexp %s with: " from))))
6703 (reftex-access-scan-info current-prefix-arg)
6704 (tags-query-replace from to (or delimited current-prefix-arg)
6705 (list 'reftex-all-document-files))))
6706
6707 (defun reftex-find-duplicate-labels ()
6708 "Produce a list of all duplicate labels in the document."
6709
6710 (interactive)
6711
6712 ;; Rescan the document to make sure
6713 (reftex-access-scan-info t)
6714
6715 (let ((master (reftex-TeX-master-file))
6716 (cnt 0)
6717 (dlist
6718 (mapcar
6719 (function
6720 (lambda (x)
6721 (let (x1)
6722 (cond
6723 ((memq (car x)
6724 '(toc bof eof bib thebib label-numbers xr xr-doc
6725 master-dir file-error bibview-cache appendix
6726 is-multi))
6727 nil)
6728 (t
6729 (setq x1 (reftex-all-assoc-string
6730 (car x) (symbol-value reftex-docstruct-symbol)))
6731 (if (< 1 (length x1))
6732 (append (list (car x))
6733 (mapcar (function
6734 (lambda(x)
6735 (abbreviate-file-name (nth 3 x))))
6736 x1))
6737 (list nil)))))))
6738 (reftex-uniquify-by-car (symbol-value reftex-docstruct-symbol)))))
6739
6740 (setq dlist (reftex-uniquify-by-car dlist))
6741 (if (null dlist) (error "No duplicate labels in document"))
6742 (switch-to-buffer-other-window "*Duplicate Labels*")
6743 (set (make-local-variable 'TeX-master) master)
6744 (erase-buffer)
6745 (insert " MULTIPLE LABELS IN CURRENT DOCUMENT:\n")
6746 (insert
6747 " Move point to label and type `r' to run a query-replace on the label\n"
6748 " and its references. Type `q' to exit this buffer.\n\n")
6749 (insert " LABEL FILE\n")
6750 (insert " -------------------------------------------------------------\n")
6751 (use-local-map (make-sparse-keymap))
6752 (local-set-key [?q] (function
6753 (lambda () "Kill this buffer." (interactive)
6754 (kill-buffer (current-buffer)) (delete-window))))
6755 (local-set-key [?r] 'reftex-change-label)
6756 (while dlist
6757 (when (and (car (car dlist))
6758 (cdr (car dlist)))
6759 (incf cnt)
6760 (insert (mapconcat 'identity (car dlist) "\n ") "\n"))
6761 (pop dlist))
6762 (goto-char (point-min))
6763 (when (= cnt 0)
6764 (kill-buffer (current-buffer))
6765 (delete-window)
6766 (message "Document does not contain duplicate labels."))))
6767
6768 (defun reftex-change-label (&optional from to)
6769 "Query replace FROM with TO in all \\label and \\ref commands.
6770 Works on the entire multifile document.
6771 If you exit (\\[keyboard-quit] or ESC), you can resume the query replace
6772 with the command \\[tags-loop-continue].
6773 No active TAGS table is required."
6774 (interactive)
6775 (let ((default (reftex-this-word "-a-zA-Z0-9_*.:")))
6776 (unless from
6777 (setq from (read-string (format "Replace label globally [%s]: "
6778 default))))
6779 (if (string= from "") (setq from default))
6780 (unless to
6781 (setq to (read-string (format "Replace label %s with: "
6782 from))))
6783 (reftex-query-replace-document
6784 (concat "\\\\\\(label\\|[a-z]*ref\\){" (regexp-quote from) "}")
6785 (format "\\\\\\1{%s}" to))))
6786
6787 (defun reftex-renumber-simple-labels ()
6788 "Renumber all simple labels in the document to make them sequentially.
6789 Simple labels are the ones created by RefTeX, consisting only of the
6790 prefix and a number. After the command completes, all these labels will
6791 have sequential numbers throughout the document. Any references to
6792 the labels will be changed as well. For this, RefTeX looks at the
6793 arguments of any macros which either start or end in the string `ref'.
6794 This command should be used with care, in particular in multifile
6795 documents. You should not use it if another document refers to this
6796 one with the `xr' package."
6797 (interactive)
6798 ;; Resan the entire document
6799 (reftex-access-scan-info 1)
6800 ;; Get some insurance
6801 (if (and (reftex-is-multi)
6802 (not (yes-or-no-p "Replacing all simple labels in multiple files is risky. Continue? ")))
6803 (error "Abort"))
6804 ;; Make the translation list
6805 (let* ((re-core (concat "\\("
6806 (mapconcat 'cdr reftex-typekey-to-prefix-alist "\\|")
6807 "\\)"))
6808 (label-re (concat "\\`" re-core "\\([0-9]+\\)\\'"))
6809 (search-re (concat "{\\(" re-core "\\([0-9]+\\)\\)}"))
6810 (error-fmt "Undefined label or reference %s. Ignore and continue? ")
6811 (label-numbers-alist (mapcar (lambda (x) (cons (cdr x) 0))
6812 reftex-typekey-to-prefix-alist))
6813 (files (reftex-all-document-files))
6814 (list (symbol-value reftex-docstruct-symbol))
6815 translate-alist n entry label new-label nr-cell changed-sequence)
6816
6817 (while (setq entry (pop list))
6818 (when (and (stringp (car entry))
6819 (string-match label-re (car entry)))
6820 (setq label (car entry)
6821 nr-cell (assoc (match-string 1 (car entry))
6822 label-numbers-alist))
6823 (if (assoc label translate-alist)
6824 (error "Duplicate label %s" label))
6825 (setq new-label (concat (match-string 1 (car entry))
6826 (incf (cdr nr-cell))))
6827 (push (cons label new-label) translate-alist)
6828 (or (string= label new-label) (setq changed-sequence t))))
6829
6830 (unless changed-sequence
6831 (error "Simple labels are already in correct sequence"))
6832
6833 ;; Save all document buffers before this operation
6834 (reftex-save-all-document-buffers)
6835
6836 ;; First test to check for erros
6837 (setq n (reftex-translate
6838 files search-re translate-alist error-fmt 'test))
6839
6840 ;; Now the real thing.
6841 (if (yes-or-no-p
6842 (format "Replace %d items at %d places in %d files? "
6843 (length translate-alist) n (length files)))
6844 (progn
6845 (let ((inhibit-quit t)) ;; Do not disturb...
6846 (reftex-translate
6847 files search-re translate-alist error-fmt nil)
6848 (setq quit-flag nil))
6849 (if (and (reftex-is-multi)
6850 (yes-or-no-p "Save entire document? "))
6851 (reftex-save-all-document-buffers))
6852 ;; Rescan again...
6853 (reftex-access-scan-info 1)
6854 (message "Done replacing simple labels."))
6855 (message "No replacements done"))))
6856
6857 (defun reftex-translate (files search-re translate-alist error-fmt test)
6858 ;; In FILES, look for SEARCH-RE and replace match 1 of it with
6859 ;; its association in TRANSLATE-ALSIT.
6860 ;; If we do not find an association and TEST is non-nil, query
6861 ;; to ignore the problematic string.
6862 ;; If TEST is nil, it is ignored without query.
6863 ;; Return the number of replacements.
6864 (let ((n 0) file label match-data buf macro pos cell)
6865 (while (setq file (pop files))
6866 (setq buf (reftex-get-file-buffer-force file))
6867 (unless buf
6868 (error "No such file %s" file))
6869 (set-buffer buf)
6870 (save-excursion
6871 (save-restriction
6872 (widen)
6873 (goto-char (point-min))
6874 (while (re-search-forward search-re nil t)
6875 (save-excursion
6876 (backward-char)
6877 (setq label (reftex-match-string 1)
6878 cell (assoc label translate-alist)
6879 match-data (match-data)
6880 macro (reftex-what-macro 1)
6881 pos (cdr macro))
6882 (goto-char (or pos (point)))
6883 (when (and macro
6884 (or (looking-at "\\\\ref")
6885 (looking-at "\\\\[a-zA-Z]*ref[^a-zA-Z]")
6886 (looking-at "\\\\ref[a-zA-Z]*[^a-zA-Z]")
6887 (looking-at (format
6888 reftex-find-label-regexp-format
6889 (regexp-quote label)))))
6890 ;; OK, we should replace it.
6891 (set-match-data match-data)
6892 (cond
6893 ((and test (not cell))
6894 ;; We've got a problem
6895 (unwind-protect
6896 (progn
6897 (reftex-highlight 1 (match-beginning 0) (match-end 0))
6898 (ding)
6899 (or (y-or-n-p (format error-fmt label))
6900 (error "Abort")))
6901 (reftex-unhighlight 1)))
6902 ((and test cell)
6903 (incf n))
6904 ((and (not test) cell)
6905 ;; Replace
6906 (goto-char (match-beginning 1))
6907 (delete-region (match-beginning 1) (match-end 1))
6908 (insert (cdr cell)))
6909 (t nil))))))))
6910 n))
6911
6912 (defun reftex-save-all-document-buffers ()
6913 "Save all documents associated with the current document.
6914 The function is useful after a global action like replacing or renumbering
6915 labels."
6916 (interactive)
6917 (let ((files (reftex-all-document-files))
6918 file buffer)
6919 (save-excursion
6920 (while (setq file (pop files))
6921 (setq buffer (reftex-get-buffer-visiting file))
6922 (when buffer
6923 (set-buffer buffer)
6924 (save-buffer))))))
6925
6926 ;;; =========================================================================
6927 ;;;
6928 ;;; AUCTeX Interface
6929
6930 (defun reftex-plug-flag (which)
6931 ;; Tell if a certain flag is set in reftex-plug-into-AUCTeX
6932 (or (eq t reftex-plug-into-AUCTeX)
6933 (and (listp reftex-plug-into-AUCTeX)
6934 (nth which reftex-plug-into-AUCTeX))))
6935
6936 (defun reftex-arg-label (optional &optional prompt definition)
6937 "Use `reftex-label', `reftex-reference' or AUCTeX's code to insert label arg.
6938 What is being used depends upon `reftex-plug-into-AUCTeX'."
6939 (let (label)
6940 (cond
6941 ((and definition (reftex-plug-flag 1))
6942 ;; Create a new label, with a temporary brace for `reftex-what-macro'
6943 (unwind-protect
6944 (progn (insert "{") (setq label (or (reftex-label nil t) "")))
6945 (delete-backward-char 1)))
6946 ((and (not definition) (reftex-plug-flag 2))
6947 ;; Reference a label with RefTeX
6948 (setq label (reftex-reference nil t)))
6949 (t
6950 ;; AUCTeX's default mechanism
6951 (setq label (completing-read (TeX-argument-prompt optional prompt "Key")
6952 (LaTeX-label-list)))))
6953 (if (and definition (not (string-equal "" label)))
6954 (LaTeX-add-labels label))
6955 (TeX-argument-insert label optional optional)))
6956
6957 (defun reftex-arg-cite (optional &optional prompt definition)
6958 "Use `reftex-citation' or AUCTeX's code to insert a cite-key macro argument.
6959 What is being used depends upon `reftex-plug-into-AUCTeX'."
6960 (let (items)
6961 (cond
6962 ((and (not definition) (reftex-plug-flag 3))
6963 (setq items (list (or (reftex-citation t) ""))))
6964 (t
6965 (setq prompt (concat (if optional "(Optional) " "")
6966 (if prompt prompt "Add key")
6967 ": (default none) "))
6968 (setq items (multi-prompt "," t prompt (LaTeX-bibitem-list)))))
6969 (apply 'LaTeX-add-bibitems items)
6970 (TeX-argument-insert (mapconcat 'identity items ",") optional optional)))
6971
6972 (defun reftex-plug-into-AUCTeX ()
6973 ;; Replace AUCTeX functions with RefTeX functions.
6974 ;; Which functions are replaced is controlled by the variable
6975 ;; `reftex-plug-into-AUCTeX'.
6976
6977 (if (reftex-plug-flag 0)
6978 (setq LaTeX-label-function 'reftex-label)
6979 (setq LaTeX-label-function nil))
6980
6981 (if (and (or (reftex-plug-flag 1) (reftex-plug-flag 2))
6982 (fboundp 'TeX-arg-label))
6983 (fset 'TeX-arg-label 'reftex-arg-label))
6984
6985 (if (and (reftex-plug-flag 3)
6986 (fboundp 'TeX-arg-cite))
6987 (fset 'TeX-arg-cite 'reftex-arg-cite)))
6988
6989 (defun reftex-toggle-plug-into-AUCTeX ()
6990 "Toggle Interface between AUCTeX and RefTeX on and off."
6991 (interactive)
6992 (unless (and (featurep 'tex-site) (featurep 'latex))
6993 (error "AUCTeX's LaTeX mode does not seem to be loaded"))
6994 (setq reftex-plug-into-AUCTeX (not reftex-plug-into-AUCTeX))
6995 (reftex-plug-into-AUCTeX)
6996 (if reftex-plug-into-AUCTeX
6997 (message "RefTeX has been plugged into AUCTeX.")
6998 (message "RefTeX no longer interacts with AUCTeX.")))
6999
7000 (defun reftex-add-label-environments (entry-list)
7001 "Add label environment descriptions to `reftex-label-alist-style'.
7002 The format of ENTRY-LIST is exactly like `reftex-label-alist'. See there
7003 for details.
7004 This function makes it possible to support RefTeX from AUCTeX style files.
7005 The entries in ENTRY-LIST will be processed after the user settings in
7006 `reftex-label-alist', and before the defaults (specified in
7007 `reftex-default-label-alist-entries'). Any changes made to
7008 `reftex-label-alist-style' will raise a flag to the effect that
7009 the label information is recompiled on next use."
7010 (unless reftex-docstruct-symbol
7011 (reftex-tie-multifile-symbols))
7012 (when (and reftex-docstruct-symbol
7013 (symbolp reftex-docstruct-symbol))
7014 (let ((list (get reftex-docstruct-symbol 'reftex-label-alist-style))
7015 entry changed)
7016 (while entry-list
7017 (setq entry (pop entry-list))
7018 (unless (member entry list)
7019 (setq reftex-tables-dirty t
7020 changed t)
7021 (push entry list)))
7022 (when changed
7023 (put reftex-docstruct-symbol 'reftex-label-alist-style list)))))
7024 (defalias 'reftex-add-to-label-alist 'reftex-add-label-environments)
7025
7026 (defun reftex-add-section-levels (entry-list)
7027 "Add entries to the value of `reftex-section-levels'.
7028 The added values are kept local to the current document. The format
7029 of ENTRY-LIST is a list of cons cells (\"MACRONAME\" . LEVEL). See
7030 `reftex-section-levels' for an example."
7031 (unless reftex-docstruct-symbol
7032 (reftex-tie-multifile-symbols))
7033 (when (and reftex-docstruct-symbol
7034 (symbolp reftex-docstruct-symbol))
7035 (let ((list (get reftex-docstruct-symbol 'reftex-section-levels))
7036 entry changed)
7037 (while entry-list
7038 (setq entry (pop entry-list))
7039 (unless (member entry list)
7040 (setq reftex-tables-dirty t
7041 changed t)
7042 (push entry list)))
7043 (when changed
7044 (put reftex-docstruct-symbol 'reftex-section-levels list)))))
7045
7046 (defun reftex-set-cite-format (value)
7047 "Set the document-local value of `reftex-cite-format'.
7048 When such a value exists, it overwrites the setting given with
7049 `reftex-cite-format'. See the documentation of `reftex-cite-format'
7050 for possible values. This function should be used from AUCTeX style files."
7051 (unless reftex-docstruct-symbol
7052 (reftex-tie-multifile-symbols))
7053 (when (and reftex-docstruct-symbol
7054 (symbolp reftex-docstruct-symbol))
7055 (put reftex-docstruct-symbol 'reftex-cite-format value)))
7056
7057 (defun reftex-notice-new-section ()
7058 "Hook to handshake with RefTeX after a new section has been inserted."
7059 ;; Add a new section to the docstruct list and renumber the
7060 ;; following sections. This hook has to be called immediately after
7061 ;; the new section was inserted into the buffer, and before the
7062 ;; section label is created.
7063
7064 (condition-case nil
7065 (catch 'exit
7066 (unless reftex-mode (throw 'exit nil))
7067 (reftex-access-scan-info)
7068 (let* ((docstruct (symbol-value reftex-docstruct-symbol))
7069 here-am-I appendix tail toc-entry star level
7070 section-number context)
7071
7072 (save-excursion
7073 (when (re-search-backward reftex-section-regexp nil t)
7074
7075 ;; Find where we are
7076 (setq here-am-I (reftex-where-am-I))
7077 (unless (cdr here-am-I) (throw 'exit nil))
7078 (setq reftex-active-toc (reftex-last-assoc-before-elt
7079 'toc (car here-am-I) docstruct)
7080 appendix (reftex-last-assoc-before-elt
7081 'appendix (car here-am-I) docstruct))
7082
7083 ;; Initialize section numbers
7084 (if (eq (car (car here-am-I)) 'appendix)
7085 (reftex-init-section-numbers nil t)
7086 (reftex-init-section-numbers reftex-active-toc appendix))
7087
7088 ;; Match the section command
7089 (when (and (re-search-forward reftex-everything-regexp nil t)
7090 (match-end 3))
7091 (setq star (= ?* (char-after (match-end 3)))
7092 toc-entry (reftex-section-info (buffer-file-name))
7093 level (nth 5 toc-entry)
7094 tail (memq (car here-am-I)
7095 (symbol-value reftex-docstruct-symbol)))
7096 (if tail
7097 ;; Insert the section info
7098 (push toc-entry (cdr tail))
7099 (throw 'exit nil))
7100
7101 ;; We are done unless we use section numbers
7102 (unless (nth 1 reftex-label-menu-flags) (throw 'exit nil))
7103
7104 ;; Update the remaining toc items
7105 (setq tail (cdr tail))
7106 (while (and (setq tail (memq (assq 'toc (cdr tail)) tail))
7107 (setq toc-entry (car tail))
7108 (>= (nth 5 toc-entry) level))
7109 (setq section-number
7110 (reftex-section-number (nth 5 toc-entry) star)
7111 context (nth 2 toc-entry))
7112 (when (string-match "\\`\\([ \t]*\\)\\([.0-9A-Z]+\\)\\(.*\\)"
7113 context)
7114 (when (and (not appendix)
7115 (>= (string-to-char (match-string 2)) ?A))
7116 ;; Just entered the appendex. Get out.
7117 (throw 'exit nil))
7118
7119 ;; Change the section number.
7120 (setf (nth 2 toc-entry)
7121 (concat (match-string 1 context)
7122 section-number
7123 (match-string 3 context))))))))))
7124 (error nil))
7125 )
7126
7127 ;;; =========================================================================
7128 ;;;
7129 ;;; Keybindings
7130
7131 ;; The default bindings in the mode map.
7132 (loop for x in
7133 '(("\C-c=" . reftex-toc)
7134 ("\C-c(" . reftex-label)
7135 ("\C-c)" . reftex-reference)
7136 ("\C-c[" . reftex-citation)
7137 ("\C-c&" . reftex-view-crossref))
7138 do (define-key reftex-mode-map (car x) (cdr x)))
7139
7140 (eval-after-load
7141 "bibtex"
7142 '(define-key bibtex-mode-map "\C-c&" 'reftex-view-crossref-from-bibtex))
7143
7144 ;; Bind `reftex-mouse-view-crossref' only when the key is still free
7145 (let ((key (if (featurep 'xemacs) [(shift button2)] [(shift mouse-2)])))
7146 (unless (key-binding key)
7147 (define-key reftex-mode-map key 'reftex-mouse-view-crossref)))
7148
7149 ;; If the user requests so, she can have a few more bindings:
7150 (when reftex-extra-bindings
7151 (loop for x in
7152 '(("\C-ct" . reftex-toc)
7153 ("\C-cl" . reftex-label)
7154 ("\C-cr" . reftex-reference)
7155 ("\C-cc" . reftex-citation)
7156 ("\C-cv" . reftex-view-crossref)
7157 ("\C-cg" . reftex-grep-document)
7158 ("\C-cs" . reftex-search-document))
7159 do (define-key reftex-mode-map (car x) (cdr x))))
7160
7161 ;; Common bindings in reftex-select-label-map and reftex-select-bib-map
7162 (let ((map (make-sparse-keymap)))
7163 (substitute-key-definition
7164 'next-line 'reftex-select-next map global-map)
7165 (substitute-key-definition
7166 'previous-line 'reftex-select-previous map global-map)
7167 (substitute-key-definition
7168 'keyboard-quit 'reftex-select-keyboard-quit map global-map)
7169 (substitute-key-definition
7170 'newline 'reftex-select-accept map global-map)
7171
7172 (loop for x in
7173 '((" " . reftex-select-callback)
7174 ("n" . reftex-select-next)
7175 ([(down)] . reftex-select-next)
7176 ("p" . reftex-select-previous)
7177 ([(up)] . reftex-select-previous)
7178 ("f" . reftex-select-toggle-follow)
7179 ("\C-m" . reftex-select-accept)
7180 ([(return)] . reftex-select-accept)
7181 ("q" . reftex-select-quit)
7182 ("." . reftex-select-show-insertion-point)
7183 ("?" . reftex-select-help))
7184 do (define-key map (car x) (cdr x)))
7185
7186 ;; The mouse-2 binding
7187 (define-key map (if (featurep 'xemacs) [(button2)] [(mouse-2)])
7188 'reftex-select-mouse-accept)
7189
7190 ;; Digit arguments
7191 (loop for key across "0123456789" do
7192 (define-key map (vector (list key)) 'digit-argument))
7193 (define-key map "-" 'negative-argument)
7194
7195 ;; Make two maps
7196 (setq reftex-select-label-map map)
7197 (setq reftex-select-bib-map (copy-keymap map)))
7198
7199 ;; Specific bindings in reftex-select-label-map
7200 (loop for key across "cgilrRstx#%" do
7201 (define-key reftex-select-label-map (vector (list key))
7202 (list 'lambda '()
7203 "Press `?' during selection to find out about this key."
7204 '(interactive) (list 'throw '(quote myexit) key))))
7205
7206 (loop for x in
7207 '(("b" . reftex-select-jump-to-previous)
7208 ("v" . reftex-select-toggle-varioref)
7209 ([(tab)] . reftex-select-read-label)
7210 ("\C-i" . reftex-select-read-label)
7211 ("\C-c\C-n" . reftex-select-next-heading)
7212 ("\C-c\C-p" . reftex-select-previous-heading))
7213 do
7214 (define-key reftex-select-label-map (car x) (cdr x)))
7215
7216 ;; Specific bindings in reftex-select-bib-map
7217 (loop for key across "grRaA" do
7218 (define-key reftex-select-bib-map (vector (list key))
7219 (list 'lambda '()
7220 "Press `?' during selection to find out about this key."
7221 '(interactive) (list 'throw '(quote myexit) key))))
7222
7223 (loop for x in
7224 '(("\C-i" . reftex-select-read-cite)
7225 ([(tab)] . reftex-select-read-cite))
7226 do (define-key reftex-select-bib-map (car x) (cdr x)))
7227
7228 ;; Table of Contents map
7229 (define-key reftex-toc-map (if (featurep 'xemacs) [(button2)] [(mouse-2)])
7230 'reftex-toc-mouse-goto-line-and-hide)
7231
7232 (substitute-key-definition
7233 'next-line 'reftex-toc-next reftex-toc-map global-map)
7234 (substitute-key-definition
7235 'previous-line 'reftex-toc-previous reftex-toc-map global-map)
7236
7237 (loop for x in
7238 '(("n" . reftex-toc-next)
7239 ("p" . reftex-toc-previous)
7240 ("?" . reftex-toc-show-help)
7241 (" " . reftex-toc-view-line)
7242 ("\C-m" . reftex-toc-goto-line-and-hide)
7243 ("\C-i" . reftex-toc-goto-line)
7244 ("r" . reftex-toc-rescan)
7245 ("R" . reftex-toc-Rescan)
7246 ("g" . revert-buffer)
7247 ("q" . reftex-toc-quit)
7248 ("Q" . reftex-toc-quit-and-kill)
7249 ("f" . reftex-toc-toggle-follow)
7250 ("i" . reftex-toc-toggle-file-boundary)
7251 ("l" . reftex-toc-toggle-labels)
7252 ("c" . reftex-toc-toggle-context)
7253 ("%" . reftex-toc-toggle-commented)
7254 ("x" . reftex-toc-external)
7255 ("." . reftex-toc-show-calling-point))
7256 do (define-key reftex-toc-map (car x) (cdr x)))
7257
7258 (loop for key across "0123456789" do
7259 (define-key reftex-toc-map (vector (list key)) 'digit-argument))
7260 (define-key reftex-toc-map "-" 'negative-argument)
7261
7262 ;;; =========================================================================
7263 ;;;
7264 ;;; Menu
7265
7266 ;; Define a menu for the menu bar if Emacs is running under X
7267
7268 (require 'easymenu)
7269
7270 (easy-menu-define reftex-mode-menu reftex-mode-map
7271 "Menu used in RefTeX mode"
7272 `("Ref"
7273 ["Table of Contents" reftex-toc t]
7274 "---"
7275 ["\\label" reftex-label t]
7276 ["\\ref" reftex-reference t]
7277 ["\\cite" reftex-citation t]
7278 ["View Crossref" reftex-view-crossref t]
7279 "---"
7280 ("Parse Document"
7281 ["Only this File" reftex-parse-one t]
7282 ["Entire Document" reftex-parse-all (reftex-is-multi)]
7283 ["Save to File" (reftex-access-parse-file 'write)
7284 (> (length (symbol-value reftex-docstruct-symbol)) 0)]
7285 ["Restore from File" (reftex-access-parse-file 'restore) t]
7286 "---"
7287 ["Reset RefTeX Mode" reftex-reset-mode t])
7288 ("Global Actions"
7289 ["Search Whole Document" reftex-search-document t]
7290 ["Replace in Document" reftex-query-replace-document t]
7291 ["Grep on Document" reftex-grep-document t]
7292 "---"
7293 ["Create TAGS File" reftex-create-tags-file t]
7294 "---"
7295 ["Find Duplicate Labels" reftex-find-duplicate-labels t]
7296 ["Change Label and Refs" reftex-change-label t]
7297 ["Renumber Simple Labels" reftex-renumber-simple-labels t]
7298 "---"
7299 ["Save Document" reftex-save-all-document-buffers t])
7300 "---"
7301 ("Options"
7302 "PARSER"
7303 ["Partial Scans"
7304 (setq reftex-enable-partial-scans (not reftex-enable-partial-scans))
7305 :style toggle :selected reftex-enable-partial-scans]
7306 ["Auto-Save Parse Info"
7307 (setq reftex-save-parse-info (not reftex-save-parse-info))
7308 :style toggle :selected reftex-save-parse-info]
7309 "---"
7310 "CROSSREF INFO"
7311 ["Automatic Info" reftex-toggle-auto-view-crossref
7312 :style toggle :selected reftex-auto-view-crossref-timer]
7313 ["...in Echo Area" (setq reftex-auto-view-crossref t)
7314 :style radio :selected (eq reftex-auto-view-crossref t)]
7315 ["...in Other Window" (setq reftex-auto-view-crossref 'window)
7316 :style radio :selected (eq reftex-auto-view-crossref 'window)]
7317 "---"
7318 "MISC"
7319 ["AUC TeX Interface" reftex-toggle-plug-into-AUCTeX
7320 :style toggle :selected reftex-plug-into-AUCTeX])
7321 ("Reference Style"
7322 ["Standard" (setq reftex-vref-is-default nil)
7323 :style radio :selected (not reftex-vref-is-default)]
7324 ["Varioref" (setq reftex-vref-is-default t)
7325 :style radio :selected reftex-vref-is-default])
7326 ("Citation Style"
7327 ,@(mapcar
7328 (function
7329 (lambda (x)
7330 (vector
7331 (capitalize (symbol-name (car x)))
7332 (list 'reftex-set-cite-format (list 'quote (car x)))
7333 :style 'radio :selected
7334 (list 'eq (list 'reftex-get-cite-format) (list 'quote (car x))))))
7335 reftex-cite-format-builtin)
7336 "---"
7337 "Sort Database Matches"
7338 ["Not" (setq reftex-sort-bibtex-matches nil)
7339 :style radio :selected (eq reftex-sort-bibtex-matches nil)]
7340 ["by Author" (setq reftex-sort-bibtex-matches 'author)
7341 :style radio :selected (eq reftex-sort-bibtex-matches 'author)]
7342 ["by Year" (setq reftex-sort-bibtex-matches 'year)
7343 :style radio :selected (eq reftex-sort-bibtex-matches 'year)]
7344 ["by Year, reversed" (setq reftex-sort-bibtex-matches 'reverse-year)
7345 :style radio :selected (eq reftex-sort-bibtex-matches 'reverse-year)])
7346 "---"
7347 ("Customize"
7348 ["Browse RefTeX Group" reftex-customize t]
7349 "---"
7350 ["Build Full Customize Menu" reftex-create-customize-menu
7351 (fboundp 'customize-menu-create)])
7352 ("Documentation"
7353 ["Info" reftex-info t]
7354 ["Commentary" reftex-show-commentary t])))
7355
7356 (defun reftex-customize ()
7357 "Call the customize function with reftex as argument."
7358 (interactive)
7359 (customize-browse 'reftex))
7360
7361 (defun reftex-create-customize-menu ()
7362 "Create a full customization menu for RefTeX, insert it into the menu."
7363 (interactive)
7364 (if (fboundp 'customize-menu-create)
7365 (progn
7366 (easy-menu-change
7367 '("Ref") "Customize"
7368 `(["Browse RefTeX group" reftex-customize t]
7369 "---"
7370 ,(customize-menu-create 'reftex)
7371 ["Set" Custom-set t]
7372 ["Save" Custom-save t]
7373 ["Reset to Current" Custom-reset-current t]
7374 ["Reset to Saved" Custom-reset-saved t]
7375 ["Reset to Standard Settings" Custom-reset-standard t]))
7376 (message "\"Ref\"-menu now contains full customization menu"))
7377 (error "Cannot expand menu (outdated version of cus-edit.el)")))
7378
7379 (defun reftex-show-commentary ()
7380 "Use the finder to view the file documentation from `reftex.el'."
7381 (interactive)
7382 (require 'finder)
7383 (finder-commentary "reftex.el"))
7384
7385 (defun reftex-info ()
7386 "Read documentation for RefTeX in the info system."
7387 (interactive)
7388 (require 'info)
7389 (Info-goto-node "(reftex)"))
7390
7391 ;;; Install the kill-buffer and kill-emacs hooks ------------------------------
7392
7393 (add-hook 'kill-buffer-hook 'reftex-kill-buffer-hook)
7394 (add-hook 'kill-emacs-hook 'reftex-kill-emacs-hook)
7395
7396 ;;; Run Hook ------------------------------------------------------------------
7397
7398 (run-hooks 'reftex-load-hook)
7399
7400 ;;; That's it! ----------------------------------------------------------------
7401
7402 (setq reftex-tables-dirty t) ; in case this file is evaluated by hand
7403 (provide 'reftex)
7404
7405 ;;;============================================================================
7406
7407 ;;; reftex.el ends here
7408
7409