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 | ;; | |
f9ad2e24 CD |
28 | ;; RefTeX is a minor mode with distinct support for \ref, \label, and \cite |
29 | ;; commands in (multi-file) LaTeX documents. | |
30 | ;; - A table of contents provides easy access to any part of a document. | |
31 | ;; - Labels are created semi-automatically. | |
32 | ;; - Definition context of labels is provided when creating a reference. | |
33 | ;; - Citations are simplified with efficient database lookup. | |
a7ec1775 | 34 | ;; |
2faef409 | 35 | ;; |
a6611c0d CD |
36 | ;; INSTALLATION |
37 | ;; ------------ | |
38 | ;; | |
f9ad2e24 CD |
39 | ;; - If this file is part of an X/Emacs distribution, it is installed. |
40 | ;; - For XEmacs 21.x, you need to install the RefTeX plug-in package | |
41 | ;; available from the XEmacs distribution sites. | |
42 | ;; - If you have downloaded this file from the maintainers webpage, follow | |
43 | ;; the instructions in the INSTALL file of the distrubution. | |
a6611c0d | 44 | ;; |
f9ad2e24 | 45 | ;; To turn RefTeX Mode on and off in a buffer, use `M-x reftex-mode'. |
a7ec1775 | 46 | ;; |
f9ad2e24 CD |
47 | ;; To turn on RefTeX Mode for all LaTeX files, add the following lines |
48 | ;; to your .emacs file: | |
a7ec1775 | 49 | ;; |
f9ad2e24 CD |
50 | ;; (add-hook 'LaTeX-mode-hook 'turn-on-reftex) ; AUCTeX LaTeX mode |
51 | ;; (add-hook 'latex-mode-hook 'turn-on-reftex) ; Emacs latex mode | |
a7ec1775 | 52 | ;; |
396e0b08 | 53 | ;; |
2faef409 RS |
54 | ;; DOCUMENTATION |
55 | ;; ------------- | |
396e0b08 | 56 | ;; |
a6611c0d CD |
57 | ;; See below for a short summary of how to use RefTeX. |
58 | ;; | |
2faef409 | 59 | ;; There is an extensive texinfo document describing RefTeX in detail. |
f9ad2e24 | 60 | ;; One way to view this documentation is `M-x reftex-info RET'. |
a7ec1775 | 61 | ;; |
a6611c0d | 62 | ;; The documentation in various formats is also available at |
396e0b08 | 63 | ;; |
2faef409 | 64 | ;; http://www.strw.leidenuniv.nl/~dominik/Tools/ |
396e0b08 | 65 | ;; |
2faef409 | 66 | ;;--------------------------------------------------------------------------- |
f9ad2e24 | 67 | ;; |
2faef409 RS |
68 | ;; RefTeX in a Nutshell |
69 | ;; ==================== | |
921759ee | 70 | ;; |
f9ad2e24 CD |
71 | ;; 1. Table of Contents |
72 | ;; Typing `C-c =' (`reftex-toc') will show a table of contents of the | |
73 | ;; document. From that buffer, you can jump quickly to every part of | |
74 | ;; your document. Press `?' to get help. | |
921759ee | 75 | ;; |
f9ad2e24 CD |
76 | ;; 2. Labels and References |
77 | ;; RefTeX distinguishes labels for different environments. It knows | |
78 | ;; about all standard environments (and many others), and can be | |
79 | ;; configured to recognize any additional labeled environments you | |
921759ee | 80 | ;; have defined yourself (variable `reftex-label-alist'). |
b849548d | 81 | ;; |
921759ee | 82 | ;; Creating Labels |
f9ad2e24 CD |
83 | ;; Type `C-c (' (`reftex-label') to insert a label at point. RefTeX |
84 | ;; will either | |
85 | ;; - derive a label from context (default for section labels) | |
86 | ;; - prompt for a label string (default for figures and tables) or | |
87 | ;; - insert a simple label made of a prefix and a number (all other | |
88 | ;; environments) | |
921759ee | 89 | ;; This is configurable with the variable `reftex-insert-label-flags'. |
b849548d | 90 | ;; |
921759ee | 91 | ;; Referencing Labels |
f9ad2e24 CD |
92 | ;; To make a reference, type `C-c )' (`reftex-reference'). This |
93 | ;; shows an outline of the document with all labels of a certain type | |
94 | ;; (figure, equation,...) and some label context. Selecting a label | |
95 | ;; inserts a `\ref{LABEL}' macro into the original buffer. | |
b849548d | 96 | ;; |
f9ad2e24 CD |
97 | ;; 3. Citations |
98 | ;; Typing `C-c [' (`reftex-citation') will let you specify a regular | |
99 | ;; expression to search in current BibTeX database files (as | |
100 | ;; specified in the `\bibliography' command) and pull out a list of | |
101 | ;; matches for you to choose from. The list is *formatted* and | |
102 | ;; sorted. The selected article is referenced as `\cite{KEY}' (see | |
921759ee | 103 | ;; variable `reftex-cite-format'). |
b849548d | 104 | ;; |
921759ee CD |
105 | ;; 4. Viewing Cross-References |
106 | ;; When point is on the KEY argument of a cross-referencing macro | |
107 | ;; (`\label', `\ref', `\cite', `\bibitem', `\index', and variations) | |
108 | ;; or inside a BibTeX database entry, you can press `C-c &' | |
109 | ;; (`reftex-view-crossref') to display corresponding locations in the | |
110 | ;; document and associated BibTeX database files. | |
111 | ;; When the enclosing macro is `\cite' or `\ref' and no other message | |
112 | ;; occupies the echo area, information about the citation or label | |
113 | ;; will automatically be displayed. | |
b849548d | 114 | ;; |
f9ad2e24 | 115 | ;; 5. Multifile Documents |
921759ee CD |
116 | ;; Multifile Documents are fully supported. RefTeX provides |
117 | ;; cross-referencing information from all parts of the document, and | |
118 | ;; across document borders (`xr.sty'). | |
b849548d | 119 | ;; |
f9ad2e24 CD |
120 | ;; 6. Document Parsing |
121 | ;; RefTeX needs to parse the document in order to find labels and | |
122 | ;; other information. It does it automatically once and updates its | |
123 | ;; list internally when `reftex-label' is used. To enforce | |
124 | ;; reparsing, call any of the commands described above with a raw | |
125 | ;; `C-u' prefix, or press the `r' key in the label selection buffer | |
126 | ;; or the table of contents buffer. | |
a6611c0d | 127 | ;; |
f9ad2e24 CD |
128 | ;; 7. Useful Settings |
129 | ;; To make RefTeX faster for large documents, and to integrate with | |
130 | ;; AUCTeX, try these: | |
131 | ;; (setq reftex-enable-partial-scans t) | |
132 | ;; (setq reftex-save-parse-info t) | |
133 | ;; (setq reftex-use-multiple-selection-buffers t) | |
134 | ;; (setq reftex-plug-into-AUCTeX t) | |
a7ec1775 | 135 | ;; |
a7ec1775 RS |
136 | ;;--------------------------------------------------------------------------- |
137 | ;; | |
138 | ;; AUTHOR | |
396e0b08 | 139 | ;; ====== |
a7ec1775 RS |
140 | ;; |
141 | ;; Carsten Dominik <dominik@strw.LeidenUniv.nl> | |
142 | ;; | |
143 | ;; with contributions from Stephen Eglen | |
144 | ;; | |
f9ad2e24 CD |
145 | ;; RefTeX is bundled with Emacs and available as a plug-in package for |
146 | ;; XEmacs 21.x. If you need to install it yourself, you can find a | |
147 | ;; distribution at | |
a7ec1775 RS |
148 | ;; |
149 | ;; http://www.strw.leidenuniv.nl/~dominik/Tools/ | |
2faef409 | 150 | ;; |
a7ec1775 RS |
151 | ;; THANKS TO: |
152 | ;; --------- | |
2faef409 RS |
153 | ;; Thanks to the people on the Net who have used RefTeX and helped |
154 | ;; developing it with their reports. In particular thanks to | |
a7ec1775 | 155 | ;; |
f9ad2e24 | 156 | ;; Fran Burstall, Alastair Burt, Soren Dayton, Stephen Eglen, |
51d628c8 CD |
157 | ;; Karl Eichwalder, Peter Galbraith, Dieter Kraft, Kai Grossjohann, |
158 | ;; Adrian Lanz, Rory Molinari, Laurent Mugnier, Sudeep Kumar Palat, | |
159 | ;; Daniel Polani, Robin Socha, Richard Stanton, Allan Strand, | |
160 | ;; Jan Vroonhof, Christoph Wedler, Alan Williams. | |
a7ec1775 | 161 | ;; |
2faef409 | 162 | ;; Finally thanks to Uwe Bolick who first got me (some years ago) into |
f9ad2e24 | 163 | ;; supporting LaTeX labels and references with an editor (which was |
2faef409 | 164 | ;; MicroEmacs at the time). |
025bb635 | 165 | ;; |
a6611c0d | 166 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
c52bdfca | 167 | ;; |
a6611c0d | 168 | ;;;;;; |
a7ec1775 RS |
169 | \f |
170 | ;;; Code: | |
171 | ||
396e0b08 KH |
172 | (eval-when-compile (require 'cl)) |
173 | ||
a7ec1775 | 174 | ;; Stuff that needs to be there when we use defcustom |
a7ec1775 RS |
175 | (require 'custom) |
176 | ||
177 | (defvar reftex-tables-dirty t | |
178 | "Flag showing if tables need to be re-computed.") | |
179 | ||
180 | (eval-and-compile | |
181 | (defun reftex-set-dirty (symbol value) | |
182 | (setq reftex-tables-dirty t) | |
183 | (set symbol value))) | |
184 | ||
b849548d CD |
185 | ;;; ====================================================================== |
186 | ;;; | |
187 | ;;; Configuration Section | |
a7ec1775 | 188 | |
396e0b08 KH |
189 | ;; Define the two constants which are needed during compilation |
190 | ||
191 | (eval-and-compile | |
192 | (defconst reftex-label-alist-builtin | |
193 | '( | |
194 | ;; Some aliases, mostly for backward compatibility | |
195 | (Sideways "Alias for -->rotating" (rotating)) | |
196 | (AMSTeX "amsmath with eqref macro" | |
197 | ((nil ?e nil "~\\eqref{%s}") | |
198 | amsmath)) | |
199 | ||
200 | ;; Individual package defaults | |
201 | (amsmath "AMS-LaTeX math environments" | |
202 | (("align" ?e nil nil eqnarray-like) | |
203 | ("gather" ?e nil nil eqnarray-like) | |
204 | ("multline" ?e nil nil t) | |
205 | ("flalign" ?e nil nil eqnarray-like) | |
206 | ("alignat" ?e nil nil alignat-like) | |
207 | ("xalignat" ?e nil nil alignat-like) | |
208 | ("xxalignat" ?e nil nil alignat-like) | |
209 | ("subequations" ?e nil nil t))) | |
210 | ||
211 | (endnotes "The \\endnote macro" | |
2faef409 | 212 | (("\\endnote[]{}" ?n nil nil 2 (regexp "Endnotes?")))) |
396e0b08 KH |
213 | |
214 | (fancybox "The Beqnarray environment" | |
215 | (("Beqnarray" ?e nil nil eqnarray-like))) | |
216 | ||
217 | (floatfig "The floatingfigure environment" | |
218 | (("floatingfigure" ?f nil nil caption))) | |
219 | ||
220 | (longtable "The longtable environment" | |
221 | (("longtable" ?t nil nil caption))) | |
222 | ||
223 | (picinpar "The figwindow and tabwindow environments" | |
224 | (("figwindow" ?f nil nil 1) | |
225 | ("tabwindow" ?f nil nil 1))) | |
226 | ||
227 | (rotating "Sidewaysfigure and table" | |
228 | (("sidewaysfigure" ?f nil nil caption) | |
229 | ("sidewaystable" ?t nil nil caption))) | |
230 | ||
29d593f8 KH |
231 | (sidecap "CSfigure and SCtable" |
232 | (("SCfigure" ?f nil nil caption) | |
233 | ("SCtable" ?t nil nil caption))) | |
234 | ||
396e0b08 KH |
235 | (subfigure "Subfigure environments/macro" |
236 | (("subfigure" ?f nil nil caption) | |
237 | ("subfigure*" ?f nil nil caption) | |
238 | ("\\subfigure[]{}" ?f nil nil 1))) | |
239 | ||
240 | (supertab "Supertabular environment" | |
241 | (("supertabular" ?t nil nil "\\tablecaption{"))) | |
242 | ||
243 | (wrapfig "The wrapfigure environment" | |
244 | (("wrapfigure" ?f nil nil caption))) | |
245 | ||
246 | ;; The LaTeX core stuff | |
247 | (LaTeX "LaTeX default environments" | |
248 | (("section" ?s "sec:" "~\\ref{%s}" (nil . t) | |
b849548d CD |
249 | (regexp "parts?" "chapters?" "chap\\." "sections?" "sect?\\." |
250 | "paragraphs?" "par\\." | |
2faef409 | 251 | "\\\\S" "\247" "Teile?" "Kapitel" "Kap\\." "Abschnitte?" |
b849548d | 252 | "appendi\\(x\\|ces\\)" "App\\." "Anh\"?ange?" "Anh\\.")) |
396e0b08 KH |
253 | |
254 | ("enumerate" ?i "item:" "~\\ref{%s}" item | |
b849548d | 255 | (regexp "items?" "Punkte?")) |
2faef409 | 256 | |
396e0b08 | 257 | ("equation" ?e "eq:" "~(\\ref{%s})" t |
b849548d | 258 | (regexp "equations?" "eqs?\\." "eqn\\." "Gleichung\\(en\\)?" "Gl\\.")) |
396e0b08 | 259 | ("eqnarray" ?e "eq:" nil eqnarray-like) |
2faef409 | 260 | |
396e0b08 | 261 | ("figure" ?f "fig:" "~\\ref{%s}" caption |
b849548d | 262 | (regexp "figure?[sn]?" "figs?\\." "Abbildung\\(en\\)?" "Abb\\.")) |
396e0b08 | 263 | ("figure*" ?f nil nil caption) |
2faef409 | 264 | |
396e0b08 | 265 | ("table" ?t "tab:" "~\\ref{%s}" caption |
b849548d | 266 | (regexp "tables?" "tab\\." "Tabellen?")) |
396e0b08 | 267 | ("table*" ?t nil nil caption) |
2faef409 | 268 | |
396e0b08 | 269 | ("\\footnote[]{}" ?n "note:" "~\\ref{%s}" 2 |
b849548d | 270 | (regexp "footnotes?" "notes?" "Anmerkung\\(en\\)?" "Anm\\.")) |
2faef409 | 271 | |
b849548d CD |
272 | ("any" ?\ " " "~\\ref{%s}" nil) |
273 | ||
274 | ;; The label macro is hard coded, but it *could* be defined like this: | |
275 | ;;("\\label{*}" nil nil nil nil) | |
276 | )) | |
396e0b08 KH |
277 | |
278 | ) | |
279 | "The default label environment descriptions. | |
280 | Lower-case symbols correspond to a style file of the same name in the LaTeX | |
281 | distribution. Mixed-case symbols are convenience aliases.") | |
282 | ||
283 | (defconst reftex-cite-format-builtin | |
f9ad2e24 | 284 | '((default "Default macro \\cite{%l}" |
396e0b08 KH |
285 | "\\cite{%l}") |
286 | (natbib "The Natbib package" | |
287 | ((?\C-m . "\\cite{%l}") | |
288 | (?t . "\\citet{%l}") | |
289 | (?T . "\\citet*{%l}") | |
290 | (?p . "\\citep{%l}") | |
291 | (?P . "\\citep*{%l}") | |
292 | (?e . "\\citep[e.g.][]{%l}") | |
b849548d | 293 | (?s . "\\citep[see][]{%l}") |
396e0b08 | 294 | (?a . "\\citeauthor{%l}") |
b849548d | 295 | (?A . "\\citeauthor*{%l}") |
396e0b08 KH |
296 | (?y . "\\citeyear{%l}"))) |
297 | (harvard "The Harvard package" | |
298 | ((?\C-m . "\\cite{%l}") | |
299 | (?p . "\\cite{%l}") | |
300 | (?t . "\\citeasnoun{%l}") | |
301 | (?n . "\\citeasnoun{%l}") | |
302 | (?s . "\\possessivecite{%l}") | |
303 | (?e . "\\citeaffixed{%l}{?}") | |
304 | (?y . "\\citeyear{%l}") | |
305 | (?a . "\\citename{%l}"))) | |
306 | (chicago "The Chicago package" | |
307 | ((?\C-m . "\\cite{%l}") | |
308 | (?t . "\\citeN{%l}") | |
309 | (?T . "\\shortciteN{%l}") | |
310 | (?p . "\\cite{%l}") | |
311 | (?P . "\\shortcite{%l}") | |
312 | (?a . "\\citeA{%l}") | |
313 | (?A . "\\shortciteA{%l}") | |
2faef409 | 314 | (?y . "\\citeyear{%l}"))) |
396e0b08 KH |
315 | (astron "The Astron package" |
316 | ((?\C-m . "\\cite{%l}") | |
317 | (?p . "\\cite{%l}" ) | |
318 | (?t . "%2a (\\cite{%l})"))) | |
319 | (author-year "Do-it-yourself Author-year" | |
320 | ((?\C-m . "\\cite{%l}") | |
321 | (?t . "%2a (%y)\\nocite{%l}") | |
322 | (?p . "(%2a %y\\nocite{%l})"))) | |
323 | (locally "Full info in parenthesis" | |
324 | "(%2a %y, %j %v, %P, %e: %b, %u, %s %<)") | |
396e0b08 | 325 | ) |
b849548d | 326 | "Builtin versions of the citation format. |
396e0b08 KH |
327 | The following conventions are valid for all alist entries: |
328 | `?\C-m' should always point to a straight \\cite{%l} macro. | |
329 | `?t' should point to a textual citation (citation as a noun). | |
330 | `?p' should point to a parenthetical citation.") | |
331 | ) | |
332 | ||
a7ec1775 RS |
333 | ;; Configuration Variables and User Options for RefTeX ------------------ |
334 | ||
335 | (defgroup reftex nil | |
336 | "LaTeX label and citation support." | |
337 | :tag "RefTeX" | |
396e0b08 KH |
338 | :link '(url-link :tag "Home Page" |
339 | "http://strw.leidenuniv.nl/~dominik/Tools/") | |
340 | :link '(emacs-commentary-link :tag "Commentary in reftex.el" "reftex.el") | |
f9ad2e24 | 341 | :link '(custom-manual "(reftex)Top") |
a7ec1775 RS |
342 | :prefix "reftex-" |
343 | :group 'tex) | |
344 | ||
f9ad2e24 CD |
345 | ;; Table of contents configuration -------------------------------------- |
346 | ||
347 | (defgroup reftex-table-of-contents-browser nil | |
348 | "A multifile table of contents browser." | |
349 | :group 'reftex) | |
350 | ||
351 | (defcustom reftex-toc-keep-other-windows t | |
352 | "*Non-nil means, split the selected window to display the *toc* buffer. | |
353 | This helps to keep the window configuration, but makes the *toc* small. | |
354 | When nil, all other windows except the selected one will be deleted, so | |
355 | that the *toc* window fills half the frame." | |
356 | :group 'reftex-table-of-contents-browser | |
357 | :type 'boolean) | |
358 | ||
359 | (defcustom reftex-toc-include-labels nil | |
360 | "*Non-nil means, include labels in *toc* buffer. | |
361 | This flag can be toggled from within the *toc* buffer with the `l' key." | |
362 | :group 'reftex-table-of-contents-browser | |
363 | :type 'boolean) | |
364 | ||
365 | (defcustom reftex-toc-include-context nil | |
366 | "*Non-nil means, include context with labels in the *toc* buffer. | |
367 | Context will only be shown when labels are visible as well. | |
368 | This flag can be toggled from within the *toc* buffer with the `c' key." | |
369 | :group 'reftex-table-of-contents-browser | |
370 | :type 'boolean) | |
371 | ||
372 | (defcustom reftex-toc-include-file-boundaries nil | |
373 | "*Non-nil means, include file boundaries in *toc* buffer. | |
374 | This flag can be toggled from within the *toc* buffer with the `i' key." | |
375 | :group 'reftex-table-of-contents-browser | |
376 | :type 'boolean) | |
377 | ||
378 | (defcustom reftex-toc-follow-mode nil | |
379 | "*Non-nil means, point in *toc* buffer will cause other window to follow. | |
380 | The other window will show the corresponding part of the document. | |
381 | This flag can be toggled from within the *toc* buffer with the `f' key." | |
382 | :group 'reftex-table-of-contents-browser | |
383 | :type 'boolean) | |
384 | ||
385 | (defcustom reftex-revisit-to-follow nil | |
386 | "*Non-nil means, follow-mode will revisit files if necessary. | |
387 | When nil, follow-mode will be suspended for stuff in unvisited files." | |
388 | :group 'reftex-table-of-contents-browser | |
389 | :group 'reftex-referencing-labels | |
390 | :type 'boolean) | |
391 | ||
392 | (defcustom reftex-toc-mode-hook nil | |
393 | "Mode hook for reftex-toc-mode." | |
394 | :group 'reftex-table-of-contents-browser | |
395 | :type 'hook) | |
396 | ||
397 | ;; Label configuration ----------------------------------------------------- | |
398 | ||
a7ec1775 | 399 | (defgroup reftex-label-support nil |
c52bdfca | 400 | "Support for creation, insertion and referencing of labels in LaTeX." |
a7ec1775 RS |
401 | :group 'reftex) |
402 | ||
403 | (defgroup reftex-defining-label-environments nil | |
c52bdfca | 404 | "Definition of environments and macros to do with label." |
a7ec1775 RS |
405 | :group 'reftex-label-support) |
406 | ||
396e0b08 KH |
407 | (defcustom reftex-default-label-alist-entries |
408 | '(amsmath endnotes fancybox floatfig longtable picinpar | |
29d593f8 | 409 | rotating sidecap subfigure supertab wrapfig LaTeX) |
396e0b08 KH |
410 | "Default label alist specifications. LaTeX should be the last entry. |
411 | This list describes the default label environments RefTeX should always use. | |
412 | It is probably a mistake to remove the LaTeX symbol from this list. | |
413 | ||
414 | The options include: | |
415 | LaTeX The standard LaTeX environments. | |
416 | Sideways The sidewaysfigure and sidewaystable environments. | |
417 | AMSTeX The math environments in the AMS-LaTeX amsmath package. | |
418 | ||
419 | For the full list of options, try | |
420 | ||
421 | M-x customize-variable RET reftex-default-label-alist-entries RET." | |
422 | :group 'reftex-defining-label-environments | |
423 | :set 'reftex-set-dirty | |
424 | :type `(set | |
425 | :indent 4 | |
426 | :inline t | |
427 | :greedy t | |
428 | ,@(mapcar | |
429 | (function | |
430 | (lambda (x) | |
921759ee | 431 | (list 'const :tag (concat (symbol-name (nth 0 x)) |
396e0b08 KH |
432 | ": " (nth 1 x)) |
433 | (nth 0 x)))) | |
434 | reftex-label-alist-builtin))) | |
435 | ||
a7ec1775 | 436 | (defcustom reftex-label-alist nil |
fba437e6 | 437 | "Alist with information on environments for \\label-\\ref use. |
a7ec1775 | 438 | |
396e0b08 KH |
439 | This docstring is easier to understand after reading the configuration |
440 | examples in `reftex.el'. Looking at the builtin defaults in the constant | |
441 | `reftex-label-alist-builtin' may also be instructive. | |
442 | ||
443 | Set this variable to define additions and changes to the default. The only | |
444 | things you MUST NOT change is that `?s' is the type indicator for section | |
445 | labels, and SPC for the `any' label type. These are hard-coded at other | |
446 | places in the code. | |
a7ec1775 | 447 | |
396e0b08 KH |
448 | Each list entry describes either an environment carrying a counter for use |
449 | with \\label and \\ref, or a LaTeX macro defining a label as (or inside) | |
450 | one of its arguments. The elements of each list entry are: | |
a7ec1775 RS |
451 | |
452 | 0. Name of the environment (like \"table\") or macro (like \"\\\\myfig\"). | |
396e0b08 KH |
453 | For macros, indicate the macro arguments for best results, as in |
454 | \"\\\\myfig[]{}{}{*}{}\". Use square brackets for optional arguments, | |
455 | a star to mark the label argument, if any. The macro does not have to | |
456 | have a label argument - you could also use \\label{..} inside one of | |
457 | its arguments. | |
a7ec1775 RS |
458 | Special names: `section' for section labels, `any' to define a group |
459 | which contains all labels. | |
396e0b08 | 460 | This may also be nil if the entry is only meant to change some settings |
a7ec1775 RS |
461 | associated with the type indicator character (see below). |
462 | ||
396e0b08 KH |
463 | 1. Type indicator character, like `?t', must be a printable ASCII character. |
464 | The type indicator is a single character which defines a label type. | |
465 | Any label inside the environment or macro is assumed to belong to this | |
466 | type. The same character may occur several times in this list, to cover | |
467 | cases in which different environments carry the same label type (like | |
468 | `equation' and `eqnarray'). | |
b849548d CD |
469 | If the type indicator is nil and the macro has a label argument {*}, |
470 | the macro defines neutral labels just like \label. In this case | |
471 | the reminder of this entry is ignored. | |
a7ec1775 RS |
472 | |
473 | 2. Label prefix string, like \"tab:\". | |
f52b232e | 474 | The prefix is a short string used as the start of a label. It may be the |
396e0b08 | 475 | empty string. The prefix may contain the following `%' escapes: |
206c6f82 RS |
476 | %f Current file name with directory and extension stripped. |
477 | %F Current file name relative to directory of master file. | |
478 | %u User login name, on systems which support this. | |
479 | ||
480 | Example: In a file `intro.tex', \"eq:%f:\" will become \"eq:intro:\"). | |
a7ec1775 | 481 | |
206c6f82 RS |
482 | 3. Format string for reference insert in buffer. `%s' will be replaced by |
483 | the label. | |
2faef409 RS |
484 | When the format starts with `~', the `~' will only be inserted if |
485 | there is not already a whitespace before point. | |
a7ec1775 RS |
486 | |
487 | 4. Indication on how to find the short context. | |
f52b232e RS |
488 | - If nil, use the text following the \\label{...} macro. |
489 | - If t, use | |
a7ec1775 | 490 | - the section heading for section labels. |
396e0b08 KH |
491 | - text following the \\begin{...} statement of environments. |
492 | (not a good choice for environments like eqnarray or enumerate, | |
493 | where one has several labels in a single environment). | |
2faef409 | 494 | - text after the macro name (starting with the first arg) for macros. |
396e0b08 KH |
495 | - If an integer, use the nth argument of the macro. As a special case, |
496 | 1000 means to get text after the last macro argument. | |
f52b232e RS |
497 | - If a string, use as regexp to search *backward* from the label. Context |
498 | is then the text following the end of the match. E.g. putting this to | |
baec1250 | 499 | \"\\\\\\\\caption[[{]\" will use the caption in a figure or table |
396e0b08 | 500 | environment. |
c52bdfca | 501 | \"\\\\\\\\begin{eqnarray}\\\\|\\\\\\\\\\\\\\\\\" works for eqnarrays. |
396e0b08 KH |
502 | - If any of `caption', `item', `eqnarray-like', `alignat-like', this |
503 | symbol will internally be translated into an appropriate regexp | |
504 | (see also the variable `reftex-default-context-regexps'). | |
a7ec1775 | 505 | - If a function, call this function with the name of the environment/macro |
f52b232e RS |
506 | as argument. On call, point will be just after the \\label macro. The |
507 | function is expected to return a suitable context string. It should | |
a7ec1775 | 508 | throw an exception (error) when failing to find context. |
206c6f82 RS |
509 | As an example, here is a function returning the 10 chars following |
510 | the label macro as context: | |
a7ec1775 RS |
511 | |
512 | (defun my-context-function (env-or-mac) | |
513 | (if (> (point-max) (+ 10 (point))) | |
514 | (buffer-substring (point) (+ 10 (point))) | |
515 | (error \"Buffer too small\"))) | |
516 | ||
206c6f82 RS |
517 | Label context is used in two ways by RefTeX: For display in the label |
518 | menu, and to derive a label string. If you want to use a different | |
519 | method for each of these, specify them as a dotted pair. | |
520 | E.g. `(nil . t)' uses the text after the label (nil) for display, and | |
521 | text from the default position (t) to derive a label string. This is | |
522 | actually used for section labels. | |
523 | ||
c52bdfca RS |
524 | 5. List of magic words which identify a reference to be of this type. |
525 | If the word before point is equal to one of these words when calling | |
206c6f82 RS |
526 | `reftex-reference', the label list offered will be automatically |
527 | restricted to labels of the correct type. | |
2faef409 RS |
528 | If the first element of this wordlist is the symbol `regexp', the |
529 | strings are interpreted as regular expressions. RefTeX will add | |
530 | a \"\\\\W\" to the beginning and other stuff to the end of the regexp. | |
a7ec1775 RS |
531 | |
532 | If the type indicator characters of two or more entries are the same, RefTeX | |
533 | will use | |
534 | - the first non-nil format and prefix | |
535 | - the magic words of all involved entries. | |
536 | ||
f52b232e | 537 | Any list entry may also be a symbol. If that has an association in |
2faef409 RS |
538 | `reftex-label-alist-builtin', the cddr of that association is spliced into the |
539 | list. However, builtin defaults should normally be set with the variable | |
540 | `reftex-default-label-alist-entries." | |
a7ec1775 RS |
541 | :group 'reftex-defining-label-environments |
542 | :set 'reftex-set-dirty | |
206c6f82 | 543 | :type |
396e0b08 | 544 | `(repeat |
b849548d | 545 | (choice :tag "Package or Detailed " |
396e0b08 | 546 | :value ("" ?a nil nil nil nil) |
b849548d | 547 | (list :tag "Detailed Entry" |
396e0b08 KH |
548 | :value ("" ?a nil nil nil nil) |
549 | (choice :tag "Environment or \\macro " | |
550 | (const :tag "Ignore, just use typekey" nil) | |
551 | (string "")) | |
b849548d CD |
552 | (choice :tag "Type specification " |
553 | (const :tag "unspecified, like in \\label" nil) | |
554 | (character :tag "Char " ?a)) | |
396e0b08 KH |
555 | (choice :tag "Label prefix string " |
556 | (const :tag "Default" nil) | |
557 | (string :tag "String" "lab:")) | |
558 | (choice :tag "Label reference format" | |
559 | (const :tag "Default" nil) | |
560 | (string :tag "String" "~\\ref{%s}")) | |
b849548d CD |
561 | (choice :tag "Context method " |
562 | (const :tag "Default position" t) | |
563 | (const :tag "After label" nil) | |
564 | (number :tag "Macro arg nr" 1) | |
565 | (regexp :tag "Regexp" "") | |
566 | (const :tag "Caption in float" caption) | |
567 | (const :tag "Item in list" item) | |
568 | (const :tag "Eqnarray-like" eqnarray-like) | |
569 | (const :tag "Alignat-like" alignat-like) | |
570 | (symbol :tag "Function" my-func)) | |
571 | (repeat :tag "Magic words" :extra-offset 2 (string))) | |
396e0b08 KH |
572 | (choice |
573 | :tag "Package" | |
206c6f82 | 574 | :value AMSTeX |
396e0b08 KH |
575 | ,@(mapcar |
576 | (function | |
577 | (lambda (x) | |
921759ee | 578 | (list 'const :tag (concat (symbol-name (nth 0 x))) |
396e0b08 KH |
579 | (nth 0 x)))) |
580 | reftex-label-alist-builtin))))) | |
a7ec1775 | 581 | |
baec1250 KH |
582 | ;; LaTeX section commands and level numbers |
583 | (defcustom reftex-section-levels | |
584 | '( | |
921759ee CD |
585 | ("part" . 0) |
586 | ("chapter" . 1) | |
587 | ("section" . 2) | |
588 | ("subsection" . 3) | |
589 | ("subsubsection" . 4) | |
590 | ("paragraph" . 5) | |
591 | ("subparagraph" . 6) | |
592 | ("subsubparagraph" . 7) | |
593 | ("addchap" . -1) ; KOMA-Script | |
594 | ("addsec" . -2) ; KOMA-Script | |
595 | ;;; ("minisec" . -7) ; KOMA-Script | |
baec1250 KH |
596 | ) |
597 | "Commands and levels used for defining sections in the document. | |
598 | The car of each cons cell is the name of the section macro. The cdr is a | |
921759ee CD |
599 | number indicating its level. A negative level means the same as the |
600 | positive value, but the section will never get a number." | |
baec1250 KH |
601 | :group 'reftex-defining-label-environments |
602 | :set 'reftex-set-dirty | |
603 | :type '(repeat | |
604 | (cons (string :tag "sectioning macro" "") | |
605 | (number :tag "level " 0)))) | |
606 | ||
607 | (defcustom reftex-default-context-regexps | |
608 | '((caption . "\\\\\\(rot\\)?caption\\*?[[{]") | |
609 | (item . "\\\\item\\(\\[[^]]*\\]\\)?") | |
610 | (eqnarray-like . "\\\\begin{%s}\\|\\\\\\\\") | |
611 | (alignat-like . "\\\\begin{%s}{[0-9]*}\\|\\\\\\\\")) | |
612 | "Alist with default regular expressions for finding context. | |
613 | The form (format regexp (regexp-quote environment)) is used to calculate | |
614 | the final regular expression - so %s will be replaced with the environment | |
615 | or macro." | |
616 | :group 'reftex-defining-label-environments | |
617 | :type '(repeat (cons (symbol) (regexp)))) | |
618 | ||
a7ec1775 RS |
619 | ;; Label insertion |
620 | ||
621 | (defgroup reftex-making-and-inserting-labels nil | |
c52bdfca | 622 | "Options on how to create new labels." |
a7ec1775 RS |
623 | :group 'reftex-label-support) |
624 | ||
625 | (defcustom reftex-insert-label-flags '("s" "sft") | |
c52bdfca | 626 | "Flags governing label insertion. First flag DERIVE, second flag PROMPT. |
a7ec1775 RS |
627 | |
628 | If DERIVE is t, RefTeX will try to derive a sensible label from context. | |
629 | A section label for example will be derived from the section heading. | |
630 | The conversion of the context to a legal label is governed by the | |
c52bdfca | 631 | specifications given in `reftex-derive-label-parameters'. |
a7ec1775 | 632 | If RefTeX fails to derive a label, it will prompt the user. |
396e0b08 KH |
633 | If DERIVE is nil, the label generated will consist of the prefix and a |
634 | unique number, like `eq:23'. | |
a7ec1775 | 635 | |
c52bdfca | 636 | If PROMPT is t, the user will be prompted for a label string. The prompt will |
a7ec1775 RS |
637 | already contain the prefix, and (if DERIVE is t) a default label derived from |
638 | context. When PROMPT is nil, the default label will be inserted without | |
639 | query. | |
640 | ||
c52bdfca | 641 | So the combination of DERIVE and PROMPT controls label insertion. Here is a |
a7ec1775 RS |
642 | table describing all four possibilities: |
643 | ||
644 | DERIVE PROMPT ACTION | |
645 | ------------------------------------------------------------------------- | |
c52bdfca RS |
646 | nil nil Insert simple label, like eq:22 or sec:13. No query. |
647 | nil t Prompt for label. | |
648 | t nil Derive a label from context and insert without query. | |
649 | t t Derive a label from context and prompt for confirmation. | |
a7ec1775 RS |
650 | |
651 | Each flag may be set to t, nil, or a string of label type letters | |
2faef409 RS |
652 | indicating the label types for which it should be true. The strings work |
653 | like character classes. | |
c52bdfca | 654 | Thus, the combination may be set differently for each label type. The |
a7ec1775 | 655 | default settings \"s\" and \"sft\" mean: Derive section labels from headings |
c52bdfca | 656 | (with confirmation). Prompt for figure and table labels. Use simple labels |
2faef409 RS |
657 | without confirmation for everything else. |
658 | The available label types are: s (section), f (figure), t (table), i (item), | |
659 | e (equation), n (footnote), plus any definitions in `reftex-label-alist'." | |
a7ec1775 RS |
660 | :group 'reftex-making-and-inserting-labels |
661 | :type '(list (choice :tag "Derive label from context" | |
662 | (const :tag "always" t) | |
663 | (const :tag "never" nil) | |
206c6f82 | 664 | (string :tag "selected label types" "")) |
a7ec1775 RS |
665 | (choice :tag "Prompt for label string " |
666 | :entry-format " %b %v" | |
667 | (const :tag "always" t) | |
668 | (const :tag "never" nil) | |
206c6f82 | 669 | (string :tag "selected label types" "")))) |
a7ec1775 | 670 | |
b849548d CD |
671 | (defcustom reftex-string-to-label-function 'reftex-string-to-label |
672 | "Function to turn an arbitrary string into a legal label. | |
673 | RefTeX's default function uses the variable `reftex-derive-label-parameters'." | |
674 | :group 'reftex-making-and-inserting-labels | |
675 | :type 'symbol) | |
676 | ||
a6611c0d | 677 | (defcustom reftex-translate-to-ascii-function 'reftex-latin1-to-ascii |
b849548d | 678 | "Filter function which will process a context string before it is used |
a6611c0d CD |
679 | to derive a label from it. The intended application is to convert ISO or |
680 | Mule characters into something legal in labels. The default function | |
681 | removes the accents from Latin-1 characters. X-Symbol (>=2.6) sets this | |
682 | variable to the much more general `x-symbol-translate-to-ascii'." | |
b849548d CD |
683 | :group 'reftex-making-and-inserting-labels |
684 | :type 'symbol) | |
685 | ||
396e0b08 | 686 | (defcustom reftex-derive-label-parameters '(3 20 t 1 "-" |
b849548d | 687 | ("the" "on" "in" "off" "a" "for" "by" "of" "and" "is" "to") t) |
a7ec1775 RS |
688 | "Parameters for converting a string into a label. |
689 | NWORDS Number of words to use. | |
690 | MAXCHAR Maximum number of characters in a label string. | |
691 | ILLEGAL nil: Throw away any words containing characters illegal in labels. | |
692 | t: Throw away only the illegal characters, not the whole word. | |
693 | ABBREV nil: Never abbreviate words. | |
c52bdfca | 694 | t: Always abbreviate words (see `reftex-abbrev-parameters'). |
a7ec1775 RS |
695 | not t and not nil: Abbreviate words if necessary to shorten |
696 | label string below MAXCHAR. | |
c52bdfca | 697 | SEPARATOR String separating different words in the label. |
b849548d CD |
698 | IGNOREWORDS List of words which should not be part of labels. |
699 | DOWNCASE t: Downcase words before using them." | |
a7ec1775 RS |
700 | :group 'reftex-making-and-inserting-labels |
701 | :type '(list (integer :tag "Number of words " 3) | |
396e0b08 KH |
702 | (integer :tag "Maximum label length " 20) |
703 | (choice :tag "Illegal characters in words" | |
704 | (const :tag "throw away entire word" nil) | |
705 | (const :tag "throw away single chars" t)) | |
706 | (choice :tag "Abbreviate words " | |
707 | (const :tag "never" nil) | |
708 | (const :tag "always" t) | |
709 | (const :tag "when label is too long" 1)) | |
710 | (string :tag "Separator between words " "-") | |
711 | (repeat :tag "Ignore words" | |
712 | :entry-format " %i %d %v" | |
b849548d CD |
713 | (string :tag "")) |
714 | (option (boolean :tag "Downcase words ")))) | |
396e0b08 | 715 | |
a6611c0d CD |
716 | (defcustom reftex-label-illegal-re "[^-a-zA-Z0-9_+=:;,.]" |
717 | "Regexp matching characters not legal in labels." | |
a7ec1775 | 718 | :group 'reftex-making-and-inserting-labels |
a6611c0d | 719 | :type '(regexp :tag "Regular Expression")) |
a7ec1775 | 720 | |
b849548d | 721 | (defcustom reftex-abbrev-parameters '(4 2 "^aeiou" "aeiou") |
a7ec1775 | 722 | "Parameters for abbreviation of words. |
c52bdfca RS |
723 | MIN-CHARS Minimum number of characters remaining after abbreviation. |
724 | MIN-KILL Minimum number of characters to remove when abbreviating words. | |
725 | BEFORE Character class before abbrev point in word. | |
726 | AFTER Character class after abbrev point in word." | |
a7ec1775 RS |
727 | :group 'reftex-making-and-inserting-labels |
728 | :type '(list | |
396e0b08 KH |
729 | (integer :tag "Minimum chars per word" 4) |
730 | (integer :tag "Shorten by at least " 2) | |
731 | (string :tag "cut before char class " "^saeiou") | |
732 | (string :tag "cut after char class " "aeiou"))) | |
a7ec1775 | 733 | |
2faef409 RS |
734 | (defcustom reftex-format-label-function nil |
735 | "Function which produces the string to insert as a label definition. | |
736 | Normally should be nil, unless you want to do something fancy. | |
737 | The function will be called with two arguments, the LABEL and the DEFAULT | |
738 | FORMAT, which usually is `\label{%s}'. The function should return the | |
739 | string to insert into the buffer." | |
740 | :group 'reftex-making-and-inserting-labels | |
741 | :type 'function) | |
742 | ||
a7ec1775 RS |
743 | ;; Label referencing |
744 | ||
745 | (defgroup reftex-referencing-labels nil | |
c52bdfca | 746 | "Options on how to reference labels." |
a7ec1775 RS |
747 | :group 'reftex-label-support) |
748 | ||
396e0b08 KH |
749 | (eval-and-compile |
750 | (defconst reftex-tmp | |
751 | '((const :tag "on" t) | |
752 | (const :tag "off" nil) | |
753 | (string :tag "Selected label types")))) | |
754 | ||
755 | (defcustom reftex-label-menu-flags '(t t nil nil nil nil t nil) | |
756 | "List of flags governing the label menu makeup. | |
a7ec1775 RS |
757 | The flags are: |
758 | ||
759 | TABLE-OF-CONTENTS Show the labels embedded in a table of context. | |
760 | SECTION-NUMBERS Include section numbers (like 4.1.3) in table of contents. | |
c52bdfca | 761 | COUNTERS Show counters. This just numbers the labels in the menu. |
a7ec1775 | 762 | NO-CONTEXT Non-nil means do NOT show the short context. |
c52bdfca | 763 | FOLLOW Follow full context in other window. |
206c6f82 | 764 | SHOW-COMMENTED Show labels from regions which are commented out. |
be456a1d | 765 | MATCH-IN-TOC Obsolete flag. |
29d593f8 | 766 | SHOW FILES Show begin and end of included files. |
a7ec1775 RS |
767 | |
768 | Each of these flags can be set to t or nil, or to a string of type letters | |
c52bdfca RS |
769 | indicating the label types for which it should be true. These strings work |
770 | like character classes in regular expressions. Thus, setting one of the | |
a7ec1775 | 771 | flags to \"sf\" makes the flag true for section and figure labels, nil |
29d593f8 | 772 | for everything else. Setting it to \"^sf\" makes it the other way round. |
2faef409 RS |
773 | The available label types are: s (section), f (figure), t (table), i (item), |
774 | e (equation), n (footnote), plus any definitions in `reftex-label-alist'. | |
a7ec1775 RS |
775 | |
776 | Most options can also be switched from the label menu itself - so if you | |
777 | decide here to not have a table of contents in the label menu, you can still | |
778 | get one interactively during selection from the label menu." | |
779 | :group 'reftex-referencing-labels | |
396e0b08 KH |
780 | :type |
781 | `(list | |
782 | (choice :tag "Embed in table of contents " ,@reftex-tmp) | |
783 | (choice :tag "Show section numbers " ,@reftex-tmp) | |
784 | (choice :tag "Show individual counters " ,@reftex-tmp) | |
785 | (choice :tag "Hide short context " ,@reftex-tmp) | |
786 | (choice :tag "Follow context in other window " ,@reftex-tmp) | |
787 | (choice :tag "Show commented labels " ,@reftex-tmp) | |
be456a1d | 788 | (choice :tag "Obsolete flag, Don't use. " ,@reftex-tmp) |
396e0b08 KH |
789 | (choice :tag "Show begin/end of included files" ,@reftex-tmp))) |
790 | ||
2faef409 RS |
791 | (defcustom reftex-vref-is-default nil |
792 | "*Non-nil means, the varioref macro \\vref is used as default. | |
793 | In the selection buffer, the `v' key toggles the reference macro between | |
794 | `\\ref' and `\\vref'. The value of this variable determines the default | |
795 | which is active when entering the selection process. | |
796 | Instead of nil or t, this may also be a string of type letters indicating | |
797 | the label types for which it should be true." | |
798 | :group 'reftex-referencing-labels | |
799 | :type `(choice :tag "\\vref is default macro" ,@reftex-tmp)) | |
800 | ||
396e0b08 KH |
801 | (defcustom reftex-level-indent 2 |
802 | "*Number of spaces to be used for indentation per section level." | |
803 | :group 'reftex-referencing-labels | |
b849548d | 804 | :type 'integer) |
396e0b08 | 805 | |
a7ec1775 | 806 | (defcustom reftex-guess-label-type t |
c52bdfca | 807 | "*Non-nil means, `reftex-reference' will try to guess the label type. |
a7ec1775 | 808 | To do that, RefTeX will look at the word before the cursor and compare it with |
c52bdfca | 809 | the words given in `reftex-label-alist'. When it finds a match, RefTeX will |
a7ec1775 | 810 | immediately offer the correct label menu - otherwise it will prompt you for |
c52bdfca | 811 | a label type. If you set this variable to nil, RefTeX will always prompt." |
a7ec1775 | 812 | :group 'reftex-referencing-labels |
b849548d | 813 | :type 'boolean) |
a7ec1775 | 814 | |
2faef409 RS |
815 | (defcustom reftex-format-ref-function nil |
816 | "Function which produces the string to insert as a reference. | |
817 | Normally should be nil, because the format to insert a reference can | |
818 | already be specified in `reftex-label-alist'. | |
819 | The function will be called with two arguments, the LABEL and the DEFAULT | |
820 | FORMAT, which normally is `~\ref{%s}'. The function should return the | |
821 | string to insert into the buffer." | |
822 | :group 'reftex-referencing-labels | |
823 | :type 'function) | |
824 | ||
b849548d CD |
825 | (defcustom reftex-select-label-mode-hook nil |
826 | "Mode hook for reftex-select-label-mode." | |
827 | :group 'reftex-referencing-labels | |
828 | :type 'hook) | |
829 | ||
a7ec1775 RS |
830 | ;; BibteX citation configuration ---------------------------------------- |
831 | ||
832 | (defgroup reftex-citation-support nil | |
c52bdfca | 833 | "Support for referencing bibliographic data with BibTeX." |
a7ec1775 RS |
834 | :group 'reftex) |
835 | ||
b849548d CD |
836 | (defvar reftex-bibfile-ignore-list nil) ; compatibility |
837 | (defcustom reftex-bibfile-ignore-regexps nil | |
838 | "*List of regular expressions to exclude files in \\bibliography{..}. | |
839 | File names matched by these regexps will not be parsed by RefTeX. | |
a7ec1775 RS |
840 | Intended for files which contain only `@string' macro definitions and the |
841 | like, which are ignored by RefTeX anyway." | |
842 | :group 'reftex-citation-support | |
843 | :set 'reftex-set-dirty | |
b849548d | 844 | :type '(repeat (regexp))) |
a7ec1775 | 845 | |
2faef409 | 846 | (defcustom reftex-default-bibliography nil |
a6611c0d | 847 | "*List of BibTeX database files which should be used if none are specified. |
2faef409 RS |
848 | When `reftex-citation' is called from a document which has neither a |
849 | `\bibliography{..}' statement nor a `thebibliography' environment, | |
921759ee CD |
850 | RefTeX will scan these files instead. Intended for using `reftex-citation' |
851 | in non-LaTeX files. The files will be searched along the BIBINPUTS or TEXBIB | |
852 | path." | |
2faef409 RS |
853 | :group 'reftex-citation-support |
854 | :type '(repeat (file))) | |
855 | ||
a7ec1775 RS |
856 | (defcustom reftex-sort-bibtex-matches 'reverse-year |
857 | "*Sorting of the entries found in BibTeX databases by reftex-citation. | |
858 | Possible values: | |
859 | nil Do not sort entries. | |
860 | 'author Sort entries by author name. | |
861 | 'year Sort entries by increasing year. | |
862 | 'reverse-year Sort entries by decreasing year." | |
863 | :group 'reftex-citation-support | |
864 | :type '(choice (const :tag "not" nil) | |
396e0b08 KH |
865 | (const :tag "by author" author) |
866 | (const :tag "by year" year) | |
867 | (const :tag "by year, reversed" reverse-year))) | |
a7ec1775 | 868 | |
206c6f82 | 869 | (defcustom reftex-cite-format 'default |
396e0b08 | 870 | "*The format of citations to be inserted into the buffer. |
206c6f82 RS |
871 | It can be a string or an alist. In the simplest case this is just |
872 | the string \"\\cite{%l}\", which is also the default. See the | |
873 | definition of `reftex-cite-format-builtin' for more complex examples. | |
874 | ||
875 | If `reftex-cite-format' is a string, it will be used as the format. | |
876 | In the format, the following percent escapes will be expanded. | |
877 | ||
878 | %l The BibTeX label of the citation. | |
879 | %a List of author names, see also `reftex-cite-punctuation. | |
880 | %2a Like %a, but abbreviate more than 2 authors like Jones et al. | |
881 | %A First author name only. | |
882 | %e Works like %a, but on list of editor names. (%2e and %E work a well) | |
883 | ||
884 | It is also possible to access all other BibTeX database fields: | |
885 | %b booktitle %c chapter %d edition %h howpublished | |
886 | %i institution %j journal %k key %m month | |
887 | %n number %o organization %p pages %P first page | |
888 | %r address %s school %u publisher %t title | |
b849548d CD |
889 | %v volume %y year |
890 | %B booktitle, abbreviated %T title, abbreviated | |
891 | ||
892 | Usually, only %l is needed. The other stuff is mainly for the echo area | |
893 | display, and for (setq reftex-comment-citations t). | |
206c6f82 | 894 | |
b849548d CD |
895 | %< as a special operator kills punctuation and space around it after the |
896 | string has been formatted. | |
206c6f82 | 897 | |
b849548d | 898 | Beware that all this only works with BibTeX database files. When |
2faef409 RS |
899 | citations are made from the \\bibitems in an explicit thebibliography |
900 | environment, only %l is available. | |
901 | ||
206c6f82 RS |
902 | If `reftex-cite-format' is an alist of characters and strings, the user |
903 | will be prompted for a character to select one of the possible format | |
904 | strings. | |
a7ec1775 | 905 | In order to configure this variable, you can either set |
c52bdfca | 906 | `reftex-cite-format' directly yourself or set it to the SYMBOL of one of |
206c6f82 | 907 | the predefined styles (see `reftex-cite-format-builtin'). E.g.: |
b849548d | 908 | (setq reftex-cite-format 'natbib)" |
396e0b08 KH |
909 | :group 'reftex-citation-support |
910 | :type | |
911 | `(choice | |
912 | :format "%{%t%}: \n%[Value Menu%] %v" | |
913 | (radio :tag "Symbolic Builtins" | |
914 | :indent 4 | |
915 | :value default | |
916 | ,@(mapcar | |
917 | (function | |
918 | (lambda (x) | |
921759ee | 919 | (list 'const :tag (concat (symbol-name (nth 0 x)) |
396e0b08 KH |
920 | ": " (nth 1 x)) |
921 | (nth 0 x)))) | |
922 | reftex-cite-format-builtin)) | |
923 | (string :tag "format string" "\\cite{%l}") | |
924 | (repeat :tag "key-ed format strings" | |
925 | :value ((?\r . "\\cite{%l}") | |
926 | (?t . "\\cite{%l}") (?p . "\\cite{%l}")) | |
927 | (cons (character :tag "Key character" ?\r) | |
928 | (string :tag "Format string" ""))))) | |
206c6f82 RS |
929 | |
930 | (defcustom reftex-comment-citations nil | |
396e0b08 | 931 | "*Non-nil means add a comment for each citation describing the full entry. |
206c6f82 RS |
932 | The comment is formatted according to `reftex-cite-comment-format'." |
933 | :group 'reftex-citation-support | |
b849548d | 934 | :type 'boolean) |
206c6f82 | 935 | |
396e0b08 | 936 | (defcustom reftex-cite-comment-format |
b849548d CD |
937 | "%% %2a %y, %j %v, %P, %b, %e, %u, %s %<\n" |
938 | "Citation format used for commented citations. Must NOT contain %l. | |
939 | See the variable `reftex-cite-format' for possible percent escapes." | |
940 | :group 'reftex-citation-support | |
941 | :type 'string) | |
942 | ||
943 | (defcustom reftex-cite-view-format | |
944 | "%2a %y, %T, %B, %j %v:%P, %s %<" | |
945 | "Citation format used to display citation info in the message area. | |
946 | Must NOT contain %l. See the variable `reftex-cite-format' for | |
947 | possible percent escapes." | |
206c6f82 | 948 | :group 'reftex-citation-support |
b849548d CD |
949 | :group 'reftex-viewing-cross-references-and-citations |
950 | :type 'string) | |
206c6f82 RS |
951 | |
952 | (defcustom reftex-cite-punctuation '(", " " \\& " " {\\it et al.}") | |
953 | "Punctuation for formatting of name lists in citations. | |
954 | This is a list of 3 strings. | |
955 | 1. normal names separator, like \", \" in Jones, Brown and Miller | |
956 | 2. final names separator, like \" and \" in Jones, Brown and Miller | |
2faef409 | 957 | 3. The \"et al\" string, like \" {\\it et al.}\" in Jones {\\it et al.}" |
396e0b08 | 958 | :group 'reftex-citation-support |
206c6f82 | 959 | :type '(list |
396e0b08 KH |
960 | (string :tag "Separator for names ") |
961 | (string :tag "Separator for last name in list") | |
962 | (string :tag "string used as et al. "))) | |
a7ec1775 | 963 | |
2faef409 RS |
964 | (defcustom reftex-format-cite-function nil |
965 | "Function which produces the string to insert as a citation. | |
966 | Normally should be nil, because the format to insert a reference can | |
967 | already be specified in `reftex-cite-format'. | |
968 | The function will be called with two arguments, the CITATION KEY and the | |
969 | DEFAULT FORMAT, which is taken from `reftex-cite-format'. The function | |
970 | should return the string to insert into the buffer." | |
971 | :group 'reftex-citation-support | |
972 | :type 'function) | |
6b94c6ad | 973 | |
b849548d CD |
974 | (defcustom reftex-select-bib-mode-hook nil |
975 | "Mode hook for reftex-select-bib-mode." | |
976 | :group 'reftex-citation-support | |
977 | :type 'hook) | |
978 | ||
b849548d CD |
979 | ;; Viewing Cross References and Citations |
980 | (defgroup reftex-viewing-cross-references-and-citations nil | |
981 | "Displaying cross references and citations." | |
982 | :group 'reftex) | |
983 | ||
921759ee CD |
984 | (defcustom reftex-view-crossref-extra |
985 | '(("index\\|idx" "\\\\[a-zA-Z]*\\(index\\|idx\\)[a-zA-Z]*\\*?\\(\\[[^]]*\\]\\|{[^}]*}\\)*{\\(%s\\)}" 3)) | |
986 | "Macros which can be used for the display of cross references. | |
987 | This is used when `reftex-view-crossref' is called with point in an | |
988 | argument of a macro. Note that crossref viewing for citations and | |
989 | references (both ways) is hard-coded. This variable is only to | |
990 | configure additional structures for which crossreference viewing | |
991 | can be useful. Each entry has the structure | |
992 | ||
993 | (MACRO-RE SEARCH-RE HIGHLIGHT). | |
994 | ||
995 | MACRO-RE is matched against the macro. SEARCH-RE is the regexp used | |
996 | to search for cross references. `%s' in this regexp is replaced with | |
997 | with the macro argument at point. HIGHLIGHT is an integer indicating | |
998 | which subgroup of the match should be highlighted." | |
999 | :group 'reftex-viewing-cross-references-and-citations | |
1000 | :type '(repeat (group (regexp :tag "Macro Regexp ") | |
1001 | (string :tag "Search Regexp ") | |
1002 | (integer :tag "Highlight Group")))) | |
1003 | ||
b849548d CD |
1004 | (defcustom reftex-auto-view-crossref t |
1005 | "*Non-nil means, initially turn automatic viewing of crossref info on. | |
a6611c0d CD |
1006 | Automatic viewing of crossref info normally uses the echo area. |
1007 | Whenever point is on the argument of a \\ref or \\cite macro, and no | |
1008 | other message is being displayed, the echo area will display | |
1009 | information about that cross reference. You can also set the variable | |
1010 | to the symbol `window'. In this case a small temporary window is | |
1011 | used for the display. | |
b849548d CD |
1012 | This feature can be turned on and of from the menu |
1013 | (Ref->Options->Crossref Viewing)." | |
1014 | :group 'reftex-viewing-cross-references-and-citations | |
a6611c0d CD |
1015 | :type '(choice (const :tag "off" nil) |
1016 | (const :tag "in Echo Area" t) | |
1017 | (const :tag "in Other Window" window))) | |
b849548d CD |
1018 | |
1019 | (defcustom reftex-idle-time 1.2 | |
1020 | "*Time (secs) Emacs has to be idle before automatic crossref display is done." | |
1021 | :group 'reftex-viewing-cross-references-and-citations | |
1022 | :type 'number) | |
1023 | ||
1024 | (defcustom reftex-revisit-to-echo nil | |
1025 | "*Non-nil means, automatic citation display will revisit files if necessary. | |
1026 | When nil, citation display in echo area will only be active for cached | |
1027 | entries and for BibTeX database files with live associated buffers." | |
1028 | :group 'reftex-viewing-cross-references-and-citations | |
1029 | :type 'boolean) | |
1030 | ||
1031 | (defcustom reftex-cache-cite-echo t | |
1032 | "*Non-nil means, the information displayed in the echo area for cite macros | |
1033 | is cached and even saved along with the parsing information. The cache | |
1034 | survives document scans. In order to clear it, use M-x reftex-reset-mode." | |
1035 | :group 'reftex-viewing-cross-references-and-citations | |
1036 | :type 'boolean) | |
1037 | ||
1038 | (defcustom reftex-display-copied-context-hook nil | |
1039 | "Normal Hook which is run before context is displayed anywhere. Designed | |
1040 | for X-Symbol, but may have other uses as well." | |
1041 | :group 'reftex-viewing-cross-references-and-citations | |
1042 | :group 'reftex-referencing-labels | |
1043 | :type 'hook) | |
a7ec1775 | 1044 | |
51d628c8 CD |
1045 | ;; Finding Files -------------------------------------------------------- |
1046 | ||
1047 | (defgroup reftex-finding-files nil | |
f9ad2e24 | 1048 | "Finding files on search paths." |
51d628c8 CD |
1049 | :group 'reftex) |
1050 | ||
1051 | (defcustom reftex-texpath-environment-variables '("TEXINPUTS") | |
1052 | "*List of specifications how to retrieve the search path for TeX files. | |
1053 | Several entries are possible. | |
1054 | - If an element is the name of an environment variable, its content is used. | |
1055 | - If an element starts with an exclamation mark, it is used as a command | |
1056 | to retrieve the path. A typical command with the kpathsearch library would | |
1057 | be `!kpsewhich -show-path=.tex'. | |
1058 | - Otherwise the element itself is interpreted as a path. | |
1059 | Multiple directories can be separated by the system dependent `path-separator'. | |
1060 | Directories ending in `//' or `!!' will be expanded recursively. | |
1061 | See also `reftex-use-external-file-finders'." | |
1062 | :group 'reftex-finding-files | |
1063 | :set 'reftex-set-dirty | |
1064 | :type '(repeat (string :tag "Specification"))) | |
1065 | ||
1066 | (defcustom reftex-bibpath-environment-variables '("BIBINPUTS" "TEXBIB") | |
1067 | "*List of specifications how to retrieve search path for .bib database files. | |
1068 | Several entries are possible. | |
1069 | - If an element is the name of an environment variable, its content is used. | |
1070 | - If an element starts with an exclamation mark, it is used as a command | |
1071 | to retrieve the path. A typical command with the kpathsearch library would | |
1072 | be `!kpsewhich -show-path=.bib'. | |
1073 | - Otherwise the element itself is interpreted as a path. | |
1074 | Multiple directories can be separated by the system dependent `path-separator'. | |
1075 | Directories ending in `//' or `!!' will be expanded recursively. | |
1076 | See also `reftex-use-external-file-finders'." | |
1077 | :group 'reftex-citation-support | |
1078 | :group 'reftex-finding-files | |
1079 | :set 'reftex-set-dirty | |
1080 | :type '(repeat (string :tag "Specification"))) | |
1081 | ||
f9ad2e24 CD |
1082 | (defcustom reftex-file-extensions '(("tex" . (".tex" ".ltx")) |
1083 | ("bib" . (".bib"))) | |
1084 | "*Association list with file extensions for different file types. | |
1085 | This is a list of items, each item is like: (TYPE . (DEF-EXT OTHER-EXT ...)) | |
1086 | ||
1087 | TYPE: File type like \"bib\" or \"tex\". | |
1088 | DEF-EXT: The default extension for that file type, like \".tex\" or \".bib\". | |
1089 | OTHER-EXT: Any number of other legal extensions for this file type. | |
1090 | ||
1091 | When a files is searched and it does not have any of the legal extensions, | |
1092 | we try the default extension first, and then the naked file name." | |
1093 | :group 'reftex-finding-files | |
1094 | :type '(repeat (cons (string :tag "File type") | |
1095 | (repeat (string :tag "Extension"))))) | |
1096 | ||
51d628c8 CD |
1097 | (defcustom reftex-search-unrecursed-path-first t |
1098 | "*Non-nil means, search all specified directories before trying recursion. | |
1099 | Thus, in a path \".//:/tex/\", search first \"./\", then \"/tex/\" and then | |
1100 | all subdirectories of \"./\". If this option is nil, the subdirectories of | |
1101 | \"./\" are searched before \"/tex/\". This is mainly for speed - most of the | |
1102 | time the recursive path is for the system files and not for the user files. | |
1103 | Set this to nil if the default makes RefTeX finding files with equal names | |
1104 | in wrong sequence." | |
1105 | :group 'reftex-finding-files | |
1106 | :type 'boolean) | |
1107 | ||
1108 | (defcustom reftex-use-external-file-finders nil | |
1109 | "*Non-nil means, use external programs to find files. | |
1110 | Normally, RefTeX searches the paths given in the environment variables | |
1111 | TEXINPUTS and BIBINPUTS to find TeX files and BibTeX database files. | |
1112 | With this option turned on, it calls an external program specified in the | |
1113 | option `reftex-external-file-finders' instead. As a side effect, | |
f9ad2e24 | 1114 | the variables `reftex-texpath-environment-variables' and |
51d628c8 CD |
1115 | `reftex-bibpath-environment-variables' will be ignored." |
1116 | :group 'reftex-finding-files | |
1117 | :type 'boolean) | |
1118 | ||
1119 | (defcustom reftex-external-file-finders '(("tex" . "kpsewhich -format=.tex %f") | |
1120 | ("bib" . "kpsewhich -format=.bib %f")) | |
1121 | "*Association list with external programs to call for finding files. | |
1122 | Each entry is a cons cell (TYPE . PROGRAM). | |
f9ad2e24 | 1123 | TYPE is either \"tex\" or \"bib\". PROGRAM is the external program to use with |
51d628c8 CD |
1124 | any arguments. %f will be replaced by the name of the file to be found. |
1125 | Note that these commands will be executed directly, not via a shell. | |
1126 | Only relevant when `reftex-use-external-file-finders' is non-nil." | |
1127 | :group 'reftex-finding-files | |
1128 | :type '(repeat (cons (string :tag "File type") | |
1129 | (string :tag "Program ")))) | |
1130 | ||
396e0b08 KH |
1131 | ;; Tuning the parser ---------------------------------------------------- |
1132 | ||
1133 | (defgroup reftex-optimizations-for-large-documents nil | |
1134 | "Configuration of parser speed and memory usage." | |
1135 | :group 'reftex) | |
1136 | ||
1137 | (defcustom reftex-keep-temporary-buffers 1 | |
1138 | "*Non-nil means, keep buffers created for parsing and lookup. | |
1139 | RefTeX sometimes needs to visit files related to the current document. | |
1140 | We distinguish files visited for | |
1141 | PARSING: Parts of a multifile document loaded when (re)-parsing the document. | |
1142 | LOOKUP: BibTeX database files and TeX files loaded to find a reference, | |
1143 | to display label context, etc. | |
1144 | The created buffers can be kept for later use, or be thrown away immediately | |
1145 | after use, depending on the value of this variable: | |
1146 | ||
1147 | nil Throw away as much as possible. | |
1148 | t Keep everything. | |
1149 | 1 Throw away buffers created for parsing, but keep the ones created | |
1150 | for lookup. | |
1151 | ||
1152 | If a buffer is to be kept, the file is visited normally (which is potentially | |
1153 | slow but will happen only once). | |
1154 | If a buffer is to be thrown away, the initialization of the buffer depends | |
1155 | upon the variable `reftex-initialize-temporary-buffers'." | |
b849548d | 1156 | :group 'reftex-optimizations-for-large-documents |
396e0b08 KH |
1157 | :type '(choice |
1158 | (const :tag "Throw away everything" nil) | |
1159 | (const :tag "Keep everything" t) | |
1160 | (const :tag "Keep lookup buffers only" 1))) | |
1161 | ||
1162 | (defcustom reftex-initialize-temporary-buffers nil | |
1163 | "*Non-nil means do initializations even when visiting file temporarily. | |
1164 | When nil, RefTeX may turn off find-file hooks and other stuff to briefly | |
1165 | visit a file. | |
1166 | When t, the full default initializations are done (find-file-hook etc.). | |
1167 | Instead of t or nil, this variable may also be a list of hook functions to | |
1168 | do a minimal initialization." | |
b849548d | 1169 | :group 'reftex-optimizations-for-large-documents |
396e0b08 KH |
1170 | :type '(choice |
1171 | (const :tag "Read files literally" nil) | |
1172 | (const :tag "Fully initialize buffers" t) | |
1173 | (repeat :tag "Hook functions" :value (nil) | |
1174 | (function-item)))) | |
1175 | ||
b849548d | 1176 | (defcustom reftex-no-include-regexps '("\\.pstex_t\\'") |
2faef409 RS |
1177 | "*List of regular expressions to exclude certain input files from parsing. |
1178 | If the name of a file included via \\include or \\input is matched by any | |
1179 | of the regular expressions in this list, that file is not parsed by RefTeX." | |
1180 | :group 'reftex-optimizations-for-large-documents | |
1181 | :type '(repeat (regexp))) | |
1182 | ||
396e0b08 KH |
1183 | (defcustom reftex-enable-partial-scans nil |
1184 | "*Non-nil means, re-parse only 1 file when asked to re-parse. | |
1185 | Re-parsing is normally requested with a `C-u' prefix to many RefTeX commands, | |
1186 | or with the `r' key in menus. When this option is t in a multifile document, | |
1187 | we will only parse the current buffer, or the file associated with the label | |
1188 | or section heading near point in a menu. Requesting re-parsing of an entire | |
1189 | multifile document then requires a `C-u C-u' prefix or the capital `R' key | |
1190 | in menus." | |
1191 | :group 'reftex-optimizations-for-large-documents | |
1192 | :type 'boolean) | |
1193 | ||
2faef409 RS |
1194 | (defcustom reftex-allow-automatic-rescan t |
1195 | "*Non-nil means, RefTeX may rescan the document when this seems necessary. | |
1196 | Currently this applies only to rescanning after label insertion, when | |
1197 | the new label cannot be inserted correctly into the internal label | |
1198 | list." | |
1199 | :group 'reftex-optimizations-for-large-documents | |
1200 | :type 'boolean) | |
1201 | ||
396e0b08 KH |
1202 | (defcustom reftex-save-parse-info nil |
1203 | "*Non-nil means, save information gathered with parsing in a file. | |
1204 | The file MASTER.rel in the same directory as MASTER.tex is used to save the | |
1205 | information. When this variable is t, | |
1206 | - accessing the parsing information for the first time in an editing session | |
1207 | will read that file (if available) instead of parsing the document. | |
b849548d CD |
1208 | - exiting Emacs or killing a buffer in reftex-mode will cause a new version |
1209 | of the file to be written." | |
396e0b08 KH |
1210 | :group 'reftex-optimizations-for-large-documents |
1211 | :type 'boolean) | |
1212 | ||
2faef409 RS |
1213 | (defcustom reftex-use-multiple-selection-buffers nil |
1214 | "*Non-nil means use a separate selection buffer for each label type. | |
1215 | These buffers are kept from one selection to the next and need not to be | |
1216 | created for each use - so the menu generally comes up faster. The | |
1217 | selection buffers will be erased (and therefore updated) automatically | |
1218 | when new labels in its category are added. See the variable | |
1219 | `reftex-auto-update-selection-buffers'." | |
1220 | :group 'reftex-optimizations-for-large-documents | |
b849548d | 1221 | :group 'reftex-referencing-labels |
2faef409 RS |
1222 | :type 'boolean) |
1223 | ||
1224 | (defcustom reftex-auto-update-selection-buffers t | |
1225 | "*Non-nil means, selection buffers will be updated automatically. | |
1226 | When a new label is defined with `reftex-label', all selection buffers | |
1227 | associated with that label category are emptied, in order to force an | |
1228 | update upon next use. When nil, the buffers are left alone and have to be | |
1229 | updated by hand, with the `g' key from the label selection process. | |
1230 | The value of this variable will only have any effect when | |
1231 | `reftex-use-multiple-selection-buffers' is non-nil." | |
1232 | :group 'reftex-optimizations-for-large-documents | |
b849548d | 1233 | :group 'reftex-referencing-labels |
2faef409 RS |
1234 | :type 'boolean) |
1235 | ||
6b94c6ad CD |
1236 | ;; Fontification and Faces ---------------------------------------------- |
1237 | ||
1238 | (defgroup reftex-fontification-configurations nil | |
1239 | "Options concerning the faces used in RefTeX." | |
1240 | :group 'reftex) | |
1241 | ||
1242 | (defcustom reftex-use-fonts t | |
1243 | "*Non-nil means, use fonts in *toc* and selection buffers. | |
b849548d CD |
1244 | Font-lock must be loaded as well to actually get fontified display. |
1245 | When changing this option, a rescan may be necessary to activate the change." | |
6b94c6ad | 1246 | :group 'reftex-fontification-configurations |
b849548d | 1247 | :type 'boolean) |
6b94c6ad CD |
1248 | |
1249 | (defcustom reftex-refontify-context 1 | |
1250 | "*Non-nil means, re-fontify the context in the label menu with font-lock. | |
1251 | This slightly slows down the creation of the label menu. It is only necessary | |
1252 | when you definitely want the context fontified. | |
1253 | ||
1254 | This option may have 3 different values: | |
1255 | nil Never refontify. | |
1256 | t Always refontify. | |
b849548d | 1257 | 1 Refontify when absolutely necessary, e.g. when old versions of X-Symbol. |
6b94c6ad CD |
1258 | The option is ignored when `reftex-use-fonts' is nil." |
1259 | :group 'reftex-fontification-configurations | |
b849548d | 1260 | :group 'reftex-referencing-labels |
6b94c6ad CD |
1261 | :type '(choice |
1262 | (const :tag "Never" nil) | |
1263 | (const :tag "Always" t) | |
1264 | (const :tag "When necessary" 1))) | |
1265 | ||
1266 | (defcustom reftex-highlight-selection 'cursor | |
1267 | "*Non-nil mean, highlight selected text in selection and *toc* buffers. | |
1268 | Normally, the text near the cursor is the selected text, and it is | |
1269 | highlighted. This is the entry most keys in the selction and *toc* | |
1270 | buffers act on. However, if you mainly use the mouse to select an | |
1271 | item, you may find it nice to have mouse-triggered highlighting | |
1272 | instead or as well. The variable may have one of these values: | |
1273 | ||
1274 | nil No highlighting. | |
1275 | cursor Highlighting is cursor driven. | |
1276 | mouse Highlighting is mouse driven. | |
b849548d CD |
1277 | both Both cursor and mouse trigger highlighting. |
1278 | ||
1279 | Changing this variable requires to rebuild the selection and *toc* buffers | |
1280 | to become effective (keys `g' or `r')." | |
6b94c6ad CD |
1281 | :group 'reftex-fontification-configurations |
1282 | :type '(choice | |
1283 | (const :tag "Never" nil) | |
1284 | (const :tag "Cursor driven" cursor) | |
1285 | (const :tag "Mouse driven" mouse) | |
1286 | (const :tag "Mouse and Cursor driven." both))) | |
1287 | ||
1288 | (defcustom reftex-cursor-selected-face 'highlight | |
1289 | "Face name to highlight cursor selected item in toc and selection buffers. | |
1290 | See also the variable `reftex-highlight-selection'." | |
1291 | :group 'reftex-fontification-configurations | |
1292 | :type 'symbol) | |
1293 | (defcustom reftex-mouse-selected-face 'secondary-selection | |
1294 | "Face name to highlight mouse selected item in toc and selection buffers. | |
1295 | See also the variable `reftex-highlight-selection'." | |
1296 | :group 'reftex-fontification-configurations | |
1297 | :type 'symbol) | |
1298 | (defcustom reftex-file-boundary-face 'font-lock-comment-face | |
1299 | "Face name for file boundaries in selection buffer." | |
1300 | :group 'reftex-fontification-configurations | |
1301 | :type 'symbol) | |
1302 | (defcustom reftex-label-face 'font-lock-constant-face | |
1303 | "Face name for labels in selection buffer." | |
1304 | :group 'reftex-fontification-configurations | |
1305 | :type 'symbol) | |
1306 | (defcustom reftex-section-heading-face 'font-lock-function-name-face | |
1307 | "Face name for section headings in toc and selection buffers." | |
1308 | :group 'reftex-fontification-configurations | |
1309 | :type 'symbol) | |
1310 | (defcustom reftex-toc-header-face 'font-lock-comment-face | |
1311 | "Face name for the header of a toc buffer." | |
1312 | :group 'reftex-fontification-configurations | |
1313 | :type 'symbol) | |
1314 | (defcustom reftex-bib-author-face 'font-lock-keyword-face | |
1315 | "Face name for author names in bib selection buffer." | |
1316 | :group 'reftex-fontification-configurations | |
1317 | :type 'symbol) | |
1318 | (defcustom reftex-bib-year-face 'font-lock-comment-face | |
1319 | "Face name for year in bib selection buffer." | |
1320 | :group 'reftex-fontification-configurations | |
1321 | :type 'symbol) | |
1322 | (defcustom reftex-bib-title-face 'font-lock-function-name-face | |
1323 | "Face name for article title in bib selection buffer." | |
1324 | :group 'reftex-fontification-configurations | |
1325 | :type 'symbol) | |
1326 | (defcustom reftex-bib-extra-face 'font-lock-comment-face | |
1327 | "Face name for bibliographic information in bib selection buffer." | |
1328 | :group 'reftex-fontification-configurations | |
1329 | :type 'symbol) | |
1330 | ||
b849548d CD |
1331 | (defcustom reftex-pre-refontification-functions nil |
1332 | "X-Symbol specific hook. | |
1333 | Functions get two arguments, the buffer from where the command started and a | |
1334 | symbol indicating in what context the hook is called." | |
1335 | :group 'reftex-fontification-configurations | |
1336 | :type 'hook) | |
1337 | ||
a7ec1775 RS |
1338 | ;; Miscellaneous configurations ----------------------------------------- |
1339 | ||
1340 | (defgroup reftex-miscellaneous-configurations nil | |
c52bdfca | 1341 | "Collection of further configurations." |
a7ec1775 RS |
1342 | :group 'reftex) |
1343 | ||
1344 | (defcustom reftex-extra-bindings nil | |
1345 | "Non-nil means, make additional key bindings on startup. | |
c52bdfca | 1346 | These extra bindings are located in the users `C-c letter' map." |
a7ec1775 | 1347 | :group 'reftex-miscellaneous-configurations |
b849548d | 1348 | :type 'boolean) |
a7ec1775 | 1349 | |
c52bdfca | 1350 | (defcustom reftex-plug-into-AUCTeX nil |
396e0b08 | 1351 | "*Plug-in flags for AUCTeX interface. |
b849548d CD |
1352 | This variable is a list of 4 boolean flags. When a flag is non-nil, |
1353 | RefTeX will | |
c52bdfca | 1354 | |
b849548d CD |
1355 | - supply labels in new sections and environments (flag 1) |
1356 | - supply arguments for macros like `\\label'. (flag 2) | |
1357 | - supply arguments for macros like `\\ref'. (flag 3) | |
1358 | - supply arguments for macros like `\\cite'. (flag 4) | |
c52bdfca RS |
1359 | |
1360 | You may also set the variable itself to t or nil in order to turn all | |
1361 | plug-ins on or off, respectively. | |
f9ad2e24 | 1362 | \\<LaTeX-mode-map>Supplying labels in new sections and environments applies when creating |
b849548d CD |
1363 | sections with \\[LaTeX-section] and environments with \\[LaTeX-environment]. |
1364 | Supplying macro arguments applies when you insert such a macro interactively | |
1365 | with \\[TeX-insert-macro]. | |
c52bdfca RS |
1366 | See the AUCTeX documentation for more information. |
1367 | RefTeX uses `fset' to take over the function calls. Changing the variable | |
1368 | may require a restart of Emacs in order to become effective." | |
1369 | :group 'reftex-miscellaneous-configurations | |
b849548d CD |
1370 | :group 'LaTeX |
1371 | :type '(choice | |
1372 | (const :tag "No plug-ins" nil) | |
1373 | (const :tag "All possible plug-ins" t) | |
1374 | (list | |
1375 | :tag "Individual choice" | |
1376 | :value (t t t t) | |
1377 | (boolean :tag "supply label in new sections and environments") | |
1378 | (boolean :tag "supply argument for macros like `\\label' ") | |
1379 | (boolean :tag "supply argument for macros like `\\ref' ") | |
1380 | (boolean :tag "supply argument for macros like `\\cite' ") | |
1381 | ))) | |
1382 | ||
1383 | (defcustom reftex-allow-detached-macro-args nil | |
1384 | "*Non-nil means, allow arguments of macros to be detached by whitespace. | |
1385 | When this is t, `aaa' will be considered as argument of \\bb in the following | |
1386 | construct: \\bbb [xxx] {aaa}." | |
1387 | :group 'texmathp | |
1388 | :type 'boolean) | |
396e0b08 | 1389 | |
2faef409 | 1390 | |
396e0b08 KH |
1391 | (defcustom reftex-load-hook nil |
1392 | "Hook which is being run when loading reftex.el." | |
1393 | :group 'reftex-miscellaneous-configurations | |
1394 | :type 'hook) | |
a7ec1775 | 1395 | |
396e0b08 KH |
1396 | (defcustom reftex-mode-hook nil |
1397 | "Hook which is being run when turning on RefTeX mode." | |
a7ec1775 | 1398 | :group 'reftex-miscellaneous-configurations |
396e0b08 | 1399 | :type 'hook) |
a7ec1775 | 1400 | |
b849548d | 1401 | ;;; ========================================================================= |
a7ec1775 RS |
1402 | ;;; |
1403 | ;;; Define the formal stuff for a minor mode named RefTeX. | |
1404 | ;;; | |
1405 | ||
921759ee | 1406 | (defconst reftex-version "RefTeX version 3.43" |
a6611c0d | 1407 | "Version string for RefTeX.") |
baec1250 | 1408 | |
a7ec1775 | 1409 | (defvar reftex-mode nil |
b849548d | 1410 | "Determines if RefTeX mode is active.") |
a7ec1775 RS |
1411 | (make-variable-buffer-local 'reftex-mode) |
1412 | ||
1413 | (defvar reftex-mode-map (make-sparse-keymap) | |
b849548d | 1414 | "Keymap for RefTeX mode.") |
a7ec1775 RS |
1415 | |
1416 | (defvar reftex-mode-menu nil) | |
1417 | ||
1418 | ;;;###autoload | |
1419 | (defun turn-on-reftex () | |
b849548d | 1420 | "Turn on RefTeX mode." |
a7ec1775 RS |
1421 | (reftex-mode t)) |
1422 | ||
1423 | ;;;###autoload | |
1424 | (defun reftex-mode (&optional arg) | |
fba437e6 | 1425 | "Minor mode with distinct support for \\label, \\ref and \\cite in LaTeX. |
a7ec1775 RS |
1426 | |
1427 | Labels can be created with `\\[reftex-label]' and referenced with `\\[reftex-reference]'. | |
1428 | When referencing, you get a menu with all labels of a given type and | |
c52bdfca | 1429 | context of the label definition. The selected label is inserted as a |
fba437e6 | 1430 | \\ref macro. |
a7ec1775 | 1431 | |
396e0b08 | 1432 | Citations can be made with `\\[reftex-citation]' which will use a regular expression |
a7ec1775 | 1433 | to pull out a *formatted* list of articles from your BibTeX |
c52bdfca | 1434 | database. The selected citation is inserted as a \\cite macro. |
a7ec1775 RS |
1435 | |
1436 | A Table of Contents of the entire (multifile) document with browsing | |
1437 | capabilities is available with `\\[reftex-toc]'. | |
1438 | ||
c52bdfca | 1439 | Most command have help available on the fly. This help is accessed by |
a7ec1775 RS |
1440 | pressing `?' to any prompt mentioning this feature. |
1441 | ||
f9ad2e24 CD |
1442 | Extensive documentation about RefTeX is available in Info format. |
1443 | You can view this information with `\\[reftex-info]'. | |
c52bdfca | 1444 | |
a7ec1775 | 1445 | \\{reftex-mode-map} |
396e0b08 KH |
1446 | Under X, these and other functions will also be available as `Ref' menu |
1447 | on the menu bar. | |
a7ec1775 RS |
1448 | |
1449 | ------------------------------------------------------------------------------" | |
1450 | ||
1451 | (interactive "P") | |
1452 | (setq reftex-mode (not (or (and (null arg) reftex-mode) | |
1453 | (<= (prefix-numeric-value arg) 0)))) | |
1454 | ||
a7ec1775 RS |
1455 | (if reftex-mode |
1456 | (progn | |
f9ad2e24 | 1457 | ;; Mode was turned on |
396e0b08 | 1458 | (easy-menu-add reftex-mode-menu) |
b849548d CD |
1459 | (and reftex-plug-into-AUCTeX |
1460 | (reftex-plug-into-AUCTeX)) | |
f9ad2e24 CD |
1461 | (unless (get 'reftex-auto-view-crossref 'initialized) |
1462 | (and reftex-auto-view-crossref | |
1463 | (reftex-toggle-auto-view-crossref)) | |
1464 | (put 'reftex-auto-view-crossref 'initialized t)) | |
396e0b08 | 1465 | (run-hooks 'reftex-mode-hook)) |
f9ad2e24 | 1466 | ;; Mode was turned off |
a7ec1775 | 1467 | (easy-menu-remove reftex-mode-menu))) |
396e0b08 | 1468 | |
b849548d CD |
1469 | (if (fboundp 'add-minor-mode) |
1470 | ;; Use it so that we get the extras | |
1471 | (progn | |
921759ee CD |
1472 | (put 'reftex-mode :included '(memq major-mode '(latex-mode tex-mode))) |
1473 | (put 'reftex-mode :menu-tag "RefTeX Mode") | |
b849548d CD |
1474 | (add-minor-mode 'reftex-mode " Ref" reftex-mode-map)) |
1475 | ;; The standard way | |
1476 | (unless (assoc 'reftex-mode minor-mode-alist) | |
396e0b08 | 1477 | (push '(reftex-mode " Ref") minor-mode-alist)) |
b849548d CD |
1478 | (unless (assoc 'reftex-mode minor-mode-map-alist) |
1479 | (push (cons 'reftex-mode reftex-mode-map) minor-mode-map-alist))) | |
a7ec1775 | 1480 | |
b849548d | 1481 | ;;; ========================================================================= |
c52bdfca RS |
1482 | ;;; |
1483 | ;;; Silence warnings about variables in other packages. | |
1484 | (defvar TeX-master) | |
b849548d | 1485 | (defvar LaTeX-section-hook) |
c52bdfca RS |
1486 | (defvar LaTeX-label-function) |
1487 | (defvar tex-main-file) | |
1488 | (defvar outline-minor-mode) | |
a6611c0d | 1489 | (defvar font-lock-mode) |
2faef409 RS |
1490 | (defvar font-lock-fontify-region-function) |
1491 | (defvar font-lock-syntactic-keywords) | |
c52bdfca | 1492 | |
b849548d | 1493 | ;;; ========================================================================= |
a7ec1775 | 1494 | ;;; |
b849548d | 1495 | ;;; Multibuffer Variables |
a7ec1775 | 1496 | ;;; |
b849548d | 1497 | ;;; Technical notes: These work as follows: We keep just one list |
a7ec1775 | 1498 | ;;; of labels for each master file - this can save a lot of memory. |
c52bdfca | 1499 | ;;; `reftex-master-index-list' is an alist which connects the true file name |
a7ec1775 | 1500 | ;;; of each master file with the symbols holding the information on that |
c52bdfca | 1501 | ;;; document. Each buffer has local variables which point to these symbols. |
a7ec1775 | 1502 | |
a7ec1775 RS |
1503 | ;; List of variables which handle the multifile stuff. |
1504 | ;; This list is used to tie, untie, and reset these symbols. | |
1505 | (defconst reftex-multifile-symbols | |
396e0b08 | 1506 | '(reftex-docstruct-symbol)) |
a7ec1775 | 1507 | |
c52bdfca | 1508 | ;; Alist connecting master file names with the corresponding lisp symbols. |
a7ec1775 RS |
1509 | (defvar reftex-master-index-list nil) |
1510 | ||
c52bdfca | 1511 | ;; Last index used for a master file. |
a7ec1775 RS |
1512 | (defvar reftex-multifile-index 0) |
1513 | ||
a7ec1775 | 1514 | ;; Variable holding the symbol with the label list of the document. |
396e0b08 KH |
1515 | (defvar reftex-docstruct-symbol nil) |
1516 | (make-variable-buffer-local 'reftex-docstruct-symbol) | |
a7ec1775 RS |
1517 | |
1518 | (defun reftex-next-multifile-index () | |
1519 | ;; Return the next free index for multifile symbols. | |
396e0b08 | 1520 | (incf reftex-multifile-index)) |
a7ec1775 RS |
1521 | |
1522 | (defun reftex-tie-multifile-symbols () | |
1523 | ;; Tie the buffer-local symbols to globals connected with the master file. | |
1524 | ;; If the symbols for the current master file do not exist, they are created. | |
1525 | ||
1526 | (let* ((master (file-truename (reftex-TeX-master-file))) | |
1527 | (index (assoc master reftex-master-index-list)) | |
1528 | (symlist reftex-multifile-symbols) | |
b849548d | 1529 | symbol symname newflag) |
c52bdfca | 1530 | ;; Find the correct index. |
a7ec1775 RS |
1531 | (if index |
1532 | ;; symbols do exist | |
1533 | (setq index (cdr index)) | |
c52bdfca | 1534 | ;; Get a new index and add info to the alist. |
a7ec1775 | 1535 | (setq index (reftex-next-multifile-index) |
396e0b08 KH |
1536 | newflag t) |
1537 | (push (cons master index) reftex-master-index-list)) | |
a7ec1775 | 1538 | |
c52bdfca | 1539 | ;; Get/create symbols and tie them. |
a7ec1775 RS |
1540 | (while symlist |
1541 | (setq symbol (car symlist) | |
1542 | symlist (cdr symlist) | |
1543 | symname (symbol-name symbol)) | |
1544 | (set symbol (intern (concat symname "-" (int-to-string index)))) | |
921759ee | 1545 | (put (symbol-value symbol) :master-index index) |
c52bdfca | 1546 | ;; Initialize if new symbols. |
a7ec1775 RS |
1547 | (if newflag (set (symbol-value symbol) nil))) |
1548 | ||
c52bdfca | 1549 | ;; Return t if the symbols did already exist, nil when we've made them. |
a7ec1775 RS |
1550 | (not newflag))) |
1551 | ||
1552 | (defun reftex-untie-multifile-symbols () | |
1553 | ;; Remove ties from multifile symbols, so that next use makes new ones. | |
1554 | (let ((symlist reftex-multifile-symbols) | |
1555 | (symbol nil)) | |
1556 | (while symlist | |
1557 | (setq symbol (car symlist) | |
1558 | symlist (cdr symlist)) | |
1559 | (set symbol nil)))) | |
1560 | ||
1561 | (defun reftex-TeX-master-file () | |
1562 | ;; Return the name of the master file associated with the current buffer. | |
ef79f4a6 | 1563 | ;; When AUCTeX is loaded, we will use its more sophisticated method. |
025bb635 RS |
1564 | ;; We also support the default TeX and LaTeX modes by checking for a |
1565 | ;; variable tex-main-file. | |
a7ec1775 RS |
1566 | (let |
1567 | ((master | |
1568 | (cond | |
c52bdfca | 1569 | ((fboundp 'TeX-master-file) ; AUCTeX is loaded. Use its mechanism. |
f9ad2e24 CD |
1570 | (condition-case nil |
1571 | (TeX-master-file t) | |
1572 | (error (buffer-file-name)))) | |
a7ec1775 RS |
1573 | ((boundp 'TeX-master) ; The variable is defined - lets use it. |
1574 | (cond | |
1575 | ((eq TeX-master t) | |
1576 | (buffer-file-name)) | |
1577 | ((eq TeX-master 'shared) | |
1578 | (setq TeX-master (read-file-name "Master file: " | |
1579 | nil nil t nil))) | |
1580 | (TeX-master) | |
1581 | (t | |
1582 | (setq TeX-master (read-file-name "Master file: " | |
1583 | nil nil t nil))))) | |
1584 | ((boundp 'tex-main-file) | |
c52bdfca | 1585 | ;; This is the variable from the default TeX modes. |
a7ec1775 RS |
1586 | (cond |
1587 | ((stringp tex-main-file) | |
1588 | ;; ok, this must be it | |
1589 | tex-main-file) | |
1590 | (t | |
c52bdfca | 1591 | ;; In this case, the buffer is its own master. |
a7ec1775 RS |
1592 | (buffer-file-name)))) |
1593 | (t | |
c52bdfca | 1594 | ;; Know nothing about master file. Assume this is a master file. |
a7ec1775 RS |
1595 | (buffer-file-name))))) |
1596 | (cond | |
1597 | ((null master) | |
a6611c0d | 1598 | (error "Need a filename for this buffer, please save it first")) |
a7ec1775 RS |
1599 | ((or (file-exists-p (concat master ".tex")) |
1600 | (reftex-get-buffer-visiting (concat master ".tex"))) | |
1601 | ;; Ahh, an extra .tex was missing... | |
1602 | (setq master (concat master ".tex"))) | |
a6611c0d CD |
1603 | ((or (file-exists-p master) |
1604 | (reftex-get-buffer-visiting master)) | |
1605 | ;; We either see the file, or have a buffer on it. OK. | |
1606 | ) | |
a7ec1775 | 1607 | (t |
b849548d | 1608 | ;; Use buffer file name. |
2faef409 | 1609 | (buffer-file-name))) |
a7ec1775 RS |
1610 | (expand-file-name master))) |
1611 | ||
b849548d CD |
1612 | ;;; ========================================================================= |
1613 | ;;; | |
1614 | ;;; Functions to parse the buffer and to create and reference labels. | |
1615 | ||
1616 | ;; The following constants are derived from `reftex-label-alist'. | |
1617 | ||
1618 | ;; Prompt used for label type queries directed to the user. | |
1619 | (defconst reftex-type-query-prompt nil) | |
1620 | ||
1621 | ;; Help string for label type queries. | |
1622 | (defconst reftex-type-query-help nil) | |
1623 | ||
1624 | ;; Alist relating label type to reference format. | |
1625 | (defconst reftex-typekey-to-format-alist nil) | |
1626 | ||
1627 | ;; Alist relating label type to label affix. | |
1628 | (defconst reftex-typekey-to-prefix-alist nil) | |
1629 | ||
1630 | ;; Alist relating environments or macros to label type and context regexp. | |
1631 | (defconst reftex-env-or-mac-alist nil) | |
1632 | ||
1633 | ;; List of macros carrying a label. | |
1634 | (defconst reftex-label-mac-list nil) | |
1635 | ||
1636 | ;; List of environments carrying a label. | |
1637 | (defconst reftex-label-env-list nil) | |
1638 | ||
1639 | ;; List of all typekey letters in use. | |
1640 | (defconst reftex-typekey-list nil) | |
1641 | ||
1642 | ;; Alist relating magic words to a label type. | |
1643 | (defconst reftex-words-to-typekey-alist nil) | |
1644 | ||
1645 | ;; The last list-of-labels entry used in a reference. | |
1646 | (defvar reftex-last-used-reference (list nil nil nil nil)) | |
1647 | ||
1648 | ;; The message when follow-mode is suspended | |
1649 | (defconst reftex-no-follow-message | |
1650 | "No follow-mode into unvisited file. Press SPC to visit it.") | |
1651 | (defconst reftex-no-info-message | |
1652 | "%s: info not available, use `\\[reftex-view-crossref]' to get it.") | |
1653 | ||
b849548d CD |
1654 | ;; Global variables used for communication between functions. |
1655 | (defvar reftex-default-context-position nil) | |
1656 | (defvar reftex-location-start nil) | |
1657 | (defvar reftex-call-back-to-this-buffer nil) | |
1658 | (defvar reftex-select-return-marker (make-marker)) | |
1659 | (defvar reftex-active-toc nil) | |
1660 | (defvar reftex-tex-path nil) | |
1661 | (defvar reftex-bib-path nil) | |
1662 | (defvar reftex-last-follow-point nil) | |
1663 | (defvar reftex-latex-syntax-table nil) | |
1664 | (defvar reftex-prefix nil) | |
1665 | (defvar reftex-section-levels-all nil) | |
1666 | (defvar reftex-buffers-with-changed-invisibility nil) | |
f9ad2e24 | 1667 | (defvar reftex-callback-fwd t) |
b849548d CD |
1668 | |
1669 | ;; List of buffers created temporarily for lookup, which should be killed. | |
1670 | (defvar reftex-buffers-to-kill nil) | |
1671 | ||
1672 | ;; Regexp to find anything. | |
1673 | (defvar reftex-section-regexp nil) | |
1674 | (defvar reftex-section-or-include-regexp nil) | |
1675 | (defvar reftex-everything-regexp nil) | |
921759ee CD |
1676 | (defvar reftex-find-citation-regexp-format |
1677 | "\\\\[a-zA-Z]*cite[*a-zA-Z]*\\*?\\(\\[[^]]*\\]\\|{[^}]*}\\)*{\\([^}]*,\\)?\\(%s\\)[},]") | |
1678 | (defvar reftex-find-reference-format | |
1679 | "\\\\\\(ref[a-zA-Z]*\\|[a-zA-Z]*ref\\)\\*?\\(\\[[^]]*\\]\\|{[^}]*}\\)*{\\(%s\\)}") | |
1680 | (defvar reftex-macros-with-labels nil) | |
b849548d CD |
1681 | (defvar reftex-find-label-regexp-format nil) |
1682 | (defvar reftex-find-label-regexp-format2 nil) | |
1683 | ||
1684 | ;;; The parser functions ----------------------------------------------------- | |
1685 | ||
1686 | (defvar reftex-memory nil | |
1687 | "Memorizes old variable values to indicate changes in these variables.") | |
1688 | ||
1689 | (defun reftex-access-scan-info (&optional rescan file) | |
1690 | "Ensure access to the scanning info for the current file." | |
1691 | ;; When the multifile symbols are not yet tied, | |
1692 | ;; tie them. When they are empty or RESCAN is non-nil, scan the document. | |
1693 | ;; But, when RESCAN is -1, don't rescan even if docstruct is empty. | |
1694 | ;; When FILE is non-nil, parse only from that file. | |
1695 | ||
1696 | ;; Make sure we have the symbols tied | |
1697 | (if (eq reftex-docstruct-symbol nil) | |
1698 | ;; Symbols are not yet tied: Tie them. | |
1699 | (reftex-tie-multifile-symbols)) | |
1700 | ||
1701 | (reftex-ensure-compiled-variables) | |
1702 | ||
1703 | (when (or (null (symbol-value reftex-docstruct-symbol)) | |
1704 | (member rescan '(t 1 (4) (16)))) | |
1705 | ;; The docstruct will change: Remove selection buffers. | |
1706 | (save-excursion | |
f9ad2e24 | 1707 | (reftex-erase-buffer "*toc*") |
b849548d CD |
1708 | (reftex-erase-all-selection-buffers))) |
1709 | ||
1710 | (if (and (null (symbol-value reftex-docstruct-symbol)) | |
1711 | (not (member rescan '(t 1 (4) (16)))) | |
1712 | reftex-save-parse-info) | |
1713 | ;; Try to read the stuff from a file | |
1714 | (reftex-access-parse-file 'read)) | |
1715 | ||
1716 | (cond | |
1717 | ((equal rescan -1)) ;; We are not allowed to scan. | |
1718 | ((not (symbol-value reftex-docstruct-symbol)) | |
1719 | ;; Scan the whole document | |
1720 | (reftex-do-parse 1 file)) | |
1721 | ((member rescan '(t 1 (4) (16))) | |
1722 | ;; Scan whatever was required by the caller. | |
1723 | (reftex-do-parse rescan file)))) | |
1724 | ||
396e0b08 KH |
1725 | (defun reftex-parse-one () |
1726 | "Re-parse this file." | |
a7ec1775 | 1727 | (interactive) |
396e0b08 KH |
1728 | (let ((reftex-enable-partial-scans t)) |
1729 | (reftex-access-scan-info '(4)))) | |
a7ec1775 | 1730 | |
396e0b08 KH |
1731 | (defun reftex-parse-all () |
1732 | "Re-parse entire document." | |
1733 | (interactive) | |
1734 | (reftex-access-scan-info '(16))) | |
1735 | ||
396e0b08 | 1736 | (defun reftex-do-parse (rescan &optional file) |
b849548d | 1737 | "Do a document rescan. When allowed, do only a partial scan from FILE." |
396e0b08 KH |
1738 | |
1739 | ;; Normalize the rescan argument | |
1740 | (setq rescan (cond ((eq rescan t) t) | |
1741 | ((eq rescan 1) 1) | |
1742 | ((equal rescan '(4)) t) | |
1743 | ((equal rescan '(16)) 1) | |
1744 | (t 1))) | |
1745 | ||
1746 | ;; Partial scans only when allowed | |
1747 | (unless reftex-enable-partial-scans | |
1748 | (setq rescan 1)) | |
1749 | ||
1750 | ;; Do the scanning. | |
1751 | ||
1752 | (let* ((old-list (symbol-value reftex-docstruct-symbol)) | |
1753 | (master (reftex-TeX-master-file)) | |
b849548d | 1754 | (true-master (file-truename master)) |
396e0b08 KH |
1755 | (master-dir (file-name-as-directory (file-name-directory master))) |
1756 | (file (or file (buffer-file-name))) | |
b849548d CD |
1757 | (true-file (file-truename file)) |
1758 | (bibview-cache (assq 'bibview-cache old-list)) | |
2faef409 | 1759 | from-file appendix docstruct tmp) |
396e0b08 KH |
1760 | |
1761 | ;; Make sure replacement is really an option here | |
1762 | (when (and (eq rescan t) | |
1763 | (not (and (member (list 'bof file) old-list) | |
1764 | (member (list 'eof file) old-list)))) | |
b849548d | 1765 | ;; Scan whole document because no such file section exists |
396e0b08 | 1766 | (setq rescan 1)) |
b849548d CD |
1767 | (when (string= true-file true-master) |
1768 | ;; Scan whole document because this file is the master | |
396e0b08 KH |
1769 | (setq rescan 1)) |
1770 | ||
1771 | ;; From which file do we start? | |
1772 | (setq from-file | |
1773 | (cond ((eq rescan t) (or file master)) | |
1774 | ((eq rescan 1) master) | |
b849548d | 1775 | (t (error "This should not happen (reftex-do-parse)")))) |
396e0b08 KH |
1776 | |
1777 | ;; Find active toc entry and initialize section-numbers | |
2faef409 RS |
1778 | (setq reftex-active-toc (reftex-last-assoc-before-elt |
1779 | 'toc (list 'bof from-file) old-list) | |
1780 | appendix (reftex-last-assoc-before-elt | |
1781 | 'appendix (list 'bof from-file) old-list)) | |
1782 | ||
1783 | (reftex-init-section-numbers reftex-active-toc appendix) | |
396e0b08 KH |
1784 | |
1785 | (if (eq rescan 1) | |
1786 | (message "Scanning entire document...") | |
1787 | (message "Scanning document from %s..." from-file)) | |
1788 | ||
1789 | (save-window-excursion | |
1790 | (save-excursion | |
1791 | (unwind-protect | |
1792 | (setq docstruct | |
1793 | (reftex-parse-from-file | |
1794 | from-file docstruct master-dir)) | |
1795 | (reftex-kill-temporary-buffers)))) | |
1796 | ||
1797 | (message "Scanning document... done") | |
1798 | ||
1799 | ;; Turn the list around. | |
1800 | (setq docstruct (nreverse docstruct)) | |
1801 | ||
1802 | ;; Set or insert | |
1803 | (setq docstruct (reftex-replace-label-list-segment | |
1804 | old-list docstruct (eq rescan 1))) | |
1805 | ||
1806 | ;; Add all missing information | |
1807 | (unless (assq 'label-numbers docstruct) | |
1808 | (push (cons 'label-numbers nil) docstruct)) | |
1809 | (unless (assq 'master-dir docstruct) | |
1810 | (push (cons 'master-dir master-dir) docstruct)) | |
b849548d CD |
1811 | (unless (assq 'bibview-cache docstruct) |
1812 | (push (cons 'bibview-cache (cdr bibview-cache)) docstruct)) | |
396e0b08 KH |
1813 | (let* ((bof1 (memq (assq 'bof docstruct) docstruct)) |
1814 | (bof2 (assq 'bof (cdr bof1))) | |
1815 | (is-multi (not (not (and bof1 bof2)))) | |
1816 | (entry (or (assq 'is-multi docstruct) | |
1817 | (car (push (list 'is-multi is-multi) docstruct))))) | |
1818 | (setcdr entry (cons is-multi nil))) | |
1819 | (unless (assq 'xr docstruct) | |
1820 | (let* ((allxr (reftex-all-assq 'xr-doc docstruct)) | |
2faef409 RS |
1821 | (alist (mapcar |
1822 | (function | |
1823 | (lambda (x) | |
f9ad2e24 CD |
1824 | (if (setq tmp (reftex-locate-file (nth 2 x) "tex" |
1825 | master-dir)) | |
396e0b08 KH |
1826 | (cons (nth 1 x) tmp) |
1827 | (message "Can't find external document %s" | |
2faef409 RS |
1828 | (nth 2 x)) |
1829 | nil))) | |
396e0b08 | 1830 | allxr)) |
b849548d CD |
1831 | (alist (delq nil alist)) |
1832 | (allprefix (delq nil (mapcar 'car alist))) | |
2faef409 RS |
1833 | (regexp (if allprefix |
1834 | (concat "\\`\\(" | |
1835 | (mapconcat 'identity allprefix "\\|") | |
1836 | "\\)") | |
1837 | "\\\\\\\\\\\\"))) ; this will never match | |
396e0b08 KH |
1838 | (push (list 'xr alist regexp) docstruct))) |
1839 | ||
1840 | (set reftex-docstruct-symbol docstruct) | |
b849548d | 1841 | (put reftex-docstruct-symbol 'modified t))) |
396e0b08 KH |
1842 | |
1843 | (defun reftex-parse-from-file (file docstruct master-dir) | |
1844 | ;; Scan the buffer for labels and save them in a list. | |
1845 | (let ((regexp reftex-everything-regexp) | |
1846 | (bound 0) | |
2faef409 | 1847 | file-found tmp include-file |
396e0b08 KH |
1848 | (level 1) |
1849 | (highest-level 100) | |
b849548d | 1850 | toc-entry next-buf buf) |
396e0b08 KH |
1851 | |
1852 | (catch 'exit | |
f9ad2e24 | 1853 | (setq file-found (reftex-locate-file file "tex" master-dir)) |
b849548d CD |
1854 | (if (and (not file-found) |
1855 | (setq buf (reftex-get-buffer-visiting file))) | |
1856 | (setq file-found (buffer-file-name buf))) | |
1857 | ||
396e0b08 KH |
1858 | (unless file-found |
1859 | (push (list 'file-error file) docstruct) | |
1860 | (throw 'exit nil)) | |
1861 | ||
1862 | (save-excursion | |
1863 | ||
1864 | (message "Scanning file %s" file) | |
1865 | (set-buffer | |
1866 | (setq next-buf | |
1867 | (reftex-get-file-buffer-force | |
1868 | file-found | |
1869 | (not (eq t reftex-keep-temporary-buffers))))) | |
1870 | ||
1871 | ;; Begin of file mark | |
1872 | (setq file (buffer-file-name)) | |
1873 | (push (list 'bof file) docstruct) | |
1874 | ||
1875 | (save-excursion | |
1876 | (save-restriction | |
1877 | (widen) | |
1878 | (goto-char 1) | |
1879 | ||
1880 | (while (re-search-forward regexp nil t) | |
1881 | ||
1882 | (cond | |
1883 | ||
1884 | ((match-end 1) | |
1885 | ;; It is a label | |
1886 | (push (reftex-label-info (reftex-match-string 1) file bound) | |
1887 | docstruct)) | |
1888 | ||
1889 | ((match-end 3) | |
1890 | ;; It is a section | |
1891 | (setq bound (point)) | |
1892 | ||
1893 | ;; Insert in List | |
1894 | (setq toc-entry (reftex-section-info file)) | |
1895 | (setq level (nth 5 toc-entry)) | |
1896 | (setq highest-level (min highest-level level)) | |
1897 | (if (= level highest-level) | |
1898 | (message | |
1899 | "Scanning %s %s ..." | |
b849548d | 1900 | (car (rassoc level reftex-section-levels)) |
396e0b08 KH |
1901 | (nth 6 toc-entry))) |
1902 | ||
1903 | (push toc-entry docstruct) | |
1904 | (setq reftex-active-toc toc-entry)) | |
1905 | ||
1906 | ((match-end 7) | |
1907 | ;; It's an include or input | |
2faef409 | 1908 | (setq include-file (reftex-match-string 7)) |
b849548d CD |
1909 | ;; Test if this file should be ignored |
1910 | (unless (delq nil (mapcar | |
1911 | (lambda (x) (string-match x include-file)) | |
1912 | reftex-no-include-regexps)) | |
2faef409 RS |
1913 | ;; Parse it |
1914 | (setq docstruct | |
1915 | (reftex-parse-from-file | |
1916 | include-file | |
1917 | docstruct master-dir)))) | |
1918 | ||
1919 | ((match-end 9) | |
1920 | ;; Appendix starts here | |
1921 | (reftex-init-section-numbers nil t) | |
1922 | (push (cons 'appendix t) docstruct)) | |
1923 | ||
1924 | ((match-end 10) | |
396e0b08 KH |
1925 | ;; A macro with label |
1926 | (save-excursion | |
2faef409 RS |
1927 | (let* ((mac (reftex-match-string 10)) |
1928 | (label (progn (goto-char (match-end 10)) | |
396e0b08 KH |
1929 | (save-match-data |
1930 | (reftex-no-props | |
1931 | (reftex-nth-arg-wrapper | |
1932 | mac))))) | |
b849548d CD |
1933 | (typekey (nth 1 (assoc mac reftex-env-or-mac-alist))) |
1934 | (entry (progn (if typekey | |
1935 | ;; A typing macro | |
1936 | (goto-char (match-end 0)) | |
1937 | ;; A newtral macro | |
1938 | (goto-char (match-end 10)) | |
1939 | (reftex-move-over-touching-args)) | |
1940 | (reftex-label-info | |
1941 | label file bound nil nil)))) | |
396e0b08 KH |
1942 | (push entry docstruct)))) |
1943 | (t (error "This should not happen (reftex-parse-from-file)"))) | |
1944 | ) | |
1945 | ||
396e0b08 KH |
1946 | ;; Find bibliography statement |
1947 | (when (setq tmp (reftex-locate-bibliography-files master-dir)) | |
1948 | (push (cons 'bib tmp) docstruct)) | |
1949 | ||
2faef409 RS |
1950 | (goto-char 1) |
1951 | (when (re-search-forward | |
1952 | "\\(\\`\\|[\n\r]\\)[ \t]*\\\\begin{thebibliography}" nil t) | |
1953 | (push (cons 'thebib file) docstruct)) | |
1954 | ||
396e0b08 KH |
1955 | ;; Find external document specifications |
1956 | (goto-char 1) | |
1957 | (while (re-search-forward "[\n\r][ \t]*\\\\externaldocument\\(\\[\\([^]]*\\)\\]\\)?{\\([^}]+\\)}" nil t) | |
2faef409 | 1958 | (push (list 'xr-doc (reftex-match-string 2) |
396e0b08 KH |
1959 | (reftex-match-string 3)) |
1960 | docstruct)) | |
1961 | ||
1962 | ;; End of file mark | |
1963 | (push (list 'eof file) docstruct)))) | |
1964 | ||
1965 | ;; Kill the scanned buffer | |
1966 | (reftex-kill-temporary-buffers next-buf)) | |
1967 | ||
1968 | ;; Return the list | |
1969 | docstruct)) | |
1970 | ||
921759ee | 1971 | (defun reftex-locate-bibliography-files (master-dir &optional files) |
2faef409 | 1972 | ;; Scan buffer for bibliography macro and return file list. |
921759ee CD |
1973 | |
1974 | (unless files | |
396e0b08 KH |
1975 | (save-excursion |
1976 | (goto-char (point-min)) | |
921759ee CD |
1977 | (if (re-search-forward |
1978 | "\\(\\`\\|[\n\r]\\)[ \t]*\\\\bibliography{[ \t]*\\([^}]+\\)" nil t) | |
1979 | (setq files | |
1980 | (split-string (reftex-match-string 2) | |
1981 | "[ \t\n\r]*,[ \t\n\r]*"))))) | |
1982 | (when files | |
1983 | (setq files | |
1984 | (mapcar | |
1985 | (lambda (x) | |
1986 | (if (or (member x reftex-bibfile-ignore-list) | |
1987 | (delq nil (mapcar (lambda (re) (string-match re x)) | |
1988 | reftex-bibfile-ignore-regexps))) | |
1989 | ;; excluded file | |
1990 | nil | |
1991 | ;; find the file | |
1992 | (reftex-locate-file x "bib" master-dir))) | |
1993 | files)) | |
1994 | (delq nil files))) | |
1995 | ||
1996 | (defun reftex-default-bibliography () | |
1997 | ;; Return the expanded value of `reftex-default-bibliography'. | |
1998 | ;; The expanded value is cached. | |
1999 | (unless (eq (get 'reftex-default-bibliography :reftex-raw) | |
2000 | reftex-default-bibliography) | |
2001 | (put 'reftex-default-bibliography :reftex-expanded | |
2002 | (reftex-locate-bibliography-files | |
2003 | default-directory reftex-default-bibliography)) | |
2004 | (put 'reftex-default-bibliography :reftex-raw | |
2005 | reftex-default-bibliography)) | |
2006 | (get 'reftex-default-bibliography :reftex-expanded)) | |
396e0b08 KH |
2007 | |
2008 | (defun reftex-replace-label-list-segment (old insert &optional entirely) | |
2009 | ;; Replace the segment in OLD which corresponds to INSERT. | |
2010 | ;; Works with side effects, directly changes old. | |
2011 | ;; If entirely is t, just return INSERT. | |
2012 | ;; This function also makes sure the old toc markers do not point anywhere. | |
2013 | ||
2014 | (cond | |
2015 | (entirely | |
2016 | (reftex-silence-toc-markers old (length old)) | |
2017 | insert) | |
2018 | (t (let* ((new old) | |
2019 | (file (nth 1 (car insert))) | |
2020 | (eof-list (member (list 'eof file) old)) | |
2021 | (bof-list (member (list 'bof file) old)) | |
2022 | n) | |
2023 | (if (not (and bof-list eof-list)) | |
2024 | (error "Cannot splice") | |
2025 | ;; Splice | |
2026 | (reftex-silence-toc-markers bof-list (- (length bof-list) | |
2027 | (length eof-list))) | |
2028 | (setq n (- (length old) (length bof-list))) | |
2029 | (setcdr (nthcdr n new) (cdr insert)) | |
2030 | (setcdr (nthcdr (1- (length new)) new) (cdr eof-list))) | |
2031 | new)))) | |
2032 | ||
2033 | (defun reftex-silence-toc-markers (list n) | |
b849548d | 2034 | ;; Set all toc markers in the first N entries in list to nil |
396e0b08 KH |
2035 | (while (and list (> (decf n) -1)) |
2036 | (and (eq (car (car list)) 'toc) | |
2037 | (markerp (nth 4 (car list))) | |
2038 | (set-marker (nth 4 (car list)) nil)) | |
2039 | (pop list))) | |
2040 | ||
2041 | (defun reftex-access-parse-file (action) | |
b849548d CD |
2042 | "Perform ACTION on the parse file (the .rel file). |
2043 | Valid actions are: readable, restore, read, kill, write." | |
396e0b08 | 2044 | (let* ((list (symbol-value reftex-docstruct-symbol)) |
b849548d | 2045 | (docstruct-symbol reftex-docstruct-symbol) |
396e0b08 KH |
2046 | (master (reftex-TeX-master-file)) |
2047 | (enable-local-variables nil) | |
2048 | (file (if (string-match "\\.[a-zA-Z]+\\'" master) | |
2049 | (concat (substring master 0 (match-beginning 0)) ".rel") | |
2050 | (concat master ".rel")))) | |
2051 | (cond | |
2052 | ((eq action 'readable) | |
2053 | (file-readable-p file)) | |
2054 | ((eq action 'restore) | |
b849548d | 2055 | (put reftex-docstruct-symbol 'modified nil) |
396e0b08 KH |
2056 | (if (eq reftex-docstruct-symbol nil) |
2057 | ;; Symbols are not yet tied: Tie them. | |
2058 | (reftex-tie-multifile-symbols)) | |
2059 | (if (file-exists-p file) | |
2060 | ;; load the file and return t for success | |
b849548d CD |
2061 | (condition-case nil |
2062 | (progn (load-file file) t) | |
2063 | (error (set reftex-docstruct-symbol nil) | |
2064 | (error "Error while loading file %s" file))) | |
2065 | ;; Throw an exception if the file does not exist | |
2faef409 | 2066 | (error "No restore file %s" file))) |
396e0b08 | 2067 | ((eq action 'read) |
b849548d | 2068 | (put reftex-docstruct-symbol 'modified nil) |
396e0b08 KH |
2069 | (if (file-exists-p file) |
2070 | ;; load the file and return t for success | |
b849548d | 2071 | (condition-case nil |
921759ee CD |
2072 | (progn |
2073 | (load-file file) | |
2074 | (reftex-check-parse-consistency) | |
2075 | t) | |
2076 | (error (message "Error while restoring file %s" file) | |
b849548d CD |
2077 | (set reftex-docstruct-symbol nil) |
2078 | nil)) | |
2faef409 | 2079 | ;; return nil for failure, but no exception |
396e0b08 | 2080 | nil)) |
b849548d CD |
2081 | ((eq action 'kill) |
2082 | ;; Remove the file | |
2083 | (when (and (file-exists-p file) (file-writable-p file)) | |
2084 | (message "Unlinking file %s" file) | |
2085 | (delete-file file))) | |
396e0b08 | 2086 | (t |
b849548d | 2087 | (put docstruct-symbol 'modified nil) |
396e0b08 KH |
2088 | (save-excursion |
2089 | (if (file-writable-p file) | |
2090 | (progn | |
2091 | (message "Writing parse file %s" (abbreviate-file-name file)) | |
2092 | (find-file file) | |
2093 | (erase-buffer) | |
2094 | (insert (format ";; RefTeX parse info file\n")) | |
2095 | (insert (format ";; File: %s\n" master)) | |
396e0b08 KH |
2096 | (insert (format ";; User: %s (%s)\n\n" |
2097 | (user-login-name) (user-full-name))) | |
2098 | (insert "(set reftex-docstruct-symbol '(\n\n") | |
2099 | (let ((standard-output (current-buffer))) | |
2100 | (mapcar | |
2101 | (function | |
2102 | (lambda (x) | |
2103 | (cond ((eq (car x) 'toc) | |
2104 | ;; A toc entry. Do not save the marker. | |
2105 | ;; Save the markers position at position 8 | |
2106 | (print (list 'toc "toc" (nth 2 x) (nth 3 x) | |
2107 | nil (nth 5 x) (nth 6 x) (nth 7 x) | |
2108 | (or (and (markerp (nth 4 x)) | |
2109 | (marker-position (nth 4 x))) | |
2110 | (nth 8 x))))) | |
2111 | (t (print x))))) | |
2112 | list)) | |
b849548d | 2113 | (insert "))\n\n") |
396e0b08 KH |
2114 | (save-buffer 0) |
2115 | (kill-buffer (current-buffer))) | |
2116 | (error "Cannot write to file %s" file))) | |
2117 | t)))) | |
2118 | ||
921759ee CD |
2119 | (defun reftex-check-parse-consistency () |
2120 | ;; Check if parse file is consistent, throw an error if not. | |
2121 | ||
2122 | ;; Check if the master is the same: when moving a document, this will see it. | |
2123 | (let* ((real-master (reftex-TeX-master-file)) | |
2124 | (parsed-master | |
2125 | (nth 1 (assq 'bof (symbol-value reftex-docstruct-symbol))))) | |
2126 | (unless (string= (file-truename real-master) (file-truename parsed-master)) | |
2127 | (message "Master file name in load file is different: %s versus %s" | |
2128 | parsed-master real-master) | |
2129 | (error "Master file name error"))) | |
2130 | ||
2131 | ;; Check for the existence of all document files | |
2132 | ;;; (let* ((all (symbol-value reftex-docstruct-symbol))) | |
2133 | ;;; (while all | |
2134 | ;;; (when (and (eq (car (car all)) 'bof) | |
2135 | ;;; (not (file-regular-p (nth 1 (car all))))) | |
2136 | ;;; (message "File %s in saved parse info not avalable" (cdr (car all))) | |
2137 | ;;; (error "File not found")) | |
2138 | ;;; (setq all (cdr all)))) | |
2139 | ) | |
2140 | ||
b849548d CD |
2141 | (defun reftex-kill-buffer-hook () |
2142 | "Save RefTeX's parse file for this buffer if the information has changed." | |
2143 | ;; Save the parsing information if it was modified. | |
2144 | ;; This function should be installed in `kill-buffer-hook'. | |
2145 | ;; We are careful to make sure nothing goes wring in this function. | |
2146 | (when (and (boundp 'reftex-mode) reftex-mode | |
2147 | (boundp 'reftex-save-parse-info) reftex-save-parse-info | |
2148 | (boundp 'reftex-docstruct-symbol) reftex-docstruct-symbol | |
2149 | (symbol-value reftex-docstruct-symbol) | |
2150 | (get reftex-docstruct-symbol 'modified)) | |
2151 | ;; Write the file. | |
2152 | (condition-case nil | |
2153 | (reftex-access-parse-file 'write) | |
2154 | (error nil)))) | |
396e0b08 | 2155 | |
b849548d CD |
2156 | (defun reftex-kill-emacs-hook () |
2157 | "Call `reftex-kill-buffer-hook' on all buffers." | |
2158 | ;; This function should be installed in `kill-emacs-hook'. | |
2159 | (save-excursion | |
2160 | (mapcar (lambda (buf) | |
2161 | (set-buffer buf) | |
2162 | (reftex-kill-buffer-hook)) | |
2163 | (buffer-list)))) | |
a7ec1775 | 2164 | |
b849548d CD |
2165 | (defun reftex-section-info (file) |
2166 | ;; Return a section entry for the current match. | |
2167 | ;; Carefull: This function expects the match-data to be still in place! | |
2168 | (let* ((marker (set-marker (make-marker) (1- (match-beginning 3)))) | |
2169 | (macro (reftex-match-string 3)) | |
b849548d | 2170 | (level (cdr (assoc macro reftex-section-levels-all))) |
921759ee CD |
2171 | (star (= ?* (char-after (match-end 3)))) |
2172 | (unnumbered (or star (< level 0))) | |
2173 | (level (abs level)) | |
2174 | (section-number (reftex-section-number level unnumbered)) | |
b849548d CD |
2175 | (text1 (save-match-data (save-excursion (reftex-context-substring)))) |
2176 | (literal (buffer-substring-no-properties | |
2177 | (1- (match-beginning 3)) | |
2178 | (min (point-max) (+ (match-end 0) (length text1) 1)))) | |
2179 | ;; Literal can be too short since text1 too short. No big problem. | |
2180 | (text (reftex-nicify-text text1))) | |
a7ec1775 | 2181 | |
b849548d CD |
2182 | ;; Add section number and indentation |
2183 | (setq text | |
2184 | (concat | |
2185 | (make-string (* reftex-level-indent level) ?\ ) | |
2186 | (if (nth 1 reftex-label-menu-flags) ; section number flag | |
2187 | (concat section-number " ")) | |
2188 | text)) | |
2189 | (list 'toc "toc" text file marker level section-number | |
2190 | literal (marker-position marker)))) | |
2faef409 | 2191 | |
b849548d CD |
2192 | (defun reftex-label-info-update (cell) |
2193 | ;; Update information about just one label in a different file. | |
2194 | ;; CELL contains the old info list | |
2195 | (let* ((label (nth 0 cell)) | |
2196 | (typekey (nth 1 cell)) | |
2197 | ;; (text (nth 2 cell)) | |
2198 | (file (nth 3 cell)) | |
2199 | (comment (nth 4 cell)) | |
2200 | (note (nth 5 cell)) | |
2201 | (buf (reftex-get-file-buffer-force | |
2202 | file (not (eq t reftex-keep-temporary-buffers))))) | |
2203 | (if (not buf) | |
2204 | (list label typekey "" file comment "LOST LABEL. RESCAN TO FIX.") | |
2205 | (save-excursion | |
2206 | (set-buffer buf) | |
2207 | (save-restriction | |
2208 | (widen) | |
2209 | (goto-char 1) | |
2faef409 | 2210 | |
b849548d CD |
2211 | (if (or (re-search-forward |
2212 | (format reftex-find-label-regexp-format | |
2213 | (regexp-quote label)) nil t) | |
2214 | (re-search-forward | |
2215 | (format reftex-find-label-regexp-format2 | |
2216 | (regexp-quote label)) nil t)) | |
2faef409 | 2217 | |
b849548d CD |
2218 | (progn |
2219 | (backward-char 1) | |
2220 | (append (reftex-label-info label file) (list note))) | |
2221 | (list label typekey "" file "LOST LABEL. RESCAN TO FIX."))))))) | |
2faef409 | 2222 | |
b849548d CD |
2223 | (defun reftex-label-info (label &optional file bound derive env-or-mac) |
2224 | ;; Return info list on LABEL at point. | |
2225 | (let* ((env-or-mac (or env-or-mac (reftex-label-location bound))) | |
2226 | (typekey (nth 1 (assoc env-or-mac reftex-env-or-mac-alist))) | |
2227 | (file (or file (buffer-file-name))) | |
f9ad2e24 | 2228 | (parse (nth 2 (assoc env-or-mac reftex-env-or-mac-alist))) |
b849548d CD |
2229 | (text (reftex-short-context env-or-mac parse reftex-location-start |
2230 | derive)) | |
2231 | (in-comment (reftex-in-comment))) | |
2232 | (list label typekey text file in-comment))) | |
2faef409 | 2233 | |
b849548d CD |
2234 | (defun reftex-in-comment () |
2235 | (save-excursion | |
2236 | (skip-chars-backward "^%\n\r") | |
2237 | (eq (preceding-char) ?%))) | |
a7ec1775 | 2238 | |
b849548d CD |
2239 | (defun reftex-short-context (env parse &optional bound derive) |
2240 | ;; Get about one line of useful context for the label definition at point. | |
a7ec1775 | 2241 | |
b849548d CD |
2242 | (if (consp parse) |
2243 | (setq parse (if derive (cdr parse) (car parse)))) | |
a7ec1775 | 2244 | |
b849548d | 2245 | (reftex-nicify-text |
a7ec1775 | 2246 | |
b849548d | 2247 | (cond |
a7ec1775 | 2248 | |
b849548d CD |
2249 | ((null parse) |
2250 | (save-excursion | |
2251 | (reftex-context-substring))) | |
a7ec1775 | 2252 | |
b849548d CD |
2253 | ((eq parse t) |
2254 | (if (string= env "section") | |
2255 | ;; special treatment for section labels | |
2256 | (save-excursion | |
2257 | (if (and (re-search-backward reftex-section-or-include-regexp | |
2258 | (point-min) t) | |
2259 | (match-end 2)) | |
2260 | (progn | |
2261 | (goto-char (match-end 0)) | |
2262 | (reftex-context-substring)) | |
2263 | (if reftex-active-toc | |
2264 | (progn | |
2265 | (string-match "{\\([^}]*\\)" (nth 7 reftex-active-toc)) | |
2266 | (match-string 1 (nth 7 reftex-active-toc))) | |
2267 | "SECTION HEADING NOT FOUND"))) | |
2268 | (save-excursion | |
2269 | (goto-char reftex-default-context-position) | |
2270 | (unless (eq (string-to-char env) ?\\) | |
2271 | (reftex-move-over-touching-args)) | |
2272 | (reftex-context-substring)))) | |
a7ec1775 | 2273 | |
b849548d CD |
2274 | ((stringp parse) |
2275 | (save-excursion | |
2276 | (if (re-search-backward parse bound t) | |
2277 | (progn | |
2278 | (goto-char (match-end 0)) | |
2279 | (reftex-context-substring)) | |
2280 | "NO MATCH FOR CONTEXT REGEXP"))) | |
a7ec1775 | 2281 | |
b849548d CD |
2282 | ((integerp parse) |
2283 | (or (save-excursion | |
2284 | (goto-char reftex-default-context-position) | |
2285 | (reftex-nth-arg | |
2286 | parse | |
2287 | (nth 6 (assoc env reftex-env-or-mac-alist)))) | |
2288 | "")) | |
a7ec1775 | 2289 | |
b849548d CD |
2290 | ((fboundp parse) |
2291 | ;; A hook function. Call it. | |
2292 | (save-excursion | |
2293 | (condition-case error-var | |
2294 | (funcall parse env) | |
2295 | (error (format "HOOK ERROR: %s" (cdr error-var)))))) | |
2296 | (t | |
2297 | "ILLEGAL VALUE OF PARSE")))) | |
a7ec1775 | 2298 | |
b849548d | 2299 | (defun reftex-nicify-text (text) |
f9ad2e24 CD |
2300 | ;; Make TEXT nice for inclusion as context into label menu. |
2301 | ;; 1. remove line breaks and extra white space | |
b849548d CD |
2302 | (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text) |
2303 | (setq text (replace-match " " nil t text))) | |
f9ad2e24 | 2304 | ;; 2. cut before the next `\end{' or `\item' or `\\' |
b849548d CD |
2305 | (if (string-match "\\(\\\\end{\\|\\\\item\\|\\\\\\\\\\).*" text) |
2306 | (setq text (replace-match "" nil t text))) | |
f9ad2e24 | 2307 | ;; 3. kill the embedded label |
b849548d CD |
2308 | (if (string-match "\\\\label{[^}]*}" text) |
2309 | (setq text (replace-match "" nil t text))) | |
f9ad2e24 | 2310 | ;; 4. remove leading garbage |
b849548d CD |
2311 | (if (string-match "\\`[ }]+" text) |
2312 | (setq text (replace-match "" nil t text))) | |
f9ad2e24 | 2313 | ;; 5. limit length |
b849548d CD |
2314 | (cond |
2315 | ((> (length text) 100) (substring text 0 100)) | |
2316 | ((= (length text) 0) (make-string 1 ?\ )) | |
2317 | (t text))) | |
a7ec1775 | 2318 | |
b849548d CD |
2319 | (defun reftex-where-am-I () |
2320 | ;; Return the docstruct entry above point. Actually returns a cons | |
2321 | ;; cell in which the cdr is a flag indicating if the information is | |
2322 | ;; exact (t) or approximate (nil). | |
a7ec1775 | 2323 | |
b849548d CD |
2324 | (let ((docstruct (symbol-value reftex-docstruct-symbol)) |
2325 | (cnt 0) rtn | |
2326 | found) | |
2327 | (save-excursion | |
2328 | (while (not rtn) | |
2329 | (incf cnt) | |
2330 | (setq found (re-search-backward reftex-everything-regexp nil t)) | |
2331 | (setq rtn | |
2332 | (cond | |
2333 | ((not found) | |
2334 | ;; no match | |
2335 | (or | |
2336 | (car (member (list 'bof (buffer-file-name)) docstruct)) | |
2337 | (not (setq cnt 2)) | |
2338 | (assq 'bof docstruct) ;; for safety reasons | |
2339 | 'corrupted)) | |
2340 | ((match-end 1) | |
2341 | ;; Label | |
2342 | (assoc (reftex-match-string 1) | |
2343 | (symbol-value reftex-docstruct-symbol))) | |
2344 | ((match-end 3) | |
2345 | ;; Section | |
2346 | (goto-char (1- (match-beginning 3))) | |
2347 | (let* ((list (member (list 'bof (buffer-file-name)) | |
2348 | docstruct)) | |
2349 | (endelt (car (member (list 'eof (buffer-file-name)) | |
2350 | list))) | |
2351 | rtn1) | |
2352 | (while (and list (not (eq endelt (car list)))) | |
2353 | (if (and (eq (car (car list)) 'toc) | |
2354 | (string= (buffer-file-name) | |
2355 | (nth 3 (car list)))) | |
2356 | (cond | |
2357 | ((equal (point) | |
2358 | (or (and (markerp (nth 4 (car list))) | |
2359 | (marker-position (nth 4 (car list)))) | |
2360 | (nth 8 (car list)))) | |
2361 | ;; Fits with marker position or recorded position | |
2362 | (setq rtn1 (car list) list nil)) | |
2363 | ((looking-at (reftex-make-regexp-allow-for-ctrl-m | |
2364 | (nth 7 (car list)))) | |
2365 | ;; Same title | |
2366 | (setq rtn1 (car list) list nil cnt 2)))) | |
2367 | (pop list)) | |
2368 | rtn1)) | |
2369 | ((match-end 7) | |
2370 | ;; Input or include... | |
2371 | (car | |
f9ad2e24 CD |
2372 | (member (list 'eof (reftex-locate-file |
2373 | (reftex-match-string 7) "tex" | |
2374 | (cdr (assq 'master-dir docstruct)))) | |
b849548d CD |
2375 | docstruct))) |
2376 | ((match-end 9) | |
2377 | (assq 'appendix (symbol-value reftex-docstruct-symbol))) | |
2378 | ((match-end 10) | |
2379 | (save-excursion | |
2380 | (goto-char (match-end 10)) | |
2381 | (assoc (reftex-no-props | |
2382 | (reftex-nth-arg-wrapper | |
2383 | (reftex-match-string 10))) | |
2384 | (symbol-value reftex-docstruct-symbol)))) | |
2385 | (t | |
2386 | (error "This should not happen (reftex-where-am-I)")))))) | |
2387 | (cons rtn (eq cnt 1)))) | |
206c6f82 | 2388 | |
a7ec1775 | 2389 | (defun reftex-label-location (&optional bound) |
b849548d CD |
2390 | "Return the environment or macro which determines the label type at point. |
2391 | If optional BOUND is an integer, limit backward searches to that point." | |
a7ec1775 RS |
2392 | |
2393 | (let* ((loc1 (reftex-what-macro reftex-label-mac-list bound)) | |
2394 | (loc2 (reftex-what-environment reftex-label-env-list bound)) | |
2395 | (p1 (or (cdr loc1) 0)) | |
2396 | (p2 (or (cdr loc2) 0))) | |
2397 | ||
2398 | (setq reftex-location-start (max p1 p2)) | |
396e0b08 | 2399 | (if (>= p1 p2) |
a7ec1775 | 2400 | (progn |
396e0b08 KH |
2401 | (setq reftex-default-context-position (+ p1 (length (car loc1)))) |
2402 | (or (car loc1) "section")) | |
2403 | (setq reftex-default-context-position (+ p2 8 (length (car loc2)))) | |
a7ec1775 RS |
2404 | (or (car loc2) "section")))) |
2405 | ||
b849548d CD |
2406 | (defun reftex-parse-args (macro) |
2407 | ;; Return a list of macro name, nargs, arg-nr which is label and a list of | |
2408 | ;; optional argument indices. | |
2409 | (if (string-match "[[{]\\*?[]}]" macro) | |
2410 | (progn | |
2411 | (let ((must-match (substring macro 0 (match-beginning 0))) | |
2412 | (args (substring macro (match-beginning 0))) | |
2413 | opt-list nlabel (cnt 0)) | |
2414 | (while (string-match "\\`[[{]\\(\\*\\)?[]}]" args) | |
2415 | (incf cnt) | |
2416 | (when (eq ?\[ (string-to-char args)) | |
2417 | (push cnt opt-list)) | |
2418 | (when (and (match-end 1) | |
2419 | (not nlabel)) | |
2420 | (setq nlabel cnt)) | |
2421 | (setq args (substring args (match-end 0)))) | |
2422 | (list must-match cnt nlabel opt-list))) | |
2423 | nil)) | |
396e0b08 | 2424 | |
b849548d CD |
2425 | (defsubst reftex-move-to-next-arg (&optional ignore) |
2426 | ;; Assuming that we are at the end of a macro name or a macro argument, | |
2427 | ;; move forward to the opening parenthesis of the next argument. | |
2428 | ;; This function understands the splitting of macros over several lines | |
2429 | ;; in TeX. | |
206c6f82 | 2430 | (cond |
b849548d CD |
2431 | ;; Just to be quick: |
2432 | ((memq (following-char) '(?\[ ?\{))) | |
2433 | ;; Do a search | |
2434 | ((and reftex-allow-detached-macro-args | |
2435 | (looking-at "[ \t]*[\n\r]?\\([ \t]*%[^\n\r]*[\n\r]\\)*[ \t]*[[{]")) | |
2436 | (goto-char (1- (match-end 0))) | |
2437 | t) | |
2438 | (t nil))) | |
a7ec1775 | 2439 | |
b849548d CD |
2440 | (defsubst reftex-move-to-previous-arg (&optional bound) |
2441 | ;; Assuming that we are in front of a macro argument, | |
2442 | ;; move backward to the closing parenthesis of the previous argument. | |
2443 | ;; This function understands the splitting of macros over several lines | |
2444 | ;; in TeX. | |
2445 | (cond | |
2446 | ;; Just to be quick: | |
2447 | ((memq (preceding-char) '(?\] ?\}))) | |
2448 | ;; Do a search | |
2449 | ((and reftex-allow-detached-macro-args | |
2450 | (re-search-backward | |
2451 | "[]}][ \t]*[\n\r]?\\([ \t]*%[^\n\r]*[\n\r]\\)*[ \t]*\\=" bound t)) | |
2452 | (goto-char (1+ (match-beginning 0))) | |
2453 | t) | |
2454 | (t nil))) | |
206c6f82 | 2455 | |
b849548d CD |
2456 | (defun reftex-nth-arg-wrapper (key) |
2457 | (let ((entry (assoc key reftex-env-or-mac-alist))) | |
2458 | (reftex-nth-arg (nth 5 entry) (nth 6 entry)))) | |
2faef409 | 2459 | |
b849548d CD |
2460 | (defun reftex-nth-arg (n &optional opt-args) |
2461 | ;; Return the nth following {} or [] parentheses content. | |
2462 | ;; OPT-ARGS is a list of argument numbers which are optional. | |
a7ec1775 | 2463 | |
b849548d CD |
2464 | ;; If we are sitting at a macro start, skip to end of macro name. |
2465 | (and (eq (following-char) ?\\) (skip-chars-forward "a-zA-Z*\\\\")) | |
29d593f8 | 2466 | |
b849548d CD |
2467 | (if (= n 1000) |
2468 | ;; Special case: Skip all touching arguments | |
2469 | (progn | |
2470 | (reftex-move-over-touching-args) | |
2471 | (reftex-context-substring)) | |
29d593f8 | 2472 | |
b849548d CD |
2473 | ;; Do the real thing. |
2474 | (let ((cnt 1)) | |
2475 | ||
2476 | (when (reftex-move-to-next-arg) | |
2477 | ||
2478 | (while (< cnt n) | |
2479 | (while (and (member cnt opt-args) | |
2480 | (eq (following-char) ?\{)) | |
2481 | (incf cnt)) | |
2482 | (when (< cnt n) | |
2483 | (unless (and (condition-case nil | |
2484 | (or (forward-list 1) t) | |
2485 | (error nil)) | |
2486 | (reftex-move-to-next-arg) | |
2487 | (incf cnt)) | |
2488 | (setq cnt 1000)))) | |
29d593f8 | 2489 | |
b849548d CD |
2490 | (while (and (memq cnt opt-args) |
2491 | (eq (following-char) ?\{)) | |
2492 | (incf cnt))) | |
2493 | (if (and (= n cnt) | |
2494 | (> (skip-chars-forward "{\\[") 0)) | |
2495 | (reftex-context-substring) | |
2496 | nil)))) | |
29d593f8 | 2497 | |
b849548d CD |
2498 | (defun reftex-move-over-touching-args () |
2499 | (condition-case nil | |
2500 | (while (memq (following-char) '(?\[ ?\{)) | |
2501 | (forward-list 1)) | |
2502 | (error nil))) | |
a7ec1775 | 2503 | |
b849548d | 2504 | (defun reftex-context-substring () |
f9ad2e24 | 2505 | ;; Return up to 150 chars from point |
b849548d CD |
2506 | ;; When point is just after a { or [, limit string to matching parenthesis |
2507 | (cond | |
2508 | ((or (= (preceding-char) ?\{) | |
2509 | (= (preceding-char) ?\[)) | |
2510 | ;; Inside a list - get only the list. | |
2511 | (buffer-substring-no-properties | |
2512 | (point) | |
2513 | (min (+ (point) 150) | |
2514 | (point-max) | |
2515 | (condition-case nil | |
2516 | (progn | |
2517 | (up-list 1) | |
2518 | (1- (point))) | |
2519 | (error (point-max)))))) | |
2520 | (t | |
f9ad2e24 | 2521 | ;; no list - just grab 150 characters |
b849548d CD |
2522 | (buffer-substring-no-properties (point) |
2523 | (min (+ (point) 150) (point-max)))))) | |
a7ec1775 | 2524 | |
b849548d CD |
2525 | ;; Variable holding the vector with section numbers |
2526 | (defvar reftex-section-numbers [0 0 0 0 0 0 0 0]) | |
2527 | ||
2528 | (defun reftex-init-section-numbers (&optional toc-entry appendix) | |
2529 | ;; Initialize the section numbers with zeros or with what is found | |
2530 | ;; in the toc entry. | |
2531 | (let* ((level (or (nth 5 toc-entry) -1)) | |
2532 | (numbers (nreverse (split-string (or (nth 6 toc-entry) "") "\\."))) | |
2533 | (depth (1- (length reftex-section-numbers))) | |
2534 | (i depth) number-string) | |
2535 | (while (>= i 0) | |
2536 | (if (> i level) | |
2537 | (aset reftex-section-numbers i 0) | |
2538 | (setq number-string (or (car numbers) "0")) | |
2539 | (if (string-match "\\`[A-Z]\\'" number-string) | |
2540 | (aset reftex-section-numbers i | |
2541 | (- (string-to-char number-string) ?A -1)) | |
2542 | (aset reftex-section-numbers i (string-to-int number-string))) | |
2543 | (pop numbers)) | |
2544 | (decf i))) | |
2545 | (put 'reftex-section-numbers 'appendix appendix)) | |
2546 | ||
2547 | (defun reftex-section-number (&optional level star) | |
2548 | ;; Return a string with the current section number. | |
2549 | ;; When LEVEL is non-nil, increase section numbers on that level. | |
2550 | (let* ((depth (1- (length reftex-section-numbers))) idx n (string "") | |
2551 | (appendix (get 'reftex-section-numbers 'appendix))) | |
2552 | (when level | |
2553 | (when (and (> level -1) (not star)) | |
2554 | (aset reftex-section-numbers | |
2555 | level (1+ (aref reftex-section-numbers level)))) | |
2556 | (setq idx (1+ level)) | |
2557 | (when (not star) | |
2558 | (while (<= idx depth) | |
2559 | (aset reftex-section-numbers idx 0) | |
2560 | (incf idx)))) | |
2561 | (setq idx 0) | |
2562 | (while (<= idx depth) | |
2563 | (setq n (aref reftex-section-numbers idx)) | |
2564 | (setq string (concat string (if (not (string= string "")) "." "") | |
2565 | (int-to-string n))) | |
2566 | (incf idx)) | |
2567 | (save-match-data | |
2568 | (if (string-match "\\`\\([@0]\\.\\)+" string) | |
2569 | (setq string (replace-match "" nil nil string))) | |
2570 | (if (string-match "\\(\\.0\\)+\\'" string) | |
2571 | (setq string (replace-match "" nil nil string))) | |
2572 | (if (and appendix | |
2573 | (string-match "\\`[0-9]+" string)) | |
2574 | (setq string | |
2575 | (concat | |
2576 | (char-to-string | |
2577 | (1- (+ ?A (string-to-int (match-string 0 string))))) | |
2578 | (substring string (match-end 0)))))) | |
2579 | (if star | |
2580 | (concat (make-string (1- (length string)) ?\ ) "*") | |
2581 | string))) | |
2582 | ||
2583 | (defun reftex-is-multi () | |
2584 | ;; Tell if this is a multifile document. When not sure, say yes. | |
2585 | (let ((entry (assq 'is-multi (symbol-value reftex-docstruct-symbol)))) | |
2586 | (if entry | |
2587 | (nth 1 entry) | |
2588 | t))) | |
2589 | ||
2590 | (defun reftex-typekey-check (typekey conf-variable &optional n) | |
2591 | ;; Check if CONF-VARIABLE is true or contains TYPEKEY | |
2592 | (and n (setq conf-variable (nth n conf-variable))) | |
2593 | (or (eq conf-variable t) | |
2594 | (and (stringp conf-variable) | |
2595 | (string-match (concat "[" conf-variable "]") typekey)))) | |
2596 | ||
2597 | (defun reftex-all-document-files (&optional relative) | |
2598 | "Return a list of all files belonging to the current document. | |
2599 | When RELATIVE is non-nil, give file names relative to directory | |
2600 | of master file." | |
2601 | (let* ((all (symbol-value reftex-docstruct-symbol)) | |
2602 | (master-dir (file-name-directory (reftex-TeX-master-file))) | |
2603 | (re (concat "\\`" (regexp-quote master-dir))) | |
2604 | file-list tmp file) | |
2605 | (while (setq tmp (assoc 'bof all)) | |
2606 | (setq file (nth 1 tmp) | |
2607 | all (cdr (memq tmp all))) | |
2608 | (and relative | |
2609 | (string-match re file) | |
2610 | (setq file (substring file (match-end 0)))) | |
2611 | (push file file-list)) | |
2612 | (nreverse file-list))) | |
2613 | ||
2614 | ;;; Creating labels --------------------------------------------------------- | |
2615 | ||
2616 | (defun reftex-label (&optional environment no-insert) | |
2617 | "Insert a unique label. Return the label. | |
2618 | If ENVIRONMENT is given, don't bother to find out yourself. | |
2619 | If NO-INSERT is non-nil, do not insert label into buffer. | |
2620 | With prefix arg, force to rescan document first. | |
2621 | When you are prompted to enter or confirm a label, and you reply with | |
2622 | just the prefix or an empty string, no label at all will be inserted. | |
2623 | A new label is also recorded into the label list. | |
2624 | This function is controlled by the settings of reftex-insert-label-flags." | |
2625 | ||
2626 | (interactive) | |
2627 | ||
2628 | ;; Ensure access to scanning info and rescan buffer if prefix are is '(4). | |
2629 | (reftex-access-scan-info current-prefix-arg) | |
2630 | ||
2631 | ;; Find out what kind of environment this is and abort if necessary. | |
2632 | (if (or (not environment) | |
2633 | (not (assoc environment reftex-env-or-mac-alist))) | |
2634 | (setq environment (reftex-label-location))) | |
2635 | (unless environment | |
2636 | (error "Can't figure out what kind of label should be inserted")) | |
2637 | ||
2638 | ;; Ok, go ahead. | |
2639 | (catch 'exit | |
2640 | (let* ((entry (assoc environment reftex-env-or-mac-alist)) | |
2641 | (typekey (nth 1 entry)) | |
2642 | (format (nth 3 entry)) | |
2643 | (macro-cell (reftex-what-macro 1)) | |
2644 | (entry1 (assoc (car macro-cell) reftex-env-or-mac-alist)) | |
2645 | label naked prefix valid default force-prompt rescan-is-useful) | |
2646 | (when (and (or (nth 5 entry) (nth 5 entry1)) | |
2647 | (memq (preceding-char) '(?\[ ?\{))) | |
2648 | ;; This is an argument of a label macro. Insert naked label. | |
2649 | (setq naked t format "%s")) | |
2650 | ||
2651 | (setq prefix (or (cdr (assoc typekey reftex-typekey-to-prefix-alist)) | |
2652 | (concat typekey "-"))) | |
2653 | ;; Replace any escapes in the prefix | |
2654 | (setq prefix (reftex-replace-prefix-escapes prefix)) | |
2655 | ||
2656 | ;; Make a default label. | |
2657 | (cond | |
2658 | ||
2659 | ((reftex-typekey-check typekey (nth 0 reftex-insert-label-flags)) | |
2660 | ;; Derive a label from context. | |
2661 | (setq reftex-active-toc (reftex-last-assoc-before-elt | |
2662 | 'toc (car (reftex-where-am-I)) | |
2663 | (symbol-value reftex-docstruct-symbol))) | |
2664 | (setq default (reftex-no-props | |
2665 | (nth 2 (reftex-label-info " " nil nil t)))) | |
2666 | ;; Catch the cases where the is actually no context available. | |
2667 | (if (or (string-match "NO MATCH FOR CONTEXT REGEXP" default) | |
2668 | (string-match "ILLEGAL VALUE OF PARSE" default) | |
2669 | (string-match "SECTION HEADING NOT FOUND" default) | |
2670 | (string-match "HOOK ERROR" default) | |
2671 | (string-match "^[ \t]*$" default)) | |
2672 | (setq default prefix | |
2673 | force-prompt t) ; need to prompt | |
2674 | (setq default | |
2675 | (concat prefix | |
2676 | (funcall reftex-string-to-label-function default))) | |
2677 | ||
2678 | ;; Make it unique. | |
2679 | (setq default (reftex-uniquify-label default nil "-")))) | |
2680 | ||
2681 | ((reftex-typekey-check typekey (nth 1 reftex-insert-label-flags)) | |
2682 | ;; Minimal default: the user will be prompted. | |
2683 | (setq default prefix)) | |
2684 | ||
2685 | (t | |
2686 | ;; Make an automatic label. | |
2687 | (setq default (reftex-uniquify-label prefix t)))) | |
2688 | ||
2689 | ;; Should we ask the user? | |
2690 | (if (or (reftex-typekey-check typekey | |
2691 | (nth 1 reftex-insert-label-flags)) ; prompt | |
2692 | force-prompt) | |
2693 | ||
2694 | (while (not valid) | |
2695 | ;; iterate until we get a legal label | |
2696 | ||
2697 | (setq label (read-string | |
2698 | (if naked "Naked Label: " "Label: ") | |
2699 | default)) | |
2700 | ||
2701 | ;; Lets make sure that this is a legal label | |
2702 | (cond | |
2703 | ||
2704 | ((string-match (concat "\\`\\(" (regexp-quote prefix) | |
2705 | "\\)?[ \t]*\\'") | |
2706 | label) | |
2707 | ;; No label at all, please | |
2708 | (message "No label inserted.") | |
2709 | (throw 'exit nil)) | |
2710 | ||
2711 | ;; Test if label contains strange characters | |
2712 | ((string-match reftex-label-illegal-re label) | |
2713 | (message "Label \"%s\" contains illegal characters" label) | |
2714 | (ding) | |
2715 | (sit-for 2)) | |
2716 | ||
2717 | ;; Look it up in the label list | |
2718 | ((setq entry (assoc label | |
2719 | (symbol-value reftex-docstruct-symbol))) | |
2720 | (ding) | |
2721 | (if (y-or-n-p | |
2722 | (format "Label '%s' exists. Use anyway? " label)) | |
2723 | (setq valid t))) | |
2724 | ||
2725 | ;; Label is ok | |
2726 | (t | |
2727 | (setq valid t)))) | |
2728 | (setq label default)) | |
2729 | ||
2730 | ;; Insert the label into the label list | |
2731 | (let* ((here-I-am-info | |
2732 | (save-excursion | |
2733 | (if (and (or naked no-insert) | |
2734 | (integerp (cdr macro-cell))) | |
2735 | (goto-char (cdr macro-cell))) | |
2736 | (reftex-where-am-I))) | |
2737 | (here-I-am (car here-I-am-info)) | |
2738 | (note (if (cdr here-I-am-info) | |
2739 | "" | |
2740 | "POSITION UNCERTAIN. RESCAN TO FIX.")) | |
2741 | (file (buffer-file-name)) | |
2742 | (text nil) | |
2743 | (tail (memq here-I-am (symbol-value reftex-docstruct-symbol)))) | |
2744 | ||
2745 | (or (cdr here-I-am-info) (setq rescan-is-useful t)) | |
2746 | ||
2747 | (when tail | |
2748 | (push (list label typekey text file nil note) (cdr tail)) | |
2749 | (put reftex-docstruct-symbol 'modified t))) | |
2750 | ||
2751 | ;; Insert the label into the buffer | |
2752 | (unless no-insert | |
2753 | (insert | |
2754 | (if reftex-format-label-function | |
2755 | (funcall reftex-format-label-function label format) | |
2756 | (format format label))) | |
2757 | (if (and reftex-plug-into-AUCTeX | |
2758 | (fboundp 'LaTeX-add-labels)) | |
2759 | ;; Tell AUCTeX about this | |
2760 | (LaTeX-add-labels label))) | |
2761 | ||
2762 | ;; Delete the corresponding selection buffers to force update on next use. | |
2763 | (when reftex-auto-update-selection-buffers | |
2764 | (reftex-erase-buffer (reftex-make-selection-buffer-name typekey)) | |
2765 | (reftex-erase-buffer (reftex-make-selection-buffer-name " "))) | |
2766 | ||
2767 | (when (and rescan-is-useful reftex-allow-automatic-rescan) | |
2768 | (reftex-parse-one)) | |
2769 | ||
2770 | ;; return value of the function is the label | |
2771 | label))) | |
2772 | ||
2773 | (defun reftex-string-to-label (string) | |
2774 | "Convert a string (a sentence) to a label. | |
2775 | Uses `reftex-derive-label-parameters' and `reftex-label-illegal-re'. It | |
2776 | also applies `reftex-translate-to-ascii-function' to the string." | |
2777 | (when (and reftex-translate-to-ascii-function | |
2778 | (fboundp reftex-translate-to-ascii-function)) | |
2779 | (setq string (funcall reftex-translate-to-ascii-function string))) | |
2780 | (apply 'reftex-convert-string string | |
2781 | "[-~ \t\n\r,;]+" reftex-label-illegal-re nil nil | |
2782 | reftex-derive-label-parameters)) | |
2783 | ||
2784 | (defun reftex-abbreviate-title (string) | |
2785 | (reftex-convert-string string "[-~ \t\n\r,;]" nil t t | |
2786 | 5 40 nil 1 " " (nth 5 reftex-derive-label-parameters))) | |
2787 | ||
2788 | (defun reftex-convert-string (string split-re illegal-re dot keep-fp | |
2789 | nwords maxchar illegal abbrev sep | |
2790 | ignore-words &optional downcase) | |
2791 | "Convert a string (a sentence) to something shorter. | |
2792 | SPLIT-RE is the regular expression used to split the string into words. | |
2793 | ILLEGAL-RE matches characters which are illegal in the final string. | |
2794 | DOT t means add dots to abbreviated words. | |
2795 | KEEP-FP t means to keep a final punctuation when applicable. | |
2796 | NWORDS Number of words to use. | |
2797 | MAXCHAR Maximum number of characters in the final string. | |
2798 | ILLEGAL nil: Throw away any words containing stuff matched with ILLEGAL-RE. | |
2799 | t: Throw away only the matched part, not the whole word. | |
2800 | ABBREV nil: Never abbreviate words. | |
2801 | t: Always abbreviate words (see `reftex-abbrev-parameters'). | |
2802 | not t and not nil: Abbreviate words if necessary to shorten | |
2803 | string below MAXCHAR. | |
2804 | SEP String separating different words in the output string. | |
2805 | IGNORE-WORDS List of words which should be removed from the string." | |
2806 | ||
2807 | (let* ((words0 (split-string string (or split-re "[ \t\n\r]"))) | |
a6611c0d | 2808 | (reftex-label-illegal-re (or illegal-re "\000")) |
51d628c8 CD |
2809 | (abbrev-re (concat |
2810 | "\\`\\(" | |
2811 | (make-string (nth 0 reftex-abbrev-parameters) ?.) | |
2812 | "[" (nth 2 reftex-abbrev-parameters) "]*" | |
2813 | "\\)" | |
2814 | "[" (nth 3 reftex-abbrev-parameters) "]" | |
2815 | (make-string (1- (nth 1 reftex-abbrev-parameters)) ?.))) | |
b849548d CD |
2816 | words word) |
2817 | ||
2818 | ;; Remove words from the ignore list or with funny characters | |
2819 | (while (setq word (pop words0)) | |
2820 | (if downcase (setq word (downcase word))) | |
2821 | (cond | |
2822 | ((member (downcase word) ignore-words)) | |
a6611c0d | 2823 | ((string-match reftex-label-illegal-re word) |
b849548d | 2824 | (when illegal |
a6611c0d | 2825 | (while (string-match reftex-label-illegal-re word) |
b849548d CD |
2826 | (setq word (replace-match "" nil nil word))) |
2827 | (push word words))) | |
2828 | (t | |
2829 | (push word words)))) | |
2830 | (setq words (nreverse words)) | |
2831 | ||
2832 | ;; Restrict number of words | |
2833 | (if (> (length words) nwords) | |
2834 | (setcdr (nthcdr (1- nwords) words) nil)) | |
2835 | ||
2836 | ;; First, try to use all words | |
2837 | (setq string (mapconcat 'identity words sep)) | |
2838 | ||
2839 | ;; Abbreviate words if enforced by user settings or string length | |
2840 | (if (or (eq t abbrev) | |
2841 | (and abbrev | |
2842 | (> (length string) maxchar))) | |
2843 | (setq words | |
2844 | (mapcar | |
2845 | (function | |
51d628c8 | 2846 | (lambda (w) (if (string-match abbrev-re w) |
b849548d CD |
2847 | (if dot |
2848 | (concat (match-string 1 w) ".") | |
2849 | (match-string 1 w)) | |
2850 | w))) | |
2851 | words) | |
2852 | string (mapconcat 'identity words sep))) | |
2853 | ||
2854 | ;; Shorten if still to long | |
2855 | (setq string | |
2856 | (if (> (length string) maxchar) | |
2857 | (substring string 0 maxchar) | |
2858 | string)) | |
2859 | ||
2860 | ;; Delete the final punctuation, if any | |
2861 | (if (and (not keep-fp) (string-match "\\s.+\\'" string)) | |
2862 | (setq string (replace-match "" nil nil string))) | |
2863 | string)) | |
2864 | ||
a6611c0d | 2865 | (defun reftex-latin1-to-ascii (string) |
f9ad2e24 CD |
2866 | ;; Translate the upper 128 chars in the Latin-1 charset to ASCII equivalents |
2867 | (let ((tab "@@@@@@@@@@@@@@@@@@'@@@@@@@@@@@@@ icLxY|S\"ca<--R-o|23'uq..1o>423?AAAAAAACEEEEIIIIDNOOOOOXOUUUUYP3aaaaaaaceeeeiiiidnooooo:ouuuuypy") | |
2868 | (emacsp (not (featurep 'xemacs)))) | |
2869 | (mapconcat | |
2870 | (lambda (c) | |
2871 | (cond ((and (> c 127) (< c 256)) ; 8 bit Latin-1 | |
2872 | (char-to-string (aref tab (- c 128)))) | |
2873 | ((and emacsp ; Not for XEmacs | |
2874 | (> c 2175) (< c 2304)) ; Mule Latin-1 | |
2875 | (char-to-string (aref tab (- c 2176)))) | |
2876 | (t (char-to-string c)))) | |
2877 | string ""))) | |
a6611c0d | 2878 | |
b849548d CD |
2879 | (defun reftex-replace-prefix-escapes (prefix) |
2880 | ;; Replace %escapes in a label prefix | |
2881 | (save-match-data | |
2882 | (let (letter (num 0) replace) | |
2883 | (while (string-match "\\%\\([a-zA-Z]\\)" prefix num) | |
2884 | (setq letter (match-string 1 prefix)) | |
2885 | (setq replace | |
2886 | (cond | |
2887 | ((equal letter "f") | |
2888 | (file-name-sans-extension | |
2889 | (file-name-nondirectory (buffer-file-name)))) | |
2890 | ((equal letter "F") | |
2891 | (let ((masterdir (file-name-directory (reftex-TeX-master-file))) | |
2892 | (file (file-name-sans-extension (buffer-file-name)))) | |
2893 | (if (string-match (concat "\\`" (regexp-quote masterdir)) | |
2894 | file) | |
2895 | (substring file (length masterdir)) | |
2896 | file))) | |
2897 | ((equal letter "u") | |
2898 | (or (user-login-name) "")) | |
2899 | (t ""))) | |
2900 | (setq num (1- (+ (match-beginning 1) (length replace))) | |
2901 | prefix (replace-match replace nil nil prefix))) | |
2902 | prefix))) | |
2903 | ||
2904 | (defun reftex-uniquify-label (label &optional force separator) | |
2905 | ;; Make label unique by appending a number. | |
2906 | ;; Optional FORCE means, force appending a number, even if label is unique. | |
2907 | ;; Optional SEPARATOR is a string to stick between label and number. | |
2908 | ||
2909 | ;; Ensure access to scanning info | |
2910 | (reftex-access-scan-info) | |
2911 | ||
2912 | (cond | |
2913 | ((and (not force) | |
2914 | (not (assoc label (symbol-value reftex-docstruct-symbol)))) | |
2915 | label) | |
2916 | (t | |
2917 | (let* ((label-numbers (assq 'label-numbers | |
2918 | (symbol-value reftex-docstruct-symbol))) | |
2919 | (label-numbers-alist (cdr label-numbers)) | |
2920 | (cell (or (assoc label label-numbers-alist) | |
2921 | (car (setcdr label-numbers | |
2922 | (cons (cons label 0) | |
2923 | label-numbers-alist))))) | |
2924 | (num (1+ (cdr cell))) | |
2925 | (sep (or separator ""))) | |
2926 | (while (assoc (concat label sep (int-to-string num)) | |
2927 | (symbol-value reftex-docstruct-symbol)) | |
2928 | (incf num)) | |
2929 | (setcdr cell num) | |
2930 | (concat label sep (int-to-string num)))))) | |
2931 | ||
2932 | ;;; Referencing labels ------------------------------------------------------ | |
2933 | ||
2934 | ;; Help string for the reference label menu | |
2935 | (defconst reftex-select-label-prompt | |
2936 | "Select: [n]ext [p]revious [r]escan [ ]context e[x]tern [q]uit RET [?]HELP+more") | |
2937 | ||
2938 | (defconst reftex-select-label-help | |
2939 | " n / p Go to next/previous label (Cursor motion works as well) | |
2940 | C-c C-n/p Go to next/previous section heading. | |
2941 | b / l Jump back to previous selection / Reuse last referenced label | |
2942 | C-s / C-r Search forward/backward. Use repeated C-s/C-r as in isearch. | |
2943 | g / s Update menu / Switch label type | |
2944 | r / R Reparse document / Reparse entire document | |
2945 | x Switch to label menu of external document (with LaTeX package `xr') | |
2946 | t i c # % Toggle: [i]ncl. file borders, [t]able of contents, [c]ontext | |
2947 | [#] label counters, [%] labels in comments | |
2948 | SPC / f Show full context in other window / Toggle follow mode | |
2949 | v / . Toggle \\ref <-> \\vref / Show insertion point in other window | |
2950 | TAB Enter a label with completion | |
2951 | q / RET Quit without referencing / Accept current label (also on mouse-2)") | |
2952 | ||
2953 | (defvar reftex-select-label-map nil | |
2954 | "Keymap used for *RefTeX Select* buffer, when selecting a label. | |
2955 | This keymap can be used to configure the label selection process which is | |
2956 | started with the command \\[reftex-reference].") | |
2957 | ||
2958 | (defun reftex-select-label-mode () | |
2959 | "Major mode for selecting a label in a LaTeX document. | |
2960 | This buffer was created with RefTeX. | |
2961 | It only has a meaningful keymap when you are in the middle of a | |
2962 | selection process. | |
2963 | To select a label, move the cursor to it and press RET. | |
2964 | Press `?' for a summary of important key bindings. | |
2965 | ||
2966 | During a selection process, these are the local bindings. | |
2967 | ||
2968 | \\{reftex-select-label-map}" | |
2969 | ||
2970 | (interactive) | |
2971 | (kill-all-local-variables) | |
2972 | (make-local-hook 'pre-command-hook) | |
2973 | (make-local-hook 'post-command-hook) | |
2974 | (setq major-mode 'reftex-select-label-mode | |
2975 | mode-name "RefTeX Select Label") | |
2976 | (when (syntax-table-p reftex-latex-syntax-table) | |
2977 | (set-syntax-table reftex-latex-syntax-table)) | |
2978 | ;; We do not set a local map - reftex-select-item does this. | |
2979 | (run-hooks 'reftex-select-label-mode-hook)) | |
2980 | ||
2981 | (defun reftex-reference (&optional type no-insert cut) | |
2982 | "Make a LaTeX reference. Look only for labels of a certain TYPE. | |
2983 | With prefix arg, force to rescan buffer for labels. This should only be | |
2984 | necessary if you have recently entered labels yourself without using | |
2985 | reftex-label. Rescanning of the buffer can also be requested from the | |
2986 | label selection menu. | |
2987 | The function returns the selected label or nil. | |
2988 | If NO-INSERT is non-nil, do not insert \\ref command, just return label. | |
2989 | When called with 2 C-u prefix args, disable magic word recognition." | |
2990 | ||
2991 | (interactive) | |
2992 | ||
2993 | ;; check for active recursive edits | |
2994 | (reftex-check-recursive-edit) | |
a7ec1775 RS |
2995 | |
2996 | ;; Ensure access to scanning info and rescan buffer if prefix are is '(4) | |
2997 | (reftex-access-scan-info current-prefix-arg) | |
2998 | ||
396e0b08 KH |
2999 | (unless type |
3000 | ;; guess type from context | |
3001 | (if (and reftex-guess-label-type | |
2faef409 RS |
3002 | (setq type (reftex-guess-label-type))) |
3003 | (setq cut (cdr type) | |
3004 | type (car type)) | |
396e0b08 | 3005 | (setq type (reftex-query-label-type)))) |
a7ec1775 | 3006 | |
2faef409 RS |
3007 | (let* ((varioref (if (reftex-typekey-check |
3008 | type reftex-vref-is-default) | |
3009 | "\\vref" "\\ref")) | |
3010 | (form "\\ref{%s}") | |
3011 | label pair) | |
a7ec1775 RS |
3012 | |
3013 | ;; Have the user select a label | |
29d593f8 | 3014 | (set-marker reftex-select-return-marker (point)) |
2faef409 RS |
3015 | (setq pair (save-excursion |
3016 | (reftex-offer-label-menu type))) | |
b849548d | 3017 | (reftex-ensure-compiled-variables) |
29d593f8 | 3018 | (set-marker reftex-select-return-marker nil) |
2faef409 RS |
3019 | (setq label (car pair) |
3020 | type (cdr pair) | |
3021 | form (or (cdr (assoc type reftex-typekey-to-format-alist)) | |
3022 | form)) | |
a7ec1775 RS |
3023 | |
3024 | (if (and label | |
3025 | (not no-insert)) | |
3026 | (progn | |
2faef409 RS |
3027 | (if cut (backward-delete-char cut)) |
3028 | ||
3029 | ;; remove ~ if we do already have a space | |
3030 | (when (and (= ?~ (string-to-char form)) | |
a6611c0d | 3031 | (member (preceding-char) '(?\ ?\t ?\n))) |
2faef409 RS |
3032 | (setq form (substring form 1))) |
3033 | ;; do we need to switch from \ref to \vref? | |
3034 | (when (string= varioref "\\vref") | |
3035 | (while (string-match "\\\\ref{" form) | |
3036 | (setq form (replace-match "\\vref{" t t form)))) | |
a7ec1775 | 3037 | ;; ok, insert the reference |
2faef409 RS |
3038 | (insert |
3039 | (if reftex-format-ref-function | |
3040 | (funcall reftex-format-ref-function label form) | |
3041 | (format form label label))) | |
396e0b08 KH |
3042 | (message "")) |
3043 | (message "Quit")) | |
3044 | ;; return the label | |
3045 | label)) | |
a7ec1775 | 3046 | |
2faef409 | 3047 | (defun reftex-guess-label-type () |
b849548d | 3048 | ;; Examine context to guess what a \ref might want to reference. |
2faef409 RS |
3049 | (let ((words reftex-words-to-typekey-alist) |
3050 | (case-fold-search t) | |
3051 | (bound (max (point-min) (- (point) 35))) | |
3052 | matched cell) | |
3053 | (save-excursion | |
3054 | (while (and (setq cell (pop words)) | |
3055 | (not (setq matched | |
3056 | (re-search-backward (car cell) bound t)))))) | |
3057 | (if matched | |
3058 | (cons (cdr cell) (- (match-end 0) (match-end 1))) | |
3059 | nil))) | |
3060 | ||
a7ec1775 | 3061 | (defun reftex-offer-label-menu (typekey) |
2faef409 | 3062 | ;; Offer a menu with the appropriate labels. Return (label . typekey). |
a7ec1775 | 3063 | (let* ((buf (current-buffer)) |
396e0b08 KH |
3064 | (xr-data (assq 'xr (symbol-value reftex-docstruct-symbol))) |
3065 | (xr-alist (cons (cons "" (buffer-file-name)) (nth 1 xr-data))) | |
3066 | (xr-index 0) | |
3067 | (here-I-am (car (reftex-where-am-I))) | |
2faef409 | 3068 | (here-I-am1 here-I-am) |
a7ec1775 | 3069 | (toc (reftex-typekey-check typekey reftex-label-menu-flags 0)) |
396e0b08 | 3070 | (files (reftex-typekey-check typekey reftex-label-menu-flags 7)) |
a7ec1775 RS |
3071 | (context (not (reftex-typekey-check |
3072 | typekey reftex-label-menu-flags 3))) | |
3073 | (counter (reftex-typekey-check | |
3074 | typekey reftex-label-menu-flags 2)) | |
3075 | (follow (reftex-typekey-check | |
3076 | typekey reftex-label-menu-flags 4)) | |
396e0b08 | 3077 | (commented (nth 5 reftex-label-menu-flags)) |
396e0b08 | 3078 | (prefix "") |
2faef409 RS |
3079 | selection-buffers |
3080 | offset rtn key data last-data entry) | |
a7ec1775 | 3081 | |
a7ec1775 RS |
3082 | (setq entry (cons nil nil)) |
3083 | ||
3084 | (unwind-protect | |
3085 | (catch 'exit | |
3086 | (while t | |
3087 | (save-window-excursion | |
2faef409 | 3088 | (delete-other-windows) |
b849548d CD |
3089 | (setq reftex-call-back-to-this-buffer buf |
3090 | reftex-latex-syntax-table (syntax-table)) | |
29d593f8 KH |
3091 | (let ((default-major-mode 'reftex-select-label-mode)) |
3092 | (if reftex-use-multiple-selection-buffers | |
3093 | (switch-to-buffer-other-window | |
3094 | (save-excursion | |
3095 | (set-buffer buf) | |
3096 | (reftex-make-selection-buffer-name typekey))) | |
3097 | (switch-to-buffer-other-window "*RefTeX Select*") | |
3098 | (reftex-erase-buffer))) | |
3099 | (unless (eq major-mode 'reftex-select-label-mode) | |
3100 | (reftex-select-label-mode)) | |
2faef409 | 3101 | (add-to-list 'selection-buffers (current-buffer)) |
a7ec1775 | 3102 | (setq truncate-lines t) |
396e0b08 KH |
3103 | (setq mode-line-format |
3104 | (list "---- " 'mode-line-buffer-identification | |
2faef409 | 3105 | " " 'varioref |
396e0b08 KH |
3106 | " " (abbreviate-file-name |
3107 | (buffer-file-name buf)) | |
3108 | " -%-")) | |
2faef409 RS |
3109 | (cond |
3110 | ((= 0 (buffer-size)) | |
29d593f8 | 3111 | (let ((buffer-read-only nil)) |
f9ad2e24 CD |
3112 | (message "Creating Selection Buffer...") |
3113 | (setq offset (reftex-insert-docstruct | |
3114 | typekey buf toc t files context counter | |
3115 | commented | |
3116 | (or here-I-am offset) prefix nil)))) | |
2faef409 RS |
3117 | (here-I-am |
3118 | (setq offset (reftex-get-offset buf here-I-am typekey))) | |
3119 | (t (setq offset t))) | |
29d593f8 | 3120 | (setq buffer-read-only t) |
2faef409 RS |
3121 | (setq offset (or offset t)) |
3122 | ||
396e0b08 | 3123 | (setq here-I-am nil) ; turn off determination of offset |
a7ec1775 RS |
3124 | (setq rtn |
3125 | (reftex-select-item | |
396e0b08 | 3126 | reftex-select-label-prompt |
206c6f82 | 3127 | reftex-select-label-help |
2faef409 | 3128 | reftex-select-label-map |
a7ec1775 | 3129 | offset |
f9ad2e24 | 3130 | 'reftex-show-label-location follow)) |
2faef409 RS |
3131 | (setq key (car rtn) |
3132 | data (nth 1 rtn) | |
3133 | last-data (nth 2 rtn) | |
3134 | offset t) | |
396e0b08 | 3135 | (unless key (throw 'exit nil)) |
a7ec1775 | 3136 | (cond |
2faef409 RS |
3137 | ((eq key ?g) |
3138 | ;; update buffer | |
29d593f8 | 3139 | (reftex-erase-buffer)) |
206c6f82 | 3140 | ((or (eq key ?r) |
2faef409 | 3141 | (eq key ?R)) |
a7ec1775 | 3142 | ;; rescan buffer |
29d593f8 | 3143 | (reftex-erase-buffer) |
b849548d | 3144 | (reftex-reparse-document buf last-data key)) |
206c6f82 | 3145 | ((eq key ?c) |
a7ec1775 | 3146 | ;; toggle context mode |
29d593f8 | 3147 | (reftex-erase-buffer) |
a7ec1775 | 3148 | (setq context (not context))) |
206c6f82 | 3149 | ((eq key ?s) |
a7ec1775 | 3150 | ;; switch type |
2faef409 | 3151 | (setq here-I-am here-I-am1) |
a7ec1775 | 3152 | (setq typekey (reftex-query-label-type))) |
206c6f82 | 3153 | ((eq key ?t) |
2faef409 | 3154 | ;; toggle table of contents display |
29d593f8 | 3155 | (reftex-erase-buffer) |
a7ec1775 | 3156 | (setq toc (not toc))) |
396e0b08 KH |
3157 | ((eq key ?i) |
3158 | ;; toggle display of included file borders | |
29d593f8 | 3159 | (reftex-erase-buffer) |
396e0b08 | 3160 | (setq files (not files))) |
206c6f82 | 3161 | ((eq key ?#) |
a7ec1775 | 3162 | ;; toggle counter display |
29d593f8 | 3163 | (reftex-erase-buffer) |
a7ec1775 | 3164 | (setq counter (not counter))) |
396e0b08 KH |
3165 | ((eq key ?%) |
3166 | ;; toggle display of commented labels | |
29d593f8 | 3167 | (reftex-erase-buffer) |
396e0b08 | 3168 | (setq commented (not commented))) |
206c6f82 | 3169 | ((eq key ?l) |
a7ec1775 RS |
3170 | ;; reuse the last referenced label again |
3171 | (setq entry reftex-last-used-reference) | |
3172 | (throw 'exit t)) | |
396e0b08 KH |
3173 | ((eq key ?x) |
3174 | ;; select an external document | |
3175 | (setq xr-index (reftex-select-external-document | |
3176 | xr-alist xr-index)) | |
3177 | (setq buf (or (reftex-get-file-buffer-force | |
baec1250 | 3178 | (cdr (nth xr-index xr-alist))) |
396e0b08 | 3179 | (error "Cannot switch document")) |
2faef409 RS |
3180 | prefix (or (car (nth xr-index xr-alist)) "")) |
3181 | (set-buffer buf) | |
3182 | (reftex-access-scan-info)) | |
3183 | ((stringp key) | |
3184 | (setq entry | |
3185 | (or (assoc key (symbol-value reftex-docstruct-symbol)) | |
3186 | (list key typekey))) | |
3187 | (throw 'exit t)) | |
a7ec1775 RS |
3188 | (t |
3189 | (set-buffer buf) | |
2faef409 | 3190 | (if data |
396e0b08 | 3191 | (progn |
2faef409 | 3192 | (setq entry data) |
396e0b08 KH |
3193 | (setq reftex-last-used-reference entry)) |
3194 | (setq entry nil)) | |
a7ec1775 | 3195 | (throw 'exit t)))))) |
b849548d CD |
3196 | (save-excursion |
3197 | (while reftex-buffers-with-changed-invisibility | |
3198 | (set-buffer (car (car reftex-buffers-with-changed-invisibility))) | |
3199 | (setq buffer-invisibility-spec | |
3200 | (cdr (pop reftex-buffers-with-changed-invisibility))))) | |
2faef409 RS |
3201 | (mapcar (function (lambda (buf) |
3202 | (and (buffer-live-p buf) | |
b849548d | 3203 | (bury-buffer buf)))) |
2faef409 | 3204 | selection-buffers) |
a7ec1775 | 3205 | (reftex-kill-temporary-buffers)) |
396e0b08 | 3206 | (cons (if (nth 0 entry) (concat prefix (nth 0 entry)) nil) |
2faef409 | 3207 | (nth 1 entry)))) |
396e0b08 | 3208 | |
b849548d CD |
3209 | (defun reftex-select-external-document (xr-alist xr-index) |
3210 | ;; Return index of an external document. | |
3211 | (let* ((len (length xr-alist)) (highest (1- (+ ?0 len))) | |
3212 | (prompt (format "[%c-%c] Select TAB: Read prefix with completion" | |
3213 | ?0 highest)) | |
3214 | key prefix) | |
3215 | (cond | |
3216 | ((= len 1) | |
3217 | (message "No external documents available") | |
3218 | (ding) (sit-for 1) 0) | |
3219 | ((= len 2) | |
3220 | (- 1 xr-index)) | |
3221 | (t | |
3222 | (save-excursion | |
3223 | (let* ((length (apply 'max (mapcar | |
3224 | (lambda(x) (length (car x))) xr-alist))) | |
3225 | (fmt (format " [%%c] %%-%ds %%s\n" length)) | |
3226 | (n (1- ?0))) | |
3227 | (setq key | |
3228 | (reftex-select-with-char | |
3229 | prompt | |
3230 | (concat | |
3231 | "SELECT EXTERNAL DOCUMENT\n------------------------\n" | |
3232 | (mapconcat | |
3233 | (function | |
3234 | (lambda (x) | |
3235 | (format fmt (incf n) (or (car x) "") | |
3236 | (abbreviate-file-name (cdr x))))) | |
3237 | xr-alist "")) | |
3238 | nil t)) | |
3239 | (cond | |
3240 | ((and (>= key ?0) (<= key highest)) (- key ?0)) | |
3241 | ((= key ?\C-i) | |
3242 | (setq prefix (completing-read "Prefix: " xr-alist nil t)) | |
3243 | (- len (length (memq (assoc prefix xr-alist) xr-alist)))) | |
3244 | (t (error "Illegal document selection [%c]" key))))))))) | |
3245 | ||
3246 | (defun reftex-reparse-document (&optional buffer data key) | |
3247 | ;; Rescan the document. | |
3248 | (save-window-excursion | |
3249 | (save-excursion | |
3250 | (if buffer | |
3251 | (if (not (bufferp buffer)) | |
3252 | (error "No such buffer %s" (buffer-name buffer)) | |
3253 | (set-buffer buffer))) | |
3254 | (let ((arg (if (eq key ?R) '(16) '(4))) | |
3255 | (file (nth 3 data))) | |
3256 | (reftex-access-scan-info arg file))))) | |
a7ec1775 | 3257 | |
b849548d CD |
3258 | (defun reftex-make-selection-buffer-name (type &optional index) |
3259 | ;; Make unique name for a selection buffer. | |
3260 | (format " *RefTeX[%s][%d]*" | |
921759ee | 3261 | type (or index (get reftex-docstruct-symbol :master-index) 0))) |
206c6f82 | 3262 | |
f9ad2e24 CD |
3263 | (defun reftex-get-offset (buf here-am-I &optional typekey toc file) |
3264 | ;; Find the correct offset data, like insert-docstruct would, but faster. | |
3265 | ;; Buffer BUF knows the correct docstruct to use. | |
3266 | ;; Basically this finds the first docstruct entry after HERE-I-AM which | |
3267 | ;; is of allowed type. The optional arguments specify what is allowed. | |
3268 | (catch 'exit | |
3269 | (save-excursion | |
3270 | (set-buffer buf) | |
3271 | (reftex-access-scan-info) | |
3272 | (let* ((rest (memq here-am-I (symbol-value reftex-docstruct-symbol))) | |
3273 | entry) | |
3274 | (while (setq entry (pop rest)) | |
3275 | (if (or (and typekey | |
3276 | (stringp (car entry)) | |
3277 | (or (equal typekey " ") | |
3278 | (equal typekey (nth 1 entry)))) | |
3279 | (and toc (eq (car entry) 'toc)) | |
3280 | (and file | |
3281 | (memq (car entry) '(bof eof file-error)))) | |
3282 | (throw 'exit entry))) | |
3283 | nil)))) | |
3284 | ||
3285 | (defun reftex-insert-docstruct | |
3286 | (typekey0 buf toc labels files context counter show-commented | |
3287 | here-I-am xr-prefix toc-buffer) | |
3288 | ;; Insert an excerpt of the docstruct list. | |
b849548d | 3289 | ;; Return the data property of the entry corresponding to HERE-I-AM. |
f9ad2e24 CD |
3290 | ;; TYPEKEY0 indicated which labels to put into the list. |
3291 | ;; BUF is the buffer which has the correct docstruct-symbol. | |
3292 | ;; LABELS non-nil meand to include labels into the list. | |
3293 | ;; FILES non-nil menas to display file boundaries. | |
3294 | ;; CONTEXT non-nil meand to include label context. | |
3295 | ;; COUNTER means to count the labels. | |
3296 | ;; SHOW-COMMENTED meand to include also labels which are commented out. | |
3297 | ;; HERE-I-AM is a member of the docstruct list. The function will return | |
3298 | ;; a used member near to this one, as a possible starting point. | |
3299 | ;; XR-PREFIX is the prefix to put in front of labels. | |
3300 | ;; TOC-BUFFER means this is to fill the toc buffer. | |
b849548d CD |
3301 | (let* ((font (reftex-use-fonts)) |
3302 | (cnt 0) | |
3303 | (index -1) | |
3304 | (toc-indent " ") | |
3305 | (label-indent | |
3306 | (concat "> " | |
3307 | (if toc (make-string (* 7 reftex-level-indent) ?\ ) ""))) | |
3308 | (context-indent | |
3309 | (concat ". " | |
3310 | (if toc (make-string (* 7 reftex-level-indent) ?\ ) ""))) | |
3311 | (mouse-face | |
3312 | (if (memq reftex-highlight-selection '(mouse both)) | |
3313 | reftex-mouse-selected-face | |
3314 | nil)) | |
3315 | (label-face (reftex-verified-face reftex-label-face | |
3316 | 'font-lock-constant-face | |
3317 | 'font-lock-reference-face)) | |
3318 | all cell text label typekey note comment master-dir-re | |
3319 | offset from to docstruct-symbol) | |
a7ec1775 | 3320 | |
b849548d CD |
3321 | ;; Pop to buffer buf to get the correct buffer-local variables |
3322 | (save-excursion | |
3323 | (set-buffer buf) | |
a7ec1775 | 3324 | |
b849548d CD |
3325 | ;; Ensure access to scanning info |
3326 | (reftex-access-scan-info) | |
206c6f82 | 3327 | |
b849548d CD |
3328 | (setq docstruct-symbol reftex-docstruct-symbol |
3329 | all (symbol-value reftex-docstruct-symbol) | |
3330 | reftex-active-toc nil | |
3331 | master-dir-re | |
3332 | (concat "\\`" (regexp-quote | |
3333 | (file-name-directory (reftex-TeX-master-file)))))) | |
206c6f82 | 3334 | |
b849548d CD |
3335 | (set (make-local-variable 'reftex-docstruct-symbol) docstruct-symbol) |
3336 | (set (make-local-variable 'reftex-prefix) | |
3337 | (cdr (assoc typekey0 reftex-typekey-to-prefix-alist))) | |
3338 | (if (equal reftex-prefix " ") (setq reftex-prefix nil)) | |
a7ec1775 | 3339 | |
b849548d CD |
3340 | ;; Walk the docstruct and insert the appropriate stuff |
3341 | (while (setq cell (pop all)) | |
396e0b08 | 3342 | |
b849548d CD |
3343 | (incf index) |
3344 | (setq from (point)) | |
396e0b08 | 3345 | |
b849548d | 3346 | (if (eq cell here-I-am) (setq offset 'attention)) |
396e0b08 | 3347 | |
b849548d | 3348 | (cond |
396e0b08 | 3349 | |
b849548d CD |
3350 | ((memq (car cell) '(bib thebib label-numbers appendix |
3351 | master-dir bibview-cache is-multi xr xr-doc))) | |
3352 | ;; These are currently ignored | |
396e0b08 | 3353 | |
b849548d CD |
3354 | ((memq (car cell) '(bof eof file-error)) |
3355 | ;; Beginning or end of a file | |
3356 | (when files | |
f9ad2e24 | 3357 | (if (eq offset 'attention) (setq offset cell)) |
b849548d CD |
3358 | (insert |
3359 | " File " (if (string-match master-dir-re (nth 1 cell)) | |
3360 | (substring (nth 1 cell) (match-end 0)) | |
3361 | (nth 1 cell)) | |
3362 | (cond ((eq (car cell) 'bof) " starts here\n") | |
3363 | ((eq (car cell) 'eof) " ends here\n") | |
3364 | ((eq (car cell) 'file-error) " was not found\n"))) | |
f9ad2e24 | 3365 | (setq to (point)) |
b849548d | 3366 | (when font |
f9ad2e24 CD |
3367 | (put-text-property from to |
3368 | 'face reftex-file-boundary-face)) | |
3369 | (when toc-buffer | |
3370 | (if mouse-face | |
3371 | (put-text-property from (1- to) | |
3372 | 'mouse-face mouse-face)) | |
921759ee | 3373 | (put-text-property from to :data cell)))) |
396e0b08 | 3374 | |
b849548d CD |
3375 | ((eq (car cell) 'toc) |
3376 | ;; a table of contents entry | |
3377 | (when toc | |
f9ad2e24 | 3378 | (if (eq offset 'attention) (setq offset cell)) |
b849548d CD |
3379 | (setq reftex-active-toc cell) |
3380 | (insert (concat toc-indent (nth 2 cell) "\n")) | |
3381 | (setq to (point)) | |
3382 | (when font | |
3383 | (put-text-property from to | |
3384 | 'face reftex-section-heading-face)) | |
f9ad2e24 CD |
3385 | (when toc-buffer |
3386 | (if mouse-face | |
3387 | (put-text-property from (1- to) | |
3388 | 'mouse-face mouse-face)) | |
921759ee | 3389 | (put-text-property from to :data cell)) |
b849548d | 3390 | (goto-char to))) |
396e0b08 | 3391 | |
b849548d CD |
3392 | ((stringp (car cell)) |
3393 | ;; a label | |
3394 | (when (null (nth 2 cell)) | |
3395 | ;; No context yet. Quick update. | |
3396 | (setcdr cell (cdr (reftex-label-info-update cell))) | |
3397 | (put docstruct-symbol 'modified t)) | |
396e0b08 | 3398 | |
b849548d CD |
3399 | (setq label (car cell) |
3400 | typekey (nth 1 cell) | |
3401 | text (nth 2 cell) | |
3402 | comment (nth 4 cell) | |
3403 | note (nth 5 cell)) | |
396e0b08 | 3404 | |
f9ad2e24 CD |
3405 | (when (and labels |
3406 | (or (string= typekey typekey0) (string= typekey0 " ")) | |
b849548d | 3407 | (or show-commented (null comment))) |
396e0b08 | 3408 | |
b849548d CD |
3409 | ;; Yes we want this one |
3410 | (incf cnt) | |
3411 | (if (eq offset 'attention) (setq offset cell)) | |
396e0b08 | 3412 | |
b849548d CD |
3413 | (setq label (concat xr-prefix label)) |
3414 | (when comment (setq label (concat "% " label))) | |
3415 | (insert label-indent label) | |
3416 | (when font | |
3417 | (setq to (point)) | |
3418 | (put-text-property | |
3419 | (- (point) (length label)) to | |
3420 | 'face (if comment | |
3421 | 'font-lock-comment-face | |
3422 | label-face)) | |
3423 | (goto-char to)) | |
206c6f82 | 3424 | |
b849548d CD |
3425 | (insert (if counter (format " (%d) " cnt) "") |
3426 | (if comment " LABEL IS COMMENTED OUT " "") | |
3427 | (if (stringp note) (concat " " note) "") | |
3428 | "\n") | |
3429 | (setq to (point)) | |
a7ec1775 | 3430 | |
b849548d CD |
3431 | (when context |
3432 | (insert context-indent text "\n") | |
3433 | (setq to (point))) | |
921759ee | 3434 | (put-text-property from to :data cell) |
b849548d CD |
3435 | (when mouse-face |
3436 | (put-text-property from (1- to) | |
3437 | 'mouse-face mouse-face)) | |
3438 | (goto-char to))))) | |
206c6f82 | 3439 | |
b849548d | 3440 | (when (reftex-refontify) |
f9ad2e24 | 3441 | ;; we need to fontify the buffer |
b849548d CD |
3442 | (reftex-fontify-select-label-buffer buf)) |
3443 | (run-hooks 'reftex-display-copied-context-hook) | |
3444 | offset)) | |
3445 | ||
f9ad2e24 CD |
3446 | (defun reftex-find-start-point (fallback &rest locations) |
3447 | ;; Set point to the first available LOCATION. When a LOCATION is a list, | |
921759ee | 3448 | ;; search for such a :data text property. When it is an integer, |
f9ad2e24 CD |
3449 | ;; use is as line number. FALLBACK is a buffer position used if everything |
3450 | ;; else fails. | |
3451 | (catch 'exit | |
3452 | (goto-char (point-min)) | |
3453 | (let (loc pos) | |
3454 | (while locations | |
3455 | (setq loc (pop locations)) | |
3456 | (cond | |
3457 | ((null loc)) | |
3458 | ((listp loc) | |
921759ee | 3459 | (setq pos (text-property-any (point-min) (point-max) :data loc)) |
f9ad2e24 CD |
3460 | (when pos |
3461 | (goto-char pos) | |
3462 | (throw 'exit t))) | |
3463 | ((integerp loc) | |
3464 | (when (<= loc (count-lines (point-min) (point-max))) | |
3465 | (goto-line loc) | |
3466 | (throw 'exit t))))) | |
3467 | (goto-char fallback)))) | |
3468 | ||
b849548d CD |
3469 | (defun reftex-query-label-type () |
3470 | ;; Ask for label type | |
3471 | (let ((key (reftex-select-with-char | |
3472 | reftex-type-query-prompt reftex-type-query-help 3))) | |
3473 | (unless (member (char-to-string key) reftex-typekey-list) | |
3474 | (error "No such label type: %s" (char-to-string key))) | |
3475 | (char-to-string key))) | |
a7ec1775 | 3476 | |
f9ad2e24 CD |
3477 | (defun reftex-show-label-location (data forward no-revisit |
3478 | &optional stay error) | |
3479 | ;; View the definition site of a label in another window. | |
3480 | ;; DATA is an entry from the docstruct list. | |
3481 | ;; FORWARD indicates if the label is likely forward from current point. | |
3482 | ;; NO-REVISIT means do not load a file to show this label. | |
3483 | ;; STAY means leave the new window selected. | |
3484 | ;; ERROR means throw an error exception when the label cannot be found. | |
3485 | ;; If ERROR is nil, the return value of this function indicates success. | |
a7ec1775 | 3486 | (let* ((this-window (selected-window)) |
f9ad2e24 | 3487 | (errorf (if error 'error 'message)) |
2faef409 | 3488 | label file buffer re found) |
f9ad2e24 | 3489 | |
a7ec1775 | 3490 | (catch 'exit |
2faef409 RS |
3491 | (setq label (nth 0 data) |
3492 | file (nth 3 data)) | |
a7ec1775 | 3493 | |
f9ad2e24 CD |
3494 | (unless file |
3495 | (funcall errorf "Unknown label - reparse might help") | |
3496 | (throw 'exit nil)) | |
3497 | ||
3498 | ;; Goto the file in another window | |
b849548d CD |
3499 | (setq buffer |
3500 | (if no-revisit | |
3501 | (reftex-get-buffer-visiting file) | |
3502 | (reftex-get-file-buffer-force | |
3503 | file (not reftex-keep-temporary-buffers)))) | |
3504 | (if buffer | |
3505 | ;; good - the file is available | |
3506 | (switch-to-buffer-other-window buffer) | |
3507 | ;; we have got a problem here. The file does not exist. | |
3508 | ;; Let' get out of here.. | |
f9ad2e24 CD |
3509 | (funcall errorf "Label %s not found" label) |
3510 | (throw 'exit nil)) | |
396e0b08 | 3511 | |
b849548d CD |
3512 | ;; search for that label |
3513 | (setq re (format reftex-find-label-regexp-format (regexp-quote label))) | |
3514 | (setq found | |
3515 | (if forward | |
3516 | (re-search-forward re nil t) | |
3517 | (re-search-backward re nil t))) | |
3518 | (unless found | |
3519 | (goto-char (point-min)) | |
f9ad2e24 | 3520 | (unless (setq found (re-search-forward re nil t)) |
b849548d | 3521 | ;; Ooops. Must be in a macro with distributed args. |
f9ad2e24 CD |
3522 | (setq found |
3523 | (re-search-forward | |
3524 | (format reftex-find-label-regexp-format2 | |
3525 | (regexp-quote label)) nil t)))) | |
3526 | (if (match-end 3) | |
3527 | (progn | |
3528 | (reftex-highlight 0 (match-beginning 3) (match-end 3)) | |
3529 | (reftex-show-entry (match-beginning 3) (match-end 3)) | |
a6611c0d | 3530 | (recenter '(4)) |
f9ad2e24 CD |
3531 | (unless stay (select-window this-window))) |
3532 | (select-window this-window) | |
3533 | (funcall errorf "Label %s not found" label)) | |
3534 | found))) | |
396e0b08 KH |
3535 | |
3536 | (defun reftex-show-entry (beg-hlt end-hlt) | |
b849548d | 3537 | ;; Show entry if point is hidden |
921759ee | 3538 | (let* ((n (/ (reftex-window-height) 2)) |
396e0b08 KH |
3539 | (beg (save-excursion |
3540 | (re-search-backward "[\n\r]" nil 1 n) (point))) | |
3541 | (end (save-excursion | |
3542 | (re-search-forward "[\n\r]" nil 1 n) (point)))) | |
b849548d CD |
3543 | (cond |
3544 | ((and (boundp 'buffer-invisibility-spec) buffer-invisibility-spec | |
3545 | (get-char-property (1+ beg-hlt) 'invisible)) | |
3546 | ;; Invisible with text properties. That is easy to change. | |
3547 | (push (cons (current-buffer) buffer-invisibility-spec) | |
3548 | reftex-buffers-with-changed-invisibility) | |
3549 | (setq buffer-invisibility-spec nil)) | |
3550 | ((string-match "\r" (buffer-substring beg end)) | |
3551 | ;; Invisible with selective display. We need to copy it. | |
3552 | (let ((string (buffer-substring-no-properties beg end))) | |
3553 | (switch-to-buffer "*RefTeX Context Copy*") | |
3554 | (setq buffer-read-only nil) | |
3555 | (erase-buffer) | |
3556 | (insert string) | |
3557 | (subst-char-in-region (point-min) (point-max) ?\r ?\n t) | |
3558 | (goto-char (- beg-hlt beg)) | |
3559 | (reftex-highlight 0 (1+ (- beg-hlt beg)) (1+ (- end-hlt beg))) | |
3560 | (if (reftex-refontify) | |
3561 | (when (or (not (eq major-mode 'latex-mode)) | |
3562 | (not font-lock-mode)) | |
3563 | (latex-mode) | |
3564 | (run-hook-with-args | |
3565 | 'reftex-pre-refontification-functions | |
3566 | reftex-call-back-to-this-buffer 'reftex-hidden) | |
3567 | (turn-on-font-lock)) | |
3568 | (when (or (not (eq major-mode 'fundamental-mode)) | |
3569 | font-lock-mode) | |
3570 | (fundamental-mode))) | |
3571 | (run-hooks 'reftex-display-copied-context-hook) | |
3572 | (setq buffer-read-only t)))))) | |
3573 | ||
3574 | ;;; ========================================================================= | |
a7ec1775 | 3575 | ;;; |
396e0b08 | 3576 | ;;; Table of contents |
a7ec1775 RS |
3577 | |
3578 | ;; We keep at most one *toc* buffer - it is easy to make them | |
3579 | ||
2faef409 RS |
3580 | (defvar reftex-toc-map (make-sparse-keymap) |
3581 | "Keymap used for *toc* buffer.") | |
3582 | ||
29d593f8 KH |
3583 | (defun reftex-toc-mode () |
3584 | "Major mode for managing Table of Contents for LaTeX files. | |
3585 | This buffer was created with RefTeX. | |
3586 | Press `?' for a summary of important key bindings. | |
3587 | ||
3588 | Here are all local bindings. | |
3589 | ||
3590 | \\{reftex-toc-map}" | |
3591 | (interactive) | |
3592 | (kill-all-local-variables) | |
3593 | (setq major-mode 'reftex-toc-mode | |
3594 | mode-name "RefTeX Table of Contents") | |
3595 | (use-local-map reftex-toc-map) | |
3596 | (set (make-local-variable 'revert-buffer-function) 'reftex-toc-revert) | |
3597 | (setq truncate-lines t) | |
3598 | (make-local-hook 'post-command-hook) | |
3599 | (make-local-hook 'pre-command-hook) | |
3600 | (make-local-variable 'reftex-last-follow-point) | |
3601 | (add-hook 'post-command-hook 'reftex-toc-post-command-hook nil t) | |
3602 | (add-hook 'pre-command-hook 'reftex-toc-pre-command-hook nil t) | |
3603 | (run-hooks 'reftex-toc-mode-hook)) | |
3604 | ||
a7ec1775 RS |
3605 | (defvar reftex-last-toc-master nil |
3606 | "Stores the name of the tex file that `reftex-toc' was last run on.") | |
3607 | ||
3608 | (defvar reftex-last-toc-file nil | |
c52bdfca | 3609 | "Stores the file name from which `reftex-toc' was called. For redo command.") |
a7ec1775 | 3610 | |
206c6f82 RS |
3611 | (defvar reftex-last-window-height nil) |
3612 | ||
a7ec1775 RS |
3613 | (defvar reftex-toc-return-marker (make-marker) |
3614 | "Marker which makes it possible to return from toc to old position.") | |
3615 | ||
206c6f82 RS |
3616 | (defconst reftex-toc-help |
3617 | " AVAILABLE KEYS IN TOC BUFFER | |
3618 | ============================ | |
2faef409 | 3619 | n / p next-line / previous-line |
206c6f82 | 3620 | SPC Show the corresponding section of the LaTeX document. |
f9ad2e24 CD |
3621 | TAB Goto the section and keep the *toc* window. |
3622 | RET Goto the section and hide the *toc* window (also on mouse-2). | |
206c6f82 | 3623 | q / Q Hide/Kill *toc* buffer, return to position of last reftex-toc command. |
f9ad2e24 CD |
3624 | l c i Toggle display of [l]abels, [c]ontext, [i]nclude file borders. |
3625 | f / g Toggle follow mode on and off / Refresh *toc* buffer. | |
3626 | r / R Reparse the LaTeX document / Reparse entire LaTeX document. | |
b849548d | 3627 | . In other window, show position from where `reftex-toc' was called. |
396e0b08 | 3628 | x Switch to TOC of external document (with LaTeX package `xr').") |
206c6f82 | 3629 | |
f9ad2e24 | 3630 | (defun reftex-toc (&optional rebuild) |
a7ec1775 | 3631 | "Show the table of contents for the current document. |
a7ec1775 RS |
3632 | When called with a raw C-u prefix, rescan the document first." |
3633 | ||
3634 | (interactive) | |
3635 | ||
206c6f82 | 3636 | (if (or (not (string= reftex-last-toc-master (reftex-TeX-master-file))) |
396e0b08 | 3637 | current-prefix-arg) |
29d593f8 | 3638 | (reftex-erase-buffer "*toc*")) |
a7ec1775 RS |
3639 | |
3640 | (setq reftex-last-toc-file (buffer-file-name)) | |
3641 | (setq reftex-last-toc-master (reftex-TeX-master-file)) | |
3642 | ||
3643 | (set-marker reftex-toc-return-marker (point)) | |
3644 | ||
206c6f82 | 3645 | ;; If follow mode is active, arrange to delay it one command |
a7ec1775 RS |
3646 | (if reftex-toc-follow-mode |
3647 | (setq reftex-toc-follow-mode 1)) | |
3648 | ||
a7ec1775 RS |
3649 | ;; Ensure access to scanning info and rescan buffer if prefix are is '(4) |
3650 | (reftex-access-scan-info current-prefix-arg) | |
3651 | ||
f9ad2e24 CD |
3652 | (let* ((this-buf (current-buffer)) |
3653 | (xr-data (assq 'xr (symbol-value reftex-docstruct-symbol))) | |
396e0b08 | 3654 | (xr-alist (cons (cons "" (buffer-file-name)) (nth 1 xr-data))) |
f9ad2e24 | 3655 | (here-I-am (if rebuild |
921759ee | 3656 | (get 'reftex-toc :reftex-data) |
f9ad2e24 CD |
3657 | (car (reftex-where-am-I)))) |
3658 | offset) | |
a7ec1775 | 3659 | |
206c6f82 RS |
3660 | (if (get-buffer-window "*toc*") |
3661 | (select-window (get-buffer-window "*toc*")) | |
f9ad2e24 CD |
3662 | (when (or (not reftex-toc-keep-other-windows) |
3663 | (< (window-height) (* 2 window-min-height))) | |
2faef409 | 3664 | (delete-other-windows)) |
206c6f82 | 3665 | (setq reftex-last-window-height (window-height)) ; remember |
2faef409 | 3666 | (split-window) |
29d593f8 KH |
3667 | (let ((default-major-mode 'reftex-toc-mode)) |
3668 | (switch-to-buffer "*toc*"))) | |
3669 | ||
3670 | (or (eq major-mode 'reftex-toc-mode) (reftex-toc-mode)) | |
a7ec1775 RS |
3671 | |
3672 | (cond | |
a7ec1775 | 3673 | ((= (buffer-size) 0) |
f9ad2e24 | 3674 | ;; buffer is empty - fill it with the table of contents |
2faef409 | 3675 | (message "Building *toc* buffer...") |
a7ec1775 | 3676 | |
29d593f8 | 3677 | (setq buffer-read-only nil) |
a7ec1775 RS |
3678 | (insert (format |
3679 | "TABLE-OF-CONTENTS on %s | |
f9ad2e24 CD |
3680 | SPC=view TAB=goto RET=goto+hide [q]uit [r]escan [l]abels [f]ollow [x]r [?]Help |
3681 | ------------------------------------------------------------------------------ | |
a7ec1775 | 3682 | " (abbreviate-file-name reftex-last-toc-master))) |
a7ec1775 RS |
3683 | |
3684 | (if (reftex-use-fonts) | |
6b94c6ad | 3685 | (put-text-property 1 (point) 'face reftex-toc-header-face)) |
a7ec1775 | 3686 | (put-text-property 1 (point) 'intangible t) |
396e0b08 | 3687 | (put-text-property 1 2 'xr-alist xr-alist) |
a7ec1775 | 3688 | |
f9ad2e24 CD |
3689 | (setq offset |
3690 | (reftex-insert-docstruct | |
3691 | " " | |
3692 | this-buf | |
3693 | t ; toc | |
3694 | reftex-toc-include-labels | |
3695 | reftex-toc-include-file-boundaries | |
3696 | reftex-toc-include-context | |
3697 | nil ; counter | |
3698 | nil ; commented | |
3699 | here-I-am "" t)) | |
3700 | ||
b849548d | 3701 | (run-hooks 'reftex-display-copied-context-hook) |
2faef409 | 3702 | (message "Building *toc* buffer...done.") |
a7ec1775 RS |
3703 | (setq buffer-read-only t)) |
3704 | (t | |
f9ad2e24 CD |
3705 | ;; Only compute the offset |
3706 | (setq offset | |
3707 | (or (reftex-get-offset this-buf here-I-am | |
3708 | (if reftex-toc-include-labels " " nil) | |
3709 | t | |
3710 | reftex-toc-include-file-boundaries) | |
3711 | (reftex-last-assoc-before-elt | |
3712 | 'toc here-I-am | |
3713 | (symbol-value reftex-docstruct-symbol)))) | |
921759ee | 3714 | (put 'reftex-toc :reftex-line 3) |
a7ec1775 | 3715 | (goto-line 3) |
f9ad2e24 | 3716 | (beginning-of-line))) |
a7ec1775 | 3717 | |
f9ad2e24 | 3718 | ;; Find the correct starting point |
921759ee | 3719 | (reftex-find-start-point (point) offset (get 'reftex-toc :reftex-line)) |
f9ad2e24 | 3720 | (setq reftex-last-follow-point (point)))) |
a7ec1775 RS |
3721 | |
3722 | (defun reftex-toc-pre-command-hook () | |
3723 | ;; used as pre command hook in *toc* buffer | |
3724 | (reftex-unhighlight 0) | |
3725 | (reftex-unhighlight 1)) | |
3726 | ||
3727 | (defun reftex-toc-post-command-hook () | |
3728 | ;; used in the post-command-hook for the *toc* buffer | |
921759ee CD |
3729 | (when (get-text-property (point) :data) |
3730 | (put 'reftex-toc :reftex-data (get-text-property (point) :data)) | |
f9ad2e24 CD |
3731 | (and (> (point) 1) |
3732 | (not (get-text-property (point) 'intangible)) | |
3733 | (memq reftex-highlight-selection '(cursor both)) | |
3734 | (reftex-highlight 1 | |
921759ee | 3735 | (or (previous-single-property-change (1+ (point)) :data) |
f9ad2e24 | 3736 | (point-min)) |
921759ee | 3737 | (or (next-single-property-change (point) :data) |
f9ad2e24 CD |
3738 | (point-max))))) |
3739 | (if (integerp reftex-toc-follow-mode) | |
3740 | ;; remove delayed action | |
3741 | (setq reftex-toc-follow-mode t) | |
3742 | (and reftex-toc-follow-mode | |
3743 | (not (equal reftex-last-follow-point (point))) | |
3744 | ;; show context in other window | |
3745 | (setq reftex-last-follow-point (point)) | |
3746 | (condition-case nil | |
3747 | (reftex-toc-visit-location nil (not reftex-revisit-to-follow)) | |
3748 | (error t))))) | |
206c6f82 | 3749 | |
206c6f82 | 3750 | (defun reftex-re-enlarge () |
b849548d | 3751 | ;; Enlarge windiw to a remembered size |
396e0b08 KH |
3752 | (enlarge-window |
3753 | (max 0 (- (or reftex-last-window-height (window-height)) | |
f9ad2e24 | 3754 | (window-height))))) |
206c6f82 RS |
3755 | |
3756 | (defun reftex-toc-show-help () | |
b849548d | 3757 | "Show a summary of special key bindings." |
206c6f82 RS |
3758 | (interactive) |
3759 | (with-output-to-temp-buffer "*RefTeX Help*" | |
3760 | (princ reftex-toc-help)) | |
3761 | ;; If follow mode is active, arrange to delay it one command | |
3762 | (if reftex-toc-follow-mode | |
3763 | (setq reftex-toc-follow-mode 1))) | |
a7ec1775 | 3764 | |
f9ad2e24 CD |
3765 | (defun reftex-toc-next (&optional arg) |
3766 | "Move to next selectable item." | |
3767 | (interactive "p") | |
3768 | (setq reftex-callback-fwd t) | |
3769 | (or (eobp) (forward-char 1)) | |
921759ee | 3770 | (goto-char (or (next-single-property-change (point) :data) |
f9ad2e24 CD |
3771 | (point)))) |
3772 | (defun reftex-toc-previous (&optional arg) | |
3773 | "Move to previous selectable item." | |
3774 | (interactive "p") | |
3775 | (setq reftex-callback-fwd nil) | |
921759ee | 3776 | (goto-char (or (previous-single-property-change (point) :data) |
f9ad2e24 | 3777 | (point)))) |
a7ec1775 | 3778 | (defun reftex-toc-toggle-follow () |
f9ad2e24 | 3779 | "Toggle follow (other window follows with context)." |
a7ec1775 | 3780 | (interactive) |
b849548d | 3781 | (setq reftex-last-follow-point -1) |
a7ec1775 | 3782 | (setq reftex-toc-follow-mode (not reftex-toc-follow-mode))) |
f9ad2e24 CD |
3783 | (defun reftex-toc-toggle-file-boundary () |
3784 | "Toggle inclusion of file boundaries in *toc* buffer." | |
3785 | (interactive) | |
3786 | (setq reftex-toc-include-file-boundaries | |
3787 | (not reftex-toc-include-file-boundaries)) | |
3788 | (reftex-toc-revert)) | |
3789 | (defun reftex-toc-toggle-labels () | |
3790 | "Toggle inclusion of labels in *toc* buffer." | |
3791 | (interactive) | |
3792 | (setq reftex-toc-include-labels (not reftex-toc-include-labels)) | |
3793 | (reftex-toc-revert)) | |
3794 | (defun reftex-toc-toggle-context () | |
3795 | "Toggle inclusion of label context in *toc* buffer. | |
3796 | Label context is only displayed when the labels are there as well." | |
3797 | (interactive) | |
3798 | (setq reftex-toc-include-context (not reftex-toc-include-context)) | |
3799 | (reftex-toc-revert)) | |
a7ec1775 RS |
3800 | (defun reftex-toc-view-line () |
3801 | "View document location in other window." | |
3802 | (interactive) | |
f9ad2e24 | 3803 | (reftex-toc-visit-location)) |
29d593f8 KH |
3804 | (defun reftex-toc-mouse-view-line (ev) |
3805 | "View document location in other window." | |
3806 | (interactive "e") | |
3807 | (mouse-set-point ev) | |
f9ad2e24 | 3808 | (reftex-toc-visit-location)) |
a7ec1775 | 3809 | (defun reftex-toc-goto-line-and-hide () |
c52bdfca | 3810 | "Go to document location in other window. Hide the *toc* window." |
a7ec1775 | 3811 | (interactive) |
f9ad2e24 | 3812 | (reftex-toc-visit-location 'hide)) |
206c6f82 | 3813 | (defun reftex-toc-goto-line () |
f9ad2e24 | 3814 | "Go to document location in other window. *toc* window stays." |
206c6f82 | 3815 | (interactive) |
f9ad2e24 | 3816 | (reftex-toc-visit-location t)) |
206c6f82 RS |
3817 | (defun reftex-toc-mouse-goto-line-and-hide (ev) |
3818 | "Go to document location in other window. Hide the *toc* window." | |
3819 | (interactive "e") | |
3820 | (mouse-set-point ev) | |
f9ad2e24 CD |
3821 | (reftex-toc-visit-location 'hide)) |
3822 | (defun reftex-toc-show-calling-point () | |
3823 | "Show point where reftex-toc was called from." | |
b849548d CD |
3824 | (interactive) |
3825 | (let ((this-window (selected-window))) | |
3826 | (unwind-protect | |
3827 | (progn | |
3828 | (switch-to-buffer-other-window | |
3829 | (marker-buffer reftex-toc-return-marker)) | |
3830 | (goto-char (marker-position reftex-toc-return-marker)) | |
a6611c0d | 3831 | (recenter '(4))) |
b849548d | 3832 | (select-window this-window)))) |
a7ec1775 RS |
3833 | (defun reftex-toc-quit () |
3834 | "Hide the *toc* window and do not move point." | |
3835 | (interactive) | |
206c6f82 | 3836 | (or (one-window-p) (delete-window)) |
a7ec1775 | 3837 | (switch-to-buffer (marker-buffer reftex-toc-return-marker)) |
206c6f82 | 3838 | (reftex-re-enlarge) |
396e0b08 | 3839 | (goto-char (or (marker-position reftex-toc-return-marker) (point)))) |
a7ec1775 RS |
3840 | (defun reftex-toc-quit-and-kill () |
3841 | "Kill the *toc* buffer." | |
3842 | (interactive) | |
3843 | (kill-buffer "*toc*") | |
206c6f82 | 3844 | (or (one-window-p) (delete-window)) |
a7ec1775 | 3845 | (switch-to-buffer (marker-buffer reftex-toc-return-marker)) |
206c6f82 | 3846 | (reftex-re-enlarge) |
a7ec1775 | 3847 | (goto-char (marker-position reftex-toc-return-marker))) |
2faef409 RS |
3848 | (defun reftex-toc-rescan (&rest ignore) |
3849 | "Regenerate the *toc* buffer by reparsing file of section at point." | |
396e0b08 KH |
3850 | (interactive) |
3851 | (if reftex-enable-partial-scans | |
921759ee | 3852 | (let* ((data (get-text-property (point) :data)) |
f9ad2e24 CD |
3853 | (what (car data)) |
3854 | (file (cond ((eq what 'toc) (nth 3 data)) | |
3855 | ((memq what '(eof bof file-error)) (nth 1 data)) | |
3856 | ((stringp what) (nth 3 data)))) | |
3857 | (line (+ (count-lines (point-min) (point)) (if (bolp) 1 0)))) | |
396e0b08 | 3858 | (if (not file) |
a6611c0d | 3859 | (error "Don't know which file to rescan. Try `R'") |
921759ee | 3860 | (put 'reftex-toc :reftex-line line) |
396e0b08 KH |
3861 | (switch-to-buffer-other-window |
3862 | (reftex-get-file-buffer-force file)) | |
3863 | (setq current-prefix-arg '(4)) | |
f9ad2e24 | 3864 | (reftex-toc t))) |
2faef409 | 3865 | (reftex-toc-Rescan)) |
396e0b08 | 3866 | (reftex-kill-temporary-buffers)) |
2faef409 | 3867 | (defun reftex-toc-Rescan (&rest ignore) |
396e0b08 | 3868 | "Regenerate the *toc* buffer by reparsing the entire document." |
a7ec1775 | 3869 | (interactive) |
206c6f82 RS |
3870 | (switch-to-buffer-other-window |
3871 | (reftex-get-file-buffer-force reftex-last-toc-file)) | |
396e0b08 | 3872 | (setq current-prefix-arg '(16)) |
f9ad2e24 | 3873 | (reftex-toc t)) |
2faef409 RS |
3874 | (defun reftex-toc-revert (&rest ignore) |
3875 | "Regenerate the *toc* from the internal lists." | |
3876 | (interactive) | |
3877 | (switch-to-buffer-other-window | |
3878 | (reftex-get-file-buffer-force reftex-last-toc-file)) | |
29d593f8 | 3879 | (reftex-erase-buffer "*toc*") |
2faef409 | 3880 | (setq current-prefix-arg nil) |
f9ad2e24 | 3881 | (reftex-toc t)) |
396e0b08 KH |
3882 | (defun reftex-toc-external (&rest ignore) |
3883 | "Switch to table of contents of an external document." | |
3884 | (interactive) | |
2faef409 RS |
3885 | (let* ((old-buf (current-buffer)) |
3886 | (xr-alist (get-text-property 1 'xr-alist)) | |
396e0b08 KH |
3887 | (xr-index (reftex-select-external-document |
3888 | xr-alist 0))) | |
3889 | (switch-to-buffer-other-window (or (reftex-get-file-buffer-force | |
3890 | (cdr (nth xr-index xr-alist))) | |
3891 | (error "Cannot switch document"))) | |
2faef409 RS |
3892 | (reftex-toc) |
3893 | (if (equal old-buf (current-buffer)) | |
3894 | (message "") | |
3895 | (message "Switched document")))) | |
a7ec1775 | 3896 | |
f9ad2e24 | 3897 | (defun reftex-toc-visit-location (&optional final no-revisit) |
a7ec1775 RS |
3898 | ;; Visit the tex file corresponding to the toc entry on the current line. |
3899 | ;; If FINAL is t, stay there | |
3900 | ;; If FINAL is 'hide, hide the *toc* window. | |
396e0b08 | 3901 | ;; Otherwise, move cursor back into *toc* window. |
f9ad2e24 | 3902 | ;; NO-REVISIT means don't visit files, just use live biffers. |
396e0b08 KH |
3903 | ;; This function is pretty clever about finding back a section heading, |
3904 | ;; even if the buffer is not live, or things like outline, x-symbol etc. | |
3905 | ;; have been active. | |
3906 | ||
921759ee | 3907 | (let* ((toc (get-text-property (point) :data)) |
396e0b08 KH |
3908 | (toc-window (selected-window)) |
3909 | show-window show-buffer match) | |
3910 | ||
3911 | (unless toc (error "Don't know which toc line to visit")) | |
f9ad2e24 CD |
3912 | |
3913 | (cond | |
3914 | ||
3915 | ((eq (car toc) 'toc) | |
3916 | ;; a toc entry | |
3917 | (setq match (reftex-toc-find-section toc no-revisit))) | |
3918 | ||
3919 | ((memq (car toc) '(bof eof)) | |
3920 | ;; A file entry | |
3921 | (setq match | |
3922 | (let ((where (car toc)) | |
3923 | (file (nth 1 toc))) | |
3924 | (if (or (not no-revisit) (reftex-get-buffer-visiting file)) | |
3925 | (progn | |
3926 | (switch-to-buffer-other-window | |
3927 | (reftex-get-file-buffer-force file nil)) | |
3928 | (goto-char (if (eq where 'bof) (point-min) (point-max)))) | |
3929 | (message reftex-no-follow-message) nil)))) | |
3930 | ||
3931 | ((stringp (car toc)) | |
3932 | ;; a label | |
3933 | (setq match (reftex-show-label-location toc reftex-callback-fwd | |
3934 | no-revisit t)))) | |
396e0b08 KH |
3935 | |
3936 | (setq show-window (selected-window) | |
3937 | show-buffer (current-buffer)) | |
3938 | ||
3939 | (unless match | |
3940 | (select-window toc-window) | |
f9ad2e24 | 3941 | (error "Cannot find location")) |
a7ec1775 RS |
3942 | |
3943 | (select-window toc-window) | |
3944 | ||
3945 | ;; use the `final' parameter to decide what to do next | |
3946 | (cond | |
206c6f82 | 3947 | ((eq final t) |
a7ec1775 RS |
3948 | (reftex-unhighlight 0) |
3949 | (select-window show-window)) | |
3950 | ((eq final 'hide) | |
3951 | (reftex-unhighlight 0) | |
206c6f82 RS |
3952 | (or (one-window-p) (delete-window)) |
3953 | (switch-to-buffer show-buffer) | |
3954 | (reftex-re-enlarge)) | |
a7ec1775 RS |
3955 | (t nil)))) |
3956 | ||
f9ad2e24 CD |
3957 | (defun reftex-toc-find-section (toc &optional no-revisit) |
3958 | (let* ((file (nth 3 toc)) | |
3959 | (marker (nth 4 toc)) | |
3960 | (level (nth 5 toc)) | |
3961 | (literal (nth 7 toc)) | |
3962 | (emergency-point (nth 8 toc)) | |
3963 | (match | |
3964 | (cond | |
3965 | ((and (markerp marker) (marker-buffer marker)) | |
3966 | ;; Buffer is still live and we have the marker. Should be easy. | |
3967 | (switch-to-buffer-other-window (marker-buffer marker)) | |
3968 | (goto-char (marker-position marker)) | |
3969 | (or (looking-at (regexp-quote literal)) | |
3970 | (looking-at (reftex-make-regexp-allow-for-ctrl-m literal)) | |
3971 | (looking-at (reftex-make-desperate-section-regexp literal)) | |
3972 | (looking-at (concat "\\\\" | |
3973 | (regexp-quote | |
3974 | (car | |
3975 | (rassq level | |
3976 | reftex-section-levels-all))) | |
3977 | "[[{]")))) | |
3978 | ((or (not no-revisit) | |
3979 | (reftex-get-buffer-visiting file)) | |
3980 | ;; Marker is lost. Use the backup method. | |
3981 | (switch-to-buffer-other-window | |
3982 | (reftex-get-file-buffer-force file nil)) | |
3983 | (goto-char (or emergency-point (point-min))) | |
3984 | (or (looking-at (regexp-quote literal)) | |
3985 | (let ((pos (point))) | |
3986 | (re-search-backward "\\`\\|[\r\n][ \t]*[\r\n]" nil t) | |
3987 | (or (reftex-nearest-match (regexp-quote literal) pos) | |
3988 | (reftex-nearest-match | |
3989 | (reftex-make-regexp-allow-for-ctrl-m literal) pos) | |
3990 | (reftex-nearest-match | |
3991 | (reftex-make-desperate-section-regexp literal) pos))))) | |
3992 | (t (message reftex-no-follow-message) nil)))) | |
3993 | (when match | |
3994 | (goto-char (match-beginning 0)) | |
3995 | (if (not (= (point) (point-max))) (recenter 1)) | |
3996 | (reftex-highlight 0 (match-beginning 0) (match-end 0) (current-buffer))) | |
3997 | match)) | |
3998 | ||
b849548d CD |
3999 | (defun reftex-make-desperate-section-regexp (old) |
4000 | ;; Return a regexp which will still match a section statement even if | |
4001 | ;; x-symbol or isotex or the like have been at work in the mean time. | |
4002 | (let* ((n (1+ (string-match "[[{]" old))) | |
4003 | (new (regexp-quote (substring old 0 (1+ (string-match "[[{]" old))))) | |
4004 | (old (substring old n))) | |
4005 | (while (string-match | |
4006 | "\\([\r\n]\\)\\|\\(\\`\\|[ \t\n\r]\\)\\([a-zA-Z0-9]+\\)\\([ \t\n\r]\\|}\\'\\)" | |
4007 | old) | |
4008 | (if (match-beginning 1) | |
4009 | (setq new (concat new "[^\n\r]*[\n\r]")) | |
4010 | (setq new (concat new "[^\n\r]*" (match-string 3 old)))) | |
4011 | (setq old (substring old (match-end 0)))) | |
4012 | new)) | |
4013 | ||
4014 | ;;; ========================================================================= | |
a7ec1775 RS |
4015 | ;;; |
4016 | ;;; BibTeX citations. | |
4017 | ||
4018 | ;; Variables and constants | |
4019 | ||
a7ec1775 RS |
4020 | ;; The history list of regular expressions used for citations |
4021 | (defvar reftex-cite-regexp-hist nil) | |
4022 | ||
206c6f82 RS |
4023 | ;; Prompt and help string for citation selection |
4024 | (defconst reftex-citation-prompt | |
4025 | "Select: [n]ext [p]revious [r]estrict [ ]full_entry [q]uit RET [?]Help+more") | |
4026 | ||
a7ec1775 | 4027 | (defconst reftex-citation-help |
2faef409 | 4028 | " n / p Go to next/previous entry (Cursor motion works as well). |
206c6f82 | 4029 | C-s / C-r Search forward/backward. Use repeated C-s/C-r as in isearch. |
2faef409 | 4030 | g / r Start over with new regexp / Refine with additional regexp. |
206c6f82 RS |
4031 | SPC Show full database entry in other window. |
4032 | f Toggle follow mode: Other window will follow with full db entry. | |
29d593f8 | 4033 | . Show insertion point. |
206c6f82 | 4034 | q Quit without inserting \\cite macro into buffer. |
2faef409 | 4035 | TAB Enter citation key with completion. |
29d593f8 | 4036 | RET Accept current entry (also on mouse-2) |
b849548d | 4037 | a / A Put all entries into single \cite / into many cite commands.") |
a7ec1775 | 4038 | |
2faef409 RS |
4039 | (defvar reftex-select-bib-map nil |
4040 | "Keymap used for *RefTeX Select* buffer, when selecting a BibTeX entry. | |
4041 | This keymap can be used to configure the BibTeX selection process which is | |
4042 | started with the command \\[reftex-citation].") | |
4043 | ||
29d593f8 KH |
4044 | (defun reftex-select-bib-mode () |
4045 | "Major mode for selecting a citation key in a LaTeX document. | |
4046 | This buffer was created with RefTeX. | |
4047 | It only has a meaningful keymap when you are in the middle of a | |
4048 | selection process. | |
4049 | In order to select a citation, move the cursor to it and press RET. | |
4050 | Press `?' for a summary of important key bindings. | |
4051 | ||
4052 | During a selection process, these are the local bindings. | |
4053 | ||
4054 | \\{reftex-select-label-map}" | |
4055 | (interactive) | |
4056 | (kill-all-local-variables) | |
4057 | (make-local-hook 'pre-command-hook) | |
4058 | (make-local-hook 'post-command-hook) | |
4059 | (setq major-mode 'reftex-select-bib-mode | |
4060 | mode-name "RefTeX Select Bib") | |
4061 | ;; We do not set a local map - reftex-select-item does this. | |
4062 | (run-hooks 'reftex-select-bib-mode-hook)) | |
4063 | ||
a7ec1775 RS |
4064 | ;; Find bibtex files |
4065 | ||
4066 | (defun reftex-get-bibfile-list () | |
396e0b08 KH |
4067 | ;; Return list of bibfiles for current document. |
4068 | ;; When using the chapterbib or bibunits package you should either | |
4069 | ;; use the same database files everywhere, or separate parts using | |
4070 | ;; different databases into different files (included into the mater file). | |
4071 | ;; Then this function will return the applicable database files. | |
a7ec1775 RS |
4072 | |
4073 | ;; Ensure access to scanning info | |
4074 | (reftex-access-scan-info) | |
396e0b08 KH |
4075 | (or |
4076 | ;; Try inside this file (and its includes) | |
4077 | (cdr (reftex-last-assoc-before-elt | |
4078 | 'bib (list 'eof (buffer-file-name)) | |
4079 | (member (list 'bof (buffer-file-name)) | |
4080 | (symbol-value reftex-docstruct-symbol)))) | |
4081 | ;; Try after the beginning of this file | |
4082 | (cdr (assq 'bib (member (list 'bof (buffer-file-name)) | |
4083 | (symbol-value reftex-docstruct-symbol)))) | |
4084 | ;; Anywhere in the entire document | |
4085 | (cdr (assq 'bib (symbol-value reftex-docstruct-symbol))) | |
921759ee | 4086 | (error "\\bibliography statement missing or .bib files not found"))) |
396e0b08 | 4087 | |
a7ec1775 RS |
4088 | ;; Find a certain reference in any of the BibTeX files. |
4089 | ||
b849548d CD |
4090 | (defun reftex-pop-to-bibtex-entry (key file-list &optional mark-to-kill |
4091 | highlight item return) | |
a7ec1775 | 4092 | ;; Find BibTeX KEY in any file in FILE-LIST in another window. |
2faef409 RS |
4093 | ;; If MARK-TO-KILL is non-nil, mark new buffer to kill. |
4094 | ;; If HIGHLIGHT is non-nil, highlight the match. | |
4095 | ;; If ITEM in non-nil, search for bibitem instead of database entry. | |
a6611c0d | 4096 | ;; If RETURN is non-nil, just return the entry. |
2faef409 RS |
4097 | |
4098 | (let* ((re | |
4099 | (if item | |
4100 | (concat "\\\\bibitem\\(\\[[^]]*\\]\\)?{" (regexp-quote key) "}") | |
b849548d CD |
4101 | (concat "@[a-zA-Z]+[ \t\n\r]*[{(][ \t\n\r]*" (regexp-quote key) |
4102 | "[, \t\r\n}]"))) | |
57ec4af0 | 4103 | (buffer-conf (current-buffer)) |
a7ec1775 | 4104 | file buf) |
2faef409 | 4105 | |
a7ec1775 | 4106 | (catch 'exit |
a7ec1775 RS |
4107 | (while file-list |
4108 | (setq file (car file-list) | |
4109 | file-list (cdr file-list)) | |
396e0b08 KH |
4110 | (unless (setq buf (reftex-get-file-buffer-force file mark-to-kill)) |
4111 | (error "No such file %s" file)) | |
57ec4af0 | 4112 | (set-buffer buf) |
a7ec1775 | 4113 | (widen) |
396e0b08 KH |
4114 | (goto-char (point-min)) |
4115 | (when (re-search-forward re nil t) | |
4116 | (goto-char (match-beginning 0)) | |
b849548d CD |
4117 | (when return |
4118 | ;; Just return the relevant entry | |
a6611c0d CD |
4119 | (if item (goto-char (match-end 0))) |
4120 | (setq return (buffer-substring | |
4121 | (point) (reftex-end-of-bib-entry item))) | |
57ec4af0 | 4122 | (set-buffer buffer-conf) |
b849548d | 4123 | (throw 'exit return)) |
57ec4af0 KH |
4124 | (switch-to-buffer-other-window buffer-conf) |
4125 | (switch-to-buffer buf) | |
396e0b08 KH |
4126 | (recenter 0) |
4127 | (if highlight | |
4128 | (reftex-highlight 0 (match-beginning 0) (match-end 0))) | |
4129 | (throw 'exit (selected-window)))) | |
57ec4af0 | 4130 | (set-buffer buffer-conf) |
2faef409 | 4131 | (if item |
b849548d CD |
4132 | (error "No \\bibitem with citation key %s" key) |
4133 | (error "No BibTeX entry with citation key %s" key))))) | |
a7ec1775 | 4134 | |
a6611c0d CD |
4135 | (defun reftex-end-of-bib-entry (item) |
4136 | (save-excursion | |
4137 | (condition-case nil | |
4138 | (if item | |
4139 | (progn (end-of-line) | |
4140 | (re-search-forward | |
4141 | "\\\\bibitem\\|\\end{thebibliography}") | |
4142 | (1- (match-beginning 0))) | |
4143 | (progn (forward-list 1) (point))) | |
4144 | (error (min (point-max) (+ 300 (point))))))) | |
4145 | ||
a7ec1775 RS |
4146 | ;; Parse bibtex buffers |
4147 | ||
b849548d | 4148 | (defun reftex-extract-bib-entries (buffers) |
a7ec1775 RS |
4149 | ;; Extract bib entries which match regexps from BUFFERS. |
4150 | ;; BUFFERS is a list of buffers or file names. | |
4151 | ;; Return list with entries." | |
4152 | (let* (re-list first-re rest-re | |
a7ec1775 RS |
4153 | (buffer-list (if (listp buffers) buffers (list buffers))) |
4154 | found-list entry buffer1 buffer alist | |
4155 | key-point start-point end-point) | |
4156 | ||
b849548d CD |
4157 | ;; Read a regexp, completing on known citation keys. |
4158 | (setq re-list | |
4159 | (split-string | |
4160 | (completing-read | |
4161 | "RegExp [ && RegExp...]: " | |
f9ad2e24 CD |
4162 | (if reftex-mode |
4163 | (if (fboundp 'LaTeX-bibitem-list) | |
4164 | (LaTeX-bibitem-list) | |
4165 | (cdr (assoc 'bibview-cache | |
4166 | (symbol-value reftex-docstruct-symbol)))) | |
4167 | nil) | |
b849548d CD |
4168 | nil nil nil 'reftex-cite-regexp-hist) |
4169 | "[ \t]*&&[ \t]*")) | |
a7ec1775 RS |
4170 | |
4171 | (setq first-re (car re-list) ; We'll use the first re to find things, | |
2faef409 | 4172 | rest-re (cdr re-list)) ; the others to narrow down. |
921759ee | 4173 | (if (string-match "\\`[ \t]*\\'" (or first-re "")) |
a7ec1775 RS |
4174 | (error "Empty regular expression")) |
4175 | ||
4176 | (save-excursion | |
4177 | (save-window-excursion | |
4178 | ||
396e0b08 | 4179 | ;; Walk through all bibtex files |
a7ec1775 RS |
4180 | (while buffer-list |
4181 | (setq buffer (car buffer-list) | |
4182 | buffer-list (cdr buffer-list)) | |
4183 | (if (and (bufferp buffer) | |
4184 | (buffer-live-p buffer)) | |
4185 | (setq buffer1 buffer) | |
4186 | (setq buffer1 (reftex-get-file-buffer-force | |
4187 | buffer (not reftex-keep-temporary-buffers)))) | |
4188 | (if (not buffer1) | |
921759ee | 4189 | (message "No such BibTeX file %s (ignored)" buffer) |
a7ec1775 RS |
4190 | (message "Scanning bibliography database %s" buffer1)) |
4191 | ||
4192 | (set-buffer buffer1) | |
396e0b08 KH |
4193 | (save-excursion |
4194 | (goto-char (point-min)) | |
4195 | (while (re-search-forward first-re nil t) | |
4196 | (catch 'search-again | |
4197 | (setq key-point (point)) | |
4198 | (unless (re-search-backward | |
4199 | "\\(\\`\\|[\n\r]\\)[ \t]*@\\([a-zA-Z]+\\)[ \t\n\r]*[{(]" nil t) | |
4200 | (throw 'search-again nil)) | |
4201 | (setq start-point (point)) | |
4202 | (goto-char (match-end 0)) | |
4203 | (condition-case nil | |
4204 | (up-list 1) | |
4205 | (error (goto-char key-point) | |
4206 | (throw 'search-again nil))) | |
4207 | (setq end-point (point)) | |
4208 | ||
4209 | ;; Ignore @string, @comment and @c entries or things | |
4210 | ;; outside entries | |
4211 | (when (or (string= (downcase (match-string 2)) "string") | |
4212 | (string= (downcase (match-string 2)) "comment") | |
4213 | (string= (downcase (match-string 2)) "c") | |
4214 | (< (point) key-point)) ; this means match not in {} | |
4215 | (goto-char key-point) | |
4216 | (throw 'search-again nil)) | |
4217 | ||
4218 | ;; Well, we have got a match | |
4219 | (setq entry (concat | |
4220 | (buffer-substring start-point (point)) "\n")) | |
4221 | ||
4222 | ;; Check if other regexp match as well | |
4223 | (setq re-list rest-re) | |
4224 | (while re-list | |
4225 | (unless (string-match (car re-list) entry) | |
4226 | ;; nope - move on | |
4227 | (throw 'search-again nil)) | |
4228 | (pop re-list)) | |
4229 | ||
4230 | (setq alist (reftex-parse-bibtex-entry | |
4231 | nil start-point end-point)) | |
4232 | (push (cons "&entry" entry) alist) | |
4233 | ||
4234 | ;; check for crossref entries | |
4235 | (if (assoc "crossref" alist) | |
4236 | (setq alist | |
4237 | (append | |
4238 | alist (reftex-get-crossref-alist alist)))) | |
4239 | ||
4240 | ;; format the entry | |
4241 | (push (cons "&formatted" (reftex-format-bib-entry alist)) | |
4242 | alist) | |
4243 | ||
b849548d CD |
4244 | ;; make key the first element |
4245 | (push (reftex-get-bib-field "&key" alist) alist) | |
4246 | ||
396e0b08 KH |
4247 | ;; add it to the list |
4248 | (push alist found-list)))) | |
a7ec1775 RS |
4249 | (reftex-kill-temporary-buffers)))) |
4250 | (setq found-list (nreverse found-list)) | |
396e0b08 | 4251 | |
a7ec1775 | 4252 | ;; Sorting |
396e0b08 | 4253 | (cond |
a7ec1775 RS |
4254 | ((eq 'author reftex-sort-bibtex-matches) |
4255 | (sort found-list 'reftex-bib-sort-author)) | |
4256 | ((eq 'year reftex-sort-bibtex-matches) | |
4257 | (sort found-list 'reftex-bib-sort-year)) | |
4258 | ((eq 'reverse-year reftex-sort-bibtex-matches) | |
4259 | (sort found-list 'reftex-bib-sort-year-reverse)) | |
4260 | (t found-list)))) | |
4261 | ||
4262 | (defun reftex-bib-sort-author (e1 e2) | |
206c6f82 | 4263 | (let ((al1 (reftex-get-bib-names "author" e1)) |
396e0b08 | 4264 | (al2 (reftex-get-bib-names "author" e2))) |
a7ec1775 | 4265 | (while (and al1 al2 (string= (car al1) (car al2))) |
396e0b08 KH |
4266 | (pop al1) |
4267 | (pop al2)) | |
a7ec1775 | 4268 | (if (and (stringp (car al1)) |
396e0b08 KH |
4269 | (stringp (car al2))) |
4270 | (string< (car al1) (car al2)) | |
a7ec1775 RS |
4271 | (not (stringp (car al1)))))) |
4272 | ||
4273 | (defun reftex-bib-sort-year (e1 e2) | |
4274 | (< (string-to-int (cdr (assoc "year" e1))) | |
4275 | (string-to-int (cdr (assoc "year" e2))))) | |
4276 | ||
4277 | (defun reftex-bib-sort-year-reverse (e1 e2) | |
4278 | (> (string-to-int (or (cdr (assoc "year" e1)) "0")) | |
4279 | (string-to-int (or (cdr (assoc "year" e2)) "0")))) | |
4280 | ||
4281 | (defun reftex-get-crossref-alist (entry) | |
4282 | ;; return the alist from a crossref entry | |
4283 | (let ((crkey (cdr (assoc "crossref" entry))) | |
4284 | start) | |
4285 | (save-excursion | |
4286 | (save-restriction | |
4287 | (widen) | |
4288 | (if (re-search-forward | |
396e0b08 KH |
4289 | (concat "@\\w+[{(][ \t\n\r]*" (regexp-quote crkey) |
4290 | "[ \t\n\r]*,") nil t) | |
a7ec1775 RS |
4291 | (progn |
4292 | (setq start (match-beginning 0)) | |
4293 | (condition-case nil | |
4294 | (up-list 1) | |
206c6f82 | 4295 | (error nil)) |
a7ec1775 RS |
4296 | (reftex-parse-bibtex-entry nil start (point))) |
4297 | nil))))) | |
4298 | ||
2faef409 RS |
4299 | ;; Parse the thebibliography environment |
4300 | (defun reftex-extract-bib-entries-from-thebibliography (file) | |
4301 | ;; Extract bib-entries from the \begin{thebibliography} environment. | |
4302 | ;; Parsing is not as good as for the BibTeX database stuff. | |
4303 | ;; The environment should be located in file FILE. | |
4304 | ||
4305 | (let* (start end buf entries re re-list) | |
4306 | (unless file | |
4307 | (error "Need file name to find thebibliography environment")) | |
4308 | (setq buf (reftex-get-file-buffer-force | |
4309 | file (not reftex-keep-temporary-buffers))) | |
4310 | (unless buf | |
4311 | (error "No such file %s" file)) | |
4312 | (message "Scanning thebibliography environment in %s" file) | |
4313 | ||
4314 | (save-excursion | |
4315 | (set-buffer buf) | |
4316 | (save-restriction | |
4317 | (widen) | |
4318 | (goto-char (point-min)) | |
4319 | (if (re-search-forward | |
4320 | "\\(\\`\\|[\n\r]\\)[ \t]*\\\\begin{thebibliography}" nil t) | |
4321 | (progn | |
4322 | (beginning-of-line 2) | |
4323 | (setq start (point)))) | |
4324 | (if (re-search-forward | |
4325 | "\\(\\`\\|[\n\r]\\)[ \t]*\\\\end{thebibliography}" nil t) | |
4326 | (progn | |
4327 | (beginning-of-line 1) | |
4328 | (setq end (point)))) | |
b849548d | 4329 | (when (and start end) |
2faef409 RS |
4330 | (setq entries |
4331 | (mapcar 'reftex-parse-bibitem | |
4332 | (delete "" | |
4333 | (split-string | |
4334 | (buffer-substring-no-properties start end) | |
4335 | "[ \t\n\r]*\\\\bibitem\\(\\[[^]]*]\\)*"))))))) | |
4336 | (unless entries | |
4337 | (error "No bibitems found")) | |
4338 | ||
4339 | (setq re-list (split-string | |
4340 | (read-string "RegExp [ && RegExp...]: " | |
4341 | nil 'reftex-cite-regexp-hist) | |
4342 | "[ \t]*&&[ \t]*")) | |
4343 | (if (string-match "\\`[ \t]*\\'" (car re-list)) | |
4344 | (error "Empty regular expression")) | |
4345 | ||
4346 | (while (and (setq re (pop re-list)) entries) | |
4347 | (setq entries | |
b849548d CD |
4348 | (delq nil (mapcar |
4349 | (function | |
4350 | (lambda (x) | |
4351 | (if (string-match re (cdr (assoc "&entry" x))) | |
4352 | x nil))) | |
4353 | entries)))) | |
2faef409 RS |
4354 | (setq entries |
4355 | (mapcar | |
2faef409 | 4356 | (lambda (x) |
b849548d CD |
4357 | (push (cons "&formatted" (reftex-format-bibitem x)) x) |
4358 | (push (reftex-get-bib-field "&key" x) x) | |
4359 | x) | |
2faef409 RS |
4360 | entries)) |
4361 | ||
4362 | entries)) | |
4363 | ||
a7ec1775 RS |
4364 | ;; Parse and format individual entries |
4365 | ||
206c6f82 | 4366 | (defun reftex-get-bib-names (field entry) |
2faef409 | 4367 | ;; Return a list with the author or editor names in ENTRY |
206c6f82 RS |
4368 | (let ((names (reftex-get-bib-field field entry))) |
4369 | (if (equal "" names) | |
4370 | (setq names (reftex-get-bib-field "editor" entry))) | |
4371 | (while (string-match "\\band\\b[ \t]*" names) | |
4372 | (setq names (replace-match "\n" nil t names))) | |
4373 | (while (string-match "[\\.a-zA-Z\\-]+\\.[ \t]*\\|,.*\\|[{}]+" names) | |
4374 | (setq names (replace-match "" nil t names))) | |
4375 | (while (string-match "^[ \t]+\\|[ \t]+$" names) | |
4376 | (setq names (replace-match "" nil t names))) | |
4377 | (while (string-match "[ \t][ \t]+" names) | |
4378 | (setq names (replace-match " " nil t names))) | |
396e0b08 | 4379 | (split-string names "\n"))) |
a7ec1775 RS |
4380 | |
4381 | (defun reftex-parse-bibtex-entry (entry &optional from to) | |
4382 | (let (alist key start field) | |
4383 | (save-excursion | |
4384 | (save-restriction | |
4385 | (if entry | |
4386 | (progn | |
b849548d | 4387 | (set-buffer (get-buffer-create " *RefTeX-scratch*")) |
a7ec1775 RS |
4388 | (fundamental-mode) |
4389 | (erase-buffer) | |
4390 | (insert entry)) | |
4391 | (widen) | |
4392 | (narrow-to-region from to)) | |
4393 | (goto-char (point-min)) | |
4394 | ||
396e0b08 | 4395 | (if (re-search-forward |
c52bdfca | 4396 | "@\\(\\w+\\)[ \t\n\r]*[{(][ \t\n\r]*\\([^ \t\n\r,]+\\)" nil t) |
a7ec1775 RS |
4397 | (setq alist |
4398 | (list | |
396e0b08 KH |
4399 | (cons "&type" (downcase (reftex-match-string 1))) |
4400 | (cons "&key" (reftex-match-string 2))))) | |
a7ec1775 | 4401 | (while (re-search-forward "\\(\\w+\\)[ \t\n\r]*=[ \t\n\r]*" nil t) |
396e0b08 | 4402 | (setq key (downcase (reftex-match-string 1))) |
a7ec1775 RS |
4403 | (cond |
4404 | ((= (following-char) ?{) | |
4405 | (forward-char 1) | |
4406 | (setq start (point)) | |
4407 | (condition-case nil | |
4408 | (up-list 1) | |
206c6f82 | 4409 | (error nil))) |
a7ec1775 RS |
4410 | ((= (following-char) ?\") |
4411 | (forward-char 1) | |
4412 | (setq start (point)) | |
4413 | (while (and (search-forward "\"" nil t) | |
4414 | (= ?\\ (char-after (- (point) 2)))))) | |
4415 | (t | |
4416 | (setq start (point)) | |
b849548d | 4417 | (re-search-forward "[ \t]*[\n\r,}]" nil 1))) |
a7ec1775 | 4418 | (setq field (buffer-substring-no-properties start (1- (point)))) |
2faef409 | 4419 | ;; remove extra whitespace |
a7ec1775 RS |
4420 | (while (string-match "[\n\t\r]\\|[ \t][ \t]+" field) |
4421 | (setq field (replace-match " " nil t field))) | |
4422 | ;; remove leading garbage | |
4423 | (if (string-match "^[ \t{]+" field) | |
4424 | (setq field (replace-match "" nil t field))) | |
4425 | ;; remove trailing garbage | |
4426 | (if (string-match "[ \t}]+$" field) | |
4427 | (setq field (replace-match "" nil t field))) | |
396e0b08 KH |
4428 | (push (cons key field) alist)))) |
4429 | alist)) | |
a7ec1775 | 4430 | |
b849548d | 4431 | (defun reftex-get-bib-field (fieldname entry &optional format) |
a7ec1775 | 4432 | ;; Extract the field FIELDNAME from an ENTRY |
b849548d CD |
4433 | (let ((cell (assoc fieldname entry))) |
4434 | (if cell | |
4435 | (if format | |
4436 | (format format (cdr cell)) | |
4437 | (cdr cell)) | |
4438 | ""))) | |
a7ec1775 RS |
4439 | |
4440 | (defun reftex-format-bib-entry (entry) | |
4441 | ;; Format a BibTeX ENTRY so that it is nice to look at | |
4442 | (let* | |
396e0b08 | 4443 | ((auth-list (reftex-get-bib-names "author" entry)) |
2faef409 | 4444 | (authors (mapconcat 'identity auth-list ", ")) |
a7ec1775 RS |
4445 | (year (reftex-get-bib-field "year" entry)) |
4446 | (title (reftex-get-bib-field "title" entry)) | |
4447 | (type (reftex-get-bib-field "&type" entry)) | |
4448 | (key (reftex-get-bib-field "&key" entry)) | |
4449 | (extra | |
4450 | (cond | |
4451 | ((equal type "article") | |
4452 | (concat (reftex-get-bib-field "journal" entry) " " | |
4453 | (reftex-get-bib-field "volume" entry) ", " | |
4454 | (reftex-get-bib-field "pages" entry))) | |
4455 | ((equal type "book") | |
4456 | (concat "book (" (reftex-get-bib-field "publisher" entry) ")")) | |
4457 | ((equal type "phdthesis") | |
4458 | (concat "PhD: " (reftex-get-bib-field "school" entry))) | |
4459 | ((equal type "mastersthesis") | |
4460 | (concat "Master: " (reftex-get-bib-field "school" entry))) | |
4461 | ((equal type "inbook") | |
4462 | (concat "Chap: " (reftex-get-bib-field "chapter" entry) | |
4463 | ", pp. " (reftex-get-bib-field "pages" entry))) | |
4464 | ((or (equal type "conference") | |
4465 | (equal type "incollection") | |
4466 | (equal type "inproceedings")) | |
b849548d | 4467 | (reftex-get-bib-field "booktitle" entry "in: %s")) |
a7ec1775 | 4468 | (t "")))) |
396e0b08 KH |
4469 | (setq authors (reftex-truncate authors 30 t t)) |
4470 | (when (reftex-use-fonts) | |
b849548d CD |
4471 | (put-text-property 0 (length key) 'face |
4472 | (reftex-verified-face reftex-label-face | |
4473 | 'font-lock-constant-face | |
4474 | 'font-lock-reference-face) | |
4475 | key) | |
6b94c6ad | 4476 | (put-text-property 0 (length authors) 'face reftex-bib-author-face |
396e0b08 | 4477 | authors) |
6b94c6ad CD |
4478 | (put-text-property 0 (length year) 'face reftex-bib-year-face |
4479 | year) | |
4480 | (put-text-property 0 (length title) 'face reftex-bib-title-face | |
396e0b08 | 4481 | title) |
6b94c6ad | 4482 | (put-text-property 0 (length extra) 'face reftex-bib-extra-face |
396e0b08 KH |
4483 | extra)) |
4484 | (concat key "\n " authors " " year " " extra "\n " title "\n\n"))) | |
a7ec1775 | 4485 | |
2faef409 RS |
4486 | (defun reftex-parse-bibitem (item) |
4487 | ;; Parse a \bibitem entry | |
4488 | (let ((key "") (text "")) | |
4489 | (when (string-match "\\`{\\([^}]+\\)}\\([\001-\255]*\\)" item) | |
4490 | (setq key (match-string 1 item) | |
4491 | text (match-string 2 item))) | |
4492 | ;; Clean up the text a little bit | |
4493 | (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text) | |
4494 | (setq text (replace-match " " nil t text))) | |
4495 | (if (string-match "\\`[ \t]+" text) | |
4496 | (setq text (replace-match "" nil t text))) | |
4497 | (list | |
4498 | (cons "&key" key) | |
4499 | (cons "&text" text) | |
4500 | (cons "&entry" (concat key " " text))))) | |
4501 | ||
4502 | (defun reftex-format-bibitem (item) | |
4503 | ;; Format a \bibitem entry so that it is (relatively) nice to look at. | |
4504 | (let ((text (reftex-get-bib-field "&text" item)) | |
4505 | (key (reftex-get-bib-field "&key" item)) | |
4506 | (lines nil)) | |
4507 | ||
4508 | ;; Wrap the text into several lines. | |
4509 | (while (and (> (length text) 70) | |
4510 | (string-match " " (substring text 60))) | |
4511 | (push (substring text 0 (+ 60 (match-beginning 0))) lines) | |
4512 | (setq text (substring text (+ 61 (match-beginning 0))))) | |
4513 | (push text lines) | |
4514 | (setq text (mapconcat 'identity (nreverse lines) "\n ")) | |
4515 | ||
4516 | (when (reftex-use-fonts) | |
6b94c6ad | 4517 | (put-text-property 0 (length text) 'face reftex-bib-author-face text)) |
2faef409 RS |
4518 | (concat key "\n " text "\n\n"))) |
4519 | ||
a7ec1775 RS |
4520 | ;; Make a citation |
4521 | ||
b849548d | 4522 | ;;;###autoload |
396e0b08 | 4523 | (defun reftex-citation (&optional no-insert) |
c52bdfca | 4524 | "Make a citation using BibTeX database files. |
f9ad2e24 | 4525 | After prompting for a regular expression, scans the buffers with |
a7ec1775 | 4526 | bibtex entries (taken from the \\bibliography command) and offers the |
c52bdfca RS |
4527 | matching entries for selection. The selected entry is formated according |
4528 | to `reftex-cite-format' and inserted into the buffer. | |
921759ee | 4529 | |
a7ec1775 | 4530 | If NO-INSERT is non-nil, nothing is inserted, only the selected key returned. |
921759ee CD |
4531 | |
4532 | When called with one or two `C-u' prefixes, first rescans the document. | |
4533 | When called with a numeric prefix, make that many citations. When | |
4534 | called with point inside the braces of a `\cite' command, it will | |
4535 | add another key, ignoring the value of `reftex-cite-format'. | |
4536 | ||
c52bdfca RS |
4537 | The regular expression uses an expanded syntax: && is interpreted as `and'. |
4538 | Thus, `aaaa&&bbb' matches entries which contain both `aaaa' and `bbb'. | |
b849548d | 4539 | While entering the regexp, completion on knows citation keys is possible. |
921759ee | 4540 | `=' is a good regular expression to match all entries in all files." |
a7ec1775 | 4541 | |
396e0b08 | 4542 | (interactive) |
a7ec1775 RS |
4543 | |
4544 | ;; check for recursive edit | |
4545 | (reftex-check-recursive-edit) | |
4546 | ||
b849548d CD |
4547 | ;; This function may also be called outside reftex-mode. |
4548 | ;; Thus look for the scanning info only if in reftex-mode. | |
4549 | ||
4550 | (when reftex-mode | |
4551 | (reftex-access-scan-info current-prefix-arg)) | |
396e0b08 KH |
4552 | |
4553 | ;; Call reftex-do-citation, but protected | |
4554 | (unwind-protect | |
4555 | (reftex-do-citation current-prefix-arg no-insert) | |
4556 | (reftex-kill-temporary-buffers))) | |
a7ec1775 | 4557 | |
396e0b08 KH |
4558 | (defun reftex-do-citation (&optional arg no-insert) |
4559 | ;; This really does the work of reftex-citation. | |
4560 | ||
b849548d CD |
4561 | (let* ((format (reftex-figure-out-cite-format arg no-insert)) |
4562 | (docstruct-symbol reftex-docstruct-symbol) | |
4563 | (selected-entries (reftex-offer-bib-menu)) | |
4564 | (insert-entries selected-entries) | |
4565 | entry string cite-view) | |
4566 | ||
4567 | (unless selected-entries (error "Quit")) | |
4568 | ||
4569 | (if (stringp selected-entries) | |
4570 | ;; Nonexistent entry | |
4571 | (setq selected-entries nil | |
4572 | insert-entries (list (list selected-entries | |
4573 | (cons "&key" selected-entries)))) | |
4574 | ;; It makes sense to compute the cite-view strings. | |
4575 | (setq cite-view t)) | |
4576 | ||
4577 | (when (eq (car selected-entries) 'concat) | |
4578 | ;; All keys go into a single command - we need to trick a little | |
4579 | (pop selected-entries) | |
4580 | (let ((concat-keys (mapconcat 'car selected-entries ","))) | |
4581 | (setq insert-entries | |
4582 | (list (list concat-keys (cons "&key" concat-keys)))))) | |
4583 | ||
4584 | (unless no-insert | |
4585 | ||
4586 | ;; We shall insert this into the buffer... | |
4587 | (message "Formatting...") | |
4588 | ||
4589 | (while (setq entry (pop insert-entries)) | |
4590 | ;; Format the citation and insert it | |
4591 | (setq string (if reftex-format-cite-function | |
4592 | (funcall reftex-format-cite-function | |
4593 | (reftex-get-bib-field "&key" entry) | |
4594 | format) | |
4595 | (reftex-format-citation entry format))) | |
4596 | (insert string)) | |
4597 | ||
4598 | ;; Reposition cursor? | |
4599 | (when (string-match "\\?" string) | |
4600 | (search-backward "?") | |
4601 | (delete-char 1)) | |
4602 | ||
4603 | ;; Tell AUCTeX | |
a6611c0d CD |
4604 | (when (and reftex-mode |
4605 | (fboundp 'LaTeX-add-bibitems) | |
4606 | reftex-plug-into-AUCTeX) | |
b849548d CD |
4607 | (apply 'LaTeX-add-bibitems (mapcar 'car selected-entries))) |
4608 | ||
4609 | ;; Produce the cite-view strings | |
a6611c0d | 4610 | (when (and reftex-mode reftex-cache-cite-echo cite-view) |
b849548d CD |
4611 | (mapcar (lambda (entry) |
4612 | (reftex-make-cite-echo-string entry docstruct-symbol)) | |
4613 | selected-entries)) | |
4614 | ||
4615 | (message "")) | |
4616 | ||
4617 | (set-marker reftex-select-return-marker nil) | |
4618 | (reftex-kill-buffer "*RefTeX Select*") | |
4619 | ||
4620 | ;; Check if the prefix arg was numeric, and call recursively | |
4621 | (when (integerp arg) | |
4622 | (if (> arg 1) | |
4623 | (progn | |
4624 | (skip-chars-backward "}") | |
4625 | (decf arg) | |
4626 | (reftex-do-citation arg)) | |
4627 | (forward-char 1))) | |
4628 | ||
4629 | ;; Return the citation key | |
4630 | (car (car selected-entries)))) | |
4631 | ||
4632 | (defun reftex-figure-out-cite-format (arg no-insert) | |
396e0b08 | 4633 | ;; Check if there is already a cite command at point and change cite format |
a7ec1775 | 4634 | ;; in order to only add another reference in the same cite command. |
b849548d CD |
4635 | (let ((macro (car (reftex-what-macro 1))) |
4636 | (cite-format-value (reftex-get-cite-format)) | |
4637 | key format) | |
4638 | (cond | |
4639 | (no-insert | |
4640 | ;; Format does not really matter because nothing will be inserted. | |
4641 | (setq format "%l")) | |
4642 | ||
4643 | ((and (stringp macro) | |
4644 | (string-match "\\`\\\\cite\\|cite\\'" macro)) | |
4645 | ;; We are already inside a cite macro | |
4646 | (if (or (not arg) (not (listp arg))) | |
4647 | (setq format | |
4648 | (concat | |
4649 | (if (member (preceding-char) '(?\{ ?,)) "" ",") | |
4650 | "%l" | |
4651 | (if (member (following-char) '(?\} ?,)) "" ","))) | |
4652 | (setq format "%l"))) | |
4653 | (t | |
4654 | ;; Figure out the correct format | |
206c6f82 | 4655 | (setq format |
b849548d CD |
4656 | (if (and (symbolp cite-format-value) |
4657 | (assq cite-format-value reftex-cite-format-builtin)) | |
4658 | (nth 2 (assq cite-format-value reftex-cite-format-builtin)) | |
4659 | cite-format-value)) | |
4660 | (when (listp format) | |
4661 | (setq key | |
4662 | (reftex-select-with-char | |
4663 | "" (concat "SELECT A CITATION FORMAT\n\n" | |
4664 | (mapconcat | |
4665 | (lambda (x) | |
4666 | (format "[%c] %s %s" (car x) | |
4667 | (if (> (car x) 31) " " "") | |
4668 | (cdr x))) | |
4669 | format "\n")))) | |
4670 | (if (assq key format) | |
4671 | (setq format (cdr (assq key format))) | |
4672 | (error "No citation format associated with key `%c'" key))))) | |
4673 | format)) | |
4674 | ||
4675 | (defun reftex-get-cite-format () | |
4676 | ;; Return the current citation format. Either the document-local value in | |
4677 | ;; reftex-cite-format-symbol, or the global value in reftex-cite-format. | |
4678 | (if (and reftex-docstruct-symbol | |
4679 | (symbolp reftex-docstruct-symbol) | |
4680 | (get reftex-docstruct-symbol 'reftex-cite-format)) | |
4681 | (get reftex-docstruct-symbol 'reftex-cite-format) | |
4682 | reftex-cite-format)) | |
4683 | ||
4684 | (defun reftex-offer-bib-menu () | |
4685 | ;; Offer bib menu and return list of selected items | |
4686 | ||
4687 | (let (found-list rtn key data selected-entries) | |
b849548d CD |
4688 | (while |
4689 | (not | |
4690 | (catch 'done | |
4691 | ;; Scan bibtex files | |
4692 | (setq found-list | |
4693 | (cond | |
4694 | ((assq 'bib (symbol-value reftex-docstruct-symbol)) | |
4695 | ;; using BibTeX database files. | |
4696 | (reftex-extract-bib-entries (reftex-get-bibfile-list))) | |
4697 | ((assq 'thebib (symbol-value reftex-docstruct-symbol)) | |
4698 | ;; using thebibliography environment. | |
4699 | (reftex-extract-bib-entries-from-thebibliography | |
4700 | (cdr (assq 'thebib (symbol-value reftex-docstruct-symbol))))) | |
4701 | (reftex-default-bibliography | |
4702 | (message "Using default bibliography") | |
921759ee | 4703 | (reftex-extract-bib-entries (reftex-default-bibliography))) |
b849548d CD |
4704 | (t (error "No valid bibliography in this document, and no default available")))) |
4705 | ||
4706 | (unless found-list | |
4707 | (error "Sorry, no matches found")) | |
4708 | ||
4709 | ;; Remember where we came from | |
4710 | (setq reftex-call-back-to-this-buffer (current-buffer)) | |
4711 | (set-marker reftex-select-return-marker (point)) | |
4712 | ||
4713 | ;; Offer selection | |
4714 | (save-window-excursion | |
4715 | (delete-other-windows) | |
4716 | (let ((default-major-mode 'reftex-select-bib-mode)) | |
4717 | (reftex-kill-buffer "*RefTeX Select*") | |
4718 | (switch-to-buffer-other-window "*RefTeX Select*") | |
4719 | (unless (eq major-mode 'reftex-select-bib-mode) | |
4720 | (reftex-select-bib-mode)) | |
4721 | (let ((buffer-read-only nil)) | |
4722 | (erase-buffer) | |
4723 | (reftex-insert-bib-matches found-list))) | |
4724 | (setq buffer-read-only t) | |
4725 | (if (= 0 (buffer-size)) | |
921759ee | 4726 | (error "No matches found")) |
b849548d CD |
4727 | (setq truncate-lines t) |
4728 | (goto-char 1) | |
4729 | (while t | |
4730 | (setq rtn | |
4731 | (reftex-select-item | |
4732 | reftex-citation-prompt | |
4733 | reftex-citation-help | |
4734 | reftex-select-bib-map | |
4735 | nil | |
4736 | 'reftex-bibtex-selection-callback nil)) | |
4737 | (setq key (car rtn) | |
4738 | data (nth 1 rtn)) | |
4739 | (unless key (throw 'done t)) | |
4740 | (cond | |
4741 | ((eq key ?g) | |
4742 | ;; Start over | |
4743 | (throw 'done nil)) | |
4744 | ((eq key ?r) | |
4745 | ;; Restrict with new regular expression | |
4746 | (setq found-list (reftex-restrict-bib-matches found-list)) | |
4747 | (let ((buffer-read-only nil)) | |
4748 | (erase-buffer) | |
4749 | (reftex-insert-bib-matches found-list)) | |
4750 | (goto-char 1)) | |
4751 | ((eq key ?A) | |
f9ad2e24 | 4752 | (debug) |
b849548d CD |
4753 | ;; Take all |
4754 | (setq selected-entries found-list) | |
4755 | (throw 'done t)) | |
4756 | ((eq key ?a) | |
4757 | ;; Take all | |
4758 | (setq selected-entries (cons 'concat found-list)) | |
4759 | (throw 'done t)) | |
4760 | ((or (eq key ?\C-m) | |
4761 | (eq key 'return)) | |
4762 | ;; Take selected | |
4763 | (setq selected-entries (if data (list data) nil)) | |
4764 | (throw 'done t)) | |
4765 | ((stringp key) | |
4766 | ;; Got this one with completion | |
4767 | (setq selected-entries key) | |
4768 | (throw 'done t)) | |
4769 | (t | |
4770 | (ding)))))))) | |
4771 | selected-entries)) | |
4772 | ||
4773 | (defun reftex-restrict-bib-matches (found-list) | |
4774 | ;; Limit FOUND-LIST with more regular expressions | |
4775 | (let ((re-list (split-string (read-string | |
4776 | "RegExp [ && RegExp...]: " | |
4777 | nil 'reftex-cite-regexp-hist) | |
4778 | "[ \t]*&&[ \t]*")) | |
4779 | (found-list-r found-list) | |
4780 | re) | |
4781 | (while (setq re (pop re-list)) | |
4782 | (setq found-list-r | |
4783 | (delq nil | |
4784 | (mapcar | |
4785 | (lambda (x) | |
4786 | (if (string-match | |
4787 | re (cdr (assoc "&entry" x))) | |
4788 | x | |
4789 | nil)) | |
4790 | found-list-r)))) | |
4791 | (if found-list-r | |
4792 | found-list-r | |
4793 | (ding) | |
4794 | found-list))) | |
396e0b08 | 4795 | |
206c6f82 RS |
4796 | (defun reftex-insert-bib-matches (list) |
4797 | ;; Insert the bib matches and number them correctly | |
6b94c6ad CD |
4798 | (let ((mouse-face |
4799 | (if (memq reftex-highlight-selection '(mouse both)) | |
4800 | reftex-mouse-selected-face | |
4801 | nil)) | |
4802 | tmp len) | |
2faef409 RS |
4803 | (mapcar |
4804 | (function | |
4805 | (lambda (x) | |
29d593f8 KH |
4806 | (setq tmp (cdr (assoc "&formatted" x)) |
4807 | len (length tmp)) | |
921759ee | 4808 | (put-text-property 0 len :data x tmp) |
29d593f8 | 4809 | (put-text-property 0 (1- len) 'mouse-face mouse-face tmp) |
2faef409 | 4810 | (insert tmp))) |
b849548d CD |
4811 | list)) |
4812 | (run-hooks 'reftex-display-copied-context-hook)) | |
206c6f82 RS |
4813 | |
4814 | (defun reftex-format-names (namelist n) | |
206c6f82 RS |
4815 | (let (last (len (length namelist))) |
4816 | (cond | |
b849548d | 4817 | ((< len 1) "") |
206c6f82 RS |
4818 | ((= 1 len) (car namelist)) |
4819 | ((> len n) (concat (car namelist) (nth 2 reftex-cite-punctuation))) | |
4820 | (t | |
4821 | (setq n (min len n) | |
396e0b08 | 4822 | last (nth (1- n) namelist)) |
206c6f82 RS |
4823 | (setcdr (nthcdr (- n 2) namelist) nil) |
4824 | (concat | |
4825 | (mapconcat 'identity namelist (nth 0 reftex-cite-punctuation)) | |
4826 | (nth 1 reftex-cite-punctuation) | |
4827 | last))))) | |
4828 | ||
4829 | (defun reftex-format-citation (entry format) | |
a7ec1775 | 4830 | ;; Format a citation from the info in the BibTeX ENTRY |
a7ec1775 | 4831 | |
396e0b08 | 4832 | (unless (stringp format) (setq format "\\cite{%l}")) |
206c6f82 RS |
4833 | |
4834 | (if (and reftex-comment-citations | |
396e0b08 | 4835 | (string-match "%l" reftex-cite-comment-format)) |
2faef409 | 4836 | (error "reftex-cite-comment-format contains illegal %%l")) |
206c6f82 | 4837 | |
396e0b08 KH |
4838 | (while (string-match |
4839 | "\\(\\`\\|[^%]\\)\\(\\(%\\([0-9]*\\)\\([a-zA-Z]\\)\\)[.,;: ]*\\)" | |
4840 | format) | |
206c6f82 | 4841 | (let ((n (string-to-int (match-string 4 format))) |
396e0b08 KH |
4842 | (l (string-to-char (match-string 5 format))) |
4843 | rpl b e) | |
206c6f82 | 4844 | (save-match-data |
396e0b08 KH |
4845 | (setq rpl |
4846 | (cond | |
4847 | ((= l ?l) (concat | |
4848 | (reftex-get-bib-field "&key" entry) | |
4849 | (if reftex-comment-citations | |
4850 | reftex-cite-comment-format | |
4851 | ""))) | |
4852 | ((= l ?a) (reftex-format-names | |
4853 | (reftex-get-bib-names "author" entry) | |
4854 | (or n 2))) | |
4855 | ((= l ?A) (car (reftex-get-bib-names "author" entry))) | |
b849548d CD |
4856 | ((= l ?b) (reftex-get-bib-field "booktitle" entry "in: %s")) |
4857 | ((= l ?B) (reftex-abbreviate-title | |
4858 | (reftex-get-bib-field "booktitle" entry "in: %s"))) | |
396e0b08 KH |
4859 | ((= l ?c) (reftex-get-bib-field "chapter" entry)) |
4860 | ((= l ?d) (reftex-get-bib-field "edition" entry)) | |
4861 | ((= l ?e) (reftex-format-names | |
4862 | (reftex-get-bib-names "editor" entry) | |
4863 | (or n 2))) | |
4864 | ((= l ?E) (car (reftex-get-bib-names "editor" entry))) | |
4865 | ((= l ?h) (reftex-get-bib-field "howpublished" entry)) | |
4866 | ((= l ?i) (reftex-get-bib-field "institution" entry)) | |
4867 | ((= l ?j) (reftex-get-bib-field "journal" entry)) | |
4868 | ((= l ?k) (reftex-get-bib-field "key" entry)) | |
4869 | ((= l ?m) (reftex-get-bib-field "month" entry)) | |
4870 | ((= l ?n) (reftex-get-bib-field "number" entry)) | |
4871 | ((= l ?o) (reftex-get-bib-field "organization" entry)) | |
4872 | ((= l ?p) (reftex-get-bib-field "pages" entry)) | |
4873 | ((= l ?P) (car (split-string | |
4874 | (reftex-get-bib-field "pages" entry) | |
4875 | "[- .]+"))) | |
4876 | ((= l ?s) (reftex-get-bib-field "school" entry)) | |
4877 | ((= l ?u) (reftex-get-bib-field "publisher" entry)) | |
4878 | ((= l ?r) (reftex-get-bib-field "address" entry)) | |
4879 | ((= l ?t) (reftex-get-bib-field "title" entry)) | |
b849548d CD |
4880 | ((= l ?T) (reftex-abbreviate-title |
4881 | (reftex-get-bib-field "title" entry))) | |
396e0b08 KH |
4882 | ((= l ?v) (reftex-get-bib-field "volume" entry)) |
4883 | ((= l ?y) (reftex-get-bib-field "year" entry))))) | |
206c6f82 RS |
4884 | |
4885 | (if (string= rpl "") | |
396e0b08 KH |
4886 | (setq b (match-beginning 2) e (match-end 2)) |
4887 | (setq b (match-beginning 3) e (match-end 3))) | |
206c6f82 RS |
4888 | (setq format (concat (substring format 0 b) rpl (substring format e))))) |
4889 | (while (string-match "%%" format) | |
4890 | (setq format (replace-match "%" t t format))) | |
4891 | (while (string-match "[ ,.;:]*%<" format) | |
4892 | (setq format (replace-match "" t t format))) | |
4893 | format) | |
a7ec1775 | 4894 | |
2faef409 | 4895 | (defun reftex-bibtex-selection-callback (data ignore no-revisit) |
a7ec1775 | 4896 | ;; Callback function to be called from the BibTeX selection, in |
c52bdfca | 4897 | ;; order to display context. This function is relatively slow and not |
2faef409 | 4898 | ;; recommended for follow mode. It works OK for individual lookups. |
a7ec1775 | 4899 | (let ((win (selected-window)) |
2faef409 RS |
4900 | (key (reftex-get-bib-field "&key" data)) |
4901 | bibfile-list item tmp) | |
4902 | ||
4903 | (catch 'exit | |
4904 | (save-excursion | |
4905 | (set-buffer reftex-call-back-to-this-buffer) | |
4906 | (cond | |
4907 | ((assq 'bib (symbol-value reftex-docstruct-symbol)) | |
4908 | (setq bibfile-list (reftex-get-bibfile-list))) | |
4909 | ((setq tmp (assq 'thebib (symbol-value reftex-docstruct-symbol))) | |
4910 | (setq bibfile-list (list (cdr tmp)) | |
4911 | item t)) | |
4912 | (reftex-default-bibliography | |
921759ee | 4913 | (setq bibfile-list (reftex-default-bibliography))) |
2faef409 RS |
4914 | (t (ding) (throw 'exit)))) |
4915 | ||
4916 | (when no-revisit | |
b849548d | 4917 | (setq bibfile-list (reftex-visited-files bibfile-list))) |
2faef409 | 4918 | |
b849548d CD |
4919 | (condition-case nil |
4920 | (reftex-pop-to-bibtex-entry | |
4921 | key bibfile-list (not reftex-keep-temporary-buffers) t item) | |
4922 | (error (ding)))) | |
4923 | ||
a7ec1775 RS |
4924 | (select-window win))) |
4925 | ||
b849548d | 4926 | ;;; ========================================================================= |
a7ec1775 RS |
4927 | ;;; |
4928 | ;;; Here is the routine used for selection | |
4929 | ||
4930 | ;; Marker for return point from recursive edit | |
4931 | (defvar reftex-recursive-edit-marker (make-marker)) | |
4932 | ||
2faef409 RS |
4933 | (defvar reftex-last-data nil) |
4934 | (defvar reftex-last-line nil) | |
4935 | ||
a7ec1775 | 4936 | (defun reftex-check-recursive-edit () |
c52bdfca | 4937 | ;; Check if we are already in a recursive edit. Abort with helpful |
a7ec1775 RS |
4938 | ;; message if so. |
4939 | (if (marker-position reftex-recursive-edit-marker) | |
4940 | (error | |
4941 | (substitute-command-keys | |
921759ee | 4942 | "In unfinished selection process. Finish, or abort with \\[abort-recursive-edit]")))) |
a7ec1775 | 4943 | |
2faef409 RS |
4944 | (defun reftex-select-item (prompt help-string keymap |
4945 | &optional offset | |
be456a1d | 4946 | call-back cb-flag) |
2faef409 RS |
4947 | ;; Select an item, using PROMPT. The function returns a key indicating |
4948 | ;; an exit status, along with a data structure indicating which item was | |
4949 | ;; selected. | |
4950 | ;; HELP-STRING contains help. KEYMAP is a keymap with the available | |
4951 | ;; selection commands. | |
4952 | ;; OFFSET can be a label list item which will be selected at start. | |
4953 | ;; When it is t, point will start out at the beginning of the buffer. | |
4954 | ;; Any other value will cause restart where last selection left off. | |
4955 | ;; When CALL-BACK is given, it is a function which is called with the index | |
4956 | ;; of the element. | |
4957 | ;; CB-FLAG is the initial value of that flag. | |
2faef409 | 4958 | |
f9ad2e24 | 4959 | (let* (ev data last-data (selection-buffer (current-buffer))) |
206c6f82 | 4960 | |
a7ec1775 | 4961 | (setq ev |
29d593f8 | 4962 | (catch 'myexit |
a7ec1775 | 4963 | (save-window-excursion |
a7ec1775 | 4964 | (setq truncate-lines t) |
a7ec1775 | 4965 | |
2faef409 | 4966 | ;; Find a good starting point |
f9ad2e24 CD |
4967 | (reftex-find-start-point |
4968 | (point-min) offset reftex-last-data reftex-last-line) | |
2faef409 | 4969 | (beginning-of-line 1) |
29d593f8 | 4970 | (set (make-local-variable 'reftex-last-follow-point) (point)) |
a7ec1775 | 4971 | |
2faef409 RS |
4972 | (unwind-protect |
4973 | (progn | |
4974 | (use-local-map keymap) | |
29d593f8 KH |
4975 | (add-hook 'pre-command-hook 'reftex-select-pre-command-hook nil t) |
4976 | (add-hook 'post-command-hook 'reftex-select-post-command-hook nil t) | |
4977 | (princ prompt) | |
4978 | (set-marker reftex-recursive-edit-marker (point)) | |
b849548d | 4979 | ;; XEmacs does not run post-command-hook here |
a6611c0d | 4980 | (and (featurep 'xemacs) (run-hooks 'post-command-hook)) |
29d593f8 KH |
4981 | (recursive-edit)) |
4982 | ||
5ff44b47 CD |
4983 | (set-marker reftex-recursive-edit-marker nil) |
4984 | (save-excursion | |
4985 | (set-buffer selection-buffer) | |
4986 | (use-local-map nil) | |
4987 | (remove-hook 'pre-command-hook 'reftex-select-pre-command-hook t) | |
4988 | (remove-hook 'post-command-hook | |
4989 | 'reftex-select-post-command-hook t)))))) | |
2faef409 RS |
4990 | |
4991 | (set (make-local-variable 'reftex-last-line) | |
4992 | (+ (count-lines (point-min) (point)) (if (bolp) 1 0))) | |
4993 | (set (make-local-variable 'reftex-last-data) last-data) | |
29d593f8 | 4994 | (reftex-kill-buffer "*RefTeX Help*") |
f9ad2e24 | 4995 | (setq reftex-callback-fwd (not reftex-callback-fwd)) ;; ;-))) |
a7ec1775 | 4996 | (message "") |
2faef409 RS |
4997 | (list ev data last-data))) |
4998 | ||
4999 | ;; The following variables are all bound dynamically in `reftex-select-item'. | |
5000 | ;; The defvars are here only to silence the byte compiler. | |
5001 | ||
2faef409 RS |
5002 | (defvar found-list) |
5003 | (defvar cb-flag) | |
5004 | (defvar data) | |
29d593f8 KH |
5005 | (defvar prompt) |
5006 | (defvar last-data) | |
2faef409 RS |
5007 | (defvar call-back) |
5008 | (defvar help-string) | |
2faef409 | 5009 | (defvar varioref) |
2faef409 RS |
5010 | |
5011 | ;; The selection commands | |
5012 | ||
29d593f8 KH |
5013 | (defun reftex-select-pre-command-hook () |
5014 | (reftex-unhighlight 1) | |
5015 | (reftex-unhighlight 0)) | |
5016 | ||
5017 | (defun reftex-select-post-command-hook () | |
5018 | (let (b e) | |
921759ee | 5019 | (setq data (get-text-property (point) :data)) |
29d593f8 KH |
5020 | (setq last-data (or data last-data)) |
5021 | ||
5022 | (when (and data cb-flag | |
5023 | (not (equal reftex-last-follow-point (point)))) | |
5024 | (setq reftex-last-follow-point (point)) | |
f9ad2e24 | 5025 | (funcall call-back data reftex-callback-fwd |
29d593f8 KH |
5026 | (not reftex-revisit-to-follow))) |
5027 | (if data | |
5028 | (setq b (or (previous-single-property-change | |
921759ee | 5029 | (1+ (point)) :data) |
29d593f8 KH |
5030 | (point-min)) |
5031 | e (or (next-single-property-change | |
921759ee | 5032 | (point) :data) |
29d593f8 KH |
5033 | (point-max))) |
5034 | (setq b (point) e (point))) | |
5035 | (and (memq reftex-highlight-selection '(cursor both)) | |
5036 | (reftex-highlight 1 b e)) | |
5037 | (if (or (not (pos-visible-in-window-p b)) | |
5038 | (not (pos-visible-in-window-p e))) | |
a6611c0d | 5039 | (recenter '(4))) |
b849548d | 5040 | (unless (current-message) |
29d593f8 KH |
5041 | (princ prompt)))) |
5042 | ||
5043 | (defun reftex-select-next (&optional arg) | |
b849548d | 5044 | "Move to next selectable item." |
29d593f8 | 5045 | (interactive "p") |
f9ad2e24 | 5046 | (setq reftex-callback-fwd t) |
2faef409 | 5047 | (or (eobp) (forward-char 1)) |
29d593f8 | 5048 | (re-search-forward "^[^. \t\n\r]" nil t arg) |
2faef409 | 5049 | (beginning-of-line 1)) |
29d593f8 | 5050 | (defun reftex-select-previous (&optional arg) |
b849548d | 5051 | "Move to previous selectable item." |
29d593f8 | 5052 | (interactive "p") |
f9ad2e24 | 5053 | (setq reftex-callback-fwd nil) |
29d593f8 KH |
5054 | (re-search-backward "^[^. \t\n\r]" nil t arg)) |
5055 | (defun reftex-select-next-heading (&optional arg) | |
b849548d | 5056 | "Move to next table of contentes line." |
29d593f8 | 5057 | (interactive "p") |
2faef409 | 5058 | (end-of-line) |
29d593f8 | 5059 | (re-search-forward "^ " nil t arg) |
2faef409 | 5060 | (beginning-of-line)) |
29d593f8 | 5061 | (defun reftex-select-previous-heading (&optional arg) |
b849548d | 5062 | "Move to previous table of contentes line." |
29d593f8 KH |
5063 | (interactive "p") |
5064 | (re-search-backward "^ " nil t arg)) | |
2faef409 | 5065 | (defun reftex-select-quit () |
b849548d | 5066 | "Abort selection process." |
2faef409 | 5067 | (interactive) |
29d593f8 KH |
5068 | (throw 'myexit nil)) |
5069 | (defun reftex-select-keyboard-quit () | |
b849548d | 5070 | "Abort selection process." |
29d593f8 KH |
5071 | (interactive) |
5072 | (throw 'exit t)) | |
2faef409 | 5073 | (defun reftex-select-jump-to-previous () |
b849548d | 5074 | "Jump back to where previous selection process left off." |
2faef409 RS |
5075 | (interactive) |
5076 | (let (pos) | |
5077 | (cond | |
5078 | ((and (local-variable-p 'reftex-last-data (current-buffer)) | |
5079 | reftex-last-data | |
5080 | (setq pos (text-property-any (point-min) (point-max) | |
921759ee | 5081 | :data reftex-last-data))) |
2faef409 RS |
5082 | (goto-char pos)) |
5083 | ((and (local-variable-p 'reftex-last-line (current-buffer)) | |
5084 | (integerp reftex-last-line)) | |
5085 | (goto-line reftex-last-line)) | |
5086 | (t (ding))))) | |
5087 | (defun reftex-select-toggle-follow () | |
b849548d | 5088 | "Toggle follow mode: Other window follows with full context." |
2faef409 | 5089 | (interactive) |
b849548d | 5090 | (setq reftex-last-follow-point -1) |
2faef409 RS |
5091 | (setq cb-flag (not cb-flag))) |
5092 | (defun reftex-select-toggle-varioref () | |
b849548d | 5093 | "Toggle the macro used for referencing the label between \\ref and \\vref." |
2faef409 RS |
5094 | (interactive) |
5095 | (if (string= varioref "\\ref") | |
5096 | (setq varioref "\\vref") | |
5097 | (setq varioref "\\ref")) | |
5098 | (force-mode-line-update)) | |
29d593f8 | 5099 | (defun reftex-select-show-insertion-point () |
b849548d | 5100 | "Show the point from where selection was started in another window." |
29d593f8 KH |
5101 | (interactive) |
5102 | (let ((this-window (selected-window))) | |
5103 | (unwind-protect | |
5104 | (progn | |
5105 | (switch-to-buffer-other-window | |
5106 | (marker-buffer reftex-select-return-marker)) | |
5107 | (goto-char (marker-position reftex-select-return-marker)) | |
a6611c0d | 5108 | (recenter '(4))) |
29d593f8 | 5109 | (select-window this-window)))) |
2faef409 | 5110 | (defun reftex-select-callback () |
b849548d | 5111 | "Show full context in another window." |
2faef409 | 5112 | (interactive) |
f9ad2e24 | 5113 | (if data (funcall call-back data reftex-callback-fwd nil) (ding))) |
2faef409 | 5114 | (defun reftex-select-accept () |
b849548d | 5115 | "Accept the currently selected item." |
2faef409 | 5116 | (interactive) |
29d593f8 KH |
5117 | (throw 'myexit 'return)) |
5118 | (defun reftex-select-mouse-accept (ev) | |
b849548d | 5119 | "Accept the item at the mouse click." |
29d593f8 KH |
5120 | (interactive "e") |
5121 | (mouse-set-point ev) | |
921759ee | 5122 | (setq data (get-text-property (point) :data)) |
29d593f8 KH |
5123 | (setq last-data (or data last-data)) |
5124 | (throw 'myexit 'return)) | |
2faef409 | 5125 | (defun reftex-select-read-label () |
b849548d | 5126 | "Use minibuffer to read a label to reference, with completion." |
2faef409 RS |
5127 | (interactive) |
5128 | (let ((label (completing-read | |
5129 | "Label: " (symbol-value reftex-docstruct-symbol) | |
5130 | nil nil reftex-prefix))) | |
5131 | (unless (or (equal label "") (equal label reftex-prefix)) | |
29d593f8 | 5132 | (throw 'myexit label)))) |
2faef409 | 5133 | (defun reftex-select-read-cite () |
b849548d | 5134 | "Use minibuffer to read a citation key with completion." |
2faef409 | 5135 | (interactive) |
b849548d CD |
5136 | (let* ((key (completing-read "Citation key: " found-list)) |
5137 | (entry (assoc key found-list))) | |
5138 | (cond | |
5139 | ((or (null key) (equal key ""))) | |
5140 | (entry | |
5141 | (setq data entry) | |
5142 | (setq last-data data) | |
5143 | (throw 'myexit 'return)) | |
5144 | (t (throw 'myexit key))))) | |
2faef409 | 5145 | (defun reftex-select-help () |
b849548d | 5146 | "Display a summary of the special key bindings." |
2faef409 RS |
5147 | (interactive) |
5148 | (with-output-to-temp-buffer "*RefTeX Help*" | |
5149 | (princ help-string)) | |
29d593f8 | 5150 | (reftex-enlarge-to-fit "*RefTeX Help*" t)) |
a7ec1775 | 5151 | |
b849548d | 5152 | ;;; ========================================================================= |
a7ec1775 RS |
5153 | ;;; |
5154 | ;;; View cross references | |
5155 | ||
921759ee CD |
5156 | (defun reftex-view-crossref (&optional arg auto-how) |
5157 | "View cross reference of macro at point. Point must be on the KEY | |
5158 | argument. When at at `\ref' macro, show corresponding `\label' | |
5159 | definition, also in external documents (`xr'). When on a label, show | |
5160 | a locations where KEY is referenced. Subsequent calls find additional | |
5161 | locations. When on a `\cite', show the associated `\bibitem' macro or | |
5162 | the BibTeX database entry. When on a `\bibitem', show a `\cite' macro | |
5163 | which uses this KEY. When on an `\index', show other locations marked | |
5164 | by the same index entry. | |
5165 | To define additional cross referencing items, use the option | |
5166 | `reftex-view-crossref-extra'. See also `reftex-view-crossref-from-bibtex'. | |
2faef409 | 5167 | With one or two C-u prefixes, enforce rescanning of the document. |
a6611c0d | 5168 | With argument 2, select the window showing the cross reference. |
921759ee CD |
5169 | AUTO-HOW is only for the automatic crossref display and is handed through |
5170 | to the functions `reftex-view-cr-cite' and `reftex-view-cr-ref'." | |
a7ec1775 RS |
5171 | |
5172 | (interactive "P") | |
a7ec1775 | 5173 | ;; See where we are. |
a6611c0d | 5174 | (let* ((macro (car (reftex-what-macro 1))) |
921759ee CD |
5175 | (key (reftex-this-word "^{}%\n\r,")) |
5176 | dw) | |
a6611c0d CD |
5177 | |
5178 | (if (or (null macro) (reftex-in-comment)) | |
921759ee CD |
5179 | (error "Not on a crossref macro argument")) |
5180 | ||
5181 | (setq reftex-call-back-to-this-buffer (current-buffer)) | |
a7ec1775 | 5182 | |
a6611c0d | 5183 | (cond |
921759ee CD |
5184 | ((string-match "\\`\\\\cite\\|cite\\*?\\'" macro) |
5185 | ;; A citation macro: search for bibitems or BibTeX entries | |
5186 | (setq dw (reftex-view-cr-cite arg key auto-how))) | |
5187 | ((string-match "\\`\\\\ref\\|ref\\*?\\'" macro) | |
5188 | ;; A reference macro: search for labels | |
5189 | (setq dw (reftex-view-cr-ref arg key auto-how))) | |
5190 | (auto-how nil) ;; No further action for automatic display (speed) | |
5191 | ((or (equal macro "\\label") | |
5192 | (member macro reftex-macros-with-labels)) | |
5193 | ;; A label macro: search for reference macros | |
5194 | (reftex-access-scan-info arg) | |
5195 | (setq dw (reftex-view-regexp-match | |
5196 | (format reftex-find-reference-format (regexp-quote key)) | |
5197 | 3 nil nil))) | |
5198 | ((equal macro "\\bibitem") | |
5199 | ;; A bibitem macro: search for citations | |
5200 | (reftex-access-scan-info arg) | |
5201 | (setq dw (reftex-view-regexp-match | |
5202 | (format reftex-find-citation-regexp-format (regexp-quote key)) | |
5203 | 3 nil nil))) | |
a6611c0d | 5204 | (t |
921759ee CD |
5205 | (reftex-access-scan-info arg) |
5206 | (catch 'exit | |
5207 | (let ((list reftex-view-crossref-extra) | |
5208 | entry mre action group) | |
5209 | (while (setq entry (pop list)) | |
5210 | (setq mre (car entry) | |
5211 | action (nth 1 entry) | |
5212 | group (nth 2 entry)) | |
5213 | (when (string-match mre macro) | |
5214 | (setq dw (reftex-view-regexp-match | |
5215 | (format action key) group nil nil)) | |
5216 | (throw 'exit t)))) | |
5217 | (error "Not on a crossref macro argument")))) | |
5218 | (if (and (eq arg 2) (windowp dw)) (select-window dw)))) | |
a6611c0d CD |
5219 | |
5220 | (defun reftex-view-cr-cite (arg key how) | |
5221 | ;; View crossreference of a ref cite. HOW can have the values | |
5222 | ;; nil: Show in another window. | |
5223 | ;; echo: Show one-line info in echo area. | |
5224 | ;; tmp-window: Show in small window and arrange for window to disappear. | |
a7ec1775 | 5225 | |
a6611c0d CD |
5226 | ;; Ensure access to scanning info |
5227 | (reftex-access-scan-info (or arg current-prefix-arg)) | |
5228 | ||
921759ee CD |
5229 | (if (eq how 'tmp-window) |
5230 | ;; Remember the window configuration | |
5231 | (put 'reftex-auto-view-crossref 'last-window-conf | |
5232 | (current-window-configuration))) | |
5233 | ||
a6611c0d CD |
5234 | (let (files size item (pos (point)) (win (selected-window)) pop-win) |
5235 | ;; Find the citation mode and the file list | |
5236 | (cond | |
5237 | ((assq 'bib (symbol-value reftex-docstruct-symbol)) | |
5238 | (setq item nil | |
5239 | files (reftex-get-bibfile-list))) | |
5240 | ((assq 'thebib (symbol-value reftex-docstruct-symbol)) | |
5241 | (setq item t | |
5242 | files (list (cdr (assq 'thebib | |
5243 | (symbol-value reftex-docstruct-symbol)))))) | |
5244 | (reftex-default-bibliography | |
5245 | (setq item nil | |
921759ee | 5246 | files (reftex-default-bibliography))) |
a6611c0d CD |
5247 | (how) ;; don't throw for special display |
5248 | (t (error "Cannot display crossref"))) | |
5249 | ||
5250 | (if (eq how 'echo) | |
5251 | ;; Display in Echo area | |
5252 | (reftex-echo-cite key files item) | |
5253 | ;; Display in a window | |
5254 | (if (not (eq how 'tmp-window)) | |
5255 | ;; Normal display | |
5256 | (reftex-pop-to-bibtex-entry key files nil t item) | |
5257 | ;; A temporary window | |
5258 | (condition-case nil | |
5259 | (reftex-pop-to-bibtex-entry key files nil t item) | |
5260 | (error (goto-char pos) | |
5261 | (message "cite: no such citation key %s" key) | |
5262 | (error ""))) | |
5263 | ;; Resize the window | |
5264 | (setq size (max 1 (count-lines (point) | |
5265 | (reftex-end-of-bib-entry item)))) | |
5266 | (let ((window-min-height 2)) | |
5267 | (shrink-window (1- (- (window-height) size))) | |
5268 | (recenter 0)) | |
5269 | ;; Arrange restoration | |
5270 | (add-hook 'pre-command-hook 'reftex-restore-window-conf)) | |
5271 | ||
5272 | ;; Normal display in other window | |
b849548d | 5273 | (add-hook 'pre-command-hook 'reftex-highlight-shall-die) |
a6611c0d CD |
5274 | (setq pop-win (selected-window)) |
5275 | (select-window win) | |
5276 | (goto-char pos) | |
5277 | (when (equal arg 2) | |
5278 | (select-window pop-win))))) | |
5279 | ||
5280 | (defun reftex-view-cr-ref (arg label how) | |
5281 | ;; View crossreference of a ref macro. HOW can have the values | |
5282 | ;; nil: Show in another window. | |
5283 | ;; echo: Show one-line info in echo area. | |
5284 | ;; tmp-window: Show in small window and arrange for window to disappear. | |
5285 | ||
5286 | ;; Ensure access to scanning info | |
5287 | (reftex-access-scan-info (or arg current-prefix-arg)) | |
5288 | ||
921759ee CD |
5289 | (if (eq how 'tmp-window) |
5290 | ;; Remember the window configuration | |
5291 | (put 'reftex-auto-view-crossref 'last-window-conf | |
5292 | (current-window-configuration))) | |
5293 | ||
a6611c0d CD |
5294 | (let* ((xr-data (assoc 'xr (symbol-value reftex-docstruct-symbol))) |
5295 | (xr-re (nth 2 xr-data)) | |
5296 | (entry (assoc label (symbol-value reftex-docstruct-symbol))) | |
5297 | (win (selected-window)) pop-win (pos (point))) | |
f9ad2e24 | 5298 | |
a6611c0d CD |
5299 | (if (and (not entry) (stringp label) xr-re (string-match xr-re label)) |
5300 | ;; Label is defined in external document | |
5301 | (save-excursion | |
5302 | (save-match-data | |
5303 | (set-buffer | |
5304 | (or (reftex-get-file-buffer-force | |
5305 | (cdr (assoc (match-string 1 label) (nth 1 | |
5306 | xr-data)))) | |
5307 | (error "Problem with external label %s" label)))) | |
5308 | (setq label (substring label (match-end 1))) | |
5309 | (reftex-access-scan-info) | |
5310 | (setq entry | |
5311 | (assoc label (symbol-value reftex-docstruct-symbol))))) | |
5312 | (if (eq how 'echo) | |
921759ee | 5313 | ;; Display in echo area |
a6611c0d | 5314 | (reftex-echo-ref label entry (symbol-value reftex-docstruct-symbol)) |
f9ad2e24 CD |
5315 | (let ((window-conf (current-window-configuration))) |
5316 | (condition-case nil | |
5317 | (reftex-show-label-location entry t nil t t) | |
5318 | (error (set-window-configuration window-conf) | |
5319 | (message "ref: Label %s not found" label) | |
5320 | (error "ref: Label %s not found" label)))) ;; 2nd is line OK | |
a6611c0d CD |
5321 | (add-hook 'pre-command-hook 'reftex-highlight-shall-die) |
5322 | ||
5323 | (when (eq how 'tmp-window) | |
5324 | ;; Resize window and arrange restauration | |
5325 | (shrink-window (1- (- (window-height) 9))) | |
5326 | (recenter '(4)) | |
5327 | (add-hook 'pre-command-hook 'reftex-restore-window-conf)) | |
5328 | (setq pop-win (selected-window)) | |
5329 | (select-window win) | |
5330 | (goto-char pos) | |
5331 | (when (equal arg 2) | |
5332 | (select-window pop-win))))) | |
a7ec1775 RS |
5333 | |
5334 | (defun reftex-mouse-view-crossref (ev) | |
fba437e6 RS |
5335 | "View cross reference of \\ref or \\cite macro where you click. |
5336 | If the macro at point is a \\ref, show the corresponding label definition. | |
5337 | If it is a \\cite, show the BibTeX database entry. | |
a7ec1775 | 5338 | If there is no such macro at point, search forward to find one. |
a7ec1775 RS |
5339 | With argument, actually select the window showing the cross reference." |
5340 | (interactive "e") | |
5341 | (mouse-set-point ev) | |
5342 | (reftex-view-crossref current-prefix-arg)) | |
5343 | ||
b849548d CD |
5344 | (defvar reftex-auto-view-crossref-timer nil |
5345 | "The timer used for auto-view-crossref.") | |
5346 | ||
5347 | (defun reftex-view-crossref-when-idle () | |
a6611c0d | 5348 | ;; Display info about crossref at point in echo area or a window. |
b849548d CD |
5349 | ;; This function was desigend to work with an idle timer. |
5350 | ;; We try to get out of here as quickly as possible if the call is useless. | |
5351 | (and reftex-mode | |
a6611c0d CD |
5352 | ;; Make sure message area is free if we need it. |
5353 | (or (eq reftex-auto-view-crossref 'window) (not (current-message))) | |
5354 | ;; Make sure we are not already displaying this one | |
5355 | (not (memq last-command '(reftex-view-crossref | |
5356 | reftex-mouse-view-crossref))) | |
f9ad2e24 CD |
5357 | ;; Quick precheck if this might be a relevant spot |
5358 | ;; FIXME: Can fail with backslash in comment | |
5359 | (save-excursion | |
5360 | (search-backward "\\" nil t) | |
5361 | (looking-at "\\\\[a-zA-Z]*\\(cite\\|ref\\)")) | |
5362 | ||
b849548d CD |
5363 | (condition-case nil |
5364 | (let ((current-prefix-arg nil)) | |
a6611c0d CD |
5365 | (cond |
5366 | ((eq reftex-auto-view-crossref t) | |
5367 | (reftex-view-crossref -1 'echo)) | |
5368 | ((eq reftex-auto-view-crossref 'window) | |
5369 | (reftex-view-crossref -1 'tmp-window)) | |
5370 | (t nil))) | |
5371 | (error nil)))) | |
5372 | ||
5373 | (defun reftex-restore-window-conf () | |
5374 | (set-window-configuration (get 'reftex-auto-view-crossref 'last-window-conf)) | |
5375 | (put 'reftex-auto-view-crossref 'last-window-conf nil) | |
5376 | (remove-hook 'pre-command-hook 'reftex-restore-window-conf)) | |
b849548d CD |
5377 | |
5378 | (defun reftex-echo-ref (label entry docstruct) | |
5379 | ;; Display crossref info in echo area. | |
5380 | (cond | |
5381 | ((null docstruct) | |
5382 | (message (substitute-command-keys (format reftex-no-info-message "ref")))) | |
5383 | ((null entry) | |
5384 | (message "ref: unknown label: %s" label)) | |
5385 | (t | |
5386 | (when (stringp (nth 2 entry)) | |
5387 | (message "ref(%s): %s" (nth 1 entry) (nth 2 entry))) | |
5388 | (let ((buf (get-buffer " *Echo Area*"))) | |
5389 | (when buf | |
5390 | (save-excursion | |
5391 | (set-buffer buf) | |
5392 | (run-hooks 'reftex-display-copied-context-hook))))))) | |
5393 | ||
a6611c0d | 5394 | (defun reftex-echo-cite (key files item) |
b849548d | 5395 | ;; Display citation info in echo area. |
a6611c0d | 5396 | (let* ((cache (assq 'bibview-cache (symbol-value reftex-docstruct-symbol))) |
b849548d | 5397 | (cache-entry (assoc key (cdr cache))) |
a6611c0d | 5398 | entry string buf (all-files files)) |
b849548d CD |
5399 | |
5400 | (if (and reftex-cache-cite-echo cache-entry) | |
5401 | ;; We can just use the cache | |
5402 | (setq string (cdr cache-entry)) | |
5403 | ||
5404 | ;; Need to look in the database | |
5405 | (unless reftex-revisit-to-echo | |
a6611c0d | 5406 | (setq files (reftex-visited-files files))) |
b849548d CD |
5407 | |
5408 | (setq entry | |
5409 | (condition-case nil | |
5410 | (save-excursion | |
5411 | (reftex-pop-to-bibtex-entry key files nil nil item t)) | |
5412 | (error | |
a6611c0d | 5413 | (if (and files (= (length all-files) (length files))) |
b849548d CD |
5414 | (message "cite: no such database entry: %s" key) |
5415 | (message (substitute-command-keys | |
5416 | (format reftex-no-info-message "cite")))) | |
5417 | nil))) | |
5418 | (when entry | |
a6611c0d CD |
5419 | (if item |
5420 | (setq string (reftex-nicify-text entry)) | |
5421 | (setq string (reftex-make-cite-echo-string | |
5422 | (reftex-parse-bibtex-entry entry) | |
5423 | reftex-docstruct-symbol))))) | |
b849548d CD |
5424 | (unless (or (null string) (equal string "")) |
5425 | (message "cite: %s" string)) | |
5426 | (when (setq buf (get-buffer " *Echo Area*")) | |
5427 | (save-excursion | |
5428 | (set-buffer buf) | |
5429 | (run-hooks 'reftex-display-copied-context-hook))))) | |
5430 | ||
5431 | (defun reftex-make-cite-echo-string (entry docstruct-symbol) | |
5432 | ;; Format a bibtex entry for the echo area and cache the result. | |
5433 | (let* ((key (reftex-get-bib-field "&key" entry)) | |
5434 | (string | |
5435 | (let* ((reftex-cite-punctuation '(" " " & " " etal."))) | |
5436 | (reftex-format-citation entry reftex-cite-view-format))) | |
5437 | (cache (assq 'bibview-cache (symbol-value docstruct-symbol))) | |
5438 | (cache-entry (assoc key (cdr cache)))) | |
5439 | (unless cache | |
5440 | ;; This docstruct has no cache - make one. | |
5441 | (set docstruct-symbol (cons (cons 'bibview-cache nil) | |
5442 | (symbol-value docstruct-symbol)))) | |
5443 | (when reftex-cache-cite-echo | |
5444 | (setq key (copy-sequence key)) | |
5445 | (set-text-properties 0 (length key) nil key) | |
5446 | (set-text-properties 0 (length string) nil string) | |
5447 | (if cache-entry | |
5448 | (unless (string= (cdr cache-entry) string) | |
5449 | (setcdr cache-entry string) | |
5450 | (put reftex-docstruct-symbol 'modified t)) | |
5451 | (push (cons key string) (cdr cache)) | |
5452 | (put reftex-docstruct-symbol 'modified t))) | |
5453 | string)) | |
5454 | ||
5455 | (defvar reftex-use-itimer-in-xemacs nil | |
5456 | "*Non-nil means use the idle timers in XEmacs for crossref display. | |
5457 | Currently, idle timer restart is broken and we use the post-command-hook.") | |
5458 | ||
5459 | (defun reftex-toggle-auto-view-crossref () | |
5460 | "Toggle the automatic display of crossref information in the echo area. | |
5461 | When active, leaving point idle in the argument of a \\ref or \\cite macro | |
5462 | will display info in the echo area." | |
5463 | (interactive) | |
5464 | (if reftex-auto-view-crossref-timer | |
5465 | (progn | |
5466 | (if (featurep 'xemacs) | |
5467 | (if reftex-use-itimer-in-xemacs | |
5468 | (delete-itimer reftex-auto-view-crossref-timer) | |
5469 | (remove-hook 'post-command-hook 'reftex-start-itimer-once)) | |
5470 | (cancel-timer reftex-auto-view-crossref-timer)) | |
5471 | (setq reftex-auto-view-crossref-timer nil) | |
5472 | (message "Automatic display of crossref information was turned off")) | |
5473 | (setq reftex-auto-view-crossref-timer | |
5474 | (if (featurep 'xemacs) | |
5475 | (if reftex-use-itimer-in-xemacs | |
5476 | (start-itimer "RefTeX Idle Timer" | |
5477 | 'reftex-view-crossref-when-idle | |
5478 | reftex-idle-time reftex-idle-time t) | |
5479 | (add-hook 'post-command-hook 'reftex-start-itimer-once) | |
f9ad2e24 | 5480 | t) |
b849548d CD |
5481 | (run-with-idle-timer |
5482 | reftex-idle-time t 'reftex-view-crossref-when-idle))) | |
51d628c8 CD |
5483 | (unless reftex-auto-view-crossref |
5484 | (setq reftex-auto-view-crossref t)) | |
b849548d CD |
5485 | (message "Automatic display of crossref information was turned on"))) |
5486 | ||
5487 | (defun reftex-start-itimer-once () | |
5488 | (and reftex-mode | |
5489 | (not (itimer-live-p reftex-auto-view-crossref-timer)) | |
5490 | (setq reftex-auto-view-crossref-timer | |
5491 | (start-itimer "RefTeX Idle Timer" | |
5492 | 'reftex-view-crossref-when-idle | |
5493 | reftex-idle-time nil t)))) | |
5494 | ||
921759ee CD |
5495 | (defun reftex-view-crossref-from-bibtex (&optional arg) |
5496 | "View location in a LaTeX document which cites the BibTeX entry at point. | |
5497 | Since BibTeX files can be used by many LaTeX documents, this function | |
5498 | promps upon first use for a buffer in RefTeX mode. To reset this | |
5499 | link to a document, call the function with with a prefix arg. | |
5500 | Calling this function several times find successive citation locations." | |
5501 | (interactive "P") | |
5502 | (when arg | |
5503 | ;; Break connection to reference buffer | |
5504 | (remprop 'reftex-bibtex-view-cite-locations :ref-buffer)) | |
5505 | (let ((ref-buffer (get 'reftex-bibtex-view-cite-locations :ref-buffer))) | |
5506 | ;; Establish connection to reference buffer | |
5507 | (unless ref-buffer | |
5508 | (setq ref-buffer | |
5509 | (save-excursion | |
5510 | (completing-read | |
5511 | "Reference buffer: " | |
5512 | (delq nil | |
5513 | (mapcar | |
5514 | (lambda (b) | |
5515 | (set-buffer b) | |
5516 | (if reftex-mode (list (buffer-name b)) nil)) | |
5517 | (buffer-list))) | |
5518 | nil t))) | |
5519 | (put 'reftex-bibtex-view-cite-locations :ref-buffer ref-buffer)) | |
5520 | ;; Search for citations | |
5521 | (bibtex-beginning-of-entry) | |
5522 | (if (looking-at | |
5523 | "@[a-zA-Z]+[ \t\n\r]*[{(][ \t\n\r]*\\([^, \t\r\n}]+\\)") | |
5524 | (progn | |
5525 | (goto-char (match-beginning 1)) | |
5526 | (reftex-view-regexp-match | |
5527 | (format reftex-find-citation-regexp-format | |
5528 | (regexp-quote (match-string 1))) | |
5529 | 3 arg ref-buffer)) | |
5530 | (error "Cannot find citation key in BibTeX entry")))) | |
5531 | ||
5532 | (defun reftex-view-regexp-match (re &optional highlight-group new ref-buffer) | |
5533 | ;; Search for RE in current document or in the document of REF-BUFFER. | |
5534 | ;; Continue the search, if the same re was searched last. | |
5535 | ;; Highlight the group HIGHLIGHT-GROUP of the match. | |
5536 | ;; When NEW is non-nil, start a new search regardless. | |
5537 | ;; Match point is displayed in another window. | |
5538 | ;; Upon success, returns the window which displays the match. | |
5539 | ||
5540 | ;;; Decide if new search or continued search | |
5541 | (let* ((oldprop (get 'reftex-view-regexp-match :props)) | |
5542 | (newprop (list (current-buffer) re)) | |
5543 | (cont (and (not new) (equal oldprop newprop))) | |
5544 | (cnt (if cont (get 'reftex-view-regexp-match :cnt) 0)) | |
5545 | (current-window (selected-window)) | |
5546 | (window-conf (current-window-configuration)) | |
5547 | match pop-window) | |
5548 | (switch-to-buffer-other-window (or ref-buffer (current-buffer))) | |
5549 | ;; Search | |
5550 | (condition-case nil | |
5551 | (if cont | |
5552 | (setq match (reftex-global-search-continue)) | |
5553 | (reftex-access-scan-info) | |
5554 | (setq match (reftex-global-search re (reftex-all-document-files)))) | |
5555 | (error nil)) | |
5556 | ;; Evaluate the match. | |
5557 | (if match | |
5558 | (progn | |
5559 | (put 'reftex-view-regexp-match :props newprop) | |
5560 | (put 'reftex-view-regexp-match :cnt (incf cnt)) | |
5561 | (reftex-highlight 0 (match-beginning highlight-group) | |
5562 | (match-end highlight-group)) | |
5563 | (add-hook 'pre-command-hook 'reftex-highlight-shall-die) | |
5564 | (setq pop-window (selected-window))) | |
5565 | (remprop 'reftex-view-regexp-match :props) | |
5566 | (or cont (set-window-configuration window-conf))) | |
5567 | (select-window current-window) | |
5568 | (if match | |
5569 | (progn | |
5570 | (message "Match Nr. %s" cnt) | |
5571 | pop-window) | |
5572 | (if cont | |
5573 | (error "No further matches (total number of matches: %d)" cnt) | |
5574 | (error "No matches"))))) | |
5575 | ||
5576 | (defvar reftex-global-search-marker (make-marker)) | |
5577 | (defun reftex-global-search (regexp file-list) | |
5578 | ;; Start a search for REGEXP in all files of FILE-LIST | |
5579 | (put 'reftex-global-search :file-list file-list) | |
5580 | (put 'reftex-global-search :regexp regexp) | |
5581 | (move-marker reftex-global-search-marker nil) | |
5582 | (reftex-global-search-continue)) | |
5583 | ||
5584 | (defun reftex-global-search-continue () | |
5585 | ;; Continue a global search started with `reftex-global-search' | |
5586 | (unless (get 'reftex-global-search :file-list) | |
5587 | (error "No global search to continue")) | |
5588 | (let* ((file-list (get 'reftex-global-search :file-list)) | |
5589 | (regexp (get 'reftex-global-search :regexp)) | |
5590 | (buf (or (marker-buffer reftex-global-search-marker) | |
5591 | (reftex-get-file-buffer-force (car file-list)))) | |
5592 | (pos (or (marker-position reftex-global-search-marker) 1)) | |
5593 | file) | |
5594 | ;; Take up starting position | |
5595 | (unless buf (error "No such buffer %s" buf)) | |
5596 | (switch-to-buffer buf) | |
5597 | (widen) | |
5598 | (goto-char pos) | |
5599 | ;; Search and switch file if necessary | |
5600 | (if (catch 'exit | |
5601 | (while t | |
5602 | (when (re-search-forward regexp nil t) | |
5603 | (move-marker reftex-global-search-marker (point)) | |
5604 | (throw 'exit t)) | |
5605 | ;; No match - goto next file | |
5606 | (pop file-list) | |
5607 | (or file-list (throw 'exit nil)) | |
5608 | (setq file (car file-list) | |
5609 | buf (reftex-get-file-buffer-force file)) | |
5610 | (unless buf (error "Cannot access file %s" file)) | |
5611 | (put 'reftex-global-search :file-list file-list) | |
5612 | (switch-to-buffer buf) | |
5613 | (widen) | |
5614 | (goto-char 1))) | |
5615 | t | |
5616 | (move-marker reftex-global-search-marker nil) | |
5617 | (error "All files processed")))) | |
5618 | ||
b849548d | 5619 | ;;; ========================================================================= |
a7ec1775 RS |
5620 | ;;; |
5621 | ;;; Functions that check out the surroundings | |
5622 | ||
5623 | (defun reftex-what-macro (which &optional bound) | |
5624 | ;; Find out if point is within the arguments of any TeX-macro. | |
c52bdfca | 5625 | ;; The return value is either ("\\macro" . (point)) or a list of them. |
a7ec1775 RS |
5626 | |
5627 | ;; If WHICH is nil, immediately return nil. | |
b849548d | 5628 | ;; If WHICH is 1, return innermost enclosing macro. |
a7ec1775 RS |
5629 | ;; If WHICH is t, return list of all macros enclosing point. |
5630 | ;; If WHICH is a list of macros, look only for those macros and return the | |
5631 | ;; name of the first macro in this list found to enclose point. | |
5632 | ;; If the optional BOUND is an integer, bound backwards directed | |
c52bdfca | 5633 | ;; searches to this point. If it is nil, limit to nearest \section - |
a7ec1775 RS |
5634 | ;; like statement. |
5635 | ||
5636 | ;; This function is pretty stable, but can be fooled if the text contains | |
c52bdfca RS |
5637 | ;; things like \macro{aa}{bb} where \macro is defined to take only one |
5638 | ;; argument. As RefTeX cannot know this, the string "bb" would still be | |
5639 | ;; considered an argument of macro \macro. | |
a7ec1775 | 5640 | |
b849548d | 5641 | (unless reftex-section-regexp (reftex-compile-variables)) |
a7ec1775 RS |
5642 | (catch 'exit |
5643 | (if (null which) (throw 'exit nil)) | |
5644 | (let ((bound (or bound (save-excursion (re-search-backward | |
5645 | reftex-section-regexp nil 1) | |
5646 | (point)))) | |
396e0b08 | 5647 | pos cmd-list cmd cnt cnt-opt entry) |
a7ec1775 RS |
5648 | (save-restriction |
5649 | (save-excursion | |
5650 | (narrow-to-region (max 1 bound) (point-max)) | |
5651 | ;; move back out of the current parenthesis | |
5652 | (while (condition-case nil | |
5653 | (progn (up-list -1) t) | |
5654 | (error nil)) | |
396e0b08 | 5655 | (setq cnt 1 cnt-opt 0) |
a7ec1775 | 5656 | ;; move back over any touching sexps |
396e0b08 KH |
5657 | (while (and (reftex-move-to-previous-arg bound) |
5658 | (condition-case nil | |
5659 | (progn (backward-sexp) t) | |
5660 | (error nil))) | |
5661 | (if (eq (following-char) ?\[) (incf cnt-opt)) | |
5662 | (incf cnt)) | |
a7ec1775 | 5663 | (setq pos (point)) |
396e0b08 KH |
5664 | (when (and (or (= (following-char) ?\[) |
5665 | (= (following-char) ?\{)) | |
5666 | (re-search-backward "\\\\[*a-zA-Z]+\\=" nil t)) | |
5667 | (setq cmd (reftex-match-string 0)) | |
5668 | (when (looking-at "\\\\begin{[^}]*}") | |
5669 | (setq cmd (reftex-match-string 0) | |
5670 | cnt (1- cnt))) | |
5671 | ;; This does ignore optional arguments. Very hard to fix. | |
5672 | (when (setq entry (assoc cmd reftex-env-or-mac-alist)) | |
5673 | (if (> cnt (or (nth 4 entry) 100)) | |
5674 | (setq cmd nil))) | |
5675 | (cond | |
5676 | ((null cmd)) | |
5677 | ((eq t which) | |
5678 | (push (cons cmd (point)) cmd-list)) | |
b849548d | 5679 | ((or (eq 1 which) (member cmd which)) |
396e0b08 | 5680 | (throw 'exit (cons cmd (point)))))) |
a7ec1775 RS |
5681 | (goto-char pos))) |
5682 | (nreverse cmd-list))))) | |
5683 | ||
5684 | (defun reftex-what-environment (which &optional bound) | |
5685 | ;; Find out if point is inside a LaTeX environment. | |
c52bdfca | 5686 | ;; The return value is (e.g.) either ("equation" . (point)) or a list of |
a7ec1775 RS |
5687 | ;; them. |
5688 | ||
5689 | ;; If WHICH is nil, immediately return nil. | |
b849548d | 5690 | ;; If WHICH is 1, return innermost enclosing environment. |
a7ec1775 RS |
5691 | ;; If WHICH is t, return list of all environments enclosing point. |
5692 | ;; If WHICH is a list of environments, look only for those environments and | |
5693 | ;; return the name of the first environment in this list found to enclose | |
5694 | ;; point. | |
5695 | ||
b849548d CD |
5696 | ;; If the optional BOUND is an integer, bound backwards directed searches to |
5697 | ;; this point. If it is nil, limit to nearest \section - like statement. | |
5698 | ||
a6611c0d | 5699 | (unless reftex-section-regexp (reftex-compile-variables)) |
b849548d CD |
5700 | (catch 'exit |
5701 | (save-excursion | |
5702 | (if (null which) (throw 'exit nil)) | |
5703 | (let ((bound (or bound (save-excursion (re-search-backward | |
5704 | reftex-section-regexp nil 1) | |
5705 | (point)))) | |
5706 | env-list end-list env) | |
5707 | (while (re-search-backward "\\\\\\(begin\\|end\\){\\([^}]+\\)}" | |
5708 | bound t) | |
5709 | (setq env (buffer-substring-no-properties | |
5710 | (match-beginning 2) (match-end 2))) | |
5711 | (cond | |
5712 | ((string= (match-string 1) "end") | |
5713 | (add-to-list 'end-list env)) | |
5714 | ((member env end-list) | |
5715 | (setq end-list (delete env end-list))) | |
5716 | ((eq t which) | |
5717 | (push (cons env (point)) env-list)) | |
5718 | ((or (eq 1 which) (member env which)) | |
5719 | (throw 'exit (cons env (point)))))) | |
5720 | (nreverse env-list))))) | |
5721 | ||
5722 | ;;; ========================================================================= | |
5723 | ;;; | |
5724 | ;;; Finding files | |
5725 | ||
f9ad2e24 CD |
5726 | (defun reftex-locate-file (file type master-dir &optional die) |
5727 | "Find FILE of type TYPE in MASTER-DIR or on the path associcted with TYPE. | |
5728 | If the file does not have any of the legal extensions for TYPE, | |
5729 | try first the default extension and only then the naked file name. | |
5730 | When DIE is non-nil, throw an error if file not found." | |
5731 | (let* ((rec-values (if reftex-search-unrecursed-path-first '(nil t) '(t))) | |
5732 | (extensions (cdr (assoc type reftex-file-extensions))) | |
5733 | (def-ext (car extensions)) | |
5734 | (ext-re (concat "\\(" | |
5735 | (mapconcat 'regexp-quote extensions "\\|") | |
5736 | "\\)\\'")) | |
5737 | (files (if (string-match ext-re file) | |
5738 | (cons file nil) | |
5739 | (cons (concat file def-ext) file))) | |
5740 | path old-path file1) | |
51d628c8 CD |
5741 | (cond |
5742 | ((file-name-absolute-p file) | |
f9ad2e24 CD |
5743 | (setq file1 |
5744 | (or | |
5745 | (and (car files) (file-regular-p (car files)) (car files)) | |
5746 | (and (cdr files) (file-regular-p (cdr files)) (cdr files))))) | |
51d628c8 | 5747 | ((and reftex-use-external-file-finders |
f9ad2e24 CD |
5748 | (assoc type reftex-external-file-finders)) |
5749 | (setq file1 (reftex-find-file-externally file type master-dir))) | |
51d628c8 | 5750 | (t |
b849548d | 5751 | (while (and (null file1) rec-values) |
a6611c0d | 5752 | (setq path (reftex-access-search-path |
f9ad2e24 | 5753 | type (pop rec-values) master-dir file)) |
b849548d CD |
5754 | (if (or (null old-path) |
5755 | (not (eq old-path path))) | |
5756 | (setq old-path path | |
5757 | path (cons master-dir path) | |
f9ad2e24 CD |
5758 | file1 (or (and (car files) |
5759 | (reftex-find-file-on-path | |
5760 | (car files) path master-dir)) | |
5761 | (and (cdr files) | |
5762 | (reftex-find-file-on-path | |
5763 | (cdr files) path master-dir)))))))) | |
b849548d CD |
5764 | (cond (file1 file1) |
5765 | (die (error "No such file: %s" file) nil) | |
5766 | (t (message "No such file: %s (ignored)" file) nil)))) | |
5767 | ||
51d628c8 CD |
5768 | (defun reftex-find-file-externally (file type &optional master-dir) |
5769 | ;; Use external program to find FILE. | |
f9ad2e24 | 5770 | ;; The program is taken from `reftex-external-file-finders'. |
51d628c8 CD |
5771 | ;; Interprete relative path definitions starting from MASTER-DIR. |
5772 | (let ((default-directory (or master-dir default-directory)) | |
5773 | (prg (cdr (assoc type reftex-external-file-finders))) | |
5774 | out) | |
5775 | (if (string-match "%f" prg) | |
5776 | (setq prg (replace-match file t t prg))) | |
5777 | (setq out (apply 'reftex-process-string (split-string prg))) | |
5778 | (if (string-match "[ \t\n]+\\'" out) | |
5779 | (setq out (replace-match "" nil nil out))) | |
5780 | (cond ((equal out "") nil) | |
5781 | ((file-regular-p out) out) | |
5782 | (t nil)))) | |
5783 | ||
5784 | (defun reftex-process-string (program &rest args) | |
5785 | "Execute PROGRAM with arguments ARGS and return its STDOUT as a string." | |
5786 | (with-output-to-string | |
f9ad2e24 | 5787 | (with-current-buffer standard-output |
51d628c8 CD |
5788 | (apply 'call-process program nil '(t nil) nil args)))) |
5789 | ||
f9ad2e24 CD |
5790 | (defun reftex-access-search-path (type &optional recurse master-dir file) |
5791 | ;; Access path from environment variables. TYPE is either "tex" or "bib". | |
b849548d CD |
5792 | ;; When RECURSE is t, expand path elements ending in `//' recursively. |
5793 | ;; Relative path elements are left as they are. However, relative recursive | |
5794 | ;; elements are expanded with MASTER-DIR as default directory. | |
5795 | ;; The expanded path is cached for the next search. | |
5796 | ;; FILE is just for the progress message. | |
5797 | ;; Returns the derived path. | |
f9ad2e24 | 5798 | (let* ((pathvar (intern (concat "reftex-" type "-path")))) |
b849548d | 5799 | (when (null (get pathvar 'status)) |
f9ad2e24 CD |
5800 | ;; Get basic path |
5801 | (set pathvar | |
5802 | (reftex-uniq | |
5803 | (reftex-parse-colon-path | |
5804 | (mapconcat | |
5805 | (lambda(x) | |
5806 | (if (string-match "^!" x) | |
5807 | (apply 'reftex-process-string | |
5808 | (split-string (substring x 1))) | |
5809 | (or (getenv x) x))) | |
5810 | ;; For consistency, the next line should look like this: | |
5811 | ;; (cdr (assoc type reftex-path-environment)) | |
5812 | ;; However, historically we have separate options for the | |
5813 | ;; environment variables, so we have to do this: | |
5814 | (symbol-value (intern (concat "reftex-" type | |
5815 | "path-environment-variables"))) | |
5816 | path-separator)))) | |
b849548d CD |
5817 | (put pathvar 'status 'split) |
5818 | ;; Check if we have recursive elements | |
5819 | (let ((path (symbol-value pathvar)) dir rec) | |
5820 | (while (setq dir (pop path)) | |
5821 | (when (string= (substring dir -2) "//") | |
5822 | (if (file-name-absolute-p dir) | |
5823 | (setq rec (or rec 'absolute)) | |
5824 | (setq rec 'relative)))) | |
5825 | (put pathvar 'rec-type rec))) | |
5826 | ||
5827 | (if recurse | |
5828 | ;; Return the recursive expansion of the path | |
5829 | (cond | |
5830 | ((not (get pathvar 'rec-type)) | |
5831 | ;; Path does not contain recursive elements - use simple path | |
5832 | (symbol-value pathvar)) | |
5833 | ((or (not (get pathvar 'recursive-path)) | |
5834 | (and (eq (get pathvar 'rec-type) 'relative) | |
5835 | (not (equal master-dir (get pathvar 'master-dir))))) | |
5836 | ;; Either: We don't have a recursive expansion yet. | |
5837 | ;; or: Relative recursive path elements need to be expanded | |
5838 | ;; relative to new default directory | |
f9ad2e24 | 5839 | (message "Expanding search path to find %s file: %s ..." type file) |
b849548d CD |
5840 | (put pathvar 'recursive-path |
5841 | (reftex-expand-path (symbol-value pathvar) master-dir)) | |
5842 | (put pathvar 'master-dir master-dir) | |
5843 | (get pathvar 'recursive-path)) | |
5844 | (t | |
5845 | ;; Recursive path computed earlier is still OK. | |
5846 | (get pathvar 'recursive-path))) | |
5847 | ;; The simple path was requested | |
5848 | (symbol-value pathvar)))) | |
5849 | ||
5850 | (defun reftex-find-file-on-path (file path &optional def-dir) | |
5851 | ;; Find FILE along the directory list PATH. | |
5852 | ;; DEF-DIR is the default directory for expanding relative path elements. | |
5853 | (catch 'exit | |
5854 | (when (file-name-absolute-p file) | |
a6611c0d | 5855 | (if (file-regular-p file) |
b849548d CD |
5856 | (throw 'exit file) |
5857 | (throw 'exit nil))) | |
f9ad2e24 | 5858 | (let* ((thepath path) file1 dir) |
b849548d CD |
5859 | (while (setq dir (pop thepath)) |
5860 | (when (string= (substring dir -2) "//") | |
5861 | (setq dir (substring dir 0 -1))) | |
5862 | (setq file1 (expand-file-name file (expand-file-name dir def-dir))) | |
a6611c0d | 5863 | (if (file-regular-p file1) |
b849548d CD |
5864 | (throw 'exit file1))) |
5865 | ;; No such file | |
5866 | nil))) | |
5867 | ||
5868 | (defun reftex-parse-colon-path (path) | |
5869 | ;; Like parse-colon-parse, but // or /~ are left alone. | |
5870 | ;; Trailing ! or !! will be converted into `//' (emTeX convention) | |
5871 | (mapcar | |
5872 | (lambda (dir) | |
5873 | (if (string-match "\\(//+\\|/*!+\\)\\'" dir) | |
5874 | (setq dir (replace-match "//" t t dir))) | |
5875 | (file-name-as-directory dir)) | |
5876 | (delete "" (split-string path (concat path-separator "+"))))) | |
5877 | ||
5878 | (defun reftex-expand-path (path &optional default-dir) | |
5879 | ;; Expand parts of path ending in `//' recursively into directory list. | |
5880 | ;; Relative recursive path elements are expanded relative to DEFAULT-DIR. | |
5881 | (let (path1 dir recursive) | |
5882 | (while (setq dir (pop path)) | |
5883 | (if (setq recursive (string= (substring dir -2) "//")) | |
5884 | (setq dir (substring dir 0 -1))) | |
5885 | (if (and recursive | |
5886 | (not (file-name-absolute-p dir))) | |
5887 | (setq dir (expand-file-name dir default-dir))) | |
5888 | (if recursive | |
5889 | ;; Expand recursively | |
5890 | (setq path1 (append (reftex-recursive-directory-list dir) path1)) | |
5891 | ;; Keep unchanged | |
5892 | (push dir path1))) | |
5893 | (nreverse path1))) | |
a7ec1775 | 5894 | |
b849548d CD |
5895 | (defun reftex-recursive-directory-list (dir) |
5896 | ;; Return a list of all directories below DIR, including DIR itself | |
5897 | (let ((path (list dir)) path1 file files) | |
5898 | (while (setq dir (pop path)) | |
5899 | (when (file-directory-p dir) | |
5900 | (setq files (nreverse (directory-files dir t "[^.]"))) | |
5901 | (while (setq file (pop files)) | |
5902 | (if (file-directory-p file) | |
5903 | (push (file-name-as-directory file) path))) | |
5904 | (push dir path1))) | |
5905 | path1)) | |
a7ec1775 | 5906 | |
f9ad2e24 CD |
5907 | (defun reftex-uniq (list) |
5908 | (let (new) | |
5909 | (while list | |
5910 | (or (member (car list) new) | |
5911 | (push (car list) new)) | |
5912 | (pop list)) | |
5913 | (nreverse new))) | |
5914 | ||
b849548d CD |
5915 | ;;; ========================================================================= |
5916 | ;;; | |
5917 | ;;; Some generally useful functions | |
a7ec1775 RS |
5918 | |
5919 | (defun reftex-no-props (string) | |
5920 | ;; Return STRING with all text properties removed | |
5921 | (and (stringp string) | |
5922 | (set-text-properties 0 (length string) nil string)) | |
5923 | string) | |
5924 | ||
396e0b08 KH |
5925 | (defun reftex-match-string (n) |
5926 | ;; Match string without properties | |
5927 | (when (match-beginning n) | |
5928 | (buffer-substring-no-properties (match-beginning n) (match-end n)))) | |
5929 | ||
2faef409 | 5930 | (defun reftex-kill-buffer (buffer) |
29d593f8 | 5931 | ;; Kill buffer if it exists. |
2faef409 RS |
5932 | (and (setq buffer (get-buffer buffer)) |
5933 | (kill-buffer buffer))) | |
5934 | ||
29d593f8 KH |
5935 | (defun reftex-erase-buffer (&optional buffer) |
5936 | ;; Erase BUFFER if it exists. BUFFER defaults to current buffer. | |
5937 | ;; This even erases read-only buffers. | |
5938 | (cond | |
5939 | ((null buffer) | |
5940 | ;; erase current buffer | |
5941 | (let ((buffer-read-only nil)) (erase-buffer))) | |
5942 | ((setq buffer (get-buffer buffer)) | |
5943 | ;; buffer exists | |
5944 | (save-excursion | |
5945 | (set-buffer buffer) | |
5946 | (let ((buffer-read-only nil)) (erase-buffer)))))) | |
2faef409 | 5947 | |
396e0b08 KH |
5948 | (defun reftex-this-word (&optional class) |
5949 | ;; Grab the word around point. | |
5950 | (setq class (or class "-a-zA-Z0-9:_/.*;|")) | |
5951 | (save-excursion | |
5952 | (buffer-substring-no-properties | |
5953 | (progn (skip-chars-backward class) (point)) | |
5954 | (progn (skip-chars-forward class) (point))))) | |
5955 | ||
b849548d CD |
5956 | (defun reftex-all-assq (key list) |
5957 | ;; Return a list of all associations of KEY in LIST. Comparison with eq. | |
5958 | (let (rtn) | |
5959 | (while (setq list (memq (assq key list) list)) | |
5960 | (push (car list) rtn) | |
5961 | (pop list)) | |
5962 | (nreverse rtn))) | |
5963 | ||
5964 | (defun reftex-all-assoc-string (key list) | |
5965 | ;; Return a list of all associations of KEY in LIST. Comparison with string=. | |
5966 | (let (rtn) | |
5967 | (while list | |
5968 | (if (string= (car (car list)) key) | |
5969 | (push (car list) rtn)) | |
5970 | (pop list)) | |
5971 | (nreverse rtn))) | |
5972 | ||
5973 | (defun reftex-last-assoc-before-elt (key elt list) | |
5974 | ;; Find the last association of KEY in LIST before or at ELT | |
5975 | ;; ELT is found in LIST with equal, not eq. | |
5976 | ;; Returns nil when either KEY or elt are not found in LIST. | |
5977 | ;; On success, returns the association. | |
5978 | (let* ((elt (car (member elt list))) ass last-ass) | |
5979 | ||
5980 | (while (and (setq ass (assoc key list)) | |
5981 | (setq list (memq ass list)) | |
5982 | (memq elt list)) | |
5983 | (setq last-ass ass | |
5984 | list (cdr list))) | |
5985 | last-ass)) | |
5986 | ||
396e0b08 | 5987 | (defun reftex-truncate (string ncols &optional ellipses padding) |
f9ad2e24 CD |
5988 | ;; Truncate STRING to NCOLS characters. |
5989 | ;; When PADDING is non-nil, and string is shorter than NCOLS, fill with | |
5990 | ;; white space to NCOLS characters. When ELLIPSES is non-nil and the | |
5991 | ;; string needs to be truncated, replace last 3 characters by dots. | |
396e0b08 | 5992 | (setq string |
f9ad2e24 CD |
5993 | (if (<= (length string) ncols) |
5994 | string | |
5995 | (if ellipses | |
5996 | (concat (substring string 0 (- ncols 3)) "...") | |
5997 | (substring string 0 ncols)))) | |
396e0b08 KH |
5998 | (if padding |
5999 | (format (format "%%-%ds" ncols) string) | |
6000 | string)) | |
6001 | ||
b849548d CD |
6002 | (defun reftex-nearest-match (regexp &optional pos) |
6003 | ;; Find the nearest match of REGEXP. Set the match data. | |
6004 | ;; If POS is given, calculate distances relative to it. | |
6005 | ;; Return nil if there is no match. | |
6006 | (let ((start (point)) (pos (or pos (point))) match1 match2 match) | |
6007 | (goto-char start) | |
6008 | (when (re-search-backward regexp nil t) | |
6009 | (setq match1 (match-data))) | |
6010 | (goto-char start) | |
6011 | (when (re-search-forward regexp nil t) | |
6012 | (setq match2 (match-data))) | |
6013 | (goto-char start) | |
6014 | (setq match | |
6015 | (cond | |
6016 | ((not match1) match2) | |
6017 | ((not match2) match1) | |
6018 | ((< (abs (- pos (car match1))) (abs (- pos (car match2)))) match1) | |
6019 | (t match2))) | |
6020 | (if match (progn (set-match-data match) t) nil))) | |
6021 | ||
6022 | (defun reftex-auto-mode-alist () | |
6023 | ;; Return an `auto-mode-alist' with only the .gz (etc) thingies. | |
6024 | ;; Stolen from gnus nnheader. | |
6025 | (let ((alist auto-mode-alist) | |
6026 | out) | |
6027 | (while alist | |
6028 | (when (listp (cdr (car alist))) | |
6029 | (push (car alist) out)) | |
6030 | (pop alist)) | |
6031 | (nreverse out))) | |
6032 | ||
921759ee CD |
6033 | (defun reftex-window-height () |
6034 | (if (fboundp 'window-displayed-height) | |
6035 | (window-displayed-height) | |
6036 | (window-height))) | |
6037 | ||
b849548d CD |
6038 | (defun reftex-enlarge-to-fit (buf2 &optional keep-current) |
6039 | ;; Enlarge other window displaying buffer to show whole buffer if possible. | |
6040 | ;; If KEEP-CURRENT in non-nil, current buffer must remain visible. | |
6041 | (let* ((win1 (selected-window)) | |
6042 | (buf1 (current-buffer)) | |
921759ee | 6043 | (win2 (get-buffer-window buf2))) ;; Only on current frame. |
b849548d CD |
6044 | (when win2 |
6045 | (select-window win2) | |
6046 | (unless (and (pos-visible-in-window-p 1) | |
6047 | (pos-visible-in-window-p (point-max))) | |
6048 | (enlarge-window (1+ (- (count-lines 1 (point-max)) | |
921759ee | 6049 | (reftex-window-height)))))) |
b849548d CD |
6050 | (cond |
6051 | ((window-live-p win1) (select-window win1)) | |
6052 | (keep-current | |
6053 | ;; we must have the old buffer! | |
6054 | (switch-to-buffer-other-window buf1) | |
6055 | (shrink-window (- (window-height) window-min-height)))))) | |
6056 | ||
6057 | (defun reftex-select-with-char (prompt help-string &optional delay-time scroll) | |
6058 | ;; Offer to select something with PROMPT and, after DELAY-TIME seconds, | |
6059 | ;; also with HELP-STRING. | |
6060 | ;; When SCROLL is non-nil, use SPC and DEL to scroll help window. | |
6061 | (let ((char ?\?)) | |
6062 | (save-window-excursion | |
6063 | (catch 'exit | |
6064 | (message (concat prompt " (?=Help)")) | |
6065 | (when (or (sit-for (or delay-time 0)) | |
6066 | (= ?\? (setq char (read-char-exclusive)))) | |
921759ee CD |
6067 | (reftex-kill-buffer "*RefTeX Select*") |
6068 | (switch-to-buffer-other-window "*RefTeX Select*") | |
6069 | (insert help-string) | |
6070 | (goto-char 1) | |
6071 | (unless (and (pos-visible-in-window-p 1) | |
6072 | (pos-visible-in-window-p (point-max))) | |
6073 | (enlarge-window (1+ (- (count-lines 1 (point-max)) | |
6074 | (reftex-window-height))))) | |
b849548d CD |
6075 | (setq truncate-lines t)) |
6076 | (setq prompt (concat prompt (if scroll " (SPC/DEL=Scroll)" ""))) | |
6077 | (message prompt) | |
6078 | (and (equal char ?\?) (setq char (read-char-exclusive))) | |
6079 | (while t | |
6080 | (cond ((equal char ?\C-g) (keyboard-quit)) | |
6081 | ((equal char ?\?)) | |
6082 | ((and scroll (equal char ?\ )) | |
6083 | (condition-case nil (scroll-up) (error nil)) | |
6084 | (message prompt)) | |
6085 | ((and scroll (equal char ?\C-? )) | |
6086 | (condition-case nil (scroll-down) (error nil)) | |
6087 | (message prompt)) | |
6088 | (t (throw 'exit char))) | |
6089 | (setq char (read-char-exclusive))))))) | |
6090 | ||
6091 | (defun reftex-make-regexp-allow-for-ctrl-m (string) | |
6092 | ;; convert STRING into a regexp, allowing ^M for \n and vice versa | |
6093 | (let ((start -2)) | |
6094 | (setq string (regexp-quote string)) | |
6095 | (while (setq start (string-match "[\n\r]" string (+ 3 start))) | |
6096 | (setq string (replace-match "[\n\r]" nil t string))) | |
6097 | string)) | |
6098 | ||
6099 | (defun reftex-get-buffer-visiting (file) | |
6100 | ;; return a buffer visiting FILE | |
6101 | (cond | |
6102 | ((boundp 'find-file-compare-truenames) ; XEmacs | |
6103 | (let ((find-file-compare-truenames t)) | |
6104 | (get-file-buffer file))) | |
6105 | ((fboundp 'find-buffer-visiting) ; Emacs | |
6106 | (find-buffer-visiting file)) | |
6107 | (t (error "This should not happen (reftex-get-buffer-visiting)")))) | |
6108 | ||
6109 | ;; Define `current-message' for compatibility with XEmacs prior to 20.4 | |
6110 | (defvar message-stack) | |
6111 | (if (and (featurep 'xemacs) | |
6112 | (not (fboundp 'current-message))) | |
6113 | (defun current-message (&optional frame) | |
6114 | (cdr (car message-stack)))) | |
6115 | ||
6116 | (defun reftex-visited-files (list) | |
6117 | ;; Takes a list of filenames and returns the buffers of those already visited | |
6118 | (delq nil (mapcar (lambda (x) (if (reftex-get-buffer-visiting x) x nil)) | |
6119 | list))) | |
6120 | ||
6121 | (defun reftex-get-file-buffer-force (file &optional mark-to-kill) | |
6122 | ;; Return a buffer visiting file. Make one, if necessary. | |
6123 | ;; If neither such a buffer nor the file exist, return nil. | |
6124 | ;; If MARK-TO-KILL is t and there is no live buffer, visit the file with | |
6125 | ;; initializations according to `reftex-initialize-temporary-buffers', | |
6126 | ;; and mark the buffer to be killed after use. | |
6127 | ||
6128 | (let ((buf (reftex-get-buffer-visiting file))) | |
6129 | ||
6130 | (cond (buf | |
6131 | ;; We have it already as a buffer - just return it | |
6132 | buf) | |
6133 | ||
6134 | ((file-readable-p file) | |
6135 | ;; At least there is such a file and we can read it. | |
6136 | ||
6137 | (if (or (not mark-to-kill) | |
6138 | (eq t reftex-initialize-temporary-buffers)) | |
6139 | ||
6140 | ;; Visit the file with full magic | |
6141 | (setq buf (find-file-noselect file)) | |
6142 | ||
6143 | ;; Else: Visit the file just briefly, without or | |
6144 | ;; with limited Magic | |
6145 | ||
6146 | ;; The magic goes away | |
6147 | (let ((format-alist nil) | |
6148 | (auto-mode-alist (reftex-auto-mode-alist)) | |
6149 | (default-major-mode 'fundamental-mode) | |
6150 | (enable-local-variables nil) | |
6151 | (after-insert-file-functions nil)) | |
6152 | (setq buf (find-file-noselect file))) | |
6153 | ||
6154 | ;; Is there a hook to run? | |
6155 | (when (listp reftex-initialize-temporary-buffers) | |
6156 | (save-excursion | |
6157 | (set-buffer buf) | |
6158 | (run-hooks 'reftex-initialize-temporary-buffers)))) | |
6159 | ||
6160 | ;; Lets see if we got a license to kill :-| | |
6161 | (and mark-to-kill | |
6162 | (add-to-list 'reftex-buffers-to-kill buf)) | |
6163 | ||
6164 | ;; Return the new buffer | |
6165 | buf) | |
6166 | ||
6167 | ;; If no such file exists, return nil | |
6168 | (t nil)))) | |
6169 | ||
6170 | (defun reftex-kill-temporary-buffers (&optional buffer) | |
6171 | ;; Kill all buffers in the list reftex-kill-temporary-buffers. | |
6172 | (cond | |
6173 | (buffer | |
6174 | (when (member buffer reftex-buffers-to-kill) | |
6175 | (kill-buffer buffer) | |
6176 | (setq reftex-buffers-to-kill | |
6177 | (delete buffer reftex-buffers-to-kill)))) | |
6178 | (t | |
6179 | (while (setq buffer (pop reftex-buffers-to-kill)) | |
6180 | (when (bufferp buffer) | |
6181 | (and (buffer-modified-p buffer) | |
6182 | (y-or-n-p (format "Save file %s? " | |
6183 | (buffer-file-name buffer))) | |
6184 | (save-excursion | |
6185 | (set-buffer buffer) | |
6186 | (save-buffer))) | |
6187 | (kill-buffer buffer)) | |
6188 | (pop reftex-buffers-to-kill))))) | |
6189 | ||
6190 | (defun reftex-splice-symbols-into-list (list alist) | |
6191 | ;; Splice the association in ALIST of any symbols in LIST into the list. | |
6192 | ;; Return new list. | |
6193 | (let (rtn tmp) | |
6194 | (while list | |
6195 | (while (and (not (null (car list))) ;; keep list elements nil | |
6196 | (symbolp (car list))) | |
6197 | (setq tmp (car list)) | |
6198 | (cond | |
6199 | ((assoc tmp alist) | |
6200 | (setq list (append (nth 2 (assoc tmp alist)) (cdr list)))) | |
6201 | (t | |
6202 | (error "Cannot treat symbol %s in reftex-label-alist" | |
6203 | (symbol-name tmp))))) | |
6204 | (push (pop list) rtn)) | |
6205 | (nreverse rtn))) | |
6206 | ||
6207 | (defun reftex-uniquify-by-car (alist &optional keep-list) | |
6208 | ;; Return a list of all elements in ALIST, but each car only once. | |
6209 | ;; Elements of KEEP-LIST are not removed even if duplicate. | |
6210 | (let (new elm) | |
6211 | (while alist | |
6212 | (setq elm (pop alist)) | |
6213 | (if (or (member (car elm) keep-list) | |
6214 | (not (assoc (car elm) new))) | |
6215 | (push elm new))) | |
6216 | (nreverse new))) | |
6217 | ||
6218 | ;;; ========================================================================= | |
6219 | ;;; | |
6220 | ;;; Fontification and Highlighting | |
6221 | ||
6222 | (defun reftex-use-fonts () | |
6223 | ;; Return t if we can and want to use fonts. | |
6224 | (and window-system | |
6225 | reftex-use-fonts | |
6226 | (featurep 'font-lock))) | |
6227 | ||
6228 | (defun reftex-refontify () | |
6229 | ;; Return t if we need to refontify context | |
6230 | (and (reftex-use-fonts) | |
6231 | (or (eq t reftex-refontify-context) | |
6232 | (and (eq 1 reftex-refontify-context) | |
6233 | ;; Test of we use the font-lock version of x-symbol | |
6234 | (and (featurep 'x-symbol-tex) (not (boundp 'x-symbol-mode))))))) | |
6235 | ||
6236 | (defun reftex-fontify-select-label-buffer (parent-buffer) | |
6237 | ;; Fontify the `*RefTeX Select*' buffer. Buffer is temporarily renamed to | |
6238 | ;; start with none-SPC char, beacuse Font-Lock otherwise refuses operation. | |
6239 | (run-hook-with-args 'reftex-pre-refontification-functions | |
6240 | parent-buffer 'reftex-ref) | |
6241 | (let* ((oldname (buffer-name)) | |
6242 | (newname (concat "Fontify-me-" oldname))) | |
6243 | (unwind-protect | |
6244 | (progn | |
6245 | ;; Rename buffer temporarily to start w/o space (because of font-lock) | |
6246 | (rename-buffer newname t) | |
6247 | (cond | |
6248 | ((fboundp 'font-lock-default-fontify-region) | |
6249 | ;; Good: we have the indirection functions | |
6250 | (set (make-local-variable 'font-lock-fontify-region-function) | |
6251 | 'reftex-select-font-lock-fontify-region) | |
6252 | (let ((major-mode 'latex-mode)) | |
6253 | (font-lock-mode 1))) | |
6254 | ((fboundp 'font-lock-set-defaults-1) | |
6255 | ;; Looks like the XEmacs font-lock stuff. | |
f9ad2e24 | 6256 | ;; FIXME: this is still kind of a hack, but it works. |
b849548d CD |
6257 | (set (make-local-variable 'font-lock-keywords) nil) |
6258 | (let ((major-mode 'latex-mode) | |
6259 | (font-lock-defaults-computed nil)) | |
6260 | (font-lock-set-defaults-1) | |
6261 | (reftex-select-font-lock-fontify-region (point-min) (point-max)))) | |
6262 | (t | |
6263 | ;; Oops? | |
6264 | (message "Sorry: cannot refontify RefTeX Select buffer.")))) | |
6265 | (rename-buffer oldname)))) | |
6266 | ||
6267 | (defun reftex-select-font-lock-fontify-region (beg end &optional loudly) | |
6268 | ;; Fontify a region, but only lines starting with a dot. | |
6269 | (let ((func (if (fboundp 'font-lock-default-fontify-region) | |
6270 | 'font-lock-default-fontify-region | |
6271 | 'font-lock-fontify-region)) | |
6272 | beg1 end1) | |
6273 | (goto-char beg) | |
6274 | (while (re-search-forward "^\\." end t) | |
6275 | (setq beg1 (point) end1 (progn (skip-chars-forward "^\n") (point))) | |
6276 | (funcall func beg1 end1 nil) | |
6277 | (goto-char end1)))) | |
6278 | ||
6279 | (defun reftex-select-font-lock-unfontify (&rest ignore) t) | |
396e0b08 | 6280 | |
b849548d CD |
6281 | (defun reftex-verified-face (&rest faces) |
6282 | ;; Return the first valid face in FACES, or nil if none is valid. | |
6283 | ;; Also, when finding a nil element in FACES, return nil. This | |
6284 | ;; function is just a safety net to catch name changes of builtin | |
6285 | ;; fonts. Currently it is only used for reftex-label-face, which has | |
6286 | ;; as default font-lock-reference-face, which was recently renamed | |
6287 | ;; to font-lock-constant-face. | |
6288 | (let (face) | |
6289 | (catch 'exit | |
6290 | (while (setq face (pop faces)) | |
6291 | (if (featurep 'xemacs) | |
6292 | (if (find-face face) (throw 'exit face)) | |
6293 | (if (facep face) (throw 'exit face))))))) | |
396e0b08 | 6294 | |
b849548d CD |
6295 | ;; Highlighting uses overlays. For XEmacs, we need the emulation. |
6296 | (if (featurep 'xemacs) (require 'overlay)) | |
6297 | ||
6298 | ;; We keep a vector with several different overlays to do our highlighting. | |
6299 | (defvar reftex-highlight-overlays [nil nil]) | |
6300 | ||
6301 | ;; Initialize the overlays | |
6302 | (aset reftex-highlight-overlays 0 (make-overlay 1 1)) | |
6303 | (overlay-put (aref reftex-highlight-overlays 0) | |
6304 | 'face 'highlight) | |
6305 | (aset reftex-highlight-overlays 1 (make-overlay 1 1)) | |
6306 | (overlay-put (aref reftex-highlight-overlays 1) | |
6307 | 'face reftex-cursor-selected-face) | |
6308 | ||
6309 | ;; Two functions for activating and deactivation highlight overlays | |
6310 | (defun reftex-highlight (index begin end &optional buffer) | |
6311 | "Highlight a region with overlay INDEX." | |
6312 | (move-overlay (aref reftex-highlight-overlays index) | |
6313 | begin end (or buffer (current-buffer)))) | |
6314 | (defun reftex-unhighlight (index) | |
6315 | "Detach overlay INDEX." | |
6316 | (delete-overlay (aref reftex-highlight-overlays index))) | |
6317 | ||
6318 | (defun reftex-highlight-shall-die () | |
6319 | ;; Function used in pre-command-hook to remove highlights. | |
6320 | (remove-hook 'pre-command-hook 'reftex-highlight-shall-die) | |
6321 | (reftex-unhighlight 0)) | |
6322 | ||
6323 | ;;; ========================================================================= | |
6324 | ;;; | |
6325 | ;;; Functions to compile the tables, reset the mode etc. | |
2faef409 | 6326 | |
b849548d CD |
6327 | ;; A list of all variables in the cache. |
6328 | ;; The cache is used to save the compiled versions of some variables. | |
6329 | (defconst reftex-cache-variables | |
6330 | '(reftex-memory ;; This MUST ALWAYS be the first! | |
6331 | reftex-env-or-mac-alist reftex-everything-regexp | |
921759ee | 6332 | reftex-macros-with-labels |
b849548d CD |
6333 | reftex-find-label-regexp-format reftex-find-label-regexp-format2 |
6334 | reftex-label-env-list reftex-label-mac-list | |
6335 | reftex-section-or-include-regexp reftex-section-levels-all | |
6336 | reftex-section-regexp reftex-type-query-help | |
6337 | reftex-type-query-prompt reftex-typekey-list | |
6338 | reftex-typekey-to-format-alist reftex-typekey-to-prefix-alist | |
6339 | reftex-words-to-typekey-alist)) | |
6340 | ||
6341 | (defun reftex-ensure-compiled-variables () | |
6342 | ;; Recompile the label alist when necessary | |
6343 | (let* ((mem reftex-memory) | |
6344 | (cache (get reftex-docstruct-symbol 'reftex-cache)) | |
6345 | (cmem (car cache)) | |
6346 | (alist reftex-label-alist) | |
6347 | (levels (get reftex-docstruct-symbol 'reftex-section-levels)) | |
6348 | (style (get reftex-docstruct-symbol 'reftex-label-alist-style)) | |
6349 | (default reftex-default-label-alist-entries)) | |
396e0b08 | 6350 | (cond |
b849548d CD |
6351 | (reftex-tables-dirty (reftex-compile-variables)) |
6352 | ((and (eq alist (nth 0 mem)) | |
6353 | (eq levels (nth 1 mem)) | |
6354 | (eq style (nth 2 mem)) | |
6355 | (eq default (nth 3 mem)))) ;; everything is OK | |
6356 | ((and (eq alist (nth 0 cmem)) | |
6357 | (eq levels (nth 1 cmem)) | |
6358 | (eq style (nth 2 cmem)) | |
6359 | (eq default (nth 2 cmem))) | |
6360 | ;; restore the cache | |
6361 | (message "Restoring cache") | |
6362 | (mapcar (lambda (sym) (set sym (pop cache))) reftex-cache-variables)) | |
6363 | (t (reftex-compile-variables))))) | |
396e0b08 | 6364 | |
b849548d CD |
6365 | (defun reftex-reset-mode () |
6366 | "Reset RefTeX Mode. | |
6367 | This will re-compile the configuration information and remove all | |
6368 | current scanning information and the parse file to enforce a rescan | |
6369 | on next use." | |
6370 | (interactive) | |
a7ec1775 | 6371 | |
b849548d CD |
6372 | ;; Reset the file search path variables |
6373 | (loop for prop in '(status master-dir recursive-path rec-type) do | |
6374 | (put 'reftex-tex-path prop nil) | |
6375 | (put 'reftex-bib-path prop nil)) | |
396e0b08 | 6376 | |
b849548d CD |
6377 | ;; Kill temporary buffers associated with RefTeX - just in case they |
6378 | ;; were not cleaned up properly | |
6379 | (save-excursion | |
6380 | (let ((buffer-list '("*RefTeX Help*" "*RefTeX Select*" | |
6381 | "*Duplicate Labels*" "*toc*" " *RefTeX-scratch*")) | |
6382 | buf) | |
6383 | (while (setq buf (pop buffer-list)) | |
6384 | (if (get-buffer buf) | |
6385 | (kill-buffer buf)))) | |
6386 | (reftex-erase-all-selection-buffers)) | |
396e0b08 | 6387 | |
b849548d CD |
6388 | ;; Make sure the current document will be rescanned soon. |
6389 | (reftex-reset-scanning-information) | |
a7ec1775 | 6390 | |
b849548d CD |
6391 | ;; Remove any parse info file |
6392 | (reftex-access-parse-file 'kill) | |
396e0b08 | 6393 | |
b849548d CD |
6394 | ;; Plug functions into AUCTeX if the user option says so. |
6395 | (and reftex-plug-into-AUCTeX | |
6396 | (reftex-plug-into-AUCTeX)) | |
a7ec1775 | 6397 | |
b849548d | 6398 | (reftex-compile-variables)) |
a7ec1775 | 6399 | |
b849548d CD |
6400 | (defun reftex-reset-scanning-information () |
6401 | "Reset the symbols containing information from buffer scanning. | |
6402 | This enforces rescanning the buffer on next use." | |
6403 | (if (string= reftex-last-toc-master (reftex-TeX-master-file)) | |
6404 | (reftex-erase-buffer "*toc*")) | |
6405 | (let ((symlist reftex-multifile-symbols) | |
6406 | symbol) | |
6407 | (while symlist | |
6408 | (setq symbol (car symlist) | |
6409 | symlist (cdr symlist)) | |
6410 | (if (and (symbolp (symbol-value symbol)) | |
6411 | (not (null (symbol-value symbol)))) | |
6412 | (set (symbol-value symbol) nil))))) | |
a7ec1775 | 6413 | |
b849548d CD |
6414 | (defun reftex-erase-all-selection-buffers () |
6415 | ;; Remove all selection buffers associated with current document. | |
6416 | (mapcar | |
6417 | (lambda (type) | |
6418 | (reftex-erase-buffer (reftex-make-selection-buffer-name type))) | |
6419 | reftex-typekey-list)) | |
396e0b08 | 6420 | |
b849548d CD |
6421 | (defun reftex-compile-variables () |
6422 | ;; Compile the information in reftex-label-alist & Co. | |
396e0b08 | 6423 | |
b849548d | 6424 | (message "Compiling label environment definitions...") |
396e0b08 | 6425 | |
b849548d CD |
6426 | ;; Update AUCTeX style information |
6427 | (when (and (featurep 'tex-site) (fboundp 'TeX-update-style)) | |
6428 | (condition-case nil (TeX-update-style) (error nil))) | |
396e0b08 | 6429 | |
b849548d CD |
6430 | ;; Record that we have done this, and what we have used. |
6431 | (setq reftex-tables-dirty nil) | |
6432 | (setq reftex-memory | |
6433 | (list reftex-label-alist | |
6434 | (get reftex-docstruct-symbol 'reftex-section-levels) | |
6435 | (get reftex-docstruct-symbol 'reftex-label-alist-style) | |
6436 | reftex-default-label-alist-entries)) | |
6437 | ||
6438 | ;; Compile information in reftex-label-alist | |
6439 | (let ((all (reftex-uniquify-by-car | |
6440 | (reftex-splice-symbols-into-list | |
6441 | (append reftex-label-alist | |
6442 | (get reftex-docstruct-symbol 'reftex-label-alist-style) | |
6443 | reftex-default-label-alist-entries) | |
6444 | reftex-label-alist-builtin) | |
6445 | '(nil))) | |
6446 | entry env-or-mac typekeychar typekey prefix context word | |
6447 | fmt reffmt labelfmt wordlist qh-list macros-with-labels | |
6448 | nargs nlabel opt-args cell sum i) | |
6449 | ||
6450 | (setq reftex-words-to-typekey-alist nil | |
6451 | reftex-typekey-list nil | |
6452 | reftex-typekey-to-format-alist nil | |
6453 | reftex-typekey-to-prefix-alist nil | |
6454 | reftex-env-or-mac-alist nil | |
6455 | reftex-label-env-list nil | |
6456 | reftex-label-mac-list nil) | |
6457 | (while all | |
6458 | (catch 'next-entry | |
6459 | (setq entry (car all) | |
6460 | env-or-mac (car entry) | |
6461 | entry (cdr entry) | |
6462 | all (cdr all)) | |
6463 | (if (null env-or-mac) | |
6464 | (setq env-or-mac "")) | |
6465 | (if (stringp (car entry)) | |
6466 | ;; This is before version 2.00 - convert entry to new format | |
6467 | ;; This is just to keep old users happy | |
6468 | (setq entry (cons (string-to-char (car entry)) | |
6469 | (cons (concat (car entry) ":") | |
6470 | (cdr entry))))) | |
6471 | (setq typekeychar (nth 0 entry) | |
6472 | typekey (if typekeychar (char-to-string typekeychar) nil) | |
6473 | prefix (nth 1 entry) | |
6474 | fmt (nth 2 entry) | |
6475 | context (nth 3 entry) | |
6476 | wordlist (nth 4 entry)) | |
6477 | (if (stringp wordlist) | |
6478 | ;; This is before version 2.04 - convert to new format | |
6479 | (setq wordlist (nthcdr 4 entry))) | |
6480 | ||
6481 | (if (and (stringp fmt) | |
6482 | (string-match "@" fmt)) | |
6483 | ;; Special syntax for specifying a label format | |
6484 | (setq fmt (split-string fmt "@+")) | |
6485 | (setq fmt (list "\\label{%s}" fmt))) | |
6486 | (setq labelfmt (car fmt) | |
6487 | reffmt (nth 1 fmt)) | |
6488 | ;; Note a new typekey | |
6489 | (if typekey | |
6490 | (add-to-list 'reftex-typekey-list typekey)) | |
6491 | (if (and typekey prefix | |
6492 | (not (assoc typekey reftex-typekey-to-prefix-alist))) | |
6493 | (add-to-list 'reftex-typekey-to-prefix-alist | |
6494 | (cons typekey prefix))) | |
6495 | ;; Check if this is a macro or environment | |
6496 | (cond | |
6497 | ((string-match "\\`\\\\" env-or-mac) | |
6498 | ;; It's a macro | |
6499 | (let ((result (reftex-parse-args env-or-mac))) | |
6500 | (setq env-or-mac (or (first result) env-or-mac) | |
6501 | nargs (second result) | |
6502 | nlabel (third result) | |
6503 | opt-args (fourth result)) | |
6504 | (if nlabel (add-to-list 'macros-with-labels env-or-mac))) | |
6505 | (if typekey (add-to-list 'reftex-label-mac-list env-or-mac))) | |
6506 | (t | |
6507 | ;; It's an environment | |
6508 | (setq nargs nil nlabel nil opt-args nil) | |
6509 | (cond ((string= env-or-mac "any")) | |
6510 | ((string= env-or-mac "")) | |
6511 | ((string= env-or-mac "section")) | |
6512 | (t | |
6513 | (add-to-list 'reftex-label-env-list env-or-mac))))) | |
6514 | ;; Translate some special context cases | |
6515 | (when (assq context reftex-default-context-regexps) | |
6516 | (setq context | |
6517 | (format | |
6518 | (cdr (assq context reftex-default-context-regexps)) | |
6519 | (regexp-quote env-or-mac)))) | |
6520 | ;; See if this is the first format for this typekey | |
6521 | (and reffmt | |
6522 | (not (assoc typekey reftex-typekey-to-format-alist)) | |
6523 | (push (cons typekey reffmt) reftex-typekey-to-format-alist)) | |
6524 | ;; See if this is the first definition for this env-or-mac | |
6525 | (and (not (string= env-or-mac "any")) | |
6526 | (not (string= env-or-mac "")) | |
6527 | (not (assoc env-or-mac reftex-env-or-mac-alist)) | |
6528 | (push (list env-or-mac typekey context labelfmt | |
6529 | nargs nlabel opt-args) | |
6530 | reftex-env-or-mac-alist)) | |
6531 | ;; Are the magic words regular expressions? Quote normal words. | |
6532 | (if (eq (car wordlist) 'regexp) | |
6533 | (setq wordlist (cdr wordlist)) | |
6534 | (setq wordlist (mapcar 'regexp-quote wordlist))) | |
6535 | ;; Remember the first association of each word. | |
6536 | (while (stringp (setq word (pop wordlist))) | |
6537 | (or (assoc word reftex-words-to-typekey-alist) | |
6538 | (push (cons word typekey) reftex-words-to-typekey-alist))) | |
6539 | (cond | |
6540 | ((string= "" env-or-mac) nil) | |
6541 | ((setq cell (assoc typekey qh-list)) | |
6542 | (push env-or-mac (cdr cell))) | |
6543 | (typekey | |
6544 | (push (list typekey env-or-mac) qh-list))))) | |
396e0b08 | 6545 | |
b849548d CD |
6546 | (setq reftex-typekey-to-prefix-alist |
6547 | (nreverse reftex-typekey-to-prefix-alist)) | |
396e0b08 | 6548 | |
b849548d CD |
6549 | ;; Prepare the typekey query prompt and help string. |
6550 | (setq qh-list | |
6551 | (sort qh-list (function | |
6552 | (lambda (x1 x2) (string< (car x1) (car x2)))))) | |
6553 | (setq reftex-type-query-prompt | |
6554 | (concat "Label type: [" | |
6555 | (mapconcat (function (lambda(x) (format "%s" (car x)))) | |
6556 | qh-list "") | |
6557 | "]")) | |
6558 | ;; In the help string, we need to wrap lines... | |
6559 | (setq reftex-type-query-help | |
6560 | (concat | |
6561 | "SELECT A LABEL TYPE:\n--------------------\n" | |
6562 | (mapconcat | |
6563 | (lambda(x) | |
6564 | (setq sum 0) | |
6565 | (format " [%s] %s" | |
6566 | (car x) | |
6567 | (mapconcat (lambda(env) | |
6568 | (setq sum (+ sum (length env))) | |
6569 | (if (< sum 60) | |
6570 | env | |
6571 | (setq sum 0) | |
6572 | (concat "\n " env))) | |
6573 | (cdr x) " "))) | |
6574 | qh-list "\n"))) | |
6575 | ||
6576 | ;; Convert magic words to regular expressions. We make regular expressions | |
6577 | ;; which allow for some chars from the ref format to be in the buffer. | |
6578 | ;; These characters will be seen and removed. | |
6579 | (setq reftex-words-to-typekey-alist | |
6580 | (mapcar | |
6581 | (lambda (x) | |
6582 | (setq word (car x) | |
6583 | typekey (cdr x) | |
6584 | fmt (cdr (assoc typekey reftex-typekey-to-format-alist))) | |
6585 | (setq word (concat "\\W\\(" word "[ \t\n\r]*\\)\\(")) | |
6586 | (setq i 0) | |
6587 | (while (and (< i 10) ; maximum number of format chars allowed | |
6588 | (< i (length fmt)) | |
6589 | (not (member (aref fmt i) '(?%)))) | |
6590 | (setq word (concat word "\\|" (regexp-quote | |
6591 | (substring fmt 0 (1+ i))))) | |
6592 | (incf i)) | |
6593 | (cons (concat word "\\)\\=") typekey)) | |
6594 | (nreverse reftex-words-to-typekey-alist))) | |
396e0b08 | 6595 | |
b849548d CD |
6596 | ;; Make the full list of section levels |
6597 | (setq reftex-section-levels-all | |
6598 | (append (get reftex-docstruct-symbol 'reftex-section-levels) | |
6599 | reftex-section-levels)) | |
396e0b08 | 6600 | |
b849548d CD |
6601 | ;; Calculate the regular expressions |
6602 | (let* ((wbol "\\(\\`\\|[\n\r]\\)[ \t]*") | |
6603 | (label-re "\\\\label{\\([^}]*\\)}") | |
6604 | (include-re (concat wbol "\\\\\\(include\\|input\\)[{ \t]+\\([^} \t\n\r]+\\)")) | |
6605 | (section-re | |
6606 | (concat wbol "\\\\\\(" | |
6607 | (mapconcat 'car reftex-section-levels-all "\\|") | |
6608 | "\\)\\*?\\(\\[[^]]*\\]\\)?{")) | |
6609 | (appendix-re (concat wbol "\\(\\\\appendix\\)")) | |
6610 | (macro-re | |
6611 | (if macros-with-labels | |
6612 | (concat "\\(" | |
6613 | (mapconcat 'regexp-quote macros-with-labels "\\|") | |
6614 | "\\)[[{]") | |
6615 | "")) | |
6616 | (find-label-re-format | |
6617 | (concat "\\(" | |
6618 | (mapconcat 'regexp-quote (append '("\\label") | |
6619 | macros-with-labels) "\\|") | |
6620 | "\\)\\([[{][^]}]*[]}]\\)*[[{]\\(%s\\)[]}]"))) | |
6621 | (setq reftex-section-regexp section-re | |
6622 | reftex-section-or-include-regexp | |
6623 | (concat section-re "\\|" include-re) | |
6624 | reftex-everything-regexp | |
6625 | (concat label-re "\\|" section-re "\\|" include-re | |
6626 | "\\|" appendix-re | |
6627 | (if macros-with-labels "\\|" "") macro-re) | |
921759ee | 6628 | reftex-macros-with-labels macros-with-labels |
b849548d CD |
6629 | reftex-find-label-regexp-format find-label-re-format |
6630 | reftex-find-label-regexp-format2 | |
6631 | "\\([]} \t\n\r]\\)\\([[{]\\)\\(%s\\)[]}]") | |
6632 | (message "Compiling label environment definitions...done"))) | |
6633 | (put reftex-docstruct-symbol 'reftex-cache | |
6634 | (mapcar 'symbol-value reftex-cache-variables))) | |
396e0b08 | 6635 | |
b849548d CD |
6636 | ;;; ========================================================================= |
6637 | ;;; | |
6638 | ;;; Operations on entire Multifile documents | |
396e0b08 | 6639 | |
b849548d CD |
6640 | (defun reftex-create-tags-file () |
6641 | "Create TAGS file by running `etags' on the current document. | |
6642 | The TAGS file is also immediately visited with `visit-tags-table'." | |
6643 | (interactive) | |
6644 | (reftex-access-scan-info current-prefix-arg) | |
6645 | (let* ((master (reftex-TeX-master-file)) | |
6646 | (files (reftex-all-document-files)) | |
6647 | (cmd (format "etags %s" (mapconcat 'identity files " ")))) | |
6648 | (save-excursion | |
6649 | (set-buffer (reftex-get-buffer-visiting master)) | |
6650 | (message "Running etags to create TAGS file...") | |
6651 | (shell-command cmd) | |
6652 | (visit-tags-table "TAGS")))) | |
a7ec1775 | 6653 | |
b849548d CD |
6654 | ;; History of grep commands. |
6655 | (defvar reftex-grep-history nil) | |
6656 | (defvar reftex-grep-command "grep -n " | |
6657 | "Last grep command used in \\[reftex-grep-document]; default for next grep.") | |
a7ec1775 | 6658 | |
b849548d CD |
6659 | (defun reftex-grep-document (grep-cmd) |
6660 | "Run grep query through all files related to this document. | |
6661 | With prefix arg, force to rescan document. | |
a6611c0d | 6662 | No active TAGS table is required." |
a7ec1775 | 6663 | |
b849548d CD |
6664 | (interactive |
6665 | (list (read-from-minibuffer "Run grep on document (like this): " | |
6666 | reftex-grep-command nil nil | |
6667 | 'reftex-grep-history))) | |
6668 | (reftex-access-scan-info current-prefix-arg) | |
6669 | (let* ((files (reftex-all-document-files t)) | |
6670 | (cmd (format | |
6671 | "%s %s" grep-cmd | |
6672 | (mapconcat 'identity files " ")))) | |
6673 | (grep cmd))) | |
396e0b08 | 6674 | |
b849548d | 6675 | (defun reftex-search-document (&optional regexp) |
f9ad2e24 | 6676 | "Regexp search through all files of the current document. |
b849548d CD |
6677 | Starts always in the master file. Stops when a match is found. |
6678 | To continue searching for next match, use command \\[tags-loop-continue]. | |
a6611c0d | 6679 | No active TAGS table is required." |
b849548d CD |
6680 | (interactive) |
6681 | (let ((default (reftex-this-word))) | |
6682 | (unless regexp | |
6683 | (setq regexp (read-string (format "Search regexp in document [%s]: " | |
6684 | default)))) | |
6685 | (if (string= regexp "") (setq regexp (regexp-quote default))) | |
a7ec1775 | 6686 | |
b849548d CD |
6687 | (reftex-access-scan-info current-prefix-arg) |
6688 | (tags-search regexp (list 'reftex-all-document-files)))) | |
2faef409 | 6689 | |
b849548d | 6690 | (defun reftex-query-replace-document (&optional from to delimited) |
f9ad2e24 | 6691 | "Run a query-replace-regexp of FROM with TO over the entire document. |
b849548d CD |
6692 | Third arg DELIMITED (prefix arg) means replace only word-delimited matches. |
6693 | If you exit (\\[keyboard-quit] or ESC), you can resume the query replace | |
6694 | with the command \\[tags-loop-continue]. | |
a6611c0d | 6695 | No active TAGS table is required." |
b849548d CD |
6696 | (interactive) |
6697 | (let ((default (reftex-this-word))) | |
6698 | (unless from | |
6699 | (setq from (read-string (format "Replace regexp in document [%s]: " | |
6700 | default))) | |
6701 | (if (string= from "") (setq from (regexp-quote default)))) | |
6702 | (unless to | |
6703 | (setq to (read-string (format "Replace regexp %s with: " from)))) | |
6704 | (reftex-access-scan-info current-prefix-arg) | |
6705 | (tags-query-replace from to (or delimited current-prefix-arg) | |
6706 | (list 'reftex-all-document-files)))) | |
2faef409 | 6707 | |
b849548d CD |
6708 | (defun reftex-find-duplicate-labels () |
6709 | "Produce a list of all duplicate labels in the document." | |
a7ec1775 | 6710 | |
b849548d | 6711 | (interactive) |
a7ec1775 | 6712 | |
b849548d CD |
6713 | ;; Rescan the document to make sure |
6714 | (reftex-access-scan-info t) | |
a7ec1775 | 6715 | |
b849548d CD |
6716 | (let ((master (reftex-TeX-master-file)) |
6717 | (cnt 0) | |
6718 | (dlist | |
6719 | (mapcar | |
6720 | (function | |
6721 | (lambda (x) | |
6722 | (let (x1) | |
6723 | (cond | |
6724 | ((memq (car x) | |
6725 | '(toc bof eof bib thebib label-numbers xr xr-doc | |
6726 | master-dir file-error bibview-cache appendix | |
6727 | is-multi)) | |
6728 | nil) | |
6729 | (t | |
6730 | (setq x1 (reftex-all-assoc-string | |
6731 | (car x) (symbol-value reftex-docstruct-symbol))) | |
6732 | (if (< 1 (length x1)) | |
6733 | (append (list (car x)) | |
6734 | (mapcar (function | |
6735 | (lambda(x) | |
6736 | (abbreviate-file-name (nth 3 x)))) | |
6737 | x1)) | |
6738 | (list nil))))))) | |
6739 | (reftex-uniquify-by-car (symbol-value reftex-docstruct-symbol))))) | |
a7ec1775 | 6740 | |
b849548d CD |
6741 | (setq dlist (reftex-uniquify-by-car dlist)) |
6742 | (if (null dlist) (error "No duplicate labels in document")) | |
6743 | (switch-to-buffer-other-window "*Duplicate Labels*") | |
f9ad2e24 | 6744 | (set (make-local-variable 'TeX-master) master) |
b849548d CD |
6745 | (erase-buffer) |
6746 | (insert " MULTIPLE LABELS IN CURRENT DOCUMENT:\n") | |
6747 | (insert | |
6748 | " Move point to label and type `r' to run a query-replace on the label\n" | |
6749 | " and its references. Type `q' to exit this buffer.\n\n") | |
6750 | (insert " LABEL FILE\n") | |
6751 | (insert " -------------------------------------------------------------\n") | |
6752 | (use-local-map (make-sparse-keymap)) | |
6753 | (local-set-key [?q] (function | |
6754 | (lambda () "Kill this buffer." (interactive) | |
6755 | (kill-buffer (current-buffer)) (delete-window)))) | |
6756 | (local-set-key [?r] 'reftex-change-label) | |
6757 | (while dlist | |
6758 | (when (and (car (car dlist)) | |
6759 | (cdr (car dlist))) | |
6760 | (incf cnt) | |
6761 | (insert (mapconcat 'identity (car dlist) "\n ") "\n")) | |
6762 | (pop dlist)) | |
6763 | (goto-char (point-min)) | |
6764 | (when (= cnt 0) | |
6765 | (kill-buffer (current-buffer)) | |
6766 | (delete-window) | |
6767 | (message "Document does not contain duplicate labels.")))) | |
a7ec1775 | 6768 | |
b849548d CD |
6769 | (defun reftex-change-label (&optional from to) |
6770 | "Query replace FROM with TO in all \\label and \\ref commands. | |
6771 | Works on the entire multifile document. | |
6772 | If you exit (\\[keyboard-quit] or ESC), you can resume the query replace | |
6773 | with the command \\[tags-loop-continue]. | |
a6611c0d | 6774 | No active TAGS table is required." |
b849548d CD |
6775 | (interactive) |
6776 | (let ((default (reftex-this-word "-a-zA-Z0-9_*.:"))) | |
6777 | (unless from | |
6778 | (setq from (read-string (format "Replace label globally [%s]: " | |
6779 | default)))) | |
6780 | (if (string= from "") (setq from default)) | |
6781 | (unless to | |
6782 | (setq to (read-string (format "Replace label %s with: " | |
6783 | from)))) | |
6784 | (reftex-query-replace-document | |
6785 | (concat "\\\\\\(label\\|[a-z]*ref\\){" (regexp-quote from) "}") | |
6786 | (format "\\\\\\1{%s}" to)))) | |
a7ec1775 | 6787 | |
b849548d CD |
6788 | (defun reftex-renumber-simple-labels () |
6789 | "Renumber all simple labels in the document to make them sequentially. | |
6790 | Simple labels are the ones created by RefTeX, consisting only of the | |
6791 | prefix and a number. After the command completes, all these labels will | |
6792 | have sequential numbers throughout the document. Any references to | |
6793 | the labels will be changed as well. For this, RefTeX looks at the | |
6794 | arguments of any macros which either start or end in the string `ref'. | |
6795 | This command should be used with care, in particular in multifile | |
6796 | documents. You should not use it if another document refers to this | |
6797 | one with the `xr' package." | |
a7ec1775 | 6798 | (interactive) |
b849548d CD |
6799 | ;; Resan the entire document |
6800 | (reftex-access-scan-info 1) | |
6801 | ;; Get some insurance | |
6802 | (if (and (reftex-is-multi) | |
6803 | (not (yes-or-no-p "Replacing all simple labels in multiple files is risky. Continue? "))) | |
6804 | (error "Abort")) | |
6805 | ;; Make the translation list | |
6806 | (let* ((re-core (concat "\\(" | |
6807 | (mapconcat 'cdr reftex-typekey-to-prefix-alist "\\|") | |
6808 | "\\)")) | |
6809 | (label-re (concat "\\`" re-core "\\([0-9]+\\)\\'")) | |
6810 | (search-re (concat "{\\(" re-core "\\([0-9]+\\)\\)}")) | |
6811 | (error-fmt "Undefined label or reference %s. Ignore and continue? ") | |
6812 | (label-numbers-alist (mapcar (lambda (x) (cons (cdr x) 0)) | |
6813 | reftex-typekey-to-prefix-alist)) | |
6814 | (files (reftex-all-document-files)) | |
6815 | (list (symbol-value reftex-docstruct-symbol)) | |
6816 | translate-alist n entry label new-label nr-cell changed-sequence) | |
6817 | ||
6818 | (while (setq entry (pop list)) | |
6819 | (when (and (stringp (car entry)) | |
6820 | (string-match label-re (car entry))) | |
6821 | (setq label (car entry) | |
6822 | nr-cell (assoc (match-string 1 (car entry)) | |
6823 | label-numbers-alist)) | |
6824 | (if (assoc label translate-alist) | |
6825 | (error "Duplicate label %s" label)) | |
6826 | (setq new-label (concat (match-string 1 (car entry)) | |
6827 | (incf (cdr nr-cell)))) | |
6828 | (push (cons label new-label) translate-alist) | |
6829 | (or (string= label new-label) (setq changed-sequence t)))) | |
6830 | ||
6831 | (unless changed-sequence | |
6832 | (error "Simple labels are already in correct sequence")) | |
6833 | ||
6834 | ;; Save all document buffers before this operation | |
6835 | (reftex-save-all-document-buffers) | |
6836 | ||
6837 | ;; First test to check for erros | |
6838 | (setq n (reftex-translate | |
6839 | files search-re translate-alist error-fmt 'test)) | |
6840 | ||
6841 | ;; Now the real thing. | |
6842 | (if (yes-or-no-p | |
6843 | (format "Replace %d items at %d places in %d files? " | |
6844 | (length translate-alist) n (length files))) | |
6845 | (progn | |
6846 | (let ((inhibit-quit t)) ;; Do not disturb... | |
6847 | (reftex-translate | |
6848 | files search-re translate-alist error-fmt nil) | |
6849 | (setq quit-flag nil)) | |
6850 | (if (and (reftex-is-multi) | |
6851 | (yes-or-no-p "Save entire document? ")) | |
6852 | (reftex-save-all-document-buffers)) | |
6853 | ;; Rescan again... | |
6854 | (reftex-access-scan-info 1) | |
6855 | (message "Done replacing simple labels.")) | |
6856 | (message "No replacements done")))) | |
6857 | ||
6858 | (defun reftex-translate (files search-re translate-alist error-fmt test) | |
6859 | ;; In FILES, look for SEARCH-RE and replace match 1 of it with | |
6860 | ;; its association in TRANSLATE-ALSIT. | |
6861 | ;; If we do not find an association and TEST is non-nil, query | |
6862 | ;; to ignore the problematic string. | |
6863 | ;; If TEST is nil, it is ignored without query. | |
6864 | ;; Return the number of replacements. | |
6865 | (let ((n 0) file label match-data buf macro pos cell) | |
6866 | (while (setq file (pop files)) | |
6867 | (setq buf (reftex-get-file-buffer-force file)) | |
6868 | (unless buf | |
6869 | (error "No such file %s" file)) | |
6870 | (set-buffer buf) | |
6871 | (save-excursion | |
6872 | (save-restriction | |
6873 | (widen) | |
6874 | (goto-char (point-min)) | |
6875 | (while (re-search-forward search-re nil t) | |
6876 | (save-excursion | |
6877 | (backward-char) | |
6878 | (setq label (reftex-match-string 1) | |
6879 | cell (assoc label translate-alist) | |
6880 | match-data (match-data) | |
6881 | macro (reftex-what-macro 1) | |
6882 | pos (cdr macro)) | |
6883 | (goto-char (or pos (point))) | |
6884 | (when (and macro | |
6885 | (or (looking-at "\\\\ref") | |
6886 | (looking-at "\\\\[a-zA-Z]*ref[^a-zA-Z]") | |
6887 | (looking-at "\\\\ref[a-zA-Z]*[^a-zA-Z]") | |
6888 | (looking-at (format | |
6889 | reftex-find-label-regexp-format | |
6890 | (regexp-quote label))))) | |
6891 | ;; OK, we should replace it. | |
6892 | (set-match-data match-data) | |
6893 | (cond | |
6894 | ((and test (not cell)) | |
6895 | ;; We've got a problem | |
6896 | (unwind-protect | |
6897 | (progn | |
6898 | (reftex-highlight 1 (match-beginning 0) (match-end 0)) | |
6899 | (ding) | |
6900 | (or (y-or-n-p (format error-fmt label)) | |
6901 | (error "Abort"))) | |
6902 | (reftex-unhighlight 1))) | |
6903 | ((and test cell) | |
6904 | (incf n)) | |
6905 | ((and (not test) cell) | |
6906 | ;; Replace | |
6907 | (goto-char (match-beginning 1)) | |
6908 | (delete-region (match-beginning 1) (match-end 1)) | |
6909 | (insert (cdr cell))) | |
6910 | (t nil)))))))) | |
6911 | n)) | |
a7ec1775 | 6912 | |
b849548d CD |
6913 | (defun reftex-save-all-document-buffers () |
6914 | "Save all documents associated with the current document. | |
6915 | The function is useful after a global action like replacing or renumbering | |
6916 | labels." | |
6917 | (interactive) | |
6918 | (let ((files (reftex-all-document-files)) | |
6919 | file buffer) | |
6920 | (save-excursion | |
6921 | (while (setq file (pop files)) | |
6922 | (setq buffer (reftex-get-buffer-visiting file)) | |
6923 | (when buffer | |
6924 | (set-buffer buffer) | |
6925 | (save-buffer)))))) | |
c52bdfca | 6926 | |
b849548d CD |
6927 | ;;; ========================================================================= |
6928 | ;;; | |
6929 | ;;; AUCTeX Interface | |
a7ec1775 | 6930 | |
b849548d CD |
6931 | (defun reftex-plug-flag (which) |
6932 | ;; Tell if a certain flag is set in reftex-plug-into-AUCTeX | |
6933 | (or (eq t reftex-plug-into-AUCTeX) | |
6934 | (and (listp reftex-plug-into-AUCTeX) | |
6935 | (nth which reftex-plug-into-AUCTeX)))) | |
a7ec1775 | 6936 | |
b849548d CD |
6937 | (defun reftex-arg-label (optional &optional prompt definition) |
6938 | "Use `reftex-label', `reftex-reference' or AUCTeX's code to insert label arg. | |
6939 | What is being used depends upon `reftex-plug-into-AUCTeX'." | |
6940 | (let (label) | |
6941 | (cond | |
6942 | ((and definition (reftex-plug-flag 1)) | |
6943 | ;; Create a new label, with a temporary brace for `reftex-what-macro' | |
6944 | (unwind-protect | |
6945 | (progn (insert "{") (setq label (or (reftex-label nil t) ""))) | |
6946 | (delete-backward-char 1))) | |
6947 | ((and (not definition) (reftex-plug-flag 2)) | |
6948 | ;; Reference a label with RefTeX | |
6949 | (setq label (reftex-reference nil t))) | |
6950 | (t | |
6951 | ;; AUCTeX's default mechanism | |
6952 | (setq label (completing-read (TeX-argument-prompt optional prompt "Key") | |
6953 | (LaTeX-label-list))))) | |
6954 | (if (and definition (not (string-equal "" label))) | |
6955 | (LaTeX-add-labels label)) | |
6956 | (TeX-argument-insert label optional optional))) | |
2faef409 | 6957 | |
b849548d CD |
6958 | (defun reftex-arg-cite (optional &optional prompt definition) |
6959 | "Use `reftex-citation' or AUCTeX's code to insert a cite-key macro argument. | |
6960 | What is being used depends upon `reftex-plug-into-AUCTeX'." | |
6961 | (let (items) | |
6962 | (cond | |
6963 | ((and (not definition) (reftex-plug-flag 3)) | |
6964 | (setq items (list (or (reftex-citation t) "")))) | |
6965 | (t | |
6966 | (setq prompt (concat (if optional "(Optional) " "") | |
6967 | (if prompt prompt "Add key") | |
6968 | ": (default none) ")) | |
6969 | (setq items (multi-prompt "," t prompt (LaTeX-bibitem-list))))) | |
6970 | (apply 'LaTeX-add-bibitems items) | |
6971 | (TeX-argument-insert (mapconcat 'identity items ",") optional optional))) | |
a7ec1775 | 6972 | |
b849548d CD |
6973 | (defun reftex-plug-into-AUCTeX () |
6974 | ;; Replace AUCTeX functions with RefTeX functions. | |
6975 | ;; Which functions are replaced is controlled by the variable | |
6976 | ;; `reftex-plug-into-AUCTeX'. | |
6977 | ||
6978 | (if (reftex-plug-flag 0) | |
6979 | (setq LaTeX-label-function 'reftex-label) | |
6980 | (setq LaTeX-label-function nil)) | |
a7ec1775 | 6981 | |
b849548d CD |
6982 | (if (and (or (reftex-plug-flag 1) (reftex-plug-flag 2)) |
6983 | (fboundp 'TeX-arg-label)) | |
6984 | (fset 'TeX-arg-label 'reftex-arg-label)) | |
a7ec1775 | 6985 | |
b849548d CD |
6986 | (if (and (reftex-plug-flag 3) |
6987 | (fboundp 'TeX-arg-cite)) | |
6988 | (fset 'TeX-arg-cite 'reftex-arg-cite))) | |
396e0b08 | 6989 | |
b849548d CD |
6990 | (defun reftex-toggle-plug-into-AUCTeX () |
6991 | "Toggle Interface between AUCTeX and RefTeX on and off." | |
6992 | (interactive) | |
6993 | (unless (and (featurep 'tex-site) (featurep 'latex)) | |
921759ee | 6994 | (error "AUCTeX's LaTeX mode does not seem to be loaded")) |
b849548d CD |
6995 | (setq reftex-plug-into-AUCTeX (not reftex-plug-into-AUCTeX)) |
6996 | (reftex-plug-into-AUCTeX) | |
6997 | (if reftex-plug-into-AUCTeX | |
6998 | (message "RefTeX has been plugged into AUCTeX.") | |
6999 | (message "RefTeX no longer interacts with AUCTeX."))) | |
a7ec1775 | 7000 | |
b849548d CD |
7001 | (defun reftex-add-label-environments (entry-list) |
7002 | "Add label environment descriptions to `reftex-label-alist-style'. | |
7003 | The format of ENTRY-LIST is exactly like `reftex-label-alist'. See there | |
7004 | for details. | |
7005 | This function makes it possible to support RefTeX from AUCTeX style files. | |
7006 | The entries in ENTRY-LIST will be processed after the user settings in | |
7007 | `reftex-label-alist', and before the defaults (specified in | |
7008 | `reftex-default-label-alist-entries'). Any changes made to | |
7009 | `reftex-label-alist-style' will raise a flag to the effect that | |
7010 | the label information is recompiled on next use." | |
7011 | (unless reftex-docstruct-symbol | |
7012 | (reftex-tie-multifile-symbols)) | |
7013 | (when (and reftex-docstruct-symbol | |
7014 | (symbolp reftex-docstruct-symbol)) | |
7015 | (let ((list (get reftex-docstruct-symbol 'reftex-label-alist-style)) | |
7016 | entry changed) | |
7017 | (while entry-list | |
7018 | (setq entry (pop entry-list)) | |
7019 | (unless (member entry list) | |
7020 | (setq reftex-tables-dirty t | |
7021 | changed t) | |
7022 | (push entry list))) | |
7023 | (when changed | |
7024 | (put reftex-docstruct-symbol 'reftex-label-alist-style list))))) | |
7025 | (defalias 'reftex-add-to-label-alist 'reftex-add-label-environments) | |
7026 | ||
7027 | (defun reftex-add-section-levels (entry-list) | |
7028 | "Add entries to the value of `reftex-section-levels'. | |
7029 | The added values are kept local to the current document. The format | |
7030 | of ENTRY-LIST is a list of cons cells (\"MACRONAME\" . LEVEL). See | |
7031 | `reftex-section-levels' for an example." | |
7032 | (unless reftex-docstruct-symbol | |
7033 | (reftex-tie-multifile-symbols)) | |
7034 | (when (and reftex-docstruct-symbol | |
7035 | (symbolp reftex-docstruct-symbol)) | |
7036 | (let ((list (get reftex-docstruct-symbol 'reftex-section-levels)) | |
7037 | entry changed) | |
7038 | (while entry-list | |
7039 | (setq entry (pop entry-list)) | |
7040 | (unless (member entry list) | |
7041 | (setq reftex-tables-dirty t | |
7042 | changed t) | |
7043 | (push entry list))) | |
7044 | (when changed | |
7045 | (put reftex-docstruct-symbol 'reftex-section-levels list))))) | |
7046 | ||
7047 | (defun reftex-set-cite-format (value) | |
7048 | "Set the document-local value of `reftex-cite-format'. | |
7049 | When such a value exists, it overwrites the setting given with | |
7050 | `reftex-cite-format'. See the documentation of `reftex-cite-format' | |
7051 | for possible values. This function should be used from AUCTeX style files." | |
7052 | (unless reftex-docstruct-symbol | |
7053 | (reftex-tie-multifile-symbols)) | |
7054 | (when (and reftex-docstruct-symbol | |
7055 | (symbolp reftex-docstruct-symbol)) | |
7056 | (put reftex-docstruct-symbol 'reftex-cite-format value))) | |
7057 | ||
7058 | (defun reftex-notice-new-section () | |
7059 | "Hook to handshake with RefTeX after a new section has been inserted." | |
7060 | ;; Add a new section to the docstruct list and renumber the | |
7061 | ;; following sections. This hook has to be called immediately after | |
7062 | ;; the new section was inserted into the buffer, and before the | |
7063 | ;; section label is created. | |
2faef409 | 7064 | |
b849548d CD |
7065 | (condition-case nil |
7066 | (catch 'exit | |
7067 | (unless reftex-mode (throw 'exit nil)) | |
7068 | (reftex-access-scan-info) | |
7069 | (let* ((docstruct (symbol-value reftex-docstruct-symbol)) | |
7070 | here-am-I appendix tail toc-entry star level | |
7071 | section-number context) | |
a7ec1775 | 7072 | |
b849548d CD |
7073 | (save-excursion |
7074 | (when (re-search-backward reftex-section-regexp nil t) | |
7075 | ||
7076 | ;; Find where we are | |
7077 | (setq here-am-I (reftex-where-am-I)) | |
7078 | (unless (cdr here-am-I) (throw 'exit nil)) | |
7079 | (setq reftex-active-toc (reftex-last-assoc-before-elt | |
7080 | 'toc (car here-am-I) docstruct) | |
7081 | appendix (reftex-last-assoc-before-elt | |
7082 | 'appendix (car here-am-I) docstruct)) | |
7083 | ||
7084 | ;; Initialize section numbers | |
7085 | (if (eq (car (car here-am-I)) 'appendix) | |
7086 | (reftex-init-section-numbers nil t) | |
7087 | (reftex-init-section-numbers reftex-active-toc appendix)) | |
7088 | ||
7089 | ;; Match the section command | |
7090 | (when (and (re-search-forward reftex-everything-regexp nil t) | |
7091 | (match-end 3)) | |
7092 | (setq star (= ?* (char-after (match-end 3))) | |
7093 | toc-entry (reftex-section-info (buffer-file-name)) | |
7094 | level (nth 5 toc-entry) | |
7095 | tail (memq (car here-am-I) | |
7096 | (symbol-value reftex-docstruct-symbol))) | |
7097 | (if tail | |
7098 | ;; Insert the section info | |
7099 | (push toc-entry (cdr tail)) | |
7100 | (throw 'exit nil)) | |
7101 | ||
7102 | ;; We are done unless we use section numbers | |
7103 | (unless (nth 1 reftex-label-menu-flags) (throw 'exit nil)) | |
7104 | ||
7105 | ;; Update the remaining toc items | |
7106 | (setq tail (cdr tail)) | |
7107 | (while (and (setq tail (memq (assq 'toc (cdr tail)) tail)) | |
7108 | (setq toc-entry (car tail)) | |
7109 | (>= (nth 5 toc-entry) level)) | |
7110 | (setq section-number | |
7111 | (reftex-section-number (nth 5 toc-entry) star) | |
7112 | context (nth 2 toc-entry)) | |
7113 | (when (string-match "\\`\\([ \t]*\\)\\([.0-9A-Z]+\\)\\(.*\\)" | |
7114 | context) | |
7115 | (when (and (not appendix) | |
7116 | (>= (string-to-char (match-string 2)) ?A)) | |
7117 | ;; Just entered the appendex. Get out. | |
7118 | (throw 'exit nil)) | |
7119 | ||
7120 | ;; Change the section number. | |
7121 | (setf (nth 2 toc-entry) | |
7122 | (concat (match-string 1 context) | |
7123 | section-number | |
7124 | (match-string 3 context)))))))))) | |
7125 | (error nil)) | |
7126 | ) | |
7127 | ||
7128 | ;;; ========================================================================= | |
7129 | ;;; | |
7130 | ;;; Keybindings | |
a7ec1775 | 7131 | |
b849548d CD |
7132 | ;; The default bindings in the mode map. |
7133 | (loop for x in | |
7134 | '(("\C-c=" . reftex-toc) | |
7135 | ("\C-c(" . reftex-label) | |
7136 | ("\C-c)" . reftex-reference) | |
7137 | ("\C-c[" . reftex-citation) | |
7138 | ("\C-c&" . reftex-view-crossref)) | |
7139 | do (define-key reftex-mode-map (car x) (cdr x))) | |
a7ec1775 | 7140 | |
921759ee CD |
7141 | (eval-after-load |
7142 | "bibtex" | |
7143 | '(define-key bibtex-mode-map "\C-c&" 'reftex-view-crossref-from-bibtex)) | |
7144 | ||
1c0dde84 | 7145 | ;; Bind `reftex-mouse-view-crossref' only when the key is still free |
921759ee CD |
7146 | (let ((key (if (featurep 'xemacs) [(shift button2)] [(shift mouse-2)]))) |
7147 | (unless (key-binding key) | |
7148 | (define-key reftex-mode-map key 'reftex-mouse-view-crossref))) | |
1c0dde84 | 7149 | |
a7ec1775 | 7150 | ;; If the user requests so, she can have a few more bindings: |
b849548d CD |
7151 | (when reftex-extra-bindings |
7152 | (loop for x in | |
7153 | '(("\C-ct" . reftex-toc) | |
7154 | ("\C-cl" . reftex-label) | |
7155 | ("\C-cr" . reftex-reference) | |
7156 | ("\C-cc" . reftex-citation) | |
7157 | ("\C-cv" . reftex-view-crossref) | |
7158 | ("\C-cg" . reftex-grep-document) | |
7159 | ("\C-cs" . reftex-search-document)) | |
7160 | do (define-key reftex-mode-map (car x) (cdr x)))) | |
7161 | ||
7162 | ;; Common bindings in reftex-select-label-map and reftex-select-bib-map | |
2faef409 | 7163 | (let ((map (make-sparse-keymap))) |
2faef409 RS |
7164 | (substitute-key-definition |
7165 | 'next-line 'reftex-select-next map global-map) | |
7166 | (substitute-key-definition | |
7167 | 'previous-line 'reftex-select-previous map global-map) | |
7168 | (substitute-key-definition | |
29d593f8 | 7169 | 'keyboard-quit 'reftex-select-keyboard-quit map global-map) |
2faef409 RS |
7170 | (substitute-key-definition |
7171 | 'newline 'reftex-select-accept map global-map) | |
29d593f8 | 7172 | |
b849548d CD |
7173 | (loop for x in |
7174 | '((" " . reftex-select-callback) | |
7175 | ("n" . reftex-select-next) | |
7176 | ([(down)] . reftex-select-next) | |
7177 | ("p" . reftex-select-previous) | |
7178 | ([(up)] . reftex-select-previous) | |
7179 | ("f" . reftex-select-toggle-follow) | |
7180 | ("\C-m" . reftex-select-accept) | |
7181 | ([(return)] . reftex-select-accept) | |
7182 | ("q" . reftex-select-quit) | |
7183 | ("." . reftex-select-show-insertion-point) | |
7184 | ("?" . reftex-select-help)) | |
7185 | do (define-key map (car x) (cdr x))) | |
7186 | ||
7187 | ;; The mouse-2 binding | |
921759ee CD |
7188 | (define-key map (if (featurep 'xemacs) [(button2)] [(mouse-2)]) |
7189 | 'reftex-select-mouse-accept) | |
b849548d CD |
7190 | |
7191 | ;; Digit arguments | |
29d593f8 KH |
7192 | (loop for key across "0123456789" do |
7193 | (define-key map (vector (list key)) 'digit-argument)) | |
7194 | (define-key map "-" 'negative-argument) | |
2faef409 | 7195 | |
b849548d | 7196 | ;; Make two maps |
2faef409 | 7197 | (setq reftex-select-label-map map) |
b849548d CD |
7198 | (setq reftex-select-bib-map (copy-keymap map))) |
7199 | ||
7200 | ;; Specific bindings in reftex-select-label-map | |
7201 | (loop for key across "cgilrRstx#%" do | |
7202 | (define-key reftex-select-label-map (vector (list key)) | |
7203 | (list 'lambda '() | |
7204 | "Press `?' during selection to find out about this key." | |
7205 | '(interactive) (list 'throw '(quote myexit) key)))) | |
7206 | ||
7207 | (loop for x in | |
7208 | '(("b" . reftex-select-jump-to-previous) | |
7209 | ("v" . reftex-select-toggle-varioref) | |
7210 | ([(tab)] . reftex-select-read-label) | |
7211 | ("\C-i" . reftex-select-read-label) | |
7212 | ("\C-c\C-n" . reftex-select-next-heading) | |
7213 | ("\C-c\C-p" . reftex-select-previous-heading)) | |
7214 | do | |
7215 | (define-key reftex-select-label-map (car x) (cdr x))) | |
7216 | ||
7217 | ;; Specific bindings in reftex-select-bib-map | |
7218 | (loop for key across "grRaA" do | |
7219 | (define-key reftex-select-bib-map (vector (list key)) | |
7220 | (list 'lambda '() | |
7221 | "Press `?' during selection to find out about this key." | |
7222 | '(interactive) (list 'throw '(quote myexit) key)))) | |
7223 | ||
7224 | (loop for x in | |
7225 | '(("\C-i" . reftex-select-read-cite) | |
7226 | ([(tab)] . reftex-select-read-cite)) | |
7227 | do (define-key reftex-select-bib-map (car x) (cdr x))) | |
7228 | ||
2faef409 | 7229 | ;; Table of Contents map |
921759ee CD |
7230 | (define-key reftex-toc-map (if (featurep 'xemacs) [(button2)] [(mouse-2)]) |
7231 | 'reftex-toc-mouse-goto-line-and-hide) | |
b849548d | 7232 | |
f9ad2e24 CD |
7233 | (substitute-key-definition |
7234 | 'next-line 'reftex-toc-next reftex-toc-map global-map) | |
7235 | (substitute-key-definition | |
7236 | 'previous-line 'reftex-toc-previous reftex-toc-map global-map) | |
7237 | ||
b849548d | 7238 | (loop for x in |
f9ad2e24 CD |
7239 | '(("n" . reftex-toc-next) |
7240 | ("p" . reftex-toc-previous) | |
b849548d CD |
7241 | ("?" . reftex-toc-show-help) |
7242 | (" " . reftex-toc-view-line) | |
7243 | ("\C-m" . reftex-toc-goto-line-and-hide) | |
7244 | ("\C-i" . reftex-toc-goto-line) | |
7245 | ("r" . reftex-toc-rescan) | |
7246 | ("R" . reftex-toc-Rescan) | |
7247 | ("g" . revert-buffer) | |
7248 | ("q" . reftex-toc-quit) | |
7249 | ("Q" . reftex-toc-quit-and-kill) | |
7250 | ("f" . reftex-toc-toggle-follow) | |
f9ad2e24 CD |
7251 | ("i" . reftex-toc-toggle-file-boundary) |
7252 | ("l" . reftex-toc-toggle-labels) | |
7253 | ("c" . reftex-toc-toggle-context) | |
7254 | ("%" . reftex-toc-toggle-commented) | |
b849548d | 7255 | ("x" . reftex-toc-external) |
f9ad2e24 | 7256 | ("." . reftex-toc-show-calling-point)) |
b849548d CD |
7257 | do (define-key reftex-toc-map (car x) (cdr x))) |
7258 | ||
7259 | (loop for key across "0123456789" do | |
7260 | (define-key reftex-toc-map (vector (list key)) 'digit-argument)) | |
7261 | (define-key reftex-toc-map "-" 'negative-argument) | |
2faef409 | 7262 | |
b849548d CD |
7263 | ;;; ========================================================================= |
7264 | ;;; | |
7265 | ;;; Menu | |
a7ec1775 RS |
7266 | |
7267 | ;; Define a menu for the menu bar if Emacs is running under X | |
7268 | ||
7269 | (require 'easymenu) | |
7270 | ||
f9ad2e24 | 7271 | (easy-menu-define reftex-mode-menu reftex-mode-map |
a7ec1775 | 7272 | "Menu used in RefTeX mode" |
396e0b08 | 7273 | `("Ref" |
206c6f82 | 7274 | ["Table of Contents" reftex-toc t] |
b849548d | 7275 | "---" |
206c6f82 RS |
7276 | ["\\label" reftex-label t] |
7277 | ["\\ref" reftex-reference t] | |
7278 | ["\\cite" reftex-citation t] | |
396e0b08 | 7279 | ["View Crossref" reftex-view-crossref t] |
b849548d | 7280 | "---" |
396e0b08 KH |
7281 | ("Parse Document" |
7282 | ["Only this File" reftex-parse-one t] | |
7283 | ["Entire Document" reftex-parse-all (reftex-is-multi)] | |
baec1250 | 7284 | ["Save to File" (reftex-access-parse-file 'write) |
396e0b08 | 7285 | (> (length (symbol-value reftex-docstruct-symbol)) 0)] |
2faef409 | 7286 | ["Restore from File" (reftex-access-parse-file 'restore) t] |
396e0b08 KH |
7287 | "---" |
7288 | ["Reset RefTeX Mode" reftex-reset-mode t]) | |
2faef409 | 7289 | ("Global Actions" |
baec1250 KH |
7290 | ["Search Whole Document" reftex-search-document t] |
7291 | ["Replace in Document" reftex-query-replace-document t] | |
7292 | ["Grep on Document" reftex-grep-document t] | |
b849548d | 7293 | "---" |
baec1250 | 7294 | ["Create TAGS File" reftex-create-tags-file t] |
b849548d | 7295 | "---" |
baec1250 | 7296 | ["Find Duplicate Labels" reftex-find-duplicate-labels t] |
2faef409 | 7297 | ["Change Label and Refs" reftex-change-label t] |
b849548d | 7298 | ["Renumber Simple Labels" reftex-renumber-simple-labels t] |
2faef409 | 7299 | "---" |
f9ad2e24 | 7300 | ["Save Document" reftex-save-all-document-buffers t]) |
2faef409 | 7301 | "---" |
b849548d | 7302 | ("Options" |
921759ee CD |
7303 | "PARSER" |
7304 | ["Partial Scans" | |
7305 | (setq reftex-enable-partial-scans (not reftex-enable-partial-scans)) | |
7306 | :style toggle :selected reftex-enable-partial-scans] | |
7307 | ["Auto-Save Parse Info" | |
7308 | (setq reftex-save-parse-info (not reftex-save-parse-info)) | |
7309 | :style toggle :selected reftex-save-parse-info] | |
7310 | "---" | |
7311 | "CROSSREF INFO" | |
7312 | ["Automatic Info" reftex-toggle-auto-view-crossref | |
7313 | :style toggle :selected reftex-auto-view-crossref-timer] | |
7314 | ["...in Echo Area" (setq reftex-auto-view-crossref t) | |
7315 | :style radio :selected (eq reftex-auto-view-crossref t)] | |
7316 | ["...in Other Window" (setq reftex-auto-view-crossref 'window) | |
7317 | :style radio :selected (eq reftex-auto-view-crossref 'window)] | |
7318 | "---" | |
7319 | "MISC" | |
7320 | ["AUC TeX Interface" reftex-toggle-plug-into-AUCTeX | |
7321 | :style toggle :selected reftex-plug-into-AUCTeX]) | |
7322 | ("Reference Style" | |
7323 | ["Standard" (setq reftex-vref-is-default nil) | |
7324 | :style radio :selected (not reftex-vref-is-default)] | |
7325 | ["Varioref" (setq reftex-vref-is-default t) | |
7326 | :style radio :selected reftex-vref-is-default]) | |
7327 | ("Citation Style" | |
7328 | ,@(mapcar | |
7329 | (function | |
7330 | (lambda (x) | |
7331 | (vector | |
7332 | (capitalize (symbol-name (car x))) | |
7333 | (list 'reftex-set-cite-format (list 'quote (car x))) | |
7334 | :style 'radio :selected | |
7335 | (list 'eq (list 'reftex-get-cite-format) (list 'quote (car x)))))) | |
7336 | reftex-cite-format-builtin) | |
7337 | "---" | |
7338 | "Sort Database Matches" | |
7339 | ["Not" (setq reftex-sort-bibtex-matches nil) | |
7340 | :style radio :selected (eq reftex-sort-bibtex-matches nil)] | |
7341 | ["by Author" (setq reftex-sort-bibtex-matches 'author) | |
7342 | :style radio :selected (eq reftex-sort-bibtex-matches 'author)] | |
7343 | ["by Year" (setq reftex-sort-bibtex-matches 'year) | |
7344 | :style radio :selected (eq reftex-sort-bibtex-matches 'year)] | |
7345 | ["by Year, reversed" (setq reftex-sort-bibtex-matches 'reverse-year) | |
7346 | :style radio :selected (eq reftex-sort-bibtex-matches 'reverse-year)]) | |
7347 | "---" | |
2faef409 | 7348 | ("Customize" |
f9ad2e24 | 7349 | ["Browse RefTeX Group" reftex-customize t] |
2faef409 RS |
7350 | "---" |
7351 | ["Build Full Customize Menu" reftex-create-customize-menu | |
7352 | (fboundp 'customize-menu-create)]) | |
2faef409 RS |
7353 | ("Documentation" |
7354 | ["Info" reftex-info t] | |
7355 | ["Commentary" reftex-show-commentary t]))) | |
a7ec1775 | 7356 | |
b849548d CD |
7357 | (defun reftex-customize () |
7358 | "Call the customize function with reftex as argument." | |
7359 | (interactive) | |
7360 | (customize-browse 'reftex)) | |
7361 | ||
7362 | (defun reftex-create-customize-menu () | |
7363 | "Create a full customization menu for RefTeX, insert it into the menu." | |
7364 | (interactive) | |
7365 | (if (fboundp 'customize-menu-create) | |
7366 | (progn | |
7367 | (easy-menu-change | |
7368 | '("Ref") "Customize" | |
7369 | `(["Browse RefTeX group" reftex-customize t] | |
7370 | "---" | |
7371 | ,(customize-menu-create 'reftex) | |
7372 | ["Set" Custom-set t] | |
7373 | ["Save" Custom-save t] | |
7374 | ["Reset to Current" Custom-reset-current t] | |
7375 | ["Reset to Saved" Custom-reset-saved t] | |
7376 | ["Reset to Standard Settings" Custom-reset-standard t])) | |
7377 | (message "\"Ref\"-menu now contains full customization menu")) | |
7378 | (error "Cannot expand menu (outdated version of cus-edit.el)"))) | |
7379 | ||
7380 | (defun reftex-show-commentary () | |
7381 | "Use the finder to view the file documentation from `reftex.el'." | |
7382 | (interactive) | |
7383 | (require 'finder) | |
7384 | (finder-commentary "reftex.el")) | |
7385 | ||
7386 | (defun reftex-info () | |
7387 | "Read documentation for RefTeX in the info system." | |
7388 | (interactive) | |
7389 | (require 'info) | |
7390 | (Info-goto-node "(reftex)")) | |
7391 | ||
b849548d CD |
7392 | ;;; Install the kill-buffer and kill-emacs hooks ------------------------------ |
7393 | ||
7394 | (add-hook 'kill-buffer-hook 'reftex-kill-buffer-hook) | |
7395 | (add-hook 'kill-emacs-hook 'reftex-kill-emacs-hook) | |
7396 | ||
a7ec1775 RS |
7397 | ;;; Run Hook ------------------------------------------------------------------ |
7398 | ||
7399 | (run-hooks 'reftex-load-hook) | |
7400 | ||
7401 | ;;; That's it! ---------------------------------------------------------------- | |
7402 | ||
6b94c6ad | 7403 | (setq reftex-tables-dirty t) ; in case this file is evaluated by hand |
396e0b08 KH |
7404 | (provide 'reftex) |
7405 | ||
a7ec1775 RS |
7406 | ;;;============================================================================ |
7407 | ||
c52bdfca | 7408 | ;;; reftex.el ends here |
b849548d | 7409 | |
921759ee | 7410 |