Commit | Line | Data |
---|---|---|
5abdc915 | 1 | ;;; reftex.el --- Minor mode for doing \label, \ref and \cite in LaTeX |
2faef409 | 2 | ;; Copyright (c) 1997, 1998 Free Software Foundation, Inc. |
a7ec1775 RS |
3 | |
4 | ;; Author: Carsten Dominik <dominik@strw.LeidenUniv.nl> | |
5 | ;; Keywords: tex | |
6 | ||
7 | ;; This file is part of GNU Emacs. | |
8 | ||
9 | ;; GNU Emacs is free software; you can redistribute it and/or modify | |
10 | ;; it under the terms of the GNU General Public License as published by | |
11 | ;; the Free Software Foundation; either version 2, or (at your option) | |
12 | ;; any later version. | |
13 | ||
14 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | ;; GNU General Public License for more details. | |
18 | ||
19 | ;; You should have received a copy of the GNU General Public License | |
20 | ;; along with GNU Emacs; see the file COPYING. If not, write to the | |
21 | ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
22 | ;; Boston, MA 02111-1307, USA. | |
23 | ||
24 | ;;--------------------------------------------------------------------------- | |
25 | ;; | |
26 | ;;; Commentary: | |
27 | ;; | |
fba437e6 RS |
28 | ;; RefTeX is a minor mode with distinct support for \ref, \label and |
29 | ;; \cite commands in (multi-file) LaTeX documents. | |
a7ec1775 RS |
30 | ;; Labels are created semi-automatically. Definition context of labels is |
31 | ;; provided when creating a reference. Citations are simplified with | |
396e0b08 KH |
32 | ;; efficient database lookup. A table of contents buffer provides easy |
33 | ;; access to any part of a document. | |
a7ec1775 | 34 | ;; |
2faef409 | 35 | ;; |
a6611c0d CD |
36 | ;; INSTALLATION |
37 | ;; ------------ | |
38 | ;; | |
39 | ;; If you got reftex.el with an Emacs distribution, it is already | |
40 | ;; installed. If not, follow the instructions in the INSTALL file of | |
41 | ;; the distribution. | |
42 | ;; | |
b849548d | 43 | ;; To turn RefTeX Mode on and off in a particular buffer, use |
a7ec1775 RS |
44 | ;; `M-x reftex-mode'. |
45 | ;; | |
b849548d CD |
46 | ;; To turn on RefTeX Mode for all LaTeX files, add one of the following |
47 | ;; lines to your .emacs file: | |
a7ec1775 RS |
48 | ;; |
49 | ;; (add-hook 'LaTeX-mode-hook 'turn-on-reftex) ; with AUCTeX LaTeX mode | |
50 | ;; (add-hook 'latex-mode-hook 'turn-on-reftex) ; with Emacs latex mode | |
51 | ;; | |
396e0b08 | 52 | ;; |
2faef409 RS |
53 | ;; DOCUMENTATION |
54 | ;; ------------- | |
396e0b08 | 55 | ;; |
a6611c0d CD |
56 | ;; See below for a short summary of how to use RefTeX. |
57 | ;; | |
2faef409 RS |
58 | ;; There is an extensive texinfo document describing RefTeX in detail. |
59 | ;; When you are getting reftex.el with the Emacs distribution, the | |
60 | ;; info files should already be installed. To view this | |
61 | ;; documentation, use `M-x reftex-info RET'. | |
a7ec1775 | 62 | ;; |
a6611c0d | 63 | ;; The documentation in various formats is also available at |
396e0b08 | 64 | ;; |
2faef409 | 65 | ;; http://www.strw.leidenuniv.nl/~dominik/Tools/ |
396e0b08 | 66 | ;; |
2faef409 RS |
67 | ;;--------------------------------------------------------------------------- |
68 | ;; | |
69 | ;; RefTeX in a Nutshell | |
70 | ;; ==================== | |
71 | ;; | |
b849548d CD |
72 | ;; 1. Labels and References |
73 | ;; RefTeX distinguishes labels for different environments. It knows | |
74 | ;; about all standard environments (and many others), and can be | |
75 | ;; configured to recognize any additional labeled environments you | |
a6611c0d | 76 | ;; have defined yourself (variable REFTEX-LABEL-ALIST). |
b849548d CD |
77 | ;; |
78 | ;; * Creating Labels | |
79 | ;; Type `C-c (' (`reftex-label') to insert a label at point. | |
80 | ;; RefTeX will either | |
81 | ;; - derive a label from context (default for section labels) | |
82 | ;; - prompt for a label string (default for figures and | |
83 | ;; tables) or | |
84 | ;; - insert a simple label made of a prefix and a number (all | |
85 | ;; other environments). | |
86 | ;; Which labels are created how is configurable (variable | |
87 | ;; REFTEX-INSERT-LABEL-FLAGS). | |
88 | ;; | |
89 | ;; * Referencing Labels | |
90 | ;; In order to make a reference, type `C-c )' | |
91 | ;; (`reftex-reference'). This shows an outline of the document | |
92 | ;; with all labels of a certain type (figure, equation,...) and | |
93 | ;; context of the label definition. Selecting a label inserts a | |
94 | ;; `\ref{LABEL}' macro into the original buffer. | |
95 | ;; | |
96 | ;; 2. Citations | |
97 | ;; After typing `C-c [' (`reftex-citation'), RefTeX will let you | |
98 | ;; specify a regular expression to search in current BibTeX database | |
99 | ;; files (as specified in the `\bibliography' command) and pull out a | |
100 | ;; list of matches for you to choose from. The list is *formatted* | |
101 | ;; and sorted. The selected article is referenced as `\cite{KEY}' | |
102 | ;; (customizable with variable REFTEX-CITE-FORMAT). | |
103 | ;; | |
104 | ;; 3. Viewing Cross References | |
105 | ;; When no other message occupies the echo area and point is idle on | |
106 | ;; the argument of a `\ref' or `\cite' macro, the echo area will | |
107 | ;; display information about the citation/cross reference. | |
a6611c0d | 108 | ;; With point on the argument of such a macro, press `C-c &' |
b849548d CD |
109 | ;; (`reftex-view-crossref'), or click with `S-mouse-2' on the macro |
110 | ;; argument. This will display the corresponding label definition or | |
111 | ;; BibTeX database entry in another window. | |
112 | ;; | |
113 | ;; 4. Table of Contents | |
114 | ;; Typing `C-c =' (`reftex-toc') will show a table of contents of the | |
115 | ;; document. From that buffer, you can jump quickly to every part of | |
116 | ;; your document. | |
117 | ;; | |
118 | ;; 5. Multifile Documents | |
119 | ;; Multifile Documents are fully supported. RefTeX will provide cross | |
120 | ;; referencing information from all files which are part of the | |
121 | ;; document, and even across document borders (`xr.sty'). | |
122 | ;; | |
123 | ;; 6. Document Parsing | |
124 | ;; RefTeX needs to parse the document in order to find labels and | |
125 | ;; other information. It does it automatically once, when you start | |
126 | ;; working with a document. RefTeX updates its lists internally when | |
127 | ;; you make a new label with `reftex-label'. To enforce reparsing, | |
128 | ;; call any of the commands described above with a raw `C-u' prefix, | |
129 | ;; or press the `r' key in the label selection buffer or the table of | |
130 | ;; contents buffer. | |
131 | ;; | |
a6611c0d CD |
132 | ;; 7. Useful Settings |
133 | ;; To make RefTeX faster for large documents include, and to integrate | |
134 | ;; it with AUCTeX, try these: | |
135 | ;; | |
b849548d CD |
136 | ;; (setq reftex-enable-partial-scans t) |
137 | ;; (setq reftex-save-parse-info t) | |
138 | ;; (setq reftex-use-multiple-selection-buffers t) | |
a6611c0d | 139 | ;; (setq reftex-plug-into-AUCTeX t) |
a7ec1775 | 140 | ;; |
a7ec1775 RS |
141 | ;;--------------------------------------------------------------------------- |
142 | ;; | |
143 | ;; AUTHOR | |
396e0b08 | 144 | ;; ====== |
a7ec1775 RS |
145 | ;; |
146 | ;; Carsten Dominik <dominik@strw.LeidenUniv.nl> | |
147 | ;; | |
148 | ;; with contributions from Stephen Eglen | |
149 | ;; | |
150 | ;; The newest version of RefTeX can be found at | |
151 | ;; | |
152 | ;; http://www.strw.leidenuniv.nl/~dominik/Tools/ | |
a6611c0d | 153 | ;; ftp://ftp.strw.leidenuniv.nl/pub/dominik/ |
a7ec1775 | 154 | ;; |
b849548d CD |
155 | ;; At that site you can also get version 3.22 of RefTeX which is still |
156 | ;; compatible with Emacs 19. The file you are reading now as well as the | |
157 | ;; ones distributed with Emacs 20 are not. | |
2faef409 | 158 | ;; |
a7ec1775 RS |
159 | ;; THANKS TO: |
160 | ;; --------- | |
2faef409 RS |
161 | ;; Thanks to the people on the Net who have used RefTeX and helped |
162 | ;; developing it with their reports. In particular thanks to | |
a7ec1775 | 163 | ;; |
2faef409 RS |
164 | ;; F. Burstall, Alastair Burt, Soren Dayton, Stephen Eglen, |
165 | ;; Karl Eichwalder, Peter Galbraith, Dieter Kraft, Adrian Lanz, | |
166 | ;; Rory Molinari, Laurent Mugnier, Sudeep Kumar Palat, Daniel Polani, | |
167 | ;; Robin Socha, Richard Stanton, Allan Strand, Jan Vroonhof, | |
a6611c0d | 168 | ;; Christoph Wedler, Alan Williams. |
a7ec1775 | 169 | ;; |
2faef409 RS |
170 | ;; Finally thanks to Uwe Bolick who first got me (some years ago) into |
171 | ;; supporting LaTeX labels and references with an Editor (which was | |
172 | ;; MicroEmacs at the time). | |
025bb635 | 173 | ;; |
a6611c0d | 174 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
c52bdfca | 175 | ;; |
a6611c0d | 176 | ;;;;;; |
a7ec1775 RS |
177 | \f |
178 | ;;; Code: | |
179 | ||
396e0b08 KH |
180 | (eval-when-compile (require 'cl)) |
181 | ||
a7ec1775 | 182 | ;; Stuff that needs to be there when we use defcustom |
a7ec1775 RS |
183 | (require 'custom) |
184 | ||
185 | (defvar reftex-tables-dirty t | |
186 | "Flag showing if tables need to be re-computed.") | |
187 | ||
188 | (eval-and-compile | |
189 | (defun reftex-set-dirty (symbol value) | |
190 | (setq reftex-tables-dirty t) | |
191 | (set symbol value))) | |
192 | ||
b849548d CD |
193 | ;;; ====================================================================== |
194 | ;;; | |
195 | ;;; Configuration Section | |
a7ec1775 | 196 | |
396e0b08 KH |
197 | ;; Define the two constants which are needed during compilation |
198 | ||
199 | (eval-and-compile | |
200 | (defconst reftex-label-alist-builtin | |
201 | '( | |
202 | ;; Some aliases, mostly for backward compatibility | |
203 | (Sideways "Alias for -->rotating" (rotating)) | |
204 | (AMSTeX "amsmath with eqref macro" | |
205 | ((nil ?e nil "~\\eqref{%s}") | |
206 | amsmath)) | |
207 | ||
208 | ;; Individual package defaults | |
209 | (amsmath "AMS-LaTeX math environments" | |
210 | (("align" ?e nil nil eqnarray-like) | |
211 | ("gather" ?e nil nil eqnarray-like) | |
212 | ("multline" ?e nil nil t) | |
213 | ("flalign" ?e nil nil eqnarray-like) | |
214 | ("alignat" ?e nil nil alignat-like) | |
215 | ("xalignat" ?e nil nil alignat-like) | |
216 | ("xxalignat" ?e nil nil alignat-like) | |
217 | ("subequations" ?e nil nil t))) | |
218 | ||
219 | (endnotes "The \\endnote macro" | |
2faef409 | 220 | (("\\endnote[]{}" ?n nil nil 2 (regexp "Endnotes?")))) |
396e0b08 KH |
221 | |
222 | (fancybox "The Beqnarray environment" | |
223 | (("Beqnarray" ?e nil nil eqnarray-like))) | |
224 | ||
225 | (floatfig "The floatingfigure environment" | |
226 | (("floatingfigure" ?f nil nil caption))) | |
227 | ||
228 | (longtable "The longtable environment" | |
229 | (("longtable" ?t nil nil caption))) | |
230 | ||
231 | (picinpar "The figwindow and tabwindow environments" | |
232 | (("figwindow" ?f nil nil 1) | |
233 | ("tabwindow" ?f nil nil 1))) | |
234 | ||
235 | (rotating "Sidewaysfigure and table" | |
236 | (("sidewaysfigure" ?f nil nil caption) | |
237 | ("sidewaystable" ?t nil nil caption))) | |
238 | ||
29d593f8 KH |
239 | (sidecap "CSfigure and SCtable" |
240 | (("SCfigure" ?f nil nil caption) | |
241 | ("SCtable" ?t nil nil caption))) | |
242 | ||
396e0b08 KH |
243 | (subfigure "Subfigure environments/macro" |
244 | (("subfigure" ?f nil nil caption) | |
245 | ("subfigure*" ?f nil nil caption) | |
246 | ("\\subfigure[]{}" ?f nil nil 1))) | |
247 | ||
248 | (supertab "Supertabular environment" | |
249 | (("supertabular" ?t nil nil "\\tablecaption{"))) | |
250 | ||
251 | (wrapfig "The wrapfigure environment" | |
252 | (("wrapfigure" ?f nil nil caption))) | |
253 | ||
254 | ;; The LaTeX core stuff | |
255 | (LaTeX "LaTeX default environments" | |
256 | (("section" ?s "sec:" "~\\ref{%s}" (nil . t) | |
b849548d CD |
257 | (regexp "parts?" "chapters?" "chap\\." "sections?" "sect?\\." |
258 | "paragraphs?" "par\\." | |
2faef409 | 259 | "\\\\S" "\247" "Teile?" "Kapitel" "Kap\\." "Abschnitte?" |
b849548d | 260 | "appendi\\(x\\|ces\\)" "App\\." "Anh\"?ange?" "Anh\\.")) |
396e0b08 KH |
261 | |
262 | ("enumerate" ?i "item:" "~\\ref{%s}" item | |
b849548d | 263 | (regexp "items?" "Punkte?")) |
2faef409 | 264 | |
396e0b08 | 265 | ("equation" ?e "eq:" "~(\\ref{%s})" t |
b849548d | 266 | (regexp "equations?" "eqs?\\." "eqn\\." "Gleichung\\(en\\)?" "Gl\\.")) |
396e0b08 | 267 | ("eqnarray" ?e "eq:" nil eqnarray-like) |
2faef409 | 268 | |
396e0b08 | 269 | ("figure" ?f "fig:" "~\\ref{%s}" caption |
b849548d | 270 | (regexp "figure?[sn]?" "figs?\\." "Abbildung\\(en\\)?" "Abb\\.")) |
396e0b08 | 271 | ("figure*" ?f nil nil caption) |
2faef409 | 272 | |
396e0b08 | 273 | ("table" ?t "tab:" "~\\ref{%s}" caption |
b849548d | 274 | (regexp "tables?" "tab\\." "Tabellen?")) |
396e0b08 | 275 | ("table*" ?t nil nil caption) |
2faef409 | 276 | |
396e0b08 | 277 | ("\\footnote[]{}" ?n "note:" "~\\ref{%s}" 2 |
b849548d | 278 | (regexp "footnotes?" "notes?" "Anmerkung\\(en\\)?" "Anm\\.")) |
2faef409 | 279 | |
b849548d CD |
280 | ("any" ?\ " " "~\\ref{%s}" nil) |
281 | ||
282 | ;; The label macro is hard coded, but it *could* be defined like this: | |
283 | ;;("\\label{*}" nil nil nil nil) | |
284 | )) | |
396e0b08 KH |
285 | |
286 | ) | |
287 | "The default label environment descriptions. | |
288 | Lower-case symbols correspond to a style file of the same name in the LaTeX | |
289 | distribution. Mixed-case symbols are convenience aliases.") | |
290 | ||
291 | (defconst reftex-cite-format-builtin | |
292 | '( | |
293 | (default "Default macro \\cite{%l}" | |
294 | "\\cite{%l}") | |
295 | (natbib "The Natbib package" | |
296 | ((?\C-m . "\\cite{%l}") | |
297 | (?t . "\\citet{%l}") | |
298 | (?T . "\\citet*{%l}") | |
299 | (?p . "\\citep{%l}") | |
300 | (?P . "\\citep*{%l}") | |
301 | (?e . "\\citep[e.g.][]{%l}") | |
b849548d | 302 | (?s . "\\citep[see][]{%l}") |
396e0b08 | 303 | (?a . "\\citeauthor{%l}") |
b849548d | 304 | (?A . "\\citeauthor*{%l}") |
396e0b08 KH |
305 | (?y . "\\citeyear{%l}"))) |
306 | (harvard "The Harvard package" | |
307 | ((?\C-m . "\\cite{%l}") | |
308 | (?p . "\\cite{%l}") | |
309 | (?t . "\\citeasnoun{%l}") | |
310 | (?n . "\\citeasnoun{%l}") | |
311 | (?s . "\\possessivecite{%l}") | |
312 | (?e . "\\citeaffixed{%l}{?}") | |
313 | (?y . "\\citeyear{%l}") | |
314 | (?a . "\\citename{%l}"))) | |
315 | (chicago "The Chicago package" | |
316 | ((?\C-m . "\\cite{%l}") | |
317 | (?t . "\\citeN{%l}") | |
318 | (?T . "\\shortciteN{%l}") | |
319 | (?p . "\\cite{%l}") | |
320 | (?P . "\\shortcite{%l}") | |
321 | (?a . "\\citeA{%l}") | |
322 | (?A . "\\shortciteA{%l}") | |
2faef409 | 323 | (?y . "\\citeyear{%l}"))) |
396e0b08 KH |
324 | (astron "The Astron package" |
325 | ((?\C-m . "\\cite{%l}") | |
326 | (?p . "\\cite{%l}" ) | |
327 | (?t . "%2a (\\cite{%l})"))) | |
328 | (author-year "Do-it-yourself Author-year" | |
329 | ((?\C-m . "\\cite{%l}") | |
330 | (?t . "%2a (%y)\\nocite{%l}") | |
331 | (?p . "(%2a %y\\nocite{%l})"))) | |
332 | (locally "Full info in parenthesis" | |
333 | "(%2a %y, %j %v, %P, %e: %b, %u, %s %<)") | |
396e0b08 | 334 | ) |
b849548d | 335 | "Builtin versions of the citation format. |
396e0b08 KH |
336 | The following conventions are valid for all alist entries: |
337 | `?\C-m' should always point to a straight \\cite{%l} macro. | |
338 | `?t' should point to a textual citation (citation as a noun). | |
339 | `?p' should point to a parenthetical citation.") | |
340 | ) | |
341 | ||
a7ec1775 RS |
342 | ;; Configuration Variables and User Options for RefTeX ------------------ |
343 | ||
344 | (defgroup reftex nil | |
345 | "LaTeX label and citation support." | |
346 | :tag "RefTeX" | |
396e0b08 KH |
347 | :link '(url-link :tag "Home Page" |
348 | "http://strw.leidenuniv.nl/~dominik/Tools/") | |
349 | :link '(emacs-commentary-link :tag "Commentary in reftex.el" "reftex.el") | |
a7ec1775 RS |
350 | :prefix "reftex-" |
351 | :group 'tex) | |
352 | ||
a7ec1775 | 353 | (defgroup reftex-label-support nil |
c52bdfca | 354 | "Support for creation, insertion and referencing of labels in LaTeX." |
a7ec1775 RS |
355 | :group 'reftex) |
356 | ||
357 | (defgroup reftex-defining-label-environments nil | |
c52bdfca | 358 | "Definition of environments and macros to do with label." |
a7ec1775 RS |
359 | :group 'reftex-label-support) |
360 | ||
396e0b08 KH |
361 | (defcustom reftex-default-label-alist-entries |
362 | '(amsmath endnotes fancybox floatfig longtable picinpar | |
29d593f8 | 363 | rotating sidecap subfigure supertab wrapfig LaTeX) |
396e0b08 KH |
364 | "Default label alist specifications. LaTeX should be the last entry. |
365 | This list describes the default label environments RefTeX should always use. | |
366 | It is probably a mistake to remove the LaTeX symbol from this list. | |
367 | ||
368 | The options include: | |
369 | LaTeX The standard LaTeX environments. | |
370 | Sideways The sidewaysfigure and sidewaystable environments. | |
371 | AMSTeX The math environments in the AMS-LaTeX amsmath package. | |
372 | ||
373 | For the full list of options, try | |
374 | ||
375 | M-x customize-variable RET reftex-default-label-alist-entries RET." | |
376 | :group 'reftex-defining-label-environments | |
377 | :set 'reftex-set-dirty | |
378 | :type `(set | |
379 | :indent 4 | |
380 | :inline t | |
381 | :greedy t | |
382 | ,@(mapcar | |
383 | (function | |
384 | (lambda (x) | |
385 | (list 'const ':tag (concat (symbol-name (nth 0 x)) | |
386 | ": " (nth 1 x)) | |
387 | (nth 0 x)))) | |
388 | reftex-label-alist-builtin))) | |
389 | ||
a7ec1775 | 390 | (defcustom reftex-label-alist nil |
fba437e6 | 391 | "Alist with information on environments for \\label-\\ref use. |
a7ec1775 | 392 | |
396e0b08 KH |
393 | This docstring is easier to understand after reading the configuration |
394 | examples in `reftex.el'. Looking at the builtin defaults in the constant | |
395 | `reftex-label-alist-builtin' may also be instructive. | |
396 | ||
397 | Set this variable to define additions and changes to the default. The only | |
398 | things you MUST NOT change is that `?s' is the type indicator for section | |
399 | labels, and SPC for the `any' label type. These are hard-coded at other | |
400 | places in the code. | |
a7ec1775 | 401 | |
396e0b08 KH |
402 | Each list entry describes either an environment carrying a counter for use |
403 | with \\label and \\ref, or a LaTeX macro defining a label as (or inside) | |
404 | one of its arguments. The elements of each list entry are: | |
a7ec1775 RS |
405 | |
406 | 0. Name of the environment (like \"table\") or macro (like \"\\\\myfig\"). | |
396e0b08 KH |
407 | For macros, indicate the macro arguments for best results, as in |
408 | \"\\\\myfig[]{}{}{*}{}\". Use square brackets for optional arguments, | |
409 | a star to mark the label argument, if any. The macro does not have to | |
410 | have a label argument - you could also use \\label{..} inside one of | |
411 | its arguments. | |
a7ec1775 RS |
412 | Special names: `section' for section labels, `any' to define a group |
413 | which contains all labels. | |
396e0b08 | 414 | This may also be nil if the entry is only meant to change some settings |
a7ec1775 RS |
415 | associated with the type indicator character (see below). |
416 | ||
396e0b08 KH |
417 | 1. Type indicator character, like `?t', must be a printable ASCII character. |
418 | The type indicator is a single character which defines a label type. | |
419 | Any label inside the environment or macro is assumed to belong to this | |
420 | type. The same character may occur several times in this list, to cover | |
421 | cases in which different environments carry the same label type (like | |
422 | `equation' and `eqnarray'). | |
b849548d CD |
423 | If the type indicator is nil and the macro has a label argument {*}, |
424 | the macro defines neutral labels just like \label. In this case | |
425 | the reminder of this entry is ignored. | |
a7ec1775 RS |
426 | |
427 | 2. Label prefix string, like \"tab:\". | |
f52b232e | 428 | The prefix is a short string used as the start of a label. It may be the |
396e0b08 | 429 | empty string. The prefix may contain the following `%' escapes: |
206c6f82 RS |
430 | %f Current file name with directory and extension stripped. |
431 | %F Current file name relative to directory of master file. | |
432 | %u User login name, on systems which support this. | |
433 | ||
434 | Example: In a file `intro.tex', \"eq:%f:\" will become \"eq:intro:\"). | |
a7ec1775 | 435 | |
206c6f82 RS |
436 | 3. Format string for reference insert in buffer. `%s' will be replaced by |
437 | the label. | |
2faef409 RS |
438 | When the format starts with `~', the `~' will only be inserted if |
439 | there is not already a whitespace before point. | |
a7ec1775 RS |
440 | |
441 | 4. Indication on how to find the short context. | |
f52b232e RS |
442 | - If nil, use the text following the \\label{...} macro. |
443 | - If t, use | |
a7ec1775 | 444 | - the section heading for section labels. |
396e0b08 KH |
445 | - text following the \\begin{...} statement of environments. |
446 | (not a good choice for environments like eqnarray or enumerate, | |
447 | where one has several labels in a single environment). | |
2faef409 | 448 | - text after the macro name (starting with the first arg) for macros. |
396e0b08 KH |
449 | - If an integer, use the nth argument of the macro. As a special case, |
450 | 1000 means to get text after the last macro argument. | |
f52b232e RS |
451 | - If a string, use as regexp to search *backward* from the label. Context |
452 | is then the text following the end of the match. E.g. putting this to | |
baec1250 | 453 | \"\\\\\\\\caption[[{]\" will use the caption in a figure or table |
396e0b08 | 454 | environment. |
c52bdfca | 455 | \"\\\\\\\\begin{eqnarray}\\\\|\\\\\\\\\\\\\\\\\" works for eqnarrays. |
396e0b08 KH |
456 | - If any of `caption', `item', `eqnarray-like', `alignat-like', this |
457 | symbol will internally be translated into an appropriate regexp | |
458 | (see also the variable `reftex-default-context-regexps'). | |
a7ec1775 | 459 | - If a function, call this function with the name of the environment/macro |
f52b232e RS |
460 | as argument. On call, point will be just after the \\label macro. The |
461 | function is expected to return a suitable context string. It should | |
a7ec1775 | 462 | throw an exception (error) when failing to find context. |
206c6f82 RS |
463 | As an example, here is a function returning the 10 chars following |
464 | the label macro as context: | |
a7ec1775 RS |
465 | |
466 | (defun my-context-function (env-or-mac) | |
467 | (if (> (point-max) (+ 10 (point))) | |
468 | (buffer-substring (point) (+ 10 (point))) | |
469 | (error \"Buffer too small\"))) | |
470 | ||
206c6f82 RS |
471 | Label context is used in two ways by RefTeX: For display in the label |
472 | menu, and to derive a label string. If you want to use a different | |
473 | method for each of these, specify them as a dotted pair. | |
474 | E.g. `(nil . t)' uses the text after the label (nil) for display, and | |
475 | text from the default position (t) to derive a label string. This is | |
476 | actually used for section labels. | |
477 | ||
f52b232e RS |
478 | Setting the variable `reftex-use-text-after-label-as-context' to t |
479 | overrides the setting here. | |
a7ec1775 | 480 | |
c52bdfca RS |
481 | 5. List of magic words which identify a reference to be of this type. |
482 | If the word before point is equal to one of these words when calling | |
206c6f82 RS |
483 | `reftex-reference', the label list offered will be automatically |
484 | restricted to labels of the correct type. | |
2faef409 RS |
485 | If the first element of this wordlist is the symbol `regexp', the |
486 | strings are interpreted as regular expressions. RefTeX will add | |
487 | a \"\\\\W\" to the beginning and other stuff to the end of the regexp. | |
a7ec1775 RS |
488 | |
489 | If the type indicator characters of two or more entries are the same, RefTeX | |
490 | will use | |
491 | - the first non-nil format and prefix | |
492 | - the magic words of all involved entries. | |
493 | ||
f52b232e | 494 | Any list entry may also be a symbol. If that has an association in |
2faef409 RS |
495 | `reftex-label-alist-builtin', the cddr of that association is spliced into the |
496 | list. However, builtin defaults should normally be set with the variable | |
497 | `reftex-default-label-alist-entries." | |
a7ec1775 RS |
498 | :group 'reftex-defining-label-environments |
499 | :set 'reftex-set-dirty | |
206c6f82 | 500 | :type |
396e0b08 | 501 | `(repeat |
b849548d | 502 | (choice :tag "Package or Detailed " |
396e0b08 | 503 | :value ("" ?a nil nil nil nil) |
b849548d | 504 | (list :tag "Detailed Entry" |
396e0b08 KH |
505 | :value ("" ?a nil nil nil nil) |
506 | (choice :tag "Environment or \\macro " | |
507 | (const :tag "Ignore, just use typekey" nil) | |
508 | (string "")) | |
b849548d CD |
509 | (choice :tag "Type specification " |
510 | (const :tag "unspecified, like in \\label" nil) | |
511 | (character :tag "Char " ?a)) | |
396e0b08 KH |
512 | (choice :tag "Label prefix string " |
513 | (const :tag "Default" nil) | |
514 | (string :tag "String" "lab:")) | |
515 | (choice :tag "Label reference format" | |
516 | (const :tag "Default" nil) | |
517 | (string :tag "String" "~\\ref{%s}")) | |
b849548d CD |
518 | (choice :tag "Context method " |
519 | (const :tag "Default position" t) | |
520 | (const :tag "After label" nil) | |
521 | (number :tag "Macro arg nr" 1) | |
522 | (regexp :tag "Regexp" "") | |
523 | (const :tag "Caption in float" caption) | |
524 | (const :tag "Item in list" item) | |
525 | (const :tag "Eqnarray-like" eqnarray-like) | |
526 | (const :tag "Alignat-like" alignat-like) | |
527 | (symbol :tag "Function" my-func)) | |
528 | (repeat :tag "Magic words" :extra-offset 2 (string))) | |
396e0b08 KH |
529 | (choice |
530 | :tag "Package" | |
206c6f82 | 531 | :value AMSTeX |
396e0b08 KH |
532 | ,@(mapcar |
533 | (function | |
534 | (lambda (x) | |
2faef409 | 535 | (list 'const ':tag (concat (symbol-name (nth 0 x))) |
396e0b08 KH |
536 | (nth 0 x)))) |
537 | reftex-label-alist-builtin))))) | |
a7ec1775 | 538 | |
baec1250 KH |
539 | ;; LaTeX section commands and level numbers |
540 | (defcustom reftex-section-levels | |
541 | '( | |
542 | ("part" . 0) | |
543 | ("chapter" . 1) | |
544 | ("section" . 2) | |
545 | ("subsection" . 3) | |
546 | ("subsubsection" . 4) | |
547 | ("paragraph" . 5) | |
548 | ("subparagraph" . 6) | |
549 | ("subsubparagraph" . 7) | |
550 | ) | |
551 | "Commands and levels used for defining sections in the document. | |
552 | The car of each cons cell is the name of the section macro. The cdr is a | |
553 | number indicating its level." | |
554 | :group 'reftex-defining-label-environments | |
555 | :set 'reftex-set-dirty | |
556 | :type '(repeat | |
557 | (cons (string :tag "sectioning macro" "") | |
558 | (number :tag "level " 0)))) | |
559 | ||
560 | (defcustom reftex-default-context-regexps | |
561 | '((caption . "\\\\\\(rot\\)?caption\\*?[[{]") | |
562 | (item . "\\\\item\\(\\[[^]]*\\]\\)?") | |
563 | (eqnarray-like . "\\\\begin{%s}\\|\\\\\\\\") | |
564 | (alignat-like . "\\\\begin{%s}{[0-9]*}\\|\\\\\\\\")) | |
565 | "Alist with default regular expressions for finding context. | |
566 | The form (format regexp (regexp-quote environment)) is used to calculate | |
567 | the final regular expression - so %s will be replaced with the environment | |
568 | or macro." | |
569 | :group 'reftex-defining-label-environments | |
570 | :type '(repeat (cons (symbol) (regexp)))) | |
571 | ||
a7ec1775 RS |
572 | (defcustom reftex-use-text-after-label-as-context nil |
573 | "*t means, grab context from directly after the \\label{..} macro. | |
574 | This is the fastest method for obtaining context of the label definition, but | |
c52bdfca RS |
575 | requires discipline when placing labels. Setting this variable to t takes |
576 | precedence over the individual settings in `reftex-label-alist'. | |
a7ec1775 RS |
577 | This variable may be set to t, nil, or a string of label type letters |
578 | indicating the label types for which it should be true." | |
579 | :group 'reftex-defining-label-environments | |
580 | :set 'reftex-set-dirty | |
581 | :type '(choice | |
396e0b08 KH |
582 | (const :tag "on" t) (const :tag "off" nil) |
583 | (string :tag "Selected label types"))) | |
a7ec1775 RS |
584 | |
585 | ;; Label insertion | |
586 | ||
587 | (defgroup reftex-making-and-inserting-labels nil | |
c52bdfca | 588 | "Options on how to create new labels." |
a7ec1775 RS |
589 | :group 'reftex-label-support) |
590 | ||
591 | (defcustom reftex-insert-label-flags '("s" "sft") | |
c52bdfca | 592 | "Flags governing label insertion. First flag DERIVE, second flag PROMPT. |
a7ec1775 RS |
593 | |
594 | If DERIVE is t, RefTeX will try to derive a sensible label from context. | |
595 | A section label for example will be derived from the section heading. | |
596 | The conversion of the context to a legal label is governed by the | |
c52bdfca | 597 | specifications given in `reftex-derive-label-parameters'. |
a7ec1775 | 598 | If RefTeX fails to derive a label, it will prompt the user. |
396e0b08 KH |
599 | If DERIVE is nil, the label generated will consist of the prefix and a |
600 | unique number, like `eq:23'. | |
a7ec1775 | 601 | |
c52bdfca | 602 | If PROMPT is t, the user will be prompted for a label string. The prompt will |
a7ec1775 RS |
603 | already contain the prefix, and (if DERIVE is t) a default label derived from |
604 | context. When PROMPT is nil, the default label will be inserted without | |
605 | query. | |
606 | ||
c52bdfca | 607 | So the combination of DERIVE and PROMPT controls label insertion. Here is a |
a7ec1775 RS |
608 | table describing all four possibilities: |
609 | ||
610 | DERIVE PROMPT ACTION | |
611 | ------------------------------------------------------------------------- | |
c52bdfca RS |
612 | nil nil Insert simple label, like eq:22 or sec:13. No query. |
613 | nil t Prompt for label. | |
614 | t nil Derive a label from context and insert without query. | |
615 | t t Derive a label from context and prompt for confirmation. | |
a7ec1775 RS |
616 | |
617 | Each flag may be set to t, nil, or a string of label type letters | |
2faef409 RS |
618 | indicating the label types for which it should be true. The strings work |
619 | like character classes. | |
c52bdfca | 620 | Thus, the combination may be set differently for each label type. The |
a7ec1775 | 621 | default settings \"s\" and \"sft\" mean: Derive section labels from headings |
c52bdfca | 622 | (with confirmation). Prompt for figure and table labels. Use simple labels |
2faef409 RS |
623 | without confirmation for everything else. |
624 | The available label types are: s (section), f (figure), t (table), i (item), | |
625 | e (equation), n (footnote), plus any definitions in `reftex-label-alist'." | |
a7ec1775 RS |
626 | :group 'reftex-making-and-inserting-labels |
627 | :type '(list (choice :tag "Derive label from context" | |
628 | (const :tag "always" t) | |
629 | (const :tag "never" nil) | |
206c6f82 | 630 | (string :tag "selected label types" "")) |
a7ec1775 RS |
631 | (choice :tag "Prompt for label string " |
632 | :entry-format " %b %v" | |
633 | (const :tag "always" t) | |
634 | (const :tag "never" nil) | |
206c6f82 | 635 | (string :tag "selected label types" "")))) |
a7ec1775 | 636 | |
b849548d CD |
637 | (defcustom reftex-string-to-label-function 'reftex-string-to-label |
638 | "Function to turn an arbitrary string into a legal label. | |
639 | RefTeX's default function uses the variable `reftex-derive-label-parameters'." | |
640 | :group 'reftex-making-and-inserting-labels | |
641 | :type 'symbol) | |
642 | ||
a6611c0d | 643 | (defcustom reftex-translate-to-ascii-function 'reftex-latin1-to-ascii |
b849548d | 644 | "Filter function which will process a context string before it is used |
a6611c0d CD |
645 | to derive a label from it. The intended application is to convert ISO or |
646 | Mule characters into something legal in labels. The default function | |
647 | removes the accents from Latin-1 characters. X-Symbol (>=2.6) sets this | |
648 | variable to the much more general `x-symbol-translate-to-ascii'." | |
b849548d CD |
649 | :group 'reftex-making-and-inserting-labels |
650 | :type 'symbol) | |
651 | ||
396e0b08 | 652 | (defcustom reftex-derive-label-parameters '(3 20 t 1 "-" |
b849548d | 653 | ("the" "on" "in" "off" "a" "for" "by" "of" "and" "is" "to") t) |
a7ec1775 RS |
654 | "Parameters for converting a string into a label. |
655 | NWORDS Number of words to use. | |
656 | MAXCHAR Maximum number of characters in a label string. | |
657 | ILLEGAL nil: Throw away any words containing characters illegal in labels. | |
658 | t: Throw away only the illegal characters, not the whole word. | |
659 | ABBREV nil: Never abbreviate words. | |
c52bdfca | 660 | t: Always abbreviate words (see `reftex-abbrev-parameters'). |
a7ec1775 RS |
661 | not t and not nil: Abbreviate words if necessary to shorten |
662 | label string below MAXCHAR. | |
c52bdfca | 663 | SEPARATOR String separating different words in the label. |
b849548d CD |
664 | IGNOREWORDS List of words which should not be part of labels. |
665 | DOWNCASE t: Downcase words before using them." | |
a7ec1775 RS |
666 | :group 'reftex-making-and-inserting-labels |
667 | :type '(list (integer :tag "Number of words " 3) | |
396e0b08 KH |
668 | (integer :tag "Maximum label length " 20) |
669 | (choice :tag "Illegal characters in words" | |
670 | (const :tag "throw away entire word" nil) | |
671 | (const :tag "throw away single chars" t)) | |
672 | (choice :tag "Abbreviate words " | |
673 | (const :tag "never" nil) | |
674 | (const :tag "always" t) | |
675 | (const :tag "when label is too long" 1)) | |
676 | (string :tag "Separator between words " "-") | |
677 | (repeat :tag "Ignore words" | |
678 | :entry-format " %i %d %v" | |
b849548d CD |
679 | (string :tag "")) |
680 | (option (boolean :tag "Downcase words ")))) | |
396e0b08 | 681 | |
a6611c0d CD |
682 | (defcustom reftex-label-illegal-re "[^-a-zA-Z0-9_+=:;,.]" |
683 | "Regexp matching characters not legal in labels." | |
a7ec1775 | 684 | :group 'reftex-making-and-inserting-labels |
a6611c0d | 685 | :type '(regexp :tag "Regular Expression")) |
a7ec1775 | 686 | |
b849548d | 687 | (defcustom reftex-abbrev-parameters '(4 2 "^aeiou" "aeiou") |
a7ec1775 | 688 | "Parameters for abbreviation of words. |
c52bdfca RS |
689 | MIN-CHARS Minimum number of characters remaining after abbreviation. |
690 | MIN-KILL Minimum number of characters to remove when abbreviating words. | |
691 | BEFORE Character class before abbrev point in word. | |
692 | AFTER Character class after abbrev point in word." | |
a7ec1775 RS |
693 | :group 'reftex-making-and-inserting-labels |
694 | :type '(list | |
396e0b08 KH |
695 | (integer :tag "Minimum chars per word" 4) |
696 | (integer :tag "Shorten by at least " 2) | |
697 | (string :tag "cut before char class " "^saeiou") | |
698 | (string :tag "cut after char class " "aeiou"))) | |
a7ec1775 | 699 | |
2faef409 RS |
700 | (defcustom reftex-format-label-function nil |
701 | "Function which produces the string to insert as a label definition. | |
702 | Normally should be nil, unless you want to do something fancy. | |
703 | The function will be called with two arguments, the LABEL and the DEFAULT | |
704 | FORMAT, which usually is `\label{%s}'. The function should return the | |
705 | string to insert into the buffer." | |
706 | :group 'reftex-making-and-inserting-labels | |
707 | :type 'function) | |
708 | ||
a7ec1775 RS |
709 | ;; Label referencing |
710 | ||
711 | (defgroup reftex-referencing-labels nil | |
c52bdfca | 712 | "Options on how to reference labels." |
a7ec1775 RS |
713 | :group 'reftex-label-support) |
714 | ||
396e0b08 KH |
715 | (eval-and-compile |
716 | (defconst reftex-tmp | |
717 | '((const :tag "on" t) | |
718 | (const :tag "off" nil) | |
719 | (string :tag "Selected label types")))) | |
720 | ||
721 | (defcustom reftex-label-menu-flags '(t t nil nil nil nil t nil) | |
722 | "List of flags governing the label menu makeup. | |
a7ec1775 RS |
723 | The flags are: |
724 | ||
725 | TABLE-OF-CONTENTS Show the labels embedded in a table of context. | |
726 | SECTION-NUMBERS Include section numbers (like 4.1.3) in table of contents. | |
c52bdfca | 727 | COUNTERS Show counters. This just numbers the labels in the menu. |
a7ec1775 | 728 | NO-CONTEXT Non-nil means do NOT show the short context. |
c52bdfca | 729 | FOLLOW Follow full context in other window. |
206c6f82 | 730 | SHOW-COMMENTED Show labels from regions which are commented out. |
be456a1d | 731 | MATCH-IN-TOC Obsolete flag. |
29d593f8 | 732 | SHOW FILES Show begin and end of included files. |
a7ec1775 RS |
733 | |
734 | Each of these flags can be set to t or nil, or to a string of type letters | |
c52bdfca RS |
735 | indicating the label types for which it should be true. These strings work |
736 | like character classes in regular expressions. Thus, setting one of the | |
a7ec1775 | 737 | flags to \"sf\" makes the flag true for section and figure labels, nil |
29d593f8 | 738 | for everything else. Setting it to \"^sf\" makes it the other way round. |
2faef409 RS |
739 | The available label types are: s (section), f (figure), t (table), i (item), |
740 | e (equation), n (footnote), plus any definitions in `reftex-label-alist'. | |
a7ec1775 RS |
741 | |
742 | Most options can also be switched from the label menu itself - so if you | |
743 | decide here to not have a table of contents in the label menu, you can still | |
744 | get one interactively during selection from the label menu." | |
745 | :group 'reftex-referencing-labels | |
396e0b08 KH |
746 | :type |
747 | `(list | |
748 | (choice :tag "Embed in table of contents " ,@reftex-tmp) | |
749 | (choice :tag "Show section numbers " ,@reftex-tmp) | |
750 | (choice :tag "Show individual counters " ,@reftex-tmp) | |
751 | (choice :tag "Hide short context " ,@reftex-tmp) | |
752 | (choice :tag "Follow context in other window " ,@reftex-tmp) | |
753 | (choice :tag "Show commented labels " ,@reftex-tmp) | |
be456a1d | 754 | (choice :tag "Obsolete flag, Don't use. " ,@reftex-tmp) |
396e0b08 KH |
755 | (choice :tag "Show begin/end of included files" ,@reftex-tmp))) |
756 | ||
2faef409 RS |
757 | (defcustom reftex-vref-is-default nil |
758 | "*Non-nil means, the varioref macro \\vref is used as default. | |
759 | In the selection buffer, the `v' key toggles the reference macro between | |
760 | `\\ref' and `\\vref'. The value of this variable determines the default | |
761 | which is active when entering the selection process. | |
762 | Instead of nil or t, this may also be a string of type letters indicating | |
763 | the label types for which it should be true." | |
764 | :group 'reftex-referencing-labels | |
765 | :type `(choice :tag "\\vref is default macro" ,@reftex-tmp)) | |
766 | ||
396e0b08 KH |
767 | (defcustom reftex-level-indent 2 |
768 | "*Number of spaces to be used for indentation per section level." | |
769 | :group 'reftex-referencing-labels | |
b849548d | 770 | :type 'integer) |
396e0b08 | 771 | |
a7ec1775 | 772 | (defcustom reftex-guess-label-type t |
c52bdfca | 773 | "*Non-nil means, `reftex-reference' will try to guess the label type. |
a7ec1775 | 774 | To do that, RefTeX will look at the word before the cursor and compare it with |
c52bdfca | 775 | the words given in `reftex-label-alist'. When it finds a match, RefTeX will |
a7ec1775 | 776 | immediately offer the correct label menu - otherwise it will prompt you for |
c52bdfca | 777 | a label type. If you set this variable to nil, RefTeX will always prompt." |
a7ec1775 | 778 | :group 'reftex-referencing-labels |
b849548d | 779 | :type 'boolean) |
a7ec1775 | 780 | |
2faef409 RS |
781 | (defcustom reftex-format-ref-function nil |
782 | "Function which produces the string to insert as a reference. | |
783 | Normally should be nil, because the format to insert a reference can | |
784 | already be specified in `reftex-label-alist'. | |
785 | The function will be called with two arguments, the LABEL and the DEFAULT | |
786 | FORMAT, which normally is `~\ref{%s}'. The function should return the | |
787 | string to insert into the buffer." | |
788 | :group 'reftex-referencing-labels | |
789 | :type 'function) | |
790 | ||
b849548d CD |
791 | (defcustom reftex-select-label-mode-hook nil |
792 | "Mode hook for reftex-select-label-mode." | |
793 | :group 'reftex-referencing-labels | |
794 | :type 'hook) | |
795 | ||
a7ec1775 RS |
796 | ;; BibteX citation configuration ---------------------------------------- |
797 | ||
798 | (defgroup reftex-citation-support nil | |
c52bdfca | 799 | "Support for referencing bibliographic data with BibTeX." |
a7ec1775 RS |
800 | :group 'reftex) |
801 | ||
802 | (defcustom reftex-bibpath-environment-variables '("BIBINPUTS" "TEXBIB") | |
b849548d CD |
803 | "*List of env vars which might contain the path to BibTeX database files. |
804 | Directories ending in `//' or `!!' will be expanded recursively when necessary | |
805 | to find files." | |
a7ec1775 RS |
806 | :group 'reftex-citation-support |
807 | :set 'reftex-set-dirty | |
808 | :type '(repeat (string :tag "Environment variable"))) | |
809 | ||
b849548d CD |
810 | (defvar reftex-bibfile-ignore-list nil) ; compatibility |
811 | (defcustom reftex-bibfile-ignore-regexps nil | |
812 | "*List of regular expressions to exclude files in \\bibliography{..}. | |
813 | File names matched by these regexps will not be parsed by RefTeX. | |
a7ec1775 RS |
814 | Intended for files which contain only `@string' macro definitions and the |
815 | like, which are ignored by RefTeX anyway." | |
816 | :group 'reftex-citation-support | |
817 | :set 'reftex-set-dirty | |
b849548d | 818 | :type '(repeat (regexp))) |
a7ec1775 | 819 | |
2faef409 | 820 | (defcustom reftex-default-bibliography nil |
a6611c0d | 821 | "*List of BibTeX database files which should be used if none are specified. |
2faef409 RS |
822 | When `reftex-citation' is called from a document which has neither a |
823 | `\bibliography{..}' statement nor a `thebibliography' environment, | |
824 | RefTeX will scan these files instead. Intended for using | |
825 | `reftex-citation' in non-LaTeX files." | |
826 | :group 'reftex-citation-support | |
827 | :type '(repeat (file))) | |
828 | ||
a7ec1775 RS |
829 | (defcustom reftex-sort-bibtex-matches 'reverse-year |
830 | "*Sorting of the entries found in BibTeX databases by reftex-citation. | |
831 | Possible values: | |
832 | nil Do not sort entries. | |
833 | 'author Sort entries by author name. | |
834 | 'year Sort entries by increasing year. | |
835 | 'reverse-year Sort entries by decreasing year." | |
836 | :group 'reftex-citation-support | |
837 | :type '(choice (const :tag "not" nil) | |
396e0b08 KH |
838 | (const :tag "by author" author) |
839 | (const :tag "by year" year) | |
840 | (const :tag "by year, reversed" reverse-year))) | |
a7ec1775 | 841 | |
206c6f82 | 842 | (defcustom reftex-cite-format 'default |
396e0b08 | 843 | "*The format of citations to be inserted into the buffer. |
206c6f82 RS |
844 | It can be a string or an alist. In the simplest case this is just |
845 | the string \"\\cite{%l}\", which is also the default. See the | |
846 | definition of `reftex-cite-format-builtin' for more complex examples. | |
847 | ||
848 | If `reftex-cite-format' is a string, it will be used as the format. | |
849 | In the format, the following percent escapes will be expanded. | |
850 | ||
851 | %l The BibTeX label of the citation. | |
852 | %a List of author names, see also `reftex-cite-punctuation. | |
853 | %2a Like %a, but abbreviate more than 2 authors like Jones et al. | |
854 | %A First author name only. | |
855 | %e Works like %a, but on list of editor names. (%2e and %E work a well) | |
856 | ||
857 | It is also possible to access all other BibTeX database fields: | |
858 | %b booktitle %c chapter %d edition %h howpublished | |
859 | %i institution %j journal %k key %m month | |
860 | %n number %o organization %p pages %P first page | |
861 | %r address %s school %u publisher %t title | |
b849548d CD |
862 | %v volume %y year |
863 | %B booktitle, abbreviated %T title, abbreviated | |
864 | ||
865 | Usually, only %l is needed. The other stuff is mainly for the echo area | |
866 | display, and for (setq reftex-comment-citations t). | |
206c6f82 | 867 | |
b849548d CD |
868 | %< as a special operator kills punctuation and space around it after the |
869 | string has been formatted. | |
206c6f82 | 870 | |
b849548d | 871 | Beware that all this only works with BibTeX database files. When |
2faef409 RS |
872 | citations are made from the \\bibitems in an explicit thebibliography |
873 | environment, only %l is available. | |
874 | ||
206c6f82 RS |
875 | If `reftex-cite-format' is an alist of characters and strings, the user |
876 | will be prompted for a character to select one of the possible format | |
877 | strings. | |
a7ec1775 | 878 | In order to configure this variable, you can either set |
c52bdfca | 879 | `reftex-cite-format' directly yourself or set it to the SYMBOL of one of |
206c6f82 | 880 | the predefined styles (see `reftex-cite-format-builtin'). E.g.: |
b849548d | 881 | (setq reftex-cite-format 'natbib)" |
396e0b08 KH |
882 | :group 'reftex-citation-support |
883 | :type | |
884 | `(choice | |
885 | :format "%{%t%}: \n%[Value Menu%] %v" | |
886 | (radio :tag "Symbolic Builtins" | |
887 | :indent 4 | |
888 | :value default | |
889 | ,@(mapcar | |
890 | (function | |
891 | (lambda (x) | |
892 | (list 'const ':tag (concat (symbol-name (nth 0 x)) | |
893 | ": " (nth 1 x)) | |
894 | (nth 0 x)))) | |
895 | reftex-cite-format-builtin)) | |
896 | (string :tag "format string" "\\cite{%l}") | |
897 | (repeat :tag "key-ed format strings" | |
898 | :value ((?\r . "\\cite{%l}") | |
899 | (?t . "\\cite{%l}") (?p . "\\cite{%l}")) | |
900 | (cons (character :tag "Key character" ?\r) | |
901 | (string :tag "Format string" ""))))) | |
206c6f82 RS |
902 | |
903 | (defcustom reftex-comment-citations nil | |
396e0b08 | 904 | "*Non-nil means add a comment for each citation describing the full entry. |
206c6f82 RS |
905 | The comment is formatted according to `reftex-cite-comment-format'." |
906 | :group 'reftex-citation-support | |
b849548d | 907 | :type 'boolean) |
206c6f82 | 908 | |
396e0b08 | 909 | (defcustom reftex-cite-comment-format |
b849548d CD |
910 | "%% %2a %y, %j %v, %P, %b, %e, %u, %s %<\n" |
911 | "Citation format used for commented citations. Must NOT contain %l. | |
912 | See the variable `reftex-cite-format' for possible percent escapes." | |
913 | :group 'reftex-citation-support | |
914 | :type 'string) | |
915 | ||
916 | (defcustom reftex-cite-view-format | |
917 | "%2a %y, %T, %B, %j %v:%P, %s %<" | |
918 | "Citation format used to display citation info in the message area. | |
919 | Must NOT contain %l. See the variable `reftex-cite-format' for | |
920 | possible percent escapes." | |
206c6f82 | 921 | :group 'reftex-citation-support |
b849548d CD |
922 | :group 'reftex-viewing-cross-references-and-citations |
923 | :type 'string) | |
206c6f82 RS |
924 | |
925 | (defcustom reftex-cite-punctuation '(", " " \\& " " {\\it et al.}") | |
926 | "Punctuation for formatting of name lists in citations. | |
927 | This is a list of 3 strings. | |
928 | 1. normal names separator, like \", \" in Jones, Brown and Miller | |
929 | 2. final names separator, like \" and \" in Jones, Brown and Miller | |
2faef409 | 930 | 3. The \"et al\" string, like \" {\\it et al.}\" in Jones {\\it et al.}" |
396e0b08 | 931 | :group 'reftex-citation-support |
206c6f82 | 932 | :type '(list |
396e0b08 KH |
933 | (string :tag "Separator for names ") |
934 | (string :tag "Separator for last name in list") | |
935 | (string :tag "string used as et al. "))) | |
a7ec1775 | 936 | |
2faef409 RS |
937 | (defcustom reftex-format-cite-function nil |
938 | "Function which produces the string to insert as a citation. | |
939 | Normally should be nil, because the format to insert a reference can | |
940 | already be specified in `reftex-cite-format'. | |
941 | The function will be called with two arguments, the CITATION KEY and the | |
942 | DEFAULT FORMAT, which is taken from `reftex-cite-format'. The function | |
943 | should return the string to insert into the buffer." | |
944 | :group 'reftex-citation-support | |
945 | :type 'function) | |
6b94c6ad | 946 | |
b849548d CD |
947 | (defcustom reftex-select-bib-mode-hook nil |
948 | "Mode hook for reftex-select-bib-mode." | |
949 | :group 'reftex-citation-support | |
950 | :type 'hook) | |
951 | ||
a7ec1775 RS |
952 | ;; Table of contents configuration -------------------------------------- |
953 | ||
954 | (defgroup reftex-table-of-contents-browser nil | |
955 | "A multifile table of contents browser." | |
956 | :group 'reftex) | |
957 | ||
958 | (defcustom reftex-toc-follow-mode nil | |
396e0b08 | 959 | "*Non-nil means, point in *toc* buffer will cause other window to follow. |
a7ec1775 RS |
960 | The other window will show the corresponding part of the document. |
961 | This flag can be toggled from within the *toc* buffer with the `f' key." | |
962 | :group 'reftex-table-of-contents-browser | |
b849548d CD |
963 | :type 'boolean) |
964 | ||
965 | (defcustom reftex-revisit-to-follow nil | |
966 | "*Non-nil means, follow-mode will revisit files if necessary. | |
967 | When nil, follow-mode will be suspended for stuff in unvisited files." | |
968 | :group 'reftex-table-of-contents-browser | |
969 | :group 'reftex-referencing-labels | |
970 | :type 'boolean) | |
971 | ||
972 | (defcustom reftex-toc-mode-hook nil | |
973 | "Mode hook for reftex-toc-mode." | |
974 | :group 'reftex-table-of-contents-browser | |
975 | :type 'hook) | |
976 | ||
977 | ;; Viewing Cross References and Citations | |
978 | (defgroup reftex-viewing-cross-references-and-citations nil | |
979 | "Displaying cross references and citations." | |
980 | :group 'reftex) | |
981 | ||
982 | (defcustom reftex-auto-view-crossref t | |
983 | "*Non-nil means, initially turn automatic viewing of crossref info on. | |
a6611c0d CD |
984 | Automatic viewing of crossref info normally uses the echo area. |
985 | Whenever point is on the argument of a \\ref or \\cite macro, and no | |
986 | other message is being displayed, the echo area will display | |
987 | information about that cross reference. You can also set the variable | |
988 | to the symbol `window'. In this case a small temporary window is | |
989 | used for the display. | |
b849548d CD |
990 | This feature can be turned on and of from the menu |
991 | (Ref->Options->Crossref Viewing)." | |
992 | :group 'reftex-viewing-cross-references-and-citations | |
a6611c0d CD |
993 | :type '(choice (const :tag "off" nil) |
994 | (const :tag "in Echo Area" t) | |
995 | (const :tag "in Other Window" window))) | |
b849548d CD |
996 | |
997 | (defcustom reftex-idle-time 1.2 | |
998 | "*Time (secs) Emacs has to be idle before automatic crossref display is done." | |
999 | :group 'reftex-viewing-cross-references-and-citations | |
1000 | :type 'number) | |
1001 | ||
1002 | (defcustom reftex-revisit-to-echo nil | |
1003 | "*Non-nil means, automatic citation display will revisit files if necessary. | |
1004 | When nil, citation display in echo area will only be active for cached | |
1005 | entries and for BibTeX database files with live associated buffers." | |
1006 | :group 'reftex-viewing-cross-references-and-citations | |
1007 | :type 'boolean) | |
1008 | ||
1009 | (defcustom reftex-cache-cite-echo t | |
1010 | "*Non-nil means, the information displayed in the echo area for cite macros | |
1011 | is cached and even saved along with the parsing information. The cache | |
1012 | survives document scans. In order to clear it, use M-x reftex-reset-mode." | |
1013 | :group 'reftex-viewing-cross-references-and-citations | |
1014 | :type 'boolean) | |
1015 | ||
1016 | (defcustom reftex-display-copied-context-hook nil | |
1017 | "Normal Hook which is run before context is displayed anywhere. Designed | |
1018 | for X-Symbol, but may have other uses as well." | |
1019 | :group 'reftex-viewing-cross-references-and-citations | |
1020 | :group 'reftex-referencing-labels | |
1021 | :type 'hook) | |
a7ec1775 | 1022 | |
396e0b08 KH |
1023 | ;; Tuning the parser ---------------------------------------------------- |
1024 | ||
1025 | (defgroup reftex-optimizations-for-large-documents nil | |
1026 | "Configuration of parser speed and memory usage." | |
1027 | :group 'reftex) | |
1028 | ||
1029 | (defcustom reftex-keep-temporary-buffers 1 | |
1030 | "*Non-nil means, keep buffers created for parsing and lookup. | |
1031 | RefTeX sometimes needs to visit files related to the current document. | |
1032 | We distinguish files visited for | |
1033 | PARSING: Parts of a multifile document loaded when (re)-parsing the document. | |
1034 | LOOKUP: BibTeX database files and TeX files loaded to find a reference, | |
1035 | to display label context, etc. | |
1036 | The created buffers can be kept for later use, or be thrown away immediately | |
1037 | after use, depending on the value of this variable: | |
1038 | ||
1039 | nil Throw away as much as possible. | |
1040 | t Keep everything. | |
1041 | 1 Throw away buffers created for parsing, but keep the ones created | |
1042 | for lookup. | |
1043 | ||
1044 | If a buffer is to be kept, the file is visited normally (which is potentially | |
1045 | slow but will happen only once). | |
1046 | If a buffer is to be thrown away, the initialization of the buffer depends | |
1047 | upon the variable `reftex-initialize-temporary-buffers'." | |
b849548d | 1048 | :group 'reftex-optimizations-for-large-documents |
396e0b08 KH |
1049 | :type '(choice |
1050 | (const :tag "Throw away everything" nil) | |
1051 | (const :tag "Keep everything" t) | |
1052 | (const :tag "Keep lookup buffers only" 1))) | |
1053 | ||
1054 | (defcustom reftex-initialize-temporary-buffers nil | |
1055 | "*Non-nil means do initializations even when visiting file temporarily. | |
1056 | When nil, RefTeX may turn off find-file hooks and other stuff to briefly | |
1057 | visit a file. | |
1058 | When t, the full default initializations are done (find-file-hook etc.). | |
1059 | Instead of t or nil, this variable may also be a list of hook functions to | |
1060 | do a minimal initialization." | |
b849548d | 1061 | :group 'reftex-optimizations-for-large-documents |
396e0b08 KH |
1062 | :type '(choice |
1063 | (const :tag "Read files literally" nil) | |
1064 | (const :tag "Fully initialize buffers" t) | |
1065 | (repeat :tag "Hook functions" :value (nil) | |
1066 | (function-item)))) | |
1067 | ||
b849548d | 1068 | (defcustom reftex-no-include-regexps '("\\.pstex_t\\'") |
2faef409 RS |
1069 | "*List of regular expressions to exclude certain input files from parsing. |
1070 | If the name of a file included via \\include or \\input is matched by any | |
1071 | of the regular expressions in this list, that file is not parsed by RefTeX." | |
1072 | :group 'reftex-optimizations-for-large-documents | |
1073 | :type '(repeat (regexp))) | |
1074 | ||
396e0b08 KH |
1075 | (defcustom reftex-enable-partial-scans nil |
1076 | "*Non-nil means, re-parse only 1 file when asked to re-parse. | |
1077 | Re-parsing is normally requested with a `C-u' prefix to many RefTeX commands, | |
1078 | or with the `r' key in menus. When this option is t in a multifile document, | |
1079 | we will only parse the current buffer, or the file associated with the label | |
1080 | or section heading near point in a menu. Requesting re-parsing of an entire | |
1081 | multifile document then requires a `C-u C-u' prefix or the capital `R' key | |
1082 | in menus." | |
1083 | :group 'reftex-optimizations-for-large-documents | |
1084 | :type 'boolean) | |
1085 | ||
2faef409 RS |
1086 | (defcustom reftex-allow-automatic-rescan t |
1087 | "*Non-nil means, RefTeX may rescan the document when this seems necessary. | |
1088 | Currently this applies only to rescanning after label insertion, when | |
1089 | the new label cannot be inserted correctly into the internal label | |
1090 | list." | |
1091 | :group 'reftex-optimizations-for-large-documents | |
1092 | :type 'boolean) | |
1093 | ||
396e0b08 KH |
1094 | (defcustom reftex-save-parse-info nil |
1095 | "*Non-nil means, save information gathered with parsing in a file. | |
1096 | The file MASTER.rel in the same directory as MASTER.tex is used to save the | |
1097 | information. When this variable is t, | |
1098 | - accessing the parsing information for the first time in an editing session | |
1099 | will read that file (if available) instead of parsing the document. | |
b849548d CD |
1100 | - exiting Emacs or killing a buffer in reftex-mode will cause a new version |
1101 | of the file to be written." | |
396e0b08 KH |
1102 | :group 'reftex-optimizations-for-large-documents |
1103 | :type 'boolean) | |
1104 | ||
2faef409 RS |
1105 | (defcustom reftex-use-multiple-selection-buffers nil |
1106 | "*Non-nil means use a separate selection buffer for each label type. | |
1107 | These buffers are kept from one selection to the next and need not to be | |
1108 | created for each use - so the menu generally comes up faster. The | |
1109 | selection buffers will be erased (and therefore updated) automatically | |
1110 | when new labels in its category are added. See the variable | |
1111 | `reftex-auto-update-selection-buffers'." | |
1112 | :group 'reftex-optimizations-for-large-documents | |
b849548d | 1113 | :group 'reftex-referencing-labels |
2faef409 RS |
1114 | :type 'boolean) |
1115 | ||
1116 | (defcustom reftex-auto-update-selection-buffers t | |
1117 | "*Non-nil means, selection buffers will be updated automatically. | |
1118 | When a new label is defined with `reftex-label', all selection buffers | |
1119 | associated with that label category are emptied, in order to force an | |
1120 | update upon next use. When nil, the buffers are left alone and have to be | |
1121 | updated by hand, with the `g' key from the label selection process. | |
1122 | The value of this variable will only have any effect when | |
1123 | `reftex-use-multiple-selection-buffers' is non-nil." | |
1124 | :group 'reftex-optimizations-for-large-documents | |
b849548d | 1125 | :group 'reftex-referencing-labels |
2faef409 RS |
1126 | :type 'boolean) |
1127 | ||
6b94c6ad CD |
1128 | ;; Fontification and Faces ---------------------------------------------- |
1129 | ||
1130 | (defgroup reftex-fontification-configurations nil | |
1131 | "Options concerning the faces used in RefTeX." | |
1132 | :group 'reftex) | |
1133 | ||
1134 | (defcustom reftex-use-fonts t | |
1135 | "*Non-nil means, use fonts in *toc* and selection buffers. | |
b849548d CD |
1136 | Font-lock must be loaded as well to actually get fontified display. |
1137 | When changing this option, a rescan may be necessary to activate the change." | |
6b94c6ad | 1138 | :group 'reftex-fontification-configurations |
b849548d | 1139 | :type 'boolean) |
6b94c6ad CD |
1140 | |
1141 | (defcustom reftex-refontify-context 1 | |
1142 | "*Non-nil means, re-fontify the context in the label menu with font-lock. | |
1143 | This slightly slows down the creation of the label menu. It is only necessary | |
1144 | when you definitely want the context fontified. | |
1145 | ||
1146 | This option may have 3 different values: | |
1147 | nil Never refontify. | |
1148 | t Always refontify. | |
b849548d | 1149 | 1 Refontify when absolutely necessary, e.g. when old versions of X-Symbol. |
6b94c6ad CD |
1150 | The option is ignored when `reftex-use-fonts' is nil." |
1151 | :group 'reftex-fontification-configurations | |
b849548d | 1152 | :group 'reftex-referencing-labels |
6b94c6ad CD |
1153 | :type '(choice |
1154 | (const :tag "Never" nil) | |
1155 | (const :tag "Always" t) | |
1156 | (const :tag "When necessary" 1))) | |
1157 | ||
1158 | (defcustom reftex-highlight-selection 'cursor | |
1159 | "*Non-nil mean, highlight selected text in selection and *toc* buffers. | |
1160 | Normally, the text near the cursor is the selected text, and it is | |
1161 | highlighted. This is the entry most keys in the selction and *toc* | |
1162 | buffers act on. However, if you mainly use the mouse to select an | |
1163 | item, you may find it nice to have mouse-triggered highlighting | |
1164 | instead or as well. The variable may have one of these values: | |
1165 | ||
1166 | nil No highlighting. | |
1167 | cursor Highlighting is cursor driven. | |
1168 | mouse Highlighting is mouse driven. | |
b849548d CD |
1169 | both Both cursor and mouse trigger highlighting. |
1170 | ||
1171 | Changing this variable requires to rebuild the selection and *toc* buffers | |
1172 | to become effective (keys `g' or `r')." | |
6b94c6ad CD |
1173 | :group 'reftex-fontification-configurations |
1174 | :type '(choice | |
1175 | (const :tag "Never" nil) | |
1176 | (const :tag "Cursor driven" cursor) | |
1177 | (const :tag "Mouse driven" mouse) | |
1178 | (const :tag "Mouse and Cursor driven." both))) | |
1179 | ||
1180 | (defcustom reftex-cursor-selected-face 'highlight | |
1181 | "Face name to highlight cursor selected item in toc and selection buffers. | |
1182 | See also the variable `reftex-highlight-selection'." | |
1183 | :group 'reftex-fontification-configurations | |
1184 | :type 'symbol) | |
1185 | (defcustom reftex-mouse-selected-face 'secondary-selection | |
1186 | "Face name to highlight mouse selected item in toc and selection buffers. | |
1187 | See also the variable `reftex-highlight-selection'." | |
1188 | :group 'reftex-fontification-configurations | |
1189 | :type 'symbol) | |
1190 | (defcustom reftex-file-boundary-face 'font-lock-comment-face | |
1191 | "Face name for file boundaries in selection buffer." | |
1192 | :group 'reftex-fontification-configurations | |
1193 | :type 'symbol) | |
1194 | (defcustom reftex-label-face 'font-lock-constant-face | |
1195 | "Face name for labels in selection buffer." | |
1196 | :group 'reftex-fontification-configurations | |
1197 | :type 'symbol) | |
1198 | (defcustom reftex-section-heading-face 'font-lock-function-name-face | |
1199 | "Face name for section headings in toc and selection buffers." | |
1200 | :group 'reftex-fontification-configurations | |
1201 | :type 'symbol) | |
1202 | (defcustom reftex-toc-header-face 'font-lock-comment-face | |
1203 | "Face name for the header of a toc buffer." | |
1204 | :group 'reftex-fontification-configurations | |
1205 | :type 'symbol) | |
1206 | (defcustom reftex-bib-author-face 'font-lock-keyword-face | |
1207 | "Face name for author names in bib selection buffer." | |
1208 | :group 'reftex-fontification-configurations | |
1209 | :type 'symbol) | |
1210 | (defcustom reftex-bib-year-face 'font-lock-comment-face | |
1211 | "Face name for year in bib selection buffer." | |
1212 | :group 'reftex-fontification-configurations | |
1213 | :type 'symbol) | |
1214 | (defcustom reftex-bib-title-face 'font-lock-function-name-face | |
1215 | "Face name for article title in bib selection buffer." | |
1216 | :group 'reftex-fontification-configurations | |
1217 | :type 'symbol) | |
1218 | (defcustom reftex-bib-extra-face 'font-lock-comment-face | |
1219 | "Face name for bibliographic information in bib selection buffer." | |
1220 | :group 'reftex-fontification-configurations | |
1221 | :type 'symbol) | |
1222 | ||
b849548d CD |
1223 | (defcustom reftex-pre-refontification-functions nil |
1224 | "X-Symbol specific hook. | |
1225 | Functions get two arguments, the buffer from where the command started and a | |
1226 | symbol indicating in what context the hook is called." | |
1227 | :group 'reftex-fontification-configurations | |
1228 | :type 'hook) | |
1229 | ||
a7ec1775 RS |
1230 | ;; Miscellaneous configurations ----------------------------------------- |
1231 | ||
1232 | (defgroup reftex-miscellaneous-configurations nil | |
c52bdfca | 1233 | "Collection of further configurations." |
a7ec1775 RS |
1234 | :group 'reftex) |
1235 | ||
1236 | (defcustom reftex-extra-bindings nil | |
1237 | "Non-nil means, make additional key bindings on startup. | |
c52bdfca | 1238 | These extra bindings are located in the users `C-c letter' map." |
a7ec1775 | 1239 | :group 'reftex-miscellaneous-configurations |
b849548d | 1240 | :type 'boolean) |
a7ec1775 | 1241 | |
c52bdfca | 1242 | (defcustom reftex-plug-into-AUCTeX nil |
396e0b08 | 1243 | "*Plug-in flags for AUCTeX interface. |
b849548d CD |
1244 | This variable is a list of 4 boolean flags. When a flag is non-nil, |
1245 | RefTeX will | |
c52bdfca | 1246 | |
b849548d CD |
1247 | - supply labels in new sections and environments (flag 1) |
1248 | - supply arguments for macros like `\\label'. (flag 2) | |
1249 | - supply arguments for macros like `\\ref'. (flag 3) | |
1250 | - supply arguments for macros like `\\cite'. (flag 4) | |
c52bdfca RS |
1251 | |
1252 | You may also set the variable itself to t or nil in order to turn all | |
1253 | plug-ins on or off, respectively. | |
b849548d CD |
1254 | \\<LaTeX-mode-map>Supplying labels in new sections and environments aplies when creating |
1255 | sections with \\[LaTeX-section] and environments with \\[LaTeX-environment]. | |
1256 | Supplying macro arguments applies when you insert such a macro interactively | |
1257 | with \\[TeX-insert-macro]. | |
c52bdfca RS |
1258 | See the AUCTeX documentation for more information. |
1259 | RefTeX uses `fset' to take over the function calls. Changing the variable | |
1260 | may require a restart of Emacs in order to become effective." | |
1261 | :group 'reftex-miscellaneous-configurations | |
b849548d CD |
1262 | :group 'LaTeX |
1263 | :type '(choice | |
1264 | (const :tag "No plug-ins" nil) | |
1265 | (const :tag "All possible plug-ins" t) | |
1266 | (list | |
1267 | :tag "Individual choice" | |
1268 | :value (t t t t) | |
1269 | (boolean :tag "supply label in new sections and environments") | |
1270 | (boolean :tag "supply argument for macros like `\\label' ") | |
1271 | (boolean :tag "supply argument for macros like `\\ref' ") | |
1272 | (boolean :tag "supply argument for macros like `\\cite' ") | |
1273 | ))) | |
1274 | ||
1275 | (defcustom reftex-allow-detached-macro-args nil | |
1276 | "*Non-nil means, allow arguments of macros to be detached by whitespace. | |
1277 | When this is t, `aaa' will be considered as argument of \\bb in the following | |
1278 | construct: \\bbb [xxx] {aaa}." | |
1279 | :group 'texmathp | |
1280 | :type 'boolean) | |
396e0b08 | 1281 | |
2faef409 | 1282 | |
396e0b08 KH |
1283 | (defcustom reftex-load-hook nil |
1284 | "Hook which is being run when loading reftex.el." | |
1285 | :group 'reftex-miscellaneous-configurations | |
1286 | :type 'hook) | |
a7ec1775 | 1287 | |
396e0b08 KH |
1288 | (defcustom reftex-mode-hook nil |
1289 | "Hook which is being run when turning on RefTeX mode." | |
a7ec1775 | 1290 | :group 'reftex-miscellaneous-configurations |
396e0b08 | 1291 | :type 'hook) |
a7ec1775 | 1292 | |
b849548d | 1293 | ;;; ========================================================================= |
a7ec1775 RS |
1294 | ;;; |
1295 | ;;; Define the formal stuff for a minor mode named RefTeX. | |
1296 | ;;; | |
1297 | ||
a6611c0d CD |
1298 | (defconst reftex-version "RefTeX version 3.38" |
1299 | "Version string for RefTeX.") | |
baec1250 | 1300 | |
a7ec1775 | 1301 | (defvar reftex-mode nil |
b849548d | 1302 | "Determines if RefTeX mode is active.") |
a7ec1775 RS |
1303 | (make-variable-buffer-local 'reftex-mode) |
1304 | ||
1305 | (defvar reftex-mode-map (make-sparse-keymap) | |
b849548d | 1306 | "Keymap for RefTeX mode.") |
a7ec1775 RS |
1307 | |
1308 | (defvar reftex-mode-menu nil) | |
1309 | ||
1310 | ;;;###autoload | |
1311 | (defun turn-on-reftex () | |
b849548d | 1312 | "Turn on RefTeX mode." |
a7ec1775 RS |
1313 | (reftex-mode t)) |
1314 | ||
1315 | ;;;###autoload | |
1316 | (defun reftex-mode (&optional arg) | |
fba437e6 | 1317 | "Minor mode with distinct support for \\label, \\ref and \\cite in LaTeX. |
a7ec1775 RS |
1318 | |
1319 | Labels can be created with `\\[reftex-label]' and referenced with `\\[reftex-reference]'. | |
1320 | When referencing, you get a menu with all labels of a given type and | |
c52bdfca | 1321 | context of the label definition. The selected label is inserted as a |
fba437e6 | 1322 | \\ref macro. |
a7ec1775 | 1323 | |
396e0b08 | 1324 | Citations can be made with `\\[reftex-citation]' which will use a regular expression |
a7ec1775 | 1325 | to pull out a *formatted* list of articles from your BibTeX |
c52bdfca | 1326 | database. The selected citation is inserted as a \\cite macro. |
a7ec1775 RS |
1327 | |
1328 | A Table of Contents of the entire (multifile) document with browsing | |
1329 | capabilities is available with `\\[reftex-toc]'. | |
1330 | ||
c52bdfca | 1331 | Most command have help available on the fly. This help is accessed by |
a7ec1775 RS |
1332 | pressing `?' to any prompt mentioning this feature. |
1333 | ||
396e0b08 KH |
1334 | Extensive documentation about RefTeX is in the file header of `reftex.el'. |
1335 | You can view this information with `\\[reftex-show-commentary]'. | |
c52bdfca | 1336 | |
a7ec1775 | 1337 | \\{reftex-mode-map} |
396e0b08 KH |
1338 | Under X, these and other functions will also be available as `Ref' menu |
1339 | on the menu bar. | |
a7ec1775 RS |
1340 | |
1341 | ------------------------------------------------------------------------------" | |
1342 | ||
1343 | (interactive "P") | |
1344 | (setq reftex-mode (not (or (and (null arg) reftex-mode) | |
1345 | (<= (prefix-numeric-value arg) 0)))) | |
1346 | ||
1347 | ; Add or remove the menu, and run the hook | |
1348 | (if reftex-mode | |
1349 | (progn | |
396e0b08 | 1350 | (easy-menu-add reftex-mode-menu) |
b849548d CD |
1351 | (and reftex-plug-into-AUCTeX |
1352 | (reftex-plug-into-AUCTeX)) | |
396e0b08 | 1353 | (run-hooks 'reftex-mode-hook)) |
a7ec1775 | 1354 | (easy-menu-remove reftex-mode-menu))) |
396e0b08 | 1355 | |
b849548d CD |
1356 | (if (fboundp 'add-minor-mode) |
1357 | ;; Use it so that we get the extras | |
1358 | (progn | |
1359 | (put 'reftex-mode ':included '(memq major-mode '(latex-mode tex-mode))) | |
1360 | (put 'reftex-mode ':menu-tag "RefTeX Mode") | |
1361 | (add-minor-mode 'reftex-mode " Ref" reftex-mode-map)) | |
1362 | ;; The standard way | |
1363 | (unless (assoc 'reftex-mode minor-mode-alist) | |
396e0b08 | 1364 | (push '(reftex-mode " Ref") minor-mode-alist)) |
b849548d CD |
1365 | (unless (assoc 'reftex-mode minor-mode-map-alist) |
1366 | (push (cons 'reftex-mode reftex-mode-map) minor-mode-map-alist))) | |
a7ec1775 | 1367 | |
b849548d | 1368 | ;;; ========================================================================= |
c52bdfca RS |
1369 | ;;; |
1370 | ;;; Silence warnings about variables in other packages. | |
1371 | (defvar TeX-master) | |
b849548d | 1372 | (defvar LaTeX-section-hook) |
c52bdfca RS |
1373 | (defvar LaTeX-label-function) |
1374 | (defvar tex-main-file) | |
1375 | (defvar outline-minor-mode) | |
a6611c0d | 1376 | (defvar font-lock-mode) |
2faef409 RS |
1377 | (defvar font-lock-fontify-region-function) |
1378 | (defvar font-lock-syntactic-keywords) | |
c52bdfca | 1379 | |
b849548d | 1380 | ;;; ========================================================================= |
a7ec1775 | 1381 | ;;; |
b849548d | 1382 | ;;; Multibuffer Variables |
a7ec1775 | 1383 | ;;; |
b849548d | 1384 | ;;; Technical notes: These work as follows: We keep just one list |
a7ec1775 | 1385 | ;;; of labels for each master file - this can save a lot of memory. |
c52bdfca | 1386 | ;;; `reftex-master-index-list' is an alist which connects the true file name |
a7ec1775 | 1387 | ;;; of each master file with the symbols holding the information on that |
c52bdfca | 1388 | ;;; document. Each buffer has local variables which point to these symbols. |
a7ec1775 | 1389 | |
a7ec1775 RS |
1390 | ;; List of variables which handle the multifile stuff. |
1391 | ;; This list is used to tie, untie, and reset these symbols. | |
1392 | (defconst reftex-multifile-symbols | |
396e0b08 | 1393 | '(reftex-docstruct-symbol)) |
a7ec1775 | 1394 | |
c52bdfca | 1395 | ;; Alist connecting master file names with the corresponding lisp symbols. |
a7ec1775 RS |
1396 | (defvar reftex-master-index-list nil) |
1397 | ||
c52bdfca | 1398 | ;; Last index used for a master file. |
a7ec1775 RS |
1399 | (defvar reftex-multifile-index 0) |
1400 | ||
a7ec1775 | 1401 | ;; Variable holding the symbol with the label list of the document. |
396e0b08 KH |
1402 | (defvar reftex-docstruct-symbol nil) |
1403 | (make-variable-buffer-local 'reftex-docstruct-symbol) | |
a7ec1775 RS |
1404 | |
1405 | (defun reftex-next-multifile-index () | |
1406 | ;; Return the next free index for multifile symbols. | |
396e0b08 | 1407 | (incf reftex-multifile-index)) |
a7ec1775 RS |
1408 | |
1409 | (defun reftex-tie-multifile-symbols () | |
1410 | ;; Tie the buffer-local symbols to globals connected with the master file. | |
1411 | ;; If the symbols for the current master file do not exist, they are created. | |
1412 | ||
1413 | (let* ((master (file-truename (reftex-TeX-master-file))) | |
1414 | (index (assoc master reftex-master-index-list)) | |
1415 | (symlist reftex-multifile-symbols) | |
b849548d | 1416 | symbol symname newflag) |
c52bdfca | 1417 | ;; Find the correct index. |
a7ec1775 RS |
1418 | (if index |
1419 | ;; symbols do exist | |
1420 | (setq index (cdr index)) | |
c52bdfca | 1421 | ;; Get a new index and add info to the alist. |
a7ec1775 | 1422 | (setq index (reftex-next-multifile-index) |
396e0b08 KH |
1423 | newflag t) |
1424 | (push (cons master index) reftex-master-index-list)) | |
a7ec1775 | 1425 | |
c52bdfca | 1426 | ;; Get/create symbols and tie them. |
a7ec1775 RS |
1427 | (while symlist |
1428 | (setq symbol (car symlist) | |
1429 | symlist (cdr symlist) | |
1430 | symname (symbol-name symbol)) | |
1431 | (set symbol (intern (concat symname "-" (int-to-string index)))) | |
2faef409 | 1432 | (put (symbol-value symbol) ':master-index index) |
c52bdfca | 1433 | ;; Initialize if new symbols. |
a7ec1775 RS |
1434 | (if newflag (set (symbol-value symbol) nil))) |
1435 | ||
c52bdfca | 1436 | ;; Return t if the symbols did already exist, nil when we've made them. |
a7ec1775 RS |
1437 | (not newflag))) |
1438 | ||
1439 | (defun reftex-untie-multifile-symbols () | |
1440 | ;; Remove ties from multifile symbols, so that next use makes new ones. | |
1441 | (let ((symlist reftex-multifile-symbols) | |
1442 | (symbol nil)) | |
1443 | (while symlist | |
1444 | (setq symbol (car symlist) | |
1445 | symlist (cdr symlist)) | |
1446 | (set symbol nil)))) | |
1447 | ||
1448 | (defun reftex-TeX-master-file () | |
1449 | ;; Return the name of the master file associated with the current buffer. | |
1450 | ;; When AUCTeX is loaded, we will use it's more sophisticated method. | |
025bb635 RS |
1451 | ;; We also support the default TeX and LaTeX modes by checking for a |
1452 | ;; variable tex-main-file. | |
a7ec1775 RS |
1453 | (let |
1454 | ((master | |
1455 | (cond | |
c52bdfca | 1456 | ((fboundp 'TeX-master-file) ; AUCTeX is loaded. Use its mechanism. |
a7ec1775 RS |
1457 | (TeX-master-file t)) |
1458 | ((boundp 'TeX-master) ; The variable is defined - lets use it. | |
1459 | (cond | |
1460 | ((eq TeX-master t) | |
1461 | (buffer-file-name)) | |
1462 | ((eq TeX-master 'shared) | |
1463 | (setq TeX-master (read-file-name "Master file: " | |
1464 | nil nil t nil))) | |
1465 | (TeX-master) | |
1466 | (t | |
1467 | (setq TeX-master (read-file-name "Master file: " | |
1468 | nil nil t nil))))) | |
1469 | ((boundp 'tex-main-file) | |
c52bdfca | 1470 | ;; This is the variable from the default TeX modes. |
a7ec1775 RS |
1471 | (cond |
1472 | ((stringp tex-main-file) | |
1473 | ;; ok, this must be it | |
1474 | tex-main-file) | |
1475 | (t | |
c52bdfca | 1476 | ;; In this case, the buffer is its own master. |
a7ec1775 RS |
1477 | (buffer-file-name)))) |
1478 | (t | |
c52bdfca | 1479 | ;; Know nothing about master file. Assume this is a master file. |
a7ec1775 RS |
1480 | (buffer-file-name))))) |
1481 | (cond | |
1482 | ((null master) | |
a6611c0d | 1483 | (error "Need a filename for this buffer, please save it first")) |
a7ec1775 RS |
1484 | ((or (file-exists-p (concat master ".tex")) |
1485 | (reftex-get-buffer-visiting (concat master ".tex"))) | |
1486 | ;; Ahh, an extra .tex was missing... | |
1487 | (setq master (concat master ".tex"))) | |
a6611c0d CD |
1488 | ((or (file-exists-p master) |
1489 | (reftex-get-buffer-visiting master)) | |
1490 | ;; We either see the file, or have a buffer on it. OK. | |
1491 | ) | |
a7ec1775 | 1492 | (t |
b849548d | 1493 | ;; Use buffer file name. |
2faef409 | 1494 | (buffer-file-name))) |
a7ec1775 RS |
1495 | (expand-file-name master))) |
1496 | ||
b849548d CD |
1497 | ;;; ========================================================================= |
1498 | ;;; | |
1499 | ;;; Functions to parse the buffer and to create and reference labels. | |
1500 | ||
1501 | ;; The following constants are derived from `reftex-label-alist'. | |
1502 | ||
1503 | ;; Prompt used for label type queries directed to the user. | |
1504 | (defconst reftex-type-query-prompt nil) | |
1505 | ||
1506 | ;; Help string for label type queries. | |
1507 | (defconst reftex-type-query-help nil) | |
1508 | ||
1509 | ;; Alist relating label type to reference format. | |
1510 | (defconst reftex-typekey-to-format-alist nil) | |
1511 | ||
1512 | ;; Alist relating label type to label affix. | |
1513 | (defconst reftex-typekey-to-prefix-alist nil) | |
1514 | ||
1515 | ;; Alist relating environments or macros to label type and context regexp. | |
1516 | (defconst reftex-env-or-mac-alist nil) | |
1517 | ||
1518 | ;; List of macros carrying a label. | |
1519 | (defconst reftex-label-mac-list nil) | |
1520 | ||
1521 | ;; List of environments carrying a label. | |
1522 | (defconst reftex-label-env-list nil) | |
1523 | ||
1524 | ;; List of all typekey letters in use. | |
1525 | (defconst reftex-typekey-list nil) | |
1526 | ||
1527 | ;; Alist relating magic words to a label type. | |
1528 | (defconst reftex-words-to-typekey-alist nil) | |
1529 | ||
1530 | ;; The last list-of-labels entry used in a reference. | |
1531 | (defvar reftex-last-used-reference (list nil nil nil nil)) | |
1532 | ||
1533 | ;; The message when follow-mode is suspended | |
1534 | (defconst reftex-no-follow-message | |
1535 | "No follow-mode into unvisited file. Press SPC to visit it.") | |
1536 | (defconst reftex-no-info-message | |
1537 | "%s: info not available, use `\\[reftex-view-crossref]' to get it.") | |
1538 | ||
1539 | ;; The regular expression used to abbreviate words. | |
1540 | (defconst reftex-abbrev-regexp | |
1541 | (concat | |
1542 | "\\`\\(" | |
1543 | (make-string (nth 0 reftex-abbrev-parameters) ?.) | |
1544 | "[" (nth 2 reftex-abbrev-parameters) "]*" | |
1545 | "\\)" | |
1546 | "[" (nth 3 reftex-abbrev-parameters) "]" | |
1547 | (make-string (1- (nth 1 reftex-abbrev-parameters)) ?.))) | |
1548 | ||
1549 | ;; Global variables used for communication between functions. | |
1550 | (defvar reftex-default-context-position nil) | |
1551 | (defvar reftex-location-start nil) | |
1552 | (defvar reftex-call-back-to-this-buffer nil) | |
1553 | (defvar reftex-select-return-marker (make-marker)) | |
1554 | (defvar reftex-active-toc nil) | |
1555 | (defvar reftex-tex-path nil) | |
1556 | (defvar reftex-bib-path nil) | |
1557 | (defvar reftex-last-follow-point nil) | |
1558 | (defvar reftex-latex-syntax-table nil) | |
1559 | (defvar reftex-prefix nil) | |
1560 | (defvar reftex-section-levels-all nil) | |
1561 | (defvar reftex-buffers-with-changed-invisibility nil) | |
1562 | ||
1563 | ;; List of buffers created temporarily for lookup, which should be killed. | |
1564 | (defvar reftex-buffers-to-kill nil) | |
1565 | ||
1566 | ;; Regexp to find anything. | |
1567 | (defvar reftex-section-regexp nil) | |
1568 | (defvar reftex-section-or-include-regexp nil) | |
1569 | (defvar reftex-everything-regexp nil) | |
1570 | (defvar reftex-find-label-regexp-format nil) | |
1571 | (defvar reftex-find-label-regexp-format2 nil) | |
1572 | ||
1573 | ;;; The parser functions ----------------------------------------------------- | |
1574 | ||
1575 | (defvar reftex-memory nil | |
1576 | "Memorizes old variable values to indicate changes in these variables.") | |
1577 | ||
1578 | (defun reftex-access-scan-info (&optional rescan file) | |
1579 | "Ensure access to the scanning info for the current file." | |
1580 | ;; When the multifile symbols are not yet tied, | |
1581 | ;; tie them. When they are empty or RESCAN is non-nil, scan the document. | |
1582 | ;; But, when RESCAN is -1, don't rescan even if docstruct is empty. | |
1583 | ;; When FILE is non-nil, parse only from that file. | |
1584 | ||
1585 | ;; Make sure we have the symbols tied | |
1586 | (if (eq reftex-docstruct-symbol nil) | |
1587 | ;; Symbols are not yet tied: Tie them. | |
1588 | (reftex-tie-multifile-symbols)) | |
1589 | ||
1590 | (reftex-ensure-compiled-variables) | |
1591 | ||
1592 | (when (or (null (symbol-value reftex-docstruct-symbol)) | |
1593 | (member rescan '(t 1 (4) (16)))) | |
1594 | ;; The docstruct will change: Remove selection buffers. | |
1595 | (save-excursion | |
1596 | (reftex-erase-all-selection-buffers))) | |
1597 | ||
1598 | (if (and (null (symbol-value reftex-docstruct-symbol)) | |
1599 | (not (member rescan '(t 1 (4) (16)))) | |
1600 | reftex-save-parse-info) | |
1601 | ;; Try to read the stuff from a file | |
1602 | (reftex-access-parse-file 'read)) | |
1603 | ||
1604 | (cond | |
1605 | ((equal rescan -1)) ;; We are not allowed to scan. | |
1606 | ((not (symbol-value reftex-docstruct-symbol)) | |
1607 | ;; Scan the whole document | |
1608 | (reftex-do-parse 1 file)) | |
1609 | ((member rescan '(t 1 (4) (16))) | |
1610 | ;; Scan whatever was required by the caller. | |
1611 | (reftex-do-parse rescan file)))) | |
1612 | ||
396e0b08 KH |
1613 | (defun reftex-parse-one () |
1614 | "Re-parse this file." | |
a7ec1775 | 1615 | (interactive) |
396e0b08 KH |
1616 | (let ((reftex-enable-partial-scans t)) |
1617 | (reftex-access-scan-info '(4)))) | |
a7ec1775 | 1618 | |
396e0b08 KH |
1619 | (defun reftex-parse-all () |
1620 | "Re-parse entire document." | |
1621 | (interactive) | |
1622 | (reftex-access-scan-info '(16))) | |
1623 | ||
396e0b08 | 1624 | (defun reftex-do-parse (rescan &optional file) |
b849548d | 1625 | "Do a document rescan. When allowed, do only a partial scan from FILE." |
396e0b08 KH |
1626 | |
1627 | ;; Normalize the rescan argument | |
1628 | (setq rescan (cond ((eq rescan t) t) | |
1629 | ((eq rescan 1) 1) | |
1630 | ((equal rescan '(4)) t) | |
1631 | ((equal rescan '(16)) 1) | |
1632 | (t 1))) | |
1633 | ||
1634 | ;; Partial scans only when allowed | |
1635 | (unless reftex-enable-partial-scans | |
1636 | (setq rescan 1)) | |
1637 | ||
1638 | ;; Do the scanning. | |
1639 | ||
1640 | (let* ((old-list (symbol-value reftex-docstruct-symbol)) | |
1641 | (master (reftex-TeX-master-file)) | |
b849548d | 1642 | (true-master (file-truename master)) |
396e0b08 KH |
1643 | (master-dir (file-name-as-directory (file-name-directory master))) |
1644 | (file (or file (buffer-file-name))) | |
b849548d CD |
1645 | (true-file (file-truename file)) |
1646 | (bibview-cache (assq 'bibview-cache old-list)) | |
2faef409 | 1647 | from-file appendix docstruct tmp) |
396e0b08 KH |
1648 | |
1649 | ;; Make sure replacement is really an option here | |
1650 | (when (and (eq rescan t) | |
1651 | (not (and (member (list 'bof file) old-list) | |
1652 | (member (list 'eof file) old-list)))) | |
b849548d | 1653 | ;; Scan whole document because no such file section exists |
396e0b08 | 1654 | (setq rescan 1)) |
b849548d CD |
1655 | (when (string= true-file true-master) |
1656 | ;; Scan whole document because this file is the master | |
396e0b08 KH |
1657 | (setq rescan 1)) |
1658 | ||
1659 | ;; From which file do we start? | |
1660 | (setq from-file | |
1661 | (cond ((eq rescan t) (or file master)) | |
1662 | ((eq rescan 1) master) | |
b849548d | 1663 | (t (error "This should not happen (reftex-do-parse)")))) |
396e0b08 KH |
1664 | |
1665 | ;; Find active toc entry and initialize section-numbers | |
2faef409 RS |
1666 | (setq reftex-active-toc (reftex-last-assoc-before-elt |
1667 | 'toc (list 'bof from-file) old-list) | |
1668 | appendix (reftex-last-assoc-before-elt | |
1669 | 'appendix (list 'bof from-file) old-list)) | |
1670 | ||
1671 | (reftex-init-section-numbers reftex-active-toc appendix) | |
396e0b08 KH |
1672 | |
1673 | (if (eq rescan 1) | |
1674 | (message "Scanning entire document...") | |
1675 | (message "Scanning document from %s..." from-file)) | |
1676 | ||
1677 | (save-window-excursion | |
1678 | (save-excursion | |
1679 | (unwind-protect | |
1680 | (setq docstruct | |
1681 | (reftex-parse-from-file | |
1682 | from-file docstruct master-dir)) | |
1683 | (reftex-kill-temporary-buffers)))) | |
1684 | ||
1685 | (message "Scanning document... done") | |
1686 | ||
1687 | ;; Turn the list around. | |
1688 | (setq docstruct (nreverse docstruct)) | |
1689 | ||
1690 | ;; Set or insert | |
1691 | (setq docstruct (reftex-replace-label-list-segment | |
1692 | old-list docstruct (eq rescan 1))) | |
1693 | ||
1694 | ;; Add all missing information | |
1695 | (unless (assq 'label-numbers docstruct) | |
1696 | (push (cons 'label-numbers nil) docstruct)) | |
1697 | (unless (assq 'master-dir docstruct) | |
1698 | (push (cons 'master-dir master-dir) docstruct)) | |
b849548d CD |
1699 | (unless (assq 'bibview-cache docstruct) |
1700 | (push (cons 'bibview-cache (cdr bibview-cache)) docstruct)) | |
396e0b08 KH |
1701 | (let* ((bof1 (memq (assq 'bof docstruct) docstruct)) |
1702 | (bof2 (assq 'bof (cdr bof1))) | |
1703 | (is-multi (not (not (and bof1 bof2)))) | |
1704 | (entry (or (assq 'is-multi docstruct) | |
1705 | (car (push (list 'is-multi is-multi) docstruct))))) | |
1706 | (setcdr entry (cons is-multi nil))) | |
1707 | (unless (assq 'xr docstruct) | |
1708 | (let* ((allxr (reftex-all-assq 'xr-doc docstruct)) | |
2faef409 RS |
1709 | (alist (mapcar |
1710 | (function | |
1711 | (lambda (x) | |
396e0b08 KH |
1712 | (if (setq tmp (reftex-find-tex-file (nth 2 x) |
1713 | master-dir)) | |
1714 | (cons (nth 1 x) tmp) | |
1715 | (message "Can't find external document %s" | |
2faef409 RS |
1716 | (nth 2 x)) |
1717 | nil))) | |
396e0b08 | 1718 | allxr)) |
b849548d CD |
1719 | (alist (delq nil alist)) |
1720 | (allprefix (delq nil (mapcar 'car alist))) | |
2faef409 RS |
1721 | (regexp (if allprefix |
1722 | (concat "\\`\\(" | |
1723 | (mapconcat 'identity allprefix "\\|") | |
1724 | "\\)") | |
1725 | "\\\\\\\\\\\\"))) ; this will never match | |
396e0b08 KH |
1726 | (push (list 'xr alist regexp) docstruct))) |
1727 | ||
1728 | (set reftex-docstruct-symbol docstruct) | |
b849548d | 1729 | (put reftex-docstruct-symbol 'modified t))) |
396e0b08 KH |
1730 | |
1731 | (defun reftex-parse-from-file (file docstruct master-dir) | |
1732 | ;; Scan the buffer for labels and save them in a list. | |
1733 | (let ((regexp reftex-everything-regexp) | |
1734 | (bound 0) | |
2faef409 | 1735 | file-found tmp include-file |
396e0b08 KH |
1736 | (level 1) |
1737 | (highest-level 100) | |
b849548d | 1738 | toc-entry next-buf buf) |
396e0b08 KH |
1739 | |
1740 | (catch 'exit | |
1741 | (setq file-found (reftex-find-tex-file file master-dir)) | |
b849548d CD |
1742 | (if (and (not file-found) |
1743 | (setq buf (reftex-get-buffer-visiting file))) | |
1744 | (setq file-found (buffer-file-name buf))) | |
1745 | ||
396e0b08 KH |
1746 | (unless file-found |
1747 | (push (list 'file-error file) docstruct) | |
1748 | (throw 'exit nil)) | |
1749 | ||
1750 | (save-excursion | |
1751 | ||
1752 | (message "Scanning file %s" file) | |
1753 | (set-buffer | |
1754 | (setq next-buf | |
1755 | (reftex-get-file-buffer-force | |
1756 | file-found | |
1757 | (not (eq t reftex-keep-temporary-buffers))))) | |
1758 | ||
1759 | ;; Begin of file mark | |
1760 | (setq file (buffer-file-name)) | |
1761 | (push (list 'bof file) docstruct) | |
1762 | ||
1763 | (save-excursion | |
1764 | (save-restriction | |
1765 | (widen) | |
1766 | (goto-char 1) | |
1767 | ||
1768 | (while (re-search-forward regexp nil t) | |
1769 | ||
1770 | (cond | |
1771 | ||
1772 | ((match-end 1) | |
1773 | ;; It is a label | |
1774 | (push (reftex-label-info (reftex-match-string 1) file bound) | |
1775 | docstruct)) | |
1776 | ||
1777 | ((match-end 3) | |
1778 | ;; It is a section | |
1779 | (setq bound (point)) | |
1780 | ||
1781 | ;; Insert in List | |
1782 | (setq toc-entry (reftex-section-info file)) | |
1783 | (setq level (nth 5 toc-entry)) | |
1784 | (setq highest-level (min highest-level level)) | |
1785 | (if (= level highest-level) | |
1786 | (message | |
1787 | "Scanning %s %s ..." | |
b849548d | 1788 | (car (rassoc level reftex-section-levels)) |
396e0b08 KH |
1789 | (nth 6 toc-entry))) |
1790 | ||
1791 | (push toc-entry docstruct) | |
1792 | (setq reftex-active-toc toc-entry)) | |
1793 | ||
1794 | ((match-end 7) | |
1795 | ;; It's an include or input | |
2faef409 | 1796 | (setq include-file (reftex-match-string 7)) |
b849548d CD |
1797 | ;; Test if this file should be ignored |
1798 | (unless (delq nil (mapcar | |
1799 | (lambda (x) (string-match x include-file)) | |
1800 | reftex-no-include-regexps)) | |
2faef409 RS |
1801 | ;; Parse it |
1802 | (setq docstruct | |
1803 | (reftex-parse-from-file | |
1804 | include-file | |
1805 | docstruct master-dir)))) | |
1806 | ||
1807 | ((match-end 9) | |
1808 | ;; Appendix starts here | |
1809 | (reftex-init-section-numbers nil t) | |
1810 | (push (cons 'appendix t) docstruct)) | |
1811 | ||
1812 | ((match-end 10) | |
396e0b08 KH |
1813 | ;; A macro with label |
1814 | (save-excursion | |
2faef409 RS |
1815 | (let* ((mac (reftex-match-string 10)) |
1816 | (label (progn (goto-char (match-end 10)) | |
396e0b08 KH |
1817 | (save-match-data |
1818 | (reftex-no-props | |
1819 | (reftex-nth-arg-wrapper | |
1820 | mac))))) | |
b849548d CD |
1821 | (typekey (nth 1 (assoc mac reftex-env-or-mac-alist))) |
1822 | (entry (progn (if typekey | |
1823 | ;; A typing macro | |
1824 | (goto-char (match-end 0)) | |
1825 | ;; A newtral macro | |
1826 | (goto-char (match-end 10)) | |
1827 | (reftex-move-over-touching-args)) | |
1828 | (reftex-label-info | |
1829 | label file bound nil nil)))) | |
396e0b08 KH |
1830 | (push entry docstruct)))) |
1831 | (t (error "This should not happen (reftex-parse-from-file)"))) | |
1832 | ) | |
1833 | ||
396e0b08 KH |
1834 | ;; Find bibliography statement |
1835 | (when (setq tmp (reftex-locate-bibliography-files master-dir)) | |
1836 | (push (cons 'bib tmp) docstruct)) | |
1837 | ||
2faef409 RS |
1838 | (goto-char 1) |
1839 | (when (re-search-forward | |
1840 | "\\(\\`\\|[\n\r]\\)[ \t]*\\\\begin{thebibliography}" nil t) | |
1841 | (push (cons 'thebib file) docstruct)) | |
1842 | ||
396e0b08 KH |
1843 | ;; Find external document specifications |
1844 | (goto-char 1) | |
1845 | (while (re-search-forward "[\n\r][ \t]*\\\\externaldocument\\(\\[\\([^]]*\\)\\]\\)?{\\([^}]+\\)}" nil t) | |
2faef409 | 1846 | (push (list 'xr-doc (reftex-match-string 2) |
396e0b08 KH |
1847 | (reftex-match-string 3)) |
1848 | docstruct)) | |
1849 | ||
1850 | ;; End of file mark | |
1851 | (push (list 'eof file) docstruct)))) | |
1852 | ||
1853 | ;; Kill the scanned buffer | |
1854 | (reftex-kill-temporary-buffers next-buf)) | |
1855 | ||
1856 | ;; Return the list | |
1857 | docstruct)) | |
1858 | ||
1859 | (defun reftex-locate-bibliography-files (master-dir) | |
2faef409 | 1860 | ;; Scan buffer for bibliography macro and return file list. |
b849548d | 1861 | (let (files) |
396e0b08 KH |
1862 | (save-excursion |
1863 | (goto-char (point-min)) | |
b849548d CD |
1864 | (when (re-search-forward |
1865 | "\\(\\`\\|[\n\r]\\)[ \t]*\\\\bibliography{[ \t]*\\([^}]+\\)" nil t) | |
1866 | (setq files (split-string (reftex-match-string 2) | |
1867 | "[ \t\n\r]*,[ \t\n\r]*")) | |
1868 | (setq files | |
1869 | (mapcar | |
1870 | (lambda (x) | |
1871 | (if (or (member x reftex-bibfile-ignore-list) | |
1872 | (delq nil (mapcar (lambda (re) (string-match re x)) | |
1873 | reftex-bibfile-ignore-regexps))) | |
1874 | ;; excluded file | |
1875 | nil | |
1876 | ;; find the file | |
1877 | (reftex-find-bib-file | |
1878 | (if (string-match "\\.bib\\'" x) x (concat x ".bib")) | |
1879 | master-dir))) | |
1880 | files)) | |
1881 | (delq nil files))))) | |
396e0b08 KH |
1882 | |
1883 | (defun reftex-replace-label-list-segment (old insert &optional entirely) | |
1884 | ;; Replace the segment in OLD which corresponds to INSERT. | |
1885 | ;; Works with side effects, directly changes old. | |
1886 | ;; If entirely is t, just return INSERT. | |
1887 | ;; This function also makes sure the old toc markers do not point anywhere. | |
1888 | ||
1889 | (cond | |
1890 | (entirely | |
1891 | (reftex-silence-toc-markers old (length old)) | |
1892 | insert) | |
1893 | (t (let* ((new old) | |
1894 | (file (nth 1 (car insert))) | |
1895 | (eof-list (member (list 'eof file) old)) | |
1896 | (bof-list (member (list 'bof file) old)) | |
1897 | n) | |
1898 | (if (not (and bof-list eof-list)) | |
1899 | (error "Cannot splice") | |
1900 | ;; Splice | |
1901 | (reftex-silence-toc-markers bof-list (- (length bof-list) | |
1902 | (length eof-list))) | |
1903 | (setq n (- (length old) (length bof-list))) | |
1904 | (setcdr (nthcdr n new) (cdr insert)) | |
1905 | (setcdr (nthcdr (1- (length new)) new) (cdr eof-list))) | |
1906 | new)))) | |
1907 | ||
1908 | (defun reftex-silence-toc-markers (list n) | |
b849548d | 1909 | ;; Set all toc markers in the first N entries in list to nil |
396e0b08 KH |
1910 | (while (and list (> (decf n) -1)) |
1911 | (and (eq (car (car list)) 'toc) | |
1912 | (markerp (nth 4 (car list))) | |
1913 | (set-marker (nth 4 (car list)) nil)) | |
1914 | (pop list))) | |
1915 | ||
1916 | (defun reftex-access-parse-file (action) | |
b849548d CD |
1917 | "Perform ACTION on the parse file (the .rel file). |
1918 | Valid actions are: readable, restore, read, kill, write." | |
396e0b08 | 1919 | (let* ((list (symbol-value reftex-docstruct-symbol)) |
b849548d | 1920 | (docstruct-symbol reftex-docstruct-symbol) |
396e0b08 KH |
1921 | (master (reftex-TeX-master-file)) |
1922 | (enable-local-variables nil) | |
1923 | (file (if (string-match "\\.[a-zA-Z]+\\'" master) | |
1924 | (concat (substring master 0 (match-beginning 0)) ".rel") | |
1925 | (concat master ".rel")))) | |
1926 | (cond | |
1927 | ((eq action 'readable) | |
1928 | (file-readable-p file)) | |
1929 | ((eq action 'restore) | |
b849548d | 1930 | (put reftex-docstruct-symbol 'modified nil) |
396e0b08 KH |
1931 | (if (eq reftex-docstruct-symbol nil) |
1932 | ;; Symbols are not yet tied: Tie them. | |
1933 | (reftex-tie-multifile-symbols)) | |
1934 | (if (file-exists-p file) | |
1935 | ;; load the file and return t for success | |
b849548d CD |
1936 | (condition-case nil |
1937 | (progn (load-file file) t) | |
1938 | (error (set reftex-docstruct-symbol nil) | |
1939 | (error "Error while loading file %s" file))) | |
1940 | ;; Throw an exception if the file does not exist | |
2faef409 | 1941 | (error "No restore file %s" file))) |
396e0b08 | 1942 | ((eq action 'read) |
b849548d | 1943 | (put reftex-docstruct-symbol 'modified nil) |
396e0b08 KH |
1944 | (if (file-exists-p file) |
1945 | ;; load the file and return t for success | |
b849548d CD |
1946 | (condition-case nil |
1947 | (progn (load-file file) t) | |
1948 | (error (message "Error while loading file %s" file) | |
1949 | (set reftex-docstruct-symbol nil) | |
1950 | nil)) | |
2faef409 | 1951 | ;; return nil for failure, but no exception |
396e0b08 | 1952 | nil)) |
b849548d CD |
1953 | ((eq action 'kill) |
1954 | ;; Remove the file | |
1955 | (when (and (file-exists-p file) (file-writable-p file)) | |
1956 | (message "Unlinking file %s" file) | |
1957 | (delete-file file))) | |
396e0b08 | 1958 | (t |
b849548d | 1959 | (put docstruct-symbol 'modified nil) |
396e0b08 KH |
1960 | (save-excursion |
1961 | (if (file-writable-p file) | |
1962 | (progn | |
1963 | (message "Writing parse file %s" (abbreviate-file-name file)) | |
1964 | (find-file file) | |
1965 | (erase-buffer) | |
1966 | (insert (format ";; RefTeX parse info file\n")) | |
1967 | (insert (format ";; File: %s\n" master)) | |
396e0b08 KH |
1968 | (insert (format ";; User: %s (%s)\n\n" |
1969 | (user-login-name) (user-full-name))) | |
1970 | (insert "(set reftex-docstruct-symbol '(\n\n") | |
1971 | (let ((standard-output (current-buffer))) | |
1972 | (mapcar | |
1973 | (function | |
1974 | (lambda (x) | |
1975 | (cond ((eq (car x) 'toc) | |
1976 | ;; A toc entry. Do not save the marker. | |
1977 | ;; Save the markers position at position 8 | |
1978 | (print (list 'toc "toc" (nth 2 x) (nth 3 x) | |
1979 | nil (nth 5 x) (nth 6 x) (nth 7 x) | |
1980 | (or (and (markerp (nth 4 x)) | |
1981 | (marker-position (nth 4 x))) | |
1982 | (nth 8 x))))) | |
1983 | (t (print x))))) | |
1984 | list)) | |
b849548d | 1985 | (insert "))\n\n") |
396e0b08 KH |
1986 | (save-buffer 0) |
1987 | (kill-buffer (current-buffer))) | |
1988 | (error "Cannot write to file %s" file))) | |
1989 | t)))) | |
1990 | ||
b849548d CD |
1991 | (defun reftex-kill-buffer-hook () |
1992 | "Save RefTeX's parse file for this buffer if the information has changed." | |
1993 | ;; Save the parsing information if it was modified. | |
1994 | ;; This function should be installed in `kill-buffer-hook'. | |
1995 | ;; We are careful to make sure nothing goes wring in this function. | |
1996 | (when (and (boundp 'reftex-mode) reftex-mode | |
1997 | (boundp 'reftex-save-parse-info) reftex-save-parse-info | |
1998 | (boundp 'reftex-docstruct-symbol) reftex-docstruct-symbol | |
1999 | (symbol-value reftex-docstruct-symbol) | |
2000 | (get reftex-docstruct-symbol 'modified)) | |
2001 | ;; Write the file. | |
2002 | (condition-case nil | |
2003 | (reftex-access-parse-file 'write) | |
2004 | (error nil)))) | |
396e0b08 | 2005 | |
b849548d CD |
2006 | (defun reftex-kill-emacs-hook () |
2007 | "Call `reftex-kill-buffer-hook' on all buffers." | |
2008 | ;; This function should be installed in `kill-emacs-hook'. | |
2009 | (save-excursion | |
2010 | (mapcar (lambda (buf) | |
2011 | (set-buffer buf) | |
2012 | (reftex-kill-buffer-hook)) | |
2013 | (buffer-list)))) | |
a7ec1775 | 2014 | |
b849548d CD |
2015 | (defun reftex-section-info (file) |
2016 | ;; Return a section entry for the current match. | |
2017 | ;; Carefull: This function expects the match-data to be still in place! | |
2018 | (let* ((marker (set-marker (make-marker) (1- (match-beginning 3)))) | |
2019 | (macro (reftex-match-string 3)) | |
2020 | (star (= ?* (char-after (match-end 3)))) | |
2021 | (level (cdr (assoc macro reftex-section-levels-all))) | |
2022 | (section-number (reftex-section-number level star)) | |
2023 | (text1 (save-match-data (save-excursion (reftex-context-substring)))) | |
2024 | (literal (buffer-substring-no-properties | |
2025 | (1- (match-beginning 3)) | |
2026 | (min (point-max) (+ (match-end 0) (length text1) 1)))) | |
2027 | ;; Literal can be too short since text1 too short. No big problem. | |
2028 | (text (reftex-nicify-text text1))) | |
a7ec1775 | 2029 | |
b849548d CD |
2030 | ;; Add section number and indentation |
2031 | (setq text | |
2032 | (concat | |
2033 | (make-string (* reftex-level-indent level) ?\ ) | |
2034 | (if (nth 1 reftex-label-menu-flags) ; section number flag | |
2035 | (concat section-number " ")) | |
2036 | text)) | |
2037 | (list 'toc "toc" text file marker level section-number | |
2038 | literal (marker-position marker)))) | |
2faef409 | 2039 | |
b849548d CD |
2040 | (defun reftex-label-info-update (cell) |
2041 | ;; Update information about just one label in a different file. | |
2042 | ;; CELL contains the old info list | |
2043 | (let* ((label (nth 0 cell)) | |
2044 | (typekey (nth 1 cell)) | |
2045 | ;; (text (nth 2 cell)) | |
2046 | (file (nth 3 cell)) | |
2047 | (comment (nth 4 cell)) | |
2048 | (note (nth 5 cell)) | |
2049 | (buf (reftex-get-file-buffer-force | |
2050 | file (not (eq t reftex-keep-temporary-buffers))))) | |
2051 | (if (not buf) | |
2052 | (list label typekey "" file comment "LOST LABEL. RESCAN TO FIX.") | |
2053 | (save-excursion | |
2054 | (set-buffer buf) | |
2055 | (save-restriction | |
2056 | (widen) | |
2057 | (goto-char 1) | |
2faef409 | 2058 | |
b849548d CD |
2059 | (if (or (re-search-forward |
2060 | (format reftex-find-label-regexp-format | |
2061 | (regexp-quote label)) nil t) | |
2062 | (re-search-forward | |
2063 | (format reftex-find-label-regexp-format2 | |
2064 | (regexp-quote label)) nil t)) | |
2faef409 | 2065 | |
b849548d CD |
2066 | (progn |
2067 | (backward-char 1) | |
2068 | (append (reftex-label-info label file) (list note))) | |
2069 | (list label typekey "" file "LOST LABEL. RESCAN TO FIX."))))))) | |
2faef409 | 2070 | |
b849548d CD |
2071 | (defun reftex-label-info (label &optional file bound derive env-or-mac) |
2072 | ;; Return info list on LABEL at point. | |
2073 | (let* ((env-or-mac (or env-or-mac (reftex-label-location bound))) | |
2074 | (typekey (nth 1 (assoc env-or-mac reftex-env-or-mac-alist))) | |
2075 | (file (or file (buffer-file-name))) | |
2076 | (parse (if (reftex-typekey-check | |
2077 | typekey reftex-use-text-after-label-as-context) | |
2078 | nil | |
2079 | (nth 2 (assoc env-or-mac reftex-env-or-mac-alist)))) | |
2080 | (text (reftex-short-context env-or-mac parse reftex-location-start | |
2081 | derive)) | |
2082 | (in-comment (reftex-in-comment))) | |
2083 | (list label typekey text file in-comment))) | |
2faef409 | 2084 | |
b849548d CD |
2085 | (defun reftex-in-comment () |
2086 | (save-excursion | |
2087 | (skip-chars-backward "^%\n\r") | |
2088 | (eq (preceding-char) ?%))) | |
a7ec1775 | 2089 | |
b849548d CD |
2090 | (defun reftex-short-context (env parse &optional bound derive) |
2091 | ;; Get about one line of useful context for the label definition at point. | |
a7ec1775 | 2092 | |
b849548d CD |
2093 | (if (consp parse) |
2094 | (setq parse (if derive (cdr parse) (car parse)))) | |
a7ec1775 | 2095 | |
b849548d | 2096 | (reftex-nicify-text |
a7ec1775 | 2097 | |
b849548d | 2098 | (cond |
a7ec1775 | 2099 | |
b849548d CD |
2100 | ((null parse) |
2101 | (save-excursion | |
2102 | (reftex-context-substring))) | |
a7ec1775 | 2103 | |
b849548d CD |
2104 | ((eq parse t) |
2105 | (if (string= env "section") | |
2106 | ;; special treatment for section labels | |
2107 | (save-excursion | |
2108 | (if (and (re-search-backward reftex-section-or-include-regexp | |
2109 | (point-min) t) | |
2110 | (match-end 2)) | |
2111 | (progn | |
2112 | (goto-char (match-end 0)) | |
2113 | (reftex-context-substring)) | |
2114 | (if reftex-active-toc | |
2115 | (progn | |
2116 | (string-match "{\\([^}]*\\)" (nth 7 reftex-active-toc)) | |
2117 | (match-string 1 (nth 7 reftex-active-toc))) | |
2118 | "SECTION HEADING NOT FOUND"))) | |
2119 | (save-excursion | |
2120 | (goto-char reftex-default-context-position) | |
2121 | (unless (eq (string-to-char env) ?\\) | |
2122 | (reftex-move-over-touching-args)) | |
2123 | (reftex-context-substring)))) | |
a7ec1775 | 2124 | |
b849548d CD |
2125 | ((stringp parse) |
2126 | (save-excursion | |
2127 | (if (re-search-backward parse bound t) | |
2128 | (progn | |
2129 | (goto-char (match-end 0)) | |
2130 | (reftex-context-substring)) | |
2131 | "NO MATCH FOR CONTEXT REGEXP"))) | |
a7ec1775 | 2132 | |
b849548d CD |
2133 | ((integerp parse) |
2134 | (or (save-excursion | |
2135 | (goto-char reftex-default-context-position) | |
2136 | (reftex-nth-arg | |
2137 | parse | |
2138 | (nth 6 (assoc env reftex-env-or-mac-alist)))) | |
2139 | "")) | |
a7ec1775 | 2140 | |
b849548d CD |
2141 | ((fboundp parse) |
2142 | ;; A hook function. Call it. | |
2143 | (save-excursion | |
2144 | (condition-case error-var | |
2145 | (funcall parse env) | |
2146 | (error (format "HOOK ERROR: %s" (cdr error-var)))))) | |
2147 | (t | |
2148 | "ILLEGAL VALUE OF PARSE")))) | |
a7ec1775 | 2149 | |
b849548d CD |
2150 | (defun reftex-nicify-text (text) |
2151 | ;; Make TEXT nice for inclusion as context into label menu | |
2152 | ;; remove line breaks and extra white space | |
2153 | (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text) | |
2154 | (setq text (replace-match " " nil t text))) | |
2155 | ;; cut before the next `\end{' or `\item' or `\\' | |
2156 | (if (string-match "\\(\\\\end{\\|\\\\item\\|\\\\\\\\\\).*" text) | |
2157 | (setq text (replace-match "" nil t text))) | |
2158 | ;; kill the embedded label | |
2159 | (if (string-match "\\\\label{[^}]*}" text) | |
2160 | (setq text (replace-match "" nil t text))) | |
2161 | ;; remove leading garbage | |
2162 | (if (string-match "\\`[ }]+" text) | |
2163 | (setq text (replace-match "" nil t text))) | |
2164 | ;; limit length | |
2165 | (cond | |
2166 | ((> (length text) 100) (substring text 0 100)) | |
2167 | ((= (length text) 0) (make-string 1 ?\ )) | |
2168 | (t text))) | |
a7ec1775 | 2169 | |
b849548d CD |
2170 | (defun reftex-where-am-I () |
2171 | ;; Return the docstruct entry above point. Actually returns a cons | |
2172 | ;; cell in which the cdr is a flag indicating if the information is | |
2173 | ;; exact (t) or approximate (nil). | |
a7ec1775 | 2174 | |
b849548d CD |
2175 | (let ((docstruct (symbol-value reftex-docstruct-symbol)) |
2176 | (cnt 0) rtn | |
2177 | found) | |
2178 | (save-excursion | |
2179 | (while (not rtn) | |
2180 | (incf cnt) | |
2181 | (setq found (re-search-backward reftex-everything-regexp nil t)) | |
2182 | (setq rtn | |
2183 | (cond | |
2184 | ((not found) | |
2185 | ;; no match | |
2186 | (or | |
2187 | (car (member (list 'bof (buffer-file-name)) docstruct)) | |
2188 | (not (setq cnt 2)) | |
2189 | (assq 'bof docstruct) ;; for safety reasons | |
2190 | 'corrupted)) | |
2191 | ((match-end 1) | |
2192 | ;; Label | |
2193 | (assoc (reftex-match-string 1) | |
2194 | (symbol-value reftex-docstruct-symbol))) | |
2195 | ((match-end 3) | |
2196 | ;; Section | |
2197 | (goto-char (1- (match-beginning 3))) | |
2198 | (let* ((list (member (list 'bof (buffer-file-name)) | |
2199 | docstruct)) | |
2200 | (endelt (car (member (list 'eof (buffer-file-name)) | |
2201 | list))) | |
2202 | rtn1) | |
2203 | (while (and list (not (eq endelt (car list)))) | |
2204 | (if (and (eq (car (car list)) 'toc) | |
2205 | (string= (buffer-file-name) | |
2206 | (nth 3 (car list)))) | |
2207 | (cond | |
2208 | ((equal (point) | |
2209 | (or (and (markerp (nth 4 (car list))) | |
2210 | (marker-position (nth 4 (car list)))) | |
2211 | (nth 8 (car list)))) | |
2212 | ;; Fits with marker position or recorded position | |
2213 | (setq rtn1 (car list) list nil)) | |
2214 | ((looking-at (reftex-make-regexp-allow-for-ctrl-m | |
2215 | (nth 7 (car list)))) | |
2216 | ;; Same title | |
2217 | (setq rtn1 (car list) list nil cnt 2)))) | |
2218 | (pop list)) | |
2219 | rtn1)) | |
2220 | ((match-end 7) | |
2221 | ;; Input or include... | |
2222 | (car | |
2223 | (member (list 'eof (reftex-find-tex-file | |
2224 | (reftex-match-string 7) | |
2225 | (cdr (assq 'master-dir docstruct)))) | |
2226 | docstruct))) | |
2227 | ((match-end 9) | |
2228 | (assq 'appendix (symbol-value reftex-docstruct-symbol))) | |
2229 | ((match-end 10) | |
2230 | (save-excursion | |
2231 | (goto-char (match-end 10)) | |
2232 | (assoc (reftex-no-props | |
2233 | (reftex-nth-arg-wrapper | |
2234 | (reftex-match-string 10))) | |
2235 | (symbol-value reftex-docstruct-symbol)))) | |
2236 | (t | |
2237 | (error "This should not happen (reftex-where-am-I)")))))) | |
2238 | (cons rtn (eq cnt 1)))) | |
206c6f82 | 2239 | |
a7ec1775 | 2240 | (defun reftex-label-location (&optional bound) |
b849548d CD |
2241 | "Return the environment or macro which determines the label type at point. |
2242 | If optional BOUND is an integer, limit backward searches to that point." | |
a7ec1775 RS |
2243 | |
2244 | (let* ((loc1 (reftex-what-macro reftex-label-mac-list bound)) | |
2245 | (loc2 (reftex-what-environment reftex-label-env-list bound)) | |
2246 | (p1 (or (cdr loc1) 0)) | |
2247 | (p2 (or (cdr loc2) 0))) | |
2248 | ||
2249 | (setq reftex-location-start (max p1 p2)) | |
396e0b08 | 2250 | (if (>= p1 p2) |
a7ec1775 | 2251 | (progn |
396e0b08 KH |
2252 | (setq reftex-default-context-position (+ p1 (length (car loc1)))) |
2253 | (or (car loc1) "section")) | |
2254 | (setq reftex-default-context-position (+ p2 8 (length (car loc2)))) | |
a7ec1775 RS |
2255 | (or (car loc2) "section")))) |
2256 | ||
b849548d CD |
2257 | (defun reftex-parse-args (macro) |
2258 | ;; Return a list of macro name, nargs, arg-nr which is label and a list of | |
2259 | ;; optional argument indices. | |
2260 | (if (string-match "[[{]\\*?[]}]" macro) | |
2261 | (progn | |
2262 | (let ((must-match (substring macro 0 (match-beginning 0))) | |
2263 | (args (substring macro (match-beginning 0))) | |
2264 | opt-list nlabel (cnt 0)) | |
2265 | (while (string-match "\\`[[{]\\(\\*\\)?[]}]" args) | |
2266 | (incf cnt) | |
2267 | (when (eq ?\[ (string-to-char args)) | |
2268 | (push cnt opt-list)) | |
2269 | (when (and (match-end 1) | |
2270 | (not nlabel)) | |
2271 | (setq nlabel cnt)) | |
2272 | (setq args (substring args (match-end 0)))) | |
2273 | (list must-match cnt nlabel opt-list))) | |
2274 | nil)) | |
396e0b08 | 2275 | |
b849548d CD |
2276 | (defsubst reftex-move-to-next-arg (&optional ignore) |
2277 | ;; Assuming that we are at the end of a macro name or a macro argument, | |
2278 | ;; move forward to the opening parenthesis of the next argument. | |
2279 | ;; This function understands the splitting of macros over several lines | |
2280 | ;; in TeX. | |
206c6f82 | 2281 | (cond |
b849548d CD |
2282 | ;; Just to be quick: |
2283 | ((memq (following-char) '(?\[ ?\{))) | |
2284 | ;; Do a search | |
2285 | ((and reftex-allow-detached-macro-args | |
2286 | (looking-at "[ \t]*[\n\r]?\\([ \t]*%[^\n\r]*[\n\r]\\)*[ \t]*[[{]")) | |
2287 | (goto-char (1- (match-end 0))) | |
2288 | t) | |
2289 | (t nil))) | |
a7ec1775 | 2290 | |
b849548d CD |
2291 | (defsubst reftex-move-to-previous-arg (&optional bound) |
2292 | ;; Assuming that we are in front of a macro argument, | |
2293 | ;; move backward to the closing parenthesis of the previous argument. | |
2294 | ;; This function understands the splitting of macros over several lines | |
2295 | ;; in TeX. | |
2296 | (cond | |
2297 | ;; Just to be quick: | |
2298 | ((memq (preceding-char) '(?\] ?\}))) | |
2299 | ;; Do a search | |
2300 | ((and reftex-allow-detached-macro-args | |
2301 | (re-search-backward | |
2302 | "[]}][ \t]*[\n\r]?\\([ \t]*%[^\n\r]*[\n\r]\\)*[ \t]*\\=" bound t)) | |
2303 | (goto-char (1+ (match-beginning 0))) | |
2304 | t) | |
2305 | (t nil))) | |
206c6f82 | 2306 | |
b849548d CD |
2307 | (defun reftex-nth-arg-wrapper (key) |
2308 | (let ((entry (assoc key reftex-env-or-mac-alist))) | |
2309 | (reftex-nth-arg (nth 5 entry) (nth 6 entry)))) | |
2faef409 | 2310 | |
b849548d CD |
2311 | (defun reftex-nth-arg (n &optional opt-args) |
2312 | ;; Return the nth following {} or [] parentheses content. | |
2313 | ;; OPT-ARGS is a list of argument numbers which are optional. | |
a7ec1775 | 2314 | |
b849548d CD |
2315 | ;; If we are sitting at a macro start, skip to end of macro name. |
2316 | (and (eq (following-char) ?\\) (skip-chars-forward "a-zA-Z*\\\\")) | |
29d593f8 | 2317 | |
b849548d CD |
2318 | (if (= n 1000) |
2319 | ;; Special case: Skip all touching arguments | |
2320 | (progn | |
2321 | (reftex-move-over-touching-args) | |
2322 | (reftex-context-substring)) | |
29d593f8 | 2323 | |
b849548d CD |
2324 | ;; Do the real thing. |
2325 | (let ((cnt 1)) | |
2326 | ||
2327 | (when (reftex-move-to-next-arg) | |
2328 | ||
2329 | (while (< cnt n) | |
2330 | (while (and (member cnt opt-args) | |
2331 | (eq (following-char) ?\{)) | |
2332 | (incf cnt)) | |
2333 | (when (< cnt n) | |
2334 | (unless (and (condition-case nil | |
2335 | (or (forward-list 1) t) | |
2336 | (error nil)) | |
2337 | (reftex-move-to-next-arg) | |
2338 | (incf cnt)) | |
2339 | (setq cnt 1000)))) | |
29d593f8 | 2340 | |
b849548d CD |
2341 | (while (and (memq cnt opt-args) |
2342 | (eq (following-char) ?\{)) | |
2343 | (incf cnt))) | |
2344 | (if (and (= n cnt) | |
2345 | (> (skip-chars-forward "{\\[") 0)) | |
2346 | (reftex-context-substring) | |
2347 | nil)))) | |
29d593f8 | 2348 | |
b849548d CD |
2349 | (defun reftex-move-over-touching-args () |
2350 | (condition-case nil | |
2351 | (while (memq (following-char) '(?\[ ?\{)) | |
2352 | (forward-list 1)) | |
2353 | (error nil))) | |
a7ec1775 | 2354 | |
b849548d CD |
2355 | (defun reftex-context-substring () |
2356 | ;; Return up to 100 chars from point | |
2357 | ;; When point is just after a { or [, limit string to matching parenthesis | |
2358 | (cond | |
2359 | ((or (= (preceding-char) ?\{) | |
2360 | (= (preceding-char) ?\[)) | |
2361 | ;; Inside a list - get only the list. | |
2362 | (buffer-substring-no-properties | |
2363 | (point) | |
2364 | (min (+ (point) 150) | |
2365 | (point-max) | |
2366 | (condition-case nil | |
2367 | (progn | |
2368 | (up-list 1) | |
2369 | (1- (point))) | |
2370 | (error (point-max)))))) | |
2371 | (t | |
2372 | ;; no list - just grab 100 characters | |
2373 | (buffer-substring-no-properties (point) | |
2374 | (min (+ (point) 150) (point-max)))))) | |
a7ec1775 | 2375 | |
b849548d CD |
2376 | ;; Variable holding the vector with section numbers |
2377 | (defvar reftex-section-numbers [0 0 0 0 0 0 0 0]) | |
2378 | ||
2379 | (defun reftex-init-section-numbers (&optional toc-entry appendix) | |
2380 | ;; Initialize the section numbers with zeros or with what is found | |
2381 | ;; in the toc entry. | |
2382 | (let* ((level (or (nth 5 toc-entry) -1)) | |
2383 | (numbers (nreverse (split-string (or (nth 6 toc-entry) "") "\\."))) | |
2384 | (depth (1- (length reftex-section-numbers))) | |
2385 | (i depth) number-string) | |
2386 | (while (>= i 0) | |
2387 | (if (> i level) | |
2388 | (aset reftex-section-numbers i 0) | |
2389 | (setq number-string (or (car numbers) "0")) | |
2390 | (if (string-match "\\`[A-Z]\\'" number-string) | |
2391 | (aset reftex-section-numbers i | |
2392 | (- (string-to-char number-string) ?A -1)) | |
2393 | (aset reftex-section-numbers i (string-to-int number-string))) | |
2394 | (pop numbers)) | |
2395 | (decf i))) | |
2396 | (put 'reftex-section-numbers 'appendix appendix)) | |
2397 | ||
2398 | (defun reftex-section-number (&optional level star) | |
2399 | ;; Return a string with the current section number. | |
2400 | ;; When LEVEL is non-nil, increase section numbers on that level. | |
2401 | (let* ((depth (1- (length reftex-section-numbers))) idx n (string "") | |
2402 | (appendix (get 'reftex-section-numbers 'appendix))) | |
2403 | (when level | |
2404 | (when (and (> level -1) (not star)) | |
2405 | (aset reftex-section-numbers | |
2406 | level (1+ (aref reftex-section-numbers level)))) | |
2407 | (setq idx (1+ level)) | |
2408 | (when (not star) | |
2409 | (while (<= idx depth) | |
2410 | (aset reftex-section-numbers idx 0) | |
2411 | (incf idx)))) | |
2412 | (setq idx 0) | |
2413 | (while (<= idx depth) | |
2414 | (setq n (aref reftex-section-numbers idx)) | |
2415 | (setq string (concat string (if (not (string= string "")) "." "") | |
2416 | (int-to-string n))) | |
2417 | (incf idx)) | |
2418 | (save-match-data | |
2419 | (if (string-match "\\`\\([@0]\\.\\)+" string) | |
2420 | (setq string (replace-match "" nil nil string))) | |
2421 | (if (string-match "\\(\\.0\\)+\\'" string) | |
2422 | (setq string (replace-match "" nil nil string))) | |
2423 | (if (and appendix | |
2424 | (string-match "\\`[0-9]+" string)) | |
2425 | (setq string | |
2426 | (concat | |
2427 | (char-to-string | |
2428 | (1- (+ ?A (string-to-int (match-string 0 string))))) | |
2429 | (substring string (match-end 0)))))) | |
2430 | (if star | |
2431 | (concat (make-string (1- (length string)) ?\ ) "*") | |
2432 | string))) | |
2433 | ||
2434 | (defun reftex-is-multi () | |
2435 | ;; Tell if this is a multifile document. When not sure, say yes. | |
2436 | (let ((entry (assq 'is-multi (symbol-value reftex-docstruct-symbol)))) | |
2437 | (if entry | |
2438 | (nth 1 entry) | |
2439 | t))) | |
2440 | ||
2441 | (defun reftex-typekey-check (typekey conf-variable &optional n) | |
2442 | ;; Check if CONF-VARIABLE is true or contains TYPEKEY | |
2443 | (and n (setq conf-variable (nth n conf-variable))) | |
2444 | (or (eq conf-variable t) | |
2445 | (and (stringp conf-variable) | |
2446 | (string-match (concat "[" conf-variable "]") typekey)))) | |
2447 | ||
2448 | (defun reftex-all-document-files (&optional relative) | |
2449 | "Return a list of all files belonging to the current document. | |
2450 | When RELATIVE is non-nil, give file names relative to directory | |
2451 | of master file." | |
2452 | (let* ((all (symbol-value reftex-docstruct-symbol)) | |
2453 | (master-dir (file-name-directory (reftex-TeX-master-file))) | |
2454 | (re (concat "\\`" (regexp-quote master-dir))) | |
2455 | file-list tmp file) | |
2456 | (while (setq tmp (assoc 'bof all)) | |
2457 | (setq file (nth 1 tmp) | |
2458 | all (cdr (memq tmp all))) | |
2459 | (and relative | |
2460 | (string-match re file) | |
2461 | (setq file (substring file (match-end 0)))) | |
2462 | (push file file-list)) | |
2463 | (nreverse file-list))) | |
2464 | ||
2465 | ;;; Creating labels --------------------------------------------------------- | |
2466 | ||
2467 | (defun reftex-label (&optional environment no-insert) | |
2468 | "Insert a unique label. Return the label. | |
2469 | If ENVIRONMENT is given, don't bother to find out yourself. | |
2470 | If NO-INSERT is non-nil, do not insert label into buffer. | |
2471 | With prefix arg, force to rescan document first. | |
2472 | When you are prompted to enter or confirm a label, and you reply with | |
2473 | just the prefix or an empty string, no label at all will be inserted. | |
2474 | A new label is also recorded into the label list. | |
2475 | This function is controlled by the settings of reftex-insert-label-flags." | |
2476 | ||
2477 | (interactive) | |
2478 | ||
2479 | ;; Ensure access to scanning info and rescan buffer if prefix are is '(4). | |
2480 | (reftex-access-scan-info current-prefix-arg) | |
2481 | ||
2482 | ;; Find out what kind of environment this is and abort if necessary. | |
2483 | (if (or (not environment) | |
2484 | (not (assoc environment reftex-env-or-mac-alist))) | |
2485 | (setq environment (reftex-label-location))) | |
2486 | (unless environment | |
2487 | (error "Can't figure out what kind of label should be inserted")) | |
2488 | ||
2489 | ;; Ok, go ahead. | |
2490 | (catch 'exit | |
2491 | (let* ((entry (assoc environment reftex-env-or-mac-alist)) | |
2492 | (typekey (nth 1 entry)) | |
2493 | (format (nth 3 entry)) | |
2494 | (macro-cell (reftex-what-macro 1)) | |
2495 | (entry1 (assoc (car macro-cell) reftex-env-or-mac-alist)) | |
2496 | label naked prefix valid default force-prompt rescan-is-useful) | |
2497 | (when (and (or (nth 5 entry) (nth 5 entry1)) | |
2498 | (memq (preceding-char) '(?\[ ?\{))) | |
2499 | ;; This is an argument of a label macro. Insert naked label. | |
2500 | (setq naked t format "%s")) | |
2501 | ||
2502 | (setq prefix (or (cdr (assoc typekey reftex-typekey-to-prefix-alist)) | |
2503 | (concat typekey "-"))) | |
2504 | ;; Replace any escapes in the prefix | |
2505 | (setq prefix (reftex-replace-prefix-escapes prefix)) | |
2506 | ||
2507 | ;; Make a default label. | |
2508 | (cond | |
2509 | ||
2510 | ((reftex-typekey-check typekey (nth 0 reftex-insert-label-flags)) | |
2511 | ;; Derive a label from context. | |
2512 | (setq reftex-active-toc (reftex-last-assoc-before-elt | |
2513 | 'toc (car (reftex-where-am-I)) | |
2514 | (symbol-value reftex-docstruct-symbol))) | |
2515 | (setq default (reftex-no-props | |
2516 | (nth 2 (reftex-label-info " " nil nil t)))) | |
2517 | ;; Catch the cases where the is actually no context available. | |
2518 | (if (or (string-match "NO MATCH FOR CONTEXT REGEXP" default) | |
2519 | (string-match "ILLEGAL VALUE OF PARSE" default) | |
2520 | (string-match "SECTION HEADING NOT FOUND" default) | |
2521 | (string-match "HOOK ERROR" default) | |
2522 | (string-match "^[ \t]*$" default)) | |
2523 | (setq default prefix | |
2524 | force-prompt t) ; need to prompt | |
2525 | (setq default | |
2526 | (concat prefix | |
2527 | (funcall reftex-string-to-label-function default))) | |
2528 | ||
2529 | ;; Make it unique. | |
2530 | (setq default (reftex-uniquify-label default nil "-")))) | |
2531 | ||
2532 | ((reftex-typekey-check typekey (nth 1 reftex-insert-label-flags)) | |
2533 | ;; Minimal default: the user will be prompted. | |
2534 | (setq default prefix)) | |
2535 | ||
2536 | (t | |
2537 | ;; Make an automatic label. | |
2538 | (setq default (reftex-uniquify-label prefix t)))) | |
2539 | ||
2540 | ;; Should we ask the user? | |
2541 | (if (or (reftex-typekey-check typekey | |
2542 | (nth 1 reftex-insert-label-flags)) ; prompt | |
2543 | force-prompt) | |
2544 | ||
2545 | (while (not valid) | |
2546 | ;; iterate until we get a legal label | |
2547 | ||
2548 | (setq label (read-string | |
2549 | (if naked "Naked Label: " "Label: ") | |
2550 | default)) | |
2551 | ||
2552 | ;; Lets make sure that this is a legal label | |
2553 | (cond | |
2554 | ||
2555 | ((string-match (concat "\\`\\(" (regexp-quote prefix) | |
2556 | "\\)?[ \t]*\\'") | |
2557 | label) | |
2558 | ;; No label at all, please | |
2559 | (message "No label inserted.") | |
2560 | (throw 'exit nil)) | |
2561 | ||
2562 | ;; Test if label contains strange characters | |
2563 | ((string-match reftex-label-illegal-re label) | |
2564 | (message "Label \"%s\" contains illegal characters" label) | |
2565 | (ding) | |
2566 | (sit-for 2)) | |
2567 | ||
2568 | ;; Look it up in the label list | |
2569 | ((setq entry (assoc label | |
2570 | (symbol-value reftex-docstruct-symbol))) | |
2571 | (ding) | |
2572 | (if (y-or-n-p | |
2573 | (format "Label '%s' exists. Use anyway? " label)) | |
2574 | (setq valid t))) | |
2575 | ||
2576 | ;; Label is ok | |
2577 | (t | |
2578 | (setq valid t)))) | |
2579 | (setq label default)) | |
2580 | ||
2581 | ;; Insert the label into the label list | |
2582 | (let* ((here-I-am-info | |
2583 | (save-excursion | |
2584 | (if (and (or naked no-insert) | |
2585 | (integerp (cdr macro-cell))) | |
2586 | (goto-char (cdr macro-cell))) | |
2587 | (reftex-where-am-I))) | |
2588 | (here-I-am (car here-I-am-info)) | |
2589 | (note (if (cdr here-I-am-info) | |
2590 | "" | |
2591 | "POSITION UNCERTAIN. RESCAN TO FIX.")) | |
2592 | (file (buffer-file-name)) | |
2593 | (text nil) | |
2594 | (tail (memq here-I-am (symbol-value reftex-docstruct-symbol)))) | |
2595 | ||
2596 | (or (cdr here-I-am-info) (setq rescan-is-useful t)) | |
2597 | ||
2598 | (when tail | |
2599 | (push (list label typekey text file nil note) (cdr tail)) | |
2600 | (put reftex-docstruct-symbol 'modified t))) | |
2601 | ||
2602 | ;; Insert the label into the buffer | |
2603 | (unless no-insert | |
2604 | (insert | |
2605 | (if reftex-format-label-function | |
2606 | (funcall reftex-format-label-function label format) | |
2607 | (format format label))) | |
2608 | (if (and reftex-plug-into-AUCTeX | |
2609 | (fboundp 'LaTeX-add-labels)) | |
2610 | ;; Tell AUCTeX about this | |
2611 | (LaTeX-add-labels label))) | |
2612 | ||
2613 | ;; Delete the corresponding selection buffers to force update on next use. | |
2614 | (when reftex-auto-update-selection-buffers | |
2615 | (reftex-erase-buffer (reftex-make-selection-buffer-name typekey)) | |
2616 | (reftex-erase-buffer (reftex-make-selection-buffer-name " "))) | |
2617 | ||
2618 | (when (and rescan-is-useful reftex-allow-automatic-rescan) | |
2619 | (reftex-parse-one)) | |
2620 | ||
2621 | ;; return value of the function is the label | |
2622 | label))) | |
2623 | ||
2624 | (defun reftex-string-to-label (string) | |
2625 | "Convert a string (a sentence) to a label. | |
2626 | Uses `reftex-derive-label-parameters' and `reftex-label-illegal-re'. It | |
2627 | also applies `reftex-translate-to-ascii-function' to the string." | |
2628 | (when (and reftex-translate-to-ascii-function | |
2629 | (fboundp reftex-translate-to-ascii-function)) | |
2630 | (setq string (funcall reftex-translate-to-ascii-function string))) | |
2631 | (apply 'reftex-convert-string string | |
2632 | "[-~ \t\n\r,;]+" reftex-label-illegal-re nil nil | |
2633 | reftex-derive-label-parameters)) | |
2634 | ||
2635 | (defun reftex-abbreviate-title (string) | |
2636 | (reftex-convert-string string "[-~ \t\n\r,;]" nil t t | |
2637 | 5 40 nil 1 " " (nth 5 reftex-derive-label-parameters))) | |
2638 | ||
2639 | (defun reftex-convert-string (string split-re illegal-re dot keep-fp | |
2640 | nwords maxchar illegal abbrev sep | |
2641 | ignore-words &optional downcase) | |
2642 | "Convert a string (a sentence) to something shorter. | |
2643 | SPLIT-RE is the regular expression used to split the string into words. | |
2644 | ILLEGAL-RE matches characters which are illegal in the final string. | |
2645 | DOT t means add dots to abbreviated words. | |
2646 | KEEP-FP t means to keep a final punctuation when applicable. | |
2647 | NWORDS Number of words to use. | |
2648 | MAXCHAR Maximum number of characters in the final string. | |
2649 | ILLEGAL nil: Throw away any words containing stuff matched with ILLEGAL-RE. | |
2650 | t: Throw away only the matched part, not the whole word. | |
2651 | ABBREV nil: Never abbreviate words. | |
2652 | t: Always abbreviate words (see `reftex-abbrev-parameters'). | |
2653 | not t and not nil: Abbreviate words if necessary to shorten | |
2654 | string below MAXCHAR. | |
2655 | SEP String separating different words in the output string. | |
2656 | IGNORE-WORDS List of words which should be removed from the string." | |
2657 | ||
2658 | (let* ((words0 (split-string string (or split-re "[ \t\n\r]"))) | |
a6611c0d | 2659 | (reftex-label-illegal-re (or illegal-re "\000")) |
b849548d CD |
2660 | words word) |
2661 | ||
2662 | ;; Remove words from the ignore list or with funny characters | |
2663 | (while (setq word (pop words0)) | |
2664 | (if downcase (setq word (downcase word))) | |
2665 | (cond | |
2666 | ((member (downcase word) ignore-words)) | |
a6611c0d | 2667 | ((string-match reftex-label-illegal-re word) |
b849548d | 2668 | (when illegal |
a6611c0d | 2669 | (while (string-match reftex-label-illegal-re word) |
b849548d CD |
2670 | (setq word (replace-match "" nil nil word))) |
2671 | (push word words))) | |
2672 | (t | |
2673 | (push word words)))) | |
2674 | (setq words (nreverse words)) | |
2675 | ||
2676 | ;; Restrict number of words | |
2677 | (if (> (length words) nwords) | |
2678 | (setcdr (nthcdr (1- nwords) words) nil)) | |
2679 | ||
2680 | ;; First, try to use all words | |
2681 | (setq string (mapconcat 'identity words sep)) | |
2682 | ||
2683 | ;; Abbreviate words if enforced by user settings or string length | |
2684 | (if (or (eq t abbrev) | |
2685 | (and abbrev | |
2686 | (> (length string) maxchar))) | |
2687 | (setq words | |
2688 | (mapcar | |
2689 | (function | |
2690 | (lambda (w) (if (string-match reftex-abbrev-regexp w) | |
2691 | (if dot | |
2692 | (concat (match-string 1 w) ".") | |
2693 | (match-string 1 w)) | |
2694 | w))) | |
2695 | words) | |
2696 | string (mapconcat 'identity words sep))) | |
2697 | ||
2698 | ;; Shorten if still to long | |
2699 | (setq string | |
2700 | (if (> (length string) maxchar) | |
2701 | (substring string 0 maxchar) | |
2702 | string)) | |
2703 | ||
2704 | ;; Delete the final punctuation, if any | |
2705 | (if (and (not keep-fp) (string-match "\\s.+\\'" string)) | |
2706 | (setq string (replace-match "" nil nil string))) | |
2707 | string)) | |
2708 | ||
a6611c0d CD |
2709 | (defun reftex-latin1-to-ascii (string) |
2710 | ;; Translate the upper 127 chars in the ISO1 charset to ASCII equivalents | |
2711 | (let ((tab "@@@@@@@@@@@@@@@@@@'@@@@@@@@@@@@@ icLxY|S\"ca<--R-o|23'uq..1o>423?AAAAAAACEEEEIIIIDNOOOOOXOUUUUYP3aaaaaaaceeeeiiiidnooooo:ouuuuypy") c) | |
2712 | (loop for i from 0 to (1- (length string)) do | |
2713 | (setq c (aref string i)) | |
2714 | (cond ((and (> c 127) (< c 256)) ; 8 bit Latin-1 | |
2715 | (aset string i (aref tab (- c 128)))) | |
2716 | ((and (> c 2175) (< c 2304)) ; Mule Latin-1, | |
2717 | (aset string i (aref tab (- c 2176)))))) ; Std. Emacs only | |
2718 | string)) | |
2719 | ||
b849548d CD |
2720 | (defun reftex-replace-prefix-escapes (prefix) |
2721 | ;; Replace %escapes in a label prefix | |
2722 | (save-match-data | |
2723 | (let (letter (num 0) replace) | |
2724 | (while (string-match "\\%\\([a-zA-Z]\\)" prefix num) | |
2725 | (setq letter (match-string 1 prefix)) | |
2726 | (setq replace | |
2727 | (cond | |
2728 | ((equal letter "f") | |
2729 | (file-name-sans-extension | |
2730 | (file-name-nondirectory (buffer-file-name)))) | |
2731 | ((equal letter "F") | |
2732 | (let ((masterdir (file-name-directory (reftex-TeX-master-file))) | |
2733 | (file (file-name-sans-extension (buffer-file-name)))) | |
2734 | (if (string-match (concat "\\`" (regexp-quote masterdir)) | |
2735 | file) | |
2736 | (substring file (length masterdir)) | |
2737 | file))) | |
2738 | ((equal letter "u") | |
2739 | (or (user-login-name) "")) | |
2740 | (t ""))) | |
2741 | (setq num (1- (+ (match-beginning 1) (length replace))) | |
2742 | prefix (replace-match replace nil nil prefix))) | |
2743 | prefix))) | |
2744 | ||
2745 | (defun reftex-uniquify-label (label &optional force separator) | |
2746 | ;; Make label unique by appending a number. | |
2747 | ;; Optional FORCE means, force appending a number, even if label is unique. | |
2748 | ;; Optional SEPARATOR is a string to stick between label and number. | |
2749 | ||
2750 | ;; Ensure access to scanning info | |
2751 | (reftex-access-scan-info) | |
2752 | ||
2753 | (cond | |
2754 | ((and (not force) | |
2755 | (not (assoc label (symbol-value reftex-docstruct-symbol)))) | |
2756 | label) | |
2757 | (t | |
2758 | (let* ((label-numbers (assq 'label-numbers | |
2759 | (symbol-value reftex-docstruct-symbol))) | |
2760 | (label-numbers-alist (cdr label-numbers)) | |
2761 | (cell (or (assoc label label-numbers-alist) | |
2762 | (car (setcdr label-numbers | |
2763 | (cons (cons label 0) | |
2764 | label-numbers-alist))))) | |
2765 | (num (1+ (cdr cell))) | |
2766 | (sep (or separator ""))) | |
2767 | (while (assoc (concat label sep (int-to-string num)) | |
2768 | (symbol-value reftex-docstruct-symbol)) | |
2769 | (incf num)) | |
2770 | (setcdr cell num) | |
2771 | (concat label sep (int-to-string num)))))) | |
2772 | ||
2773 | ;;; Referencing labels ------------------------------------------------------ | |
2774 | ||
2775 | ;; Help string for the reference label menu | |
2776 | (defconst reftex-select-label-prompt | |
2777 | "Select: [n]ext [p]revious [r]escan [ ]context e[x]tern [q]uit RET [?]HELP+more") | |
2778 | ||
2779 | (defconst reftex-select-label-help | |
2780 | " n / p Go to next/previous label (Cursor motion works as well) | |
2781 | C-c C-n/p Go to next/previous section heading. | |
2782 | b / l Jump back to previous selection / Reuse last referenced label | |
2783 | C-s / C-r Search forward/backward. Use repeated C-s/C-r as in isearch. | |
2784 | g / s Update menu / Switch label type | |
2785 | r / R Reparse document / Reparse entire document | |
2786 | x Switch to label menu of external document (with LaTeX package `xr') | |
2787 | t i c # % Toggle: [i]ncl. file borders, [t]able of contents, [c]ontext | |
2788 | [#] label counters, [%] labels in comments | |
2789 | SPC / f Show full context in other window / Toggle follow mode | |
2790 | v / . Toggle \\ref <-> \\vref / Show insertion point in other window | |
2791 | TAB Enter a label with completion | |
2792 | q / RET Quit without referencing / Accept current label (also on mouse-2)") | |
2793 | ||
2794 | (defvar reftex-select-label-map nil | |
2795 | "Keymap used for *RefTeX Select* buffer, when selecting a label. | |
2796 | This keymap can be used to configure the label selection process which is | |
2797 | started with the command \\[reftex-reference].") | |
2798 | ||
2799 | (defun reftex-select-label-mode () | |
2800 | "Major mode for selecting a label in a LaTeX document. | |
2801 | This buffer was created with RefTeX. | |
2802 | It only has a meaningful keymap when you are in the middle of a | |
2803 | selection process. | |
2804 | To select a label, move the cursor to it and press RET. | |
2805 | Press `?' for a summary of important key bindings. | |
2806 | ||
2807 | During a selection process, these are the local bindings. | |
2808 | ||
2809 | \\{reftex-select-label-map}" | |
2810 | ||
2811 | (interactive) | |
2812 | (kill-all-local-variables) | |
2813 | (make-local-hook 'pre-command-hook) | |
2814 | (make-local-hook 'post-command-hook) | |
2815 | (setq major-mode 'reftex-select-label-mode | |
2816 | mode-name "RefTeX Select Label") | |
2817 | (when (syntax-table-p reftex-latex-syntax-table) | |
2818 | (set-syntax-table reftex-latex-syntax-table)) | |
2819 | ;; We do not set a local map - reftex-select-item does this. | |
2820 | (run-hooks 'reftex-select-label-mode-hook)) | |
2821 | ||
2822 | (defun reftex-reference (&optional type no-insert cut) | |
2823 | "Make a LaTeX reference. Look only for labels of a certain TYPE. | |
2824 | With prefix arg, force to rescan buffer for labels. This should only be | |
2825 | necessary if you have recently entered labels yourself without using | |
2826 | reftex-label. Rescanning of the buffer can also be requested from the | |
2827 | label selection menu. | |
2828 | The function returns the selected label or nil. | |
2829 | If NO-INSERT is non-nil, do not insert \\ref command, just return label. | |
2830 | When called with 2 C-u prefix args, disable magic word recognition." | |
2831 | ||
2832 | (interactive) | |
2833 | ||
2834 | ;; check for active recursive edits | |
2835 | (reftex-check-recursive-edit) | |
a7ec1775 RS |
2836 | |
2837 | ;; Ensure access to scanning info and rescan buffer if prefix are is '(4) | |
2838 | (reftex-access-scan-info current-prefix-arg) | |
2839 | ||
396e0b08 KH |
2840 | (unless type |
2841 | ;; guess type from context | |
2842 | (if (and reftex-guess-label-type | |
2faef409 RS |
2843 | (setq type (reftex-guess-label-type))) |
2844 | (setq cut (cdr type) | |
2845 | type (car type)) | |
396e0b08 | 2846 | (setq type (reftex-query-label-type)))) |
a7ec1775 | 2847 | |
2faef409 RS |
2848 | (let* ((varioref (if (reftex-typekey-check |
2849 | type reftex-vref-is-default) | |
2850 | "\\vref" "\\ref")) | |
2851 | (form "\\ref{%s}") | |
2852 | label pair) | |
a7ec1775 RS |
2853 | |
2854 | ;; Have the user select a label | |
29d593f8 | 2855 | (set-marker reftex-select-return-marker (point)) |
2faef409 RS |
2856 | (setq pair (save-excursion |
2857 | (reftex-offer-label-menu type))) | |
b849548d | 2858 | (reftex-ensure-compiled-variables) |
29d593f8 | 2859 | (set-marker reftex-select-return-marker nil) |
2faef409 RS |
2860 | (setq label (car pair) |
2861 | type (cdr pair) | |
2862 | form (or (cdr (assoc type reftex-typekey-to-format-alist)) | |
2863 | form)) | |
a7ec1775 RS |
2864 | |
2865 | (if (and label | |
2866 | (not no-insert)) | |
2867 | (progn | |
2faef409 RS |
2868 | (if cut (backward-delete-char cut)) |
2869 | ||
2870 | ;; remove ~ if we do already have a space | |
2871 | (when (and (= ?~ (string-to-char form)) | |
a6611c0d | 2872 | (member (preceding-char) '(?\ ?\t ?\n))) |
2faef409 RS |
2873 | (setq form (substring form 1))) |
2874 | ;; do we need to switch from \ref to \vref? | |
2875 | (when (string= varioref "\\vref") | |
2876 | (while (string-match "\\\\ref{" form) | |
2877 | (setq form (replace-match "\\vref{" t t form)))) | |
a7ec1775 | 2878 | ;; ok, insert the reference |
2faef409 RS |
2879 | (insert |
2880 | (if reftex-format-ref-function | |
2881 | (funcall reftex-format-ref-function label form) | |
2882 | (format form label label))) | |
396e0b08 KH |
2883 | (message "")) |
2884 | (message "Quit")) | |
2885 | ;; return the label | |
2886 | label)) | |
a7ec1775 | 2887 | |
2faef409 | 2888 | (defun reftex-guess-label-type () |
b849548d | 2889 | ;; Examine context to guess what a \ref might want to reference. |
2faef409 RS |
2890 | (let ((words reftex-words-to-typekey-alist) |
2891 | (case-fold-search t) | |
2892 | (bound (max (point-min) (- (point) 35))) | |
2893 | matched cell) | |
2894 | (save-excursion | |
2895 | (while (and (setq cell (pop words)) | |
2896 | (not (setq matched | |
2897 | (re-search-backward (car cell) bound t)))))) | |
2898 | (if matched | |
2899 | (cons (cdr cell) (- (match-end 0) (match-end 1))) | |
2900 | nil))) | |
2901 | ||
a7ec1775 | 2902 | (defun reftex-offer-label-menu (typekey) |
2faef409 | 2903 | ;; Offer a menu with the appropriate labels. Return (label . typekey). |
a7ec1775 | 2904 | (let* ((buf (current-buffer)) |
396e0b08 KH |
2905 | (xr-data (assq 'xr (symbol-value reftex-docstruct-symbol))) |
2906 | (xr-alist (cons (cons "" (buffer-file-name)) (nth 1 xr-data))) | |
2907 | (xr-index 0) | |
2908 | (here-I-am (car (reftex-where-am-I))) | |
2faef409 | 2909 | (here-I-am1 here-I-am) |
a7ec1775 | 2910 | (toc (reftex-typekey-check typekey reftex-label-menu-flags 0)) |
396e0b08 | 2911 | (files (reftex-typekey-check typekey reftex-label-menu-flags 7)) |
a7ec1775 RS |
2912 | (context (not (reftex-typekey-check |
2913 | typekey reftex-label-menu-flags 3))) | |
2914 | (counter (reftex-typekey-check | |
2915 | typekey reftex-label-menu-flags 2)) | |
2916 | (follow (reftex-typekey-check | |
2917 | typekey reftex-label-menu-flags 4)) | |
396e0b08 | 2918 | (commented (nth 5 reftex-label-menu-flags)) |
396e0b08 | 2919 | (prefix "") |
2faef409 RS |
2920 | selection-buffers |
2921 | offset rtn key data last-data entry) | |
a7ec1775 | 2922 | |
a7ec1775 RS |
2923 | (setq entry (cons nil nil)) |
2924 | ||
2925 | (unwind-protect | |
2926 | (catch 'exit | |
2927 | (while t | |
2928 | (save-window-excursion | |
2faef409 | 2929 | (delete-other-windows) |
b849548d CD |
2930 | (setq reftex-call-back-to-this-buffer buf |
2931 | reftex-latex-syntax-table (syntax-table)) | |
29d593f8 KH |
2932 | (let ((default-major-mode 'reftex-select-label-mode)) |
2933 | (if reftex-use-multiple-selection-buffers | |
2934 | (switch-to-buffer-other-window | |
2935 | (save-excursion | |
2936 | (set-buffer buf) | |
2937 | (reftex-make-selection-buffer-name typekey))) | |
2938 | (switch-to-buffer-other-window "*RefTeX Select*") | |
2939 | (reftex-erase-buffer))) | |
2940 | (unless (eq major-mode 'reftex-select-label-mode) | |
2941 | (reftex-select-label-mode)) | |
2faef409 | 2942 | (add-to-list 'selection-buffers (current-buffer)) |
a7ec1775 | 2943 | (setq truncate-lines t) |
396e0b08 KH |
2944 | (setq mode-line-format |
2945 | (list "---- " 'mode-line-buffer-identification | |
2faef409 | 2946 | " " 'varioref |
396e0b08 KH |
2947 | " " (abbreviate-file-name |
2948 | (buffer-file-name buf)) | |
2949 | " -%-")) | |
2faef409 RS |
2950 | (cond |
2951 | ((= 0 (buffer-size)) | |
29d593f8 KH |
2952 | (let ((buffer-read-only nil)) |
2953 | (setq offset (reftex-make-and-insert-label-list | |
2954 | typekey buf toc files context counter commented | |
2955 | (or here-I-am offset) prefix)))) | |
2faef409 RS |
2956 | (here-I-am |
2957 | (setq offset (reftex-get-offset buf here-I-am typekey))) | |
2958 | (t (setq offset t))) | |
29d593f8 | 2959 | (setq buffer-read-only t) |
2faef409 RS |
2960 | (setq offset (or offset t)) |
2961 | ||
396e0b08 | 2962 | (setq here-I-am nil) ; turn off determination of offset |
a7ec1775 RS |
2963 | (setq rtn |
2964 | (reftex-select-item | |
396e0b08 | 2965 | reftex-select-label-prompt |
206c6f82 | 2966 | reftex-select-label-help |
2faef409 | 2967 | reftex-select-label-map |
a7ec1775 | 2968 | offset |
be456a1d | 2969 | 'reftex-select-label-callback follow)) |
2faef409 RS |
2970 | (setq key (car rtn) |
2971 | data (nth 1 rtn) | |
2972 | last-data (nth 2 rtn) | |
2973 | offset t) | |
396e0b08 | 2974 | (unless key (throw 'exit nil)) |
a7ec1775 | 2975 | (cond |
2faef409 RS |
2976 | ((eq key ?g) |
2977 | ;; update buffer | |
29d593f8 | 2978 | (reftex-erase-buffer)) |
206c6f82 | 2979 | ((or (eq key ?r) |
2faef409 | 2980 | (eq key ?R)) |
a7ec1775 | 2981 | ;; rescan buffer |
29d593f8 | 2982 | (reftex-erase-buffer) |
b849548d | 2983 | (reftex-reparse-document buf last-data key)) |
206c6f82 | 2984 | ((eq key ?c) |
a7ec1775 | 2985 | ;; toggle context mode |
29d593f8 | 2986 | (reftex-erase-buffer) |
a7ec1775 | 2987 | (setq context (not context))) |
206c6f82 | 2988 | ((eq key ?s) |
a7ec1775 | 2989 | ;; switch type |
2faef409 | 2990 | (setq here-I-am here-I-am1) |
a7ec1775 | 2991 | (setq typekey (reftex-query-label-type))) |
206c6f82 | 2992 | ((eq key ?t) |
2faef409 | 2993 | ;; toggle table of contents display |
29d593f8 | 2994 | (reftex-erase-buffer) |
a7ec1775 | 2995 | (setq toc (not toc))) |
396e0b08 KH |
2996 | ((eq key ?i) |
2997 | ;; toggle display of included file borders | |
29d593f8 | 2998 | (reftex-erase-buffer) |
396e0b08 | 2999 | (setq files (not files))) |
206c6f82 | 3000 | ((eq key ?#) |
a7ec1775 | 3001 | ;; toggle counter display |
29d593f8 | 3002 | (reftex-erase-buffer) |
a7ec1775 | 3003 | (setq counter (not counter))) |
396e0b08 KH |
3004 | ((eq key ?%) |
3005 | ;; toggle display of commented labels | |
29d593f8 | 3006 | (reftex-erase-buffer) |
396e0b08 | 3007 | (setq commented (not commented))) |
206c6f82 | 3008 | ((eq key ?l) |
a7ec1775 RS |
3009 | ;; reuse the last referenced label again |
3010 | (setq entry reftex-last-used-reference) | |
3011 | (throw 'exit t)) | |
396e0b08 KH |
3012 | ((eq key ?x) |
3013 | ;; select an external document | |
3014 | (setq xr-index (reftex-select-external-document | |
3015 | xr-alist xr-index)) | |
3016 | (setq buf (or (reftex-get-file-buffer-force | |
baec1250 | 3017 | (cdr (nth xr-index xr-alist))) |
396e0b08 | 3018 | (error "Cannot switch document")) |
2faef409 RS |
3019 | prefix (or (car (nth xr-index xr-alist)) "")) |
3020 | (set-buffer buf) | |
3021 | (reftex-access-scan-info)) | |
3022 | ((stringp key) | |
3023 | (setq entry | |
3024 | (or (assoc key (symbol-value reftex-docstruct-symbol)) | |
3025 | (list key typekey))) | |
3026 | (throw 'exit t)) | |
a7ec1775 RS |
3027 | (t |
3028 | (set-buffer buf) | |
2faef409 | 3029 | (if data |
396e0b08 | 3030 | (progn |
2faef409 | 3031 | (setq entry data) |
396e0b08 KH |
3032 | (setq reftex-last-used-reference entry)) |
3033 | (setq entry nil)) | |
a7ec1775 | 3034 | (throw 'exit t)))))) |
b849548d CD |
3035 | (save-excursion |
3036 | (while reftex-buffers-with-changed-invisibility | |
3037 | (set-buffer (car (car reftex-buffers-with-changed-invisibility))) | |
3038 | (setq buffer-invisibility-spec | |
3039 | (cdr (pop reftex-buffers-with-changed-invisibility))))) | |
2faef409 RS |
3040 | (mapcar (function (lambda (buf) |
3041 | (and (buffer-live-p buf) | |
b849548d | 3042 | (bury-buffer buf)))) |
2faef409 | 3043 | selection-buffers) |
a7ec1775 | 3044 | (reftex-kill-temporary-buffers)) |
396e0b08 | 3045 | (cons (if (nth 0 entry) (concat prefix (nth 0 entry)) nil) |
2faef409 | 3046 | (nth 1 entry)))) |
396e0b08 | 3047 | |
b849548d CD |
3048 | (defun reftex-select-external-document (xr-alist xr-index) |
3049 | ;; Return index of an external document. | |
3050 | (let* ((len (length xr-alist)) (highest (1- (+ ?0 len))) | |
3051 | (prompt (format "[%c-%c] Select TAB: Read prefix with completion" | |
3052 | ?0 highest)) | |
3053 | key prefix) | |
3054 | (cond | |
3055 | ((= len 1) | |
3056 | (message "No external documents available") | |
3057 | (ding) (sit-for 1) 0) | |
3058 | ((= len 2) | |
3059 | (- 1 xr-index)) | |
3060 | (t | |
3061 | (save-excursion | |
3062 | (let* ((length (apply 'max (mapcar | |
3063 | (lambda(x) (length (car x))) xr-alist))) | |
3064 | (fmt (format " [%%c] %%-%ds %%s\n" length)) | |
3065 | (n (1- ?0))) | |
3066 | (setq key | |
3067 | (reftex-select-with-char | |
3068 | prompt | |
3069 | (concat | |
3070 | "SELECT EXTERNAL DOCUMENT\n------------------------\n" | |
3071 | (mapconcat | |
3072 | (function | |
3073 | (lambda (x) | |
3074 | (format fmt (incf n) (or (car x) "") | |
3075 | (abbreviate-file-name (cdr x))))) | |
3076 | xr-alist "")) | |
3077 | nil t)) | |
3078 | (cond | |
3079 | ((and (>= key ?0) (<= key highest)) (- key ?0)) | |
3080 | ((= key ?\C-i) | |
3081 | (setq prefix (completing-read "Prefix: " xr-alist nil t)) | |
3082 | (- len (length (memq (assoc prefix xr-alist) xr-alist)))) | |
3083 | (t (error "Illegal document selection [%c]" key))))))))) | |
3084 | ||
3085 | (defun reftex-reparse-document (&optional buffer data key) | |
3086 | ;; Rescan the document. | |
3087 | (save-window-excursion | |
3088 | (save-excursion | |
3089 | (if buffer | |
3090 | (if (not (bufferp buffer)) | |
3091 | (error "No such buffer %s" (buffer-name buffer)) | |
3092 | (set-buffer buffer))) | |
3093 | (let ((arg (if (eq key ?R) '(16) '(4))) | |
3094 | (file (nth 3 data))) | |
3095 | (reftex-access-scan-info arg file))))) | |
a7ec1775 | 3096 | |
b849548d CD |
3097 | (defun reftex-make-selection-buffer-name (type &optional index) |
3098 | ;; Make unique name for a selection buffer. | |
3099 | (format " *RefTeX[%s][%d]*" | |
3100 | type (or index (get reftex-docstruct-symbol ':master-index) 0))) | |
206c6f82 | 3101 | |
b849548d CD |
3102 | (defun reftex-get-offset (buf here-am-I typekey) |
3103 | ;; Find the correct offset data, like make-and-insert would, but faster. | |
3104 | (save-excursion | |
3105 | (set-buffer buf) | |
3106 | (reftex-access-scan-info) | |
3107 | (let* ((rest (memq here-am-I (symbol-value reftex-docstruct-symbol))) | |
3108 | entry) | |
3109 | (while (and (setq entry (pop rest)) | |
3110 | (not (and (stringp (car entry)) | |
3111 | (equal typekey (nth 1 entry)))))) | |
3112 | entry))) | |
a7ec1775 | 3113 | |
b849548d CD |
3114 | (defun reftex-make-and-insert-label-list |
3115 | (typekey0 buf toc files context counter show-commented here-I-am xr-prefix) | |
3116 | ;; Insert a menu of all labels in buffer BUF into current buffer. | |
3117 | ;; Return the data property of the entry corresponding to HERE-I-AM. | |
3118 | (let* ((font (reftex-use-fonts)) | |
3119 | (cnt 0) | |
3120 | (index -1) | |
3121 | (toc-indent " ") | |
3122 | (label-indent | |
3123 | (concat "> " | |
3124 | (if toc (make-string (* 7 reftex-level-indent) ?\ ) ""))) | |
3125 | (context-indent | |
3126 | (concat ". " | |
3127 | (if toc (make-string (* 7 reftex-level-indent) ?\ ) ""))) | |
3128 | (mouse-face | |
3129 | (if (memq reftex-highlight-selection '(mouse both)) | |
3130 | reftex-mouse-selected-face | |
3131 | nil)) | |
3132 | (label-face (reftex-verified-face reftex-label-face | |
3133 | 'font-lock-constant-face | |
3134 | 'font-lock-reference-face)) | |
3135 | all cell text label typekey note comment master-dir-re | |
3136 | offset from to docstruct-symbol) | |
a7ec1775 | 3137 | |
b849548d | 3138 | (message "Creating Selection Buffer...") |
a7ec1775 | 3139 | |
b849548d CD |
3140 | ;; Pop to buffer buf to get the correct buffer-local variables |
3141 | (save-excursion | |
3142 | (set-buffer buf) | |
a7ec1775 | 3143 | |
b849548d CD |
3144 | ;; Ensure access to scanning info |
3145 | (reftex-access-scan-info) | |
206c6f82 | 3146 | |
b849548d CD |
3147 | (setq docstruct-symbol reftex-docstruct-symbol |
3148 | all (symbol-value reftex-docstruct-symbol) | |
3149 | reftex-active-toc nil | |
3150 | master-dir-re | |
3151 | (concat "\\`" (regexp-quote | |
3152 | (file-name-directory (reftex-TeX-master-file)))))) | |
206c6f82 | 3153 | |
b849548d CD |
3154 | (set (make-local-variable 'reftex-docstruct-symbol) docstruct-symbol) |
3155 | (set (make-local-variable 'reftex-prefix) | |
3156 | (cdr (assoc typekey0 reftex-typekey-to-prefix-alist))) | |
3157 | (if (equal reftex-prefix " ") (setq reftex-prefix nil)) | |
a7ec1775 | 3158 | |
b849548d CD |
3159 | ;; Walk the docstruct and insert the appropriate stuff |
3160 | (while (setq cell (pop all)) | |
396e0b08 | 3161 | |
b849548d CD |
3162 | (incf index) |
3163 | (setq from (point)) | |
396e0b08 | 3164 | |
b849548d | 3165 | (if (eq cell here-I-am) (setq offset 'attention)) |
396e0b08 | 3166 | |
b849548d | 3167 | (cond |
396e0b08 | 3168 | |
b849548d CD |
3169 | ((memq (car cell) '(bib thebib label-numbers appendix |
3170 | master-dir bibview-cache is-multi xr xr-doc))) | |
3171 | ;; These are currently ignored | |
396e0b08 | 3172 | |
b849548d CD |
3173 | ((memq (car cell) '(bof eof file-error)) |
3174 | ;; Beginning or end of a file | |
3175 | (when files | |
3176 | (insert | |
3177 | " File " (if (string-match master-dir-re (nth 1 cell)) | |
3178 | (substring (nth 1 cell) (match-end 0)) | |
3179 | (nth 1 cell)) | |
3180 | (cond ((eq (car cell) 'bof) " starts here\n") | |
3181 | ((eq (car cell) 'eof) " ends here\n") | |
3182 | ((eq (car cell) 'file-error) " was not found\n"))) | |
3183 | (when font | |
3184 | (put-text-property from (point) | |
3185 | 'face reftex-file-boundary-face)))) | |
396e0b08 | 3186 | |
b849548d CD |
3187 | ((eq (car cell) 'toc) |
3188 | ;; a table of contents entry | |
3189 | (when toc | |
3190 | (setq reftex-active-toc cell) | |
3191 | (insert (concat toc-indent (nth 2 cell) "\n")) | |
3192 | (setq to (point)) | |
3193 | (when font | |
3194 | (put-text-property from to | |
3195 | 'face reftex-section-heading-face)) | |
3196 | (goto-char to))) | |
396e0b08 | 3197 | |
b849548d CD |
3198 | ((stringp (car cell)) |
3199 | ;; a label | |
3200 | (when (null (nth 2 cell)) | |
3201 | ;; No context yet. Quick update. | |
3202 | (setcdr cell (cdr (reftex-label-info-update cell))) | |
3203 | (put docstruct-symbol 'modified t)) | |
396e0b08 | 3204 | |
b849548d CD |
3205 | (setq label (car cell) |
3206 | typekey (nth 1 cell) | |
3207 | text (nth 2 cell) | |
3208 | comment (nth 4 cell) | |
3209 | note (nth 5 cell)) | |
396e0b08 | 3210 | |
b849548d CD |
3211 | (when (and (or (string= typekey typekey0) (string= typekey0 " ")) |
3212 | (or show-commented (null comment))) | |
396e0b08 | 3213 | |
b849548d CD |
3214 | ;; Yes we want this one |
3215 | (incf cnt) | |
3216 | (if (eq offset 'attention) (setq offset cell)) | |
396e0b08 | 3217 | |
b849548d CD |
3218 | (setq label (concat xr-prefix label)) |
3219 | (when comment (setq label (concat "% " label))) | |
3220 | (insert label-indent label) | |
3221 | (when font | |
3222 | (setq to (point)) | |
3223 | (put-text-property | |
3224 | (- (point) (length label)) to | |
3225 | 'face (if comment | |
3226 | 'font-lock-comment-face | |
3227 | label-face)) | |
3228 | (goto-char to)) | |
206c6f82 | 3229 | |
b849548d CD |
3230 | (insert (if counter (format " (%d) " cnt) "") |
3231 | (if comment " LABEL IS COMMENTED OUT " "") | |
3232 | (if (stringp note) (concat " " note) "") | |
3233 | "\n") | |
3234 | (setq to (point)) | |
a7ec1775 | 3235 | |
b849548d CD |
3236 | (when context |
3237 | (insert context-indent text "\n") | |
3238 | (setq to (point))) | |
3239 | (put-text-property from to ':data cell) | |
3240 | (when mouse-face | |
3241 | (put-text-property from (1- to) | |
3242 | 'mouse-face mouse-face)) | |
3243 | (goto-char to))))) | |
206c6f82 | 3244 | |
b849548d CD |
3245 | (when (reftex-refontify) |
3246 | (reftex-fontify-select-label-buffer buf)) | |
3247 | (run-hooks 'reftex-display-copied-context-hook) | |
3248 | offset)) | |
3249 | ||
3250 | (defun reftex-query-label-type () | |
3251 | ;; Ask for label type | |
3252 | (let ((key (reftex-select-with-char | |
3253 | reftex-type-query-prompt reftex-type-query-help 3))) | |
3254 | (unless (member (char-to-string key) reftex-typekey-list) | |
3255 | (error "No such label type: %s" (char-to-string key))) | |
3256 | (char-to-string key))) | |
a7ec1775 | 3257 | |
2faef409 | 3258 | (defun reftex-select-label-callback (data forward no-revisit) |
a7ec1775 RS |
3259 | ;; Callback function called from the label selection in order to |
3260 | ;; show context in another window | |
3261 | (let* ((this-window (selected-window)) | |
2faef409 | 3262 | label file buffer re found) |
a7ec1775 RS |
3263 | ;; pop to original buffer in order to get correct variables |
3264 | (catch 'exit | |
2faef409 RS |
3265 | (setq label (nth 0 data) |
3266 | file (nth 3 data)) | |
a7ec1775 | 3267 | |
b849548d CD |
3268 | ;; goto the file in another window |
3269 | (setq buffer | |
3270 | (if no-revisit | |
3271 | (reftex-get-buffer-visiting file) | |
3272 | (reftex-get-file-buffer-force | |
3273 | file (not reftex-keep-temporary-buffers)))) | |
3274 | (if buffer | |
3275 | ;; good - the file is available | |
3276 | (switch-to-buffer-other-window buffer) | |
3277 | ;; we have got a problem here. The file does not exist. | |
3278 | ;; Let' get out of here.. | |
3279 | ;; (ding) | |
3280 | (message reftex-no-follow-message) | |
3281 | (throw 'exit nil)) | |
396e0b08 | 3282 | |
b849548d CD |
3283 | ;; search for that label |
3284 | (setq re (format reftex-find-label-regexp-format (regexp-quote label))) | |
3285 | (setq found | |
3286 | (if forward | |
3287 | (re-search-forward re nil t) | |
3288 | (re-search-backward re nil t))) | |
3289 | (unless found | |
3290 | (goto-char (point-min)) | |
3291 | (unless (re-search-forward re nil t) | |
3292 | ;; Ooops. Must be in a macro with distributed args. | |
3293 | (re-search-forward (format reftex-find-label-regexp-format2 | |
3294 | (regexp-quote label)) nil t))) | |
3295 | (when (match-end 3) | |
3296 | (setq reftex-latex-syntax-table (syntax-table)) | |
3297 | (reftex-highlight 0 (match-beginning 3) (match-end 3)) | |
3298 | (reftex-show-entry (match-beginning 3) (match-end 3)) | |
a6611c0d | 3299 | (recenter '(4))) |
b849548d | 3300 | (select-window this-window)))) |
a7ec1775 | 3301 | |
b849548d CD |
3302 | (defun reftex-pop-to-label (label file-list &optional mark-to-kill highlight) |
3303 | ;; Find LABEL in any file in FILE-LIST in another window. | |
3304 | ;; If mark-to-kill is non-nil, mark new buffer for killing. | |
3305 | ;; If HIGHLIGHT is non-nil, highlight the label definition. | |
3306 | (let* ((re1 (format reftex-find-label-regexp-format (regexp-quote label))) | |
3307 | (re2 (format reftex-find-label-regexp-format2 (regexp-quote label))) | |
3308 | (re-list (list re1 re2)) re | |
3309 | (file-list-1 file-list) | |
3310 | file buf) | |
3311 | (catch 'exit | |
3312 | (while (setq re (pop re-list)) | |
3313 | (setq file-list file-list-1) | |
3314 | (while (setq file (pop file-list)) | |
3315 | (unless (setq buf (reftex-get-file-buffer-force file mark-to-kill)) | |
3316 | (error "No such file %s" file)) | |
3317 | (set-buffer buf) | |
3318 | (widen) | |
3319 | (goto-char (point-min)) | |
3320 | (when (re-search-forward re nil t) | |
3321 | (switch-to-buffer-other-window buf) | |
3322 | (goto-char (match-beginning 0)) | |
a6611c0d | 3323 | (recenter '(4)) |
b849548d CD |
3324 | (if highlight |
3325 | (reftex-highlight 0 (match-beginning 3) (match-end 3))) | |
3326 | (throw 'exit (selected-window))))) | |
3327 | (error "Label %s not found" label)))) | |
396e0b08 KH |
3328 | |
3329 | (defun reftex-show-entry (beg-hlt end-hlt) | |
b849548d CD |
3330 | ;; Show entry if point is hidden |
3331 | (let* ((n (/ (window-height) 2)) | |
396e0b08 KH |
3332 | (beg (save-excursion |
3333 | (re-search-backward "[\n\r]" nil 1 n) (point))) | |
3334 | (end (save-excursion | |
3335 | (re-search-forward "[\n\r]" nil 1 n) (point)))) | |
b849548d CD |
3336 | (cond |
3337 | ((and (boundp 'buffer-invisibility-spec) buffer-invisibility-spec | |
3338 | (get-char-property (1+ beg-hlt) 'invisible)) | |
3339 | ;; Invisible with text properties. That is easy to change. | |
3340 | (push (cons (current-buffer) buffer-invisibility-spec) | |
3341 | reftex-buffers-with-changed-invisibility) | |
3342 | (setq buffer-invisibility-spec nil)) | |
3343 | ((string-match "\r" (buffer-substring beg end)) | |
3344 | ;; Invisible with selective display. We need to copy it. | |
3345 | (let ((string (buffer-substring-no-properties beg end))) | |
3346 | (switch-to-buffer "*RefTeX Context Copy*") | |
3347 | (setq buffer-read-only nil) | |
3348 | (erase-buffer) | |
3349 | (insert string) | |
3350 | (subst-char-in-region (point-min) (point-max) ?\r ?\n t) | |
3351 | (goto-char (- beg-hlt beg)) | |
3352 | (reftex-highlight 0 (1+ (- beg-hlt beg)) (1+ (- end-hlt beg))) | |
3353 | (if (reftex-refontify) | |
3354 | (when (or (not (eq major-mode 'latex-mode)) | |
3355 | (not font-lock-mode)) | |
3356 | (latex-mode) | |
3357 | (run-hook-with-args | |
3358 | 'reftex-pre-refontification-functions | |
3359 | reftex-call-back-to-this-buffer 'reftex-hidden) | |
3360 | (turn-on-font-lock)) | |
3361 | (when (or (not (eq major-mode 'fundamental-mode)) | |
3362 | font-lock-mode) | |
3363 | (fundamental-mode))) | |
3364 | (run-hooks 'reftex-display-copied-context-hook) | |
3365 | (setq buffer-read-only t)))))) | |
3366 | ||
3367 | ;;; ========================================================================= | |
a7ec1775 | 3368 | ;;; |
396e0b08 | 3369 | ;;; Table of contents |
a7ec1775 RS |
3370 | |
3371 | ;; We keep at most one *toc* buffer - it is easy to make them | |
3372 | ||
2faef409 RS |
3373 | (defvar reftex-toc-map (make-sparse-keymap) |
3374 | "Keymap used for *toc* buffer.") | |
3375 | ||
29d593f8 KH |
3376 | (defun reftex-toc-mode () |
3377 | "Major mode for managing Table of Contents for LaTeX files. | |
3378 | This buffer was created with RefTeX. | |
3379 | Press `?' for a summary of important key bindings. | |
3380 | ||
3381 | Here are all local bindings. | |
3382 | ||
3383 | \\{reftex-toc-map}" | |
3384 | (interactive) | |
3385 | (kill-all-local-variables) | |
3386 | (setq major-mode 'reftex-toc-mode | |
3387 | mode-name "RefTeX Table of Contents") | |
3388 | (use-local-map reftex-toc-map) | |
3389 | (set (make-local-variable 'revert-buffer-function) 'reftex-toc-revert) | |
3390 | (setq truncate-lines t) | |
3391 | (make-local-hook 'post-command-hook) | |
3392 | (make-local-hook 'pre-command-hook) | |
3393 | (make-local-variable 'reftex-last-follow-point) | |
3394 | (add-hook 'post-command-hook 'reftex-toc-post-command-hook nil t) | |
3395 | (add-hook 'pre-command-hook 'reftex-toc-pre-command-hook nil t) | |
3396 | (run-hooks 'reftex-toc-mode-hook)) | |
3397 | ||
a7ec1775 RS |
3398 | (defvar reftex-last-toc-master nil |
3399 | "Stores the name of the tex file that `reftex-toc' was last run on.") | |
3400 | ||
3401 | (defvar reftex-last-toc-file nil | |
c52bdfca | 3402 | "Stores the file name from which `reftex-toc' was called. For redo command.") |
a7ec1775 | 3403 | |
206c6f82 RS |
3404 | (defvar reftex-last-window-height nil) |
3405 | ||
a7ec1775 RS |
3406 | (defvar reftex-toc-return-marker (make-marker) |
3407 | "Marker which makes it possible to return from toc to old position.") | |
3408 | ||
206c6f82 RS |
3409 | (defconst reftex-toc-help |
3410 | " AVAILABLE KEYS IN TOC BUFFER | |
3411 | ============================ | |
2faef409 | 3412 | n / p next-line / previous-line |
206c6f82 RS |
3413 | SPC Show the corresponding section of the LaTeX document. |
3414 | TAB Goto the section. | |
3415 | RET Goto the section and hide the *toc* buffer (also on mouse-2). | |
3416 | q / Q Hide/Kill *toc* buffer, return to position of last reftex-toc command. | |
2faef409 RS |
3417 | f / g Toggle follow mode on and off / Refresh *toc* buffer. |
3418 | r / R Reparse the LaTeX document / Reparse entire LaTeX document. | |
b849548d | 3419 | . In other window, show position from where `reftex-toc' was called. |
396e0b08 | 3420 | x Switch to TOC of external document (with LaTeX package `xr').") |
206c6f82 | 3421 | |
a7ec1775 RS |
3422 | (defun reftex-toc () |
3423 | "Show the table of contents for the current document. | |
a7ec1775 RS |
3424 | When called with a raw C-u prefix, rescan the document first." |
3425 | ||
3426 | (interactive) | |
3427 | ||
206c6f82 | 3428 | (if (or (not (string= reftex-last-toc-master (reftex-TeX-master-file))) |
396e0b08 | 3429 | current-prefix-arg) |
29d593f8 | 3430 | (reftex-erase-buffer "*toc*")) |
a7ec1775 RS |
3431 | |
3432 | (setq reftex-last-toc-file (buffer-file-name)) | |
3433 | (setq reftex-last-toc-master (reftex-TeX-master-file)) | |
3434 | ||
3435 | (set-marker reftex-toc-return-marker (point)) | |
3436 | ||
206c6f82 | 3437 | ;; If follow mode is active, arrange to delay it one command |
a7ec1775 RS |
3438 | (if reftex-toc-follow-mode |
3439 | (setq reftex-toc-follow-mode 1)) | |
3440 | ||
a7ec1775 RS |
3441 | ;; Ensure access to scanning info and rescan buffer if prefix are is '(4) |
3442 | (reftex-access-scan-info current-prefix-arg) | |
3443 | ||
396e0b08 KH |
3444 | (let* ((all (symbol-value reftex-docstruct-symbol)) |
3445 | (xr-data (assq 'xr all)) | |
3446 | (xr-alist (cons (cons "" (buffer-file-name)) (nth 1 xr-data))) | |
a7ec1775 | 3447 | (where (reftex-nearest-section)) |
6b94c6ad CD |
3448 | (mouse-face |
3449 | (if (memq reftex-highlight-selection '(mouse both)) | |
3450 | reftex-mouse-selected-face | |
3451 | nil)) | |
b849548d | 3452 | (fontify (reftex-use-fonts)) |
29d593f8 | 3453 | toc1 cell startpos) |
a7ec1775 | 3454 | |
206c6f82 RS |
3455 | (if (get-buffer-window "*toc*") |
3456 | (select-window (get-buffer-window "*toc*")) | |
2faef409 RS |
3457 | (when (< (window-height) (* 2 window-min-height)) |
3458 | (delete-other-windows)) | |
206c6f82 | 3459 | (setq reftex-last-window-height (window-height)) ; remember |
2faef409 | 3460 | (split-window) |
29d593f8 KH |
3461 | (let ((default-major-mode 'reftex-toc-mode)) |
3462 | (switch-to-buffer "*toc*"))) | |
3463 | ||
3464 | (or (eq major-mode 'reftex-toc-mode) (reftex-toc-mode)) | |
a7ec1775 RS |
3465 | |
3466 | (cond | |
3467 | ;; buffer is empty - fill it with the table of contents | |
3468 | ((= (buffer-size) 0) | |
2faef409 | 3469 | (message "Building *toc* buffer...") |
a7ec1775 | 3470 | |
29d593f8 | 3471 | (setq buffer-read-only nil) |
a7ec1775 RS |
3472 | (insert (format |
3473 | "TABLE-OF-CONTENTS on %s | |
396e0b08 | 3474 | SPC=view TAB=goto RET=goto+hide [q]uit [r]escan [f]ollow-mode e[x]tern [?]Help |
a7ec1775 RS |
3475 | ------------------------------------------------------------------------------- |
3476 | " (abbreviate-file-name reftex-last-toc-master))) | |
3477 | (setq startpos (point)) | |
3478 | ||
3479 | (if (reftex-use-fonts) | |
6b94c6ad | 3480 | (put-text-property 1 (point) 'face reftex-toc-header-face)) |
a7ec1775 | 3481 | (put-text-property 1 (point) 'intangible t) |
396e0b08 | 3482 | (put-text-property 1 2 'xr-alist xr-alist) |
a7ec1775 RS |
3483 | |
3484 | (while all | |
3485 | (setq cell (car all) | |
3486 | all (cdr all)) | |
396e0b08 KH |
3487 | (when (eq (car cell) 'toc) |
3488 | (setq toc1 (concat (nth 2 cell) "\n")) | |
3489 | (put-text-property 0 (length toc1) 'toc cell toc1) | |
b849548d CD |
3490 | (when fontify |
3491 | (put-text-property 0 (length toc1) | |
3492 | 'face reftex-section-heading-face toc1)) | |
29d593f8 KH |
3493 | (when mouse-face |
3494 | (put-text-property 0 (1- (length toc1)) | |
3495 | 'mouse-face mouse-face toc1)) | |
396e0b08 | 3496 | (insert toc1))) |
a7ec1775 RS |
3497 | |
3498 | (backward-delete-char 1) | |
3499 | ||
b849548d | 3500 | (run-hooks 'reftex-display-copied-context-hook) |
2faef409 | 3501 | (message "Building *toc* buffer...done.") |
a7ec1775 RS |
3502 | (setq buffer-read-only t)) |
3503 | (t | |
3504 | (goto-line 3) | |
3505 | (beginning-of-line) | |
3506 | (setq startpos (point)))) | |
3507 | ||
3508 | ;; Find the correct section | |
3509 | (goto-char (point-max)) | |
3510 | (beginning-of-line) | |
3511 | (while (and (> (point) startpos) | |
396e0b08 | 3512 | (not (eq (get-text-property (point) 'toc) where))) |
29d593f8 KH |
3513 | (beginning-of-line 0)) |
3514 | (setq reftex-last-follow-point (point)))) | |
a7ec1775 RS |
3515 | |
3516 | (defun reftex-nearest-section () | |
3517 | ;; Return (file . find) of nearest section command | |
396e0b08 KH |
3518 | (let* ((here-I-am (car (reftex-where-am-I)))) |
3519 | (reftex-last-assoc-before-elt | |
3520 | 'toc here-I-am (symbol-value reftex-docstruct-symbol)))) | |
a7ec1775 RS |
3521 | |
3522 | (defun reftex-toc-pre-command-hook () | |
3523 | ;; used as pre command hook in *toc* buffer | |
3524 | (reftex-unhighlight 0) | |
3525 | (reftex-unhighlight 1)) | |
3526 | ||
3527 | (defun reftex-toc-post-command-hook () | |
3528 | ;; used in the post-command-hook for the *toc* buffer | |
3529 | (and (> (point) 1) | |
29d593f8 | 3530 | (memq reftex-highlight-selection '(cursor both)) |
a7ec1775 | 3531 | (save-excursion |
396e0b08 KH |
3532 | (reftex-highlight 1 |
3533 | (progn (beginning-of-line) (point)) | |
3534 | (progn (end-of-line) (point))))) | |
a7ec1775 RS |
3535 | (cond |
3536 | ((integerp reftex-toc-follow-mode) | |
3537 | ;; remove delayed action | |
3538 | (setq reftex-toc-follow-mode t)) | |
29d593f8 KH |
3539 | ((and reftex-toc-follow-mode |
3540 | (not (equal reftex-last-follow-point (point)))) | |
a7ec1775 | 3541 | ;; show context in other window |
29d593f8 | 3542 | (setq reftex-last-follow-point (point)) |
a7ec1775 | 3543 | (condition-case nil |
2faef409 RS |
3544 | (reftex-toc-visit-line nil (not reftex-revisit-to-follow)) |
3545 | (error t))))) | |
206c6f82 | 3546 | |
206c6f82 | 3547 | (defun reftex-re-enlarge () |
b849548d | 3548 | ;; Enlarge windiw to a remembered size |
396e0b08 KH |
3549 | (enlarge-window |
3550 | (max 0 (- (or reftex-last-window-height (window-height)) | |
3551 | (window-height))))) | |
206c6f82 RS |
3552 | |
3553 | (defun reftex-toc-show-help () | |
b849548d | 3554 | "Show a summary of special key bindings." |
206c6f82 RS |
3555 | (interactive) |
3556 | (with-output-to-temp-buffer "*RefTeX Help*" | |
3557 | (princ reftex-toc-help)) | |
3558 | ;; If follow mode is active, arrange to delay it one command | |
3559 | (if reftex-toc-follow-mode | |
3560 | (setq reftex-toc-follow-mode 1))) | |
a7ec1775 RS |
3561 | |
3562 | (defun reftex-toc-toggle-follow () | |
b849548d | 3563 | "Toggle toc-follow mode. (It is not really a mode, just a flag)." |
a7ec1775 | 3564 | (interactive) |
b849548d | 3565 | (setq reftex-last-follow-point -1) |
a7ec1775 RS |
3566 | (setq reftex-toc-follow-mode (not reftex-toc-follow-mode))) |
3567 | (defun reftex-toc-view-line () | |
3568 | "View document location in other window." | |
3569 | (interactive) | |
3570 | (reftex-toc-visit-line)) | |
29d593f8 KH |
3571 | (defun reftex-toc-mouse-view-line (ev) |
3572 | "View document location in other window." | |
3573 | (interactive "e") | |
3574 | (mouse-set-point ev) | |
3575 | (reftex-toc-visit-line)) | |
a7ec1775 | 3576 | (defun reftex-toc-goto-line-and-hide () |
c52bdfca | 3577 | "Go to document location in other window. Hide the *toc* window." |
a7ec1775 RS |
3578 | (interactive) |
3579 | (reftex-toc-visit-line 'hide)) | |
206c6f82 RS |
3580 | (defun reftex-toc-goto-line () |
3581 | "Go to document location in other window. Hide the *toc* window." | |
3582 | (interactive) | |
3583 | (reftex-toc-visit-line t)) | |
3584 | (defun reftex-toc-mouse-goto-line-and-hide (ev) | |
3585 | "Go to document location in other window. Hide the *toc* window." | |
3586 | (interactive "e") | |
3587 | (mouse-set-point ev) | |
3588 | (reftex-toc-visit-line 'hide)) | |
b849548d CD |
3589 | (defun reftex-toc-show-insertion-point () |
3590 | (interactive) | |
3591 | (let ((this-window (selected-window))) | |
3592 | (unwind-protect | |
3593 | (progn | |
3594 | (switch-to-buffer-other-window | |
3595 | (marker-buffer reftex-toc-return-marker)) | |
3596 | (goto-char (marker-position reftex-toc-return-marker)) | |
a6611c0d | 3597 | (recenter '(4))) |
b849548d | 3598 | (select-window this-window)))) |
a7ec1775 RS |
3599 | (defun reftex-toc-quit () |
3600 | "Hide the *toc* window and do not move point." | |
3601 | (interactive) | |
206c6f82 | 3602 | (or (one-window-p) (delete-window)) |
a7ec1775 | 3603 | (switch-to-buffer (marker-buffer reftex-toc-return-marker)) |
206c6f82 | 3604 | (reftex-re-enlarge) |
396e0b08 | 3605 | (goto-char (or (marker-position reftex-toc-return-marker) (point)))) |
a7ec1775 RS |
3606 | (defun reftex-toc-quit-and-kill () |
3607 | "Kill the *toc* buffer." | |
3608 | (interactive) | |
3609 | (kill-buffer "*toc*") | |
206c6f82 | 3610 | (or (one-window-p) (delete-window)) |
a7ec1775 | 3611 | (switch-to-buffer (marker-buffer reftex-toc-return-marker)) |
206c6f82 | 3612 | (reftex-re-enlarge) |
a7ec1775 | 3613 | (goto-char (marker-position reftex-toc-return-marker))) |
2faef409 RS |
3614 | (defun reftex-toc-rescan (&rest ignore) |
3615 | "Regenerate the *toc* buffer by reparsing file of section at point." | |
396e0b08 KH |
3616 | (interactive) |
3617 | (if reftex-enable-partial-scans | |
3618 | (let ((file (nth 3 (get-text-property (point) 'toc)))) | |
3619 | (if (not file) | |
a6611c0d | 3620 | (error "Don't know which file to rescan. Try `R'") |
396e0b08 KH |
3621 | (switch-to-buffer-other-window |
3622 | (reftex-get-file-buffer-force file)) | |
3623 | (setq current-prefix-arg '(4)) | |
3624 | (reftex-toc))) | |
2faef409 | 3625 | (reftex-toc-Rescan)) |
396e0b08 | 3626 | (reftex-kill-temporary-buffers)) |
2faef409 | 3627 | (defun reftex-toc-Rescan (&rest ignore) |
396e0b08 | 3628 | "Regenerate the *toc* buffer by reparsing the entire document." |
a7ec1775 | 3629 | (interactive) |
206c6f82 RS |
3630 | (switch-to-buffer-other-window |
3631 | (reftex-get-file-buffer-force reftex-last-toc-file)) | |
396e0b08 | 3632 | (setq current-prefix-arg '(16)) |
a7ec1775 | 3633 | (reftex-toc)) |
2faef409 RS |
3634 | (defun reftex-toc-revert (&rest ignore) |
3635 | "Regenerate the *toc* from the internal lists." | |
3636 | (interactive) | |
3637 | (switch-to-buffer-other-window | |
3638 | (reftex-get-file-buffer-force reftex-last-toc-file)) | |
29d593f8 | 3639 | (reftex-erase-buffer "*toc*") |
2faef409 RS |
3640 | (setq current-prefix-arg nil) |
3641 | (reftex-toc)) | |
396e0b08 KH |
3642 | (defun reftex-toc-external (&rest ignore) |
3643 | "Switch to table of contents of an external document." | |
3644 | (interactive) | |
2faef409 RS |
3645 | (let* ((old-buf (current-buffer)) |
3646 | (xr-alist (get-text-property 1 'xr-alist)) | |
396e0b08 KH |
3647 | (xr-index (reftex-select-external-document |
3648 | xr-alist 0))) | |
3649 | (switch-to-buffer-other-window (or (reftex-get-file-buffer-force | |
3650 | (cdr (nth xr-index xr-alist))) | |
3651 | (error "Cannot switch document"))) | |
2faef409 RS |
3652 | (reftex-toc) |
3653 | (if (equal old-buf (current-buffer)) | |
3654 | (message "") | |
3655 | (message "Switched document")))) | |
a7ec1775 | 3656 | |
2faef409 | 3657 | (defun reftex-toc-visit-line (&optional final no-revisit) |
a7ec1775 RS |
3658 | ;; Visit the tex file corresponding to the toc entry on the current line. |
3659 | ;; If FINAL is t, stay there | |
3660 | ;; If FINAL is 'hide, hide the *toc* window. | |
396e0b08 KH |
3661 | ;; Otherwise, move cursor back into *toc* window. |
3662 | ;; This function is pretty clever about finding back a section heading, | |
3663 | ;; even if the buffer is not live, or things like outline, x-symbol etc. | |
3664 | ;; have been active. | |
3665 | ||
3666 | (let* ((toc (get-text-property (point) 'toc)) | |
3667 | (file (nth 3 toc)) | |
3668 | (marker (nth 4 toc)) | |
3669 | (level (nth 5 toc)) | |
3670 | (literal (nth 7 toc)) | |
3671 | (emergency-point (nth 8 toc)) | |
3672 | (toc-window (selected-window)) | |
3673 | show-window show-buffer match) | |
3674 | ||
3675 | (unless toc (error "Don't know which toc line to visit")) | |
3676 | ||
3677 | (setq match | |
3678 | (cond | |
3679 | ((and (markerp marker) (marker-buffer marker)) | |
3680 | ;; Buffer is still live and we have the marker. Should be easy. | |
3681 | (switch-to-buffer-other-window (marker-buffer marker)) | |
3682 | (goto-char (marker-position marker)) | |
3683 | (or (looking-at (regexp-quote literal)) | |
3684 | (looking-at (reftex-make-regexp-allow-for-ctrl-m literal)) | |
2faef409 | 3685 | (looking-at (reftex-make-desperate-section-regexp literal)) |
396e0b08 KH |
3686 | (looking-at (concat "\\\\" |
3687 | (regexp-quote | |
b849548d CD |
3688 | (car (rassq level |
3689 | reftex-section-levels-all))) | |
396e0b08 | 3690 | "[[{]")))) |
2faef409 | 3691 | ((or (not no-revisit) |
b849548d | 3692 | (reftex-get-buffer-visiting file)) |
396e0b08 KH |
3693 | ;; Marker is lost. Use the backup method. |
3694 | (switch-to-buffer-other-window | |
3695 | (reftex-get-file-buffer-force file nil)) | |
3696 | (goto-char (or emergency-point (point-min))) | |
3697 | (or (looking-at (regexp-quote literal)) | |
3698 | (let ((pos (point))) | |
3699 | (re-search-backward "\\`\\|[\r\n][ \t]*[\r\n]" nil t) | |
3700 | (or (reftex-nearest-match (regexp-quote literal) pos) | |
3701 | (reftex-nearest-match | |
3702 | (reftex-make-regexp-allow-for-ctrl-m literal) pos) | |
3703 | (reftex-nearest-match | |
2faef409 | 3704 | (reftex-make-desperate-section-regexp literal) pos))))) |
b849548d | 3705 | (t (message reftex-no-follow-message) nil) |
396e0b08 KH |
3706 | )) |
3707 | ||
3708 | (setq show-window (selected-window) | |
3709 | show-buffer (current-buffer)) | |
3710 | ||
3711 | (unless match | |
3712 | (select-window toc-window) | |
3713 | (error "Cannot find line")) | |
3714 | ||
3715 | (goto-char (match-beginning 0)) | |
a7ec1775 | 3716 | (recenter 1) |
396e0b08 | 3717 | (reftex-highlight 0 (match-beginning 0) (match-end 0) (current-buffer)) |
a7ec1775 RS |
3718 | |
3719 | (select-window toc-window) | |
3720 | ||
3721 | ;; use the `final' parameter to decide what to do next | |
3722 | (cond | |
206c6f82 | 3723 | ((eq final t) |
a7ec1775 RS |
3724 | (reftex-unhighlight 0) |
3725 | (select-window show-window)) | |
3726 | ((eq final 'hide) | |
3727 | (reftex-unhighlight 0) | |
206c6f82 RS |
3728 | (or (one-window-p) (delete-window)) |
3729 | (switch-to-buffer show-buffer) | |
3730 | (reftex-re-enlarge)) | |
a7ec1775 RS |
3731 | (t nil)))) |
3732 | ||
b849548d CD |
3733 | (defun reftex-make-desperate-section-regexp (old) |
3734 | ;; Return a regexp which will still match a section statement even if | |
3735 | ;; x-symbol or isotex or the like have been at work in the mean time. | |
3736 | (let* ((n (1+ (string-match "[[{]" old))) | |
3737 | (new (regexp-quote (substring old 0 (1+ (string-match "[[{]" old))))) | |
3738 | (old (substring old n))) | |
3739 | (while (string-match | |
3740 | "\\([\r\n]\\)\\|\\(\\`\\|[ \t\n\r]\\)\\([a-zA-Z0-9]+\\)\\([ \t\n\r]\\|}\\'\\)" | |
3741 | old) | |
3742 | (if (match-beginning 1) | |
3743 | (setq new (concat new "[^\n\r]*[\n\r]")) | |
3744 | (setq new (concat new "[^\n\r]*" (match-string 3 old)))) | |
3745 | (setq old (substring old (match-end 0)))) | |
3746 | new)) | |
3747 | ||
3748 | ;;; ========================================================================= | |
a7ec1775 RS |
3749 | ;;; |
3750 | ;;; BibTeX citations. | |
3751 | ||
3752 | ;; Variables and constants | |
3753 | ||
a7ec1775 RS |
3754 | ;; The history list of regular expressions used for citations |
3755 | (defvar reftex-cite-regexp-hist nil) | |
3756 | ||
206c6f82 RS |
3757 | ;; Prompt and help string for citation selection |
3758 | (defconst reftex-citation-prompt | |
3759 | "Select: [n]ext [p]revious [r]estrict [ ]full_entry [q]uit RET [?]Help+more") | |
3760 | ||
a7ec1775 | 3761 | (defconst reftex-citation-help |
2faef409 | 3762 | " n / p Go to next/previous entry (Cursor motion works as well). |
206c6f82 | 3763 | C-s / C-r Search forward/backward. Use repeated C-s/C-r as in isearch. |
2faef409 | 3764 | g / r Start over with new regexp / Refine with additional regexp. |
206c6f82 RS |
3765 | SPC Show full database entry in other window. |
3766 | f Toggle follow mode: Other window will follow with full db entry. | |
29d593f8 | 3767 | . Show insertion point. |
206c6f82 | 3768 | q Quit without inserting \\cite macro into buffer. |
2faef409 | 3769 | TAB Enter citation key with completion. |
29d593f8 | 3770 | RET Accept current entry (also on mouse-2) |
b849548d | 3771 | a / A Put all entries into single \cite / into many cite commands.") |
a7ec1775 | 3772 | |
2faef409 RS |
3773 | (defvar reftex-select-bib-map nil |
3774 | "Keymap used for *RefTeX Select* buffer, when selecting a BibTeX entry. | |
3775 | This keymap can be used to configure the BibTeX selection process which is | |
3776 | started with the command \\[reftex-citation].") | |
3777 | ||
29d593f8 KH |
3778 | (defun reftex-select-bib-mode () |
3779 | "Major mode for selecting a citation key in a LaTeX document. | |
3780 | This buffer was created with RefTeX. | |
3781 | It only has a meaningful keymap when you are in the middle of a | |
3782 | selection process. | |
3783 | In order to select a citation, move the cursor to it and press RET. | |
3784 | Press `?' for a summary of important key bindings. | |
3785 | ||
3786 | During a selection process, these are the local bindings. | |
3787 | ||
3788 | \\{reftex-select-label-map}" | |
3789 | (interactive) | |
3790 | (kill-all-local-variables) | |
3791 | (make-local-hook 'pre-command-hook) | |
3792 | (make-local-hook 'post-command-hook) | |
3793 | (setq major-mode 'reftex-select-bib-mode | |
3794 | mode-name "RefTeX Select Bib") | |
3795 | ;; We do not set a local map - reftex-select-item does this. | |
3796 | (run-hooks 'reftex-select-bib-mode-hook)) | |
3797 | ||
a7ec1775 RS |
3798 | ;; Find bibtex files |
3799 | ||
3800 | (defun reftex-get-bibfile-list () | |
396e0b08 KH |
3801 | ;; Return list of bibfiles for current document. |
3802 | ;; When using the chapterbib or bibunits package you should either | |
3803 | ;; use the same database files everywhere, or separate parts using | |
3804 | ;; different databases into different files (included into the mater file). | |
3805 | ;; Then this function will return the applicable database files. | |
a7ec1775 RS |
3806 | |
3807 | ;; Ensure access to scanning info | |
3808 | (reftex-access-scan-info) | |
396e0b08 KH |
3809 | (or |
3810 | ;; Try inside this file (and its includes) | |
3811 | (cdr (reftex-last-assoc-before-elt | |
3812 | 'bib (list 'eof (buffer-file-name)) | |
3813 | (member (list 'bof (buffer-file-name)) | |
3814 | (symbol-value reftex-docstruct-symbol)))) | |
3815 | ;; Try after the beginning of this file | |
3816 | (cdr (assq 'bib (member (list 'bof (buffer-file-name)) | |
3817 | (symbol-value reftex-docstruct-symbol)))) | |
3818 | ;; Anywhere in the entire document | |
3819 | (cdr (assq 'bib (symbol-value reftex-docstruct-symbol))) | |
2faef409 | 3820 | (error "\\bibliography statement missing or .bib files not found."))) |
396e0b08 | 3821 | |
a7ec1775 RS |
3822 | ;; Find a certain reference in any of the BibTeX files. |
3823 | ||
b849548d CD |
3824 | (defun reftex-pop-to-bibtex-entry (key file-list &optional mark-to-kill |
3825 | highlight item return) | |
a7ec1775 | 3826 | ;; Find BibTeX KEY in any file in FILE-LIST in another window. |
2faef409 RS |
3827 | ;; If MARK-TO-KILL is non-nil, mark new buffer to kill. |
3828 | ;; If HIGHLIGHT is non-nil, highlight the match. | |
3829 | ;; If ITEM in non-nil, search for bibitem instead of database entry. | |
a6611c0d | 3830 | ;; If RETURN is non-nil, just return the entry. |
2faef409 RS |
3831 | |
3832 | (let* ((re | |
3833 | (if item | |
3834 | (concat "\\\\bibitem\\(\\[[^]]*\\]\\)?{" (regexp-quote key) "}") | |
b849548d CD |
3835 | (concat "@[a-zA-Z]+[ \t\n\r]*[{(][ \t\n\r]*" (regexp-quote key) |
3836 | "[, \t\r\n}]"))) | |
a7ec1775 RS |
3837 | (window-conf (current-window-configuration)) |
3838 | file buf) | |
2faef409 | 3839 | |
a7ec1775 RS |
3840 | (catch 'exit |
3841 | (switch-to-buffer-other-window (current-buffer)) | |
3842 | (while file-list | |
3843 | (setq file (car file-list) | |
3844 | file-list (cdr file-list)) | |
396e0b08 KH |
3845 | (unless (setq buf (reftex-get-file-buffer-force file mark-to-kill)) |
3846 | (error "No such file %s" file)) | |
a7ec1775 RS |
3847 | (switch-to-buffer buf) |
3848 | (widen) | |
396e0b08 KH |
3849 | (goto-char (point-min)) |
3850 | (when (re-search-forward re nil t) | |
3851 | (goto-char (match-beginning 0)) | |
b849548d CD |
3852 | (when return |
3853 | ;; Just return the relevant entry | |
a6611c0d CD |
3854 | (if item (goto-char (match-end 0))) |
3855 | (setq return (buffer-substring | |
3856 | (point) (reftex-end-of-bib-entry item))) | |
b849548d CD |
3857 | (set-window-configuration window-conf) |
3858 | (throw 'exit return)) | |
396e0b08 KH |
3859 | (recenter 0) |
3860 | (if highlight | |
3861 | (reftex-highlight 0 (match-beginning 0) (match-end 0))) | |
3862 | (throw 'exit (selected-window)))) | |
a7ec1775 | 3863 | (set-window-configuration window-conf) |
2faef409 | 3864 | (if item |
b849548d CD |
3865 | (error "No \\bibitem with citation key %s" key) |
3866 | (error "No BibTeX entry with citation key %s" key))))) | |
a7ec1775 | 3867 | |
a6611c0d CD |
3868 | (defun reftex-end-of-bib-entry (item) |
3869 | (save-excursion | |
3870 | (condition-case nil | |
3871 | (if item | |
3872 | (progn (end-of-line) | |
3873 | (re-search-forward | |
3874 | "\\\\bibitem\\|\\end{thebibliography}") | |
3875 | (1- (match-beginning 0))) | |
3876 | (progn (forward-list 1) (point))) | |
3877 | (error (min (point-max) (+ 300 (point))))))) | |
3878 | ||
a7ec1775 RS |
3879 | ;; Parse bibtex buffers |
3880 | ||
b849548d | 3881 | (defun reftex-extract-bib-entries (buffers) |
a7ec1775 RS |
3882 | ;; Extract bib entries which match regexps from BUFFERS. |
3883 | ;; BUFFERS is a list of buffers or file names. | |
3884 | ;; Return list with entries." | |
3885 | (let* (re-list first-re rest-re | |
a7ec1775 RS |
3886 | (buffer-list (if (listp buffers) buffers (list buffers))) |
3887 | found-list entry buffer1 buffer alist | |
3888 | key-point start-point end-point) | |
3889 | ||
b849548d CD |
3890 | ;; Read a regexp, completing on known citation keys. |
3891 | (setq re-list | |
3892 | (split-string | |
3893 | (completing-read | |
3894 | "RegExp [ && RegExp...]: " | |
3895 | (if (fboundp 'LaTeX-bibitem-list) | |
3896 | (LaTeX-bibitem-list) | |
3897 | (cdr (assoc 'bibview-cache | |
3898 | (symbol-value reftex-docstruct-symbol)))) | |
3899 | nil nil nil 'reftex-cite-regexp-hist) | |
3900 | "[ \t]*&&[ \t]*")) | |
a7ec1775 RS |
3901 | |
3902 | (setq first-re (car re-list) ; We'll use the first re to find things, | |
2faef409 | 3903 | rest-re (cdr re-list)) ; the others to narrow down. |
a7ec1775 RS |
3904 | (if (string-match "\\`[ \t]*\\'" first-re) |
3905 | (error "Empty regular expression")) | |
3906 | ||
3907 | (save-excursion | |
3908 | (save-window-excursion | |
3909 | ||
396e0b08 | 3910 | ;; Walk through all bibtex files |
a7ec1775 RS |
3911 | (while buffer-list |
3912 | (setq buffer (car buffer-list) | |
3913 | buffer-list (cdr buffer-list)) | |
3914 | (if (and (bufferp buffer) | |
3915 | (buffer-live-p buffer)) | |
3916 | (setq buffer1 buffer) | |
3917 | (setq buffer1 (reftex-get-file-buffer-force | |
3918 | buffer (not reftex-keep-temporary-buffers)))) | |
3919 | (if (not buffer1) | |
3920 | (error "Cannot find BibTeX file %s" buffer) | |
3921 | (message "Scanning bibliography database %s" buffer1)) | |
3922 | ||
3923 | (set-buffer buffer1) | |
396e0b08 KH |
3924 | (save-excursion |
3925 | (goto-char (point-min)) | |
3926 | (while (re-search-forward first-re nil t) | |
3927 | (catch 'search-again | |
3928 | (setq key-point (point)) | |
3929 | (unless (re-search-backward | |
3930 | "\\(\\`\\|[\n\r]\\)[ \t]*@\\([a-zA-Z]+\\)[ \t\n\r]*[{(]" nil t) | |
3931 | (throw 'search-again nil)) | |
3932 | (setq start-point (point)) | |
3933 | (goto-char (match-end 0)) | |
3934 | (condition-case nil | |
3935 | (up-list 1) | |
3936 | (error (goto-char key-point) | |
3937 | (throw 'search-again nil))) | |
3938 | (setq end-point (point)) | |
3939 | ||
3940 | ;; Ignore @string, @comment and @c entries or things | |
3941 | ;; outside entries | |
3942 | (when (or (string= (downcase (match-string 2)) "string") | |
3943 | (string= (downcase (match-string 2)) "comment") | |
3944 | (string= (downcase (match-string 2)) "c") | |
3945 | (< (point) key-point)) ; this means match not in {} | |
3946 | (goto-char key-point) | |
3947 | (throw 'search-again nil)) | |
3948 | ||
3949 | ;; Well, we have got a match | |
3950 | (setq entry (concat | |
3951 | (buffer-substring start-point (point)) "\n")) | |
3952 | ||
3953 | ;; Check if other regexp match as well | |
3954 | (setq re-list rest-re) | |
3955 | (while re-list | |
3956 | (unless (string-match (car re-list) entry) | |
3957 | ;; nope - move on | |
3958 | (throw 'search-again nil)) | |
3959 | (pop re-list)) | |
3960 | ||
3961 | (setq alist (reftex-parse-bibtex-entry | |
3962 | nil start-point end-point)) | |
3963 | (push (cons "&entry" entry) alist) | |
3964 | ||
3965 | ;; check for crossref entries | |
3966 | (if (assoc "crossref" alist) | |
3967 | (setq alist | |
3968 | (append | |
3969 | alist (reftex-get-crossref-alist alist)))) | |
3970 | ||
3971 | ;; format the entry | |
3972 | (push (cons "&formatted" (reftex-format-bib-entry alist)) | |
3973 | alist) | |
3974 | ||
b849548d CD |
3975 | ;; make key the first element |
3976 | (push (reftex-get-bib-field "&key" alist) alist) | |
3977 | ||
396e0b08 KH |
3978 | ;; add it to the list |
3979 | (push alist found-list)))) | |
a7ec1775 RS |
3980 | (reftex-kill-temporary-buffers)))) |
3981 | (setq found-list (nreverse found-list)) | |
396e0b08 | 3982 | |
a7ec1775 | 3983 | ;; Sorting |
396e0b08 | 3984 | (cond |
a7ec1775 RS |
3985 | ((eq 'author reftex-sort-bibtex-matches) |
3986 | (sort found-list 'reftex-bib-sort-author)) | |
3987 | ((eq 'year reftex-sort-bibtex-matches) | |
3988 | (sort found-list 'reftex-bib-sort-year)) | |
3989 | ((eq 'reverse-year reftex-sort-bibtex-matches) | |
3990 | (sort found-list 'reftex-bib-sort-year-reverse)) | |
3991 | (t found-list)))) | |
3992 | ||
3993 | (defun reftex-bib-sort-author (e1 e2) | |
206c6f82 | 3994 | (let ((al1 (reftex-get-bib-names "author" e1)) |
396e0b08 | 3995 | (al2 (reftex-get-bib-names "author" e2))) |
a7ec1775 | 3996 | (while (and al1 al2 (string= (car al1) (car al2))) |
396e0b08 KH |
3997 | (pop al1) |
3998 | (pop al2)) | |
a7ec1775 | 3999 | (if (and (stringp (car al1)) |
396e0b08 KH |
4000 | (stringp (car al2))) |
4001 | (string< (car al1) (car al2)) | |
a7ec1775 RS |
4002 | (not (stringp (car al1)))))) |
4003 | ||
4004 | (defun reftex-bib-sort-year (e1 e2) | |
4005 | (< (string-to-int (cdr (assoc "year" e1))) | |
4006 | (string-to-int (cdr (assoc "year" e2))))) | |
4007 | ||
4008 | (defun reftex-bib-sort-year-reverse (e1 e2) | |
4009 | (> (string-to-int (or (cdr (assoc "year" e1)) "0")) | |
4010 | (string-to-int (or (cdr (assoc "year" e2)) "0")))) | |
4011 | ||
4012 | (defun reftex-get-crossref-alist (entry) | |
4013 | ;; return the alist from a crossref entry | |
4014 | (let ((crkey (cdr (assoc "crossref" entry))) | |
4015 | start) | |
4016 | (save-excursion | |
4017 | (save-restriction | |
4018 | (widen) | |
4019 | (if (re-search-forward | |
396e0b08 KH |
4020 | (concat "@\\w+[{(][ \t\n\r]*" (regexp-quote crkey) |
4021 | "[ \t\n\r]*,") nil t) | |
a7ec1775 RS |
4022 | (progn |
4023 | (setq start (match-beginning 0)) | |
4024 | (condition-case nil | |
4025 | (up-list 1) | |
206c6f82 | 4026 | (error nil)) |
a7ec1775 RS |
4027 | (reftex-parse-bibtex-entry nil start (point))) |
4028 | nil))))) | |
4029 | ||
2faef409 RS |
4030 | ;; Parse the thebibliography environment |
4031 | (defun reftex-extract-bib-entries-from-thebibliography (file) | |
4032 | ;; Extract bib-entries from the \begin{thebibliography} environment. | |
4033 | ;; Parsing is not as good as for the BibTeX database stuff. | |
4034 | ;; The environment should be located in file FILE. | |
4035 | ||
4036 | (let* (start end buf entries re re-list) | |
4037 | (unless file | |
4038 | (error "Need file name to find thebibliography environment")) | |
4039 | (setq buf (reftex-get-file-buffer-force | |
4040 | file (not reftex-keep-temporary-buffers))) | |
4041 | (unless buf | |
4042 | (error "No such file %s" file)) | |
4043 | (message "Scanning thebibliography environment in %s" file) | |
4044 | ||
4045 | (save-excursion | |
4046 | (set-buffer buf) | |
4047 | (save-restriction | |
4048 | (widen) | |
4049 | (goto-char (point-min)) | |
4050 | (if (re-search-forward | |
4051 | "\\(\\`\\|[\n\r]\\)[ \t]*\\\\begin{thebibliography}" nil t) | |
4052 | (progn | |
4053 | (beginning-of-line 2) | |
4054 | (setq start (point)))) | |
4055 | (if (re-search-forward | |
4056 | "\\(\\`\\|[\n\r]\\)[ \t]*\\\\end{thebibliography}" nil t) | |
4057 | (progn | |
4058 | (beginning-of-line 1) | |
4059 | (setq end (point)))) | |
b849548d | 4060 | (when (and start end) |
2faef409 RS |
4061 | (setq entries |
4062 | (mapcar 'reftex-parse-bibitem | |
4063 | (delete "" | |
4064 | (split-string | |
4065 | (buffer-substring-no-properties start end) | |
4066 | "[ \t\n\r]*\\\\bibitem\\(\\[[^]]*]\\)*"))))))) | |
4067 | (unless entries | |
4068 | (error "No bibitems found")) | |
4069 | ||
4070 | (setq re-list (split-string | |
4071 | (read-string "RegExp [ && RegExp...]: " | |
4072 | nil 'reftex-cite-regexp-hist) | |
4073 | "[ \t]*&&[ \t]*")) | |
4074 | (if (string-match "\\`[ \t]*\\'" (car re-list)) | |
4075 | (error "Empty regular expression")) | |
4076 | ||
4077 | (while (and (setq re (pop re-list)) entries) | |
4078 | (setq entries | |
b849548d CD |
4079 | (delq nil (mapcar |
4080 | (function | |
4081 | (lambda (x) | |
4082 | (if (string-match re (cdr (assoc "&entry" x))) | |
4083 | x nil))) | |
4084 | entries)))) | |
2faef409 RS |
4085 | (setq entries |
4086 | (mapcar | |
2faef409 | 4087 | (lambda (x) |
b849548d CD |
4088 | (push (cons "&formatted" (reftex-format-bibitem x)) x) |
4089 | (push (reftex-get-bib-field "&key" x) x) | |
4090 | x) | |
2faef409 RS |
4091 | entries)) |
4092 | ||
4093 | entries)) | |
4094 | ||
a7ec1775 RS |
4095 | ;; Parse and format individual entries |
4096 | ||
206c6f82 | 4097 | (defun reftex-get-bib-names (field entry) |
2faef409 | 4098 | ;; Return a list with the author or editor names in ENTRY |
206c6f82 RS |
4099 | (let ((names (reftex-get-bib-field field entry))) |
4100 | (if (equal "" names) | |
4101 | (setq names (reftex-get-bib-field "editor" entry))) | |
4102 | (while (string-match "\\band\\b[ \t]*" names) | |
4103 | (setq names (replace-match "\n" nil t names))) | |
4104 | (while (string-match "[\\.a-zA-Z\\-]+\\.[ \t]*\\|,.*\\|[{}]+" names) | |
4105 | (setq names (replace-match "" nil t names))) | |
4106 | (while (string-match "^[ \t]+\\|[ \t]+$" names) | |
4107 | (setq names (replace-match "" nil t names))) | |
4108 | (while (string-match "[ \t][ \t]+" names) | |
4109 | (setq names (replace-match " " nil t names))) | |
396e0b08 | 4110 | (split-string names "\n"))) |
a7ec1775 RS |
4111 | |
4112 | (defun reftex-parse-bibtex-entry (entry &optional from to) | |
4113 | (let (alist key start field) | |
4114 | (save-excursion | |
4115 | (save-restriction | |
4116 | (if entry | |
4117 | (progn | |
b849548d | 4118 | (set-buffer (get-buffer-create " *RefTeX-scratch*")) |
a7ec1775 RS |
4119 | (fundamental-mode) |
4120 | (erase-buffer) | |
4121 | (insert entry)) | |
4122 | (widen) | |
4123 | (narrow-to-region from to)) | |
4124 | (goto-char (point-min)) | |
4125 | ||
396e0b08 | 4126 | (if (re-search-forward |
c52bdfca | 4127 | "@\\(\\w+\\)[ \t\n\r]*[{(][ \t\n\r]*\\([^ \t\n\r,]+\\)" nil t) |
a7ec1775 RS |
4128 | (setq alist |
4129 | (list | |
396e0b08 KH |
4130 | (cons "&type" (downcase (reftex-match-string 1))) |
4131 | (cons "&key" (reftex-match-string 2))))) | |
a7ec1775 | 4132 | (while (re-search-forward "\\(\\w+\\)[ \t\n\r]*=[ \t\n\r]*" nil t) |
396e0b08 | 4133 | (setq key (downcase (reftex-match-string 1))) |
a7ec1775 RS |
4134 | (cond |
4135 | ((= (following-char) ?{) | |
4136 | (forward-char 1) | |
4137 | (setq start (point)) | |
4138 | (condition-case nil | |
4139 | (up-list 1) | |
206c6f82 | 4140 | (error nil))) |
a7ec1775 RS |
4141 | ((= (following-char) ?\") |
4142 | (forward-char 1) | |
4143 | (setq start (point)) | |
4144 | (while (and (search-forward "\"" nil t) | |
4145 | (= ?\\ (char-after (- (point) 2)))))) | |
4146 | (t | |
4147 | (setq start (point)) | |
b849548d | 4148 | (re-search-forward "[ \t]*[\n\r,}]" nil 1))) |
a7ec1775 | 4149 | (setq field (buffer-substring-no-properties start (1- (point)))) |
2faef409 | 4150 | ;; remove extra whitespace |
a7ec1775 RS |
4151 | (while (string-match "[\n\t\r]\\|[ \t][ \t]+" field) |
4152 | (setq field (replace-match " " nil t field))) | |
4153 | ;; remove leading garbage | |
4154 | (if (string-match "^[ \t{]+" field) | |
4155 | (setq field (replace-match "" nil t field))) | |
4156 | ;; remove trailing garbage | |
4157 | (if (string-match "[ \t}]+$" field) | |
4158 | (setq field (replace-match "" nil t field))) | |
396e0b08 KH |
4159 | (push (cons key field) alist)))) |
4160 | alist)) | |
a7ec1775 | 4161 | |
b849548d | 4162 | (defun reftex-get-bib-field (fieldname entry &optional format) |
a7ec1775 | 4163 | ;; Extract the field FIELDNAME from an ENTRY |
b849548d CD |
4164 | (let ((cell (assoc fieldname entry))) |
4165 | (if cell | |
4166 | (if format | |
4167 | (format format (cdr cell)) | |
4168 | (cdr cell)) | |
4169 | ""))) | |
a7ec1775 RS |
4170 | |
4171 | (defun reftex-format-bib-entry (entry) | |
4172 | ;; Format a BibTeX ENTRY so that it is nice to look at | |
4173 | (let* | |
396e0b08 | 4174 | ((auth-list (reftex-get-bib-names "author" entry)) |
2faef409 | 4175 | (authors (mapconcat 'identity auth-list ", ")) |
a7ec1775 RS |
4176 | (year (reftex-get-bib-field "year" entry)) |
4177 | (title (reftex-get-bib-field "title" entry)) | |
4178 | (type (reftex-get-bib-field "&type" entry)) | |
4179 | (key (reftex-get-bib-field "&key" entry)) | |
4180 | (extra | |
4181 | (cond | |
4182 | ((equal type "article") | |
4183 | (concat (reftex-get-bib-field "journal" entry) " " | |
4184 | (reftex-get-bib-field "volume" entry) ", " | |
4185 | (reftex-get-bib-field "pages" entry))) | |
4186 | ((equal type "book") | |
4187 | (concat "book (" (reftex-get-bib-field "publisher" entry) ")")) | |
4188 | ((equal type "phdthesis") | |
4189 | (concat "PhD: " (reftex-get-bib-field "school" entry))) | |
4190 | ((equal type "mastersthesis") | |
4191 | (concat "Master: " (reftex-get-bib-field "school" entry))) | |
4192 | ((equal type "inbook") | |
4193 | (concat "Chap: " (reftex-get-bib-field "chapter" entry) | |
4194 | ", pp. " (reftex-get-bib-field "pages" entry))) | |
4195 | ((or (equal type "conference") | |
4196 | (equal type "incollection") | |
4197 | (equal type "inproceedings")) | |
b849548d | 4198 | (reftex-get-bib-field "booktitle" entry "in: %s")) |
a7ec1775 | 4199 | (t "")))) |
396e0b08 KH |
4200 | (setq authors (reftex-truncate authors 30 t t)) |
4201 | (when (reftex-use-fonts) | |
b849548d CD |
4202 | (put-text-property 0 (length key) 'face |
4203 | (reftex-verified-face reftex-label-face | |
4204 | 'font-lock-constant-face | |
4205 | 'font-lock-reference-face) | |
4206 | key) | |
6b94c6ad | 4207 | (put-text-property 0 (length authors) 'face reftex-bib-author-face |
396e0b08 | 4208 | authors) |
6b94c6ad CD |
4209 | (put-text-property 0 (length year) 'face reftex-bib-year-face |
4210 | year) | |
4211 | (put-text-property 0 (length title) 'face reftex-bib-title-face | |
396e0b08 | 4212 | title) |
6b94c6ad | 4213 | (put-text-property 0 (length extra) 'face reftex-bib-extra-face |
396e0b08 KH |
4214 | extra)) |
4215 | (concat key "\n " authors " " year " " extra "\n " title "\n\n"))) | |
a7ec1775 | 4216 | |
2faef409 RS |
4217 | (defun reftex-parse-bibitem (item) |
4218 | ;; Parse a \bibitem entry | |
4219 | (let ((key "") (text "")) | |
4220 | (when (string-match "\\`{\\([^}]+\\)}\\([\001-\255]*\\)" item) | |
4221 | (setq key (match-string 1 item) | |
4222 | text (match-string 2 item))) | |
4223 | ;; Clean up the text a little bit | |
4224 | (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text) | |
4225 | (setq text (replace-match " " nil t text))) | |
4226 | (if (string-match "\\`[ \t]+" text) | |
4227 | (setq text (replace-match "" nil t text))) | |
4228 | (list | |
4229 | (cons "&key" key) | |
4230 | (cons "&text" text) | |
4231 | (cons "&entry" (concat key " " text))))) | |
4232 | ||
4233 | (defun reftex-format-bibitem (item) | |
4234 | ;; Format a \bibitem entry so that it is (relatively) nice to look at. | |
4235 | (let ((text (reftex-get-bib-field "&text" item)) | |
4236 | (key (reftex-get-bib-field "&key" item)) | |
4237 | (lines nil)) | |
4238 | ||
4239 | ;; Wrap the text into several lines. | |
4240 | (while (and (> (length text) 70) | |
4241 | (string-match " " (substring text 60))) | |
4242 | (push (substring text 0 (+ 60 (match-beginning 0))) lines) | |
4243 | (setq text (substring text (+ 61 (match-beginning 0))))) | |
4244 | (push text lines) | |
4245 | (setq text (mapconcat 'identity (nreverse lines) "\n ")) | |
4246 | ||
4247 | (when (reftex-use-fonts) | |
6b94c6ad | 4248 | (put-text-property 0 (length text) 'face reftex-bib-author-face text)) |
2faef409 RS |
4249 | (concat key "\n " text "\n\n"))) |
4250 | ||
a7ec1775 RS |
4251 | ;; Make a citation |
4252 | ||
b849548d | 4253 | ;;;###autoload |
396e0b08 | 4254 | (defun reftex-citation (&optional no-insert) |
c52bdfca | 4255 | "Make a citation using BibTeX database files. |
a7ec1775 RS |
4256 | After asking for a Regular Expression, it scans the buffers with |
4257 | bibtex entries (taken from the \\bibliography command) and offers the | |
c52bdfca RS |
4258 | matching entries for selection. The selected entry is formated according |
4259 | to `reftex-cite-format' and inserted into the buffer. | |
a7ec1775 | 4260 | If NO-INSERT is non-nil, nothing is inserted, only the selected key returned. |
c52bdfca RS |
4261 | The regular expression uses an expanded syntax: && is interpreted as `and'. |
4262 | Thus, `aaaa&&bbb' matches entries which contain both `aaaa' and `bbb'. | |
b849548d | 4263 | While entering the regexp, completion on knows citation keys is possible. |
fba437e6 | 4264 | When this function is called with point inside the braces of a \\cite |
c52bdfca | 4265 | command, it will add another key, ignoring the value of `reftex-cite-format'. |
a7ec1775 | 4266 | When called with a numeric prefix, that many citations will be made and all |
fba437e6 | 4267 | put into the same \\cite command. |
b849548d | 4268 | When called with just or two C-u as prefix, enforces rescan of buffer for |
a7ec1775 RS |
4269 | bibliography statement (e.g. if it was changed)." |
4270 | ||
396e0b08 | 4271 | (interactive) |
a7ec1775 RS |
4272 | |
4273 | ;; check for recursive edit | |
4274 | (reftex-check-recursive-edit) | |
4275 | ||
b849548d CD |
4276 | ;; This function may also be called outside reftex-mode. |
4277 | ;; Thus look for the scanning info only if in reftex-mode. | |
4278 | ||
4279 | (when reftex-mode | |
4280 | (reftex-access-scan-info current-prefix-arg)) | |
396e0b08 KH |
4281 | |
4282 | ;; Call reftex-do-citation, but protected | |
4283 | (unwind-protect | |
4284 | (reftex-do-citation current-prefix-arg no-insert) | |
4285 | (reftex-kill-temporary-buffers))) | |
a7ec1775 | 4286 | |
396e0b08 KH |
4287 | (defun reftex-do-citation (&optional arg no-insert) |
4288 | ;; This really does the work of reftex-citation. | |
4289 | ||
b849548d CD |
4290 | (let* ((format (reftex-figure-out-cite-format arg no-insert)) |
4291 | (docstruct-symbol reftex-docstruct-symbol) | |
4292 | (selected-entries (reftex-offer-bib-menu)) | |
4293 | (insert-entries selected-entries) | |
4294 | entry string cite-view) | |
4295 | ||
4296 | (unless selected-entries (error "Quit")) | |
4297 | ||
4298 | (if (stringp selected-entries) | |
4299 | ;; Nonexistent entry | |
4300 | (setq selected-entries nil | |
4301 | insert-entries (list (list selected-entries | |
4302 | (cons "&key" selected-entries)))) | |
4303 | ;; It makes sense to compute the cite-view strings. | |
4304 | (setq cite-view t)) | |
4305 | ||
4306 | (when (eq (car selected-entries) 'concat) | |
4307 | ;; All keys go into a single command - we need to trick a little | |
4308 | (pop selected-entries) | |
4309 | (let ((concat-keys (mapconcat 'car selected-entries ","))) | |
4310 | (setq insert-entries | |
4311 | (list (list concat-keys (cons "&key" concat-keys)))))) | |
4312 | ||
4313 | (unless no-insert | |
4314 | ||
4315 | ;; We shall insert this into the buffer... | |
4316 | (message "Formatting...") | |
4317 | ||
4318 | (while (setq entry (pop insert-entries)) | |
4319 | ;; Format the citation and insert it | |
4320 | (setq string (if reftex-format-cite-function | |
4321 | (funcall reftex-format-cite-function | |
4322 | (reftex-get-bib-field "&key" entry) | |
4323 | format) | |
4324 | (reftex-format-citation entry format))) | |
4325 | (insert string)) | |
4326 | ||
4327 | ;; Reposition cursor? | |
4328 | (when (string-match "\\?" string) | |
4329 | (search-backward "?") | |
4330 | (delete-char 1)) | |
4331 | ||
4332 | ;; Tell AUCTeX | |
a6611c0d CD |
4333 | (when (and reftex-mode |
4334 | (fboundp 'LaTeX-add-bibitems) | |
4335 | reftex-plug-into-AUCTeX) | |
b849548d CD |
4336 | (apply 'LaTeX-add-bibitems (mapcar 'car selected-entries))) |
4337 | ||
4338 | ;; Produce the cite-view strings | |
a6611c0d | 4339 | (when (and reftex-mode reftex-cache-cite-echo cite-view) |
b849548d CD |
4340 | (mapcar (lambda (entry) |
4341 | (reftex-make-cite-echo-string entry docstruct-symbol)) | |
4342 | selected-entries)) | |
4343 | ||
4344 | (message "")) | |
4345 | ||
4346 | (set-marker reftex-select-return-marker nil) | |
4347 | (reftex-kill-buffer "*RefTeX Select*") | |
4348 | ||
4349 | ;; Check if the prefix arg was numeric, and call recursively | |
4350 | (when (integerp arg) | |
4351 | (if (> arg 1) | |
4352 | (progn | |
4353 | (skip-chars-backward "}") | |
4354 | (decf arg) | |
4355 | (reftex-do-citation arg)) | |
4356 | (forward-char 1))) | |
4357 | ||
4358 | ;; Return the citation key | |
4359 | (car (car selected-entries)))) | |
4360 | ||
4361 | (defun reftex-figure-out-cite-format (arg no-insert) | |
396e0b08 | 4362 | ;; Check if there is already a cite command at point and change cite format |
a7ec1775 | 4363 | ;; in order to only add another reference in the same cite command. |
b849548d CD |
4364 | (let ((macro (car (reftex-what-macro 1))) |
4365 | (cite-format-value (reftex-get-cite-format)) | |
4366 | key format) | |
4367 | (cond | |
4368 | (no-insert | |
4369 | ;; Format does not really matter because nothing will be inserted. | |
4370 | (setq format "%l")) | |
4371 | ||
4372 | ((and (stringp macro) | |
4373 | (string-match "\\`\\\\cite\\|cite\\'" macro)) | |
4374 | ;; We are already inside a cite macro | |
4375 | (if (or (not arg) (not (listp arg))) | |
4376 | (setq format | |
4377 | (concat | |
4378 | (if (member (preceding-char) '(?\{ ?,)) "" ",") | |
4379 | "%l" | |
4380 | (if (member (following-char) '(?\} ?,)) "" ","))) | |
4381 | (setq format "%l"))) | |
4382 | (t | |
4383 | ;; Figure out the correct format | |
206c6f82 | 4384 | (setq format |
b849548d CD |
4385 | (if (and (symbolp cite-format-value) |
4386 | (assq cite-format-value reftex-cite-format-builtin)) | |
4387 | (nth 2 (assq cite-format-value reftex-cite-format-builtin)) | |
4388 | cite-format-value)) | |
4389 | (when (listp format) | |
4390 | (setq key | |
4391 | (reftex-select-with-char | |
4392 | "" (concat "SELECT A CITATION FORMAT\n\n" | |
4393 | (mapconcat | |
4394 | (lambda (x) | |
4395 | (format "[%c] %s %s" (car x) | |
4396 | (if (> (car x) 31) " " "") | |
4397 | (cdr x))) | |
4398 | format "\n")))) | |
4399 | (if (assq key format) | |
4400 | (setq format (cdr (assq key format))) | |
4401 | (error "No citation format associated with key `%c'" key))))) | |
4402 | format)) | |
4403 | ||
4404 | (defun reftex-get-cite-format () | |
4405 | ;; Return the current citation format. Either the document-local value in | |
4406 | ;; reftex-cite-format-symbol, or the global value in reftex-cite-format. | |
4407 | (if (and reftex-docstruct-symbol | |
4408 | (symbolp reftex-docstruct-symbol) | |
4409 | (get reftex-docstruct-symbol 'reftex-cite-format)) | |
4410 | (get reftex-docstruct-symbol 'reftex-cite-format) | |
4411 | reftex-cite-format)) | |
4412 | ||
4413 | (defun reftex-offer-bib-menu () | |
4414 | ;; Offer bib menu and return list of selected items | |
4415 | ||
4416 | (let (found-list rtn key data selected-entries) | |
4417 | ||
4418 | (while | |
4419 | (not | |
4420 | (catch 'done | |
4421 | ;; Scan bibtex files | |
4422 | (setq found-list | |
4423 | (cond | |
4424 | ((assq 'bib (symbol-value reftex-docstruct-symbol)) | |
4425 | ;; using BibTeX database files. | |
4426 | (reftex-extract-bib-entries (reftex-get-bibfile-list))) | |
4427 | ((assq 'thebib (symbol-value reftex-docstruct-symbol)) | |
4428 | ;; using thebibliography environment. | |
4429 | (reftex-extract-bib-entries-from-thebibliography | |
4430 | (cdr (assq 'thebib (symbol-value reftex-docstruct-symbol))))) | |
4431 | (reftex-default-bibliography | |
4432 | (message "Using default bibliography") | |
4433 | (reftex-extract-bib-entries reftex-default-bibliography)) | |
4434 | (t (error "No valid bibliography in this document, and no default available")))) | |
4435 | ||
4436 | (unless found-list | |
4437 | (error "Sorry, no matches found")) | |
4438 | ||
4439 | ;; Remember where we came from | |
4440 | (setq reftex-call-back-to-this-buffer (current-buffer)) | |
4441 | (set-marker reftex-select-return-marker (point)) | |
4442 | ||
4443 | ;; Offer selection | |
4444 | (save-window-excursion | |
4445 | (delete-other-windows) | |
4446 | (let ((default-major-mode 'reftex-select-bib-mode)) | |
4447 | (reftex-kill-buffer "*RefTeX Select*") | |
4448 | (switch-to-buffer-other-window "*RefTeX Select*") | |
4449 | (unless (eq major-mode 'reftex-select-bib-mode) | |
4450 | (reftex-select-bib-mode)) | |
4451 | (let ((buffer-read-only nil)) | |
4452 | (erase-buffer) | |
4453 | (reftex-insert-bib-matches found-list))) | |
4454 | (setq buffer-read-only t) | |
4455 | (if (= 0 (buffer-size)) | |
4456 | (error "Sorry, no matches found")) | |
4457 | (setq truncate-lines t) | |
4458 | (goto-char 1) | |
4459 | (while t | |
4460 | (setq rtn | |
4461 | (reftex-select-item | |
4462 | reftex-citation-prompt | |
4463 | reftex-citation-help | |
4464 | reftex-select-bib-map | |
4465 | nil | |
4466 | 'reftex-bibtex-selection-callback nil)) | |
4467 | (setq key (car rtn) | |
4468 | data (nth 1 rtn)) | |
4469 | (unless key (throw 'done t)) | |
4470 | (cond | |
4471 | ((eq key ?g) | |
4472 | ;; Start over | |
4473 | (throw 'done nil)) | |
4474 | ((eq key ?r) | |
4475 | ;; Restrict with new regular expression | |
4476 | (setq found-list (reftex-restrict-bib-matches found-list)) | |
4477 | (let ((buffer-read-only nil)) | |
4478 | (erase-buffer) | |
4479 | (reftex-insert-bib-matches found-list)) | |
4480 | (goto-char 1)) | |
4481 | ((eq key ?A) | |
4482 | ;; Take all | |
4483 | (setq selected-entries found-list) | |
4484 | (throw 'done t)) | |
4485 | ((eq key ?a) | |
4486 | ;; Take all | |
4487 | (setq selected-entries (cons 'concat found-list)) | |
4488 | (throw 'done t)) | |
4489 | ((or (eq key ?\C-m) | |
4490 | (eq key 'return)) | |
4491 | ;; Take selected | |
4492 | (setq selected-entries (if data (list data) nil)) | |
4493 | (throw 'done t)) | |
4494 | ((stringp key) | |
4495 | ;; Got this one with completion | |
4496 | (setq selected-entries key) | |
4497 | (throw 'done t)) | |
4498 | (t | |
4499 | (ding)))))))) | |
4500 | selected-entries)) | |
4501 | ||
4502 | (defun reftex-restrict-bib-matches (found-list) | |
4503 | ;; Limit FOUND-LIST with more regular expressions | |
4504 | (let ((re-list (split-string (read-string | |
4505 | "RegExp [ && RegExp...]: " | |
4506 | nil 'reftex-cite-regexp-hist) | |
4507 | "[ \t]*&&[ \t]*")) | |
4508 | (found-list-r found-list) | |
4509 | re) | |
4510 | (while (setq re (pop re-list)) | |
4511 | (setq found-list-r | |
4512 | (delq nil | |
4513 | (mapcar | |
4514 | (lambda (x) | |
4515 | (if (string-match | |
4516 | re (cdr (assoc "&entry" x))) | |
4517 | x | |
4518 | nil)) | |
4519 | found-list-r)))) | |
4520 | (if found-list-r | |
4521 | found-list-r | |
4522 | (ding) | |
4523 | found-list))) | |
396e0b08 | 4524 | |
206c6f82 RS |
4525 | (defun reftex-insert-bib-matches (list) |
4526 | ;; Insert the bib matches and number them correctly | |
6b94c6ad CD |
4527 | (let ((mouse-face |
4528 | (if (memq reftex-highlight-selection '(mouse both)) | |
4529 | reftex-mouse-selected-face | |
4530 | nil)) | |
4531 | tmp len) | |
2faef409 RS |
4532 | (mapcar |
4533 | (function | |
4534 | (lambda (x) | |
29d593f8 KH |
4535 | (setq tmp (cdr (assoc "&formatted" x)) |
4536 | len (length tmp)) | |
4537 | (put-text-property 0 len ':data x tmp) | |
4538 | (put-text-property 0 (1- len) 'mouse-face mouse-face tmp) | |
2faef409 | 4539 | (insert tmp))) |
b849548d CD |
4540 | list)) |
4541 | (run-hooks 'reftex-display-copied-context-hook)) | |
206c6f82 RS |
4542 | |
4543 | (defun reftex-format-names (namelist n) | |
206c6f82 RS |
4544 | (let (last (len (length namelist))) |
4545 | (cond | |
b849548d | 4546 | ((< len 1) "") |
206c6f82 RS |
4547 | ((= 1 len) (car namelist)) |
4548 | ((> len n) (concat (car namelist) (nth 2 reftex-cite-punctuation))) | |
4549 | (t | |
4550 | (setq n (min len n) | |
396e0b08 | 4551 | last (nth (1- n) namelist)) |
206c6f82 RS |
4552 | (setcdr (nthcdr (- n 2) namelist) nil) |
4553 | (concat | |
4554 | (mapconcat 'identity namelist (nth 0 reftex-cite-punctuation)) | |
4555 | (nth 1 reftex-cite-punctuation) | |
4556 | last))))) | |
4557 | ||
4558 | (defun reftex-format-citation (entry format) | |
a7ec1775 | 4559 | ;; Format a citation from the info in the BibTeX ENTRY |
a7ec1775 | 4560 | |
396e0b08 | 4561 | (unless (stringp format) (setq format "\\cite{%l}")) |
206c6f82 RS |
4562 | |
4563 | (if (and reftex-comment-citations | |
396e0b08 | 4564 | (string-match "%l" reftex-cite-comment-format)) |
2faef409 | 4565 | (error "reftex-cite-comment-format contains illegal %%l")) |
206c6f82 | 4566 | |
396e0b08 KH |
4567 | (while (string-match |
4568 | "\\(\\`\\|[^%]\\)\\(\\(%\\([0-9]*\\)\\([a-zA-Z]\\)\\)[.,;: ]*\\)" | |
4569 | format) | |
206c6f82 | 4570 | (let ((n (string-to-int (match-string 4 format))) |
396e0b08 KH |
4571 | (l (string-to-char (match-string 5 format))) |
4572 | rpl b e) | |
206c6f82 | 4573 | (save-match-data |
396e0b08 KH |
4574 | (setq rpl |
4575 | (cond | |
4576 | ((= l ?l) (concat | |
4577 | (reftex-get-bib-field "&key" entry) | |
4578 | (if reftex-comment-citations | |
4579 | reftex-cite-comment-format | |
4580 | ""))) | |
4581 | ((= l ?a) (reftex-format-names | |
4582 | (reftex-get-bib-names "author" entry) | |
4583 | (or n 2))) | |
4584 | ((= l ?A) (car (reftex-get-bib-names "author" entry))) | |
b849548d CD |
4585 | ((= l ?b) (reftex-get-bib-field "booktitle" entry "in: %s")) |
4586 | ((= l ?B) (reftex-abbreviate-title | |
4587 | (reftex-get-bib-field "booktitle" entry "in: %s"))) | |
396e0b08 KH |
4588 | ((= l ?c) (reftex-get-bib-field "chapter" entry)) |
4589 | ((= l ?d) (reftex-get-bib-field "edition" entry)) | |
4590 | ((= l ?e) (reftex-format-names | |
4591 | (reftex-get-bib-names "editor" entry) | |
4592 | (or n 2))) | |
4593 | ((= l ?E) (car (reftex-get-bib-names "editor" entry))) | |
4594 | ((= l ?h) (reftex-get-bib-field "howpublished" entry)) | |
4595 | ((= l ?i) (reftex-get-bib-field "institution" entry)) | |
4596 | ((= l ?j) (reftex-get-bib-field "journal" entry)) | |
4597 | ((= l ?k) (reftex-get-bib-field "key" entry)) | |
4598 | ((= l ?m) (reftex-get-bib-field "month" entry)) | |
4599 | ((= l ?n) (reftex-get-bib-field "number" entry)) | |
4600 | ((= l ?o) (reftex-get-bib-field "organization" entry)) | |
4601 | ((= l ?p) (reftex-get-bib-field "pages" entry)) | |
4602 | ((= l ?P) (car (split-string | |
4603 | (reftex-get-bib-field "pages" entry) | |
4604 | "[- .]+"))) | |
4605 | ((= l ?s) (reftex-get-bib-field "school" entry)) | |
4606 | ((= l ?u) (reftex-get-bib-field "publisher" entry)) | |
4607 | ((= l ?r) (reftex-get-bib-field "address" entry)) | |
4608 | ((= l ?t) (reftex-get-bib-field "title" entry)) | |
b849548d CD |
4609 | ((= l ?T) (reftex-abbreviate-title |
4610 | (reftex-get-bib-field "title" entry))) | |
396e0b08 KH |
4611 | ((= l ?v) (reftex-get-bib-field "volume" entry)) |
4612 | ((= l ?y) (reftex-get-bib-field "year" entry))))) | |
206c6f82 RS |
4613 | |
4614 | (if (string= rpl "") | |
396e0b08 KH |
4615 | (setq b (match-beginning 2) e (match-end 2)) |
4616 | (setq b (match-beginning 3) e (match-end 3))) | |
206c6f82 RS |
4617 | (setq format (concat (substring format 0 b) rpl (substring format e))))) |
4618 | (while (string-match "%%" format) | |
4619 | (setq format (replace-match "%" t t format))) | |
4620 | (while (string-match "[ ,.;:]*%<" format) | |
4621 | (setq format (replace-match "" t t format))) | |
4622 | format) | |
a7ec1775 | 4623 | |
2faef409 | 4624 | (defun reftex-bibtex-selection-callback (data ignore no-revisit) |
a7ec1775 | 4625 | ;; Callback function to be called from the BibTeX selection, in |
c52bdfca | 4626 | ;; order to display context. This function is relatively slow and not |
2faef409 | 4627 | ;; recommended for follow mode. It works OK for individual lookups. |
a7ec1775 | 4628 | (let ((win (selected-window)) |
2faef409 RS |
4629 | (key (reftex-get-bib-field "&key" data)) |
4630 | bibfile-list item tmp) | |
4631 | ||
4632 | (catch 'exit | |
4633 | (save-excursion | |
4634 | (set-buffer reftex-call-back-to-this-buffer) | |
4635 | (cond | |
4636 | ((assq 'bib (symbol-value reftex-docstruct-symbol)) | |
4637 | (setq bibfile-list (reftex-get-bibfile-list))) | |
4638 | ((setq tmp (assq 'thebib (symbol-value reftex-docstruct-symbol))) | |
4639 | (setq bibfile-list (list (cdr tmp)) | |
4640 | item t)) | |
4641 | (reftex-default-bibliography | |
4642 | (setq bibfile-list reftex-default-bibliography)) | |
4643 | (t (ding) (throw 'exit)))) | |
4644 | ||
4645 | (when no-revisit | |
b849548d | 4646 | (setq bibfile-list (reftex-visited-files bibfile-list))) |
2faef409 | 4647 | |
b849548d CD |
4648 | (condition-case nil |
4649 | (reftex-pop-to-bibtex-entry | |
4650 | key bibfile-list (not reftex-keep-temporary-buffers) t item) | |
4651 | (error (ding)))) | |
4652 | ||
a7ec1775 RS |
4653 | (select-window win))) |
4654 | ||
b849548d | 4655 | ;;; ========================================================================= |
a7ec1775 RS |
4656 | ;;; |
4657 | ;;; Here is the routine used for selection | |
4658 | ||
4659 | ;; Marker for return point from recursive edit | |
4660 | (defvar reftex-recursive-edit-marker (make-marker)) | |
4661 | ||
2faef409 RS |
4662 | (defvar reftex-last-data nil) |
4663 | (defvar reftex-last-line nil) | |
4664 | ||
a7ec1775 | 4665 | (defun reftex-check-recursive-edit () |
c52bdfca | 4666 | ;; Check if we are already in a recursive edit. Abort with helpful |
a7ec1775 RS |
4667 | ;; message if so. |
4668 | (if (marker-position reftex-recursive-edit-marker) | |
4669 | (error | |
4670 | (substitute-command-keys | |
29d593f8 | 4671 | "In unfinished selection process. Finish, or abort with \\[abort-recursive-edit].")))) |
a7ec1775 | 4672 | |
2faef409 RS |
4673 | (defun reftex-select-item (prompt help-string keymap |
4674 | &optional offset | |
be456a1d | 4675 | call-back cb-flag) |
2faef409 RS |
4676 | ;; Select an item, using PROMPT. The function returns a key indicating |
4677 | ;; an exit status, along with a data structure indicating which item was | |
4678 | ;; selected. | |
4679 | ;; HELP-STRING contains help. KEYMAP is a keymap with the available | |
4680 | ;; selection commands. | |
4681 | ;; OFFSET can be a label list item which will be selected at start. | |
4682 | ;; When it is t, point will start out at the beginning of the buffer. | |
4683 | ;; Any other value will cause restart where last selection left off. | |
4684 | ;; When CALL-BACK is given, it is a function which is called with the index | |
4685 | ;; of the element. | |
4686 | ;; CB-FLAG is the initial value of that flag. | |
2faef409 | 4687 | |
5ff44b47 | 4688 | (let* (ev data last-data callback-fwd (selection-buffer (current-buffer))) |
206c6f82 | 4689 | |
a7ec1775 | 4690 | (setq ev |
29d593f8 | 4691 | (catch 'myexit |
a7ec1775 | 4692 | (save-window-excursion |
a7ec1775 | 4693 | (setq truncate-lines t) |
a7ec1775 | 4694 | |
2faef409 RS |
4695 | ;; Find a good starting point |
4696 | (cond | |
4697 | (offset | |
4698 | (goto-char | |
4699 | (or (and (listp offset) | |
4700 | (text-property-any (point-min) (point-max) | |
4701 | ':data offset)) | |
4702 | (and (local-variable-p 'reftex-last-data (current-buffer)) | |
4703 | (boundp 'reftex-last-data) | |
4704 | (listp reftex-last-data) | |
4705 | (text-property-any (point-min) (point-max) | |
4706 | ':data reftex-last-data)) | |
4707 | (and (local-variable-p 'reftex-last-line (current-buffer)) | |
4708 | (boundp 'reftex-last-line) | |
4709 | (integerp reftex-last-line) | |
4710 | (progn (goto-line reftex-last-line) (point))) | |
4711 | (point-min)))) | |
4712 | (t (goto-char (point-min)))) | |
4713 | (beginning-of-line 1) | |
29d593f8 | 4714 | (set (make-local-variable 'reftex-last-follow-point) (point)) |
a7ec1775 | 4715 | |
2faef409 RS |
4716 | (unwind-protect |
4717 | (progn | |
4718 | (use-local-map keymap) | |
29d593f8 KH |
4719 | (add-hook 'pre-command-hook 'reftex-select-pre-command-hook nil t) |
4720 | (add-hook 'post-command-hook 'reftex-select-post-command-hook nil t) | |
4721 | (princ prompt) | |
4722 | (set-marker reftex-recursive-edit-marker (point)) | |
b849548d | 4723 | ;; XEmacs does not run post-command-hook here |
a6611c0d | 4724 | (and (featurep 'xemacs) (run-hooks 'post-command-hook)) |
29d593f8 KH |
4725 | (recursive-edit)) |
4726 | ||
5ff44b47 CD |
4727 | (set-marker reftex-recursive-edit-marker nil) |
4728 | (save-excursion | |
4729 | (set-buffer selection-buffer) | |
4730 | (use-local-map nil) | |
4731 | (remove-hook 'pre-command-hook 'reftex-select-pre-command-hook t) | |
4732 | (remove-hook 'post-command-hook | |
4733 | 'reftex-select-post-command-hook t)))))) | |
2faef409 RS |
4734 | |
4735 | (set (make-local-variable 'reftex-last-line) | |
4736 | (+ (count-lines (point-min) (point)) (if (bolp) 1 0))) | |
4737 | (set (make-local-variable 'reftex-last-data) last-data) | |
29d593f8 | 4738 | (reftex-kill-buffer "*RefTeX Help*") |
b849548d | 4739 | (setq callback-fwd (not callback-fwd)) ;; ;-))) |
a7ec1775 | 4740 | (message "") |
2faef409 RS |
4741 | (list ev data last-data))) |
4742 | ||
4743 | ;; The following variables are all bound dynamically in `reftex-select-item'. | |
4744 | ;; The defvars are here only to silence the byte compiler. | |
4745 | ||
2faef409 RS |
4746 | (defvar found-list) |
4747 | (defvar cb-flag) | |
4748 | (defvar data) | |
29d593f8 KH |
4749 | (defvar prompt) |
4750 | (defvar last-data) | |
2faef409 RS |
4751 | (defvar call-back) |
4752 | (defvar help-string) | |
2faef409 RS |
4753 | (defvar callback-fwd) |
4754 | (defvar varioref) | |
2faef409 RS |
4755 | |
4756 | ;; The selection commands | |
4757 | ||
29d593f8 KH |
4758 | (defun reftex-select-pre-command-hook () |
4759 | (reftex-unhighlight 1) | |
4760 | (reftex-unhighlight 0)) | |
4761 | ||
4762 | (defun reftex-select-post-command-hook () | |
4763 | (let (b e) | |
4764 | (setq data (get-text-property (point) ':data)) | |
4765 | (setq last-data (or data last-data)) | |
4766 | ||
4767 | (when (and data cb-flag | |
4768 | (not (equal reftex-last-follow-point (point)))) | |
4769 | (setq reftex-last-follow-point (point)) | |
4770 | (funcall call-back data callback-fwd | |
4771 | (not reftex-revisit-to-follow))) | |
4772 | (if data | |
4773 | (setq b (or (previous-single-property-change | |
4774 | (1+ (point)) ':data) | |
4775 | (point-min)) | |
4776 | e (or (next-single-property-change | |
4777 | (point) ':data) | |
4778 | (point-max))) | |
4779 | (setq b (point) e (point))) | |
4780 | (and (memq reftex-highlight-selection '(cursor both)) | |
4781 | (reftex-highlight 1 b e)) | |
4782 | (if (or (not (pos-visible-in-window-p b)) | |
4783 | (not (pos-visible-in-window-p e))) | |
a6611c0d | 4784 | (recenter '(4))) |
b849548d | 4785 | (unless (current-message) |
29d593f8 KH |
4786 | (princ prompt)))) |
4787 | ||
4788 | (defun reftex-select-next (&optional arg) | |
b849548d | 4789 | "Move to next selectable item." |
29d593f8 | 4790 | (interactive "p") |
2faef409 RS |
4791 | (setq callback-fwd t) |
4792 | (or (eobp) (forward-char 1)) | |
29d593f8 | 4793 | (re-search-forward "^[^. \t\n\r]" nil t arg) |
2faef409 | 4794 | (beginning-of-line 1)) |
29d593f8 | 4795 | (defun reftex-select-previous (&optional arg) |
b849548d | 4796 | "Move to previous selectable item." |
29d593f8 | 4797 | (interactive "p") |
2faef409 | 4798 | (setq callback-fwd nil) |
29d593f8 KH |
4799 | (re-search-backward "^[^. \t\n\r]" nil t arg)) |
4800 | (defun reftex-select-next-heading (&optional arg) | |
b849548d | 4801 | "Move to next table of contentes line." |
29d593f8 | 4802 | (interactive "p") |
2faef409 | 4803 | (end-of-line) |
29d593f8 | 4804 | (re-search-forward "^ " nil t arg) |
2faef409 | 4805 | (beginning-of-line)) |
29d593f8 | 4806 | (defun reftex-select-previous-heading (&optional arg) |
b849548d | 4807 | "Move to previous table of contentes line." |
29d593f8 KH |
4808 | (interactive "p") |
4809 | (re-search-backward "^ " nil t arg)) | |
2faef409 | 4810 | (defun reftex-select-quit () |
b849548d | 4811 | "Abort selection process." |
2faef409 | 4812 | (interactive) |
29d593f8 KH |
4813 | (throw 'myexit nil)) |
4814 | (defun reftex-select-keyboard-quit () | |
b849548d | 4815 | "Abort selection process." |
29d593f8 KH |
4816 | (interactive) |
4817 | (throw 'exit t)) | |
2faef409 | 4818 | (defun reftex-select-jump-to-previous () |
b849548d | 4819 | "Jump back to where previous selection process left off." |
2faef409 RS |
4820 | (interactive) |
4821 | (let (pos) | |
4822 | (cond | |
4823 | ((and (local-variable-p 'reftex-last-data (current-buffer)) | |
4824 | reftex-last-data | |
4825 | (setq pos (text-property-any (point-min) (point-max) | |
4826 | ':data reftex-last-data))) | |
4827 | (goto-char pos)) | |
4828 | ((and (local-variable-p 'reftex-last-line (current-buffer)) | |
4829 | (integerp reftex-last-line)) | |
4830 | (goto-line reftex-last-line)) | |
4831 | (t (ding))))) | |
4832 | (defun reftex-select-toggle-follow () | |
b849548d | 4833 | "Toggle follow mode: Other window follows with full context." |
2faef409 | 4834 | (interactive) |
b849548d | 4835 | (setq reftex-last-follow-point -1) |
2faef409 RS |
4836 | (setq cb-flag (not cb-flag))) |
4837 | (defun reftex-select-toggle-varioref () | |
b849548d | 4838 | "Toggle the macro used for referencing the label between \\ref and \\vref." |
2faef409 RS |
4839 | (interactive) |
4840 | (if (string= varioref "\\ref") | |
4841 | (setq varioref "\\vref") | |
4842 | (setq varioref "\\ref")) | |
4843 | (force-mode-line-update)) | |
29d593f8 | 4844 | (defun reftex-select-show-insertion-point () |
b849548d | 4845 | "Show the point from where selection was started in another window." |
29d593f8 KH |
4846 | (interactive) |
4847 | (let ((this-window (selected-window))) | |
4848 | (unwind-protect | |
4849 | (progn | |
4850 | (switch-to-buffer-other-window | |
4851 | (marker-buffer reftex-select-return-marker)) | |
4852 | (goto-char (marker-position reftex-select-return-marker)) | |
a6611c0d | 4853 | (recenter '(4))) |
29d593f8 | 4854 | (select-window this-window)))) |
2faef409 | 4855 | (defun reftex-select-callback () |
b849548d | 4856 | "Show full context in another window." |
2faef409 RS |
4857 | (interactive) |
4858 | (if data (funcall call-back data callback-fwd nil) (ding))) | |
4859 | (defun reftex-select-accept () | |
b849548d | 4860 | "Accept the currently selected item." |
2faef409 | 4861 | (interactive) |
29d593f8 KH |
4862 | (throw 'myexit 'return)) |
4863 | (defun reftex-select-mouse-accept (ev) | |
b849548d | 4864 | "Accept the item at the mouse click." |
29d593f8 KH |
4865 | (interactive "e") |
4866 | (mouse-set-point ev) | |
4867 | (setq data (get-text-property (point) ':data)) | |
4868 | (setq last-data (or data last-data)) | |
4869 | (throw 'myexit 'return)) | |
2faef409 | 4870 | (defun reftex-select-read-label () |
b849548d | 4871 | "Use minibuffer to read a label to reference, with completion." |
2faef409 RS |
4872 | (interactive) |
4873 | (let ((label (completing-read | |
4874 | "Label: " (symbol-value reftex-docstruct-symbol) | |
4875 | nil nil reftex-prefix))) | |
4876 | (unless (or (equal label "") (equal label reftex-prefix)) | |
29d593f8 | 4877 | (throw 'myexit label)))) |
2faef409 | 4878 | (defun reftex-select-read-cite () |
b849548d | 4879 | "Use minibuffer to read a citation key with completion." |
2faef409 | 4880 | (interactive) |
b849548d CD |
4881 | (let* ((key (completing-read "Citation key: " found-list)) |
4882 | (entry (assoc key found-list))) | |
4883 | (cond | |
4884 | ((or (null key) (equal key ""))) | |
4885 | (entry | |
4886 | (setq data entry) | |
4887 | (setq last-data data) | |
4888 | (throw 'myexit 'return)) | |
4889 | (t (throw 'myexit key))))) | |
2faef409 | 4890 | (defun reftex-select-help () |
b849548d | 4891 | "Display a summary of the special key bindings." |
2faef409 RS |
4892 | (interactive) |
4893 | (with-output-to-temp-buffer "*RefTeX Help*" | |
4894 | (princ help-string)) | |
29d593f8 | 4895 | (reftex-enlarge-to-fit "*RefTeX Help*" t)) |
a7ec1775 | 4896 | |
b849548d | 4897 | ;;; ========================================================================= |
a7ec1775 RS |
4898 | ;;; |
4899 | ;;; View cross references | |
4900 | ||
a6611c0d | 4901 | (defun reftex-view-crossref (&optional arg how) |
fba437e6 RS |
4902 | "View cross reference of \\ref or \\cite macro at point. |
4903 | If the macro at point is a \\ref, show the corresponding label definition. | |
2faef409 | 4904 | If it is a \\cite, show the BibTeX database entry or the \\bibitem. |
a6611c0d CD |
4905 | To cope with the plethora of variations in packages, this |
4906 | function assumes any macro either starting with or ending in `ref' or | |
4907 | `cite' to contain cross references. | |
2faef409 RS |
4908 | When the LaTeX package `xr' is being used, this command will also view |
4909 | crossreferences in external documents. However, this works correctly only | |
4910 | when the \\externaldocument macros are used with the optional label prefix | |
4911 | argument. | |
4912 | With one or two C-u prefixes, enforce rescanning of the document. | |
a6611c0d CD |
4913 | With argument 2, select the window showing the cross reference. |
4914 | When HOW is 'echo, call the corresponding echo function. | |
4915 | When HOW is 'tmp-window, make the pop-up window as small as possible and | |
4916 | arrange for its removal before the next command." | |
a7ec1775 RS |
4917 | |
4918 | (interactive "P") | |
4919 | ||
4920 | ;; See where we are. | |
a6611c0d CD |
4921 | (let* ((macro (car (reftex-what-macro 1))) |
4922 | (key (reftex-this-word "^{}%\n\r,"))) | |
396e0b08 | 4923 | |
b849548d CD |
4924 | (setq reftex-call-back-to-this-buffer (current-buffer)) |
4925 | ||
a6611c0d CD |
4926 | (if (and macro |
4927 | (string-match "\\`\\\\cite\\|\\`\\\\ref\\|cite\\'\\|ref\\'" | |
4928 | macro)) | |
4929 | (and (setq macro (match-string 0 macro)) | |
4930 | (string-match "\\`\\\\" macro) | |
4931 | (setq macro (substring macro 1))) | |
4932 | (setq macro nil)) | |
4933 | ||
4934 | (if (or (null macro) (reftex-in-comment)) | |
b849548d | 4935 | (error "No cross reference to display")) |
a7ec1775 | 4936 | |
a6611c0d CD |
4937 | (if (eq how 'tmp-window) |
4938 | ;; Remember the window configuration | |
4939 | (put 'reftex-auto-view-crossref 'last-window-conf | |
4940 | (current-window-configuration))) | |
4941 | (cond | |
4942 | ((string= macro "cite") | |
4943 | (reftex-view-cr-cite arg key how)) | |
4944 | ((string= macro "ref") | |
4945 | (reftex-view-cr-ref arg key how)) | |
4946 | (t | |
4947 | (error "Cannot display crossref\n"))))) | |
4948 | ||
4949 | (defun reftex-view-cr-cite (arg key how) | |
4950 | ;; View crossreference of a ref cite. HOW can have the values | |
4951 | ;; nil: Show in another window. | |
4952 | ;; echo: Show one-line info in echo area. | |
4953 | ;; tmp-window: Show in small window and arrange for window to disappear. | |
a7ec1775 | 4954 | |
a6611c0d CD |
4955 | ;; Ensure access to scanning info |
4956 | (reftex-access-scan-info (or arg current-prefix-arg)) | |
4957 | ||
4958 | (let (files size item (pos (point)) (win (selected-window)) pop-win) | |
4959 | ;; Find the citation mode and the file list | |
4960 | (cond | |
4961 | ((assq 'bib (symbol-value reftex-docstruct-symbol)) | |
4962 | (setq item nil | |
4963 | files (reftex-get-bibfile-list))) | |
4964 | ((assq 'thebib (symbol-value reftex-docstruct-symbol)) | |
4965 | (setq item t | |
4966 | files (list (cdr (assq 'thebib | |
4967 | (symbol-value reftex-docstruct-symbol)))))) | |
4968 | (reftex-default-bibliography | |
4969 | (setq item nil | |
4970 | files reftex-default-bibliography)) | |
4971 | (how) ;; don't throw for special display | |
4972 | (t (error "Cannot display crossref"))) | |
4973 | ||
4974 | (if (eq how 'echo) | |
4975 | ;; Display in Echo area | |
4976 | (reftex-echo-cite key files item) | |
4977 | ;; Display in a window | |
4978 | (if (not (eq how 'tmp-window)) | |
4979 | ;; Normal display | |
4980 | (reftex-pop-to-bibtex-entry key files nil t item) | |
4981 | ;; A temporary window | |
4982 | (condition-case nil | |
4983 | (reftex-pop-to-bibtex-entry key files nil t item) | |
4984 | (error (goto-char pos) | |
4985 | (message "cite: no such citation key %s" key) | |
4986 | (error ""))) | |
4987 | ;; Resize the window | |
4988 | (setq size (max 1 (count-lines (point) | |
4989 | (reftex-end-of-bib-entry item)))) | |
4990 | (let ((window-min-height 2)) | |
4991 | (shrink-window (1- (- (window-height) size))) | |
4992 | (recenter 0)) | |
4993 | ;; Arrange restoration | |
4994 | (add-hook 'pre-command-hook 'reftex-restore-window-conf)) | |
4995 | ||
4996 | ;; Normal display in other window | |
b849548d | 4997 | (add-hook 'pre-command-hook 'reftex-highlight-shall-die) |
a6611c0d CD |
4998 | (setq pop-win (selected-window)) |
4999 | (select-window win) | |
5000 | (goto-char pos) | |
5001 | (when (equal arg 2) | |
5002 | (select-window pop-win))))) | |
5003 | ||
5004 | (defun reftex-view-cr-ref (arg label how) | |
5005 | ;; View crossreference of a ref macro. HOW can have the values | |
5006 | ;; nil: Show in another window. | |
5007 | ;; echo: Show one-line info in echo area. | |
5008 | ;; tmp-window: Show in small window and arrange for window to disappear. | |
5009 | ||
5010 | ;; Ensure access to scanning info | |
5011 | (reftex-access-scan-info (or arg current-prefix-arg)) | |
5012 | ||
5013 | (let* ((xr-data (assoc 'xr (symbol-value reftex-docstruct-symbol))) | |
5014 | (xr-re (nth 2 xr-data)) | |
5015 | (entry (assoc label (symbol-value reftex-docstruct-symbol))) | |
5016 | (win (selected-window)) pop-win (pos (point))) | |
5017 | ||
5018 | (if (and (not entry) (stringp label) xr-re (string-match xr-re label)) | |
5019 | ;; Label is defined in external document | |
5020 | (save-excursion | |
5021 | (save-match-data | |
5022 | (set-buffer | |
5023 | (or (reftex-get-file-buffer-force | |
5024 | (cdr (assoc (match-string 1 label) (nth 1 | |
5025 | xr-data)))) | |
5026 | (error "Problem with external label %s" label)))) | |
5027 | (setq label (substring label (match-end 1))) | |
5028 | (reftex-access-scan-info) | |
5029 | (setq entry | |
5030 | (assoc label (symbol-value reftex-docstruct-symbol))))) | |
5031 | (if (eq how 'echo) | |
5032 | (reftex-echo-ref label entry (symbol-value reftex-docstruct-symbol)) | |
5033 | (unless entry | |
5034 | (message "Label %s not known - reparse document might help" label)) | |
5035 | ||
5036 | (reftex-pop-to-label label (list (nth 3 entry)) nil t) | |
5037 | (add-hook 'pre-command-hook 'reftex-highlight-shall-die) | |
5038 | ||
5039 | (when (eq how 'tmp-window) | |
5040 | ;; Resize window and arrange restauration | |
5041 | (shrink-window (1- (- (window-height) 9))) | |
5042 | (recenter '(4)) | |
5043 | (add-hook 'pre-command-hook 'reftex-restore-window-conf)) | |
5044 | (setq pop-win (selected-window)) | |
5045 | (select-window win) | |
5046 | (goto-char pos) | |
5047 | (when (equal arg 2) | |
5048 | (select-window pop-win))))) | |
a7ec1775 RS |
5049 | |
5050 | (defun reftex-mouse-view-crossref (ev) | |
fba437e6 RS |
5051 | "View cross reference of \\ref or \\cite macro where you click. |
5052 | If the macro at point is a \\ref, show the corresponding label definition. | |
5053 | If it is a \\cite, show the BibTeX database entry. | |
a7ec1775 | 5054 | If there is no such macro at point, search forward to find one. |
a7ec1775 RS |
5055 | With argument, actually select the window showing the cross reference." |
5056 | (interactive "e") | |
5057 | (mouse-set-point ev) | |
5058 | (reftex-view-crossref current-prefix-arg)) | |
5059 | ||
b849548d CD |
5060 | (defvar reftex-auto-view-crossref-timer nil |
5061 | "The timer used for auto-view-crossref.") | |
5062 | ||
5063 | (defun reftex-view-crossref-when-idle () | |
a6611c0d | 5064 | ;; Display info about crossref at point in echo area or a window. |
b849548d CD |
5065 | ;; This function was desigend to work with an idle timer. |
5066 | ;; We try to get out of here as quickly as possible if the call is useless. | |
5067 | (and reftex-mode | |
5068 | ;; Quick precheck if this might be a relevant spot | |
a6611c0d | 5069 | ;; FIXME: failes with backslash in comment |
b849548d CD |
5070 | (save-excursion |
5071 | (search-backward "\\" nil t) | |
5072 | (looking-at "\\\\[a-zA-Z]*\\(cite\\|ref\\)")) | |
a6611c0d CD |
5073 | ;; Make sure message area is free if we need it. |
5074 | (or (eq reftex-auto-view-crossref 'window) (not (current-message))) | |
5075 | ;; Make sure we are not already displaying this one | |
5076 | (not (memq last-command '(reftex-view-crossref | |
5077 | reftex-mouse-view-crossref))) | |
b849548d CD |
5078 | (condition-case nil |
5079 | (let ((current-prefix-arg nil)) | |
a6611c0d CD |
5080 | (cond |
5081 | ((eq reftex-auto-view-crossref t) | |
5082 | (reftex-view-crossref -1 'echo)) | |
5083 | ((eq reftex-auto-view-crossref 'window) | |
5084 | (reftex-view-crossref -1 'tmp-window)) | |
5085 | (t nil))) | |
5086 | (error nil)))) | |
5087 | ||
5088 | (defun reftex-restore-window-conf () | |
5089 | (set-window-configuration (get 'reftex-auto-view-crossref 'last-window-conf)) | |
5090 | (put 'reftex-auto-view-crossref 'last-window-conf nil) | |
5091 | (remove-hook 'pre-command-hook 'reftex-restore-window-conf)) | |
b849548d CD |
5092 | |
5093 | (defun reftex-echo-ref (label entry docstruct) | |
5094 | ;; Display crossref info in echo area. | |
5095 | (cond | |
5096 | ((null docstruct) | |
5097 | (message (substitute-command-keys (format reftex-no-info-message "ref")))) | |
5098 | ((null entry) | |
5099 | (message "ref: unknown label: %s" label)) | |
5100 | (t | |
5101 | (when (stringp (nth 2 entry)) | |
5102 | (message "ref(%s): %s" (nth 1 entry) (nth 2 entry))) | |
5103 | (let ((buf (get-buffer " *Echo Area*"))) | |
5104 | (when buf | |
5105 | (save-excursion | |
5106 | (set-buffer buf) | |
5107 | (run-hooks 'reftex-display-copied-context-hook))))))) | |
5108 | ||
a6611c0d | 5109 | (defun reftex-echo-cite (key files item) |
b849548d | 5110 | ;; Display citation info in echo area. |
a6611c0d | 5111 | (let* ((cache (assq 'bibview-cache (symbol-value reftex-docstruct-symbol))) |
b849548d | 5112 | (cache-entry (assoc key (cdr cache))) |
a6611c0d | 5113 | entry string buf (all-files files)) |
b849548d CD |
5114 | |
5115 | (if (and reftex-cache-cite-echo cache-entry) | |
5116 | ;; We can just use the cache | |
5117 | (setq string (cdr cache-entry)) | |
5118 | ||
5119 | ;; Need to look in the database | |
5120 | (unless reftex-revisit-to-echo | |
a6611c0d | 5121 | (setq files (reftex-visited-files files))) |
b849548d CD |
5122 | |
5123 | (setq entry | |
5124 | (condition-case nil | |
5125 | (save-excursion | |
5126 | (reftex-pop-to-bibtex-entry key files nil nil item t)) | |
5127 | (error | |
a6611c0d | 5128 | (if (and files (= (length all-files) (length files))) |
b849548d CD |
5129 | (message "cite: no such database entry: %s" key) |
5130 | (message (substitute-command-keys | |
5131 | (format reftex-no-info-message "cite")))) | |
5132 | nil))) | |
5133 | (when entry | |
a6611c0d CD |
5134 | (if item |
5135 | (setq string (reftex-nicify-text entry)) | |
5136 | (setq string (reftex-make-cite-echo-string | |
5137 | (reftex-parse-bibtex-entry entry) | |
5138 | reftex-docstruct-symbol))))) | |
b849548d CD |
5139 | (unless (or (null string) (equal string "")) |
5140 | (message "cite: %s" string)) | |
5141 | (when (setq buf (get-buffer " *Echo Area*")) | |
5142 | (save-excursion | |
5143 | (set-buffer buf) | |
5144 | (run-hooks 'reftex-display-copied-context-hook))))) | |
5145 | ||
5146 | (defun reftex-make-cite-echo-string (entry docstruct-symbol) | |
5147 | ;; Format a bibtex entry for the echo area and cache the result. | |
5148 | (let* ((key (reftex-get-bib-field "&key" entry)) | |
5149 | (string | |
5150 | (let* ((reftex-cite-punctuation '(" " " & " " etal."))) | |
5151 | (reftex-format-citation entry reftex-cite-view-format))) | |
5152 | (cache (assq 'bibview-cache (symbol-value docstruct-symbol))) | |
5153 | (cache-entry (assoc key (cdr cache)))) | |
5154 | (unless cache | |
5155 | ;; This docstruct has no cache - make one. | |
5156 | (set docstruct-symbol (cons (cons 'bibview-cache nil) | |
5157 | (symbol-value docstruct-symbol)))) | |
5158 | (when reftex-cache-cite-echo | |
5159 | (setq key (copy-sequence key)) | |
5160 | (set-text-properties 0 (length key) nil key) | |
5161 | (set-text-properties 0 (length string) nil string) | |
5162 | (if cache-entry | |
5163 | (unless (string= (cdr cache-entry) string) | |
5164 | (setcdr cache-entry string) | |
5165 | (put reftex-docstruct-symbol 'modified t)) | |
5166 | (push (cons key string) (cdr cache)) | |
5167 | (put reftex-docstruct-symbol 'modified t))) | |
5168 | string)) | |
5169 | ||
5170 | (defvar reftex-use-itimer-in-xemacs nil | |
5171 | "*Non-nil means use the idle timers in XEmacs for crossref display. | |
5172 | Currently, idle timer restart is broken and we use the post-command-hook.") | |
5173 | ||
5174 | (defun reftex-toggle-auto-view-crossref () | |
5175 | "Toggle the automatic display of crossref information in the echo area. | |
5176 | When active, leaving point idle in the argument of a \\ref or \\cite macro | |
5177 | will display info in the echo area." | |
5178 | (interactive) | |
5179 | (if reftex-auto-view-crossref-timer | |
5180 | (progn | |
5181 | (if (featurep 'xemacs) | |
5182 | (if reftex-use-itimer-in-xemacs | |
5183 | (delete-itimer reftex-auto-view-crossref-timer) | |
5184 | (remove-hook 'post-command-hook 'reftex-start-itimer-once)) | |
5185 | (cancel-timer reftex-auto-view-crossref-timer)) | |
5186 | (setq reftex-auto-view-crossref-timer nil) | |
5187 | (message "Automatic display of crossref information was turned off")) | |
5188 | (setq reftex-auto-view-crossref-timer | |
5189 | (if (featurep 'xemacs) | |
5190 | (if reftex-use-itimer-in-xemacs | |
5191 | (start-itimer "RefTeX Idle Timer" | |
5192 | 'reftex-view-crossref-when-idle | |
5193 | reftex-idle-time reftex-idle-time t) | |
5194 | (add-hook 'post-command-hook 'reftex-start-itimer-once) | |
5195 | nil) | |
5196 | (run-with-idle-timer | |
5197 | reftex-idle-time t 'reftex-view-crossref-when-idle))) | |
5198 | (message "Automatic display of crossref information was turned on"))) | |
5199 | ||
5200 | (defun reftex-start-itimer-once () | |
5201 | (and reftex-mode | |
5202 | (not (itimer-live-p reftex-auto-view-crossref-timer)) | |
5203 | (setq reftex-auto-view-crossref-timer | |
5204 | (start-itimer "RefTeX Idle Timer" | |
5205 | 'reftex-view-crossref-when-idle | |
5206 | reftex-idle-time nil t)))) | |
5207 | ||
5208 | ;;; ========================================================================= | |
a7ec1775 RS |
5209 | ;;; |
5210 | ;;; Functions that check out the surroundings | |
5211 | ||
5212 | (defun reftex-what-macro (which &optional bound) | |
5213 | ;; Find out if point is within the arguments of any TeX-macro. | |
c52bdfca | 5214 | ;; The return value is either ("\\macro" . (point)) or a list of them. |
a7ec1775 RS |
5215 | |
5216 | ;; If WHICH is nil, immediately return nil. | |
b849548d | 5217 | ;; If WHICH is 1, return innermost enclosing macro. |
a7ec1775 RS |
5218 | ;; If WHICH is t, return list of all macros enclosing point. |
5219 | ;; If WHICH is a list of macros, look only for those macros and return the | |
5220 | ;; name of the first macro in this list found to enclose point. | |
5221 | ;; If the optional BOUND is an integer, bound backwards directed | |
c52bdfca | 5222 | ;; searches to this point. If it is nil, limit to nearest \section - |
a7ec1775 RS |
5223 | ;; like statement. |
5224 | ||
5225 | ;; This function is pretty stable, but can be fooled if the text contains | |
c52bdfca RS |
5226 | ;; things like \macro{aa}{bb} where \macro is defined to take only one |
5227 | ;; argument. As RefTeX cannot know this, the string "bb" would still be | |
5228 | ;; considered an argument of macro \macro. | |
a7ec1775 | 5229 | |
b849548d | 5230 | (unless reftex-section-regexp (reftex-compile-variables)) |
a7ec1775 RS |
5231 | (catch 'exit |
5232 | (if (null which) (throw 'exit nil)) | |
5233 | (let ((bound (or bound (save-excursion (re-search-backward | |
5234 | reftex-section-regexp nil 1) | |
5235 | (point)))) | |
396e0b08 | 5236 | pos cmd-list cmd cnt cnt-opt entry) |
a7ec1775 RS |
5237 | (save-restriction |
5238 | (save-excursion | |
5239 | (narrow-to-region (max 1 bound) (point-max)) | |
5240 | ;; move back out of the current parenthesis | |
5241 | (while (condition-case nil | |
5242 | (progn (up-list -1) t) | |
5243 | (error nil)) | |
396e0b08 | 5244 | (setq cnt 1 cnt-opt 0) |
a7ec1775 | 5245 | ;; move back over any touching sexps |
396e0b08 KH |
5246 | (while (and (reftex-move-to-previous-arg bound) |
5247 | (condition-case nil | |
5248 | (progn (backward-sexp) t) | |
5249 | (error nil))) | |
5250 | (if (eq (following-char) ?\[) (incf cnt-opt)) | |
5251 | (incf cnt)) | |
a7ec1775 | 5252 | (setq pos (point)) |
396e0b08 KH |
5253 | (when (and (or (= (following-char) ?\[) |
5254 | (= (following-char) ?\{)) | |
5255 | (re-search-backward "\\\\[*a-zA-Z]+\\=" nil t)) | |
5256 | (setq cmd (reftex-match-string 0)) | |
5257 | (when (looking-at "\\\\begin{[^}]*}") | |
5258 | (setq cmd (reftex-match-string 0) | |
5259 | cnt (1- cnt))) | |
5260 | ;; This does ignore optional arguments. Very hard to fix. | |
5261 | (when (setq entry (assoc cmd reftex-env-or-mac-alist)) | |
5262 | (if (> cnt (or (nth 4 entry) 100)) | |
5263 | (setq cmd nil))) | |
5264 | (cond | |
5265 | ((null cmd)) | |
5266 | ((eq t which) | |
5267 | (push (cons cmd (point)) cmd-list)) | |
b849548d | 5268 | ((or (eq 1 which) (member cmd which)) |
396e0b08 | 5269 | (throw 'exit (cons cmd (point)))))) |
a7ec1775 RS |
5270 | (goto-char pos))) |
5271 | (nreverse cmd-list))))) | |
5272 | ||
5273 | (defun reftex-what-environment (which &optional bound) | |
5274 | ;; Find out if point is inside a LaTeX environment. | |
c52bdfca | 5275 | ;; The return value is (e.g.) either ("equation" . (point)) or a list of |
a7ec1775 RS |
5276 | ;; them. |
5277 | ||
5278 | ;; If WHICH is nil, immediately return nil. | |
b849548d | 5279 | ;; If WHICH is 1, return innermost enclosing environment. |
a7ec1775 RS |
5280 | ;; If WHICH is t, return list of all environments enclosing point. |
5281 | ;; If WHICH is a list of environments, look only for those environments and | |
5282 | ;; return the name of the first environment in this list found to enclose | |
5283 | ;; point. | |
5284 | ||
b849548d CD |
5285 | ;; If the optional BOUND is an integer, bound backwards directed searches to |
5286 | ;; this point. If it is nil, limit to nearest \section - like statement. | |
5287 | ||
a6611c0d | 5288 | (unless reftex-section-regexp (reftex-compile-variables)) |
b849548d CD |
5289 | (catch 'exit |
5290 | (save-excursion | |
5291 | (if (null which) (throw 'exit nil)) | |
5292 | (let ((bound (or bound (save-excursion (re-search-backward | |
5293 | reftex-section-regexp nil 1) | |
5294 | (point)))) | |
5295 | env-list end-list env) | |
5296 | (while (re-search-backward "\\\\\\(begin\\|end\\){\\([^}]+\\)}" | |
5297 | bound t) | |
5298 | (setq env (buffer-substring-no-properties | |
5299 | (match-beginning 2) (match-end 2))) | |
5300 | (cond | |
5301 | ((string= (match-string 1) "end") | |
5302 | (add-to-list 'end-list env)) | |
5303 | ((member env end-list) | |
5304 | (setq end-list (delete env end-list))) | |
5305 | ((eq t which) | |
5306 | (push (cons env (point)) env-list)) | |
5307 | ((or (eq 1 which) (member env which)) | |
5308 | (throw 'exit (cons env (point)))))) | |
5309 | (nreverse env-list))))) | |
5310 | ||
5311 | ;;; ========================================================================= | |
5312 | ;;; | |
5313 | ;;; Finding files | |
5314 | ||
5315 | (defun reftex-find-tex-file (file master-dir &optional die) | |
5316 | ;; Find FILE in MASTER-DIR or on reftex-tex-path. | |
5317 | ;; FILE may be given with or without the .tex extension. | |
5318 | (let ((rec-values '(nil t)) path file1 old-path) | |
a6611c0d CD |
5319 | (if (file-name-absolute-p file) |
5320 | (if (file-regular-p (concat file ".tex")) | |
5321 | (setq file1 (concat file ".tex")) | |
5322 | (if (file-regular-p file) (setq file1 file))) | |
b849548d | 5323 | (while (and (null file1) rec-values) |
a6611c0d | 5324 | (setq path (reftex-access-search-path |
b849548d CD |
5325 | "tex" (pop rec-values) master-dir file)) |
5326 | (if (or (null old-path) | |
5327 | (not (eq old-path path))) | |
5328 | (setq old-path path | |
5329 | path (cons master-dir path) | |
5330 | file1 (or (reftex-find-file-on-path | |
5331 | (concat file ".tex") path master-dir) | |
5332 | (reftex-find-file-on-path file path master-dir)))))) | |
5333 | (cond (file1 file1) | |
5334 | (die (error "No such file: %s" file) nil) | |
5335 | (t (message "No such file: %s (ignored)" file) nil)))) | |
5336 | ||
5337 | (defun reftex-find-bib-file (file master-dir &optional die) | |
5338 | ;; Find FILE in MASTER-DIR or on reftex-bib-path | |
5339 | (let ((rec-values '(nil t)) path file1 old-path) | |
a6611c0d CD |
5340 | (if (file-name-absolute-p file) |
5341 | (if (file-regular-p file) (setq file1 file)) | |
b849548d CD |
5342 | (while (and (null file1) rec-values) |
5343 | (setq path (reftex-access-search-path | |
5344 | "bib" (pop rec-values) master-dir file)) | |
5345 | (if (or (null old-path) | |
5346 | (not (eq old-path path))) | |
5347 | (setq old-path path | |
5348 | path (cons master-dir path) | |
5349 | file1 (reftex-find-file-on-path file path master-dir))))) | |
5350 | (cond (file1 file1) | |
5351 | (die (error "No such file: %s" file) nil) | |
5352 | (t (message "No such file: %s (ignored)" file) nil)))) | |
5353 | ||
5354 | (defun reftex-access-search-path (which &optional recurse master-dir file) | |
5355 | ;; Access path from environment variables. WHICH is either "tex" or "bib". | |
5356 | ;; When RECURSE is t, expand path elements ending in `//' recursively. | |
5357 | ;; Relative path elements are left as they are. However, relative recursive | |
5358 | ;; elements are expanded with MASTER-DIR as default directory. | |
5359 | ;; The expanded path is cached for the next search. | |
5360 | ;; FILE is just for the progress message. | |
5361 | ;; Returns the derived path. | |
5362 | (let* ((pathvar (intern (concat "reftex-" which "-path")))) | |
5363 | (when (null (get pathvar 'status)) | |
5364 | ;; Get basic path from environment | |
5365 | (let ((env-vars (if (equal which "tex") (list "TEXINPUTS") | |
5366 | reftex-bibpath-environment-variables))) | |
5367 | (set pathvar (reftex-parse-colon-path | |
5368 | (mapconcat (lambda(x) (or (getenv x) "")) | |
5369 | env-vars path-separator)))) | |
5370 | (put pathvar 'status 'split) | |
5371 | ;; Check if we have recursive elements | |
5372 | (let ((path (symbol-value pathvar)) dir rec) | |
5373 | (while (setq dir (pop path)) | |
5374 | (when (string= (substring dir -2) "//") | |
5375 | (if (file-name-absolute-p dir) | |
5376 | (setq rec (or rec 'absolute)) | |
5377 | (setq rec 'relative)))) | |
5378 | (put pathvar 'rec-type rec))) | |
5379 | ||
5380 | (if recurse | |
5381 | ;; Return the recursive expansion of the path | |
5382 | (cond | |
5383 | ((not (get pathvar 'rec-type)) | |
5384 | ;; Path does not contain recursive elements - use simple path | |
5385 | (symbol-value pathvar)) | |
5386 | ((or (not (get pathvar 'recursive-path)) | |
5387 | (and (eq (get pathvar 'rec-type) 'relative) | |
5388 | (not (equal master-dir (get pathvar 'master-dir))))) | |
5389 | ;; Either: We don't have a recursive expansion yet. | |
5390 | ;; or: Relative recursive path elements need to be expanded | |
5391 | ;; relative to new default directory | |
5392 | (message "Expanding search path to find %s file: %s ..." which file) | |
5393 | (put pathvar 'recursive-path | |
5394 | (reftex-expand-path (symbol-value pathvar) master-dir)) | |
5395 | (put pathvar 'master-dir master-dir) | |
5396 | (get pathvar 'recursive-path)) | |
5397 | (t | |
5398 | ;; Recursive path computed earlier is still OK. | |
5399 | (get pathvar 'recursive-path))) | |
5400 | ;; The simple path was requested | |
5401 | (symbol-value pathvar)))) | |
5402 | ||
5403 | (defun reftex-find-file-on-path (file path &optional def-dir) | |
5404 | ;; Find FILE along the directory list PATH. | |
5405 | ;; DEF-DIR is the default directory for expanding relative path elements. | |
5406 | (catch 'exit | |
5407 | (when (file-name-absolute-p file) | |
a6611c0d | 5408 | (if (file-regular-p file) |
b849548d CD |
5409 | (throw 'exit file) |
5410 | (throw 'exit nil))) | |
5411 | (let* ((thepath path) file1 dir ) | |
5412 | (while (setq dir (pop thepath)) | |
5413 | (when (string= (substring dir -2) "//") | |
5414 | (setq dir (substring dir 0 -1))) | |
5415 | (setq file1 (expand-file-name file (expand-file-name dir def-dir))) | |
a6611c0d | 5416 | (if (file-regular-p file1) |
b849548d CD |
5417 | (throw 'exit file1))) |
5418 | ;; No such file | |
5419 | nil))) | |
5420 | ||
5421 | (defun reftex-parse-colon-path (path) | |
5422 | ;; Like parse-colon-parse, but // or /~ are left alone. | |
5423 | ;; Trailing ! or !! will be converted into `//' (emTeX convention) | |
5424 | (mapcar | |
5425 | (lambda (dir) | |
5426 | (if (string-match "\\(//+\\|/*!+\\)\\'" dir) | |
5427 | (setq dir (replace-match "//" t t dir))) | |
5428 | (file-name-as-directory dir)) | |
5429 | (delete "" (split-string path (concat path-separator "+"))))) | |
5430 | ||
5431 | (defun reftex-expand-path (path &optional default-dir) | |
5432 | ;; Expand parts of path ending in `//' recursively into directory list. | |
5433 | ;; Relative recursive path elements are expanded relative to DEFAULT-DIR. | |
5434 | (let (path1 dir recursive) | |
5435 | (while (setq dir (pop path)) | |
5436 | (if (setq recursive (string= (substring dir -2) "//")) | |
5437 | (setq dir (substring dir 0 -1))) | |
5438 | (if (and recursive | |
5439 | (not (file-name-absolute-p dir))) | |
5440 | (setq dir (expand-file-name dir default-dir))) | |
5441 | (if recursive | |
5442 | ;; Expand recursively | |
5443 | (setq path1 (append (reftex-recursive-directory-list dir) path1)) | |
5444 | ;; Keep unchanged | |
5445 | (push dir path1))) | |
5446 | (nreverse path1))) | |
a7ec1775 | 5447 | |
b849548d CD |
5448 | (defun reftex-recursive-directory-list (dir) |
5449 | ;; Return a list of all directories below DIR, including DIR itself | |
5450 | (let ((path (list dir)) path1 file files) | |
5451 | (while (setq dir (pop path)) | |
5452 | (when (file-directory-p dir) | |
5453 | (setq files (nreverse (directory-files dir t "[^.]"))) | |
5454 | (while (setq file (pop files)) | |
5455 | (if (file-directory-p file) | |
5456 | (push (file-name-as-directory file) path))) | |
5457 | (push dir path1))) | |
5458 | path1)) | |
a7ec1775 | 5459 | |
b849548d CD |
5460 | ;;; ========================================================================= |
5461 | ;;; | |
5462 | ;;; Some generally useful functions | |
a7ec1775 RS |
5463 | |
5464 | (defun reftex-no-props (string) | |
5465 | ;; Return STRING with all text properties removed | |
5466 | (and (stringp string) | |
5467 | (set-text-properties 0 (length string) nil string)) | |
5468 | string) | |
5469 | ||
396e0b08 KH |
5470 | (defun reftex-match-string (n) |
5471 | ;; Match string without properties | |
5472 | (when (match-beginning n) | |
5473 | (buffer-substring-no-properties (match-beginning n) (match-end n)))) | |
5474 | ||
2faef409 | 5475 | (defun reftex-kill-buffer (buffer) |
29d593f8 | 5476 | ;; Kill buffer if it exists. |
2faef409 RS |
5477 | (and (setq buffer (get-buffer buffer)) |
5478 | (kill-buffer buffer))) | |
5479 | ||
29d593f8 KH |
5480 | (defun reftex-erase-buffer (&optional buffer) |
5481 | ;; Erase BUFFER if it exists. BUFFER defaults to current buffer. | |
5482 | ;; This even erases read-only buffers. | |
5483 | (cond | |
5484 | ((null buffer) | |
5485 | ;; erase current buffer | |
5486 | (let ((buffer-read-only nil)) (erase-buffer))) | |
5487 | ((setq buffer (get-buffer buffer)) | |
5488 | ;; buffer exists | |
5489 | (save-excursion | |
5490 | (set-buffer buffer) | |
5491 | (let ((buffer-read-only nil)) (erase-buffer)))))) | |
2faef409 | 5492 | |
396e0b08 KH |
5493 | (defun reftex-this-word (&optional class) |
5494 | ;; Grab the word around point. | |
5495 | (setq class (or class "-a-zA-Z0-9:_/.*;|")) | |
5496 | (save-excursion | |
5497 | (buffer-substring-no-properties | |
5498 | (progn (skip-chars-backward class) (point)) | |
5499 | (progn (skip-chars-forward class) (point))))) | |
5500 | ||
b849548d CD |
5501 | (defun reftex-all-assq (key list) |
5502 | ;; Return a list of all associations of KEY in LIST. Comparison with eq. | |
5503 | (let (rtn) | |
5504 | (while (setq list (memq (assq key list) list)) | |
5505 | (push (car list) rtn) | |
5506 | (pop list)) | |
5507 | (nreverse rtn))) | |
5508 | ||
5509 | (defun reftex-all-assoc-string (key list) | |
5510 | ;; Return a list of all associations of KEY in LIST. Comparison with string=. | |
5511 | (let (rtn) | |
5512 | (while list | |
5513 | (if (string= (car (car list)) key) | |
5514 | (push (car list) rtn)) | |
5515 | (pop list)) | |
5516 | (nreverse rtn))) | |
5517 | ||
5518 | (defun reftex-last-assoc-before-elt (key elt list) | |
5519 | ;; Find the last association of KEY in LIST before or at ELT | |
5520 | ;; ELT is found in LIST with equal, not eq. | |
5521 | ;; Returns nil when either KEY or elt are not found in LIST. | |
5522 | ;; On success, returns the association. | |
5523 | (let* ((elt (car (member elt list))) ass last-ass) | |
5524 | ||
5525 | (while (and (setq ass (assoc key list)) | |
5526 | (setq list (memq ass list)) | |
5527 | (memq elt list)) | |
5528 | (setq last-ass ass | |
5529 | list (cdr list))) | |
5530 | last-ass)) | |
5531 | ||
baec1250 | 5532 | (defvar enable-multibyte-characters) |
396e0b08 KH |
5533 | (defun reftex-truncate (string ncols &optional ellipses padding) |
5534 | ;; Truncate a string to NCHAR characters. | |
5535 | ;; Works fast with ASCII and correctly with Mule characters. | |
5536 | ;; When ELLIPSES is non-nil, put three dots at the end of the string. | |
b849548d | 5537 | ;; When padding is non-nil, fills with white space to NCOLS characters. |
396e0b08 KH |
5538 | (setq string |
5539 | (cond | |
5540 | ((and (boundp 'enable-multibyte-characters) | |
b849548d | 5541 | enable-multibyte-characters |
a6611c0d | 5542 | (fboundp 'string-width) |
b849548d | 5543 | (fboundp 'truncate-string-to-width)) |
396e0b08 KH |
5544 | (if (<= (string-width string) ncols) |
5545 | string | |
5546 | (if ellipses | |
5547 | (concat (truncate-string-to-width string (- ncols 3)) "...") | |
5548 | (truncate-string-to-width string ncols)))) | |
5549 | (t | |
5550 | (if (<= (length string) ncols) | |
5551 | string | |
5552 | (if ellipses | |
5553 | (concat (substring string 0 (- ncols 3)) "...") | |
5554 | (substring string 0 ncols)))))) | |
5555 | (if padding | |
5556 | (format (format "%%-%ds" ncols) string) | |
5557 | string)) | |
5558 | ||
b849548d CD |
5559 | (defun reftex-nearest-match (regexp &optional pos) |
5560 | ;; Find the nearest match of REGEXP. Set the match data. | |
5561 | ;; If POS is given, calculate distances relative to it. | |
5562 | ;; Return nil if there is no match. | |
5563 | (let ((start (point)) (pos (or pos (point))) match1 match2 match) | |
5564 | (goto-char start) | |
5565 | (when (re-search-backward regexp nil t) | |
5566 | (setq match1 (match-data))) | |
5567 | (goto-char start) | |
5568 | (when (re-search-forward regexp nil t) | |
5569 | (setq match2 (match-data))) | |
5570 | (goto-char start) | |
5571 | (setq match | |
5572 | (cond | |
5573 | ((not match1) match2) | |
5574 | ((not match2) match1) | |
5575 | ((< (abs (- pos (car match1))) (abs (- pos (car match2)))) match1) | |
5576 | (t match2))) | |
5577 | (if match (progn (set-match-data match) t) nil))) | |
5578 | ||
5579 | (defun reftex-auto-mode-alist () | |
5580 | ;; Return an `auto-mode-alist' with only the .gz (etc) thingies. | |
5581 | ;; Stolen from gnus nnheader. | |
5582 | (let ((alist auto-mode-alist) | |
5583 | out) | |
5584 | (while alist | |
5585 | (when (listp (cdr (car alist))) | |
5586 | (push (car alist) out)) | |
5587 | (pop alist)) | |
5588 | (nreverse out))) | |
5589 | ||
5590 | (defun reftex-enlarge-to-fit (buf2 &optional keep-current) | |
5591 | ;; Enlarge other window displaying buffer to show whole buffer if possible. | |
5592 | ;; If KEEP-CURRENT in non-nil, current buffer must remain visible. | |
5593 | (let* ((win1 (selected-window)) | |
5594 | (buf1 (current-buffer)) | |
5595 | (win2 (get-buffer-window buf2))) | |
5596 | (when win2 | |
5597 | (select-window win2) | |
5598 | (unless (and (pos-visible-in-window-p 1) | |
5599 | (pos-visible-in-window-p (point-max))) | |
5600 | (enlarge-window (1+ (- (count-lines 1 (point-max)) | |
5601 | (window-height)))))) | |
5602 | (cond | |
5603 | ((window-live-p win1) (select-window win1)) | |
5604 | (keep-current | |
5605 | ;; we must have the old buffer! | |
5606 | (switch-to-buffer-other-window buf1) | |
5607 | (shrink-window (- (window-height) window-min-height)))))) | |
5608 | ||
5609 | (defun reftex-select-with-char (prompt help-string &optional delay-time scroll) | |
5610 | ;; Offer to select something with PROMPT and, after DELAY-TIME seconds, | |
5611 | ;; also with HELP-STRING. | |
5612 | ;; When SCROLL is non-nil, use SPC and DEL to scroll help window. | |
5613 | (let ((char ?\?)) | |
5614 | (save-window-excursion | |
5615 | (catch 'exit | |
5616 | (message (concat prompt " (?=Help)")) | |
5617 | (when (or (sit-for (or delay-time 0)) | |
5618 | (= ?\? (setq char (read-char-exclusive)))) | |
5619 | (with-output-to-temp-buffer " *RefTeX Help*" | |
5620 | (princ help-string)) | |
5621 | (reftex-enlarge-to-fit " *RefTeX Help*") | |
5622 | (select-window (get-buffer-window " *RefTeX Help*")) | |
5623 | (setq truncate-lines t)) | |
5624 | (setq prompt (concat prompt (if scroll " (SPC/DEL=Scroll)" ""))) | |
5625 | (message prompt) | |
5626 | (and (equal char ?\?) (setq char (read-char-exclusive))) | |
5627 | (while t | |
5628 | (cond ((equal char ?\C-g) (keyboard-quit)) | |
5629 | ((equal char ?\?)) | |
5630 | ((and scroll (equal char ?\ )) | |
5631 | (condition-case nil (scroll-up) (error nil)) | |
5632 | (message prompt)) | |
5633 | ((and scroll (equal char ?\C-? )) | |
5634 | (condition-case nil (scroll-down) (error nil)) | |
5635 | (message prompt)) | |
5636 | (t (throw 'exit char))) | |
5637 | (setq char (read-char-exclusive))))))) | |
5638 | ||
5639 | (defun reftex-make-regexp-allow-for-ctrl-m (string) | |
5640 | ;; convert STRING into a regexp, allowing ^M for \n and vice versa | |
5641 | (let ((start -2)) | |
5642 | (setq string (regexp-quote string)) | |
5643 | (while (setq start (string-match "[\n\r]" string (+ 3 start))) | |
5644 | (setq string (replace-match "[\n\r]" nil t string))) | |
5645 | string)) | |
5646 | ||
5647 | (defun reftex-get-buffer-visiting (file) | |
5648 | ;; return a buffer visiting FILE | |
5649 | (cond | |
5650 | ((boundp 'find-file-compare-truenames) ; XEmacs | |
5651 | (let ((find-file-compare-truenames t)) | |
5652 | (get-file-buffer file))) | |
5653 | ((fboundp 'find-buffer-visiting) ; Emacs | |
5654 | (find-buffer-visiting file)) | |
5655 | (t (error "This should not happen (reftex-get-buffer-visiting)")))) | |
5656 | ||
5657 | ;; Define `current-message' for compatibility with XEmacs prior to 20.4 | |
5658 | (defvar message-stack) | |
5659 | (if (and (featurep 'xemacs) | |
5660 | (not (fboundp 'current-message))) | |
5661 | (defun current-message (&optional frame) | |
5662 | (cdr (car message-stack)))) | |
5663 | ||
5664 | (defun reftex-visited-files (list) | |
5665 | ;; Takes a list of filenames and returns the buffers of those already visited | |
5666 | (delq nil (mapcar (lambda (x) (if (reftex-get-buffer-visiting x) x nil)) | |
5667 | list))) | |
5668 | ||
5669 | (defun reftex-get-file-buffer-force (file &optional mark-to-kill) | |
5670 | ;; Return a buffer visiting file. Make one, if necessary. | |
5671 | ;; If neither such a buffer nor the file exist, return nil. | |
5672 | ;; If MARK-TO-KILL is t and there is no live buffer, visit the file with | |
5673 | ;; initializations according to `reftex-initialize-temporary-buffers', | |
5674 | ;; and mark the buffer to be killed after use. | |
5675 | ||
5676 | (let ((buf (reftex-get-buffer-visiting file))) | |
5677 | ||
5678 | (cond (buf | |
5679 | ;; We have it already as a buffer - just return it | |
5680 | buf) | |
5681 | ||
5682 | ((file-readable-p file) | |
5683 | ;; At least there is such a file and we can read it. | |
5684 | ||
5685 | (if (or (not mark-to-kill) | |
5686 | (eq t reftex-initialize-temporary-buffers)) | |
5687 | ||
5688 | ;; Visit the file with full magic | |
5689 | (setq buf (find-file-noselect file)) | |
5690 | ||
5691 | ;; Else: Visit the file just briefly, without or | |
5692 | ;; with limited Magic | |
5693 | ||
5694 | ;; The magic goes away | |
5695 | (let ((format-alist nil) | |
5696 | (auto-mode-alist (reftex-auto-mode-alist)) | |
5697 | (default-major-mode 'fundamental-mode) | |
5698 | (enable-local-variables nil) | |
5699 | (after-insert-file-functions nil)) | |
5700 | (setq buf (find-file-noselect file))) | |
5701 | ||
5702 | ;; Is there a hook to run? | |
5703 | (when (listp reftex-initialize-temporary-buffers) | |
5704 | (save-excursion | |
5705 | (set-buffer buf) | |
5706 | (run-hooks 'reftex-initialize-temporary-buffers)))) | |
5707 | ||
5708 | ;; Lets see if we got a license to kill :-| | |
5709 | (and mark-to-kill | |
5710 | (add-to-list 'reftex-buffers-to-kill buf)) | |
5711 | ||
5712 | ;; Return the new buffer | |
5713 | buf) | |
5714 | ||
5715 | ;; If no such file exists, return nil | |
5716 | (t nil)))) | |
5717 | ||
5718 | (defun reftex-kill-temporary-buffers (&optional buffer) | |
5719 | ;; Kill all buffers in the list reftex-kill-temporary-buffers. | |
5720 | (cond | |
5721 | (buffer | |
5722 | (when (member buffer reftex-buffers-to-kill) | |
5723 | (kill-buffer buffer) | |
5724 | (setq reftex-buffers-to-kill | |
5725 | (delete buffer reftex-buffers-to-kill)))) | |
5726 | (t | |
5727 | (while (setq buffer (pop reftex-buffers-to-kill)) | |
5728 | (when (bufferp buffer) | |
5729 | (and (buffer-modified-p buffer) | |
5730 | (y-or-n-p (format "Save file %s? " | |
5731 | (buffer-file-name buffer))) | |
5732 | (save-excursion | |
5733 | (set-buffer buffer) | |
5734 | (save-buffer))) | |
5735 | (kill-buffer buffer)) | |
5736 | (pop reftex-buffers-to-kill))))) | |
5737 | ||
5738 | (defun reftex-splice-symbols-into-list (list alist) | |
5739 | ;; Splice the association in ALIST of any symbols in LIST into the list. | |
5740 | ;; Return new list. | |
5741 | (let (rtn tmp) | |
5742 | (while list | |
5743 | (while (and (not (null (car list))) ;; keep list elements nil | |
5744 | (symbolp (car list))) | |
5745 | (setq tmp (car list)) | |
5746 | (cond | |
5747 | ((assoc tmp alist) | |
5748 | (setq list (append (nth 2 (assoc tmp alist)) (cdr list)))) | |
5749 | (t | |
5750 | (error "Cannot treat symbol %s in reftex-label-alist" | |
5751 | (symbol-name tmp))))) | |
5752 | (push (pop list) rtn)) | |
5753 | (nreverse rtn))) | |
5754 | ||
5755 | (defun reftex-uniquify-by-car (alist &optional keep-list) | |
5756 | ;; Return a list of all elements in ALIST, but each car only once. | |
5757 | ;; Elements of KEEP-LIST are not removed even if duplicate. | |
5758 | (let (new elm) | |
5759 | (while alist | |
5760 | (setq elm (pop alist)) | |
5761 | (if (or (member (car elm) keep-list) | |
5762 | (not (assoc (car elm) new))) | |
5763 | (push elm new))) | |
5764 | (nreverse new))) | |
5765 | ||
5766 | ;;; ========================================================================= | |
5767 | ;;; | |
5768 | ;;; Fontification and Highlighting | |
5769 | ||
5770 | (defun reftex-use-fonts () | |
5771 | ;; Return t if we can and want to use fonts. | |
5772 | (and window-system | |
5773 | reftex-use-fonts | |
5774 | (featurep 'font-lock))) | |
5775 | ||
5776 | (defun reftex-refontify () | |
5777 | ;; Return t if we need to refontify context | |
5778 | (and (reftex-use-fonts) | |
5779 | (or (eq t reftex-refontify-context) | |
5780 | (and (eq 1 reftex-refontify-context) | |
5781 | ;; Test of we use the font-lock version of x-symbol | |
5782 | (and (featurep 'x-symbol-tex) (not (boundp 'x-symbol-mode))))))) | |
5783 | ||
5784 | (defun reftex-fontify-select-label-buffer (parent-buffer) | |
5785 | ;; Fontify the `*RefTeX Select*' buffer. Buffer is temporarily renamed to | |
5786 | ;; start with none-SPC char, beacuse Font-Lock otherwise refuses operation. | |
5787 | (run-hook-with-args 'reftex-pre-refontification-functions | |
5788 | parent-buffer 'reftex-ref) | |
5789 | (let* ((oldname (buffer-name)) | |
5790 | (newname (concat "Fontify-me-" oldname))) | |
5791 | (unwind-protect | |
5792 | (progn | |
5793 | ;; Rename buffer temporarily to start w/o space (because of font-lock) | |
5794 | (rename-buffer newname t) | |
5795 | (cond | |
5796 | ((fboundp 'font-lock-default-fontify-region) | |
5797 | ;; Good: we have the indirection functions | |
5798 | (set (make-local-variable 'font-lock-fontify-region-function) | |
5799 | 'reftex-select-font-lock-fontify-region) | |
5800 | (let ((major-mode 'latex-mode)) | |
5801 | (font-lock-mode 1))) | |
5802 | ((fboundp 'font-lock-set-defaults-1) | |
5803 | ;; Looks like the XEmacs font-lock stuff. | |
5804 | ;; FIXME: this is still kind of a hack. | |
5805 | (set (make-local-variable 'font-lock-keywords) nil) | |
5806 | (let ((major-mode 'latex-mode) | |
5807 | (font-lock-defaults-computed nil)) | |
5808 | (font-lock-set-defaults-1) | |
5809 | (reftex-select-font-lock-fontify-region (point-min) (point-max)))) | |
5810 | (t | |
5811 | ;; Oops? | |
5812 | (message "Sorry: cannot refontify RefTeX Select buffer.")))) | |
5813 | (rename-buffer oldname)))) | |
5814 | ||
5815 | (defun reftex-select-font-lock-fontify-region (beg end &optional loudly) | |
5816 | ;; Fontify a region, but only lines starting with a dot. | |
5817 | (let ((func (if (fboundp 'font-lock-default-fontify-region) | |
5818 | 'font-lock-default-fontify-region | |
5819 | 'font-lock-fontify-region)) | |
5820 | beg1 end1) | |
5821 | (goto-char beg) | |
5822 | (while (re-search-forward "^\\." end t) | |
5823 | (setq beg1 (point) end1 (progn (skip-chars-forward "^\n") (point))) | |
5824 | (funcall func beg1 end1 nil) | |
5825 | (goto-char end1)))) | |
5826 | ||
5827 | (defun reftex-select-font-lock-unfontify (&rest ignore) t) | |
396e0b08 | 5828 | |
b849548d CD |
5829 | (defun reftex-verified-face (&rest faces) |
5830 | ;; Return the first valid face in FACES, or nil if none is valid. | |
5831 | ;; Also, when finding a nil element in FACES, return nil. This | |
5832 | ;; function is just a safety net to catch name changes of builtin | |
5833 | ;; fonts. Currently it is only used for reftex-label-face, which has | |
5834 | ;; as default font-lock-reference-face, which was recently renamed | |
5835 | ;; to font-lock-constant-face. | |
5836 | (let (face) | |
5837 | (catch 'exit | |
5838 | (while (setq face (pop faces)) | |
5839 | (if (featurep 'xemacs) | |
5840 | (if (find-face face) (throw 'exit face)) | |
5841 | (if (facep face) (throw 'exit face))))))) | |
396e0b08 | 5842 | |
b849548d CD |
5843 | ;; Highlighting uses overlays. For XEmacs, we need the emulation. |
5844 | (if (featurep 'xemacs) (require 'overlay)) | |
5845 | ||
5846 | ;; We keep a vector with several different overlays to do our highlighting. | |
5847 | (defvar reftex-highlight-overlays [nil nil]) | |
5848 | ||
5849 | ;; Initialize the overlays | |
5850 | (aset reftex-highlight-overlays 0 (make-overlay 1 1)) | |
5851 | (overlay-put (aref reftex-highlight-overlays 0) | |
5852 | 'face 'highlight) | |
5853 | (aset reftex-highlight-overlays 1 (make-overlay 1 1)) | |
5854 | (overlay-put (aref reftex-highlight-overlays 1) | |
5855 | 'face reftex-cursor-selected-face) | |
5856 | ||
5857 | ;; Two functions for activating and deactivation highlight overlays | |
5858 | (defun reftex-highlight (index begin end &optional buffer) | |
5859 | "Highlight a region with overlay INDEX." | |
5860 | (move-overlay (aref reftex-highlight-overlays index) | |
5861 | begin end (or buffer (current-buffer)))) | |
5862 | (defun reftex-unhighlight (index) | |
5863 | "Detach overlay INDEX." | |
5864 | (delete-overlay (aref reftex-highlight-overlays index))) | |
5865 | ||
5866 | (defun reftex-highlight-shall-die () | |
5867 | ;; Function used in pre-command-hook to remove highlights. | |
5868 | (remove-hook 'pre-command-hook 'reftex-highlight-shall-die) | |
5869 | (reftex-unhighlight 0)) | |
5870 | ||
5871 | ;;; ========================================================================= | |
5872 | ;;; | |
5873 | ;;; Functions to compile the tables, reset the mode etc. | |
2faef409 | 5874 | |
b849548d CD |
5875 | ;; A list of all variables in the cache. |
5876 | ;; The cache is used to save the compiled versions of some variables. | |
5877 | (defconst reftex-cache-variables | |
5878 | '(reftex-memory ;; This MUST ALWAYS be the first! | |
5879 | reftex-env-or-mac-alist reftex-everything-regexp | |
5880 | reftex-find-label-regexp-format reftex-find-label-regexp-format2 | |
5881 | reftex-label-env-list reftex-label-mac-list | |
5882 | reftex-section-or-include-regexp reftex-section-levels-all | |
5883 | reftex-section-regexp reftex-type-query-help | |
5884 | reftex-type-query-prompt reftex-typekey-list | |
5885 | reftex-typekey-to-format-alist reftex-typekey-to-prefix-alist | |
5886 | reftex-words-to-typekey-alist)) | |
5887 | ||
5888 | (defun reftex-ensure-compiled-variables () | |
5889 | ;; Recompile the label alist when necessary | |
5890 | (let* ((mem reftex-memory) | |
5891 | (cache (get reftex-docstruct-symbol 'reftex-cache)) | |
5892 | (cmem (car cache)) | |
5893 | (alist reftex-label-alist) | |
5894 | (levels (get reftex-docstruct-symbol 'reftex-section-levels)) | |
5895 | (style (get reftex-docstruct-symbol 'reftex-label-alist-style)) | |
5896 | (default reftex-default-label-alist-entries)) | |
396e0b08 | 5897 | (cond |
b849548d CD |
5898 | (reftex-tables-dirty (reftex-compile-variables)) |
5899 | ((and (eq alist (nth 0 mem)) | |
5900 | (eq levels (nth 1 mem)) | |
5901 | (eq style (nth 2 mem)) | |
5902 | (eq default (nth 3 mem)))) ;; everything is OK | |
5903 | ((and (eq alist (nth 0 cmem)) | |
5904 | (eq levels (nth 1 cmem)) | |
5905 | (eq style (nth 2 cmem)) | |
5906 | (eq default (nth 2 cmem))) | |
5907 | ;; restore the cache | |
5908 | (message "Restoring cache") | |
5909 | (mapcar (lambda (sym) (set sym (pop cache))) reftex-cache-variables)) | |
5910 | (t (reftex-compile-variables))))) | |
396e0b08 | 5911 | |
b849548d CD |
5912 | (defun reftex-reset-mode () |
5913 | "Reset RefTeX Mode. | |
5914 | This will re-compile the configuration information and remove all | |
5915 | current scanning information and the parse file to enforce a rescan | |
5916 | on next use." | |
5917 | (interactive) | |
a7ec1775 | 5918 | |
b849548d CD |
5919 | ;; Reset the file search path variables |
5920 | (loop for prop in '(status master-dir recursive-path rec-type) do | |
5921 | (put 'reftex-tex-path prop nil) | |
5922 | (put 'reftex-bib-path prop nil)) | |
396e0b08 | 5923 | |
b849548d CD |
5924 | ;; Kill temporary buffers associated with RefTeX - just in case they |
5925 | ;; were not cleaned up properly | |
5926 | (save-excursion | |
5927 | (let ((buffer-list '("*RefTeX Help*" "*RefTeX Select*" | |
5928 | "*Duplicate Labels*" "*toc*" " *RefTeX-scratch*")) | |
5929 | buf) | |
5930 | (while (setq buf (pop buffer-list)) | |
5931 | (if (get-buffer buf) | |
5932 | (kill-buffer buf)))) | |
5933 | (reftex-erase-all-selection-buffers)) | |
396e0b08 | 5934 | |
b849548d CD |
5935 | ;; Make sure the current document will be rescanned soon. |
5936 | (reftex-reset-scanning-information) | |
a7ec1775 | 5937 | |
b849548d CD |
5938 | ;; Remove any parse info file |
5939 | (reftex-access-parse-file 'kill) | |
396e0b08 | 5940 | |
b849548d CD |
5941 | ;; Plug functions into AUCTeX if the user option says so. |
5942 | (and reftex-plug-into-AUCTeX | |
5943 | (reftex-plug-into-AUCTeX)) | |
a7ec1775 | 5944 | |
b849548d | 5945 | (reftex-compile-variables)) |
a7ec1775 | 5946 | |
b849548d CD |
5947 | (defun reftex-reset-scanning-information () |
5948 | "Reset the symbols containing information from buffer scanning. | |
5949 | This enforces rescanning the buffer on next use." | |
5950 | (if (string= reftex-last-toc-master (reftex-TeX-master-file)) | |
5951 | (reftex-erase-buffer "*toc*")) | |
5952 | (let ((symlist reftex-multifile-symbols) | |
5953 | symbol) | |
5954 | (while symlist | |
5955 | (setq symbol (car symlist) | |
5956 | symlist (cdr symlist)) | |
5957 | (if (and (symbolp (symbol-value symbol)) | |
5958 | (not (null (symbol-value symbol)))) | |
5959 | (set (symbol-value symbol) nil))))) | |
a7ec1775 | 5960 | |
b849548d CD |
5961 | (defun reftex-erase-all-selection-buffers () |
5962 | ;; Remove all selection buffers associated with current document. | |
5963 | (mapcar | |
5964 | (lambda (type) | |
5965 | (reftex-erase-buffer (reftex-make-selection-buffer-name type))) | |
5966 | reftex-typekey-list)) | |
396e0b08 | 5967 | |
b849548d CD |
5968 | (defun reftex-compile-variables () |
5969 | ;; Compile the information in reftex-label-alist & Co. | |
396e0b08 | 5970 | |
b849548d | 5971 | (message "Compiling label environment definitions...") |
396e0b08 | 5972 | |
b849548d CD |
5973 | ;; Update AUCTeX style information |
5974 | (when (and (featurep 'tex-site) (fboundp 'TeX-update-style)) | |
5975 | (condition-case nil (TeX-update-style) (error nil))) | |
396e0b08 | 5976 | |
b849548d CD |
5977 | ;; Record that we have done this, and what we have used. |
5978 | (setq reftex-tables-dirty nil) | |
5979 | (setq reftex-memory | |
5980 | (list reftex-label-alist | |
5981 | (get reftex-docstruct-symbol 'reftex-section-levels) | |
5982 | (get reftex-docstruct-symbol 'reftex-label-alist-style) | |
5983 | reftex-default-label-alist-entries)) | |
5984 | ||
5985 | ;; Compile information in reftex-label-alist | |
5986 | (let ((all (reftex-uniquify-by-car | |
5987 | (reftex-splice-symbols-into-list | |
5988 | (append reftex-label-alist | |
5989 | (get reftex-docstruct-symbol 'reftex-label-alist-style) | |
5990 | reftex-default-label-alist-entries) | |
5991 | reftex-label-alist-builtin) | |
5992 | '(nil))) | |
5993 | entry env-or-mac typekeychar typekey prefix context word | |
5994 | fmt reffmt labelfmt wordlist qh-list macros-with-labels | |
5995 | nargs nlabel opt-args cell sum i) | |
5996 | ||
5997 | (setq reftex-words-to-typekey-alist nil | |
5998 | reftex-typekey-list nil | |
5999 | reftex-typekey-to-format-alist nil | |
6000 | reftex-typekey-to-prefix-alist nil | |
6001 | reftex-env-or-mac-alist nil | |
6002 | reftex-label-env-list nil | |
6003 | reftex-label-mac-list nil) | |
6004 | (while all | |
6005 | (catch 'next-entry | |
6006 | (setq entry (car all) | |
6007 | env-or-mac (car entry) | |
6008 | entry (cdr entry) | |
6009 | all (cdr all)) | |
6010 | (if (null env-or-mac) | |
6011 | (setq env-or-mac "")) | |
6012 | (if (stringp (car entry)) | |
6013 | ;; This is before version 2.00 - convert entry to new format | |
6014 | ;; This is just to keep old users happy | |
6015 | (setq entry (cons (string-to-char (car entry)) | |
6016 | (cons (concat (car entry) ":") | |
6017 | (cdr entry))))) | |
6018 | (setq typekeychar (nth 0 entry) | |
6019 | typekey (if typekeychar (char-to-string typekeychar) nil) | |
6020 | prefix (nth 1 entry) | |
6021 | fmt (nth 2 entry) | |
6022 | context (nth 3 entry) | |
6023 | wordlist (nth 4 entry)) | |
6024 | (if (stringp wordlist) | |
6025 | ;; This is before version 2.04 - convert to new format | |
6026 | (setq wordlist (nthcdr 4 entry))) | |
6027 | ||
6028 | (if (and (stringp fmt) | |
6029 | (string-match "@" fmt)) | |
6030 | ;; Special syntax for specifying a label format | |
6031 | (setq fmt (split-string fmt "@+")) | |
6032 | (setq fmt (list "\\label{%s}" fmt))) | |
6033 | (setq labelfmt (car fmt) | |
6034 | reffmt (nth 1 fmt)) | |
6035 | ;; Note a new typekey | |
6036 | (if typekey | |
6037 | (add-to-list 'reftex-typekey-list typekey)) | |
6038 | (if (and typekey prefix | |
6039 | (not (assoc typekey reftex-typekey-to-prefix-alist))) | |
6040 | (add-to-list 'reftex-typekey-to-prefix-alist | |
6041 | (cons typekey prefix))) | |
6042 | ;; Check if this is a macro or environment | |
6043 | (cond | |
6044 | ((string-match "\\`\\\\" env-or-mac) | |
6045 | ;; It's a macro | |
6046 | (let ((result (reftex-parse-args env-or-mac))) | |
6047 | (setq env-or-mac (or (first result) env-or-mac) | |
6048 | nargs (second result) | |
6049 | nlabel (third result) | |
6050 | opt-args (fourth result)) | |
6051 | (if nlabel (add-to-list 'macros-with-labels env-or-mac))) | |
6052 | (if typekey (add-to-list 'reftex-label-mac-list env-or-mac))) | |
6053 | (t | |
6054 | ;; It's an environment | |
6055 | (setq nargs nil nlabel nil opt-args nil) | |
6056 | (cond ((string= env-or-mac "any")) | |
6057 | ((string= env-or-mac "")) | |
6058 | ((string= env-or-mac "section")) | |
6059 | (t | |
6060 | (add-to-list 'reftex-label-env-list env-or-mac))))) | |
6061 | ;; Translate some special context cases | |
6062 | (when (assq context reftex-default-context-regexps) | |
6063 | (setq context | |
6064 | (format | |
6065 | (cdr (assq context reftex-default-context-regexps)) | |
6066 | (regexp-quote env-or-mac)))) | |
6067 | ;; See if this is the first format for this typekey | |
6068 | (and reffmt | |
6069 | (not (assoc typekey reftex-typekey-to-format-alist)) | |
6070 | (push (cons typekey reffmt) reftex-typekey-to-format-alist)) | |
6071 | ;; See if this is the first definition for this env-or-mac | |
6072 | (and (not (string= env-or-mac "any")) | |
6073 | (not (string= env-or-mac "")) | |
6074 | (not (assoc env-or-mac reftex-env-or-mac-alist)) | |
6075 | (push (list env-or-mac typekey context labelfmt | |
6076 | nargs nlabel opt-args) | |
6077 | reftex-env-or-mac-alist)) | |
6078 | ;; Are the magic words regular expressions? Quote normal words. | |
6079 | (if (eq (car wordlist) 'regexp) | |
6080 | (setq wordlist (cdr wordlist)) | |
6081 | (setq wordlist (mapcar 'regexp-quote wordlist))) | |
6082 | ;; Remember the first association of each word. | |
6083 | (while (stringp (setq word (pop wordlist))) | |
6084 | (or (assoc word reftex-words-to-typekey-alist) | |
6085 | (push (cons word typekey) reftex-words-to-typekey-alist))) | |
6086 | (cond | |
6087 | ((string= "" env-or-mac) nil) | |
6088 | ((setq cell (assoc typekey qh-list)) | |
6089 | (push env-or-mac (cdr cell))) | |
6090 | (typekey | |
6091 | (push (list typekey env-or-mac) qh-list))))) | |
396e0b08 | 6092 | |
b849548d CD |
6093 | (setq reftex-typekey-to-prefix-alist |
6094 | (nreverse reftex-typekey-to-prefix-alist)) | |
396e0b08 | 6095 | |
b849548d CD |
6096 | ;; Prepare the typekey query prompt and help string. |
6097 | (setq qh-list | |
6098 | (sort qh-list (function | |
6099 | (lambda (x1 x2) (string< (car x1) (car x2)))))) | |
6100 | (setq reftex-type-query-prompt | |
6101 | (concat "Label type: [" | |
6102 | (mapconcat (function (lambda(x) (format "%s" (car x)))) | |
6103 | qh-list "") | |
6104 | "]")) | |
6105 | ;; In the help string, we need to wrap lines... | |
6106 | (setq reftex-type-query-help | |
6107 | (concat | |
6108 | "SELECT A LABEL TYPE:\n--------------------\n" | |
6109 | (mapconcat | |
6110 | (lambda(x) | |
6111 | (setq sum 0) | |
6112 | (format " [%s] %s" | |
6113 | (car x) | |
6114 | (mapconcat (lambda(env) | |
6115 | (setq sum (+ sum (length env))) | |
6116 | (if (< sum 60) | |
6117 | env | |
6118 | (setq sum 0) | |
6119 | (concat "\n " env))) | |
6120 | (cdr x) " "))) | |
6121 | qh-list "\n"))) | |
6122 | ||
6123 | ;; Convert magic words to regular expressions. We make regular expressions | |
6124 | ;; which allow for some chars from the ref format to be in the buffer. | |
6125 | ;; These characters will be seen and removed. | |
6126 | (setq reftex-words-to-typekey-alist | |
6127 | (mapcar | |
6128 | (lambda (x) | |
6129 | (setq word (car x) | |
6130 | typekey (cdr x) | |
6131 | fmt (cdr (assoc typekey reftex-typekey-to-format-alist))) | |
6132 | (setq word (concat "\\W\\(" word "[ \t\n\r]*\\)\\(")) | |
6133 | (setq i 0) | |
6134 | (while (and (< i 10) ; maximum number of format chars allowed | |
6135 | (< i (length fmt)) | |
6136 | (not (member (aref fmt i) '(?%)))) | |
6137 | (setq word (concat word "\\|" (regexp-quote | |
6138 | (substring fmt 0 (1+ i))))) | |
6139 | (incf i)) | |
6140 | (cons (concat word "\\)\\=") typekey)) | |
6141 | (nreverse reftex-words-to-typekey-alist))) | |
396e0b08 | 6142 | |
b849548d CD |
6143 | ;; Make the full list of section levels |
6144 | (setq reftex-section-levels-all | |
6145 | (append (get reftex-docstruct-symbol 'reftex-section-levels) | |
6146 | reftex-section-levels)) | |
396e0b08 | 6147 | |
b849548d CD |
6148 | ;; Calculate the regular expressions |
6149 | (let* ((wbol "\\(\\`\\|[\n\r]\\)[ \t]*") | |
6150 | (label-re "\\\\label{\\([^}]*\\)}") | |
6151 | (include-re (concat wbol "\\\\\\(include\\|input\\)[{ \t]+\\([^} \t\n\r]+\\)")) | |
6152 | (section-re | |
6153 | (concat wbol "\\\\\\(" | |
6154 | (mapconcat 'car reftex-section-levels-all "\\|") | |
6155 | "\\)\\*?\\(\\[[^]]*\\]\\)?{")) | |
6156 | (appendix-re (concat wbol "\\(\\\\appendix\\)")) | |
6157 | (macro-re | |
6158 | (if macros-with-labels | |
6159 | (concat "\\(" | |
6160 | (mapconcat 'regexp-quote macros-with-labels "\\|") | |
6161 | "\\)[[{]") | |
6162 | "")) | |
6163 | (find-label-re-format | |
6164 | (concat "\\(" | |
6165 | (mapconcat 'regexp-quote (append '("\\label") | |
6166 | macros-with-labels) "\\|") | |
6167 | "\\)\\([[{][^]}]*[]}]\\)*[[{]\\(%s\\)[]}]"))) | |
6168 | (setq reftex-section-regexp section-re | |
6169 | reftex-section-or-include-regexp | |
6170 | (concat section-re "\\|" include-re) | |
6171 | reftex-everything-regexp | |
6172 | (concat label-re "\\|" section-re "\\|" include-re | |
6173 | "\\|" appendix-re | |
6174 | (if macros-with-labels "\\|" "") macro-re) | |
6175 | reftex-find-label-regexp-format find-label-re-format | |
6176 | reftex-find-label-regexp-format2 | |
6177 | "\\([]} \t\n\r]\\)\\([[{]\\)\\(%s\\)[]}]") | |
6178 | (message "Compiling label environment definitions...done"))) | |
6179 | (put reftex-docstruct-symbol 'reftex-cache | |
6180 | (mapcar 'symbol-value reftex-cache-variables))) | |
396e0b08 | 6181 | |
b849548d CD |
6182 | ;;; ========================================================================= |
6183 | ;;; | |
6184 | ;;; Operations on entire Multifile documents | |
396e0b08 | 6185 | |
b849548d CD |
6186 | (defun reftex-create-tags-file () |
6187 | "Create TAGS file by running `etags' on the current document. | |
6188 | The TAGS file is also immediately visited with `visit-tags-table'." | |
6189 | (interactive) | |
6190 | (reftex-access-scan-info current-prefix-arg) | |
6191 | (let* ((master (reftex-TeX-master-file)) | |
6192 | (files (reftex-all-document-files)) | |
6193 | (cmd (format "etags %s" (mapconcat 'identity files " ")))) | |
6194 | (save-excursion | |
6195 | (set-buffer (reftex-get-buffer-visiting master)) | |
6196 | (message "Running etags to create TAGS file...") | |
6197 | (shell-command cmd) | |
6198 | (visit-tags-table "TAGS")))) | |
a7ec1775 | 6199 | |
b849548d CD |
6200 | ;; History of grep commands. |
6201 | (defvar reftex-grep-history nil) | |
6202 | (defvar reftex-grep-command "grep -n " | |
6203 | "Last grep command used in \\[reftex-grep-document]; default for next grep.") | |
a7ec1775 | 6204 | |
b849548d CD |
6205 | (defun reftex-grep-document (grep-cmd) |
6206 | "Run grep query through all files related to this document. | |
6207 | With prefix arg, force to rescan document. | |
a6611c0d | 6208 | No active TAGS table is required." |
a7ec1775 | 6209 | |
b849548d CD |
6210 | (interactive |
6211 | (list (read-from-minibuffer "Run grep on document (like this): " | |
6212 | reftex-grep-command nil nil | |
6213 | 'reftex-grep-history))) | |
6214 | (reftex-access-scan-info current-prefix-arg) | |
6215 | (let* ((files (reftex-all-document-files t)) | |
6216 | (cmd (format | |
6217 | "%s %s" grep-cmd | |
6218 | (mapconcat 'identity files " ")))) | |
6219 | (grep cmd))) | |
396e0b08 | 6220 | |
b849548d CD |
6221 | (defun reftex-search-document (&optional regexp) |
6222 | "Regexp search through all files of the current TeX document. | |
6223 | Starts always in the master file. Stops when a match is found. | |
6224 | To continue searching for next match, use command \\[tags-loop-continue]. | |
a6611c0d | 6225 | No active TAGS table is required." |
b849548d CD |
6226 | (interactive) |
6227 | (let ((default (reftex-this-word))) | |
6228 | (unless regexp | |
6229 | (setq regexp (read-string (format "Search regexp in document [%s]: " | |
6230 | default)))) | |
6231 | (if (string= regexp "") (setq regexp (regexp-quote default))) | |
a7ec1775 | 6232 | |
b849548d CD |
6233 | (reftex-access-scan-info current-prefix-arg) |
6234 | (tags-search regexp (list 'reftex-all-document-files)))) | |
2faef409 | 6235 | |
b849548d CD |
6236 | (defun reftex-query-replace-document (&optional from to delimited) |
6237 | "Run a query-replace-regexp of FROM with TO over the entire TeX document. | |
6238 | Third arg DELIMITED (prefix arg) means replace only word-delimited matches. | |
6239 | If you exit (\\[keyboard-quit] or ESC), you can resume the query replace | |
6240 | with the command \\[tags-loop-continue]. | |
a6611c0d | 6241 | No active TAGS table is required." |
b849548d CD |
6242 | (interactive) |
6243 | (let ((default (reftex-this-word))) | |
6244 | (unless from | |
6245 | (setq from (read-string (format "Replace regexp in document [%s]: " | |
6246 | default))) | |
6247 | (if (string= from "") (setq from (regexp-quote default)))) | |
6248 | (unless to | |
6249 | (setq to (read-string (format "Replace regexp %s with: " from)))) | |
6250 | (reftex-access-scan-info current-prefix-arg) | |
6251 | (tags-query-replace from to (or delimited current-prefix-arg) | |
6252 | (list 'reftex-all-document-files)))) | |
2faef409 | 6253 | |
b849548d CD |
6254 | (defun reftex-find-duplicate-labels () |
6255 | "Produce a list of all duplicate labels in the document." | |
a7ec1775 | 6256 | |
b849548d | 6257 | (interactive) |
a7ec1775 | 6258 | |
b849548d CD |
6259 | ;; Rescan the document to make sure |
6260 | (reftex-access-scan-info t) | |
a7ec1775 | 6261 | |
b849548d CD |
6262 | (let ((master (reftex-TeX-master-file)) |
6263 | (cnt 0) | |
6264 | (dlist | |
6265 | (mapcar | |
6266 | (function | |
6267 | (lambda (x) | |
6268 | (let (x1) | |
6269 | (cond | |
6270 | ((memq (car x) | |
6271 | '(toc bof eof bib thebib label-numbers xr xr-doc | |
6272 | master-dir file-error bibview-cache appendix | |
6273 | is-multi)) | |
6274 | nil) | |
6275 | (t | |
6276 | (setq x1 (reftex-all-assoc-string | |
6277 | (car x) (symbol-value reftex-docstruct-symbol))) | |
6278 | (if (< 1 (length x1)) | |
6279 | (append (list (car x)) | |
6280 | (mapcar (function | |
6281 | (lambda(x) | |
6282 | (abbreviate-file-name (nth 3 x)))) | |
6283 | x1)) | |
6284 | (list nil))))))) | |
6285 | (reftex-uniquify-by-car (symbol-value reftex-docstruct-symbol))))) | |
a7ec1775 | 6286 | |
b849548d CD |
6287 | (setq dlist (reftex-uniquify-by-car dlist)) |
6288 | (if (null dlist) (error "No duplicate labels in document")) | |
6289 | (switch-to-buffer-other-window "*Duplicate Labels*") | |
6290 | (make-local-variable 'TeX-master) | |
6291 | (setq TeX-master master) | |
6292 | (erase-buffer) | |
6293 | (insert " MULTIPLE LABELS IN CURRENT DOCUMENT:\n") | |
6294 | (insert | |
6295 | " Move point to label and type `r' to run a query-replace on the label\n" | |
6296 | " and its references. Type `q' to exit this buffer.\n\n") | |
6297 | (insert " LABEL FILE\n") | |
6298 | (insert " -------------------------------------------------------------\n") | |
6299 | (use-local-map (make-sparse-keymap)) | |
6300 | (local-set-key [?q] (function | |
6301 | (lambda () "Kill this buffer." (interactive) | |
6302 | (kill-buffer (current-buffer)) (delete-window)))) | |
6303 | (local-set-key [?r] 'reftex-change-label) | |
6304 | (while dlist | |
6305 | (when (and (car (car dlist)) | |
6306 | (cdr (car dlist))) | |
6307 | (incf cnt) | |
6308 | (insert (mapconcat 'identity (car dlist) "\n ") "\n")) | |
6309 | (pop dlist)) | |
6310 | (goto-char (point-min)) | |
6311 | (when (= cnt 0) | |
6312 | (kill-buffer (current-buffer)) | |
6313 | (delete-window) | |
6314 | (message "Document does not contain duplicate labels.")))) | |
a7ec1775 | 6315 | |
b849548d CD |
6316 | (defun reftex-change-label (&optional from to) |
6317 | "Query replace FROM with TO in all \\label and \\ref commands. | |
6318 | Works on the entire multifile document. | |
6319 | If you exit (\\[keyboard-quit] or ESC), you can resume the query replace | |
6320 | with the command \\[tags-loop-continue]. | |
a6611c0d | 6321 | No active TAGS table is required." |
b849548d CD |
6322 | (interactive) |
6323 | (let ((default (reftex-this-word "-a-zA-Z0-9_*.:"))) | |
6324 | (unless from | |
6325 | (setq from (read-string (format "Replace label globally [%s]: " | |
6326 | default)))) | |
6327 | (if (string= from "") (setq from default)) | |
6328 | (unless to | |
6329 | (setq to (read-string (format "Replace label %s with: " | |
6330 | from)))) | |
6331 | (reftex-query-replace-document | |
6332 | (concat "\\\\\\(label\\|[a-z]*ref\\){" (regexp-quote from) "}") | |
6333 | (format "\\\\\\1{%s}" to)))) | |
a7ec1775 | 6334 | |
b849548d CD |
6335 | (defun reftex-renumber-simple-labels () |
6336 | "Renumber all simple labels in the document to make them sequentially. | |
6337 | Simple labels are the ones created by RefTeX, consisting only of the | |
6338 | prefix and a number. After the command completes, all these labels will | |
6339 | have sequential numbers throughout the document. Any references to | |
6340 | the labels will be changed as well. For this, RefTeX looks at the | |
6341 | arguments of any macros which either start or end in the string `ref'. | |
6342 | This command should be used with care, in particular in multifile | |
6343 | documents. You should not use it if another document refers to this | |
6344 | one with the `xr' package." | |
a7ec1775 | 6345 | (interactive) |
b849548d CD |
6346 | ;; Resan the entire document |
6347 | (reftex-access-scan-info 1) | |
6348 | ;; Get some insurance | |
6349 | (if (and (reftex-is-multi) | |
6350 | (not (yes-or-no-p "Replacing all simple labels in multiple files is risky. Continue? "))) | |
6351 | (error "Abort")) | |
6352 | ;; Make the translation list | |
6353 | (let* ((re-core (concat "\\(" | |
6354 | (mapconcat 'cdr reftex-typekey-to-prefix-alist "\\|") | |
6355 | "\\)")) | |
6356 | (label-re (concat "\\`" re-core "\\([0-9]+\\)\\'")) | |
6357 | (search-re (concat "{\\(" re-core "\\([0-9]+\\)\\)}")) | |
6358 | (error-fmt "Undefined label or reference %s. Ignore and continue? ") | |
6359 | (label-numbers-alist (mapcar (lambda (x) (cons (cdr x) 0)) | |
6360 | reftex-typekey-to-prefix-alist)) | |
6361 | (files (reftex-all-document-files)) | |
6362 | (list (symbol-value reftex-docstruct-symbol)) | |
6363 | translate-alist n entry label new-label nr-cell changed-sequence) | |
6364 | ||
6365 | (while (setq entry (pop list)) | |
6366 | (when (and (stringp (car entry)) | |
6367 | (string-match label-re (car entry))) | |
6368 | (setq label (car entry) | |
6369 | nr-cell (assoc (match-string 1 (car entry)) | |
6370 | label-numbers-alist)) | |
6371 | (if (assoc label translate-alist) | |
6372 | (error "Duplicate label %s" label)) | |
6373 | (setq new-label (concat (match-string 1 (car entry)) | |
6374 | (incf (cdr nr-cell)))) | |
6375 | (push (cons label new-label) translate-alist) | |
6376 | (or (string= label new-label) (setq changed-sequence t)))) | |
6377 | ||
6378 | (unless changed-sequence | |
6379 | (error "Simple labels are already in correct sequence")) | |
6380 | ||
6381 | ;; Save all document buffers before this operation | |
6382 | (reftex-save-all-document-buffers) | |
6383 | ||
6384 | ;; First test to check for erros | |
6385 | (setq n (reftex-translate | |
6386 | files search-re translate-alist error-fmt 'test)) | |
6387 | ||
6388 | ;; Now the real thing. | |
6389 | (if (yes-or-no-p | |
6390 | (format "Replace %d items at %d places in %d files? " | |
6391 | (length translate-alist) n (length files))) | |
6392 | (progn | |
6393 | (let ((inhibit-quit t)) ;; Do not disturb... | |
6394 | (reftex-translate | |
6395 | files search-re translate-alist error-fmt nil) | |
6396 | (setq quit-flag nil)) | |
6397 | (if (and (reftex-is-multi) | |
6398 | (yes-or-no-p "Save entire document? ")) | |
6399 | (reftex-save-all-document-buffers)) | |
6400 | ;; Rescan again... | |
6401 | (reftex-access-scan-info 1) | |
6402 | (message "Done replacing simple labels.")) | |
6403 | (message "No replacements done")))) | |
6404 | ||
6405 | (defun reftex-translate (files search-re translate-alist error-fmt test) | |
6406 | ;; In FILES, look for SEARCH-RE and replace match 1 of it with | |
6407 | ;; its association in TRANSLATE-ALSIT. | |
6408 | ;; If we do not find an association and TEST is non-nil, query | |
6409 | ;; to ignore the problematic string. | |
6410 | ;; If TEST is nil, it is ignored without query. | |
6411 | ;; Return the number of replacements. | |
6412 | (let ((n 0) file label match-data buf macro pos cell) | |
6413 | (while (setq file (pop files)) | |
6414 | (setq buf (reftex-get-file-buffer-force file)) | |
6415 | (unless buf | |
6416 | (error "No such file %s" file)) | |
6417 | (set-buffer buf) | |
6418 | (save-excursion | |
6419 | (save-restriction | |
6420 | (widen) | |
6421 | (goto-char (point-min)) | |
6422 | (while (re-search-forward search-re nil t) | |
6423 | (save-excursion | |
6424 | (backward-char) | |
6425 | (setq label (reftex-match-string 1) | |
6426 | cell (assoc label translate-alist) | |
6427 | match-data (match-data) | |
6428 | macro (reftex-what-macro 1) | |
6429 | pos (cdr macro)) | |
6430 | (goto-char (or pos (point))) | |
6431 | (when (and macro | |
6432 | (or (looking-at "\\\\ref") | |
6433 | (looking-at "\\\\[a-zA-Z]*ref[^a-zA-Z]") | |
6434 | (looking-at "\\\\ref[a-zA-Z]*[^a-zA-Z]") | |
6435 | (looking-at (format | |
6436 | reftex-find-label-regexp-format | |
6437 | (regexp-quote label))))) | |
6438 | ;; OK, we should replace it. | |
6439 | (set-match-data match-data) | |
6440 | (cond | |
6441 | ((and test (not cell)) | |
6442 | ;; We've got a problem | |
6443 | (unwind-protect | |
6444 | (progn | |
6445 | (reftex-highlight 1 (match-beginning 0) (match-end 0)) | |
6446 | (ding) | |
6447 | (or (y-or-n-p (format error-fmt label)) | |
6448 | (error "Abort"))) | |
6449 | (reftex-unhighlight 1))) | |
6450 | ((and test cell) | |
6451 | (incf n)) | |
6452 | ((and (not test) cell) | |
6453 | ;; Replace | |
6454 | (goto-char (match-beginning 1)) | |
6455 | (delete-region (match-beginning 1) (match-end 1)) | |
6456 | (insert (cdr cell))) | |
6457 | (t nil)))))))) | |
6458 | n)) | |
a7ec1775 | 6459 | |
b849548d CD |
6460 | (defun reftex-save-all-document-buffers () |
6461 | "Save all documents associated with the current document. | |
6462 | The function is useful after a global action like replacing or renumbering | |
6463 | labels." | |
6464 | (interactive) | |
6465 | (let ((files (reftex-all-document-files)) | |
6466 | file buffer) | |
6467 | (save-excursion | |
6468 | (while (setq file (pop files)) | |
6469 | (setq buffer (reftex-get-buffer-visiting file)) | |
6470 | (when buffer | |
6471 | (set-buffer buffer) | |
6472 | (save-buffer)))))) | |
c52bdfca | 6473 | |
b849548d CD |
6474 | ;;; ========================================================================= |
6475 | ;;; | |
6476 | ;;; AUCTeX Interface | |
a7ec1775 | 6477 | |
b849548d CD |
6478 | (defun reftex-plug-flag (which) |
6479 | ;; Tell if a certain flag is set in reftex-plug-into-AUCTeX | |
6480 | (or (eq t reftex-plug-into-AUCTeX) | |
6481 | (and (listp reftex-plug-into-AUCTeX) | |
6482 | (nth which reftex-plug-into-AUCTeX)))) | |
a7ec1775 | 6483 | |
b849548d CD |
6484 | (defun reftex-arg-label (optional &optional prompt definition) |
6485 | "Use `reftex-label', `reftex-reference' or AUCTeX's code to insert label arg. | |
6486 | What is being used depends upon `reftex-plug-into-AUCTeX'." | |
6487 | (let (label) | |
6488 | (cond | |
6489 | ((and definition (reftex-plug-flag 1)) | |
6490 | ;; Create a new label, with a temporary brace for `reftex-what-macro' | |
6491 | (unwind-protect | |
6492 | (progn (insert "{") (setq label (or (reftex-label nil t) ""))) | |
6493 | (delete-backward-char 1))) | |
6494 | ((and (not definition) (reftex-plug-flag 2)) | |
6495 | ;; Reference a label with RefTeX | |
6496 | (setq label (reftex-reference nil t))) | |
6497 | (t | |
6498 | ;; AUCTeX's default mechanism | |
6499 | (setq label (completing-read (TeX-argument-prompt optional prompt "Key") | |
6500 | (LaTeX-label-list))))) | |
6501 | (if (and definition (not (string-equal "" label))) | |
6502 | (LaTeX-add-labels label)) | |
6503 | (TeX-argument-insert label optional optional))) | |
2faef409 | 6504 | |
b849548d CD |
6505 | (defun reftex-arg-cite (optional &optional prompt definition) |
6506 | "Use `reftex-citation' or AUCTeX's code to insert a cite-key macro argument. | |
6507 | What is being used depends upon `reftex-plug-into-AUCTeX'." | |
6508 | (let (items) | |
6509 | (cond | |
6510 | ((and (not definition) (reftex-plug-flag 3)) | |
6511 | (setq items (list (or (reftex-citation t) "")))) | |
6512 | (t | |
6513 | (setq prompt (concat (if optional "(Optional) " "") | |
6514 | (if prompt prompt "Add key") | |
6515 | ": (default none) ")) | |
6516 | (setq items (multi-prompt "," t prompt (LaTeX-bibitem-list))))) | |
6517 | (apply 'LaTeX-add-bibitems items) | |
6518 | (TeX-argument-insert (mapconcat 'identity items ",") optional optional))) | |
a7ec1775 | 6519 | |
b849548d CD |
6520 | (defun reftex-plug-into-AUCTeX () |
6521 | ;; Replace AUCTeX functions with RefTeX functions. | |
6522 | ;; Which functions are replaced is controlled by the variable | |
6523 | ;; `reftex-plug-into-AUCTeX'. | |
6524 | ||
6525 | (if (reftex-plug-flag 0) | |
6526 | (setq LaTeX-label-function 'reftex-label) | |
6527 | (setq LaTeX-label-function nil)) | |
a7ec1775 | 6528 | |
b849548d CD |
6529 | (if (and (or (reftex-plug-flag 1) (reftex-plug-flag 2)) |
6530 | (fboundp 'TeX-arg-label)) | |
6531 | (fset 'TeX-arg-label 'reftex-arg-label)) | |
a7ec1775 | 6532 | |
b849548d CD |
6533 | (if (and (reftex-plug-flag 3) |
6534 | (fboundp 'TeX-arg-cite)) | |
6535 | (fset 'TeX-arg-cite 'reftex-arg-cite))) | |
396e0b08 | 6536 | |
b849548d CD |
6537 | (defun reftex-toggle-plug-into-AUCTeX () |
6538 | "Toggle Interface between AUCTeX and RefTeX on and off." | |
6539 | (interactive) | |
6540 | (unless (and (featurep 'tex-site) (featurep 'latex)) | |
6541 | (error "AUCTeX's LaTeX mode does not seem to be loaded.")) | |
6542 | (setq reftex-plug-into-AUCTeX (not reftex-plug-into-AUCTeX)) | |
6543 | (reftex-plug-into-AUCTeX) | |
6544 | (if reftex-plug-into-AUCTeX | |
6545 | (message "RefTeX has been plugged into AUCTeX.") | |
6546 | (message "RefTeX no longer interacts with AUCTeX."))) | |
a7ec1775 | 6547 | |
b849548d CD |
6548 | (defun reftex-add-label-environments (entry-list) |
6549 | "Add label environment descriptions to `reftex-label-alist-style'. | |
6550 | The format of ENTRY-LIST is exactly like `reftex-label-alist'. See there | |
6551 | for details. | |
6552 | This function makes it possible to support RefTeX from AUCTeX style files. | |
6553 | The entries in ENTRY-LIST will be processed after the user settings in | |
6554 | `reftex-label-alist', and before the defaults (specified in | |
6555 | `reftex-default-label-alist-entries'). Any changes made to | |
6556 | `reftex-label-alist-style' will raise a flag to the effect that | |
6557 | the label information is recompiled on next use." | |
6558 | (unless reftex-docstruct-symbol | |
6559 | (reftex-tie-multifile-symbols)) | |
6560 | (when (and reftex-docstruct-symbol | |
6561 | (symbolp reftex-docstruct-symbol)) | |
6562 | (let ((list (get reftex-docstruct-symbol 'reftex-label-alist-style)) | |
6563 | entry changed) | |
6564 | (while entry-list | |
6565 | (setq entry (pop entry-list)) | |
6566 | (unless (member entry list) | |
6567 | (setq reftex-tables-dirty t | |
6568 | changed t) | |
6569 | (push entry list))) | |
6570 | (when changed | |
6571 | (put reftex-docstruct-symbol 'reftex-label-alist-style list))))) | |
6572 | (defalias 'reftex-add-to-label-alist 'reftex-add-label-environments) | |
6573 | ||
6574 | (defun reftex-add-section-levels (entry-list) | |
6575 | "Add entries to the value of `reftex-section-levels'. | |
6576 | The added values are kept local to the current document. The format | |
6577 | of ENTRY-LIST is a list of cons cells (\"MACRONAME\" . LEVEL). See | |
6578 | `reftex-section-levels' for an example." | |
6579 | (unless reftex-docstruct-symbol | |
6580 | (reftex-tie-multifile-symbols)) | |
6581 | (when (and reftex-docstruct-symbol | |
6582 | (symbolp reftex-docstruct-symbol)) | |
6583 | (let ((list (get reftex-docstruct-symbol 'reftex-section-levels)) | |
6584 | entry changed) | |
6585 | (while entry-list | |
6586 | (setq entry (pop entry-list)) | |
6587 | (unless (member entry list) | |
6588 | (setq reftex-tables-dirty t | |
6589 | changed t) | |
6590 | (push entry list))) | |
6591 | (when changed | |
6592 | (put reftex-docstruct-symbol 'reftex-section-levels list))))) | |
6593 | ||
6594 | (defun reftex-set-cite-format (value) | |
6595 | "Set the document-local value of `reftex-cite-format'. | |
6596 | When such a value exists, it overwrites the setting given with | |
6597 | `reftex-cite-format'. See the documentation of `reftex-cite-format' | |
6598 | for possible values. This function should be used from AUCTeX style files." | |
6599 | (unless reftex-docstruct-symbol | |
6600 | (reftex-tie-multifile-symbols)) | |
6601 | (when (and reftex-docstruct-symbol | |
6602 | (symbolp reftex-docstruct-symbol)) | |
6603 | (put reftex-docstruct-symbol 'reftex-cite-format value))) | |
6604 | ||
6605 | (defun reftex-notice-new-section () | |
6606 | "Hook to handshake with RefTeX after a new section has been inserted." | |
6607 | ;; Add a new section to the docstruct list and renumber the | |
6608 | ;; following sections. This hook has to be called immediately after | |
6609 | ;; the new section was inserted into the buffer, and before the | |
6610 | ;; section label is created. | |
2faef409 | 6611 | |
b849548d CD |
6612 | (condition-case nil |
6613 | (catch 'exit | |
6614 | (unless reftex-mode (throw 'exit nil)) | |
6615 | (reftex-access-scan-info) | |
6616 | (let* ((docstruct (symbol-value reftex-docstruct-symbol)) | |
6617 | here-am-I appendix tail toc-entry star level | |
6618 | section-number context) | |
a7ec1775 | 6619 | |
b849548d CD |
6620 | (save-excursion |
6621 | (when (re-search-backward reftex-section-regexp nil t) | |
6622 | ||
6623 | ;; Find where we are | |
6624 | (setq here-am-I (reftex-where-am-I)) | |
6625 | (unless (cdr here-am-I) (throw 'exit nil)) | |
6626 | (setq reftex-active-toc (reftex-last-assoc-before-elt | |
6627 | 'toc (car here-am-I) docstruct) | |
6628 | appendix (reftex-last-assoc-before-elt | |
6629 | 'appendix (car here-am-I) docstruct)) | |
6630 | ||
6631 | ;; Initialize section numbers | |
6632 | (if (eq (car (car here-am-I)) 'appendix) | |
6633 | (reftex-init-section-numbers nil t) | |
6634 | (reftex-init-section-numbers reftex-active-toc appendix)) | |
6635 | ||
6636 | ;; Match the section command | |
6637 | (when (and (re-search-forward reftex-everything-regexp nil t) | |
6638 | (match-end 3)) | |
6639 | (setq star (= ?* (char-after (match-end 3))) | |
6640 | toc-entry (reftex-section-info (buffer-file-name)) | |
6641 | level (nth 5 toc-entry) | |
6642 | tail (memq (car here-am-I) | |
6643 | (symbol-value reftex-docstruct-symbol))) | |
6644 | (if tail | |
6645 | ;; Insert the section info | |
6646 | (push toc-entry (cdr tail)) | |
6647 | (throw 'exit nil)) | |
6648 | ||
6649 | ;; We are done unless we use section numbers | |
6650 | (unless (nth 1 reftex-label-menu-flags) (throw 'exit nil)) | |
6651 | ||
6652 | ;; Update the remaining toc items | |
6653 | (setq tail (cdr tail)) | |
6654 | (while (and (setq tail (memq (assq 'toc (cdr tail)) tail)) | |
6655 | (setq toc-entry (car tail)) | |
6656 | (>= (nth 5 toc-entry) level)) | |
6657 | (setq section-number | |
6658 | (reftex-section-number (nth 5 toc-entry) star) | |
6659 | context (nth 2 toc-entry)) | |
6660 | (when (string-match "\\`\\([ \t]*\\)\\([.0-9A-Z]+\\)\\(.*\\)" | |
6661 | context) | |
6662 | (when (and (not appendix) | |
6663 | (>= (string-to-char (match-string 2)) ?A)) | |
6664 | ;; Just entered the appendex. Get out. | |
6665 | (throw 'exit nil)) | |
6666 | ||
6667 | ;; Change the section number. | |
6668 | (setf (nth 2 toc-entry) | |
6669 | (concat (match-string 1 context) | |
6670 | section-number | |
6671 | (match-string 3 context)))))))))) | |
6672 | (error nil)) | |
6673 | ) | |
6674 | ||
6675 | ;;; ========================================================================= | |
6676 | ;;; | |
6677 | ;;; Keybindings | |
a7ec1775 | 6678 | |
b849548d CD |
6679 | ;; The default bindings in the mode map. |
6680 | (loop for x in | |
6681 | '(("\C-c=" . reftex-toc) | |
6682 | ("\C-c(" . reftex-label) | |
6683 | ("\C-c)" . reftex-reference) | |
6684 | ("\C-c[" . reftex-citation) | |
6685 | ("\C-c&" . reftex-view-crossref)) | |
6686 | do (define-key reftex-mode-map (car x) (cdr x))) | |
a7ec1775 | 6687 | |
1c0dde84 | 6688 | ;; Bind `reftex-mouse-view-crossref' only when the key is still free |
b849548d | 6689 | (if (featurep 'xemacs) |
1c0dde84 CD |
6690 | (unless (key-binding [(shift button2)]) |
6691 | (define-key reftex-mode-map [(shift button2)] | |
6692 | 'reftex-mouse-view-crossref)) | |
6693 | (unless (key-binding [(shift mouse-2)]) | |
6694 | (define-key reftex-mode-map [(shift mouse-2)] | |
6695 | 'reftex-mouse-view-crossref))) | |
6696 | ||
a7ec1775 | 6697 | ;; If the user requests so, she can have a few more bindings: |
b849548d CD |
6698 | (when reftex-extra-bindings |
6699 | (loop for x in | |
6700 | '(("\C-ct" . reftex-toc) | |
6701 | ("\C-cl" . reftex-label) | |
6702 | ("\C-cr" . reftex-reference) | |
6703 | ("\C-cc" . reftex-citation) | |
6704 | ("\C-cv" . reftex-view-crossref) | |
6705 | ("\C-cg" . reftex-grep-document) | |
6706 | ("\C-cs" . reftex-search-document)) | |
6707 | do (define-key reftex-mode-map (car x) (cdr x)))) | |
6708 | ||
6709 | ;; Common bindings in reftex-select-label-map and reftex-select-bib-map | |
2faef409 | 6710 | (let ((map (make-sparse-keymap))) |
2faef409 RS |
6711 | (substitute-key-definition |
6712 | 'next-line 'reftex-select-next map global-map) | |
6713 | (substitute-key-definition | |
6714 | 'previous-line 'reftex-select-previous map global-map) | |
6715 | (substitute-key-definition | |
29d593f8 | 6716 | 'keyboard-quit 'reftex-select-keyboard-quit map global-map) |
2faef409 RS |
6717 | (substitute-key-definition |
6718 | 'newline 'reftex-select-accept map global-map) | |
29d593f8 | 6719 | |
b849548d CD |
6720 | (loop for x in |
6721 | '((" " . reftex-select-callback) | |
6722 | ("n" . reftex-select-next) | |
6723 | ([(down)] . reftex-select-next) | |
6724 | ("p" . reftex-select-previous) | |
6725 | ([(up)] . reftex-select-previous) | |
6726 | ("f" . reftex-select-toggle-follow) | |
6727 | ("\C-m" . reftex-select-accept) | |
6728 | ([(return)] . reftex-select-accept) | |
6729 | ("q" . reftex-select-quit) | |
6730 | ("." . reftex-select-show-insertion-point) | |
6731 | ("?" . reftex-select-help)) | |
6732 | do (define-key map (car x) (cdr x))) | |
6733 | ||
6734 | ;; The mouse-2 binding | |
6735 | (if (featurep 'xemacs) | |
6736 | (define-key map [(button2)] 'reftex-select-mouse-accept) | |
6737 | (define-key map [(mouse-2)] 'reftex-select-mouse-accept)) | |
6738 | ||
6739 | ;; Digit arguments | |
29d593f8 KH |
6740 | (loop for key across "0123456789" do |
6741 | (define-key map (vector (list key)) 'digit-argument)) | |
6742 | (define-key map "-" 'negative-argument) | |
2faef409 | 6743 | |
b849548d | 6744 | ;; Make two maps |
2faef409 | 6745 | (setq reftex-select-label-map map) |
b849548d CD |
6746 | (setq reftex-select-bib-map (copy-keymap map))) |
6747 | ||
6748 | ;; Specific bindings in reftex-select-label-map | |
6749 | (loop for key across "cgilrRstx#%" do | |
6750 | (define-key reftex-select-label-map (vector (list key)) | |
6751 | (list 'lambda '() | |
6752 | "Press `?' during selection to find out about this key." | |
6753 | '(interactive) (list 'throw '(quote myexit) key)))) | |
6754 | ||
6755 | (loop for x in | |
6756 | '(("b" . reftex-select-jump-to-previous) | |
6757 | ("v" . reftex-select-toggle-varioref) | |
6758 | ([(tab)] . reftex-select-read-label) | |
6759 | ("\C-i" . reftex-select-read-label) | |
6760 | ("\C-c\C-n" . reftex-select-next-heading) | |
6761 | ("\C-c\C-p" . reftex-select-previous-heading)) | |
6762 | do | |
6763 | (define-key reftex-select-label-map (car x) (cdr x))) | |
6764 | ||
6765 | ;; Specific bindings in reftex-select-bib-map | |
6766 | (loop for key across "grRaA" do | |
6767 | (define-key reftex-select-bib-map (vector (list key)) | |
6768 | (list 'lambda '() | |
6769 | "Press `?' during selection to find out about this key." | |
6770 | '(interactive) (list 'throw '(quote myexit) key)))) | |
6771 | ||
6772 | (loop for x in | |
6773 | '(("\C-i" . reftex-select-read-cite) | |
6774 | ([(tab)] . reftex-select-read-cite)) | |
6775 | do (define-key reftex-select-bib-map (car x) (cdr x))) | |
6776 | ||
2faef409 | 6777 | ;; Table of Contents map |
b849548d CD |
6778 | (if (featurep 'xemacs) |
6779 | (define-key reftex-toc-map [(button2)] 'reftex-toc-mouse-goto-line-and-hide) | |
6780 | (define-key reftex-toc-map [(mouse-2)] 'reftex-toc-mouse-goto-line-and-hide)) | |
6781 | ||
6782 | (loop for x in | |
6783 | '(("n" . next-line) | |
6784 | ("p" . previous-line) | |
6785 | ("?" . reftex-toc-show-help) | |
6786 | (" " . reftex-toc-view-line) | |
6787 | ("\C-m" . reftex-toc-goto-line-and-hide) | |
6788 | ("\C-i" . reftex-toc-goto-line) | |
6789 | ("r" . reftex-toc-rescan) | |
6790 | ("R" . reftex-toc-Rescan) | |
6791 | ("g" . revert-buffer) | |
6792 | ("q" . reftex-toc-quit) | |
6793 | ("Q" . reftex-toc-quit-and-kill) | |
6794 | ("f" . reftex-toc-toggle-follow) | |
6795 | ("x" . reftex-toc-external) | |
6796 | ("." . reftex-toc-show-insertion-point)) | |
6797 | do (define-key reftex-toc-map (car x) (cdr x))) | |
6798 | ||
6799 | (loop for key across "0123456789" do | |
6800 | (define-key reftex-toc-map (vector (list key)) 'digit-argument)) | |
6801 | (define-key reftex-toc-map "-" 'negative-argument) | |
2faef409 | 6802 | |
b849548d CD |
6803 | ;;; ========================================================================= |
6804 | ;;; | |
6805 | ;;; Menu | |
a7ec1775 RS |
6806 | |
6807 | ;; Define a menu for the menu bar if Emacs is running under X | |
6808 | ||
6809 | (require 'easymenu) | |
6810 | ||
396e0b08 | 6811 | (easy-menu-define |
a7ec1775 RS |
6812 | reftex-mode-menu reftex-mode-map |
6813 | "Menu used in RefTeX mode" | |
396e0b08 | 6814 | `("Ref" |
206c6f82 | 6815 | ["Table of Contents" reftex-toc t] |
b849548d | 6816 | "---" |
206c6f82 RS |
6817 | ["\\label" reftex-label t] |
6818 | ["\\ref" reftex-reference t] | |
6819 | ["\\cite" reftex-citation t] | |
396e0b08 | 6820 | ["View Crossref" reftex-view-crossref t] |
b849548d | 6821 | "---" |
396e0b08 KH |
6822 | ("Parse Document" |
6823 | ["Only this File" reftex-parse-one t] | |
6824 | ["Entire Document" reftex-parse-all (reftex-is-multi)] | |
baec1250 | 6825 | ["Save to File" (reftex-access-parse-file 'write) |
396e0b08 | 6826 | (> (length (symbol-value reftex-docstruct-symbol)) 0)] |
2faef409 | 6827 | ["Restore from File" (reftex-access-parse-file 'restore) t] |
396e0b08 KH |
6828 | "---" |
6829 | ["Reset RefTeX Mode" reftex-reset-mode t]) | |
2faef409 | 6830 | ("Global Actions" |
baec1250 KH |
6831 | ["Search Whole Document" reftex-search-document t] |
6832 | ["Replace in Document" reftex-query-replace-document t] | |
6833 | ["Grep on Document" reftex-grep-document t] | |
b849548d | 6834 | "---" |
baec1250 | 6835 | ["Create TAGS File" reftex-create-tags-file t] |
b849548d | 6836 | "---" |
baec1250 | 6837 | ["Find Duplicate Labels" reftex-find-duplicate-labels t] |
2faef409 | 6838 | ["Change Label and Refs" reftex-change-label t] |
b849548d | 6839 | ["Renumber Simple Labels" reftex-renumber-simple-labels t] |
2faef409 RS |
6840 | "---" |
6841 | ["Save document" reftex-save-all-document-buffers t]) | |
6842 | "---" | |
b849548d CD |
6843 | ("Options" |
6844 | ("Table of Contents" | |
6845 | ["Follow Mode" (setq reftex-toc-follow-mode (not reftex-toc-follow-mode)) | |
6846 | :style toggle :selected reftex-toc-follow-mode] | |
6847 | ["Follow Mode may visit files" | |
6848 | (setq reftex-revisit-to-follow (not reftex-revisit-to-follow)) | |
6849 | :style toggle :selected reftex-revisit-to-follow]) | |
6850 | ("References" | |
6851 | ["Guess Label Type" | |
6852 | (setq reftex-guess-label-type (not reftex-guess-label-type)) | |
6853 | :style toggle :selected reftex-guess-label-type] | |
6854 | ["Use `\\vref' by Default" | |
6855 | (setq reftex-vref-is-default (not reftex-vref-is-default)) | |
6856 | :style toggle :selected reftex-vref-is-default] | |
6857 | "---" | |
6858 | "Selection Buffers" | |
6859 | ["Use Multiple Buffers" | |
6860 | (setq reftex-use-multiple-selection-buffers | |
6861 | (not reftex-use-multiple-selection-buffers)) | |
6862 | :style toggle :selected reftex-use-multiple-selection-buffers] | |
6863 | ["Auto Update Buffers" | |
6864 | (setq reftex-auto-update-selection-buffers | |
6865 | (not reftex-auto-update-selection-buffers)) | |
6866 | :style toggle :selected reftex-auto-update-selection-buffers]) | |
6867 | ("Citations" | |
6868 | "Citation Style" | |
6869 | ,@(mapcar | |
6870 | (function | |
6871 | (lambda (x) | |
6872 | (vector | |
6873 | (capitalize (symbol-name (car x))) | |
6874 | (list 'reftex-set-cite-format (list 'quote (car x))) | |
6875 | ':style 'radio ':selected | |
6876 | (list 'eq (list 'reftex-get-cite-format) (list 'quote (car x)))))) | |
baec1250 | 6877 | reftex-cite-format-builtin) |
b849548d CD |
6878 | "---" |
6879 | "Bibinfo in Comments" | |
6880 | ["Attach Comments" | |
6881 | (setq reftex-comment-citations (not reftex-comment-citations)) | |
6882 | :style toggle :selected reftex-comment-citations] | |
6883 | "---" | |
6884 | "Sort Database Matches" | |
6885 | ["by Author" (setq reftex-sort-bibtex-matches 'author) | |
6886 | :style radio :selected (eq reftex-sort-bibtex-matches 'author)] | |
6887 | ["by Year" (setq reftex-sort-bibtex-matches 'year) | |
6888 | :style radio :selected (eq reftex-sort-bibtex-matches 'year)] | |
6889 | ["by Year, reversed" (setq reftex-sort-bibtex-matches 'reverse-year) | |
6890 | :style radio :selected (eq reftex-sort-bibtex-matches 'reverse-year)] | |
6891 | ["Not" (setq reftex-sort-bibtex-matches nil) | |
6892 | :style radio :selected (eq reftex-sort-bibtex-matches nil)]) | |
6893 | ("Crossref Viewing" | |
a6611c0d | 6894 | ["Automatic Info" reftex-toggle-auto-view-crossref |
b849548d | 6895 | :style toggle :selected reftex-auto-view-crossref-timer] |
a6611c0d CD |
6896 | ["...in Echo Area" (setq reftex-auto-view-crossref t) |
6897 | :style radio :selected (eq reftex-auto-view-crossref t)] | |
6898 | ["...in Other Window" (setq reftex-auto-view-crossref 'window) | |
6899 | :style radio :selected (eq reftex-auto-view-crossref 'window)] | |
6900 | "---" | |
b849548d CD |
6901 | ["Crossref Echo may visit files" |
6902 | (setq reftex-revisit-to-echo (not reftex-revisit-to-echo)) | |
6903 | :style toggle :selected reftex-revisit-to-echo] | |
6904 | ["Cache Echo strings for \cite" | |
6905 | (setq reftex-cache-cite-echo (not reftex-cache-cite-echo)) | |
6906 | :style toggle :selected reftex-cache-cite-echo]) | |
6907 | ("Parser" | |
6908 | "Document Scans" | |
6909 | ["Partial Scans" | |
6910 | (setq reftex-enable-partial-scans (not reftex-enable-partial-scans)) | |
6911 | :style toggle :selected reftex-enable-partial-scans] | |
6912 | ["Auto-Save Parse Info" | |
6913 | (setq reftex-save-parse-info (not reftex-save-parse-info)) | |
6914 | :style toggle :selected reftex-save-parse-info] | |
6915 | ["Automatic Rescans" | |
6916 | (setq reftex-allow-automatic-rescan (not reftex-allow-automatic-rescan)) | |
6917 | :style toggle :selected reftex-allow-automatic-rescan] | |
6918 | "---" | |
6919 | "Temporary Buffers" | |
6920 | ["Keep Buffers" | |
6921 | (setq reftex-keep-temporary-buffers (not reftex-keep-temporary-buffers)) | |
6922 | :style toggle :selected reftex-keep-temporary-buffers] | |
6923 | ["Initialize when Visiting" | |
6924 | (setq reftex-initialize-temporary-buffers | |
6925 | (not reftex-initialize-temporary-buffers)) | |
6926 | :style toggle :selected reftex-initialize-temporary-buffers]) | |
6927 | ("AUC TeX" | |
6928 | ["Plug into AUC TeX" reftex-toggle-plug-into-AUCTeX | |
6929 | :style toggle :selected reftex-plug-into-AUCTeX]) | |
6930 | ("Fontification" | |
6931 | ["Use Fontification" (setq reftex-use-fonts (not reftex-use-fonts)) | |
6932 | :style toggle :selected reftex-use-fonts] | |
6933 | ["Fontify Context Display" (setq reftex-refontify-context | |
6934 | (not (reftex-refontify))) | |
6935 | :style toggle :selected (reftex-refontify)])) | |
6936 | ;;"---" | |
2faef409 RS |
6937 | ("Customize" |
6938 | ["Browse RefTeX group" reftex-customize t] | |
6939 | "---" | |
6940 | ["Build Full Customize Menu" reftex-create-customize-menu | |
6941 | (fboundp 'customize-menu-create)]) | |
b849548d | 6942 | "---" |
2faef409 RS |
6943 | ("Documentation" |
6944 | ["Info" reftex-info t] | |
6945 | ["Commentary" reftex-show-commentary t]))) | |
a7ec1775 | 6946 | |
b849548d CD |
6947 | (defun reftex-customize () |
6948 | "Call the customize function with reftex as argument." | |
6949 | (interactive) | |
6950 | (customize-browse 'reftex)) | |
6951 | ||
6952 | (defun reftex-create-customize-menu () | |
6953 | "Create a full customization menu for RefTeX, insert it into the menu." | |
6954 | (interactive) | |
6955 | (if (fboundp 'customize-menu-create) | |
6956 | (progn | |
6957 | (easy-menu-change | |
6958 | '("Ref") "Customize" | |
6959 | `(["Browse RefTeX group" reftex-customize t] | |
6960 | "---" | |
6961 | ,(customize-menu-create 'reftex) | |
6962 | ["Set" Custom-set t] | |
6963 | ["Save" Custom-save t] | |
6964 | ["Reset to Current" Custom-reset-current t] | |
6965 | ["Reset to Saved" Custom-reset-saved t] | |
6966 | ["Reset to Standard Settings" Custom-reset-standard t])) | |
6967 | (message "\"Ref\"-menu now contains full customization menu")) | |
6968 | (error "Cannot expand menu (outdated version of cus-edit.el)"))) | |
6969 | ||
6970 | (defun reftex-show-commentary () | |
6971 | "Use the finder to view the file documentation from `reftex.el'." | |
6972 | (interactive) | |
6973 | (require 'finder) | |
6974 | (finder-commentary "reftex.el")) | |
6975 | ||
6976 | (defun reftex-info () | |
6977 | "Read documentation for RefTeX in the info system." | |
6978 | (interactive) | |
6979 | (require 'info) | |
6980 | (Info-goto-node "(reftex)")) | |
6981 | ||
6982 | ;; Support for \label and \ref -------------------------------------- | |
6983 | ||
6984 | ;;; Install the kill-buffer and kill-emacs hooks ------------------------------ | |
6985 | ||
6986 | (add-hook 'kill-buffer-hook 'reftex-kill-buffer-hook) | |
6987 | (add-hook 'kill-emacs-hook 'reftex-kill-emacs-hook) | |
6988 | ||
6989 | ;;; Install the idle timer if requested --------------------------------------- | |
6990 | ||
6991 | (and reftex-auto-view-crossref | |
6992 | (not reftex-auto-view-crossref-timer) | |
6993 | (reftex-toggle-auto-view-crossref)) | |
6994 | ||
a7ec1775 RS |
6995 | ;;; Run Hook ------------------------------------------------------------------ |
6996 | ||
6997 | (run-hooks 'reftex-load-hook) | |
6998 | ||
6999 | ;;; That's it! ---------------------------------------------------------------- | |
7000 | ||
6b94c6ad | 7001 | (setq reftex-tables-dirty t) ; in case this file is evaluated by hand |
396e0b08 KH |
7002 | (provide 'reftex) |
7003 | ||
a7ec1775 RS |
7004 | ;;;============================================================================ |
7005 | ||
c52bdfca | 7006 | ;;; reftex.el ends here |
b849548d | 7007 |