Mercurial > emacs
comparison lisp/textmodes/reftex.el @ 18050:506b35a4537e
Initial revision
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sat, 31 May 1997 00:34:13 +0000 |
parents | |
children | 7831ac89a334 |
comparison
equal
deleted
inserted
replaced
18049:f1fa9625e2b9 | 18050:506b35a4537e |
---|---|
1 ;; reftex.el --- Minor mode for doing \label{} \ref{} and \cite{} in LaTeX | |
2 ;; Copyright (c) 1997 Free Software Foundation, Inc. | |
3 | |
4 ;; Author: Carsten Dominik <dominik@strw.LeidenUniv.nl> | |
5 ;; Keywords: tex | |
6 | |
7 ;; This file is part of GNU Emacs. | |
8 | |
9 ;; GNU Emacs is free software; you can redistribute it and/or modify | |
10 ;; it under the terms of the GNU General Public License as published by | |
11 ;; the Free Software Foundation; either version 2, or (at your option) | |
12 ;; any later version. | |
13 | |
14 ;; GNU Emacs is distributed in the hope that it will be useful, | |
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 ;; GNU General Public License for more details. | |
18 | |
19 ;; You should have received a copy of the GNU General Public License | |
20 ;; along with GNU Emacs; see the file COPYING. If not, write to the | |
21 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
22 ;; Boston, MA 02111-1307, USA. | |
23 | |
24 ;;--------------------------------------------------------------------------- | |
25 ;; | |
26 ;;; Commentary: | |
27 ;; | |
28 ;; RefTeX is a minor mode with distinct support for \ref{}, \label{} and | |
29 ;; \cite{} commands in (multi-file) LaTeX documents. | |
30 ;; Labels are created semi-automatically. Definition context of labels is | |
31 ;; provided when creating a reference. Citations are simplified with | |
32 ;; efficient database lookup. | |
33 ;; | |
34 ;; To turn RefTeX Minor Mode on and off in a particular buffer, use | |
35 ;; `M-x reftex-mode'. | |
36 ;; | |
37 ;; To turn on RefTeX Minor Mode for all LaTeX files, add one of the | |
38 ;; following lines to your .emacs file: | |
39 ;; | |
40 ;; (add-hook 'LaTeX-mode-hook 'turn-on-reftex) ; with AUCTeX LaTeX mode | |
41 ;; (add-hook 'latex-mode-hook 'turn-on-reftex) ; with Emacs latex mode | |
42 ;; | |
43 ;; For key bindings, see further down in this documentation. | |
44 ;; | |
45 ;;--------------------------------------------------------------------------- | |
46 ;; | |
47 ;; OVERVIEW | |
48 ;; | |
49 ;; 1. USING \label{} AND \ref{}. Labels and references are one of the | |
50 ;; strong points of LaTeX. But, in documents with hundreds of | |
51 ;; equations, figures, tables etc. it becomes quickly impossible to | |
52 ;; find good label names and to actually remember them. Then, also | |
53 ;; completion of labels in not enough. One actually needs to see the | |
54 ;; context of the label definition to find the right one. | |
55 ;; | |
56 ;; - RefTeX distinguishes labels for different environments. It | |
57 ;; always knows if a certain label references a figure, table | |
58 ;; etc. You can configure RefTeX to recognize any additional | |
59 ;; labeled environments you might have defined yourself. | |
60 ;; | |
61 ;; - RefTeX defines automatically unique labels. Type `C-c (' | |
62 ;; (reftex-label) to insert a label at point. RefTeX will either | |
63 ;; - derive a label from context (default for section labels) | |
64 ;; - insert a simple label consisting of a prefix and a number | |
65 ;; (default for equations and enumerate items) or | |
66 ;; - prompt for a label string (figures and tables) | |
67 ;; Which labels are created how can be controlled with the variable | |
68 ;; reftex-insert-label-flags. | |
69 ;; | |
70 ;; - Referencing labels is a snap and I promise you'll love it. | |
71 ;; In order to make a reference, type `C-c )' (reftex-reference). | |
72 ;; This shows an outline of the documents with all labels of a | |
73 ;; certain type (figure, equation,...) and context of the label | |
74 ;; definition. Selecting one of the labels inserts a \ref{} macro | |
75 ;; into the original buffer. Online help during the selection is | |
76 ;; available with `?'. | |
77 ;; | |
78 ;; 2. CITATIONS. After typing `C-c [' (reftex-citation), RefTeX will | |
79 ;; let you specify a regexp to search in current BibTeX database files | |
80 ;; (as specified in the \bibliography command) and pull out a formatted | |
81 ;; list of matches for you to choose from. The list is *formatted* and | |
82 ;; thus much easier to read than the raw database entries. It can also | |
83 ;; be sorted. The text inserted into the buffer is by default just | |
84 ;; `\cite{KEY}', but can also contain author names and the year in a | |
85 ;; configurable way. See documentation of the variable | |
86 ;; reftex-cite-format. | |
87 ;; | |
88 ;; 3. TABLE OF CONTENTS. Typing `C-c =' (reftex-toc) will show | |
89 ;; a table of contents of the document. From that buffer, you can | |
90 ;; jump quickly to every part of your document. This is similar to | |
91 ;; imenu, only it works for entire multifile documents and uses the | |
92 ;; keyboard rather than the mouse. The initial version of this | |
93 ;; function was contributed by Stephen Eglen. | |
94 ;; | |
95 ;; 4. MULTIFILE DOCUMENTS are supported in the same way as by AUCTeX. | |
96 ;; I.e. if a source file is not a full LaTeX document by itself, | |
97 ;; but included by another file, you may specify the name of | |
98 ;; the (top level) master file in a local variable section at the | |
99 ;; end of the source file, like so: | |
100 ;; | |
101 ;; %%% Local Variables: | |
102 ;; %%% TeX-master: my_master.tex | |
103 ;; %%% End: | |
104 ;; | |
105 ;; This will only take effect when you load the file next time or when | |
106 ;; you reset RefTeX with M-x reftex-reset-mode. | |
107 ;; | |
108 ;; RefTeX will also recognize the file variable tex-main-file. This | |
109 ;; variable is used by the Emacs TeX modes and works just like | |
110 ;; AUCTeX's TeX-master variable. See the documentation of your TeX/LaTeX | |
111 ;; modes. | |
112 ;; | |
113 ;; RefTeX knows about all files related to a document via input and | |
114 ;; include. It provides functions to run regular expression searches and | |
115 ;; replaces over the entire document and to create a TAGS file. | |
116 ;; | |
117 ;; 5. DOCUMENT PARSING. RefTeX needs to parse the document in order to find | |
118 ;; labels and other information. It will do it automatically once, when | |
119 ;; you start working with a document. If you need to enforce reparsing | |
120 ;; later, call any of the functions reftex-citation, reftex-label, | |
121 ;; reftex-reference, reftex-toc with a raw C-u prefix. | |
122 ;; | |
123 ;;------------------------------------------------------------------------- | |
124 ;; | |
125 ;; CONFIGURATION | |
126 ;; | |
127 ;; RefTeX contains many configurable options which change the way it works. | |
128 ;; | |
129 ;; Most importantly, RefTeX needs to be configured if you use labels to | |
130 ;; mark non-standard environments. RefTeX always understands LaTeX section | |
131 ;; commands and the following environments: figure, figure*, | |
132 ;; sidewaysfigure, table, table*, sidewaystable, equation, eqnarray, | |
133 ;; enumerate. For everythings else, it needs to be configured. | |
134 ;; | |
135 ;; A good way to configure RefTeX is with the custom.el package by Per | |
136 ;; Abrahamsen, shipped with Emacs 20 and XEmacs 19.15. To do this, just | |
137 ;; say `M-x reftex-customize'. This will not work with older versions | |
138 ;; of custom.el. | |
139 ;; | |
140 ;; Here is a complete list of the RefTeX configuration variables with | |
141 ;; their default settings. You could copy this list to your .emacs file | |
142 ;; and change whatever is necessary. Each variable has an extensive | |
143 ;; documentation string. Look it up for more information! | |
144 ;; | |
145 ;; ;; Configuration Variables and User Options for RefTeX ------------------ | |
146 ;; ;; Support for \label{} and \ref{} -------------------------------------- | |
147 ;; (setq reftex-label-alist nil) | |
148 ;; (setq reftex-default-label-alist-entries '(Sideways LaTeX)) | |
149 ;; (setq reftex-use-text-after-label-as-context nil) | |
150 ;; ;; Label insertion | |
151 ;; (setq reftex-insert-label-flags '("s" "sft")) | |
152 ;; (setq reftex-derive-label-parameters '(3 20 t 1 "-" | |
153 ;; ("the" "on" "in" "off" "a" "for" "by" "of" "and" "is"))) | |
154 ;; (setq reftex-label-illegal-re "[\000-\040\177-\377\\\\#$%&~^_{}]") | |
155 ;; (setq reftex-abbrev-parameters '(4 2 "^saeiou" "aeiou")) | |
156 ;; ;; Label referencing | |
157 ;; (setq reftex-label-menu-flags '(t t nil nil nil nil)) | |
158 ;; (setq reftex-guess-label-type t) | |
159 ;; ;; BibteX citation configuration ---------------------------------------- | |
160 ;; (setq reftex-bibpath-environment-variables '("BIBINPUTS" "TEXBIB")) | |
161 ;; (setq reftex-bibfile-ignore-list nil) | |
162 ;; (setq reftex-sort-bibtex-matches 'reverse-year) | |
163 ;; (setq reftex-cite-format 'reftex-cite-format-default) | |
164 ;; ;; Table of contents configuration -------------------------------------- | |
165 ;; (setq reftex-toc-follow-mode nil) | |
166 ;; ;; Miscellaneous configurations ----------------------------------------- | |
167 ;; (setq reftex-extra-bindings nil) | |
168 ;; (setq reftex-use-fonts t) | |
169 ;; (setq reftex-keep-temporary-buffers t) | |
170 ;; (setq reftex-auto-show-entry t) | |
171 ;; | |
172 ;; CONFIGURATION EXAMPLES: | |
173 ;; ======================= | |
174 ;; | |
175 ;; Suppose you are working with AMS-LaTeX amsmath package (with its math | |
176 ;; environments like `align', `multiline' etc.). Here is how you would | |
177 ;; configure RefTeX to recognize these environments: | |
178 ;; | |
179 ;; (setq reftex-label-alist '(AMSTeX)) | |
180 ;; | |
181 ;; This is very easy since RefTeX has builtin support for AMS-LaTeX. | |
182 ;; Suppose, however, you are also | |
183 ;; | |
184 ;; - using "\newtheorem" in LaTeX in order to define two new environments | |
185 ;; "Theorem" and "Axiom" like this: | |
186 ;; | |
187 ;; \newtheorem{axiom}{Axiom} | |
188 ;; \newtheorem{theorem}{Theorem} | |
189 ;; | |
190 ;; - making your figures not directly with the figure environment, but with | |
191 ;; a macro like | |
192 ;; | |
193 ;; \newcommand{\myfig}[4][tbp]{ | |
194 ;; \begin{figure}[#1] | |
195 ;; \epsimp[#4]{#2} | |
196 ;; \caption{#3} | |
197 ;; \end{figure}} | |
198 ;; | |
199 ;; which would be called like | |
200 ;; | |
201 ;; \myfig{filename}{\label{fig:13} caption text}{1} | |
202 ;; | |
203 ;; Here is how to tell RefTeX to also recognize Theorem and Axiom as | |
204 ;; labeled environments, and that any labels defined inside the \myfig | |
205 ;; macro are figure labels: | |
206 ;; | |
207 ;; (setq reftex-label-alist | |
208 ;; '(AMSTeX | |
209 ;; ("axiom" ?a "ax:" "~\\ref{%s}" nil ("Axiom" "Ax.")) | |
210 ;; ("theorem" ?h "thr:" "~\\ref{%s}" t ("Theorem" "Theor." "Th.")) | |
211 ;; ("\\myfig" ?f "fig:" nil t))) | |
212 ;; | |
213 ;; The type indicator characters ?a and ?h are used for prompts when | |
214 ;; RefTeX queries for a label type. Note that "h" was chosen for "theorem" | |
215 ;; since "t" is already taken by "table". Note that also "s", "f", "e", "n" | |
216 ;; are taken by the standard environments. | |
217 ;; The automatic labels for Axioms and Theorems will look like "ax:23" or | |
218 ;; "thr:24". | |
219 ;; The "\ref{%s}" is a format string indicating how to insert references to | |
220 ;; these labels. The nil format in the \myfig entry means to use the same | |
221 ;; format as other figure labels. | |
222 ;; The next item indicates how to grab context of the label definition. | |
223 ;; - t means to get it from a default location (from the beginning of a \macro | |
224 ;; or after the \begin{} statement). t is *not* a good choice for eqnarray | |
225 ;; and similar environments. | |
226 ;; - nil means to use the text right after the label definition. | |
227 ;; - For more complex ways of getting context, see the docstring of | |
228 ;; reftex-label-alist. | |
229 ;; The strings at the end of each entry are used to guess the correct label | |
230 ;; type from the word before point when creating a reference. E.g. if you | |
231 ;; write: "as we have shown in Theorem" and then press `C-)', RefTeX will | |
232 ;; know that you are looking for a Theorem label and restrict the labels in | |
233 ;; the menu to only these labels without even asking. | |
234 ;; See also the documentation string of the variable reftex-label-alist. | |
235 ;; | |
236 ;; Depending on how you would like the label insertion and selection for the | |
237 ;; new environments to work, you might want to add the letters "a" and "h" | |
238 ;; to some of the flags in the following variables: | |
239 ;; | |
240 ;; reftex-insert-label-flags | |
241 ;; reftex-label-menu-flags | |
242 ;; | |
243 ;; The individual flags in these variables can be set to t or nil to enable or | |
244 ;; disable the feature for all label types. They may also contain a string of | |
245 ;; label type letters in order to turn on the feature for those types only. | |
246 ;; | |
247 ;; ----- | |
248 ;; If you are writing in a language different from english you might want to | |
249 ;; add magic words for that language. Here is a German example: | |
250 ;; | |
251 ;; (setq reftex-label-alist | |
252 ;; '((nil ?s nil nil nil ("Kapitel" "Kap." "Abschnitt" "Teil")) | |
253 ;; (nil ?e nil nil nil ("Gleichung" "Gl.")) | |
254 ;; (nil ?t nil nil nil ("Tabelle")) | |
255 ;; (nil ?f nil nil nil ("Figur" "Abbildung" "Abb.")) | |
256 ;; (nil ?n nil nil nil ("Punkt")))) | |
257 ;; | |
258 ;; Using `nil' as first item in each entry makes sure that this entry does | |
259 ;; not replace the original entry for that label type. | |
260 ;; | |
261 ;; HOOKS | |
262 ;; ----- | |
263 ;; Loading reftex.el runs the hook reftex-load-hook. Turning on reftex-mode | |
264 ;; runs reftex-mode-hook. | |
265 ;; | |
266 ;;------------------------------------------------------------------------- | |
267 ;; | |
268 ;; KEY BINDINGS | |
269 ;; | |
270 ;; All important functions of RefTeX can be reached from its menu which | |
271 ;; is installed in the menu bar as "Ref" menu. Only the more frequently used | |
272 ;; functions have key bindings. | |
273 ;; | |
274 ;; Here is the default set of keybindings from RefTeX. | |
275 ;; | |
276 ;; C-c = reftex-toc | |
277 ;; C-c ( reftex-label | |
278 ;; C-c ) reftex-reference | |
279 ;; C-c [ reftex-citation | |
280 ;; C-c & reftex-view-crossref | |
281 ;; | |
282 ;; I've used these bindings in order to avoid interfering with AUCTeX's | |
283 ;; settings. Personally, I also bind some functions in the C-c LETTER | |
284 ;; map for easier access: | |
285 ;; | |
286 ;; C-c t reftex-toc | |
287 ;; C-c l reftex-label | |
288 ;; C-c r reftex-reference | |
289 ;; C-c c reftex-citation | |
290 ;; C-c v reftex-view-crossref | |
291 ;; C-c s reftex-search-document | |
292 ;; C-c g reftex-grep-document | |
293 ;; | |
294 ;; If you want to copy those as well, set in your .emacs file: | |
295 ;; | |
296 ;; (setq reftex-extra-bindings t) | |
297 ;; | |
298 ;; It is possible to bind the function for viewing cross references to a | |
299 ;; mouse event. Something like the following in .emacs will do the trick: | |
300 ;; | |
301 ;; (add-hook 'reftex-load-hook | |
302 ;; '(lambda () | |
303 ;; (define-key reftex-mode-map [(alt mouse-1)] | |
304 ;; 'reftex-mouse-view-crossref))) | |
305 ;; | |
306 ;;------------------------------------------------------------------------- | |
307 ;; | |
308 ;; RELATED PACKAGES | |
309 ;; | |
310 ;; AUCTeX | |
311 ;; ------ | |
312 ;; If you are writing any TeX or LaTeX documents with Emacs, you should | |
313 ;; have a look at AUCTeX, the definitive package to work with TeX and LaTeX. | |
314 ;; Information on AUCTeX can be found here: | |
315 ;; | |
316 ;; http://www.sunsite.auc.dk/auctex/ | |
317 ;; | |
318 ;; AUCTeX version 9.7f and later can be configured to delegate label | |
319 ;; insertion to RefTeX. Do do that, say in your .emacs file | |
320 ;; | |
321 ;; (setq LaTeX-label-function 'reftex-label) | |
322 ;; | |
323 ;; RefTeX also provides functions which can replace TeX-arg-label and | |
324 ;; TeX-arg-cite in AUCTeX. These functions are compatible with the originals, | |
325 ;; but use RefTeX internals to create and select labels and citation keys. | |
326 ;; There are 3 functions: reftex-arg-label, reftex-arg-ref, reftex-arg-cite. | |
327 ;; | |
328 ;; AUCTeX can support RefTeX via style files. A style file may contain | |
329 ;; calls to reftex-add-to-label-alist which defines additions to | |
330 ;; reftex-label-alist. The argument taken by this function must have exactly | |
331 ;; the same format as reftex-label-alist. E.g. a good entry in a style file | |
332 ;; for the amsmath package would be | |
333 ;; | |
334 ;; (and (fboundp 'reftex-add-to-label-alist) | |
335 ;; (reftex-add-to-label-alist '(AMSTeX))) | |
336 ;; | |
337 ;; while a package defining a proposition environment with \newtheorem | |
338 ;; might use | |
339 ;; | |
340 ;; (and | |
341 ;; (fboundp 'reftex-add-to-label-alist) | |
342 ;; (reftex-add-to-label-alist | |
343 ;; '(("proposition" ?p "prop:" "~\\ref{%s}" t | |
344 ;; ("Proposition" "Prop."))))) | |
345 ;; | |
346 ;; Bib-cite.el | |
347 ;; ----------- | |
348 ;; Once you have written a document with labels, refs and citations, it can be | |
349 ;; nice to read such a file like a hypertext document. RefTeX has some support | |
350 ;; for that (reftex-view-crossref, reftex-search-document). A more elegant | |
351 ;; interface with mouse support and links into Hyperbole is provided (among | |
352 ;; other things) by Peter S. Galbraith's bib-cite.el. There is some overlap in | |
353 ;; the functionalities of bib-cite and RefTeX. Bib-cite.el comes bundled with | |
354 ;; AUCTeX. You can also get the latest version from | |
355 ;; | |
356 ;; ftp://ftp.phys.ocean.dal.ca/users/rhogee/elisp/bib-cite.el | |
357 ;; | |
358 ;;------------------------------------------------------------------------- | |
359 ;; | |
360 ;; PERFORMANCE ISSUES | |
361 ;; | |
362 ;; 1. RefTeX will load other parts of a multifile document as well as BibTeX | |
363 ;; database files for lookup purposes. These buffers are kept, so that | |
364 ;; subsequent lookup in the same files is fast. For large documents and | |
365 ;; large BibTeX databases, this can use up a lot of memory. If you have | |
366 ;; more time than memory, try the following option, which will remove | |
367 ;; buffers created for lookup after use. | |
368 ;; | |
369 ;; (setq reftex-keep-temporary-buffers nil) | |
370 ;; | |
371 ;; 2. Parsing the document for labels and their context can be slow. | |
372 ;; Therefore, RefTeX does it just once automatically. Further parsing | |
373 ;; happens only on user request | |
374 ;; - with a raw C-u prefix arg to any of the functions reftex-label, | |
375 ;; reftex-reference, reftex-citation, reftex-toc. | |
376 ;; - with the `r' key from the label selection menu or the *toc* buffer. | |
377 ;; | |
378 ;; *** If you use reftex-label to create labels, the list will be updated | |
379 ;; *** internally, so that no extra parsing is required. | |
380 ;; | |
381 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
382 ;; | |
383 ;; KNOWN BUGS | |
384 ;; | |
385 ;; o If you change reftex-label-alist in an editing session, you need to | |
386 ;; reset reftex with `M-x reftex-reset-mode' in order to make these | |
387 ;; changes effective. Changes introduced with the function | |
388 ;; reftex-add-to-label-alist as well as changes applied from the | |
389 ;; customization buffer automatically trigger a reset. | |
390 ;; | |
391 ;; o At times the short context shown by RefTeX may not be what you want. | |
392 ;; In particular, eqnarray environments can be difficult to | |
393 ;; parse. RefTeX's default behavior for eqnarrays is to scan backwards to | |
394 ;; either a double backslash or the beginning of the environment. If this | |
395 ;; gives unsatisfactory results, make it a habit to place the label | |
396 ;; *before* each equation | |
397 ;; | |
398 ;; \begin{eqnarray} | |
399 ;; \label{eq:1} | |
400 ;; E = \gamma m c^2 \\ | |
401 ;; \label{eq:2} | |
402 ;; \gamma = \sqrt{1-v^2/c^2} | |
403 ;; \end{eqnarray} | |
404 ;; | |
405 ;; and turn off parsing for context in equation and eqnarray environments | |
406 ;; with | |
407 ;; | |
408 ;; (setq reftex-use-text-after-label-as-context "e"). | |
409 ;; | |
410 ;; o RefTeX keeps only one global copy of the configuration variables. | |
411 ;; Also any additions from style files go into a global variable. | |
412 ;; Practically, this should not be a problem. Theoretically, it could | |
413 ;; give conflicts if two documents used environments with identical | |
414 ;; names, but different associated label types. | |
415 ;; | |
416 ;; o Input, include, bibliography and section statements have to be first | |
417 ;; on a line (except for white space) in order to be seen by reftex. | |
418 ;; | |
419 ;; o When the document is scanned, RefTeX creates a large buffer containing | |
420 ;; the entire document instead of scanning the individual files one by | |
421 ;; one. This is necessary since a file might not contain the context | |
422 ;; needed by RefTeX. | |
423 ;; | |
424 ;; o If you have two identical section headings in the same file, | |
425 ;; reftex-toc will only let you jump to the first one because it searches | |
426 ;; for the section heading from the beginning of the file. You can work | |
427 ;; around this by changing one of the section titles in a way LaTeX does | |
428 ;; not see, e.g. with extra white space. RefTeX will distinguish | |
429 ;; \section{Introduction} from \section{ Introduction}. | |
430 ;; | |
431 ;; o RefTeX sees also labels in regions commented out and will refuse to | |
432 ;; make duplicates of such a label. This is considered to be a feature. | |
433 ;; | |
434 ;; o When RefTeX tries to show a window full of context from inside a | |
435 ;; section hidden with outline-minor-mode, it will unhide that section. | |
436 ;; This change will not be reversed automatically. | |
437 ;; | |
438 ;;--------------------------------------------------------------------------- | |
439 ;; | |
440 ;; TO DO | |
441 ;; | |
442 ;; I think I am pretty much done with this one... | |
443 ;; | |
444 ;;--------------------------------------------------------------------------- | |
445 ;; | |
446 ;; AUTHOR | |
447 ;; | |
448 ;; Carsten Dominik <dominik@strw.LeidenUniv.nl> | |
449 ;; | |
450 ;; with contributions from Stephen Eglen | |
451 ;; | |
452 ;; The newest version of RefTeX can be found at | |
453 ;; | |
454 ;; http://www.strw.leidenuniv.nl/~dominik/Tools/ | |
455 ;; ftp://strw.leidenuniv.nl/pub/dominik/ | |
456 ;; | |
457 ;; THANKS TO: | |
458 ;; --------- | |
459 ;; At least the following people have invested time to test and bug-fix | |
460 ;; reftex.el. Some have send patches for fixes or new features. | |
461 ;; | |
462 ;; Stephen Eglen <stephene@cogs.susx.ac.uk> | |
463 ;; F.E.Burstall <F.E.Burstall@maths.bath.ac.uk> | |
464 ;; Karl Eichwalder <ke@ke.Central.DE> | |
465 ;; Laurent Mugnier <mugnier@onera.fr> | |
466 ;; Rory Molinari <molinari@yunt.math.lsa.umich.edu> | |
467 ;; Soren Dayton <csdayton@cs.uchicago.edu> | |
468 ;; Daniel Polani <polani@Informatik.Uni-Mainz.DE> | |
469 ;; Allan Strand <astrand@trillium.NMSU.Edu> | |
470 ;; | |
471 ;; The view crossref feature was inspired by the similar function in | |
472 ;; Peter S. Galbraith's bib-cite.el. | |
473 ;; | |
474 ;; Finally thanks to Uwe Bolick <bolick@physik.tu-berlin.de> who first | |
475 ;; got me (some years ago) into supporting LaTeX labels and references | |
476 ;; with an Editor (which was MicroEmacs at the time). | |
477 | |
478 ;;; Code: | |
479 | |
480 ;; Stuff that needs to be there when we use defcustom | |
481 ;; -------------------------------------------------- | |
482 | |
483 (require 'custom) | |
484 | |
485 (defvar reftex-tables-dirty t | |
486 "Flag showing if tables need to be re-computed.") | |
487 | |
488 (eval-and-compile | |
489 (defun reftex-set-dirty (symbol value) | |
490 (setq reftex-tables-dirty t) | |
491 (set symbol value))) | |
492 | |
493 ;;; Begin of Configuration Section ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
494 | |
495 ;; Configuration Variables and User Options for RefTeX ------------------ | |
496 | |
497 (defgroup reftex nil | |
498 "LaTeX label and citation support." | |
499 :tag "RefTeX" | |
500 :link '(url-link :tag "Home Page" "http://strw.leidenuniv.nl/~dominik/Tools/") | |
501 :prefix "reftex-" | |
502 :group 'tex) | |
503 | |
504 (defun reftex-customize () | |
505 "Call the customize function with reftex as argument." | |
506 (interactive) | |
507 (if (fboundp 'customize-group) | |
508 (customize-group 'reftex) | |
509 (customize 'reftex))) | |
510 | |
511 ;; Support for \label{} and \ref{} -------------------------------------- | |
512 | |
513 (defgroup reftex-label-support nil | |
514 "Support for creation, insertion and referencing of labels in LaTeX" | |
515 :group 'reftex) | |
516 | |
517 (defgroup reftex-defining-label-environments nil | |
518 "Definition of environments and macros to do with label" | |
519 :group 'reftex-label-support) | |
520 | |
521 | |
522 (defcustom reftex-label-alist nil | |
523 "AList with information on environments for \\label{}-\\ref{} use. | |
524 See the definition of reftex-label-alist-builtin for examples. This variable | |
525 should define additions and changes to the default. The only things you MUST | |
526 NOT change is that '?s' is the type indicator for section labels and SPACE is | |
527 for the 'any' label type. These are hard-coded at other places in the code. | |
528 | |
529 Changes to this variable after reftex.el has been loaded become only | |
530 effective when RefTeX is reset with \\[reftex-reset-mode]. | |
531 | |
532 Each list entry is a list describing an environment or macro carrying a | |
533 label. The elements of each list entry are: | |
534 | |
535 0. Name of the environment (like \"table\") or macro (like \"\\\\myfig\"). | |
536 Special names: `section' for section labels, `any' to define a group | |
537 which contains all labels. | |
538 This may also be nil if this entry is only meant to change some settings | |
539 associated with the type indicator character (see below). | |
540 | |
541 1. Type indicator character, like ?t. | |
542 The type indicator is a single character used in prompts for | |
543 label types. It must be a printable character. The same character | |
544 may occur several times in this list, to cover cases in which different | |
545 environments carry the same label type (like equation and eqnarray). | |
546 | |
547 2. Label prefix string, like \"tab:\". | |
548 The prefix is a short string used as the start of a label. It may be the | |
549 empty string. | |
550 | |
551 3. Format string for reference insert in buffer. Each %s will be replaced by | |
552 the label (yes, several %s can be in there, so that you can set this to: | |
553 \"\\ref{%s} on page~\\pageref{%s}\"). | |
554 When the format starts with ~, whitespace before point will be removed so | |
555 that the reference cannot be separated from the word before it. | |
556 | |
557 4. Indication on how to find the short context. | |
558 - If `nil', use the text following the \\label{...} macro. | |
559 - If `t', use | |
560 - text following the \\begin{...} statement of environments | |
561 (not a good choice in in eqnarray or enumerate environments!) | |
562 - the section heading for section labels. | |
563 - the begin of the macro for macros. | |
564 - If a string, use as regexp to search *backward* from the label. Context | |
565 is then the text following the end of the match. E.g. putting this to | |
566 \"\\\\\\\\caption{\" will use the beginning of the caption in a figure | |
567 or table environment. \"\\\\\\\\begin{eqnarray}\\\\|\\\\\\\\\\\\\\\\\" | |
568 works for eqnarrays. | |
569 - If a function, call this function with the name of the environment/macro | |
570 as argument. On call, point will be just after the \\label{} macro. The | |
571 function is expected to return a suitable context string. It should | |
572 throw an exception (error) when failing to find context. | |
573 Consider the following example, which would return the 10 characters | |
574 following the label as context: | |
575 | |
576 (defun my-context-function (env-or-mac) | |
577 (if (> (point-max) (+ 10 (point))) | |
578 (buffer-substring (point) (+ 10 (point))) | |
579 (error \"Buffer too small\"))) | |
580 | |
581 Setting the variable reftex-use-text-after-label-as-context to t overrides | |
582 the setting here. | |
583 | |
584 5. List of magic words which identify a reference to be of this type. If the | |
585 word before point is equal to one of these words when calling | |
586 reftex-reference, the label list offered will be automatically restricted | |
587 to labels of the correct type. | |
588 | |
589 If the type indicator characters of two or more entries are the same, RefTeX | |
590 will use | |
591 - the first non-nil format and prefix | |
592 - the magic words of all involved entries. | |
593 | |
594 Any list entry may also be a symbol. If that has an association in | |
595 reftex-label-alist-builtin, the cdr of that association is spliced into the | |
596 list. See the AMSTeX configuration example in the comment section of | |
597 reftex.el." | |
598 :group 'reftex-defining-label-environments | |
599 :set 'reftex-set-dirty | |
600 :type '(list | |
601 :convert-widget | |
602 (lambda (widget) | |
603 (let* | |
604 ((args | |
605 (list | |
606 `(repeat | |
607 :inline t | |
608 (radio | |
609 :value ("" ?a nil nil t nil) | |
610 (choice | |
611 :tag "Builtin" | |
612 :value AMSTeX | |
613 ,@(mapcar (function (lambda (x) | |
614 (list 'const ':tag (nth 1 x) (car x)))) | |
615 reftex-label-alist-builtin)) | |
616 (list :tag "Detailed custom entry" | |
617 (choice :tag "Environment or \\macro " | |
618 (const :tag "Ignore, just use typekey" nil) | |
619 (string "")) | |
620 (character :tag "Typekey character " ?a) | |
621 (choice :tag "Label prefix string " | |
622 (const :tag "Copy from similar label type" nil) | |
623 (string :tag "Specify here" "lab:")) | |
624 (choice :tag "Label reference format" | |
625 (const :tag "Copy from similar label type" nil) | |
626 (string :tag "Specify here" "~\\ref{%s}")) | |
627 (choice :tag "Grab context method " | |
628 (const :tag "Default position" t) | |
629 (const :tag "After label" nil) | |
630 (regexp :tag "Regular expression" "") | |
631 (symbol :tag "Function" my-context-function)) | |
632 (repeat :tag "List of Magic Words" (string)))))))) | |
633 (widget-put widget :args args) | |
634 widget)))) | |
635 | |
636 (defcustom reftex-default-label-alist-entries '(Sideways LaTeX) | |
637 "Default label alist specifications. LaTeX should be the last entry. | |
638 This list describes the default label environments RefTeX should always use in | |
639 addition to the specifications in reftex-label-alist. It is probably a | |
640 mistake to remove the LaTeX symbol from this list. | |
641 | |
642 Here are the current options: | |
643 | |
644 LaTeX The standard LaTeX environments | |
645 Sideways The sidewaysfigure and sidewaystable environments | |
646 AMSTeX The math environments in the AMS_LaTeX amsmath package | |
647 AAS The deluxetable environment from the American Astronomical Society" | |
648 :group 'reftex-defining-label-environments | |
649 :set 'reftex-set-dirty | |
650 :type '(list :indent 4 | |
651 :convert-widget | |
652 (lambda (widget) | |
653 (let* ((args | |
654 (list | |
655 `(checklist | |
656 :inline t | |
657 ,@(reverse | |
658 (mapcar (lambda (x) | |
659 (list 'const ':tag (nth 1 x) (car x))) | |
660 reftex-label-alist-builtin)))))) | |
661 (widget-put widget :args args) | |
662 widget)))) | |
663 | |
664 (defcustom reftex-use-text-after-label-as-context nil | |
665 "*t means, grab context from directly after the \\label{..} macro. | |
666 This is the fastest method for obtaining context of the label definition, but | |
667 requires discipline when placing labels. Setting this variable to t takes | |
668 precedence over the individual settings in reftex-label-alist. | |
669 This variable may be set to t, nil, or a string of label type letters | |
670 indicating the label types for which it should be true." | |
671 :group 'reftex-defining-label-environments | |
672 :set 'reftex-set-dirty | |
673 :type '(choice | |
674 (const :tag "on" t) (const :tag "off" nil) | |
675 (string :tag "Selected label types"))) | |
676 | |
677 ;; Label insertion | |
678 | |
679 (defgroup reftex-making-and-inserting-labels nil | |
680 "Options on how to create new labels" | |
681 :group 'reftex-label-support) | |
682 | |
683 (defcustom reftex-insert-label-flags '("s" "sft") | |
684 "Flags governing label insertion. First flag DERIVE, second flag PROMPT. | |
685 | |
686 If DERIVE is t, RefTeX will try to derive a sensible label from context. | |
687 A section label for example will be derived from the section heading. | |
688 The conversion of the context to a legal label is governed by the | |
689 specifications given in reftex-derive-label-parameters. | |
690 If RefTeX fails to derive a label, it will prompt the user. | |
691 | |
692 If PROMPT is t, the user will be prompted for a label string. The prompt will | |
693 already contain the prefix, and (if DERIVE is t) a default label derived from | |
694 context. When PROMPT is nil, the default label will be inserted without | |
695 query. | |
696 | |
697 So the combination of DERIVE and PROMPT controls label insertion. Here is a | |
698 table describing all four possibilities: | |
699 | |
700 DERIVE PROMPT ACTION | |
701 ------------------------------------------------------------------------- | |
702 nil nil Insert simple label, like eq:22 or sec:13. No query. | |
703 nil t Prompt for label | |
704 t nil Derive a label from context and insert without query | |
705 t t Derive a label from context and prompt for confirmation | |
706 | |
707 Each flag may be set to t, nil, or a string of label type letters | |
708 indicating the label types for which it should be true. | |
709 Thus, the combination may be set differently for each label type. The | |
710 default settings \"s\" and \"sft\" mean: Derive section labels from headings | |
711 (with confirmation). Prompt for figure and table labels. Use simple labels | |
712 without confirmation for everything else." | |
713 :group 'reftex-making-and-inserting-labels | |
714 :type '(list (choice :tag "Derive label from context" | |
715 (const :tag "always" t) | |
716 (const :tag "never" nil) | |
717 (string :tag "for selected label types" "")) | |
718 (choice :tag "Prompt for label string " | |
719 :entry-format " %b %v" | |
720 (const :tag "always" t) | |
721 (const :tag "never" nil) | |
722 (string :tag "for selected label types" "")))) | |
723 | |
724 (defcustom reftex-derive-label-parameters '(3 20 t 1 "-" ; continue | |
725 ("the" "on" "in" "off" "a" "for" "by" "of" "and" "is")) | |
726 "Parameters for converting a string into a label. | |
727 NWORDS Number of words to use. | |
728 MAXCHAR Maximum number of characters in a label string. | |
729 ILLEGAL nil: Throw away any words containing characters illegal in labels. | |
730 t: Throw away only the illegal characters, not the whole word. | |
731 ABBREV nil: Never abbreviate words. | |
732 t: Always abbreviate words (see reftex-abbrev-parameters). | |
733 not t and not nil: Abbreviate words if necessary to shorten | |
734 label string below MAXCHAR. | |
735 SEPARATOR String separating different words in the label | |
736 IGNOREWORDS List of words which should not be part of labels" | |
737 :group 'reftex-making-and-inserting-labels | |
738 :type '(list (integer :tag "Number of words " 3) | |
739 (integer :tag "Maximum label length " 20) | |
740 (choice :tag "Illegal characters in words" | |
741 (const :tag "throw away entire word" nil) | |
742 (const :tag "throw away single chars" t)) | |
743 (choice :tag "Abbreviate words " | |
744 (const :tag "never" nil) | |
745 (const :tag "always" t) | |
746 (const :tag "when label is too long" 1)) | |
747 (string :tag "Separator between words " "-") | |
748 (repeat :tag "Ignore words" | |
749 :entry-format " %i %d %v" | |
750 (string :tag "")))) | |
751 | |
752 (defcustom reftex-label-illegal-re "[\000-\040\177-\377\\\\#$%&~^_{}]" | |
753 "Regexp matching characters not legal in labels. | |
754 For historic reasons, this character class comes *with* the [] brackets." | |
755 :group 'reftex-making-and-inserting-labels | |
756 :type '(regexp :tag "Character class")) | |
757 | |
758 (defcustom reftex-abbrev-parameters '(4 2 "^saeiou" "aeiou") | |
759 "Parameters for abbreviation of words. | |
760 MIN-CHARS minimum number of characters remaining after abbreviation | |
761 MIN-KILL minimum number of characters to remove when abbreviating words | |
762 BEFORE character class before abbrev point in word | |
763 AFTER character class after abbrev point in word" | |
764 :group 'reftex-making-and-inserting-labels | |
765 :type '(list | |
766 (integer :tag "Minimum chars per word" 4) | |
767 (integer :tag "Shorten by at least " 2) | |
768 (string :tag "cut before char class " "^saeiou") | |
769 (string :tag "cut after char class " "aeiou"))) | |
770 | |
771 | |
772 ;; Label referencing | |
773 | |
774 (defgroup reftex-referencing-labels nil | |
775 "Options on how to reference labels" | |
776 :group 'reftex-label-support) | |
777 | |
778 (defcustom reftex-label-menu-flags '(t t nil nil nil nil) | |
779 "*List of flags governing the label menu makeup. | |
780 The flags are: | |
781 | |
782 TABLE-OF-CONTENTS Show the labels embedded in a table of context. | |
783 SECTION-NUMBERS Include section numbers (like 4.1.3) in table of contents. | |
784 COUNTERS Show counters. This just numbers the labels in the menu. | |
785 NO-CONTEXT Non-nil means do NOT show the short context. | |
786 FOLLOW follow full context in other window. | |
787 SHOW-COMMENTED Show labels from regions which are commented out. RefTeX | |
788 sees these labels, but does not normally show them. | |
789 | |
790 Each of these flags can be set to t or nil, or to a string of type letters | |
791 indicating the label types for which it should be true. These strings work | |
792 like character classes in regular expressions. Thus, setting one of the | |
793 flags to \"sf\" makes the flag true for section and figure labels, nil | |
794 for everything else. Setting it to \"^ft\" makes it the other way round. | |
795 | |
796 Most options can also be switched from the label menu itself - so if you | |
797 decide here to not have a table of contents in the label menu, you can still | |
798 get one interactively during selection from the label menu." | |
799 :group 'reftex-referencing-labels | |
800 :type '(list | |
801 (choice :tag "Embed in table of contents " | |
802 (const :tag "on" t) (const :tag "off" nil) | |
803 (string :tag "Selected label types")) | |
804 (choice :tag "Show section numbers " | |
805 (const :tag "on" t) (const :tag "off" nil)) | |
806 (choice :tag "Show individual counters " | |
807 (const :tag "on" t) (const :tag "off" nil) | |
808 (string :tag "Selected label types")) | |
809 (choice :tag "Hide short context " | |
810 (const :tag "on" t) (const :tag "off" nil) | |
811 (string :tag "Selected label types")) | |
812 (choice :tag "Follow context in other window" | |
813 (const :tag "on" t) (const :tag "off" nil) | |
814 (string :tag "Selected label types")) | |
815 (choice :tag "Show commented labels " | |
816 (const :tag "on" t) (const :tag "off" nil) | |
817 (string :tag "Selected label types")))) | |
818 | |
819 | |
820 (defcustom reftex-guess-label-type t | |
821 "*Non-nil means, reftex-reference will try to guess the label type. | |
822 To do that, RefTeX will look at the word before the cursor and compare it with | |
823 the words given in reftex-label-alist. When it finds a match, RefTeX will | |
824 immediately offer the correct label menu - otherwise it will prompt you for | |
825 a label type. If you set this variable to nil, RefTeX will always prompt." | |
826 :group 'reftex-referencing-labels | |
827 :type '(boolean)) | |
828 | |
829 ;; BibteX citation configuration ---------------------------------------- | |
830 | |
831 (defgroup reftex-citation-support nil | |
832 "Support for referencing bibliographic data with BibTeX" | |
833 :group 'reftex) | |
834 | |
835 (defcustom reftex-bibpath-environment-variables '("BIBINPUTS" "TEXBIB") | |
836 "*List of env vars which might contain the path to BibTeX database files." | |
837 :group 'reftex-citation-support | |
838 :set 'reftex-set-dirty | |
839 :type '(repeat (string :tag "Environment variable"))) | |
840 | |
841 (defcustom reftex-bibfile-ignore-list nil | |
842 "List of files in \\bibliography{..} RefTeX should *not* parse. | |
843 The file names have to be in the exact same form as in the bibliography | |
844 macro - i.e. without the .bib extension. | |
845 Intended for files which contain only `@string' macro definitions and the | |
846 like, which are ignored by RefTeX anyway." | |
847 :group 'reftex-citation-support | |
848 :set 'reftex-set-dirty | |
849 :type '(repeat (string :tag "File name"))) | |
850 | |
851 (defcustom reftex-sort-bibtex-matches 'reverse-year | |
852 "*Sorting of the entries found in BibTeX databases by reftex-citation. | |
853 Possible values: | |
854 nil Do not sort entries. | |
855 'author Sort entries by author name. | |
856 'year Sort entries by increasing year. | |
857 'reverse-year Sort entries by decreasing year." | |
858 :group 'reftex-citation-support | |
859 :type '(choice (const :tag "not" nil) | |
860 (const :tag "by author" author) | |
861 (const :tag "by year" year) | |
862 (const :tag "by year, reversed" reverse-year))) | |
863 | |
864 (defcustom reftex-cite-format 'reftex-cite-format-default | |
865 "Defines the format of citations to be inserted into the buffer. | |
866 It can be a string, a list of strings, or an alist with characters as keys | |
867 and a list of strings in the car. In the simplest case, this can just | |
868 be the string \"\\cite{KEY}\", which is also the default. See the | |
869 definition of the reftex-cite-format-XXXX constants for more complex | |
870 examples. | |
871 If reftex-cite-format is a string, it will be used as the format. In | |
872 the format, AUTHOR will be replaced by the last name of the | |
873 author, YEAR will be replaced by the year and KEY by the citation | |
874 key. If AUTHOR is present several times, it will be replaced with | |
875 successive author names. | |
876 See the constant reftex-cite-format-default for an example. | |
877 If reftex-cite-format is a list of strings, the string used will | |
878 depend upon the number of authors of the article. No authors means, | |
879 the first string will be used, 1 author means, the second string will | |
880 be used etc. The last string in the list will be used for all articles | |
881 with too many authors. See reftex-cite-format-1-author-simple for an | |
882 example. | |
883 If reftex-cite-format is a list of cons cells, the car of each cell | |
884 needs to be a character. When a selected reference is accepted by | |
885 pressing that key, the cdr of the associated list will be used as | |
886 described above. See reftex-cite-format-2-authors for an example. | |
887 In order to configure this variable, you can either set | |
888 reftex-cite-format directly yourself or set it to the SYMBOL of one of | |
889 the predefined constants. E.g.: | |
890 (setq reftex-cite-format 'reftex-cite-format-2-authors)" | |
891 :group 'reftex-citation-support | |
892 :type | |
893 '(choice | |
894 (choice :tag "symbolic defaults" | |
895 :value reftex-cite-format-default | |
896 (const reftex-cite-format-default) | |
897 (const reftex-cite-format-1-author-simple) | |
898 (const reftex-cite-format-2-authors)) | |
899 (string :tag "format string" "\\cite{KEY}") | |
900 (repeat :tag "list of strings" | |
901 :value ("\cite{KEY}" "AUTHOR \cite{KEY}" "AUTHOR and AUTHOR \cite{KEY}") | |
902 (string :tag "format string" "")) | |
903 (repeat :tag "key-ed lists of strings" | |
904 :value ((? | |
905 . ("\cite{KEY}" "AUTHOR \cite{KEY}" "AUTHOR and AUTHOR \cite{KEY}"))) | |
906 (cons :tag "Enter a keyed list of format strings" | |
907 (character :tag "Key character " ? | |
908 ) | |
909 (repeat | |
910 (string :tag "format string" "")))))) | |
911 | |
912 ;; Table of contents configuration -------------------------------------- | |
913 | |
914 (defgroup reftex-table-of-contents-browser nil | |
915 "A multifile table of contents browser." | |
916 :group 'reftex) | |
917 | |
918 (defcustom reftex-toc-follow-mode nil | |
919 "Non-nil means, point in *toc* buffer will cause other window to follow. | |
920 The other window will show the corresponding part of the document. | |
921 This flag can be toggled from within the *toc* buffer with the `f' key." | |
922 :group 'reftex-table-of-contents-browser | |
923 :type '(boolean)) | |
924 | |
925 ;; Miscellaneous configurations ----------------------------------------- | |
926 | |
927 (defgroup reftex-miscellaneous-configurations nil | |
928 "Collection of further configurations" | |
929 :group 'reftex) | |
930 | |
931 (defcustom reftex-extra-bindings nil | |
932 "Non-nil means, make additional key bindings on startup. | |
933 These extra bindings are located in the users C-c letter map." | |
934 :group 'reftex-miscellaneous-configurations | |
935 :type '(boolean)) | |
936 | |
937 (defcustom reftex-use-fonts t | |
938 "*Non-nil means, use fonts in label menu and on-the-fly help. | |
939 Font-lock must be loaded as well to actually get fontified display." | |
940 :group 'reftex-miscellaneous-configurations | |
941 :type '(boolean)) | |
942 | |
943 (defcustom reftex-keep-temporary-buffers t | |
944 "*Non-nil means, keep any TeX and BibTeX files loaded for lookup. | |
945 Nil means, kill it immediately after use unless it was already an existing | |
946 buffer before the lookup happened. It is faster to keep the buffers, but can | |
947 use a lot of memory, depending on the size of your database and document." | |
948 :group 'reftex-miscellaneous-configurations | |
949 :type '(boolean)) | |
950 | |
951 (defcustom reftex-auto-show-entry t | |
952 "*Non-nil means, showing context in another window may unhide a section. | |
953 This is important when using outline-minor-mode. If the context to be shown | |
954 is in a hidden section, RefTeX will issue a \"show-entry\" command in order | |
955 to show it. This is not reversed when the label is selected - so the section | |
956 remains shown after command completion." | |
957 :group 'reftex-miscellaneous-configurations | |
958 :type '(boolean)) | |
959 | |
960 | |
961 ;;; End of Configuration Section ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
962 | |
963 ;;;=========================================================================== | |
964 ;;; | |
965 ;;; Define the formal stuff for a minor mode named RefTeX. | |
966 ;;; | |
967 | |
968 (defvar reftex-mode nil | |
969 "Determines if RefTeX minor mode is active.") | |
970 (make-variable-buffer-local 'reftex-mode) | |
971 | |
972 (defvar reftex-mode-map (make-sparse-keymap) | |
973 "Keymap for RefTeX minor mode.") | |
974 | |
975 (defvar reftex-mode-menu nil) | |
976 | |
977 ;;;###autoload | |
978 (defun turn-on-reftex () | |
979 "Turn on RefTeX minor mode." | |
980 (reftex-mode t)) | |
981 | |
982 ;;;###autoload | |
983 (defun reftex-mode (&optional arg) | |
984 "Minor mode with distinct support for \\label{}, \\ref{} and \\cite{} | |
985 in LaTeX documents. | |
986 | |
987 Labels can be created with `\\[reftex-label]' and referenced with `\\[reftex-reference]'. | |
988 When referencing, you get a menu with all labels of a given type and | |
989 context of the label definition. The selected label is inserted as a | |
990 \\ref{} macro. | |
991 | |
992 Citations can be made with `\\[reftex-citation]' which will use a regular expression | |
993 to pull out a *formatted* list of articles from your BibTeX | |
994 database. The selected citation is inserted as a \\cite{} macro. | |
995 | |
996 A Table of Contents of the entire (multifile) document with browsing | |
997 capabilities is available with `\\[reftex-toc]'. | |
998 | |
999 Most command have help available on the fly. This help is accessed by | |
1000 pressing `?' to any prompt mentioning this feature. | |
1001 | |
1002 \\{reftex-mode-map} | |
1003 Under X, these functions will be available also in a menu on the menu bar. | |
1004 | |
1005 ------------------------------------------------------------------------------" | |
1006 | |
1007 (interactive "P") | |
1008 (setq reftex-mode (not (or (and (null arg) reftex-mode) | |
1009 (<= (prefix-numeric-value arg) 0)))) | |
1010 | |
1011 ; Add or remove the menu, and run the hook | |
1012 (if reftex-mode | |
1013 (progn | |
1014 (easy-menu-add reftex-mode-menu) | |
1015 (run-hooks 'reftex-mode-hook)) | |
1016 (easy-menu-remove reftex-mode-menu))) | |
1017 | |
1018 (or (assoc 'reftex-mode minor-mode-alist) | |
1019 (setq minor-mode-alist | |
1020 (cons '(reftex-mode " Ref") minor-mode-alist))) | |
1021 | |
1022 (or (assoc 'reftex-mode minor-mode-map-alist) | |
1023 (setq minor-mode-map-alist | |
1024 (cons (cons 'reftex-mode reftex-mode-map) | |
1025 minor-mode-map-alist))) | |
1026 | |
1027 | |
1028 ;;; =========================================================================== | |
1029 ;;; | |
1030 ;;; Interfaces for other packages | |
1031 ;;; ----------------------------- | |
1032 ;;; | |
1033 ;;; AUCTeX | |
1034 ;;; ------ | |
1035 | |
1036 (defun reftex-arg-label (optional &optional prompt definition) | |
1037 "Use reftex-label to create a label and insert it with TeX-argument-insert. | |
1038 This function is intended for AUCTeX macro support." | |
1039 (let ((label (reftex-label nil t))) | |
1040 (if (and definition (not (string-equal "" label))) | |
1041 (LaTeX-add-labels label)) | |
1042 (TeX-argument-insert label optional optional))) | |
1043 | |
1044 (defun reftex-arg-ref (optional &optional prompt definition) | |
1045 "Use reftex-reference to select a label, insert it with TeX-argument-insert. | |
1046 This function is intended for AUCTeX macro support." | |
1047 (let ((label (reftex-reference nil t))) | |
1048 (if (and definition (not (string-equal "" label))) | |
1049 (LaTeX-add-labels label)) | |
1050 (TeX-argument-insert label optional optional))) | |
1051 | |
1052 (defun reftex-arg-cite (optional &optional prompt definition) | |
1053 "Use reftex-citation to select a key, insert it with TeX-argument-insert. | |
1054 This function is intended for AUCTeX macro support." | |
1055 (let ((key (reftex-citation nil t))) | |
1056 (TeX-argument-insert (or key "") optional optional))) | |
1057 | |
1058 (defvar reftex-label-alist-external-add-ons nil | |
1059 "List of label alist entries added with reftex-add-to-label-alist.") | |
1060 | |
1061 ;;;###autoload | |
1062 (defun reftex-add-to-label-alist (entry-list) | |
1063 "Add label environment descriptions to reftex-label-alist-external-add-ons. | |
1064 The format of ENTRY-LIST is exactly like reftex-label-alist. See there | |
1065 for details. | |
1066 This function makes it possible to support RefTeX from AUCTeX style files. | |
1067 The entries in ENTRY-LIST will be processed after the user settings in | |
1068 reftex-label-alist, and before the defaults (specified in | |
1069 reftex-default-label-alist-entries). Any changes made to | |
1070 reftex-label-alist-external-add-ons will raise a flag to the effect that a | |
1071 mode reset is done on the next occasion." | |
1072 (let (entry) | |
1073 (while entry-list | |
1074 (setq entry (car entry-list) | |
1075 entry-list (cdr entry-list)) | |
1076 (if (not (member entry reftex-label-alist-external-add-ons)) | |
1077 (setq reftex-tables-dirty t | |
1078 reftex-label-alist-external-add-ons | |
1079 (cons entry reftex-label-alist-external-add-ons)))))) | |
1080 | |
1081 ;;; =========================================================================== | |
1082 ;;; | |
1083 ;;; Multifile support | |
1084 ;;; | |
1085 ;;; Technical notes: Multifile works as follows: We keep just one list | |
1086 ;;; of labels for each master file - this can save a lot of memory. | |
1087 ;;; reftex-master-index-list is an alist which connects the true file name | |
1088 ;;; of each master file with the symbols holding the information on that | |
1089 ;;; document. Each buffer has local variables which point to these symbols. | |
1090 | |
1091 | |
1092 ;; List of variables which handle the multifile stuff. | |
1093 ;; This list is used to tie, untie, and reset these symbols. | |
1094 (defconst reftex-multifile-symbols | |
1095 '(reftex-label-numbers-symbol reftex-list-of-labels-symbol | |
1096 reftex-bibfile-list-symbol)) | |
1097 | |
1098 ;; Alist connecting master file names with the corresponding lisp symbols | |
1099 (defvar reftex-master-index-list nil) | |
1100 | |
1101 ;; Last index used for a master file | |
1102 (defvar reftex-multifile-index 0) | |
1103 | |
1104 ;; Alist connecting a master file with all included files. | |
1105 ;; This information is not yet used, just collected. | |
1106 (defvar reftex-master-include-list nil) | |
1107 | |
1108 ;; Variable holding the symbol with current value of label postfix | |
1109 (defvar reftex-label-numbers-symbol nil ) | |
1110 (make-variable-buffer-local 'reftex-label-numbers-symbol) | |
1111 | |
1112 ;; Variable holding the symbol with the label list of the document. | |
1113 ;; Each element of the label list is again a list with the following elements: | |
1114 ;; 0: One character label type indicator | |
1115 ;; 1: Short context to put into label menu | |
1116 ;; 2: The label | |
1117 ;; 3: The name of the file where the label is defined | |
1118 (defvar reftex-list-of-labels-symbol nil) | |
1119 (make-variable-buffer-local 'reftex-list-of-labels-symbol) | |
1120 | |
1121 ;; Variable holding the symbol with a list of library files for this document | |
1122 (defvar reftex-bibfile-list-symbol nil) | |
1123 (make-variable-buffer-local 'reftex-bibfile-list-symbol) | |
1124 | |
1125 (defun reftex-next-multifile-index () | |
1126 ;; Return the next free index for multifile symbols. | |
1127 (setq reftex-multifile-index (1+ reftex-multifile-index))) | |
1128 | |
1129 (defun reftex-tie-multifile-symbols () | |
1130 ;; Tie the buffer-local symbols to globals connected with the master file. | |
1131 ;; If the symbols for the current master file do not exist, they are created. | |
1132 | |
1133 (let* ((master (file-truename (reftex-TeX-master-file))) | |
1134 (index (assoc master reftex-master-index-list)) | |
1135 (symlist reftex-multifile-symbols) | |
1136 (symbol nil) | |
1137 (symname nil) | |
1138 (newflag nil)) | |
1139 ;; find the correct index | |
1140 (if index | |
1141 ;; symbols do exist | |
1142 (setq index (cdr index)) | |
1143 ;; get a new index and add info to the alist | |
1144 (setq index (reftex-next-multifile-index) | |
1145 reftex-master-index-list (cons | |
1146 (cons master index) | |
1147 reftex-master-index-list) | |
1148 newflag t)) | |
1149 | |
1150 ;; get/create symbols and tie them | |
1151 (while symlist | |
1152 (setq symbol (car symlist) | |
1153 symlist (cdr symlist) | |
1154 symname (symbol-name symbol)) | |
1155 (set symbol (intern (concat symname "-" (int-to-string index)))) | |
1156 ;; initialize if new symbols | |
1157 (if newflag (set (symbol-value symbol) nil))) | |
1158 | |
1159 ;; Return t if the symbols did already exist, nil when we've made them | |
1160 (not newflag))) | |
1161 | |
1162 (defun reftex-untie-multifile-symbols () | |
1163 ;; Remove ties from multifile symbols, so that next use makes new ones. | |
1164 (let ((symlist reftex-multifile-symbols) | |
1165 (symbol nil)) | |
1166 (while symlist | |
1167 (setq symbol (car symlist) | |
1168 symlist (cdr symlist)) | |
1169 (set symbol nil)))) | |
1170 | |
1171 (defun reftex-TeX-master-file () | |
1172 ;; Return the name of the master file associated with the current buffer. | |
1173 ;; When AUCTeX is loaded, we will use it's more sophisticated method. | |
1174 ;; We also support the default TeX and LaTeX modes | |
1175 ;; by checking for a variable tex-main-file. | |
1176 | |
1177 (let | |
1178 ((master | |
1179 (cond | |
1180 ((fboundp 'TeX-master-file) ; AUCTeX is loaded. Use its mechanism. | |
1181 (TeX-master-file t)) | |
1182 ((boundp 'TeX-master) ; The variable is defined - lets use it. | |
1183 (cond | |
1184 ((eq TeX-master t) | |
1185 (buffer-file-name)) | |
1186 ((eq TeX-master 'shared) | |
1187 (setq TeX-master (read-file-name "Master file: " | |
1188 nil nil t nil))) | |
1189 (TeX-master) | |
1190 (t | |
1191 (setq TeX-master (read-file-name "Master file: " | |
1192 nil nil t nil))))) | |
1193 ((boundp 'tex-main-file) | |
1194 ;; This is the variable from the default TeX modes | |
1195 (cond | |
1196 ((stringp tex-main-file) | |
1197 ;; ok, this must be it | |
1198 tex-main-file) | |
1199 (t | |
1200 ;; In this case, the buffer is its own master | |
1201 (buffer-file-name)))) | |
1202 (t | |
1203 ;; Know nothing about master file. Assume this is a master file. | |
1204 (buffer-file-name))))) | |
1205 (cond | |
1206 ((null master) | |
1207 (error "Need a filename for this buffer. Please save it first.")) | |
1208 ((or (file-exists-p master) | |
1209 (reftex-get-buffer-visiting master)) | |
1210 ;; We either see the file, or have a buffer on it. OK. | |
1211 ) | |
1212 ((or (file-exists-p (concat master ".tex")) | |
1213 (reftex-get-buffer-visiting (concat master ".tex"))) | |
1214 ;; Ahh, an extra .tex was missing... | |
1215 (setq master (concat master ".tex"))) | |
1216 (t | |
1217 ;; Something is wrong here. Throw an exception. | |
1218 (error "No such master file %s" master))) | |
1219 (expand-file-name master))) | |
1220 | |
1221 (defun reftex-make-master-buffer (master-file mode) | |
1222 "Make a master buffer which contains the MASTER-FILE and all includes. | |
1223 This is to prepare a buffer containing the entire document in correct | |
1224 sequence for parsing. Therefore it will even expand includes which are | |
1225 commented out. | |
1226 The function returns the number of input/include files not found." | |
1227 | |
1228 (interactive "fmaster file: ") | |
1229 (let ((not-found 0) file file-list tmp (font-lock-maximum-size 1)) | |
1230 (switch-to-buffer "*reftex-master.tex*") | |
1231 (erase-buffer) | |
1232 (if (not (eq major-mode mode)) | |
1233 (funcall mode)) | |
1234 ;; first insert the master file | |
1235 (if (not (file-exists-p master-file)) | |
1236 (error "No such master file: %s" master-file)) | |
1237 (reftex-insert-buffer-or-file master-file) | |
1238 (subst-char-in-region (point-min) (point-max) ?\r ?\n t) | |
1239 (setq file-list (cons master-file file-list)) | |
1240 (goto-char 1) | |
1241 ;; remember from which file these lines came | |
1242 (put-text-property (point-min) (point-max) 'file | |
1243 (expand-file-name master-file)) | |
1244 ;; Now find recursively all include/input statements and expand them | |
1245 (while (re-search-forward | |
1246 "^[ \t]*\\\\\\(include\\|input\\){\\([^}\n]+\\)}" nil t) | |
1247 ;; Change default directory, so that relative fine names work correctly | |
1248 (setq file (reftex-no-props (match-string 2))) | |
1249 (save-match-data | |
1250 (cd (file-name-directory | |
1251 (get-text-property (match-beginning 0) 'file))) | |
1252 (if (not (string-match "\\.tex$" file)) | |
1253 (setq file (concat file ".tex")))) | |
1254 (if (file-exists-p file) | |
1255 (progn | |
1256 (replace-match | |
1257 (format "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% START OF %s FILE: %s\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% END OF %s FILE: %s\n" | |
1258 (match-string 1) file | |
1259 (match-string 1) file)) | |
1260 (beginning-of-line 0) | |
1261 (narrow-to-region (point) (point)) | |
1262 ;; insert the file | |
1263 (reftex-insert-buffer-or-file file) | |
1264 (subst-char-in-region (point-min) (point-max) ?\r ?\n t) | |
1265 (setq file-list (cons (expand-file-name file) file-list)) | |
1266 ;; remember from which file these lines came | |
1267 (put-text-property (point-min) (point-max) | |
1268 'file (expand-file-name file)) | |
1269 (goto-char (point-min)) | |
1270 (widen)) | |
1271 (message "Input/include file %s not found. Ignored. Continuing..." | |
1272 file) | |
1273 (setq not-found (1+ not-found)))) | |
1274 (setq file-list (nreverse file-list)) | |
1275 (while (setq tmp (assoc (car file-list) reftex-master-include-list)) | |
1276 (setq reftex-master-include-list (delq tmp reftex-master-include-list))) | |
1277 (setq reftex-master-include-list (cons file-list reftex-master-include-list)) | |
1278 not-found)) | |
1279 | |
1280 (defun reftex-insert-buffer-or-file (file) | |
1281 "If there is a buffer associated with FILE, insert it - otherwise the FILE." | |
1282 (let ((buffer (reftex-get-buffer-visiting file))) | |
1283 (if buffer | |
1284 (let (beg end beg1 end1) | |
1285 (save-excursion | |
1286 ;; make sure we get the whole buffer | |
1287 (set-buffer buffer) | |
1288 (setq beg (point-min) end (point-max)) | |
1289 (widen) | |
1290 (setq beg1 (point-min) end1 (point-max))) | |
1291 (insert-buffer-substring buffer beg1 end1) | |
1292 (save-excursion | |
1293 (set-buffer buffer) | |
1294 (narrow-to-region beg end))) | |
1295 (insert-file-contents file)))) | |
1296 | |
1297 | |
1298 (defun reftex-parse-document (&optional buffer) | |
1299 "Rescan the document." | |
1300 (interactive) | |
1301 (save-window-excursion | |
1302 (save-excursion | |
1303 (if buffer | |
1304 (if (not (bufferp buffer)) | |
1305 (error "No such buffer %s" (buffer-name buffer)) | |
1306 (set-buffer buffer))) | |
1307 (reftex-access-scan-info t)))) | |
1308 | |
1309 (defun reftex-access-scan-info (&optional rescan) | |
1310 ;; Access the scanning info. When the multifile symbols are not yet tied, | |
1311 ;; tie them. When they are have to be created, do a buffer scan to | |
1312 ;; fill them. | |
1313 | |
1314 ;; If RESCAN is non-nil, enforce document scanning | |
1315 | |
1316 (catch 'exit | |
1317 (let ((rescan (or (equal rescan t) (equal rescan '(4))))) | |
1318 | |
1319 ;; Reset the mode if we had changes from style hooks | |
1320 (and reftex-tables-dirty | |
1321 (reftex-reset-mode)) | |
1322 | |
1323 (if (eq reftex-list-of-labels-symbol nil) | |
1324 ;; Symbols are not yet tied: Tie them and see if they are set | |
1325 (reftex-tie-multifile-symbols)) | |
1326 | |
1327 (if (and (symbol-value reftex-list-of-labels-symbol) | |
1328 (not rescan)) | |
1329 ;; Lists do already exist and we don't need to rescan. | |
1330 ;; Return from here. | |
1331 (throw 'exit t)) | |
1332 | |
1333 ;; We need to rescan | |
1334 ;; ================= | |
1335 | |
1336 (unwind-protect | |
1337 (save-window-excursion | |
1338 (save-excursion | |
1339 | |
1340 ;; do the scanning | |
1341 | |
1342 (let ((label-list-symbol reftex-list-of-labels-symbol) | |
1343 (label-numbers-symbol reftex-label-numbers-symbol) | |
1344 (bibfile-list-symbol reftex-bibfile-list-symbol)) | |
1345 | |
1346 (message "Creating master buffer...") | |
1347 (reftex-make-master-buffer (reftex-TeX-master-file) major-mode) | |
1348 | |
1349 (message "Scanning document...") | |
1350 | |
1351 (reftex-scan-buffer-for-labels | |
1352 label-numbers-symbol label-list-symbol) | |
1353 | |
1354 (reftex-scan-buffer-for-bibliography-statement | |
1355 bibfile-list-symbol) | |
1356 | |
1357 (message "Scanning document... done")))) | |
1358 | |
1359 (if (get-buffer "*reftex-master.tex*") | |
1360 (kill-buffer "*reftex-master.tex*")))))) | |
1361 | |
1362 (defun reftex-create-tags-file () | |
1363 "Create TAGS file by running `etags' on the current document. | |
1364 The TAGS file is also immediately visited with `visit-tags-table." | |
1365 (interactive) | |
1366 (reftex-access-scan-info current-prefix-arg) | |
1367 (let* ((master (reftex-TeX-master-file)) | |
1368 (files (assoc master reftex-master-include-list)) | |
1369 (cmd (format "etags %s" (mapconcat 'identity files " ")))) | |
1370 (save-excursion | |
1371 (set-buffer (reftex-get-buffer-visiting master)) | |
1372 (message "Running etags to create TAGS file...") | |
1373 (shell-command cmd) | |
1374 (visit-tags-table "TAGS")))) | |
1375 | |
1376 ;; History of grep commands. | |
1377 (defvar reftex-grep-history nil) | |
1378 (defvar reftex-grep-command "grep -n " | |
1379 "Last grep command used in \\[reftex-grep-document]; default for next grep.") | |
1380 | |
1381 (defun reftex-grep-document (grep-cmd) | |
1382 "Run grep query through all files related to this document. | |
1383 With prefix arg, force to rescan document. | |
1384 This works also without an active TAGS table." | |
1385 | |
1386 (interactive | |
1387 (list (read-from-minibuffer "Run grep on document (like this): " | |
1388 reftex-grep-command nil nil | |
1389 'reftex-grep-history))) | |
1390 (reftex-access-scan-info current-prefix-arg) | |
1391 (let* ((master (reftex-TeX-master-file)) | |
1392 (default-directory (file-name-directory master)) | |
1393 (re (format "\\`%s\\(.*\\)" (regexp-quote | |
1394 (expand-file-name default-directory)))) | |
1395 (files (assoc master reftex-master-include-list)) | |
1396 (cmd (format | |
1397 "%s %s" grep-cmd | |
1398 (mapconcat (function (lambda (x) | |
1399 (if (string-match re x) | |
1400 (match-string 1 x) | |
1401 x))) | |
1402 files " ")))) | |
1403 (grep cmd))) | |
1404 | |
1405 (defun reftex-search-document (&optional regexp) | |
1406 "Regexp search through all files of the current TeX document. | |
1407 Starts always in the master file. Stops when a match is found. | |
1408 To continue searching for next match, use command \\[tags-loop-continue]. | |
1409 This works also without an active TAGS table." | |
1410 (interactive) | |
1411 (let ((default (reftex-this-word))) | |
1412 (if (not regexp) | |
1413 (setq regexp (read-string (format "Search regexp in document [%s]: " | |
1414 default)))) | |
1415 (if (string= regexp "") (setq regexp (regexp-quote default))) | |
1416 | |
1417 (reftex-access-scan-info current-prefix-arg) | |
1418 (tags-search regexp (list 'assoc (reftex-TeX-master-file) | |
1419 'reftex-master-include-list)))) | |
1420 | |
1421 (defun reftex-query-replace-document (&optional from to delimited) | |
1422 "Run a query-replace-regexp of FROM with TO over the entire TeX document. | |
1423 Third arg DELIMITED (prefix arg) means replace only word-delimited matches. | |
1424 If you exit (\\[keyboard-quit] or ESC), you can resume the query replace | |
1425 with the command \\[tags-loop-continue]. | |
1426 This works also without an active TAGS table." | |
1427 (interactive) | |
1428 (let ((default (reftex-this-word))) | |
1429 (if (not from) | |
1430 (progn | |
1431 (setq from (read-string (format "Replace regexp in document [%s]: " | |
1432 default))) | |
1433 (if (string= from "") (setq from (regexp-quote default))))) | |
1434 (if (not to) | |
1435 (setq to (read-string (format "Replace regexp %s with: " from)))) | |
1436 (reftex-access-scan-info current-prefix-arg) | |
1437 (tags-query-replace from to (or delimited current-prefix-arg) | |
1438 (list 'assoc (reftex-TeX-master-file) | |
1439 'reftex-master-include-list)))) | |
1440 | |
1441 (defun reftex-change-label (&optional from to) | |
1442 "Query replace FROM with TO in all \\label{} and \\ref{} commands. | |
1443 Works on the entire multifile document. | |
1444 If you exit (\\[keyboard-quit] or ESC), you can resume the query replace | |
1445 with the command \\[tags-loop-continue]. | |
1446 This works also without an active TAGS table." | |
1447 (interactive) | |
1448 (let ((default (reftex-this-word "-a-zA-Z0-9_*.:"))) | |
1449 (if (not from) | |
1450 (setq from (read-string (format "Replace label globally [%s]: " | |
1451 default)))) | |
1452 (if (string= from "") (setq from default)) | |
1453 (if (not to) | |
1454 (setq to (read-string (format "Replace label %s with: " | |
1455 from)))) | |
1456 (reftex-query-replace-document | |
1457 (concat "\\\\\\(label\\|[a-z]*ref\\){" (regexp-quote from) "}") | |
1458 (format "\\\\\\1{%s}" to)))) | |
1459 | |
1460 (defun reftex-this-word (&optional class) | |
1461 ;; grab the word around point | |
1462 (setq class (or class "-a-zA-Z0-9:_/.*;|")) | |
1463 (save-excursion | |
1464 (buffer-substring-no-properties | |
1465 (progn (skip-chars-backward class) (point)) | |
1466 (progn (skip-chars-forward class) (point))))) | |
1467 | |
1468 ;;; =========================================================================== | |
1469 ;;; | |
1470 ;;; Functions to create and reference automatic labels | |
1471 | |
1472 ;; The following constants are derived from reftex-label-alist | |
1473 | |
1474 ;; Prompt used for label type querys directed to the user | |
1475 (defconst reftex-type-query-prompt nil) | |
1476 | |
1477 ;; Help string for label type querys | |
1478 (defconst reftex-type-query-help nil) | |
1479 | |
1480 ;; Alist relating label type to reference format | |
1481 (defconst reftex-typekey-to-format-alist nil) | |
1482 | |
1483 ;; Alist relating label type to label affix | |
1484 (defconst reftex-typekey-to-prefix-alist nil) | |
1485 | |
1486 ;; Alist relating environments or macros to label type and context regexp | |
1487 (defconst reftex-env-or-mac-alist nil) | |
1488 | |
1489 ;; List of macros carrying a label | |
1490 (defconst reftex-label-mac-list nil) | |
1491 | |
1492 ;; List of environments carrying a label | |
1493 (defconst reftex-label-env-list nil) | |
1494 | |
1495 ;; List of all typekey letters in use | |
1496 (defconst reftex-typekey-list nil) | |
1497 | |
1498 ;; Alist relating magic words to a label type | |
1499 (defconst reftex-words-to-typekey-alist nil) | |
1500 | |
1501 ;; The last list-of-labels entry used in a reference | |
1502 (defvar reftex-last-used-reference (list nil nil nil nil)) | |
1503 | |
1504 ;; The regular expression used to abbreviate words | |
1505 (defconst reftex-abbrev-regexp | |
1506 (concat | |
1507 "^\\(" | |
1508 (make-string (nth 0 reftex-abbrev-parameters) ?.) | |
1509 "[" (nth 2 reftex-abbrev-parameters) "]*" | |
1510 "\\)" | |
1511 "[" (nth 3 reftex-abbrev-parameters) "]" | |
1512 (make-string (1- (nth 1 reftex-abbrev-parameters)) ?.))) | |
1513 | |
1514 ;; Global variables used for communication between functions | |
1515 (defvar reftex-default-context-position nil) | |
1516 (defvar reftex-location-start nil) | |
1517 (defvar reftex-call-back-to-this-buffer nil) | |
1518 | |
1519 ;; List of buffers created temporarily for lookup, which should be killed | |
1520 (defvar reftex-buffers-to-kill nil) | |
1521 | |
1522 ;; The regexp used to find section statements | |
1523 (defconst reftex-section-regexp "^[ ]*\\\\\\(part\\|chapter\\|section\\|subsection\\|subsubsection\\|paragraph\\|subparagraph\\|subsubparagraph\\)\\*?\\(\\[[^]]*\\]\\)?{") | |
1524 | |
1525 ;; LaTeX section commands and level numbers | |
1526 (defconst reftex-section-levels | |
1527 '( | |
1528 ("part" . 0) | |
1529 ("chapter" . 1) | |
1530 ("section" . 2) | |
1531 ("subsection" . 3) | |
1532 ("subsubsection" . 4) | |
1533 ("paragraph" . 5) | |
1534 ("subparagraph" . 6) | |
1535 ("subsubparagraph" . 7) | |
1536 )) | |
1537 | |
1538 (defun reftex-label (&optional environment no-insert) | |
1539 "Insert a unique label. Return the label. | |
1540 If ENVIRONMENT is given, don't bother to find out yourself. | |
1541 If NO-INSERT is non-nil, do not insert label into buffer. | |
1542 With prefix arg, force to rescan document first. | |
1543 The label is also inserted into the label list. | |
1544 This function is controlled by the settings of reftex-insert-label-flags." | |
1545 | |
1546 (interactive) | |
1547 | |
1548 ;; Ensure access to scanning info and rescan buffer if prefix are is '(4) | |
1549 (reftex-access-scan-info current-prefix-arg) | |
1550 | |
1551 ;; Find out what kind of environment this is and abort if necessary | |
1552 (if (or (not environment) | |
1553 (not (assoc environment reftex-env-or-mac-alist))) | |
1554 (setq environment (reftex-label-location))) | |
1555 (if (not environment) | |
1556 (error "Can't figure out what kind of label should be inserted")) | |
1557 | |
1558 ;; Ok, go ahead | |
1559 (let (label num typekey prefix entry cell lab valid default force-prompt) | |
1560 (setq typekey (nth 1 (assoc environment | |
1561 reftex-env-or-mac-alist))) | |
1562 (setq prefix (or (cdr (assoc typekey reftex-typekey-to-prefix-alist)) | |
1563 (concat typekey "-"))) | |
1564 | |
1565 ;; make a default label | |
1566 (cond | |
1567 | |
1568 ((reftex-typekey-check typekey (nth 0 reftex-insert-label-flags)) | |
1569 ;; derive a label from context | |
1570 (setq default (nth 2 (reftex-label-info " "))) | |
1571 ;; catch the cases where the is actually no context available | |
1572 (if (or (string-match "NO MATCH FOR CONTEXT REGEXP" default) | |
1573 (string-match "ILLEGAL VALUE OF PARSE" default) | |
1574 (string-match "SECTION HEADING NOT FOUND" default) | |
1575 (string-match "HOOK ERROR" default) | |
1576 (string-match "^[ \t]*$" default)) | |
1577 (setq default prefix | |
1578 force-prompt t) ; need to prompt | |
1579 (setq default (concat prefix (reftex-string-to-label default))) | |
1580 | |
1581 ;; make it unique | |
1582 (setq label default) | |
1583 (setq num 1) | |
1584 (while (assoc label (symbol-value reftex-list-of-labels-symbol)) | |
1585 (setq label (concat default "-" (setq num (1+ num))))) | |
1586 (setq default label))) | |
1587 | |
1588 ((reftex-typekey-check typekey (nth 1 reftex-insert-label-flags)) ; prompt | |
1589 ;; Minimal default: the user will be prompted | |
1590 (setq default prefix)) | |
1591 | |
1592 (t | |
1593 ;; make an automatic label | |
1594 (while (assoc | |
1595 (setq default (concat prefix (reftex-next-label-number typekey))) | |
1596 (symbol-value reftex-list-of-labels-symbol))))) | |
1597 | |
1598 ;; Should we ask the user? | |
1599 (if (or (reftex-typekey-check typekey | |
1600 (nth 1 reftex-insert-label-flags)) ; prompt | |
1601 force-prompt) | |
1602 | |
1603 (while (not valid) | |
1604 ;; iterate until we get a legal label | |
1605 | |
1606 (setq label (read-string "Label: " default)) | |
1607 | |
1608 ;; Lets make sure that this is a legal label | |
1609 (cond | |
1610 | |
1611 ;; Test if label contains strange characters | |
1612 ((string-match reftex-label-illegal-re label) | |
1613 (message "Label \"%s\" contains illegal characters" label) | |
1614 (ding) | |
1615 (sit-for 2)) | |
1616 | |
1617 ;; Look it up in the label list | |
1618 ((setq entry (assoc label | |
1619 (symbol-value reftex-list-of-labels-symbol))) | |
1620 (message "Label \"%s\" exists in file %s" label (nth 3 entry)) | |
1621 (ding) | |
1622 (sit-for 2)) | |
1623 | |
1624 ;; Label is ok | |
1625 (t | |
1626 (setq valid t)))) | |
1627 (setq label default)) | |
1628 | |
1629 ;; Insert the label | |
1630 (if (not no-insert) | |
1631 (insert "\\label{" label "}")) | |
1632 | |
1633 ;; Insert the label into the label list | |
1634 (if (symbol-value reftex-list-of-labels-symbol) | |
1635 (let ((cnt 0) | |
1636 (pos (point)) | |
1637 (all (symbol-value reftex-list-of-labels-symbol)) | |
1638 (look-for nil) | |
1639 (note nil) | |
1640 (text nil) | |
1641 (file (buffer-file-name))) | |
1642 | |
1643 ;; find the previous label in order to know where to insert new label | |
1644 ;; into label list | |
1645 (save-excursion | |
1646 (if (re-search-backward "\\\\label{\\([^}]+\\)}" nil 1 2) | |
1647 (setq look-for (reftex-no-props (match-string 1)))) | |
1648 (if (or (re-search-forward | |
1649 "\\\\\\(include\\|input\\){[^}\n]+}" pos t) | |
1650 (re-search-forward reftex-section-regexp pos t) | |
1651 (null look-for)) | |
1652 (setq note "POSITION UNCERTAIN. RESCAN TO FIX."))) | |
1653 (if (not look-for) | |
1654 (set reftex-list-of-labels-symbol | |
1655 (cons (list label typekey text file note) | |
1656 (symbol-value reftex-list-of-labels-symbol))) | |
1657 (while all | |
1658 (setq cell (car all) | |
1659 all (cdr all) | |
1660 cnt (1+ cnt) | |
1661 lab (nth 0 cell)) | |
1662 (if (string= lab look-for) | |
1663 (progn | |
1664 (setcdr | |
1665 (nthcdr (1- cnt) | |
1666 (symbol-value reftex-list-of-labels-symbol)) | |
1667 (cons (list label typekey text file note) | |
1668 (nthcdr | |
1669 cnt (symbol-value reftex-list-of-labels-symbol)))) | |
1670 ;; to end the loop, set all to nil | |
1671 (setq all nil))))))) | |
1672 ;; return value of the function is the label | |
1673 label)) | |
1674 | |
1675 (defun reftex-string-to-label (string) | |
1676 ;; Convert a string (a sentence) to a label. | |
1677 ;; | |
1678 ;; Uses reftex-derive-label-parameters and reftex-abbrev-parameters | |
1679 ;; | |
1680 | |
1681 (let* ((words0 (reftex-split "[- \t\n\r]+" | |
1682 (reftex-no-props string))) | |
1683 (ignore-words (nth 5 reftex-derive-label-parameters)) | |
1684 words word) | |
1685 | |
1686 ;; remove words from the ignore list or with funny characters | |
1687 (while words0 | |
1688 (setq word (car words0) words0 (cdr words0)) | |
1689 (cond | |
1690 ((member (downcase word) ignore-words)) | |
1691 ((string-match reftex-label-illegal-re word) | |
1692 (if (nth 2 reftex-derive-label-parameters) | |
1693 (progn | |
1694 (while (string-match reftex-label-illegal-re word) | |
1695 (setq word (replace-match "" nil nil word))) | |
1696 (setq words (cons word words))))) | |
1697 (t | |
1698 (setq words (cons word words))))) | |
1699 (setq words (nreverse words)) | |
1700 | |
1701 ;; restrict number of words | |
1702 (if (> (length words) (nth 0 reftex-derive-label-parameters)) | |
1703 (setcdr (nthcdr (1- (nth 0 reftex-derive-label-parameters)) words) nil)) | |
1704 | |
1705 ;; First, try to use all words | |
1706 (setq string (mapconcat '(lambda(w) w) words | |
1707 (nth 4 reftex-derive-label-parameters))) | |
1708 | |
1709 ;; Abbreviate words if enforced by user settings or string length | |
1710 (if (or (eq t (nth 3 reftex-derive-label-parameters)) | |
1711 (and (nth 3 reftex-derive-label-parameters) | |
1712 (> (length string) (nth 1 reftex-derive-label-parameters)))) | |
1713 (setq words | |
1714 (mapcar | |
1715 '(lambda (w) (if (string-match reftex-abbrev-regexp w) | |
1716 (match-string 1 w) | |
1717 w)) | |
1718 words) | |
1719 string (mapconcat '(lambda(w) w) words | |
1720 (nth 4 reftex-derive-label-parameters)))) | |
1721 | |
1722 ;; Shorten if still to long | |
1723 (setq string | |
1724 (if (> (length string) (nth 1 reftex-derive-label-parameters)) | |
1725 (substring string 0 (nth 1 reftex-derive-label-parameters)) | |
1726 string)) | |
1727 | |
1728 ;; Delete the final punctuation, if any | |
1729 (if (string-match "[^a-zA-Z0-9]+$" string) | |
1730 (setq string (replace-match "" nil nil string))) | |
1731 string)) | |
1732 | |
1733 (defun reftex-label-location (&optional bound) | |
1734 ;; Return the environment or macro which determines the label type at point. | |
1735 ;; If optional BOUND is an integer, limit backward searches to that point. | |
1736 | |
1737 (let* ((loc1 (reftex-what-macro reftex-label-mac-list bound)) | |
1738 (loc2 (reftex-what-environment reftex-label-env-list bound)) | |
1739 (p1 (or (cdr loc1) 0)) | |
1740 (p2 (or (cdr loc2) 0))) | |
1741 | |
1742 (setq reftex-location-start (max p1 p2)) | |
1743 (if (> p1 p2) | |
1744 (progn | |
1745 (setq reftex-default-context-position p1) | |
1746 (car loc1)) | |
1747 (setq reftex-default-context-position | |
1748 (+ p2 8 (length (car loc2)))) | |
1749 (or (car loc2) "section")))) | |
1750 | |
1751 | |
1752 (defun reftex-next-label-number (type) | |
1753 ;; Increment value of automatic labels in current buffer. Return new value. | |
1754 | |
1755 ;; Ensure access to scanning info | |
1756 (reftex-access-scan-info) | |
1757 | |
1758 (let ((n (cdr (assoc type (symbol-value reftex-label-numbers-symbol))))) | |
1759 (if (not (integerp n)) | |
1760 ;; oops - type not known - make one here | |
1761 (progn | |
1762 (set reftex-label-numbers-symbol | |
1763 (cons (cons type 0) | |
1764 (symbol-value reftex-label-numbers-symbol))) | |
1765 (setq n 0))) | |
1766 (setq n (1+ n)) | |
1767 (setcdr (assoc type (symbol-value reftex-label-numbers-symbol)) n) | |
1768 n)) | |
1769 | |
1770 ;; Help string for the reference label menu | |
1771 (defconst reftex-reference-label-help | |
1772 " AVAILABLE KEYS IN REFERENCE LABEL MENU | |
1773 ====================================== | |
1774 n / p Go to next/previous label (Cursor motion works as well) | |
1775 r / s Rescan document for labels / Switch label type | |
1776 t / # Toggle table of contents / Toggle counter mode | |
1777 c Toggle display of short context | |
1778 SPACE Show full context for current label in other window | |
1779 f Toggle follow mode: other window will follow context | |
1780 a / q Use last referenced label / Quit without accepting label | |
1781 ? / C-r Display this help message / Recursive Edit into other window | |
1782 RETURN Accept current label") | |
1783 | |
1784 (defun reftex-reference (&optional type no-insert) | |
1785 "Make a LaTeX reference. Look only for labels of a certain TYPE. | |
1786 With prefix arg, force to rescan buffer for labels. This should only be | |
1787 necessary if you have recently entered labels yourself without using | |
1788 reftex-label. Rescanning of the buffer can also be requested from the | |
1789 label selection menu. | |
1790 The function returns the selected label or nil. | |
1791 If NO-INSERT is non-nil, do not insert \\ref{} command, just return label. | |
1792 When called with 2 C-u prefix args, disable magic word recognition." | |
1793 | |
1794 (interactive) | |
1795 | |
1796 ;; check for active recursive edits | |
1797 (reftex-check-recursive-edit) | |
1798 | |
1799 ;; Ensure access to scanning info and rescan buffer if prefix are is '(4) | |
1800 (reftex-access-scan-info current-prefix-arg) | |
1801 | |
1802 (if (not type) | |
1803 ;; guess type from context | |
1804 (if (and reftex-guess-label-type | |
1805 (not (= 16 (prefix-numeric-value current-prefix-arg))) | |
1806 (setq type (assoc (downcase (reftex-word-before-point)) | |
1807 reftex-words-to-typekey-alist))) | |
1808 (setq type (cdr type)) | |
1809 (setq type (reftex-query-label-type)))) | |
1810 | |
1811 (let (label pair | |
1812 (form (or (cdr (assoc type reftex-typekey-to-format-alist)) | |
1813 "\\ref{%s}"))) | |
1814 | |
1815 ;; Have the user select a label | |
1816 (setq pair (reftex-offer-label-menu type)) | |
1817 (setq label (car pair)) | |
1818 | |
1819 (if (and label | |
1820 (not no-insert)) | |
1821 (progn | |
1822 ;; do we need to remove spaces? | |
1823 (if (string= "~" (substring form 0 1)) | |
1824 (while (or (= (preceding-char) ?\ ) | |
1825 (= (preceding-char) ?\C-i)) | |
1826 (backward-delete-char 1))) | |
1827 ;; ok, insert the reference | |
1828 (insert (format form label label)) | |
1829 (message "")) | |
1830 (message "Quit")) | |
1831 ;; return the label | |
1832 label)) | |
1833 | |
1834 (defun reftex-goto-label (&optional arg) | |
1835 "Go to a LaTeX label. With prefix ARG: go to label in another window." | |
1836 (interactive "P") | |
1837 (let (type label file pair) | |
1838 (if (not type) | |
1839 (setq type (reftex-query-label-type))) | |
1840 | |
1841 (setq pair (reftex-offer-label-menu type) | |
1842 label (car pair) | |
1843 file (cdr pair)) | |
1844 (if (and label file (file-exists-p file)) | |
1845 (progn | |
1846 (if arg | |
1847 (find-file-other-window file) | |
1848 (find-file file)) | |
1849 (goto-char (point-min)) | |
1850 (if (not (search-forward (concat "\\label{" label "}") nil t)) | |
1851 (error "No such label found: %s" label) | |
1852 (reftex-highlight 0 (match-beginning 0) (match-end 0)) | |
1853 (add-hook 'pre-command-hook 'reftex-highlight-shall-die))) | |
1854 (message "Quit") | |
1855 nil))) | |
1856 | |
1857 ;; Internal list with index numbers of labels in the selection menu | |
1858 (defvar reftex-label-index-list nil) | |
1859 | |
1860 (defun reftex-offer-label-menu (typekey) | |
1861 ;; Offer a menu with the appropriate labels. Return (label . file). | |
1862 (let* ((buf (current-buffer)) | |
1863 (near-label (reftex-find-nearby-label)) | |
1864 (toc (reftex-typekey-check typekey reftex-label-menu-flags 0)) | |
1865 (context (not (reftex-typekey-check | |
1866 typekey reftex-label-menu-flags 3))) | |
1867 (counter (reftex-typekey-check | |
1868 typekey reftex-label-menu-flags 2)) | |
1869 (follow (reftex-typekey-check | |
1870 typekey reftex-label-menu-flags 4)) | |
1871 offset rtn key cnt entry) | |
1872 | |
1873 (setq reftex-call-back-to-this-buffer buf) | |
1874 (setq entry (cons nil nil)) | |
1875 | |
1876 (unwind-protect | |
1877 (catch 'exit | |
1878 (while t | |
1879 (save-window-excursion | |
1880 (switch-to-buffer-other-window "*RefTeX Select*") | |
1881 (erase-buffer) | |
1882 (setq truncate-lines t) | |
1883 (setq reftex-label-index-list (reftex-make-and-insert-label-list | |
1884 typekey buf toc context counter | |
1885 near-label)) | |
1886 (setq near-label "_ ") ; turn off search for near label | |
1887 (setq offset (or (car reftex-label-index-list) offset)) | |
1888 ;; use only when searched | |
1889 (setq reftex-label-index-list (cdr reftex-label-index-list)) | |
1890 ;; only this is the true list | |
1891 (if (not reftex-label-index-list) | |
1892 (error "No labels of type \"%s\"" typekey)) | |
1893 (setq rtn | |
1894 (reftex-select-item | |
1895 nil | |
1896 "Label: [n]ext [p]rev [r]escan [t]oc [ ]context [q]uit RETURN [?]HELP+more" | |
1897 "^>" | |
1898 "\n[^.]" | |
1899 2 | |
1900 reftex-reference-label-help | |
1901 '(?r ?c ?t ?s ?# ?a) | |
1902 offset | |
1903 'reftex-select-label-callback follow)) | |
1904 (setq key (car rtn) | |
1905 cnt (cdr rtn) | |
1906 offset (1+ cnt)) | |
1907 (if (not key) (throw 'exit nil)) | |
1908 (cond | |
1909 ((equal key ?r) | |
1910 ;; rescan buffer | |
1911 (reftex-parse-document buf)) | |
1912 ((equal key ?c) | |
1913 ;; toggle context mode | |
1914 (setq context (not context))) | |
1915 ((equal key ?s) | |
1916 ;; switch type | |
1917 (setq typekey (reftex-query-label-type))) | |
1918 ((equal key ?t) | |
1919 ;; toggle tabel of contents display | |
1920 (setq toc (not toc))) | |
1921 ((equal key ?#) | |
1922 ;; toggle counter display | |
1923 (setq counter (not counter))) | |
1924 ((equal key ?a) | |
1925 ;; reuse the last referenced label again | |
1926 (setq entry reftex-last-used-reference) | |
1927 (throw 'exit t)) | |
1928 (t | |
1929 (set-buffer buf) | |
1930 (setq entry (nth (nth cnt reftex-label-index-list) | |
1931 (symbol-value reftex-list-of-labels-symbol))) | |
1932 (setq reftex-last-used-reference entry) | |
1933 (throw 'exit t)))))) | |
1934 (kill-buffer "*RefTeX Select*") | |
1935 (reftex-kill-temporary-buffers)) | |
1936 (cons (reftex-no-props (nth 0 entry)) (nth 3 entry)))) | |
1937 | |
1938 ;; Indentation for table of context lines in the menu | |
1939 (defconst reftex-toc-indent " ") | |
1940 ;; Indentation for the lines containing the label | |
1941 (defconst reftex-label-indent "> ") | |
1942 ;; Indentation for context lines | |
1943 (defconst reftex-context-indent ". ") | |
1944 ;; Indentation per section level | |
1945 (defvar reftex-level-indent 2 | |
1946 "*Number of spaces to be used for indentation per section level. | |
1947 With more indentation, the label menu looks nicer, but shows less context. | |
1948 Changing this is only fully operational after the next buffer scan.") | |
1949 | |
1950 (defun reftex-make-and-insert-label-list (typekey0 buf toc context | |
1951 counter near-label) | |
1952 ;; Insert a menu of all labels in buffer BUF into current buffer. | |
1953 ;; Return the list of labels, with the index of NEAR-LABEL as extra car. | |
1954 (let (ins-list index-list offset) | |
1955 (save-excursion | |
1956 (set-buffer buf) | |
1957 (let* ((all nil) | |
1958 (font (reftex-use-fonts)) | |
1959 (cnt 0) | |
1960 (file nil) | |
1961 (index -1) | |
1962 (toc-indent reftex-toc-indent) | |
1963 (label-indent | |
1964 (concat reftex-label-indent | |
1965 (if toc (make-string (* 7 reftex-level-indent) ?\ ) ""))) | |
1966 (context-indent | |
1967 (concat reftex-context-indent | |
1968 (if toc (make-string (* 7 reftex-level-indent) ?\ ) ""))) | |
1969 cell text label typekey note comment) | |
1970 | |
1971 ; Ensure access to scanning info | |
1972 (reftex-access-scan-info) | |
1973 | |
1974 (setq all (symbol-value reftex-list-of-labels-symbol)) | |
1975 | |
1976 (while all | |
1977 | |
1978 (setq index (1+ index) | |
1979 cell (car all) | |
1980 all (cdr all)) | |
1981 | |
1982 (if (null (nth 2 cell)) | |
1983 ;; No context yet. Quick update | |
1984 (progn | |
1985 (setq cell (reftex-label-info-update cell)) | |
1986 (setcar (nthcdr index | |
1987 (symbol-value reftex-list-of-labels-symbol)) | |
1988 cell))) | |
1989 | |
1990 ;; in the following setq we *copy* the label, since we will change | |
1991 ;; its properties, and we cannot have any properties in the list | |
1992 ;; (because of assoc searches) | |
1993 (setq label (copy-sequence (nth 0 cell)) | |
1994 typekey (nth 1 cell) | |
1995 text (nth 2 cell) | |
1996 file (nth 3 cell) | |
1997 note (nth 4 cell) | |
1998 comment (get-text-property 0 'in-comment text)) | |
1999 | |
2000 (if (string= label near-label) | |
2001 (setq offset (1+ cnt))) | |
2002 | |
2003 (cond | |
2004 ((and toc (string= typekey "toc")) | |
2005 (setq ins-list | |
2006 (cons (concat toc-indent text "\n") | |
2007 ins-list))) | |
2008 ((string= typekey "toc")) | |
2009 ((and (or (string= typekey typekey0) (string= typekey0 " ")) | |
2010 (or (nth 5 reftex-label-menu-flags) ; show-commented? | |
2011 (null comment))) | |
2012 (setq cnt (1+ cnt)) | |
2013 (if comment (setq label (concat "% " label))) | |
2014 (if font | |
2015 (put-text-property | |
2016 0 (length label) | |
2017 'face | |
2018 (if comment | |
2019 'font-lock-comment-face | |
2020 'font-lock-reference-face) | |
2021 label)) | |
2022 (setq index-list (cons index index-list)) | |
2023 (setq ins-list | |
2024 (cons (concat | |
2025 label-indent | |
2026 label | |
2027 (if counter (format " (%d) " cnt)) | |
2028 (if comment " LABEL IS COMMENTED OUT ") | |
2029 (if note (concat " " note) "") | |
2030 "\n" | |
2031 (if context (concat context-indent text "\n"))) | |
2032 ins-list)))) | |
2033 ))) | |
2034 | |
2035 (apply 'insert (nreverse ins-list)) | |
2036 (cons offset (nreverse index-list)))) | |
2037 | |
2038 (defun reftex-query-label-type () | |
2039 ;; Ask for label type | |
2040 (message reftex-type-query-prompt) | |
2041 (let ((key (read-char))) | |
2042 (if (equal key ?\?) | |
2043 (progn | |
2044 (save-window-excursion | |
2045 (with-output-to-temp-buffer "*RefTeX Help*" | |
2046 (princ reftex-type-query-help)) | |
2047 (setq key (read-char)) | |
2048 (kill-buffer "*RefTeX Help*")))) | |
2049 (if (not (member (char-to-string key) reftex-typekey-list)) | |
2050 (error "No such label type: %s" (char-to-string key))) | |
2051 (char-to-string key))) | |
2052 | |
2053 (defun reftex-find-nearby-label () | |
2054 ;; Find a nearby label. | |
2055 (save-excursion | |
2056 (if (or (re-search-backward "\\\\label{\\([^}]+\\)}" nil t) | |
2057 (re-search-forward "\\\\label{\\([^}]+\\)}" nil t)) | |
2058 (reftex-no-props (match-string 1)) | |
2059 nil))) | |
2060 | |
2061 ;; Variable holding the vector with section numbers | |
2062 (defvar reftex-section-numbers [0 0 0 0 0 0 0 0]) | |
2063 | |
2064 (defun reftex-scan-buffer-for-labels (label-numbers-symbol label-list-symbol) | |
2065 ;; Scan the buffer for labels and save them in a list. | |
2066 (save-excursion | |
2067 (let ((regexp (concat "\\\\label{\\([^}]*\\)}" "\\|" | |
2068 reftex-section-regexp)) | |
2069 (font (reftex-use-fonts)) | |
2070 (bound 0) | |
2071 (highest-level 100) | |
2072 file (level 1) start star text text1 label section-number macro find) | |
2073 (set label-list-symbol nil) | |
2074 (goto-char 0) | |
2075 | |
2076 ;; reset label numbers | |
2077 (set label-numbers-symbol | |
2078 (mapcar '(lambda(x) (cons x 0)) reftex-typekey-list)) | |
2079 | |
2080 ;; reset section numbers | |
2081 (reftex-section-number reftex-section-numbers -1) | |
2082 | |
2083 (while (re-search-forward regexp nil t) | |
2084 (setq file (get-text-property (match-beginning 0) 'file)) | |
2085 (if (string= (buffer-substring (match-beginning 0) | |
2086 (+ 7 (match-beginning 0))) "\\label{") | |
2087 ;; It is a label | |
2088 (progn | |
2089 (setq label (reftex-no-props (match-string 1))) | |
2090 (set label-list-symbol | |
2091 (cons (reftex-label-info label file bound) | |
2092 (symbol-value label-list-symbol)))) | |
2093 | |
2094 ;; It is a section | |
2095 (setq bound (point)) | |
2096 (setq star (= ?* (char-after (match-end 2)))) | |
2097 (setq find (buffer-substring-no-properties | |
2098 (1- (match-beginning 2)) (match-end 0))) | |
2099 (setq macro (reftex-no-props (match-string 2))) | |
2100 (setq level (cdr (assoc macro reftex-section-levels))) | |
2101 | |
2102 (setq section-number (reftex-section-number | |
2103 reftex-section-numbers level star)) | |
2104 (setq highest-level (min highest-level level)) | |
2105 (if (= level highest-level) | |
2106 (message | |
2107 "Scanning %s %s ..." | |
2108 (car (nth level reftex-section-levels)) | |
2109 section-number)) | |
2110 | |
2111 ;; get the title | |
2112 (save-match-data | |
2113 (setq text1 (reftex-context-substring)) | |
2114 (setq text (reftex-nicify-text text1))) | |
2115 | |
2116 (setq find (reftex-allow-for-ctrl-m (concat find text1))) | |
2117 | |
2118 ;; add section number and indentation | |
2119 (setq text | |
2120 (concat | |
2121 (make-string (* reftex-level-indent level) ?\ ) | |
2122 (if (nth 1 reftex-label-menu-flags) ; section number flag | |
2123 (concat section-number " ")) | |
2124 text)) | |
2125 ;; fontify | |
2126 (if font (put-text-property 0 (length text) | |
2127 'face 'font-lock-comment-face text)) | |
2128 | |
2129 ;; insert in list | |
2130 (set label-list-symbol | |
2131 (cons (list nil "toc" text file find) | |
2132 (symbol-value label-list-symbol))))) | |
2133 (set label-list-symbol | |
2134 (nreverse (symbol-value label-list-symbol)))))) | |
2135 | |
2136 | |
2137 (defun reftex-label-info-update (cell) | |
2138 ;; Update information about just one label in a different file. | |
2139 ;; CELL contains the old info list | |
2140 (let* ((label (nth 0 cell)) | |
2141 (typekey (nth 1 cell)) | |
2142 (text (nth 2 cell)) | |
2143 (file (nth 3 cell)) | |
2144 (note (nth 4 cell)) | |
2145 (buf (reftex-get-file-buffer-force | |
2146 file (not reftex-keep-temporary-buffers)))) | |
2147 (if (not buf) | |
2148 (list label typekey "" file "LOST LABEL. RESCAN TO FIX.") | |
2149 (save-excursion | |
2150 (set-buffer buf) | |
2151 (save-restriction | |
2152 (widen) | |
2153 (goto-char 1) | |
2154 | |
2155 (if (re-search-forward (concat "\\\\label{" (regexp-quote label) "}") | |
2156 nil t) | |
2157 (append (reftex-label-info label file) (list note)) | |
2158 (list label typekey "" file "LOST LABEL. RESCAN TO FIX."))))))) | |
2159 | |
2160 (defun reftex-label-info (label &optional file bound) | |
2161 ;; Return info list on LABEL at point. | |
2162 (let* ((env-or-mac (reftex-label-location bound)) | |
2163 (typekey (nth 1 (assoc env-or-mac reftex-env-or-mac-alist))) | |
2164 (file (or file (buffer-file-name))) | |
2165 (parse (if (reftex-typekey-check | |
2166 typekey reftex-use-text-after-label-as-context) | |
2167 nil | |
2168 (nth 2 (assoc env-or-mac reftex-env-or-mac-alist)))) | |
2169 (text (reftex-short-context env-or-mac parse reftex-location-start))) | |
2170 (if (reftex-in-comment) | |
2171 (put-text-property 0 1 'in-comment t text)) | |
2172 (list label typekey text file))) | |
2173 | |
2174 (defun reftex-in-comment () | |
2175 (save-excursion | |
2176 (skip-chars-backward "^%\n\r") | |
2177 (= (preceding-char) ?%))) | |
2178 | |
2179 (defun reftex-short-context (env parse &optional bound) | |
2180 ;; Get about one line of useful context for the label definition at point. | |
2181 | |
2182 (reftex-nicify-text | |
2183 | |
2184 (cond | |
2185 | |
2186 ((null parse) | |
2187 (save-excursion | |
2188 (reftex-context-substring))) | |
2189 | |
2190 ((eq parse t) | |
2191 (if (string= env "section") | |
2192 ;; special treatment for section labels | |
2193 (save-excursion | |
2194 (if (re-search-backward reftex-section-regexp (point-min) t) | |
2195 (progn | |
2196 (goto-char (match-end 0)) | |
2197 (reftex-context-substring)) | |
2198 "SECTION HEADING NOT FOUND")) | |
2199 (save-excursion | |
2200 (goto-char reftex-default-context-position) | |
2201 (reftex-context-substring)))) | |
2202 | |
2203 ((stringp parse) | |
2204 (save-excursion | |
2205 (if (re-search-backward parse bound t) | |
2206 (progn | |
2207 (goto-char (match-end 0)) | |
2208 (reftex-context-substring)) | |
2209 "NO MATCH FOR CONTEXT REGEXP"))) | |
2210 ((fboundp parse) | |
2211 ;; A hook function. Call it. | |
2212 (save-excursion | |
2213 (condition-case error-var | |
2214 (funcall parse env) | |
2215 ('error (format "HOOK ERROR: %s" (cdr error-var)))))) | |
2216 (t | |
2217 "ILLEGAL VALUE OF PARSE")))) | |
2218 | |
2219 (defun reftex-context-substring () | |
2220 ;; Return up to 100 chars from point | |
2221 ;; When point is just after a { or [, limit string to matching parenthesis | |
2222 (cond | |
2223 ((or (= (preceding-char) ?\{) | |
2224 (= (preceding-char) ?\[)) | |
2225 ;; inside a list - get only the list, with modified syntax to be perfect | |
2226 (buffer-substring | |
2227 (point) | |
2228 (min (+ 100 (point)) | |
2229 (point-max) | |
2230 (condition-case nil | |
2231 (progn | |
2232 (up-list 1) | |
2233 (1- (point))) | |
2234 ('error (point-max)))))) | |
2235 (t | |
2236 ;; no list - just grab 100 characters | |
2237 (buffer-substring (point) (min (+ 100 (point)) (point-max)))))) | |
2238 | |
2239 (defun reftex-section-number (section-numbers &optional level star) | |
2240 ;; Return a string with the current section number. | |
2241 ;; When LEVEL is non-nil, increase section numbers on that level. | |
2242 (let* ((depth 6) idx n (string "")) | |
2243 (if level | |
2244 (progn | |
2245 (if (and (> level -1) (not star)) | |
2246 (aset section-numbers level (1+ (aref section-numbers level)))) | |
2247 (setq idx (1+ level)) | |
2248 (while (<= idx depth) | |
2249 (aset section-numbers idx 0) | |
2250 (setq idx (1+ idx))))) | |
2251 (setq idx 0) | |
2252 (while (<= idx depth) | |
2253 (setq n (aref section-numbers idx)) | |
2254 (setq string (concat string (if (not (string= string "")) "." "") | |
2255 (int-to-string n))) | |
2256 (setq idx (1+ idx))) | |
2257 (save-match-data | |
2258 (if (string-match "\\`\\(0\\.\\)+" string) | |
2259 (setq string (replace-match "" nil nil string))) | |
2260 (if (string-match "\\(\\.0\\)+\\'" string) | |
2261 (setq string (replace-match "" nil nil string)))) | |
2262 (if star | |
2263 (concat (make-string (1- (length string)) ?\ ) "*") | |
2264 string))) | |
2265 | |
2266 ;; A variable to remember the index of the last label context shown | |
2267 (defvar reftex-last-cnt 0) | |
2268 | |
2269 (defun reftex-select-label-callback (cnt) | |
2270 ;; Callback function called from the label selection in order to | |
2271 ;; show context in another window | |
2272 (let* ((this-window (selected-window)) | |
2273 index entry label file buffer) | |
2274 ;; pop to original buffer in order to get correct variables | |
2275 (catch 'exit | |
2276 (save-excursion | |
2277 (set-buffer reftex-call-back-to-this-buffer) | |
2278 (setq index (nth (or cnt 1) reftex-label-index-list) | |
2279 entry (nth index (symbol-value reftex-list-of-labels-symbol)) | |
2280 label (nth 0 entry) | |
2281 file (nth 3 entry))) | |
2282 | |
2283 ;; goto the file in another window | |
2284 (setq buffer (reftex-get-file-buffer-force | |
2285 file (not reftex-keep-temporary-buffers))) | |
2286 (if buffer | |
2287 ;; good - the file is available | |
2288 (switch-to-buffer-other-window buffer) | |
2289 ;; we have got a problem here. The file does not exist. | |
2290 ;; Let' get out of here.. | |
2291 (ding) | |
2292 (throw 'exit nil)) | |
2293 | |
2294 | |
2295 ;; search for that label | |
2296 (if (not (and (integerp cnt) | |
2297 (integerp reftex-last-cnt) | |
2298 (if (> cnt reftex-last-cnt) | |
2299 (search-forward (concat "\\label{" label "}") nil t) | |
2300 (search-backward (concat "\\label{" label "}") nil t)))) | |
2301 (progn | |
2302 (goto-char 1) | |
2303 (search-forward (concat "\\label{" label "}") nil t))) | |
2304 (reftex-highlight 0 (match-beginning 0) (match-end 0)) | |
2305 (reftex-show-entry) | |
2306 (recenter (/ (window-height) 2)) | |
2307 (select-window this-window)))) | |
2308 | |
2309 (defun reftex-pop-to-label (label file-list &optional mark-to-kill highlight) | |
2310 ;; Find LABEL in any file in FILE-LIST in another window. | |
2311 ;; If mark-to-kill is non-nil, mark new buffer for killing. | |
2312 ;; If HIGHLIGHT is non-nil, highlight the label definition. | |
2313 (let* ((re (concat "\\\\label{" (regexp-quote label) "}")) | |
2314 file buf) | |
2315 (catch 'exit | |
2316 (while file-list | |
2317 (setq file (car file-list) | |
2318 file-list (cdr file-list)) | |
2319 (if (not (setq buf (reftex-get-file-buffer-force file mark-to-kill))) | |
2320 (error "No such file %s" file)) | |
2321 (set-buffer buf) | |
2322 (widen) | |
2323 (goto-char (point-min)) | |
2324 (if (re-search-forward re nil t) | |
2325 (progn | |
2326 (switch-to-buffer-other-window buf) | |
2327 (goto-char (match-beginning 0)) | |
2328 (recenter (/ (window-height) 2)) | |
2329 (if highlight | |
2330 (reftex-highlight 0 (match-beginning 0) (match-end 0))) | |
2331 (throw 'exit (selected-window))))) | |
2332 (error "Label %s not found" label)))) | |
2333 | |
2334 (defun reftex-find-duplicate-labels () | |
2335 "Produce a list of all duplicate labels in the document." | |
2336 | |
2337 (interactive) | |
2338 | |
2339 ;; Rescan the document to make sure | |
2340 (reftex-access-scan-info t) | |
2341 | |
2342 (let ((master (reftex-TeX-master-file)) | |
2343 (dlist | |
2344 (mapcar | |
2345 '(lambda(x) | |
2346 (let (x1) | |
2347 (cond | |
2348 ((car x) | |
2349 (setq x1 (reftex-all-assoc-string | |
2350 (car x) (symbol-value reftex-list-of-labels-symbol))) | |
2351 (if (< 1 (length x1)) | |
2352 (append (list (reftex-no-props (car x))) | |
2353 (mapcar '(lambda(x) | |
2354 (abbreviate-file-name (nth 3 x))) x1)) | |
2355 (list nil))) | |
2356 (t nil)))) | |
2357 (reftex-uniquify (symbol-value reftex-list-of-labels-symbol))))) | |
2358 (setq dlist (reftex-uniquify dlist)) | |
2359 (if (null dlist) (error "No duplicate labels in document")) | |
2360 (switch-to-buffer-other-window "*Help*") | |
2361 (make-local-variable 'TeX-master) | |
2362 (setq TeX-master master) | |
2363 (erase-buffer) | |
2364 (insert " MULTIPLE LABELS IN CURRENT DOCUMENT:\n") | |
2365 (insert " Move point to label and type `M-x reftex-change-label'\n" | |
2366 " This will run a query-replace on the label and its references\n") | |
2367 (insert " LABEL FILE\n") | |
2368 (insert " -------------------------------------------------------------\n") | |
2369 (while dlist | |
2370 (if (and (car (car dlist)) | |
2371 (cdr (car dlist))) | |
2372 (progn | |
2373 (insert (mapconcat '(lambda(x) x) (car dlist) "\n ") "\n"))) | |
2374 (setq dlist (cdr dlist))) | |
2375 (goto-char (point-min)))) | |
2376 | |
2377 (defun reftex-all-assoc-string (key list) | |
2378 ;; Return a list of all associations of KEY in LIST. Comparison with string= | |
2379 (let (rtn) | |
2380 (while list | |
2381 (if (string= (car (car list)) key) | |
2382 (setq rtn (cons (car list) rtn))) | |
2383 (setq list (cdr list))) | |
2384 (nreverse rtn))) | |
2385 | |
2386 (defun reftex-kill-temporary-buffers () | |
2387 ;; Kill all buffers in the list reftex-kill-temporary-buffers. | |
2388 (while reftex-buffers-to-kill | |
2389 (if (bufferp (car reftex-buffers-to-kill)) | |
2390 (progn | |
2391 (and (buffer-modified-p (car reftex-buffers-to-kill)) | |
2392 (y-or-n-p (format "Save file %s? " | |
2393 (buffer-file-name | |
2394 (car reftex-buffers-to-kill)))) | |
2395 (save-excursion | |
2396 (set-buffer (car reftex-buffers-to-kill)) | |
2397 (save-buffer))) | |
2398 (kill-buffer (car reftex-buffers-to-kill)))) | |
2399 (setq reftex-buffers-to-kill (cdr reftex-buffers-to-kill)))) | |
2400 | |
2401 (defun reftex-show-entry () | |
2402 ;; Show entry if point is hidden by outline mode | |
2403 (let ((pos (point))) | |
2404 (if (and reftex-auto-show-entry | |
2405 (boundp 'outline-minor-mode) | |
2406 outline-minor-mode | |
2407 (looking-at "[^\n\r]*\r")) | |
2408 (progn | |
2409 (outline-back-to-heading) | |
2410 (show-entry) | |
2411 (goto-char pos))))) | |
2412 | |
2413 | |
2414 (defun reftex-nicify-text (text) | |
2415 ;; Make TEXT nice for inclusion into label menu | |
2416 (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text) ; remove extra whitespace | |
2417 (setq text (replace-match " " nil t text))) | |
2418 (if (string-match "\\\\end{.*" text) ; nothing beyond \end{ | |
2419 (setq text (replace-match "" nil t text))) | |
2420 (if (string-match "\\\\label{[^}]*}" text) ; kill the label | |
2421 (setq text (replace-match "" nil t text))) | |
2422 (if (string-match "^ +" text) ; leading whitespace | |
2423 (setq text (replace-match "" nil t text))) | |
2424 (cond | |
2425 ((> (length text) 100) ; not to long | |
2426 (setq text (substring text 0 100))) | |
2427 ((= (length text) 0) ; not empty | |
2428 (setq text " "))) | |
2429 text) | |
2430 | |
2431 (defun reftex-typekey-check (typekey conf-variable &optional n) | |
2432 ;; Check if CONF-VARIABLE is true or contains TYPEKEY | |
2433 (and n (setq conf-variable (nth n conf-variable))) | |
2434 (or (equal conf-variable t) | |
2435 (and (stringp conf-variable) | |
2436 (string-match (concat "[" conf-variable "]") typekey)))) | |
2437 | |
2438 ;;; =========================================================================== | |
2439 ;;; | |
2440 ;;; Table of contents (contributed from Stephen Eglen, changed by C. Dominik) | |
2441 | |
2442 ;; We keep at most one *toc* buffer - it is easy to make them | |
2443 | |
2444 (defvar reftex-last-toc-master nil | |
2445 "Stores the name of the tex file that `reftex-toc' was last run on.") | |
2446 | |
2447 (defvar reftex-last-toc-file nil | |
2448 "Stores the file name from which `reftex-toc' was called. For redo command.") | |
2449 | |
2450 (defvar reftex-toc-return-marker (make-marker) | |
2451 "Marker which makes it possible to return from toc to old position.") | |
2452 | |
2453 (defun reftex-toc () | |
2454 "Show the table of contents for the current document. | |
2455 To see the corresponding part of the LaTeX document, use within the | |
2456 *toc* buffer: | |
2457 | |
2458 SPC Show the corresponding section of the LaTeX document | |
2459 RET Goto the section and hide the *toc* buffer | |
2460 q Hide the *toc* window and return to position of last reftex-toc command | |
2461 Q Kill the *toc* buffer and return to position of last reftex-toc command | |
2462 f Toggle follow mode on and off | |
2463 | |
2464 When called with a raw C-u prefix, rescan the document first." | |
2465 | |
2466 (interactive) | |
2467 | |
2468 (and (not (string= reftex-last-toc-master (reftex-TeX-master-file))) | |
2469 (get-buffer "*toc*") | |
2470 (kill-buffer "*toc*")) | |
2471 | |
2472 (setq reftex-last-toc-file (buffer-file-name)) | |
2473 (setq reftex-last-toc-master (reftex-TeX-master-file)) | |
2474 | |
2475 (set-marker reftex-toc-return-marker (point)) | |
2476 | |
2477 ;; if follow mode is active, arrange to delay it one command | |
2478 (if reftex-toc-follow-mode | |
2479 (setq reftex-toc-follow-mode 1)) | |
2480 | |
2481 (if (and current-prefix-arg | |
2482 (get-buffer "*toc*")) | |
2483 (kill-buffer "*toc*")) | |
2484 | |
2485 ;; Ensure access to scanning info and rescan buffer if prefix are is '(4) | |
2486 (reftex-access-scan-info current-prefix-arg) | |
2487 | |
2488 (let* ((all (symbol-value reftex-list-of-labels-symbol)) | |
2489 (where (reftex-nearest-section)) | |
2490 toc toc1 cell label file find startpos) | |
2491 | |
2492 (if (and (get-buffer "*toc*") | |
2493 (get-buffer-window (get-buffer "*toc*"))) | |
2494 (select-window (get-buffer-window (get-buffer "*toc*"))) | |
2495 (delete-other-windows) | |
2496 (switch-to-buffer-other-window (current-buffer)) | |
2497 (switch-to-buffer-other-window (get-buffer-create "*toc*"))) | |
2498 | |
2499 (cond | |
2500 ;; buffer is empty - fill it with the table of contents | |
2501 ((= (buffer-size) 0) | |
2502 | |
2503 (local-set-key " " 'reftex-toc-view-line) | |
2504 (local-set-key "\C-m" 'reftex-toc-goto-line-and-hide) | |
2505 (local-set-key "r" 'reftex-toc-redo) | |
2506 (local-set-key "q" 'reftex-toc-quit) | |
2507 (local-set-key "Q" 'reftex-toc-quit-and-kill) | |
2508 (local-set-key "f" 'reftex-toc-toggle-follow) | |
2509 (setq truncate-lines t) | |
2510 (make-local-hook 'post-command-hook) | |
2511 (make-local-hook 'pre-command-hook) | |
2512 (setq post-command-hook '(reftex-toc-post-command-hook)) | |
2513 (setq pre-command-hook '(reftex-toc-pre-command-hook)) | |
2514 | |
2515 (insert (format | |
2516 "TABLE-OF-CONTENTS on %s | |
2517 MENU: SPC=view RET=goto [q]uit [Q]uit+kill [r]escan [f]ollow-mode on/off | |
2518 ------------------------------------------------------------------------------- | |
2519 " (abbreviate-file-name reftex-last-toc-master))) | |
2520 (setq startpos (point)) | |
2521 | |
2522 (if (reftex-use-fonts) | |
2523 (put-text-property 1 (point) 'face 'font-lock-keyword-face)) | |
2524 (put-text-property 1 (point) 'intangible t) | |
2525 | |
2526 (while all | |
2527 (setq cell (car all) | |
2528 all (cdr all)) | |
2529 (setq label (nth 0 cell) | |
2530 toc (nth 2 cell) | |
2531 file (nth 3 cell) | |
2532 find (nth 4 cell)) | |
2533 (if (not label) | |
2534 (progn | |
2535 (setq toc1 (concat toc "\n")) | |
2536 (put-text-property 0 (length toc1) | |
2537 'file file toc1) | |
2538 (put-text-property 0 (length toc1) | |
2539 'find find toc1) | |
2540 (insert toc1) | |
2541 ))) | |
2542 | |
2543 (backward-delete-char 1) | |
2544 | |
2545 (setq buffer-read-only t)) | |
2546 (t | |
2547 (goto-line 3) | |
2548 (beginning-of-line) | |
2549 (setq startpos (point)))) | |
2550 | |
2551 ;; Find the correct section | |
2552 (goto-char (point-max)) | |
2553 (beginning-of-line) | |
2554 (while (and (> (point) startpos) | |
2555 (or (not (string= (get-text-property (point) 'file) | |
2556 (car where))) | |
2557 (not (string= (get-text-property (point) 'find) | |
2558 (cdr where))))) | |
2559 (beginning-of-line 0)))) | |
2560 | |
2561 (defun reftex-nearest-section () | |
2562 ;; Return (file . find) of nearest section command | |
2563 (let (cell label rest) | |
2564 (save-excursion | |
2565 (cond | |
2566 ;; Try to find a section heading | |
2567 ((or (re-search-backward reftex-section-regexp nil t) | |
2568 (re-search-forward reftex-section-regexp nil t)) | |
2569 (goto-char (match-end 0)) | |
2570 (cons (buffer-file-name) | |
2571 (reftex-allow-for-ctrl-m | |
2572 (concat (buffer-substring-no-properties | |
2573 (1- (match-beginning 1)) (match-end 0)) | |
2574 (reftex-context-substring))))) | |
2575 ;; Try to find a label | |
2576 ((and (or (re-search-backward "\\\\label{\\([^}]+\\)}" nil t) | |
2577 (re-search-forward "\\\\label{\\([^}]+\\)}" nil t)) | |
2578 (setq label (reftex-no-props (match-string 1))) | |
2579 (setq cell (assoc label (symbol-value | |
2580 reftex-list-of-labels-symbol))) | |
2581 (setq rest (memq cell (symbol-value reftex-list-of-labels-symbol))) | |
2582 (setq cell (car (memq (assoc nil rest) rest))) | |
2583 (null (car cell))) | |
2584 (cons (nth 3 cell) (nth 4 cell))) | |
2585 (t nil))))) | |
2586 | |
2587 (defun reftex-toc-pre-command-hook () | |
2588 ;; used as pre command hook in *toc* buffer | |
2589 (reftex-unhighlight 0) | |
2590 (reftex-unhighlight 1)) | |
2591 | |
2592 (defun reftex-toc-post-command-hook () | |
2593 ;; used in the post-command-hook for the *toc* buffer | |
2594 (and (> (point) 1) | |
2595 (save-excursion | |
2596 (reftex-highlight 1 | |
2597 (progn (beginning-of-line) (point)) | |
2598 (progn (end-of-line) (point))))) | |
2599 (cond | |
2600 ((integerp reftex-toc-follow-mode) | |
2601 ;; remove delayed action | |
2602 (setq reftex-toc-follow-mode t)) | |
2603 (reftex-toc-follow-mode | |
2604 ;; show context in other window | |
2605 (condition-case nil | |
2606 (reftex-toc-visit-line) | |
2607 ('error t))))) | |
2608 | |
2609 (defun reftex-toc-toggle-follow () | |
2610 "Toggle toc-follow mode. | |
2611 (it is not really a mode, just a flag)." | |
2612 (interactive) | |
2613 (setq reftex-toc-follow-mode (not reftex-toc-follow-mode))) | |
2614 (defun reftex-toc-view-line () | |
2615 "View document location in other window." | |
2616 (interactive) | |
2617 (reftex-toc-visit-line)) | |
2618 (defun reftex-toc-goto-line-and-hide () | |
2619 "Go to document location in other window. Hide the *toc* window." | |
2620 (interactive) | |
2621 (reftex-toc-visit-line 'hide)) | |
2622 (defun reftex-toc-quit () | |
2623 "Hide the *toc* window and do not move point." | |
2624 (interactive) | |
2625 (delete-window) | |
2626 (switch-to-buffer (marker-buffer reftex-toc-return-marker)) | |
2627 (goto-char (marker-position reftex-toc-return-marker))) | |
2628 (defun reftex-toc-quit-and-kill () | |
2629 "Kill the *toc* buffer." | |
2630 (interactive) | |
2631 (kill-buffer "*toc*") | |
2632 (delete-window) | |
2633 (switch-to-buffer (marker-buffer reftex-toc-return-marker)) | |
2634 (goto-char (marker-position reftex-toc-return-marker))) | |
2635 (defun reftex-toc-redo () | |
2636 "Regenerate the *toc* buffer. Call only from within the *toc* buffer" | |
2637 (interactive) | |
2638 (switch-to-buffer (reftex-get-file-buffer-force reftex-last-toc-file)) | |
2639 (delete-other-windows) | |
2640 (setq current-prefix-arg '(4)) | |
2641 (reftex-toc)) | |
2642 | |
2643 (defun reftex-toc-visit-line (&optional final) | |
2644 ;; Visit the tex file corresponding to the toc entry on the current line. | |
2645 ;; If FINAL is t, stay there | |
2646 ;; If FINAL is 'hide, hide the *toc* window. | |
2647 ;; Otherwise, move cursor back into *toc* window | |
2648 | |
2649 (let (file find beg end (toc-window (selected-window)) show-window) | |
2650 (save-excursion | |
2651 (beginning-of-line) | |
2652 (setq beg (point)) | |
2653 (end-of-line) | |
2654 (setq end (point))) | |
2655 | |
2656 ;; get the file and the search string | |
2657 (setq file (get-text-property (point) 'file)) | |
2658 (setq find (get-text-property (point) 'find)) | |
2659 (if (or (not file) (not find)) | |
2660 (error "Cannot visit line")) | |
2661 | |
2662 (switch-to-buffer-other-window (reftex-get-file-buffer-force file)) | |
2663 (setq show-window (selected-window)) | |
2664 (goto-char (point-min)) | |
2665 | |
2666 (if (not (re-search-forward find nil t)) | |
2667 (error "Cannot visit line")) | |
2668 | |
2669 (setq beg (match-beginning 0) | |
2670 end (match-end 0)) | |
2671 | |
2672 (goto-char beg) | |
2673 (recenter 1) | |
2674 (reftex-highlight 0 beg end (current-buffer)) | |
2675 | |
2676 (select-window toc-window) | |
2677 | |
2678 ;; use the `final' parameter to decide what to do next | |
2679 (cond | |
2680 ((equal final t) | |
2681 (reftex-unhighlight 0) | |
2682 (select-window show-window)) | |
2683 ((eq final 'hide) | |
2684 (reftex-unhighlight 0) | |
2685 (delete-window)) | |
2686 (t nil)))) | |
2687 | |
2688 ;;; =========================================================================== | |
2689 ;;; | |
2690 ;;; BibTeX citations. | |
2691 | |
2692 ;; Variables and constants | |
2693 | |
2694 ;; Internal variable, but used from different functions | |
2695 (defvar reftex-cite-format1 nil) | |
2696 | |
2697 ;; The history list of regular expressions used for citations | |
2698 (defvar reftex-cite-regexp-hist nil) | |
2699 | |
2700 ;; Help string for citation selection | |
2701 (defconst reftex-citation-help | |
2702 "AVAILABLE KEYS IN MAKE CITATION MENU | |
2703 --------------------------------------- | |
2704 n / p Go to next/previous entry (Cursor motion works as well) | |
2705 r restrict selection with another regexp | |
2706 SPACE Show full database entry in other window | |
2707 f Toggle follow mode: Other window will follow with full db entry | |
2708 q Quit without inserting \\cite macro into buffer | |
2709 ? Display this help message | |
2710 C-r Recursive edit into other window | |
2711 RETURN ... Accept current entry and insert in format according to | |
2712 reftex-cite-format") | |
2713 | |
2714 (defconst reftex-cite-format-default "\\cite{KEY}" | |
2715 "The default value for reftex-cite-format. | |
2716 Uses the string version of scitex-cite-format.") | |
2717 | |
2718 (defconst reftex-cite-format-1-author-simple | |
2719 '( "\\cite{KEY}" "AUTHOR \\cite{KEY}" "AUTHOR {\it et al.} \\cite{KEY}") | |
2720 "Value for reftex-cite format establishing a simple citation with name | |
2721 of the first author. | |
2722 Uses the list version of reftex-cite-format.") | |
2723 | |
2724 (defconst reftex-cite-format-2-authors | |
2725 '((?\C-m | |
2726 . ( "\\cite{KEY}" "AUTHOR \\cite{KEY}" | |
2727 "AUTHOR \\& AUTHOR \\cite{KEY}" "AUTHOR \\etal{} \\cite{KEY}")) | |
2728 (?\, | |
2729 . ("\\cite{KEY}" "AUTHOR, \\cite{KEY}" | |
2730 "AUTHOR \\& AUTHOR, \\cite{KEY}" "AUTHOR \\etal{}, \\cite{KEY}")) | |
2731 (?\; | |
2732 . ("\\cite{KEY}" "AUTHOR; \\cite{KEY}" | |
2733 "AUTHOR \\& AUTHOR; \\cite{KEY}" "AUTHOR \\etal{}; \\cite{KEY}")) | |
2734 (?\: | |
2735 . ("\\cite{KEY}" "AUTHOR: \\cite{KEY}" | |
2736 "AUTHOR \\& AUTHOR: \\cite{KEY}" "AUTHOR \\etal{}: \\cite{KEY}")) | |
2737 (?\( | |
2738 . ("(\\cite{KEY})" "AUTHOR (\\cite{KEY})" | |
2739 "AUTHOR \\& AUTHOR (\\cite{KEY})" "AUTHOR \\etal{} (\\cite{KEY})")) | |
2740 (?\[ | |
2741 . ("[\\cite{KEY}]" "AUTHOR [\\cite{KEY}]" | |
2742 "AUTHOR \\& AUTHOR [\\cite{KEY}]" "AUTHOR \\etal{} [\\cite{KEY}]"))) | |
2743 "Value for reftex-cite-format that estabishes an Author/Year citation | |
2744 where the year is supplied from BibTeX. Depending on which character | |
2745 is used during selection to accept the label, an extra ,;: or pair of | |
2746 parenthesis will be inserted. | |
2747 Uses the list-of-cons-cells version of reftex-cite-format.") | |
2748 | |
2749 ;; Find bibtex files | |
2750 | |
2751 (defun reftex-get-bibfile-list () | |
2752 ;; Return list of bibfiles for current document | |
2753 | |
2754 ;; Ensure access to scanning info | |
2755 (reftex-access-scan-info) | |
2756 | |
2757 (or (symbol-value reftex-bibfile-list-symbol) | |
2758 (error "No BibTeX files to parse. Add \\bibliography statment to document and reparse."))) | |
2759 | |
2760 (defun reftex-scan-buffer-for-bibliography-statement (bib-list-symbol) | |
2761 ;; Scan buffer for bibliography macro and store file list in bib-list-symbol. | |
2762 (let (file-list dir-list) | |
2763 (setq dir-list | |
2764 (reftex-split | |
2765 (concat path-separator "+") | |
2766 (mapconcat '(lambda(x) | |
2767 (if (getenv x) (getenv x) "")) | |
2768 reftex-bibpath-environment-variables | |
2769 path-separator))) | |
2770 (goto-char (point-min)) | |
2771 (if (re-search-forward "^[ \t]*\\\\bibliography{[ \t]*\\([^}]+\\)" nil t) | |
2772 (progn | |
2773 (setq dir-list | |
2774 (cons (file-name-directory | |
2775 (get-text-property (match-beginning 0) 'file)) | |
2776 dir-list)) | |
2777 (setq file-list | |
2778 (mapcar '(lambda (x) (concat x ".bib")) | |
2779 (reftex-delete-list | |
2780 reftex-bibfile-ignore-list | |
2781 (reftex-split | |
2782 "[ \t\n]*,[ \t\n]*" | |
2783 (reftex-no-props (match-string 1))))))) | |
2784 (message "No \\bibliography command in document.")) | |
2785 (set bib-list-symbol | |
2786 (if file-list | |
2787 (reftex-find-files-on-path file-list dir-list | |
2788 "While parsing \\bibliography{}:") | |
2789 nil)))) | |
2790 | |
2791 (defun reftex-find-files-on-path (file-list path-list &optional error-string) | |
2792 ;; Search for all files in FILE-LIST on the PATH-LIST. Return absolute names. | |
2793 ;; A missing file throws an exception with the error message ERROR-STRING. | |
2794 (let (found-list found file) | |
2795 (while file-list | |
2796 (setq file (car file-list) | |
2797 file-list (cdr file-list) | |
2798 found nil) | |
2799 (if (file-name-absolute-p file) | |
2800 (setq found (expand-file-name file)) | |
2801 (let ((dirs path-list)) | |
2802 (while (and dirs (not found)) | |
2803 (if (and (not (string= (car dirs) "")) | |
2804 (file-exists-p (expand-file-name file (car dirs)))) | |
2805 (setq found (expand-file-name file (car dirs)))) | |
2806 (setq dirs (cdr dirs))))) | |
2807 (if (and found | |
2808 (file-exists-p found)) | |
2809 (add-to-list 'found-list (expand-file-name found)) | |
2810 (error "%s No such file %s." | |
2811 (or error-string "") file))) | |
2812 (nreverse found-list))) | |
2813 | |
2814 ;; Find a certain reference in any of the BibTeX files. | |
2815 | |
2816 (defun reftex-pop-to-bibtex-entry (key file-list | |
2817 &optional mark-to-kill highlight) | |
2818 ;; Find BibTeX KEY in any file in FILE-LIST in another window. | |
2819 ;; If mark-to-kill is non-nil, mark new buffer to kill." | |
2820 | |
2821 (let* ((re (concat "@[a-zA-Z]+[ \t\n\r]*{[ \t\n\r]*" (regexp-quote key) "[ \t\n\r,]")) | |
2822 (window-conf (current-window-configuration)) | |
2823 file buf) | |
2824 (catch 'exit | |
2825 (switch-to-buffer-other-window (current-buffer)) | |
2826 (while file-list | |
2827 (setq file (car file-list) | |
2828 file-list (cdr file-list)) | |
2829 (if (not (setq buf (reftex-get-file-buffer-force file mark-to-kill))) | |
2830 (error "No such file %s" file)) | |
2831 (switch-to-buffer buf) | |
2832 (widen) | |
2833 (goto-char 0) | |
2834 (if (re-search-forward re nil t) | |
2835 (progn | |
2836 (goto-char (match-beginning 0)) | |
2837 (recenter 0) | |
2838 (if highlight | |
2839 (reftex-highlight 0 (match-beginning 0) (match-end 0))) | |
2840 (throw 'exit (selected-window))))) | |
2841 (set-window-configuration window-conf) | |
2842 (beep) | |
2843 (message "No BibTeX entry with citation key %s" key)))) | |
2844 | |
2845 ;; Parse bibtex buffers | |
2846 | |
2847 (defun reftex-extract-bib-entries (buffers &optional get-word) | |
2848 ;; Extract bib entries which match regexps from BUFFERS. | |
2849 ;; BUFFERS is a list of buffers or file names. | |
2850 ;; Return list with entries." | |
2851 (let* (re-list first-re rest-re | |
2852 ;; avoid fontification of lookup buffers | |
2853 (lazy-lock-minimum-size 1) | |
2854 (buffer-list (if (listp buffers) buffers (list buffers))) | |
2855 found-list entry buffer1 buffer alist | |
2856 key-point start-point end-point) | |
2857 | |
2858 (setq re-list (reftex-split "[ \t]*&&[ \t]*" | |
2859 (read-string "RegExp [ && RegExp...]: " | |
2860 nil 'reftex-cite-regexp-hist))) | |
2861 | |
2862 (setq first-re (car re-list) ; We'll use the first re to find things, | |
2863 rest-re (cdr re-list)) ; the other to narrow down. | |
2864 (if (string-match "\\`[ \t]*\\'" first-re) | |
2865 (error "Empty regular expression")) | |
2866 | |
2867 (save-excursion | |
2868 (save-window-excursion | |
2869 | |
2870 ;; walk through all bibtex files | |
2871 (while buffer-list | |
2872 (setq buffer (car buffer-list) | |
2873 buffer-list (cdr buffer-list)) | |
2874 (if (and (bufferp buffer) | |
2875 (buffer-live-p buffer)) | |
2876 (setq buffer1 buffer) | |
2877 (setq buffer1 (reftex-get-file-buffer-force | |
2878 buffer (not reftex-keep-temporary-buffers)))) | |
2879 (if (not buffer1) | |
2880 (error "Cannot find BibTeX file %s" buffer) | |
2881 (message "Scanning bibliography database %s" buffer1)) | |
2882 | |
2883 (set-buffer buffer1) | |
2884 (save-excursion | |
2885 (goto-char (point-min)) | |
2886 (while (re-search-forward first-re nil t) | |
2887 (catch 'search-again | |
2888 (setq key-point (point)) | |
2889 (if (not (re-search-backward | |
2890 "^[ \t]*@\\([a-zA-Z]+\\)[ \t\n\r]*{" nil t)) | |
2891 (throw 'search-again nil)) | |
2892 (setq start-point (point)) | |
2893 (goto-char (match-end 0)) | |
2894 (condition-case nil | |
2895 (up-list 1) | |
2896 ('error (goto-char key-point) | |
2897 (throw 'search-again nil))) | |
2898 (setq end-point (point)) | |
2899 | |
2900 ;; Ignore @string, @comment and @c entries or things | |
2901 ;; outside entries | |
2902 (if (or (string= (downcase (match-string 1)) "string") | |
2903 (string= (downcase (match-string 1)) "comment") | |
2904 (string= (downcase (match-string 1)) "c") | |
2905 (< (point) key-point)) ; this means match not in {} | |
2906 (progn | |
2907 (goto-char key-point) | |
2908 (throw 'search-again nil))) | |
2909 | |
2910 ;; Well, we have got a match | |
2911 (setq entry (concat | |
2912 (buffer-substring start-point (point)) "\n")) | |
2913 | |
2914 ;; Check if other regexp match as well | |
2915 (setq re-list rest-re) | |
2916 (while re-list | |
2917 (if (not (string-match (car re-list) entry)) | |
2918 ;; nope - move on | |
2919 (throw 'search-again nil)) | |
2920 (setq re-list (cdr re-list))) | |
2921 | |
2922 (setq alist (reftex-parse-bibtex-entry | |
2923 nil start-point end-point)) | |
2924 (setq alist (cons (cons "&entry" entry) alist)) | |
2925 | |
2926 ;; check for crossref entries | |
2927 (if (assoc "crossref" alist) | |
2928 (setq alist | |
2929 (append | |
2930 alist (reftex-get-crossref-alist alist)))) | |
2931 | |
2932 ;; format the entry | |
2933 (setq alist | |
2934 (cons | |
2935 (cons "&formatted" | |
2936 (reftex-format-bib-entry alist)) | |
2937 alist)) | |
2938 | |
2939 ;; add it to the list | |
2940 (setq found-list (cons alist found-list))))) | |
2941 (reftex-kill-temporary-buffers)))) | |
2942 (setq found-list (nreverse found-list)) | |
2943 | |
2944 ;; Sorting | |
2945 (cond | |
2946 ((eq 'author reftex-sort-bibtex-matches) | |
2947 (sort found-list 'reftex-bib-sort-author)) | |
2948 ((eq 'year reftex-sort-bibtex-matches) | |
2949 (sort found-list 'reftex-bib-sort-year)) | |
2950 ((eq 'reverse-year reftex-sort-bibtex-matches) | |
2951 (sort found-list 'reftex-bib-sort-year-reverse)) | |
2952 (t found-list)))) | |
2953 | |
2954 (defun reftex-bib-sort-author (e1 e2) | |
2955 (let ((al1 (reftex-get-bib-authors e1)) (al2 (reftex-get-bib-authors e2))) | |
2956 (while (and al1 al2 (string= (car al1) (car al2))) | |
2957 (setq al1 (cdr al1) | |
2958 al2 (cdr al2))) | |
2959 (if (and (stringp (car al1)) | |
2960 (stringp (car al2))) | |
2961 (string< (car al1) (car al2)) | |
2962 (not (stringp (car al1)))))) | |
2963 | |
2964 (defun reftex-bib-sort-year (e1 e2) | |
2965 (< (string-to-int (cdr (assoc "year" e1))) | |
2966 (string-to-int (cdr (assoc "year" e2))))) | |
2967 | |
2968 (defun reftex-bib-sort-year-reverse (e1 e2) | |
2969 (> (string-to-int (or (cdr (assoc "year" e1)) "0")) | |
2970 (string-to-int (or (cdr (assoc "year" e2)) "0")))) | |
2971 | |
2972 (defun reftex-get-crossref-alist (entry) | |
2973 ;; return the alist from a crossref entry | |
2974 (let ((crkey (cdr (assoc "crossref" entry))) | |
2975 start) | |
2976 (save-excursion | |
2977 (save-restriction | |
2978 (widen) | |
2979 (if (re-search-forward | |
2980 (concat "@\\w+{[ \t\n\r]*" (regexp-quote crkey) "[ \t\n\r]*,") nil t) | |
2981 (progn | |
2982 (setq start (match-beginning 0)) | |
2983 (condition-case nil | |
2984 (up-list 1) | |
2985 ('error nil)) | |
2986 (reftex-parse-bibtex-entry nil start (point))) | |
2987 nil))))) | |
2988 | |
2989 ;; Parse and format individual entries | |
2990 | |
2991 (defun reftex-get-bib-authors (entry) | |
2992 ;; Return a list with the author names in ENTRY | |
2993 (let (authors) | |
2994 (setq authors (reftex-get-bib-field "author" entry)) | |
2995 (if (equal "" authors) | |
2996 (setq authors (reftex-get-bib-field "editor" entry))) | |
2997 (while (string-match "\\band\\b[ \t]*" authors) | |
2998 (setq authors (replace-match "\n" nil t authors))) | |
2999 (while (string-match "[\\.a-zA-Z\\-]+\\.[ \t]*\\|,.*\\|[{}]+" authors) | |
3000 (setq authors (replace-match "" nil t authors))) | |
3001 (while (string-match "^[ \t]+\\|[ \t]+$" authors) | |
3002 (setq authors (replace-match "" nil t authors))) | |
3003 (while (string-match "[ \t][ \t]+" authors) | |
3004 (setq authors (replace-match " " nil t authors))) | |
3005 (reftex-split "\n" authors))) | |
3006 | |
3007 (defun reftex-parse-bibtex-entry (entry &optional from to) | |
3008 (let (alist key start field) | |
3009 (save-excursion | |
3010 (save-restriction | |
3011 (if entry | |
3012 (progn | |
3013 (switch-to-buffer "*RefTeX-scratch*") | |
3014 (fundamental-mode) | |
3015 (erase-buffer) | |
3016 (insert entry)) | |
3017 (widen) | |
3018 (narrow-to-region from to)) | |
3019 (goto-char (point-min)) | |
3020 | |
3021 (if (re-search-forward | |
3022 "@\\(\\w+\\)[ \t\n\r]*{[ \t\n\r]*\\([^ \t\n\r,]+\\)" nil t) | |
3023 (setq alist | |
3024 (list | |
3025 (cons "&type" (downcase (reftex-no-props (match-string 1)))) | |
3026 (cons "&key" (reftex-no-props (match-string 2)))))) | |
3027 (while (re-search-forward "\\(\\w+\\)[ \t\n\r]*=[ \t\n\r]*" nil t) | |
3028 (setq key (reftex-no-props (downcase (match-string 1)))) | |
3029 (cond | |
3030 ((= (following-char) ?{) | |
3031 (forward-char 1) | |
3032 (setq start (point)) | |
3033 (condition-case nil | |
3034 (up-list 1) | |
3035 ('error nil))) | |
3036 ((= (following-char) ?\") | |
3037 (forward-char 1) | |
3038 (setq start (point)) | |
3039 (while (and (search-forward "\"" nil t) | |
3040 (= ?\\ (char-after (- (point) 2)))))) | |
3041 (t | |
3042 (setq start (point)) | |
3043 (re-search-forward "[ \t\n\r,}]" nil 1))) | |
3044 (setq field (buffer-substring-no-properties start (1- (point)))) | |
3045 ;; remove extra whitesp | |
3046 (while (string-match "[\n\t\r]\\|[ \t][ \t]+" field) | |
3047 (setq field (replace-match " " nil t field))) | |
3048 ;; remove leading garbage | |
3049 (if (string-match "^[ \t{]+" field) | |
3050 (setq field (replace-match "" nil t field))) | |
3051 ;; remove trailing garbage | |
3052 (if (string-match "[ \t}]+$" field) | |
3053 (setq field (replace-match "" nil t field))) | |
3054 (setq alist (cons (cons key field) alist))) | |
3055 alist)))) | |
3056 | |
3057 (defun reftex-get-bib-field (fieldname entry) | |
3058 ;; Extract the field FIELDNAME from an ENTRY | |
3059 (or (cdr (assoc fieldname entry)) | |
3060 "")) | |
3061 | |
3062 (defun reftex-format-bib-entry (entry) | |
3063 ;; Format a BibTeX ENTRY so that it is nice to look at | |
3064 (let* | |
3065 ((rtn nil) | |
3066 (auth-list (reftex-get-bib-authors entry)) | |
3067 (authors (mapconcat '(lambda (x) x) auth-list ", ")) | |
3068 (year (reftex-get-bib-field "year" entry)) | |
3069 (title (reftex-get-bib-field "title" entry)) | |
3070 (type (reftex-get-bib-field "&type" entry)) | |
3071 (key (reftex-get-bib-field "&key" entry)) | |
3072 (extra | |
3073 (cond | |
3074 ((equal type "article") | |
3075 (concat (reftex-get-bib-field "journal" entry) " " | |
3076 (reftex-get-bib-field "volume" entry) ", " | |
3077 (reftex-get-bib-field "pages" entry))) | |
3078 ((equal type "book") | |
3079 (concat "book (" (reftex-get-bib-field "publisher" entry) ")")) | |
3080 ((equal type "phdthesis") | |
3081 (concat "PhD: " (reftex-get-bib-field "school" entry))) | |
3082 ((equal type "mastersthesis") | |
3083 (concat "Master: " (reftex-get-bib-field "school" entry))) | |
3084 ((equal type "inbook") | |
3085 (concat "Chap: " (reftex-get-bib-field "chapter" entry) | |
3086 ", pp. " (reftex-get-bib-field "pages" entry))) | |
3087 ((or (equal type "conference") | |
3088 (equal type "incollection") | |
3089 (equal type "inproceedings")) | |
3090 (concat "in: " (reftex-get-bib-field "booktitle" entry))) | |
3091 (t "")))) | |
3092 (setq authors | |
3093 (if (> (length authors) 30) | |
3094 (concat (substring authors 0 27) "...") | |
3095 (format "%-30s" authors)) | |
3096 title | |
3097 (if (> (length title) 70) | |
3098 (concat (substring title 0 67) "...") | |
3099 (format "%-70s" title)) | |
3100 extra | |
3101 (if (> (length extra) 40) | |
3102 (concat (substring extra 0 37) "...") | |
3103 (format "%-40s" extra))) | |
3104 (if (reftex-use-fonts) | |
3105 (progn | |
3106 (put-text-property 0 (length authors) 'face 'font-lock-keyword-face | |
3107 authors) | |
3108 (put-text-property 0 (length title) 'face 'font-lock-comment-face | |
3109 title) | |
3110 (put-text-property 0 (length extra) 'face 'font-lock-reference-face | |
3111 extra))) | |
3112 (setq rtn (concat key "\n " authors " " year " " extra | |
3113 "\n " title "\n\n")) | |
3114 rtn)) | |
3115 | |
3116 ;; Make a citation | |
3117 | |
3118 (defun reftex-citation (&optional arg no-insert) | |
3119 "Make a citation unsing BibTeX database files. | |
3120 After asking for a Regular Expression, it scans the buffers with | |
3121 bibtex entries (taken from the \\bibliography command) and offers the | |
3122 matching entries for selection. The selected entry is formated according | |
3123 to reftex-cite-format and inserted into the buffer. | |
3124 If NO-INSERT is non-nil, nothing is inserted, only the selected key returned. | |
3125 The regular expression uses an expanded syntax: && is interpreted as 'and'. | |
3126 Thus, aaaa&&bbb matches entries which contain both aaaa and bbb. | |
3127 When this function is called with point inside the braces of a \\cite{} | |
3128 command, it will add another key, ignoring the value of reftex-cite-format. | |
3129 When called with a numeric prefix, that many citations will be made and all | |
3130 put into the same \\cite{} command. | |
3131 When called with just C-u as prefix, enforces rescan of buffer for | |
3132 bibliography statement (e.g. if it was changed)." | |
3133 | |
3134 (interactive "P") | |
3135 | |
3136 ;; check for recursive edit | |
3137 (reftex-check-recursive-edit) | |
3138 | |
3139 ;; if there is just 1 C-u prefix arg, force to rescan buffer | |
3140 (if (and current-prefix-arg | |
3141 (listp current-prefix-arg) | |
3142 (= 4 (prefix-numeric-value arg))) | |
3143 (reftex-reset-scanning-information)) | |
3144 | |
3145 ;; check if there is already a cite command at point and change cite format | |
3146 ;; in order to only add another reference in the same cite command. | |
3147 (let ((pos (point))) | |
3148 (search-backward "\\" (point-min) 1) | |
3149 (if (and (looking-at "\\\\[a-zA-Z]*cite\\*?\\(\\[[^]]*\\]\\)*{\\([^}]*\\)") | |
3150 (>= (match-end 0) pos) | |
3151 (>= pos (match-beginning 2))) | |
3152 (progn | |
3153 (goto-char pos) | |
3154 (cond | |
3155 ((or (not arg) | |
3156 (not (listp arg))) | |
3157 (setq reftex-cite-format1 | |
3158 (concat | |
3159 (if (not (or (= (preceding-char) ?{) | |
3160 (= (preceding-char) ?,))) | |
3161 "," | |
3162 "") | |
3163 "KEY" | |
3164 (if (not (or (= (following-char) ?}) | |
3165 (= (following-char) ?,))) | |
3166 "," | |
3167 "")))) | |
3168 (t | |
3169 (setq reftex-cite-format1 "KEY")))) | |
3170 (setq reftex-cite-format1 | |
3171 (if (symbolp reftex-cite-format) | |
3172 (symbol-value reftex-cite-format) | |
3173 reftex-cite-format)) | |
3174 (goto-char pos))) | |
3175 | |
3176 (let* (key entry cnt rtn ins-string re-list re | |
3177 ;; scan bibtex files | |
3178 (lazy-lock-minimum-size 1) | |
3179 (found-list (reftex-extract-bib-entries | |
3180 (reftex-get-bibfile-list))) | |
3181 (found-list-r nil) | |
3182 (accept-keys | |
3183 (if (and (listp reftex-cite-format1) | |
3184 (listp (car reftex-cite-format1))) | |
3185 (mapcar 'car reftex-cite-format1) | |
3186 '(?\C-m)))) | |
3187 (if (not found-list) | |
3188 (error "Sorry, no matches found")) | |
3189 | |
3190 ;; remember where we came from | |
3191 (setq reftex-call-back-to-this-buffer (current-buffer)) | |
3192 | |
3193 ;; offer selection | |
3194 (save-window-excursion | |
3195 (switch-to-buffer-other-window "*RefTeX Select*") | |
3196 (erase-buffer) | |
3197 (mapcar '(lambda (x) (insert (cdr (assoc "&formatted" x)))) | |
3198 found-list) | |
3199 (if (= 0 (buffer-size)) | |
3200 (error "Sorry, no matches found")) | |
3201 (setq truncate-lines t) | |
3202 (goto-char 1) | |
3203 (if (catch 'exit | |
3204 (while t | |
3205 (setq rtn | |
3206 (reftex-select-item | |
3207 nil | |
3208 (concat | |
3209 "Select: [n]ext [p]rev [r]estrict [q]uit [?]Help ||" | |
3210 " RETURN " | |
3211 (condition-case nil | |
3212 (mapconcat 'char-to-string accept-keys " ") | |
3213 (error (error "Illegal reftex-cite-format")))) | |
3214 "^[^ \t\n]" | |
3215 "\n\n" | |
3216 4 | |
3217 reftex-citation-help | |
3218 (cons ?r accept-keys) | |
3219 nil | |
3220 'reftex-bibtex-selection-callback nil)) | |
3221 (setq key (car rtn) | |
3222 cnt (cdr rtn)) | |
3223 (if (not key) (throw 'exit nil)) | |
3224 (cond | |
3225 ((equal key ?r) | |
3226 ;; restrict with new regular expression | |
3227 (setq re-list | |
3228 (reftex-split "[ \t]*&&[ \t]*" | |
3229 (read-string "RegExp [ && RegExp...]: " | |
3230 nil 'reftex-cite-regexp-hist))) | |
3231 (while re-list | |
3232 (setq re (car re-list) | |
3233 re-list (cdr re-list)) | |
3234 (setq found-list-r | |
3235 (delete "" | |
3236 (mapcar | |
3237 '(lambda (x) | |
3238 (if (string-match re | |
3239 (cdr (assoc "&entry" x))) | |
3240 x | |
3241 "")) | |
3242 found-list)))) | |
3243 (if found-list-r | |
3244 (setq found-list found-list-r) | |
3245 (ding)) | |
3246 (erase-buffer) | |
3247 (mapcar '(lambda (x) (insert (cdr (assoc "&formatted" x)))) | |
3248 found-list) | |
3249 (goto-char 1)) | |
3250 ((or (member key accept-keys) | |
3251 (equal key ?\C-m) | |
3252 (equal key 'return)) | |
3253 (setq entry (nth cnt found-list)) | |
3254 (throw 'exit t)) | |
3255 (t | |
3256 (ding))))) | |
3257 (progn | |
3258 ;; format the entry | |
3259 (if (not (integerp key)) (setq key ?\C-m)) | |
3260 (setq ins-string (reftex-format-citation entry key))) | |
3261 (setq ins-string "") | |
3262 (message "Quit"))) | |
3263 (kill-buffer "*RefTeX Select*") | |
3264 | |
3265 (if (not no-insert) | |
3266 (insert ins-string)) | |
3267 (message "") | |
3268 | |
3269 ;; Check if the prefix arg was numeric, and call reftex-citation recursively | |
3270 (if (and (integerp arg) | |
3271 (> arg 1) | |
3272 (re-search-backward | |
3273 "\\\\[a-zA-Z]*cite\\*?\\(\\[[^]]*\\]\\)*{\\([^}]*\\)" nil t)) | |
3274 (progn | |
3275 (goto-char (match-end 0)) | |
3276 (setq arg (1- arg)) | |
3277 (reftex-citation arg)) | |
3278 (reftex-kill-temporary-buffers)) | |
3279 ;; Return the citation key | |
3280 (reftex-get-bib-field "&key" entry))) | |
3281 | |
3282 (defun reftex-format-citation (entry key) | |
3283 ;; Format a citation from the info in the BibTeX ENTRY | |
3284 (let* ((cite-key (reftex-get-bib-field "&key" entry)) | |
3285 (year (reftex-get-bib-field "year" entry)) | |
3286 (auth-list (reftex-get-bib-authors entry)) | |
3287 (nauthors (length auth-list)) | |
3288 format) | |
3289 | |
3290 (save-excursion | |
3291 ;; Find the correct format | |
3292 (if (and (listp reftex-cite-format1) | |
3293 (listp (car reftex-cite-format1))) | |
3294 (if (integerp (car (car reftex-cite-format1))) | |
3295 (if (assoc key reftex-cite-format1) | |
3296 (setq format (cdr (assoc key reftex-cite-format1))) | |
3297 (if (or (equal key ?\C-m) | |
3298 (equal key 'return)) | |
3299 (setq format (cdr (car reftex-cite-format1))) | |
3300 (error "Error in reftex-cite-format"))) | |
3301 (error "Error in reftex-cite-format")) | |
3302 (setq format reftex-cite-format1)) | |
3303 | |
3304 (if (listp format) | |
3305 (let ((nn (min nauthors (1- (length format))))) | |
3306 (while (and (> nn 0) (string= "" (nth nn format))) | |
3307 (setq nn (1- nn))) | |
3308 (setq format (nth nn format)))) | |
3309 (if (stringp format) | |
3310 (setq format format) | |
3311 (setq format "\\cite{KEY}")) | |
3312 | |
3313 ;; Insert the author names | |
3314 (while (string-match "\\bAUTHOR\\b" format) | |
3315 (setq format (replace-match (car auth-list) t t format)) | |
3316 (setq auth-list (cdr auth-list))) | |
3317 (while (string-match "\\bKEY\\b" format) | |
3318 (setq format (replace-match cite-key t t format))) | |
3319 (while (string-match "\\bYEAR\\b" format) | |
3320 (setq format (replace-match year t t format))) | |
3321 format))) | |
3322 | |
3323 ;; this is slow and not recommended for follow mode | |
3324 (defun reftex-bibtex-selection-callback (cnt) | |
3325 ;; Callback function to be called from the BibTeX selection, in | |
3326 ;; order to display context. This function is relatively slow and not | |
3327 ;; recommended for follow mode, just for individual lookups. | |
3328 ;; When compiled, this gives a warning about found-list. However, | |
3329 ;; the calling function binds found-list with let. | |
3330 (let ((win (selected-window)) | |
3331 (key (reftex-get-bib-field "&key" (nth cnt found-list))) | |
3332 (bibfile-list (save-excursion | |
3333 (set-buffer reftex-call-back-to-this-buffer) | |
3334 (reftex-get-bibfile-list)))) | |
3335 (reftex-pop-to-bibtex-entry key bibfile-list | |
3336 (not reftex-keep-temporary-buffers) t) | |
3337 (select-window win))) | |
3338 | |
3339 ;;; =========================================================================== | |
3340 ;;; | |
3341 ;;; Here is the routine used for selection | |
3342 | |
3343 ;; Marker for return point from recursive edit | |
3344 (defvar reftex-recursive-edit-marker (make-marker)) | |
3345 | |
3346 (defun reftex-check-recursive-edit () | |
3347 ;; Check if we are already in a recursive edit. Abort with helpful | |
3348 ;; message if so. | |
3349 (if (marker-position reftex-recursive-edit-marker) | |
3350 (error | |
3351 (substitute-command-keys | |
3352 "In unfinished recursive edit. Finish (\\[exit-recursive-edit]) or abort (\\[abort-recursive-edit]).")))) | |
3353 | |
3354 (defun reftex-select-item (buffer prompt next-re end-re size help-string | |
3355 event-list &optional offset | |
3356 call-back cb-flag) | |
3357 ;; Select an item from the buffer BUFFER. Show PROMPT to user, find | |
3358 ;; next item with NEXT-RE regular expression, return on any of the | |
3359 ;; events listed in EVENT-LIST. The function returns the event along | |
3360 ;; with an integer indicating which item was selected. When OFFSET is | |
3361 ;; specified, starts at that item in the list. When CALL-BACK is | |
3362 ;; given, it is a function which is called with the match of the | |
3363 ;; NEXT-RE match and the index of the element. | |
3364 (let* (key key-sq b e ev cnt cmd | |
3365 (offset1 (or offset 1))) | |
3366 (setq ev | |
3367 (catch 'exit | |
3368 (save-window-excursion | |
3369 (if buffer | |
3370 (switch-to-buffer-other-window buffer)) | |
3371 (if (= 0 (buffer-size)) | |
3372 (throw 'exit nil)) | |
3373 (setq truncate-lines t) | |
3374 (goto-char 1) | |
3375 (if (not (re-search-forward next-re nil t offset1)) | |
3376 (progn ; in case the offset is illegal | |
3377 (setq offset1 1) | |
3378 (if (not (re-search-forward next-re nil t offset1)) | |
3379 (throw 'exit nil)))) | |
3380 (beginning-of-line 1) | |
3381 (setq cnt (if offset1 (1- offset1) 0)) | |
3382 (while t | |
3383 (if (and cb-flag call-back) | |
3384 (funcall call-back cnt)) | |
3385 (setq b (point) | |
3386 e (save-excursion | |
3387 (save-match-data | |
3388 (re-search-forward end-re nil 1)) | |
3389 (point))) | |
3390 (reftex-highlight 1 b e) | |
3391 (if (or (not (pos-visible-in-window-p b)) | |
3392 (not (pos-visible-in-window-p e))) | |
3393 (recenter (/ (window-height) 2))) | |
3394 (setq key-sq (read-key-sequence prompt)) | |
3395 (setq key (car | |
3396 (cond | |
3397 ((fboundp 'listify-key-sequence) ; Emacs | |
3398 (listify-key-sequence key-sq)) | |
3399 ((fboundp 'event-to-character) ; XEmacs | |
3400 (mapcar 'event-to-character key-sq)) | |
3401 (t (error "Please report this problem to dominik@strw.leidenuniv.nl"))))) | |
3402 | |
3403 (setq cmd (key-binding key-sq)) | |
3404 | |
3405 (reftex-unhighlight 0) | |
3406 | |
3407 (cond | |
3408 | |
3409 ((or (equal key ?n) | |
3410 (equal key ?\C-i) | |
3411 (equal cmd 'next-line)) | |
3412 (if (re-search-forward next-re nil t 2) | |
3413 (setq cnt (1+ cnt))) | |
3414 (beginning-of-line 1)) | |
3415 | |
3416 ((equal cmd 'scroll-up) | |
3417 (setq cnt (1- cnt)) | |
3418 (while (and (pos-visible-in-window-p) | |
3419 (re-search-forward next-re nil t)) | |
3420 (setq cnt (1+ cnt))) | |
3421 (beginning-of-line 1) | |
3422 (recenter 1)) | |
3423 | |
3424 ((or (equal key ?p) | |
3425 (equal cmd 'previous-line)) | |
3426 (if (re-search-backward next-re nil t) | |
3427 (setq cnt (1- cnt)))) | |
3428 | |
3429 ((equal cmd 'scroll-down) | |
3430 (while (and (pos-visible-in-window-p) | |
3431 (re-search-backward next-re nil t)) | |
3432 (setq cnt (1- cnt))) | |
3433 (recenter (- (window-height) size 2))) | |
3434 | |
3435 ((equal key ?q) | |
3436 (throw 'exit nil)) | |
3437 | |
3438 ((equal key ?\C-g) | |
3439 (bury-buffer) | |
3440 (error "Abort")) | |
3441 | |
3442 ((or (equal key ?\C-m) | |
3443 (equal key 'return) | |
3444 (equal cmd 'newline)) | |
3445 (throw 'exit 'return)) | |
3446 | |
3447 ((or (equal key ?C) ; backward compatibility | |
3448 (equal key ?f)) | |
3449 (setq cb-flag (not cb-flag))) | |
3450 | |
3451 ((equal key ?\ ) | |
3452 (funcall call-back cnt)) | |
3453 | |
3454 ((equal key ?\?) | |
3455 (save-window-excursion | |
3456 (with-output-to-temp-buffer "*RefTeX Help*" | |
3457 (princ help-string)) | |
3458 (setq unread-command-events | |
3459 (cons | |
3460 (cond | |
3461 ((fboundp 'read-event) ; Emacs | |
3462 (read-event)) | |
3463 ((fboundp 'next-command-event) ; XEmacs | |
3464 (next-command-event)) | |
3465 (t (error "Please report this problem to dominik@strw.leidenuniv.nl"))) | |
3466 nil))) | |
3467 (kill-buffer "*RefTeX Help*")) | |
3468 | |
3469 ((equal key ?\C-r) | |
3470 ;; sje - code copied from ispell.el for | |
3471 ;; performing recursive edit | |
3472 (set-marker reftex-recursive-edit-marker (point)) | |
3473 (unwind-protect | |
3474 (progn | |
3475 (save-window-excursion | |
3476 (save-excursion | |
3477 (other-window 1) | |
3478 (message | |
3479 (substitute-command-keys | |
3480 "Recursive edit. Return to selection with \\[exit-recursive-edit]")) | |
3481 (recursive-edit))) | |
3482 (if (not (equal (marker-buffer | |
3483 reftex-recursive-edit-marker) | |
3484 (current-buffer))) | |
3485 (error | |
3486 "Cannot continue RefTeX from this buffer.")) | |
3487 (goto-char reftex-recursive-edit-marker)) | |
3488 (set-marker reftex-recursive-edit-marker nil))) | |
3489 | |
3490 ((member key event-list) | |
3491 (throw 'exit key)) | |
3492 (t | |
3493 (ding))))))) | |
3494 (message "") | |
3495 (cons ev cnt))) | |
3496 | |
3497 ;;; =========================================================================== | |
3498 ;;; | |
3499 ;;; View cross references | |
3500 | |
3501 (defun reftex-view-crossref (&optional arg) | |
3502 "View cross reference of \\ref{} or \\cite{} macro at point. | |
3503 If the macro at point is a \\ref{}, show the corresponding label definition. | |
3504 If it is a \\cite{}, show the BibTeX database entry. | |
3505 If there is no such macro at point, search forward to find one. | |
3506 When you call this function several times in direct successtion, point will | |
3507 move to view subsequent cross references further down in the buffer. | |
3508 With argument, actually select the window showing the cross reference." | |
3509 | |
3510 (interactive "P") | |
3511 | |
3512 ;; See where we are. | |
3513 (let* ((pos (point)) | |
3514 (re "\\\\[a-z]*\\(cite\\|ref\\)\\(\\[[^{}]*\\]\\)?{\\([^}]+\\)}") | |
3515 (my-window (get-buffer-window (current-buffer))) | |
3516 pop-window cmd args macro label entry key-start point) | |
3517 | |
3518 (if (save-excursion | |
3519 (forward-char 1) | |
3520 (and (search-backward "\\" nil t) | |
3521 (looking-at re) | |
3522 (< pos (match-end 0)))) | |
3523 (setq macro (match-string 1) | |
3524 key-start (match-beginning 3))) | |
3525 | |
3526 (if (and macro (eq last-command this-command)) | |
3527 (if (and (string= macro "cite") | |
3528 (skip-chars-forward "^}, \t\n\r") | |
3529 (= (following-char) ?,)) | |
3530 (setq key-start (1+ (point))) | |
3531 (setq macro nil))) | |
3532 | |
3533 (if (not macro) | |
3534 (if (re-search-forward re nil t) | |
3535 (setq macro (match-string 1) | |
3536 key-start (match-beginning 3)) | |
3537 (error "No further cross references in buffer"))) | |
3538 | |
3539 (goto-char key-start) | |
3540 | |
3541 ;; Ensure access to scanning info | |
3542 (reftex-access-scan-info) | |
3543 | |
3544 (cond | |
3545 ((string= macro "cite") | |
3546 (setq cmd 'reftex-pop-to-bibtex-entry | |
3547 args (list | |
3548 (reftex-no-props (reftex-this-word "^{},")) | |
3549 (reftex-get-bibfile-list) nil t))) | |
3550 ((string= macro "ref") | |
3551 (let ((label (reftex-no-props (reftex-this-word "^{}"))) | |
3552 (entry (assoc label (symbol-value reftex-list-of-labels-symbol)))) | |
3553 (if entry | |
3554 (setq cmd 'reftex-pop-to-label | |
3555 args (list label (list (nth 3 entry)) nil t)) | |
3556 (error "Label %s not known - reparse document might help" label)))) | |
3557 (t (error "This should not happen"))) | |
3558 (setq point (point)) | |
3559 (apply cmd args) | |
3560 (setq pop-window (selected-window)) | |
3561 (add-hook 'pre-command-hook 'reftex-highlight-shall-die) | |
3562 (select-window my-window) | |
3563 (goto-char point) | |
3564 (and arg (select-window pop-window)))) | |
3565 | |
3566 (defun reftex-mouse-view-crossref (ev) | |
3567 "View cross reference of \\ref{} or \\cite{} macro where you click. | |
3568 If the macro at point is a \\ref{}, show the corresponding label definition. | |
3569 If it is a \\cite{}, show the BibTeX database entry. | |
3570 If there is no such macro at point, search forward to find one. | |
3571 When you call this function several times in direct successtion, point will | |
3572 move to view subsequent cross references further down in the buffer. | |
3573 With argument, actually select the window showing the cross reference." | |
3574 (interactive "e") | |
3575 (mouse-set-point ev) | |
3576 (reftex-view-crossref current-prefix-arg)) | |
3577 | |
3578 ;;; =========================================================================== | |
3579 ;;; | |
3580 ;;; Functions that check out the surroundings | |
3581 | |
3582 (defun reftex-what-macro (which &optional bound) | |
3583 ;; Find out if point is within the arguments of any TeX-macro. | |
3584 ;; The return value is either (\"\\\\macro\" . (point)) or a list of them. | |
3585 | |
3586 ;; If WHICH is nil, immediately return nil. | |
3587 ;; If WHICH is t, return list of all macros enclosing point. | |
3588 ;; If WHICH is a list of macros, look only for those macros and return the | |
3589 ;; name of the first macro in this list found to enclose point. | |
3590 ;; If the optional BOUND is an integer, bound backwards directed | |
3591 ;; searches to this point. If it is nil, limit to nearest \\section - | |
3592 ;; like statement. | |
3593 | |
3594 ;; This function is pretty stable, but can be fooled if the text contains | |
3595 ;; things like \\macro{aa}{bb} where \\macro is defined to take only one | |
3596 ;; argument. As RefTeX cannot know this, the string \"bb\" would still be | |
3597 ;; considered an argument of macro \\macro. | |
3598 | |
3599 (catch 'exit | |
3600 (if (null which) (throw 'exit nil)) | |
3601 (let ((bound (or bound (save-excursion (re-search-backward | |
3602 reftex-section-regexp nil 1) | |
3603 (point)))) | |
3604 pos cmd-list cmd) | |
3605 (save-restriction | |
3606 (save-excursion | |
3607 (narrow-to-region (max 1 bound) (point-max)) | |
3608 ;; move back out of the current parenthesis | |
3609 (while (condition-case nil | |
3610 (progn (up-list -1) t) | |
3611 (error nil)) | |
3612 ;; move back over any touching sexps | |
3613 (while (or (= (preceding-char) ?\]) | |
3614 (= (preceding-char) ?\})) | |
3615 (backward-sexp)) | |
3616 (setq pos (point)) | |
3617 (if (and (or (= (following-char) ?\[) | |
3618 (= (following-char) ?\{)) | |
3619 (and (re-search-backward "\\(\\\\[a-zA-Z]+\\)" nil t) | |
3620 (= (match-end 0) pos))) | |
3621 (progn | |
3622 (setq cmd (buffer-substring-no-properties | |
3623 (match-beginning 0) (match-end 0))) | |
3624 (if (eq t which) | |
3625 (setq cmd-list (cons (cons cmd (point)) cmd-list)) | |
3626 (if (member cmd which) | |
3627 (throw 'exit (cons cmd (point))))))) | |
3628 (goto-char pos))) | |
3629 (nreverse cmd-list))))) | |
3630 | |
3631 (defun reftex-what-environment (which &optional bound) | |
3632 ;; Find out if point is inside a LaTeX environment. | |
3633 ;; The return value is (e.g.) either (\"equation\" . (point)) or a list of | |
3634 ;; them. | |
3635 | |
3636 ;; If WHICH is nil, immediately return nil. | |
3637 ;; If WHICH is t, return list of all environments enclosing point. | |
3638 ;; If WHICH is a list of environments, look only for those environments and | |
3639 ;; return the name of the first environment in this list found to enclose | |
3640 ;; point. | |
3641 | |
3642 ;; If the optional BOUND is an integer, bound backwards directed searches to | |
3643 ;; this point. If it is nil, limit to nearest \\section - like statement. | |
3644 | |
3645 (catch 'exit | |
3646 (save-excursion | |
3647 (if (null which) (throw 'exit nil)) | |
3648 (let ((bound (or bound (save-excursion (re-search-backward | |
3649 reftex-section-regexp nil 1) | |
3650 (point)))) | |
3651 env-list end-list env) | |
3652 (while (re-search-backward "\\\\\\(begin\\|end\\){\\([^}]+\\)}" | |
3653 bound t) | |
3654 (setq env (buffer-substring-no-properties | |
3655 (match-beginning 2) (match-end 2))) | |
3656 (cond | |
3657 ((string= (match-string 1) "end") | |
3658 (add-to-list 'end-list env)) | |
3659 ((member env end-list) | |
3660 (setq end-list (delete env end-list))) | |
3661 ((eq t which) | |
3662 (setq env-list (cons (cons env (point)) env-list))) | |
3663 ((member env which) | |
3664 (throw 'exit (cons env (point)))))) | |
3665 (nreverse env-list))))) | |
3666 | |
3667 (defun reftex-word-before-point () | |
3668 ;; Return the word before point. Word means here: | |
3669 ;; Consists of [a-zA-Z0-9.:] and ends at point or whitespace. | |
3670 (let ((pos (point))) | |
3671 (save-excursion | |
3672 (re-search-backward "[^ \t\n\r]" (point-min) 1) | |
3673 (setq pos (1+ (point))) | |
3674 (if (re-search-backward "[^a-zA-Z0-9\\\.:]" (point-min) 1) | |
3675 (forward-char 1)) | |
3676 (buffer-substring-no-properties (point) pos)))) | |
3677 | |
3678 ;; ============================================================================ | |
3679 ;; | |
3680 ;; Some generally useful functions | |
3681 | |
3682 (defun reftex-no-props (string) | |
3683 ;; Return STRING with all text properties removed | |
3684 (and (stringp string) | |
3685 (set-text-properties 0 (length string) nil string)) | |
3686 string) | |
3687 | |
3688 (defun reftex-split (regexp string) | |
3689 ;; Split like perl | |
3690 (let ((start 0) list) | |
3691 (while (string-match regexp string start) | |
3692 (setq list (cons (substring string start (match-beginning 0)) list)) | |
3693 (setq start (match-end 0))) | |
3694 (setq list (nreverse (cons (substring string start) list))))) | |
3695 | |
3696 (defun reftex-allow-for-ctrl-m (string) | |
3697 ;; convert STRING into a regexp, allowing ^M for \n | |
3698 (let ((start -2)) | |
3699 (setq string (regexp-quote string)) | |
3700 (while (setq start (string-match "[\n\r]" string (+ 3 start))) | |
3701 (setq string (replace-match "[\n\r]" nil t string))) | |
3702 string)) | |
3703 | |
3704 (defun reftex-delete-list (elt-list list) | |
3705 ;; like delete, but with a list of things to delete | |
3706 ;; (original code from Rory Molinari) | |
3707 (while elt-list | |
3708 (setq list (delete (car elt-list) list) | |
3709 elt-list (cdr elt-list))) | |
3710 list) | |
3711 | |
3712 (defun reftex-get-buffer-visiting (file) | |
3713 ;; return a buffer visiting FILE | |
3714 (cond | |
3715 ((fboundp 'find-buffer-visiting) ; Emacs | |
3716 (find-buffer-visiting file)) | |
3717 ((boundp 'find-file-compare-truenames) ; XEmacs | |
3718 (let ((find-file-compare-truenames t)) | |
3719 (get-file-buffer file))) | |
3720 (t (error "Please report this problem to dominik@strw.leidenuniv.nl")))) | |
3721 | |
3722 (defun reftex-get-file-buffer-force (file &optional mark-to-kill) | |
3723 ;; Return a buffer visiting file. Make one, if necessary. | |
3724 ;; If neither such a buffer no the file exist, return nil. | |
3725 ;; If MARK-TO-KILL in non-nil, put any new buffers into the kill list." | |
3726 | |
3727 (let ((buf (reftex-get-buffer-visiting file))) | |
3728 (cond | |
3729 (buf buf) | |
3730 ((file-exists-p file) | |
3731 (setq buf (find-file-noselect file)) | |
3732 (if mark-to-kill | |
3733 (add-to-list 'reftex-buffers-to-kill buf)) | |
3734 buf) | |
3735 (t nil)))) | |
3736 | |
3737 (defun reftex-splice-symbols-into-list (list alist) | |
3738 ;; Splice the association in ALIST of any symbols in LIST into the list. | |
3739 ;; Return new list. | |
3740 (let (rtn tmp) | |
3741 (while list | |
3742 (while (and (not (null (car list))) | |
3743 (symbolp (car list))) | |
3744 (setq tmp (car list)) | |
3745 (cond | |
3746 ((assoc tmp alist) | |
3747 (setq list (append (cdr (cdr (assoc tmp alist))) (cdr list)))) | |
3748 (t | |
3749 (error "Cannot treat symbol %s in reftex-label-alist" | |
3750 (symbol-name tmp))))) | |
3751 (setq rtn (cons (car list) rtn) | |
3752 list (cdr list))) | |
3753 (nreverse rtn))) | |
3754 | |
3755 (defun reftex-uniquify (alist &optional keep-list) | |
3756 ;; Return a list of all elements in ALIST, but each car only once | |
3757 ;; Elements of KEEP-LIST are not removed even if duplicate | |
3758 (let (new elm) | |
3759 (while alist | |
3760 (setq elm (car alist) | |
3761 alist (cdr alist)) | |
3762 (if (or (member (car elm) keep-list) | |
3763 (not (assoc (car elm) new))) | |
3764 (setq new (cons elm new)))) | |
3765 (setq new (nreverse new)) | |
3766 new)) | |
3767 | |
3768 (defun reftex-use-fonts () | |
3769 ;; Return t if we can and want to use fonts | |
3770 (and window-system | |
3771 reftex-use-fonts | |
3772 (boundp 'font-lock-keyword-face))) | |
3773 | |
3774 ;; Highlighting uses overlays. If this is for XEmacs, we need to load | |
3775 ;; the overlay library, available in version 19.15 | |
3776 (and (not (fboundp 'make-overlay)) | |
3777 (condition-case nil | |
3778 (require 'overlay) | |
3779 ('error | |
3780 (error "RefTeX needs overlay emulation (available in XEmacs 19.15)")))) | |
3781 | |
3782 ;; We keep a vector with several different overlays to do our highlighting. | |
3783 (defvar reftex-highlight-overlays [nil nil]) | |
3784 | |
3785 ;; Initialize the overlays | |
3786 (aset reftex-highlight-overlays 0 (make-overlay 1 1)) | |
3787 (overlay-put (aref reftex-highlight-overlays 0) 'face 'highlight) | |
3788 (aset reftex-highlight-overlays 1 (make-overlay 1 1)) | |
3789 (overlay-put (aref reftex-highlight-overlays 1) 'face 'highlight) | |
3790 | |
3791 ;; Two functions for activating and deactivation highlight overlays | |
3792 (defun reftex-highlight (index begin end &optional buffer) | |
3793 "Highlight a region with overlay INDEX." | |
3794 (move-overlay (aref reftex-highlight-overlays index) | |
3795 begin end (or buffer (current-buffer)))) | |
3796 (defun reftex-unhighlight (index) | |
3797 "Detatch overlay INDEX." | |
3798 (delete-overlay (aref reftex-highlight-overlays index))) | |
3799 | |
3800 (defun reftex-highlight-shall-die () | |
3801 ;; Function used in pre-command-hook to remove highlights | |
3802 (remove-hook 'pre-command-hook 'reftex-highlight-shall-die) | |
3803 (reftex-unhighlight 0)) | |
3804 | |
3805 ;;; --------------------------------------------------------------------------- | |
3806 ;;; | |
3807 ;;; Cursor position after insertion of forms | |
3808 | |
3809 (defun reftex-position-cursor () | |
3810 ;; Search back to question mark, delete it, leave point there | |
3811 (if (search-backward "\?" (- (point) 100) t) | |
3812 (delete-char 1))) | |
3813 | |
3814 (defun reftex-item () | |
3815 "Insert an \\item and provide a label if the environments supports that." | |
3816 (interactive) | |
3817 (let ((env (car | |
3818 (reftex-what-environment '("itemize" "enumerate" "eqnarray"))))) | |
3819 | |
3820 (if (and env (not (bolp))) (newline)) | |
3821 | |
3822 (cond | |
3823 | |
3824 ((string= env "eqnarray") | |
3825 (if (not (bolp)) | |
3826 (newline)) | |
3827 (reftex-label env) | |
3828 (insert "\n & & ") | |
3829 (beginning-of-line 1)) | |
3830 | |
3831 ((string= env "itemize") | |
3832 (newline) | |
3833 (insert "\\item ")) | |
3834 | |
3835 ((string= env "enumerate") | |
3836 (newline) | |
3837 (insert "\\item") | |
3838 (reftex-label env) | |
3839 (insert " ")) | |
3840 (t | |
3841 (error "\\item command does not make sense here..."))))) | |
3842 | |
3843 ;;; --------------------------------------------------------------------------- | |
3844 ;;; --------------------------------------------------------------------------- | |
3845 ;;; --------------------------------------------------------------------------- | |
3846 ;;; | |
3847 ;;; Data Section: Definition of large constants | |
3848 | |
3849 | |
3850 (defconst reftex-label-alist-builtin | |
3851 '( | |
3852 (LaTeX | |
3853 "LaTeX default environments" | |
3854 ("section" ?s "sec:" "~\\ref{%s}" t | |
3855 ("Part" "Chapter" "Chap." "Section" "Sec." "Sect." "Paragraph" "Par." | |
3856 "\\S" "Teil" "Kapitel" "Kap." "Abschnitt" )) | |
3857 | |
3858 ("enumerate" ?n "item:" "~\\ref{%s}" "\\\\item\\(\\[[^]]*\\]\\)?" | |
3859 ("Item" "Punkt")) | |
3860 | |
3861 ("equation" ?e "eq:" "~(\\ref{%s})" t | |
3862 ("Equation" "Eq." "Eqn." "Gleichung" "Gl.")) | |
3863 ("eqnarray" ?e "eq:" nil "\\\\begin{eqnarray}\\|\\\\\\\\") | |
3864 | |
3865 ("figure" ?f "fig:" "~\\ref{%s}" "\\\\caption\\(\\[[^]]*\\]\\)?{" | |
3866 ("Figure" "Fig." "Abbildung" "Abb.")) | |
3867 ("figure*" ?f nil nil "\\\\caption\\(\\[[^]]*\\]\\)?{") | |
3868 | |
3869 ("table" ?t "tab:" "~\\ref{%s}" "\\\\caption\\(\\[[^]]*\\]\\)?{" | |
3870 ("Table" "Tab." "Tabelle")) | |
3871 ("table*" ?t nil nil "\\\\caption\\(\\[[^]]*\\]\\)?{") | |
3872 | |
3873 ("any" ?\ " " "\\ref{%s}" nil)) | |
3874 | |
3875 (Sideways | |
3876 "Sidewaysfigure and sidewaystable" | |
3877 ("sidewaysfigure" ?f nil nil "\\\\caption\\(\\[[^]]*\\]\\)?{") | |
3878 ("sidewaystable" ?t nil nil "\\\\caption\\(\\[[^]]*\\]\\)?{")) | |
3879 | |
3880 (AMSTeX | |
3881 "AMS-LaTeX: amsmath package environents" | |
3882 ("align" ?e "eq:" "~\\eqref{%s}" "\\\\begin{align}\\|\\\\\\\\") | |
3883 ("gather" ?e "eq:" nil "\\\\begin{gather}\\|\\\\\\\\") | |
3884 ("multline" ?e "eq:" nil t) | |
3885 ("flalign" ?e "eq:" nil "\\\\begin{flalign}\\|\\\\\\\\") | |
3886 ("alignat" ?e "eq:" nil "\\\\begin{alignat}{[0-9]*}\\|\\\\\\\\")) | |
3887 | |
3888 (AASTeX | |
3889 "AAS deluxetable environment" | |
3890 ("deluxetable" ?t "tab:" nil "\\\\caption{"))) | |
3891 "The default label environment descriptions.") | |
3892 | |
3893 ;;; --------------------------------------------------------------------------- | |
3894 ;;; | |
3895 ;;; Functions to compile the tables, reset the mode etc. | |
3896 | |
3897 (defun reftex-reset-mode () | |
3898 "Reset RefTeX Mode. Required to implement changes to some list variables. | |
3899 This function will compile the information in reftex-label-alist and similar | |
3900 variables. It is called when RefTeX is first used, and after changes to | |
3901 these variables via reftex-add-to-label-alist." | |
3902 (interactive) | |
3903 | |
3904 ; record that we have done this | |
3905 (setq reftex-tables-dirty nil) | |
3906 | |
3907 ;; To update buffer-local variables | |
3908 (hack-local-variables) | |
3909 (message "updating internal tables...") | |
3910 (reftex-compute-ref-cite-tables) | |
3911 (message "updating internal tables... done") | |
3912 (reftex-reset-scanning-information)) | |
3913 | |
3914 (defun reftex-reset-scanning-information () | |
3915 "Reset the symbols containing information from buffer scanning. | |
3916 This enforces rescanning the buffer on next use." | |
3917 (if (and (string= reftex-last-toc-master (reftex-TeX-master-file)) | |
3918 (get-buffer "*toc*")) | |
3919 (kill-buffer "*toc*")) | |
3920 (let ((symlist reftex-multifile-symbols) | |
3921 symbol) | |
3922 (while symlist | |
3923 (setq symbol (car symlist) | |
3924 symlist (cdr symlist)) | |
3925 (if (and (symbolp (symbol-value symbol)) | |
3926 (not (null (symbol-value symbol)))) | |
3927 (set (symbol-value symbol) nil))))) | |
3928 | |
3929 (defun reftex-compute-ref-cite-tables () | |
3930 ;; Update ref and cite tables | |
3931 | |
3932 (interactive) | |
3933 | |
3934 ;; Compile information in reftex-label-alist | |
3935 (let ((tmp (reftex-uniquify (reftex-splice-symbols-into-list | |
3936 (append | |
3937 reftex-label-alist | |
3938 reftex-label-alist-external-add-ons | |
3939 reftex-default-label-alist-entries) | |
3940 reftex-label-alist-builtin) | |
3941 '(nil))) | |
3942 entry env-or-mac typekeychar typekey prefix regexp | |
3943 fmt wordlist cmd qh-list) | |
3944 | |
3945 (setq reftex-words-to-typekey-alist nil | |
3946 reftex-typekey-list nil | |
3947 reftex-typekey-to-format-alist nil | |
3948 reftex-typekey-to-prefix-alist nil | |
3949 reftex-env-or-mac-alist nil | |
3950 reftex-label-env-list nil | |
3951 reftex-label-mac-list nil) | |
3952 (while tmp | |
3953 (catch 'next-entry | |
3954 (setq entry (car tmp) | |
3955 env-or-mac (car entry) | |
3956 entry (cdr entry) | |
3957 tmp (cdr tmp)) | |
3958 (if (null env-or-mac) | |
3959 (setq env-or-mac "")) | |
3960 (if (stringp (car entry)) | |
3961 ;; This is before version 2.00 - convert entry to new format | |
3962 ;; This is just to keep old users happy | |
3963 (setq entry (cons (string-to-char (car entry)) | |
3964 (cons (concat (car entry) ":") | |
3965 (cdr entry))))) | |
3966 (setq typekeychar (nth 0 entry) | |
3967 typekey (char-to-string typekeychar) | |
3968 prefix (nth 1 entry) | |
3969 fmt (nth 2 entry) | |
3970 regexp (nth 3 entry) | |
3971 wordlist (nth 4 entry)) | |
3972 (if (stringp wordlist) | |
3973 ;; This is before version 2.04 - convert to new format | |
3974 (setq wordlist (nthcdr 4 entry))) | |
3975 (if typekey | |
3976 (add-to-list 'reftex-typekey-list typekey)) | |
3977 (if (and typekey prefix) | |
3978 (add-to-list 'reftex-typekey-to-prefix-alist (cons typekey prefix))) | |
3979 (cond | |
3980 ((string-match "\\`\\\\" env-or-mac) | |
3981 ;; It's a macro | |
3982 (add-to-list 'reftex-label-mac-list env-or-mac)) | |
3983 (t | |
3984 (or (string= env-or-mac "any") | |
3985 (string= env-or-mac "") | |
3986 (add-to-list 'reftex-label-env-list env-or-mac)))) | |
3987 (and fmt | |
3988 (not (assoc typekey reftex-typekey-to-format-alist)) | |
3989 (setq reftex-typekey-to-format-alist | |
3990 (cons (cons typekey fmt) | |
3991 reftex-typekey-to-format-alist))) | |
3992 (and (not (string= env-or-mac "any")) | |
3993 (not (string= env-or-mac "")) | |
3994 (not (assoc env-or-mac reftex-env-or-mac-alist)) | |
3995 (setq reftex-env-or-mac-alist | |
3996 (cons (list env-or-mac typekey regexp) | |
3997 reftex-env-or-mac-alist))) | |
3998 (while (and wordlist (stringp (car wordlist))) | |
3999 (or (assoc (car wordlist) reftex-words-to-typekey-alist) | |
4000 (setq reftex-words-to-typekey-alist | |
4001 (cons (cons (downcase (car wordlist)) typekey) | |
4002 reftex-words-to-typekey-alist))) | |
4003 (setq wordlist (cdr wordlist))) | |
4004 (cond | |
4005 ((string= "" env-or-mac) nil) | |
4006 ((assoc typekey qh-list) | |
4007 (setcdr (assoc typekey qh-list) | |
4008 (concat (cdr (assoc typekey qh-list)) " " env-or-mac))) | |
4009 (t | |
4010 (setq qh-list (cons (cons typekey env-or-mac) qh-list)))))) | |
4011 | |
4012 (setq qh-list (nreverse qh-list)) | |
4013 (setq reftex-typekey-to-prefix-alist | |
4014 (nreverse reftex-typekey-to-prefix-alist)) | |
4015 (setq reftex-type-query-prompt | |
4016 (concat "Label type: " | |
4017 (mapconcat '(lambda(x) | |
4018 (format "[%s]" (car x))) | |
4019 qh-list " ") | |
4020 " (?=Help)")) | |
4021 (setq reftex-type-query-help | |
4022 (concat "SELECT A LABEL TYPE:\n--------------------\n" | |
4023 (mapconcat '(lambda(x) | |
4024 (format " [%s] %s" | |
4025 (car x) (cdr x))) | |
4026 qh-list "\n"))))) | |
4027 | |
4028 ;;; Keybindings -------------------------------------------------------------- | |
4029 | |
4030 (define-key reftex-mode-map "\C-c-" 'reftex-item) | |
4031 (define-key reftex-mode-map "\C-c=" 'reftex-toc) | |
4032 (define-key reftex-mode-map "\C-c(" 'reftex-label) | |
4033 (define-key reftex-mode-map "\C-c)" 'reftex-reference) | |
4034 (define-key reftex-mode-map "\C-c[" 'reftex-citation) | |
4035 (define-key reftex-mode-map "\C-c&" 'reftex-view-crossref) | |
4036 | |
4037 ;; If the user requests so, she can have a few more bindings: | |
4038 (cond | |
4039 (reftex-extra-bindings | |
4040 (define-key reftex-mode-map "\C-ct" 'reftex-toc) | |
4041 (define-key reftex-mode-map "\C-cl" 'reftex-label) | |
4042 (define-key reftex-mode-map "\C-cr" 'reftex-reference) | |
4043 (define-key reftex-mode-map "\C-cc" 'reftex-citation) | |
4044 (define-key reftex-mode-map "\C-cv" 'reftex-view-crossref) | |
4045 (define-key reftex-mode-map "\C-cg" 'reftex-grep-document) | |
4046 (define-key reftex-mode-map "\C-cs" 'reftex-search-document))) | |
4047 | |
4048 ;;; Menus -------------------------------------------------------------------- | |
4049 | |
4050 ;; Define a menu for the menu bar if Emacs is running under X | |
4051 | |
4052 (require 'easymenu) | |
4053 | |
4054 (easy-menu-define | |
4055 reftex-mode-menu reftex-mode-map | |
4056 "Menu used in RefTeX mode" | |
4057 '("Ref" | |
4058 ["Table of Contents" reftex-toc t] | |
4059 "----" | |
4060 ["\\label{}" reftex-label t] | |
4061 ["\\ref{}" reftex-reference t] | |
4062 ["\\cite{}" reftex-citation t] | |
4063 ["View crossref" reftex-view-crossref t] | |
4064 "----" | |
4065 ("Search and Replace" | |
4066 ["Search whole document" reftex-search-document t] | |
4067 ["Replace in document" reftex-query-replace-document t] | |
4068 ["Grep on document" reftex-grep-document t] | |
4069 "----" | |
4070 ["Find duplicate labels" reftex-find-duplicate-labels t] | |
4071 ["Change label and refs" reftex-change-label t] | |
4072 "----" | |
4073 ["Create TAGS file" reftex-create-tags-file t]) | |
4074 "----" | |
4075 ["Parse document" reftex-parse-document t] | |
4076 ["Reset RefTeX Mode" reftex-reset-mode t] | |
4077 ["Customize RefTeX" reftex-customize t])) | |
4078 | |
4079 ;;; Run Hook ------------------------------------------------------------------ | |
4080 | |
4081 (run-hooks 'reftex-load-hook) | |
4082 | |
4083 ;;; That's it! ---------------------------------------------------------------- | |
4084 | |
4085 ; Make sure tabels are compiled | |
4086 (message "updating internal tables...") | |
4087 (reftex-compute-ref-cite-tables) | |
4088 (setq reftex-tables-dirty nil) | |
4089 | |
4090 (provide 'reftex) | |
4091 | |
4092 ;;;============================================================================ | |
4093 | |
4094 ;;; reftex.el end here |