Commit | Line | Data |
---|---|---|
a7ec1775 RS |
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 | \f | |
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 ((?\r . ("\cite{KEY}" "AUTHOR \cite{KEY}" "AUTHOR and AUTHOR \cite{KEY}"))) | |
905 | (cons :tag "Enter a keyed list of format strings" | |
906 | (character :tag "Key character " ?\r) | |
907 | (repeat | |
908 | (string :tag "format string" "")))))) | |
909 | ||
910 | ;; Table of contents configuration -------------------------------------- | |
911 | ||
912 | (defgroup reftex-table-of-contents-browser nil | |
913 | "A multifile table of contents browser." | |
914 | :group 'reftex) | |
915 | ||
916 | (defcustom reftex-toc-follow-mode nil | |
917 | "Non-nil means, point in *toc* buffer will cause other window to follow. | |
918 | The other window will show the corresponding part of the document. | |
919 | This flag can be toggled from within the *toc* buffer with the `f' key." | |
920 | :group 'reftex-table-of-contents-browser | |
921 | :type '(boolean)) | |
922 | ||
923 | ;; Miscellaneous configurations ----------------------------------------- | |
924 | ||
925 | (defgroup reftex-miscellaneous-configurations nil | |
926 | "Collection of further configurations" | |
927 | :group 'reftex) | |
928 | ||
929 | (defcustom reftex-extra-bindings nil | |
930 | "Non-nil means, make additional key bindings on startup. | |
931 | These extra bindings are located in the users C-c letter map." | |
932 | :group 'reftex-miscellaneous-configurations | |
933 | :type '(boolean)) | |
934 | ||
935 | (defcustom reftex-use-fonts t | |
936 | "*Non-nil means, use fonts in label menu and on-the-fly help. | |
937 | Font-lock must be loaded as well to actually get fontified display." | |
938 | :group 'reftex-miscellaneous-configurations | |
939 | :type '(boolean)) | |
940 | ||
941 | (defcustom reftex-keep-temporary-buffers t | |
942 | "*Non-nil means, keep any TeX and BibTeX files loaded for lookup. | |
943 | Nil means, kill it immediately after use unless it was already an existing | |
944 | buffer before the lookup happened. It is faster to keep the buffers, but can | |
945 | use a lot of memory, depending on the size of your database and document." | |
946 | :group 'reftex-miscellaneous-configurations | |
947 | :type '(boolean)) | |
948 | ||
949 | (defcustom reftex-auto-show-entry t | |
950 | "*Non-nil means, showing context in another window may unhide a section. | |
951 | This is important when using outline-minor-mode. If the context to be shown | |
952 | is in a hidden section, RefTeX will issue a \"show-entry\" command in order | |
953 | to show it. This is not reversed when the label is selected - so the section | |
954 | remains shown after command completion." | |
955 | :group 'reftex-miscellaneous-configurations | |
956 | :type '(boolean)) | |
957 | ||
958 | ||
959 | ;;; End of Configuration Section ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
960 | ||
961 | ;;;=========================================================================== | |
962 | ;;; | |
963 | ;;; Define the formal stuff for a minor mode named RefTeX. | |
964 | ;;; | |
965 | ||
966 | (defvar reftex-mode nil | |
967 | "Determines if RefTeX minor mode is active.") | |
968 | (make-variable-buffer-local 'reftex-mode) | |
969 | ||
970 | (defvar reftex-mode-map (make-sparse-keymap) | |
971 | "Keymap for RefTeX minor mode.") | |
972 | ||
973 | (defvar reftex-mode-menu nil) | |
974 | ||
975 | ;;;###autoload | |
976 | (defun turn-on-reftex () | |
977 | "Turn on RefTeX minor mode." | |
978 | (reftex-mode t)) | |
979 | ||
980 | ;;;###autoload | |
981 | (defun reftex-mode (&optional arg) | |
982 | "Minor mode with distinct support for \\label{}, \\ref{} and \\cite{} | |
983 | in LaTeX documents. | |
984 | ||
985 | Labels can be created with `\\[reftex-label]' and referenced with `\\[reftex-reference]'. | |
986 | When referencing, you get a menu with all labels of a given type and | |
987 | context of the label definition. The selected label is inserted as a | |
988 | \\ref{} macro. | |
989 | ||
990 | Citations can be made with `\\[reftex-citation]' which will use a regular expression | |
991 | to pull out a *formatted* list of articles from your BibTeX | |
992 | database. The selected citation is inserted as a \\cite{} macro. | |
993 | ||
994 | A Table of Contents of the entire (multifile) document with browsing | |
995 | capabilities is available with `\\[reftex-toc]'. | |
996 | ||
997 | Most command have help available on the fly. This help is accessed by | |
998 | pressing `?' to any prompt mentioning this feature. | |
999 | ||
1000 | \\{reftex-mode-map} | |
1001 | Under X, these functions will be available also in a menu on the menu bar. | |
1002 | ||
1003 | ------------------------------------------------------------------------------" | |
1004 | ||
1005 | (interactive "P") | |
1006 | (setq reftex-mode (not (or (and (null arg) reftex-mode) | |
1007 | (<= (prefix-numeric-value arg) 0)))) | |
1008 | ||
1009 | ; Add or remove the menu, and run the hook | |
1010 | (if reftex-mode | |
1011 | (progn | |
1012 | (easy-menu-add reftex-mode-menu) | |
1013 | (run-hooks 'reftex-mode-hook)) | |
1014 | (easy-menu-remove reftex-mode-menu))) | |
1015 | ||
1016 | (or (assoc 'reftex-mode minor-mode-alist) | |
1017 | (setq minor-mode-alist | |
1018 | (cons '(reftex-mode " Ref") minor-mode-alist))) | |
1019 | ||
1020 | (or (assoc 'reftex-mode minor-mode-map-alist) | |
1021 | (setq minor-mode-map-alist | |
1022 | (cons (cons 'reftex-mode reftex-mode-map) | |
1023 | minor-mode-map-alist))) | |
1024 | ||
1025 | ||
1026 | ;;; =========================================================================== | |
1027 | ;;; | |
1028 | ;;; Interfaces for other packages | |
1029 | ;;; ----------------------------- | |
1030 | ;;; | |
1031 | ;;; AUCTeX | |
1032 | ;;; ------ | |
1033 | ||
1034 | (defun reftex-arg-label (optional &optional prompt definition) | |
1035 | "Use reftex-label to create a label and insert it with TeX-argument-insert. | |
1036 | This function is intended for AUCTeX macro support." | |
1037 | (let ((label (reftex-label nil t))) | |
1038 | (if (and definition (not (string-equal "" label))) | |
1039 | (LaTeX-add-labels label)) | |
1040 | (TeX-argument-insert label optional optional))) | |
1041 | ||
1042 | (defun reftex-arg-ref (optional &optional prompt definition) | |
1043 | "Use reftex-reference to select a label, insert it with TeX-argument-insert. | |
1044 | This function is intended for AUCTeX macro support." | |
1045 | (let ((label (reftex-reference nil t))) | |
1046 | (if (and definition (not (string-equal "" label))) | |
1047 | (LaTeX-add-labels label)) | |
1048 | (TeX-argument-insert label optional optional))) | |
1049 | ||
1050 | (defun reftex-arg-cite (optional &optional prompt definition) | |
1051 | "Use reftex-citation to select a key, insert it with TeX-argument-insert. | |
1052 | This function is intended for AUCTeX macro support." | |
1053 | (let ((key (reftex-citation nil t))) | |
1054 | (TeX-argument-insert (or key "") optional optional))) | |
1055 | ||
1056 | (defvar reftex-label-alist-external-add-ons nil | |
1057 | "List of label alist entries added with reftex-add-to-label-alist.") | |
1058 | ||
1059 | ;;;###autoload | |
1060 | (defun reftex-add-to-label-alist (entry-list) | |
1061 | "Add label environment descriptions to reftex-label-alist-external-add-ons. | |
1062 | The format of ENTRY-LIST is exactly like reftex-label-alist. See there | |
1063 | for details. | |
1064 | This function makes it possible to support RefTeX from AUCTeX style files. | |
1065 | The entries in ENTRY-LIST will be processed after the user settings in | |
1066 | reftex-label-alist, and before the defaults (specified in | |
1067 | reftex-default-label-alist-entries). Any changes made to | |
1068 | reftex-label-alist-external-add-ons will raise a flag to the effect that a | |
1069 | mode reset is done on the next occasion." | |
1070 | (let (entry) | |
1071 | (while entry-list | |
1072 | (setq entry (car entry-list) | |
1073 | entry-list (cdr entry-list)) | |
1074 | (if (not (member entry reftex-label-alist-external-add-ons)) | |
1075 | (setq reftex-tables-dirty t | |
1076 | reftex-label-alist-external-add-ons | |
1077 | (cons entry reftex-label-alist-external-add-ons)))))) | |
1078 | ||
1079 | ;;; =========================================================================== | |
1080 | ;;; | |
1081 | ;;; Multifile support | |
1082 | ;;; | |
1083 | ;;; Technical notes: Multifile works as follows: We keep just one list | |
1084 | ;;; of labels for each master file - this can save a lot of memory. | |
1085 | ;;; reftex-master-index-list is an alist which connects the true file name | |
1086 | ;;; of each master file with the symbols holding the information on that | |
1087 | ;;; document. Each buffer has local variables which point to these symbols. | |
1088 | ||
1089 | ||
1090 | ;; List of variables which handle the multifile stuff. | |
1091 | ;; This list is used to tie, untie, and reset these symbols. | |
1092 | (defconst reftex-multifile-symbols | |
1093 | '(reftex-label-numbers-symbol reftex-list-of-labels-symbol | |
1094 | reftex-bibfile-list-symbol)) | |
1095 | ||
1096 | ;; Alist connecting master file names with the corresponding lisp symbols | |
1097 | (defvar reftex-master-index-list nil) | |
1098 | ||
1099 | ;; Last index used for a master file | |
1100 | (defvar reftex-multifile-index 0) | |
1101 | ||
1102 | ;; Alist connecting a master file with all included files. | |
1103 | ;; This information is not yet used, just collected. | |
1104 | (defvar reftex-master-include-list nil) | |
1105 | ||
1106 | ;; Variable holding the symbol with current value of label postfix | |
1107 | (defvar reftex-label-numbers-symbol nil ) | |
1108 | (make-variable-buffer-local 'reftex-label-numbers-symbol) | |
1109 | ||
1110 | ;; Variable holding the symbol with the label list of the document. | |
1111 | ;; Each element of the label list is again a list with the following elements: | |
1112 | ;; 0: One character label type indicator | |
1113 | ;; 1: Short context to put into label menu | |
1114 | ;; 2: The label | |
1115 | ;; 3: The name of the file where the label is defined | |
1116 | (defvar reftex-list-of-labels-symbol nil) | |
1117 | (make-variable-buffer-local 'reftex-list-of-labels-symbol) | |
1118 | ||
1119 | ;; Variable holding the symbol with a list of library files for this document | |
1120 | (defvar reftex-bibfile-list-symbol nil) | |
1121 | (make-variable-buffer-local 'reftex-bibfile-list-symbol) | |
1122 | ||
1123 | (defun reftex-next-multifile-index () | |
1124 | ;; Return the next free index for multifile symbols. | |
1125 | (setq reftex-multifile-index (1+ reftex-multifile-index))) | |
1126 | ||
1127 | (defun reftex-tie-multifile-symbols () | |
1128 | ;; Tie the buffer-local symbols to globals connected with the master file. | |
1129 | ;; If the symbols for the current master file do not exist, they are created. | |
1130 | ||
1131 | (let* ((master (file-truename (reftex-TeX-master-file))) | |
1132 | (index (assoc master reftex-master-index-list)) | |
1133 | (symlist reftex-multifile-symbols) | |
1134 | (symbol nil) | |
1135 | (symname nil) | |
1136 | (newflag nil)) | |
1137 | ;; find the correct index | |
1138 | (if index | |
1139 | ;; symbols do exist | |
1140 | (setq index (cdr index)) | |
1141 | ;; get a new index and add info to the alist | |
1142 | (setq index (reftex-next-multifile-index) | |
1143 | reftex-master-index-list (cons | |
1144 | (cons master index) | |
1145 | reftex-master-index-list) | |
1146 | newflag t)) | |
1147 | ||
1148 | ;; get/create symbols and tie them | |
1149 | (while symlist | |
1150 | (setq symbol (car symlist) | |
1151 | symlist (cdr symlist) | |
1152 | symname (symbol-name symbol)) | |
1153 | (set symbol (intern (concat symname "-" (int-to-string index)))) | |
1154 | ;; initialize if new symbols | |
1155 | (if newflag (set (symbol-value symbol) nil))) | |
1156 | ||
1157 | ;; Return t if the symbols did already exist, nil when we've made them | |
1158 | (not newflag))) | |
1159 | ||
1160 | (defun reftex-untie-multifile-symbols () | |
1161 | ;; Remove ties from multifile symbols, so that next use makes new ones. | |
1162 | (let ((symlist reftex-multifile-symbols) | |
1163 | (symbol nil)) | |
1164 | (while symlist | |
1165 | (setq symbol (car symlist) | |
1166 | symlist (cdr symlist)) | |
1167 | (set symbol nil)))) | |
1168 | ||
1169 | (defun reftex-TeX-master-file () | |
1170 | ;; Return the name of the master file associated with the current buffer. | |
1171 | ;; When AUCTeX is loaded, we will use it's more sophisticated method. | |
1172 | ;; We also support the default TeX and LaTeX modes | |
1173 | ;; by checking for a variable tex-main-file. | |
1174 | ||
1175 | (let | |
1176 | ((master | |
1177 | (cond | |
1178 | ((fboundp 'TeX-master-file) ; AUCTeX is loaded. Use its mechanism. | |
1179 | (TeX-master-file t)) | |
1180 | ((boundp 'TeX-master) ; The variable is defined - lets use it. | |
1181 | (cond | |
1182 | ((eq TeX-master t) | |
1183 | (buffer-file-name)) | |
1184 | ((eq TeX-master 'shared) | |
1185 | (setq TeX-master (read-file-name "Master file: " | |
1186 | nil nil t nil))) | |
1187 | (TeX-master) | |
1188 | (t | |
1189 | (setq TeX-master (read-file-name "Master file: " | |
1190 | nil nil t nil))))) | |
1191 | ((boundp 'tex-main-file) | |
1192 | ;; This is the variable from the default TeX modes | |
1193 | (cond | |
1194 | ((stringp tex-main-file) | |
1195 | ;; ok, this must be it | |
1196 | tex-main-file) | |
1197 | (t | |
1198 | ;; In this case, the buffer is its own master | |
1199 | (buffer-file-name)))) | |
1200 | (t | |
1201 | ;; Know nothing about master file. Assume this is a master file. | |
1202 | (buffer-file-name))))) | |
1203 | (cond | |
1204 | ((null master) | |
1205 | (error "Need a filename for this buffer. Please save it first.")) | |
1206 | ((or (file-exists-p master) | |
1207 | (reftex-get-buffer-visiting master)) | |
1208 | ;; We either see the file, or have a buffer on it. OK. | |
1209 | ) | |
1210 | ((or (file-exists-p (concat master ".tex")) | |
1211 | (reftex-get-buffer-visiting (concat master ".tex"))) | |
1212 | ;; Ahh, an extra .tex was missing... | |
1213 | (setq master (concat master ".tex"))) | |
1214 | (t | |
1215 | ;; Something is wrong here. Throw an exception. | |
1216 | (error "No such master file %s" master))) | |
1217 | (expand-file-name master))) | |
1218 | ||
1219 | (defun reftex-make-master-buffer (master-file mode) | |
1220 | "Make a master buffer which contains the MASTER-FILE and all includes. | |
1221 | This is to prepare a buffer containing the entire document in correct | |
1222 | sequence for parsing. Therefore it will even expand includes which are | |
1223 | commented out. | |
1224 | The function returns the number of input/include files not found." | |
1225 | ||
1226 | (interactive "fmaster file: ") | |
1227 | (let ((not-found 0) file file-list tmp (font-lock-maximum-size 1)) | |
1228 | (switch-to-buffer "*reftex-master.tex*") | |
1229 | (erase-buffer) | |
1230 | (if (not (eq major-mode mode)) | |
1231 | (funcall mode)) | |
1232 | ;; first insert the master file | |
1233 | (if (not (file-exists-p master-file)) | |
1234 | (error "No such master file: %s" master-file)) | |
1235 | (reftex-insert-buffer-or-file master-file) | |
1236 | (subst-char-in-region (point-min) (point-max) ?\r ?\n t) | |
1237 | (setq file-list (cons master-file file-list)) | |
1238 | (goto-char 1) | |
1239 | ;; remember from which file these lines came | |
1240 | (put-text-property (point-min) (point-max) 'file | |
1241 | (expand-file-name master-file)) | |
1242 | ;; Now find recursively all include/input statements and expand them | |
1243 | (while (re-search-forward | |
1244 | "^[ \t]*\\\\\\(include\\|input\\){\\([^}\n]+\\)}" nil t) | |
1245 | ;; Change default directory, so that relative fine names work correctly | |
1246 | (setq file (reftex-no-props (match-string 2))) | |
1247 | (save-match-data | |
1248 | (cd (file-name-directory | |
1249 | (get-text-property (match-beginning 0) 'file))) | |
1250 | (if (not (string-match "\\.tex$" file)) | |
1251 | (setq file (concat file ".tex")))) | |
1252 | (if (file-exists-p file) | |
1253 | (progn | |
1254 | (replace-match | |
1255 | (format "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% START OF %s FILE: %s\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% END OF %s FILE: %s\n" | |
1256 | (match-string 1) file | |
1257 | (match-string 1) file)) | |
1258 | (beginning-of-line 0) | |
1259 | (narrow-to-region (point) (point)) | |
1260 | ;; insert the file | |
1261 | (reftex-insert-buffer-or-file file) | |
1262 | (subst-char-in-region (point-min) (point-max) ?\r ?\n t) | |
1263 | (setq file-list (cons (expand-file-name file) file-list)) | |
1264 | ;; remember from which file these lines came | |
1265 | (put-text-property (point-min) (point-max) | |
1266 | 'file (expand-file-name file)) | |
1267 | (goto-char (point-min)) | |
1268 | (widen)) | |
1269 | (message "Input/include file %s not found. Ignored. Continuing..." | |
1270 | file) | |
1271 | (setq not-found (1+ not-found)))) | |
1272 | (setq file-list (nreverse file-list)) | |
1273 | (while (setq tmp (assoc (car file-list) reftex-master-include-list)) | |
1274 | (setq reftex-master-include-list (delq tmp reftex-master-include-list))) | |
1275 | (setq reftex-master-include-list (cons file-list reftex-master-include-list)) | |
1276 | not-found)) | |
1277 | ||
1278 | (defun reftex-insert-buffer-or-file (file) | |
1279 | "If there is a buffer associated with FILE, insert it - otherwise the FILE." | |
1280 | (let ((buffer (reftex-get-buffer-visiting file))) | |
1281 | (if buffer | |
1282 | (let (beg end beg1 end1) | |
1283 | (save-excursion | |
1284 | ;; make sure we get the whole buffer | |
1285 | (set-buffer buffer) | |
1286 | (setq beg (point-min) end (point-max)) | |
1287 | (widen) | |
1288 | (setq beg1 (point-min) end1 (point-max))) | |
1289 | (insert-buffer-substring buffer beg1 end1) | |
1290 | (save-excursion | |
1291 | (set-buffer buffer) | |
1292 | (narrow-to-region beg end))) | |
1293 | (insert-file-contents file)))) | |
1294 | ||
1295 | ||
1296 | (defun reftex-parse-document (&optional buffer) | |
1297 | "Rescan the document." | |
1298 | (interactive) | |
1299 | (save-window-excursion | |
1300 | (save-excursion | |
1301 | (if buffer | |
1302 | (if (not (bufferp buffer)) | |
1303 | (error "No such buffer %s" (buffer-name buffer)) | |
1304 | (set-buffer buffer))) | |
1305 | (reftex-access-scan-info t)))) | |
1306 | ||
1307 | (defun reftex-access-scan-info (&optional rescan) | |
1308 | ;; Access the scanning info. When the multifile symbols are not yet tied, | |
1309 | ;; tie them. When they are have to be created, do a buffer scan to | |
1310 | ;; fill them. | |
1311 | ||
1312 | ;; If RESCAN is non-nil, enforce document scanning | |
1313 | ||
1314 | (catch 'exit | |
1315 | (let ((rescan (or (equal rescan t) (equal rescan '(4))))) | |
1316 | ||
1317 | ;; Reset the mode if we had changes from style hooks | |
1318 | (and reftex-tables-dirty | |
1319 | (reftex-reset-mode)) | |
1320 | ||
1321 | (if (eq reftex-list-of-labels-symbol nil) | |
1322 | ;; Symbols are not yet tied: Tie them and see if they are set | |
1323 | (reftex-tie-multifile-symbols)) | |
1324 | ||
1325 | (if (and (symbol-value reftex-list-of-labels-symbol) | |
1326 | (not rescan)) | |
1327 | ;; Lists do already exist and we don't need to rescan. | |
1328 | ;; Return from here. | |
1329 | (throw 'exit t)) | |
1330 | ||
1331 | ;; We need to rescan | |
1332 | ;; ================= | |
1333 | ||
1334 | (unwind-protect | |
1335 | (save-window-excursion | |
1336 | (save-excursion | |
1337 | ||
1338 | ;; do the scanning | |
1339 | ||
1340 | (let ((label-list-symbol reftex-list-of-labels-symbol) | |
1341 | (label-numbers-symbol reftex-label-numbers-symbol) | |
1342 | (bibfile-list-symbol reftex-bibfile-list-symbol)) | |
1343 | ||
1344 | (message "Creating master buffer...") | |
1345 | (reftex-make-master-buffer (reftex-TeX-master-file) major-mode) | |
1346 | ||
1347 | (message "Scanning document...") | |
1348 | ||
1349 | (reftex-scan-buffer-for-labels | |
1350 | label-numbers-symbol label-list-symbol) | |
1351 | ||
1352 | (reftex-scan-buffer-for-bibliography-statement | |
1353 | bibfile-list-symbol) | |
1354 | ||
1355 | (message "Scanning document... done")))) | |
1356 | ||
1357 | (if (get-buffer "*reftex-master.tex*") | |
1358 | (kill-buffer "*reftex-master.tex*")))))) | |
1359 | ||
1360 | (defun reftex-create-tags-file () | |
1361 | "Create TAGS file by running `etags' on the current document. | |
1362 | The TAGS file is also immediately visited with `visit-tags-table." | |
1363 | (interactive) | |
1364 | (reftex-access-scan-info current-prefix-arg) | |
1365 | (let* ((master (reftex-TeX-master-file)) | |
1366 | (files (assoc master reftex-master-include-list)) | |
1367 | (cmd (format "etags %s" (mapconcat 'identity files " ")))) | |
1368 | (save-excursion | |
1369 | (set-buffer (reftex-get-buffer-visiting master)) | |
1370 | (message "Running etags to create TAGS file...") | |
1371 | (shell-command cmd) | |
1372 | (visit-tags-table "TAGS")))) | |
1373 | ||
1374 | ;; History of grep commands. | |
1375 | (defvar reftex-grep-history nil) | |
1376 | (defvar reftex-grep-command "grep -n " | |
1377 | "Last grep command used in \\[reftex-grep-document]; default for next grep.") | |
1378 | ||
1379 | (defun reftex-grep-document (grep-cmd) | |
1380 | "Run grep query through all files related to this document. | |
1381 | With prefix arg, force to rescan document. | |
1382 | This works also without an active TAGS table." | |
1383 | ||
1384 | (interactive | |
1385 | (list (read-from-minibuffer "Run grep on document (like this): " | |
1386 | reftex-grep-command nil nil | |
1387 | 'reftex-grep-history))) | |
1388 | (reftex-access-scan-info current-prefix-arg) | |
1389 | (let* ((master (reftex-TeX-master-file)) | |
1390 | (default-directory (file-name-directory master)) | |
1391 | (re (format "\\`%s\\(.*\\)" (regexp-quote | |
1392 | (expand-file-name default-directory)))) | |
1393 | (files (assoc master reftex-master-include-list)) | |
1394 | (cmd (format | |
1395 | "%s %s" grep-cmd | |
1396 | (mapconcat (function (lambda (x) | |
1397 | (if (string-match re x) | |
1398 | (match-string 1 x) | |
1399 | x))) | |
1400 | files " ")))) | |
1401 | (grep cmd))) | |
1402 | ||
1403 | (defun reftex-search-document (&optional regexp) | |
1404 | "Regexp search through all files of the current TeX document. | |
1405 | Starts always in the master file. Stops when a match is found. | |
1406 | To continue searching for next match, use command \\[tags-loop-continue]. | |
1407 | This works also without an active TAGS table." | |
1408 | (interactive) | |
1409 | (let ((default (reftex-this-word))) | |
1410 | (if (not regexp) | |
1411 | (setq regexp (read-string (format "Search regexp in document [%s]: " | |
1412 | default)))) | |
1413 | (if (string= regexp "") (setq regexp (regexp-quote default))) | |
1414 | ||
1415 | (reftex-access-scan-info current-prefix-arg) | |
1416 | (tags-search regexp (list 'assoc (reftex-TeX-master-file) | |
1417 | 'reftex-master-include-list)))) | |
1418 | ||
1419 | (defun reftex-query-replace-document (&optional from to delimited) | |
1420 | "Run a query-replace-regexp of FROM with TO over the entire TeX document. | |
1421 | Third arg DELIMITED (prefix arg) means replace only word-delimited matches. | |
1422 | If you exit (\\[keyboard-quit] or ESC), you can resume the query replace | |
1423 | with the command \\[tags-loop-continue]. | |
1424 | This works also without an active TAGS table." | |
1425 | (interactive) | |
1426 | (let ((default (reftex-this-word))) | |
1427 | (if (not from) | |
1428 | (progn | |
1429 | (setq from (read-string (format "Replace regexp in document [%s]: " | |
1430 | default))) | |
1431 | (if (string= from "") (setq from (regexp-quote default))))) | |
1432 | (if (not to) | |
1433 | (setq to (read-string (format "Replace regexp %s with: " from)))) | |
1434 | (reftex-access-scan-info current-prefix-arg) | |
1435 | (tags-query-replace from to (or delimited current-prefix-arg) | |
1436 | (list 'assoc (reftex-TeX-master-file) | |
1437 | 'reftex-master-include-list)))) | |
1438 | ||
1439 | (defun reftex-change-label (&optional from to) | |
1440 | "Query replace FROM with TO in all \\label{} and \\ref{} commands. | |
1441 | Works on the entire multifile document. | |
1442 | If you exit (\\[keyboard-quit] or ESC), you can resume the query replace | |
1443 | with the command \\[tags-loop-continue]. | |
1444 | This works also without an active TAGS table." | |
1445 | (interactive) | |
1446 | (let ((default (reftex-this-word "-a-zA-Z0-9_*.:"))) | |
1447 | (if (not from) | |
1448 | (setq from (read-string (format "Replace label globally [%s]: " | |
1449 | default)))) | |
1450 | (if (string= from "") (setq from default)) | |
1451 | (if (not to) | |
1452 | (setq to (read-string (format "Replace label %s with: " | |
1453 | from)))) | |
1454 | (reftex-query-replace-document | |
1455 | (concat "\\\\\\(label\\|[a-z]*ref\\){" (regexp-quote from) "}") | |
1456 | (format "\\\\\\1{%s}" to)))) | |
1457 | ||
1458 | (defun reftex-this-word (&optional class) | |
1459 | ;; grab the word around point | |
1460 | (setq class (or class "-a-zA-Z0-9:_/.*;|")) | |
1461 | (save-excursion | |
1462 | (buffer-substring-no-properties | |
1463 | (progn (skip-chars-backward class) (point)) | |
1464 | (progn (skip-chars-forward class) (point))))) | |
1465 | ||
1466 | ;;; =========================================================================== | |
1467 | ;;; | |
1468 | ;;; Functions to create and reference automatic labels | |
1469 | ||
1470 | ;; The following constants are derived from reftex-label-alist | |
1471 | ||
1472 | ;; Prompt used for label type querys directed to the user | |
1473 | (defconst reftex-type-query-prompt nil) | |
1474 | ||
1475 | ;; Help string for label type querys | |
1476 | (defconst reftex-type-query-help nil) | |
1477 | ||
1478 | ;; Alist relating label type to reference format | |
1479 | (defconst reftex-typekey-to-format-alist nil) | |
1480 | ||
1481 | ;; Alist relating label type to label affix | |
1482 | (defconst reftex-typekey-to-prefix-alist nil) | |
1483 | ||
1484 | ;; Alist relating environments or macros to label type and context regexp | |
1485 | (defconst reftex-env-or-mac-alist nil) | |
1486 | ||
1487 | ;; List of macros carrying a label | |
1488 | (defconst reftex-label-mac-list nil) | |
1489 | ||
1490 | ;; List of environments carrying a label | |
1491 | (defconst reftex-label-env-list nil) | |
1492 | ||
1493 | ;; List of all typekey letters in use | |
1494 | (defconst reftex-typekey-list nil) | |
1495 | ||
1496 | ;; Alist relating magic words to a label type | |
1497 | (defconst reftex-words-to-typekey-alist nil) | |
1498 | ||
1499 | ;; The last list-of-labels entry used in a reference | |
1500 | (defvar reftex-last-used-reference (list nil nil nil nil)) | |
1501 | ||
1502 | ;; The regular expression used to abbreviate words | |
1503 | (defconst reftex-abbrev-regexp | |
1504 | (concat | |
1505 | "^\\(" | |
1506 | (make-string (nth 0 reftex-abbrev-parameters) ?.) | |
1507 | "[" (nth 2 reftex-abbrev-parameters) "]*" | |
1508 | "\\)" | |
1509 | "[" (nth 3 reftex-abbrev-parameters) "]" | |
1510 | (make-string (1- (nth 1 reftex-abbrev-parameters)) ?.))) | |
1511 | ||
1512 | ;; Global variables used for communication between functions | |
1513 | (defvar reftex-default-context-position nil) | |
1514 | (defvar reftex-location-start nil) | |
1515 | (defvar reftex-call-back-to-this-buffer nil) | |
1516 | ||
1517 | ;; List of buffers created temporarily for lookup, which should be killed | |
1518 | (defvar reftex-buffers-to-kill nil) | |
1519 | ||
1520 | ;; The regexp used to find section statements | |
1521 | (defconst reftex-section-regexp "^[ ]*\\\\\\(part\\|chapter\\|section\\|subsection\\|subsubsection\\|paragraph\\|subparagraph\\|subsubparagraph\\)\\*?\\(\\[[^]]*\\]\\)?{") | |
1522 | ||
1523 | ;; LaTeX section commands and level numbers | |
1524 | (defconst reftex-section-levels | |
1525 | '( | |
1526 | ("part" . 0) | |
1527 | ("chapter" . 1) | |
1528 | ("section" . 2) | |
1529 | ("subsection" . 3) | |
1530 | ("subsubsection" . 4) | |
1531 | ("paragraph" . 5) | |
1532 | ("subparagraph" . 6) | |
1533 | ("subsubparagraph" . 7) | |
1534 | )) | |
1535 | ||
1536 | (defun reftex-label (&optional environment no-insert) | |
1537 | "Insert a unique label. Return the label. | |
1538 | If ENVIRONMENT is given, don't bother to find out yourself. | |
1539 | If NO-INSERT is non-nil, do not insert label into buffer. | |
1540 | With prefix arg, force to rescan document first. | |
1541 | The label is also inserted into the label list. | |
1542 | This function is controlled by the settings of reftex-insert-label-flags." | |
1543 | ||
1544 | (interactive) | |
1545 | ||
1546 | ;; Ensure access to scanning info and rescan buffer if prefix are is '(4) | |
1547 | (reftex-access-scan-info current-prefix-arg) | |
1548 | ||
1549 | ;; Find out what kind of environment this is and abort if necessary | |
1550 | (if (or (not environment) | |
1551 | (not (assoc environment reftex-env-or-mac-alist))) | |
1552 | (setq environment (reftex-label-location))) | |
1553 | (if (not environment) | |
1554 | (error "Can't figure out what kind of label should be inserted")) | |
1555 | ||
1556 | ;; Ok, go ahead | |
1557 | (let (label num typekey prefix entry cell lab valid default force-prompt) | |
1558 | (setq typekey (nth 1 (assoc environment | |
1559 | reftex-env-or-mac-alist))) | |
1560 | (setq prefix (or (cdr (assoc typekey reftex-typekey-to-prefix-alist)) | |
1561 | (concat typekey "-"))) | |
1562 | ||
1563 | ;; make a default label | |
1564 | (cond | |
1565 | ||
1566 | ((reftex-typekey-check typekey (nth 0 reftex-insert-label-flags)) | |
1567 | ;; derive a label from context | |
1568 | (setq default (nth 2 (reftex-label-info " "))) | |
1569 | ;; catch the cases where the is actually no context available | |
1570 | (if (or (string-match "NO MATCH FOR CONTEXT REGEXP" default) | |
1571 | (string-match "ILLEGAL VALUE OF PARSE" default) | |
1572 | (string-match "SECTION HEADING NOT FOUND" default) | |
1573 | (string-match "HOOK ERROR" default) | |
1574 | (string-match "^[ \t]*$" default)) | |
1575 | (setq default prefix | |
1576 | force-prompt t) ; need to prompt | |
1577 | (setq default (concat prefix (reftex-string-to-label default))) | |
1578 | ||
1579 | ;; make it unique | |
1580 | (setq label default) | |
1581 | (setq num 1) | |
1582 | (while (assoc label (symbol-value reftex-list-of-labels-symbol)) | |
1583 | (setq label (concat default "-" (setq num (1+ num))))) | |
1584 | (setq default label))) | |
1585 | ||
1586 | ((reftex-typekey-check typekey (nth 1 reftex-insert-label-flags)) ; prompt | |
1587 | ;; Minimal default: the user will be prompted | |
1588 | (setq default prefix)) | |
1589 | ||
1590 | (t | |
1591 | ;; make an automatic label | |
1592 | (while (assoc | |
1593 | (setq default (concat prefix (reftex-next-label-number typekey))) | |
1594 | (symbol-value reftex-list-of-labels-symbol))))) | |
1595 | ||
1596 | ;; Should we ask the user? | |
1597 | (if (or (reftex-typekey-check typekey | |
1598 | (nth 1 reftex-insert-label-flags)) ; prompt | |
1599 | force-prompt) | |
1600 | ||
1601 | (while (not valid) | |
1602 | ;; iterate until we get a legal label | |
1603 | ||
1604 | (setq label (read-string "Label: " default)) | |
1605 | ||
1606 | ;; Lets make sure that this is a legal label | |
1607 | (cond | |
1608 | ||
1609 | ;; Test if label contains strange characters | |
1610 | ((string-match reftex-label-illegal-re label) | |
1611 | (message "Label \"%s\" contains illegal characters" label) | |
1612 | (ding) | |
1613 | (sit-for 2)) | |
1614 | ||
1615 | ;; Look it up in the label list | |
1616 | ((setq entry (assoc label | |
1617 | (symbol-value reftex-list-of-labels-symbol))) | |
1618 | (message "Label \"%s\" exists in file %s" label (nth 3 entry)) | |
1619 | (ding) | |
1620 | (sit-for 2)) | |
1621 | ||
1622 | ;; Label is ok | |
1623 | (t | |
1624 | (setq valid t)))) | |
1625 | (setq label default)) | |
1626 | ||
1627 | ;; Insert the label | |
1628 | (if (not no-insert) | |
1629 | (insert "\\label{" label "}")) | |
1630 | ||
1631 | ;; Insert the label into the label list | |
1632 | (if (symbol-value reftex-list-of-labels-symbol) | |
1633 | (let ((cnt 0) | |
1634 | (pos (point)) | |
1635 | (all (symbol-value reftex-list-of-labels-symbol)) | |
1636 | (look-for nil) | |
1637 | (note nil) | |
1638 | (text nil) | |
1639 | (file (buffer-file-name))) | |
1640 | ||
1641 | ;; find the previous label in order to know where to insert new label | |
1642 | ;; into label list | |
1643 | (save-excursion | |
1644 | (if (re-search-backward "\\\\label{\\([^}]+\\)}" nil 1 2) | |
1645 | (setq look-for (reftex-no-props (match-string 1)))) | |
1646 | (if (or (re-search-forward | |
1647 | "\\\\\\(include\\|input\\){[^}\n]+}" pos t) | |
1648 | (re-search-forward reftex-section-regexp pos t) | |
1649 | (null look-for)) | |
1650 | (setq note "POSITION UNCERTAIN. RESCAN TO FIX."))) | |
1651 | (if (not look-for) | |
1652 | (set reftex-list-of-labels-symbol | |
1653 | (cons (list label typekey text file note) | |
1654 | (symbol-value reftex-list-of-labels-symbol))) | |
1655 | (while all | |
1656 | (setq cell (car all) | |
1657 | all (cdr all) | |
1658 | cnt (1+ cnt) | |
1659 | lab (nth 0 cell)) | |
1660 | (if (string= lab look-for) | |
1661 | (progn | |
1662 | (setcdr | |
1663 | (nthcdr (1- cnt) | |
1664 | (symbol-value reftex-list-of-labels-symbol)) | |
1665 | (cons (list label typekey text file note) | |
1666 | (nthcdr | |
1667 | cnt (symbol-value reftex-list-of-labels-symbol)))) | |
1668 | ;; to end the loop, set all to nil | |
1669 | (setq all nil))))))) | |
1670 | ;; return value of the function is the label | |
1671 | label)) | |
1672 | ||
1673 | (defun reftex-string-to-label (string) | |
1674 | ;; Convert a string (a sentence) to a label. | |
1675 | ;; | |
1676 | ;; Uses reftex-derive-label-parameters and reftex-abbrev-parameters | |
1677 | ;; | |
1678 | ||
1679 | (let* ((words0 (reftex-split "[- \t\n\r]+" | |
1680 | (reftex-no-props string))) | |
1681 | (ignore-words (nth 5 reftex-derive-label-parameters)) | |
1682 | words word) | |
1683 | ||
1684 | ;; remove words from the ignore list or with funny characters | |
1685 | (while words0 | |
1686 | (setq word (car words0) words0 (cdr words0)) | |
1687 | (cond | |
1688 | ((member (downcase word) ignore-words)) | |
1689 | ((string-match reftex-label-illegal-re word) | |
1690 | (if (nth 2 reftex-derive-label-parameters) | |
1691 | (progn | |
1692 | (while (string-match reftex-label-illegal-re word) | |
1693 | (setq word (replace-match "" nil nil word))) | |
1694 | (setq words (cons word words))))) | |
1695 | (t | |
1696 | (setq words (cons word words))))) | |
1697 | (setq words (nreverse words)) | |
1698 | ||
1699 | ;; restrict number of words | |
1700 | (if (> (length words) (nth 0 reftex-derive-label-parameters)) | |
1701 | (setcdr (nthcdr (1- (nth 0 reftex-derive-label-parameters)) words) nil)) | |
1702 | ||
1703 | ;; First, try to use all words | |
1704 | (setq string (mapconcat '(lambda(w) w) words | |
1705 | (nth 4 reftex-derive-label-parameters))) | |
1706 | ||
1707 | ;; Abbreviate words if enforced by user settings or string length | |
1708 | (if (or (eq t (nth 3 reftex-derive-label-parameters)) | |
1709 | (and (nth 3 reftex-derive-label-parameters) | |
1710 | (> (length string) (nth 1 reftex-derive-label-parameters)))) | |
1711 | (setq words | |
1712 | (mapcar | |
1713 | '(lambda (w) (if (string-match reftex-abbrev-regexp w) | |
1714 | (match-string 1 w) | |
1715 | w)) | |
1716 | words) | |
1717 | string (mapconcat '(lambda(w) w) words | |
1718 | (nth 4 reftex-derive-label-parameters)))) | |
1719 | ||
1720 | ;; Shorten if still to long | |
1721 | (setq string | |
1722 | (if (> (length string) (nth 1 reftex-derive-label-parameters)) | |
1723 | (substring string 0 (nth 1 reftex-derive-label-parameters)) | |
1724 | string)) | |
1725 | ||
1726 | ;; Delete the final punctuation, if any | |
1727 | (if (string-match "[^a-zA-Z0-9]+$" string) | |
1728 | (setq string (replace-match "" nil nil string))) | |
1729 | string)) | |
1730 | ||
1731 | (defun reftex-label-location (&optional bound) | |
1732 | ;; Return the environment or macro which determines the label type at point. | |
1733 | ;; If optional BOUND is an integer, limit backward searches to that point. | |
1734 | ||
1735 | (let* ((loc1 (reftex-what-macro reftex-label-mac-list bound)) | |
1736 | (loc2 (reftex-what-environment reftex-label-env-list bound)) | |
1737 | (p1 (or (cdr loc1) 0)) | |
1738 | (p2 (or (cdr loc2) 0))) | |
1739 | ||
1740 | (setq reftex-location-start (max p1 p2)) | |
1741 | (if (> p1 p2) | |
1742 | (progn | |
1743 | (setq reftex-default-context-position p1) | |
1744 | (car loc1)) | |
1745 | (setq reftex-default-context-position | |
1746 | (+ p2 8 (length (car loc2)))) | |
1747 | (or (car loc2) "section")))) | |
1748 | ||
1749 | ||
1750 | (defun reftex-next-label-number (type) | |
1751 | ;; Increment value of automatic labels in current buffer. Return new value. | |
1752 | ||
1753 | ;; Ensure access to scanning info | |
1754 | (reftex-access-scan-info) | |
1755 | ||
1756 | (let ((n (cdr (assoc type (symbol-value reftex-label-numbers-symbol))))) | |
1757 | (if (not (integerp n)) | |
1758 | ;; oops - type not known - make one here | |
1759 | (progn | |
1760 | (set reftex-label-numbers-symbol | |
1761 | (cons (cons type 0) | |
1762 | (symbol-value reftex-label-numbers-symbol))) | |
1763 | (setq n 0))) | |
1764 | (setq n (1+ n)) | |
1765 | (setcdr (assoc type (symbol-value reftex-label-numbers-symbol)) n) | |
1766 | n)) | |
1767 | ||
1768 | ;; Help string for the reference label menu | |
1769 | (defconst reftex-reference-label-help | |
1770 | " AVAILABLE KEYS IN REFERENCE LABEL MENU | |
1771 | ====================================== | |
1772 | n / p Go to next/previous label (Cursor motion works as well) | |
1773 | r / s Rescan document for labels / Switch label type | |
1774 | t / # Toggle table of contents / Toggle counter mode | |
1775 | c Toggle display of short context | |
1776 | SPACE Show full context for current label in other window | |
1777 | f Toggle follow mode: other window will follow context | |
1778 | a / q Use last referenced label / Quit without accepting label | |
1779 | ? / C-r Display this help message / Recursive Edit into other window | |
1780 | RETURN Accept current label") | |
1781 | ||
1782 | (defun reftex-reference (&optional type no-insert) | |
1783 | "Make a LaTeX reference. Look only for labels of a certain TYPE. | |
1784 | With prefix arg, force to rescan buffer for labels. This should only be | |
1785 | necessary if you have recently entered labels yourself without using | |
1786 | reftex-label. Rescanning of the buffer can also be requested from the | |
1787 | label selection menu. | |
1788 | The function returns the selected label or nil. | |
1789 | If NO-INSERT is non-nil, do not insert \\ref{} command, just return label. | |
1790 | When called with 2 C-u prefix args, disable magic word recognition." | |
1791 | ||
1792 | (interactive) | |
1793 | ||
1794 | ;; check for active recursive edits | |
1795 | (reftex-check-recursive-edit) | |
1796 | ||
1797 | ;; Ensure access to scanning info and rescan buffer if prefix are is '(4) | |
1798 | (reftex-access-scan-info current-prefix-arg) | |
1799 | ||
1800 | (if (not type) | |
1801 | ;; guess type from context | |
1802 | (if (and reftex-guess-label-type | |
1803 | (not (= 16 (prefix-numeric-value current-prefix-arg))) | |
1804 | (setq type (assoc (downcase (reftex-word-before-point)) | |
1805 | reftex-words-to-typekey-alist))) | |
1806 | (setq type (cdr type)) | |
1807 | (setq type (reftex-query-label-type)))) | |
1808 | ||
1809 | (let (label pair | |
1810 | (form (or (cdr (assoc type reftex-typekey-to-format-alist)) | |
1811 | "\\ref{%s}"))) | |
1812 | ||
1813 | ;; Have the user select a label | |
1814 | (setq pair (reftex-offer-label-menu type)) | |
1815 | (setq label (car pair)) | |
1816 | ||
1817 | (if (and label | |
1818 | (not no-insert)) | |
1819 | (progn | |
1820 | ;; do we need to remove spaces? | |
1821 | (if (string= "~" (substring form 0 1)) | |
1822 | (while (or (= (preceding-char) ?\ ) | |
1823 | (= (preceding-char) ?\C-i)) | |
1824 | (backward-delete-char 1))) | |
1825 | ;; ok, insert the reference | |
1826 | (insert (format form label label)) | |
1827 | (message "")) | |
1828 | (message "Quit")) | |
1829 | ;; return the label | |
1830 | label)) | |
1831 | ||
1832 | (defun reftex-goto-label (&optional arg) | |
1833 | "Go to a LaTeX label. With prefix ARG: go to label in another window." | |
1834 | (interactive "P") | |
1835 | (let (type label file pair) | |
1836 | (if (not type) | |
1837 | (setq type (reftex-query-label-type))) | |
1838 | ||
1839 | (setq pair (reftex-offer-label-menu type) | |
1840 | label (car pair) | |
1841 | file (cdr pair)) | |
1842 | (if (and label file (file-exists-p file)) | |
1843 | (progn | |
1844 | (if arg | |
1845 | (find-file-other-window file) | |
1846 | (find-file file)) | |
1847 | (goto-char (point-min)) | |
1848 | (if (not (search-forward (concat "\\label{" label "}") nil t)) | |
1849 | (error "No such label found: %s" label) | |
1850 | (reftex-highlight 0 (match-beginning 0) (match-end 0)) | |
1851 | (add-hook 'pre-command-hook 'reftex-highlight-shall-die))) | |
1852 | (message "Quit") | |
1853 | nil))) | |
1854 | ||
1855 | ;; Internal list with index numbers of labels in the selection menu | |
1856 | (defvar reftex-label-index-list nil) | |
1857 | ||
1858 | (defun reftex-offer-label-menu (typekey) | |
1859 | ;; Offer a menu with the appropriate labels. Return (label . file). | |
1860 | (let* ((buf (current-buffer)) | |
1861 | (near-label (reftex-find-nearby-label)) | |
1862 | (toc (reftex-typekey-check typekey reftex-label-menu-flags 0)) | |
1863 | (context (not (reftex-typekey-check | |
1864 | typekey reftex-label-menu-flags 3))) | |
1865 | (counter (reftex-typekey-check | |
1866 | typekey reftex-label-menu-flags 2)) | |
1867 | (follow (reftex-typekey-check | |
1868 | typekey reftex-label-menu-flags 4)) | |
1869 | offset rtn key cnt entry) | |
1870 | ||
1871 | (setq reftex-call-back-to-this-buffer buf) | |
1872 | (setq entry (cons nil nil)) | |
1873 | ||
1874 | (unwind-protect | |
1875 | (catch 'exit | |
1876 | (while t | |
1877 | (save-window-excursion | |
1878 | (switch-to-buffer-other-window "*RefTeX Select*") | |
1879 | (erase-buffer) | |
1880 | (setq truncate-lines t) | |
1881 | (setq reftex-label-index-list (reftex-make-and-insert-label-list | |
1882 | typekey buf toc context counter | |
1883 | near-label)) | |
1884 | (setq near-label "_ ") ; turn off search for near label | |
1885 | (setq offset (or (car reftex-label-index-list) offset)) | |
1886 | ;; use only when searched | |
1887 | (setq reftex-label-index-list (cdr reftex-label-index-list)) | |
1888 | ;; only this is the true list | |
1889 | (if (not reftex-label-index-list) | |
1890 | (error "No labels of type \"%s\"" typekey)) | |
1891 | (setq rtn | |
1892 | (reftex-select-item | |
1893 | nil | |
1894 | "Label: [n]ext [p]rev [r]escan [t]oc [ ]context [q]uit RETURN [?]HELP+more" | |
1895 | "^>" | |
1896 | "\n[^.]" | |
1897 | 2 | |
1898 | reftex-reference-label-help | |
1899 | '(?r ?c ?t ?s ?# ?a) | |
1900 | offset | |
1901 | 'reftex-select-label-callback follow)) | |
1902 | (setq key (car rtn) | |
1903 | cnt (cdr rtn) | |
1904 | offset (1+ cnt)) | |
1905 | (if (not key) (throw 'exit nil)) | |
1906 | (cond | |
1907 | ((equal key ?r) | |
1908 | ;; rescan buffer | |
1909 | (reftex-parse-document buf)) | |
1910 | ((equal key ?c) | |
1911 | ;; toggle context mode | |
1912 | (setq context (not context))) | |
1913 | ((equal key ?s) | |
1914 | ;; switch type | |
1915 | (setq typekey (reftex-query-label-type))) | |
1916 | ((equal key ?t) | |
1917 | ;; toggle tabel of contents display | |
1918 | (setq toc (not toc))) | |
1919 | ((equal key ?#) | |
1920 | ;; toggle counter display | |
1921 | (setq counter (not counter))) | |
1922 | ((equal key ?a) | |
1923 | ;; reuse the last referenced label again | |
1924 | (setq entry reftex-last-used-reference) | |
1925 | (throw 'exit t)) | |
1926 | (t | |
1927 | (set-buffer buf) | |
1928 | (setq entry (nth (nth cnt reftex-label-index-list) | |
1929 | (symbol-value reftex-list-of-labels-symbol))) | |
1930 | (setq reftex-last-used-reference entry) | |
1931 | (throw 'exit t)))))) | |
1932 | (kill-buffer "*RefTeX Select*") | |
1933 | (reftex-kill-temporary-buffers)) | |
1934 | (cons (reftex-no-props (nth 0 entry)) (nth 3 entry)))) | |
1935 | ||
1936 | ;; Indentation for table of context lines in the menu | |
1937 | (defconst reftex-toc-indent " ") | |
1938 | ;; Indentation for the lines containing the label | |
1939 | (defconst reftex-label-indent "> ") | |
1940 | ;; Indentation for context lines | |
1941 | (defconst reftex-context-indent ". ") | |
1942 | ;; Indentation per section level | |
1943 | (defvar reftex-level-indent 2 | |
1944 | "*Number of spaces to be used for indentation per section level. | |
1945 | With more indentation, the label menu looks nicer, but shows less context. | |
1946 | Changing this is only fully operational after the next buffer scan.") | |
1947 | ||
1948 | (defun reftex-make-and-insert-label-list (typekey0 buf toc context | |
1949 | counter near-label) | |
1950 | ;; Insert a menu of all labels in buffer BUF into current buffer. | |
1951 | ;; Return the list of labels, with the index of NEAR-LABEL as extra car. | |
1952 | (let (ins-list index-list offset) | |
1953 | (save-excursion | |
1954 | (set-buffer buf) | |
1955 | (let* ((all nil) | |
1956 | (font (reftex-use-fonts)) | |
1957 | (cnt 0) | |
1958 | (file nil) | |
1959 | (index -1) | |
1960 | (toc-indent reftex-toc-indent) | |
1961 | (label-indent | |
1962 | (concat reftex-label-indent | |
1963 | (if toc (make-string (* 7 reftex-level-indent) ?\ ) ""))) | |
1964 | (context-indent | |
1965 | (concat reftex-context-indent | |
1966 | (if toc (make-string (* 7 reftex-level-indent) ?\ ) ""))) | |
1967 | cell text label typekey note comment) | |
1968 | ||
1969 | ; Ensure access to scanning info | |
1970 | (reftex-access-scan-info) | |
1971 | ||
1972 | (setq all (symbol-value reftex-list-of-labels-symbol)) | |
1973 | ||
1974 | (while all | |
1975 | ||
1976 | (setq index (1+ index) | |
1977 | cell (car all) | |
1978 | all (cdr all)) | |
1979 | ||
1980 | (if (null (nth 2 cell)) | |
1981 | ;; No context yet. Quick update | |
1982 | (progn | |
1983 | (setq cell (reftex-label-info-update cell)) | |
1984 | (setcar (nthcdr index | |
1985 | (symbol-value reftex-list-of-labels-symbol)) | |
1986 | cell))) | |
1987 | ||
1988 | ;; in the following setq we *copy* the label, since we will change | |
1989 | ;; its properties, and we cannot have any properties in the list | |
1990 | ;; (because of assoc searches) | |
1991 | (setq label (copy-sequence (nth 0 cell)) | |
1992 | typekey (nth 1 cell) | |
1993 | text (nth 2 cell) | |
1994 | file (nth 3 cell) | |
1995 | note (nth 4 cell) | |
1996 | comment (get-text-property 0 'in-comment text)) | |
1997 | ||
1998 | (if (string= label near-label) | |
1999 | (setq offset (1+ cnt))) | |
2000 | ||
2001 | (cond | |
2002 | ((and toc (string= typekey "toc")) | |
2003 | (setq ins-list | |
2004 | (cons (concat toc-indent text "\n") | |
2005 | ins-list))) | |
2006 | ((string= typekey "toc")) | |
2007 | ((and (or (string= typekey typekey0) (string= typekey0 " ")) | |
2008 | (or (nth 5 reftex-label-menu-flags) ; show-commented? | |
2009 | (null comment))) | |
2010 | (setq cnt (1+ cnt)) | |
2011 | (if comment (setq label (concat "% " label))) | |
2012 | (if font | |
2013 | (put-text-property | |
2014 | 0 (length label) | |
2015 | 'face | |
2016 | (if comment | |
2017 | 'font-lock-comment-face | |
2018 | 'font-lock-reference-face) | |
2019 | label)) | |
2020 | (setq index-list (cons index index-list)) | |
2021 | (setq ins-list | |
2022 | (cons (concat | |
2023 | label-indent | |
2024 | label | |
2025 | (if counter (format " (%d) " cnt)) | |
2026 | (if comment " LABEL IS COMMENTED OUT ") | |
2027 | (if note (concat " " note) "") | |
2028 | "\n" | |
2029 | (if context (concat context-indent text "\n"))) | |
2030 | ins-list)))) | |
2031 | ))) | |
2032 | ||
2033 | (apply 'insert (nreverse ins-list)) | |
2034 | (cons offset (nreverse index-list)))) | |
2035 | ||
2036 | (defun reftex-query-label-type () | |
2037 | ;; Ask for label type | |
2038 | (message reftex-type-query-prompt) | |
2039 | (let ((key (read-char))) | |
2040 | (if (equal key ?\?) | |
2041 | (progn | |
2042 | (save-window-excursion | |
2043 | (with-output-to-temp-buffer "*RefTeX Help*" | |
2044 | (princ reftex-type-query-help)) | |
2045 | (setq key (read-char)) | |
2046 | (kill-buffer "*RefTeX Help*")))) | |
2047 | (if (not (member (char-to-string key) reftex-typekey-list)) | |
2048 | (error "No such label type: %s" (char-to-string key))) | |
2049 | (char-to-string key))) | |
2050 | ||
2051 | (defun reftex-find-nearby-label () | |
2052 | ;; Find a nearby label. | |
2053 | (save-excursion | |
2054 | (if (or (re-search-backward "\\\\label{\\([^}]+\\)}" nil t) | |
2055 | (re-search-forward "\\\\label{\\([^}]+\\)}" nil t)) | |
2056 | (reftex-no-props (match-string 1)) | |
2057 | nil))) | |
2058 | ||
2059 | ;; Variable holding the vector with section numbers | |
2060 | (defvar reftex-section-numbers [0 0 0 0 0 0 0 0]) | |
2061 | ||
2062 | (defun reftex-scan-buffer-for-labels (label-numbers-symbol label-list-symbol) | |
2063 | ;; Scan the buffer for labels and save them in a list. | |
2064 | (save-excursion | |
2065 | (let ((regexp (concat "\\\\label{\\([^}]*\\)}" "\\|" | |
2066 | reftex-section-regexp)) | |
2067 | (font (reftex-use-fonts)) | |
2068 | (bound 0) | |
2069 | (highest-level 100) | |
2070 | file (level 1) start star text text1 label section-number macro find) | |
2071 | (set label-list-symbol nil) | |
2072 | (goto-char 0) | |
2073 | ||
2074 | ;; reset label numbers | |
2075 | (set label-numbers-symbol | |
2076 | (mapcar '(lambda(x) (cons x 0)) reftex-typekey-list)) | |
2077 | ||
2078 | ;; reset section numbers | |
2079 | (reftex-section-number reftex-section-numbers -1) | |
2080 | ||
2081 | (while (re-search-forward regexp nil t) | |
2082 | (setq file (get-text-property (match-beginning 0) 'file)) | |
2083 | (if (string= (buffer-substring (match-beginning 0) | |
2084 | (+ 7 (match-beginning 0))) "\\label{") | |
2085 | ;; It is a label | |
2086 | (progn | |
2087 | (setq label (reftex-no-props (match-string 1))) | |
2088 | (set label-list-symbol | |
2089 | (cons (reftex-label-info label file bound) | |
2090 | (symbol-value label-list-symbol)))) | |
2091 | ||
2092 | ;; It is a section | |
2093 | (setq bound (point)) | |
2094 | (setq star (= ?* (char-after (match-end 2)))) | |
2095 | (setq find (buffer-substring-no-properties | |
2096 | (1- (match-beginning 2)) (match-end 0))) | |
2097 | (setq macro (reftex-no-props (match-string 2))) | |
2098 | (setq level (cdr (assoc macro reftex-section-levels))) | |
2099 | ||
2100 | (setq section-number (reftex-section-number | |
2101 | reftex-section-numbers level star)) | |
2102 | (setq highest-level (min highest-level level)) | |
2103 | (if (= level highest-level) | |
2104 | (message | |
2105 | "Scanning %s %s ..." | |
2106 | (car (nth level reftex-section-levels)) | |
2107 | section-number)) | |
2108 | ||
2109 | ;; get the title | |
2110 | (save-match-data | |
2111 | (setq text1 (reftex-context-substring)) | |
2112 | (setq text (reftex-nicify-text text1))) | |
2113 | ||
2114 | (setq find (reftex-allow-for-ctrl-m (concat find text1))) | |
2115 | ||
2116 | ;; add section number and indentation | |
2117 | (setq text | |
2118 | (concat | |
2119 | (make-string (* reftex-level-indent level) ?\ ) | |
2120 | (if (nth 1 reftex-label-menu-flags) ; section number flag | |
2121 | (concat section-number " ")) | |
2122 | text)) | |
2123 | ;; fontify | |
2124 | (if font (put-text-property 0 (length text) | |
2125 | 'face 'font-lock-comment-face text)) | |
2126 | ||
2127 | ;; insert in list | |
2128 | (set label-list-symbol | |
2129 | (cons (list nil "toc" text file find) | |
2130 | (symbol-value label-list-symbol))))) | |
2131 | (set label-list-symbol | |
2132 | (nreverse (symbol-value label-list-symbol)))))) | |
2133 | ||
2134 | ||
2135 | (defun reftex-label-info-update (cell) | |
2136 | ;; Update information about just one label in a different file. | |
2137 | ;; CELL contains the old info list | |
2138 | (let* ((label (nth 0 cell)) | |
2139 | (typekey (nth 1 cell)) | |
2140 | (text (nth 2 cell)) | |
2141 | (file (nth 3 cell)) | |
2142 | (note (nth 4 cell)) | |
2143 | (buf (reftex-get-file-buffer-force | |
2144 | file (not reftex-keep-temporary-buffers)))) | |
2145 | (if (not buf) | |
2146 | (list label typekey "" file "LOST LABEL. RESCAN TO FIX.") | |
2147 | (save-excursion | |
2148 | (set-buffer buf) | |
2149 | (save-restriction | |
2150 | (widen) | |
2151 | (goto-char 1) | |
2152 | ||
2153 | (if (re-search-forward (concat "\\\\label{" (regexp-quote label) "}") | |
2154 | nil t) | |
2155 | (append (reftex-label-info label file) (list note)) | |
2156 | (list label typekey "" file "LOST LABEL. RESCAN TO FIX."))))))) | |
2157 | ||
2158 | (defun reftex-label-info (label &optional file bound) | |
2159 | ;; Return info list on LABEL at point. | |
2160 | (let* ((env-or-mac (reftex-label-location bound)) | |
2161 | (typekey (nth 1 (assoc env-or-mac reftex-env-or-mac-alist))) | |
2162 | (file (or file (buffer-file-name))) | |
2163 | (parse (if (reftex-typekey-check | |
2164 | typekey reftex-use-text-after-label-as-context) | |
2165 | nil | |
2166 | (nth 2 (assoc env-or-mac reftex-env-or-mac-alist)))) | |
2167 | (text (reftex-short-context env-or-mac parse reftex-location-start))) | |
2168 | (if (reftex-in-comment) | |
2169 | (put-text-property 0 1 'in-comment t text)) | |
2170 | (list label typekey text file))) | |
2171 | ||
2172 | (defun reftex-in-comment () | |
2173 | (save-excursion | |
2174 | (skip-chars-backward "^%\n\r") | |
2175 | (= (preceding-char) ?%))) | |
2176 | ||
2177 | (defun reftex-short-context (env parse &optional bound) | |
2178 | ;; Get about one line of useful context for the label definition at point. | |
2179 | ||
2180 | (reftex-nicify-text | |
2181 | ||
2182 | (cond | |
2183 | ||
2184 | ((null parse) | |
2185 | (save-excursion | |
2186 | (reftex-context-substring))) | |
2187 | ||
2188 | ((eq parse t) | |
2189 | (if (string= env "section") | |
2190 | ;; special treatment for section labels | |
2191 | (save-excursion | |
2192 | (if (re-search-backward reftex-section-regexp (point-min) t) | |
2193 | (progn | |
2194 | (goto-char (match-end 0)) | |
2195 | (reftex-context-substring)) | |
2196 | "SECTION HEADING NOT FOUND")) | |
2197 | (save-excursion | |
2198 | (goto-char reftex-default-context-position) | |
2199 | (reftex-context-substring)))) | |
2200 | ||
2201 | ((stringp parse) | |
2202 | (save-excursion | |
2203 | (if (re-search-backward parse bound t) | |
2204 | (progn | |
2205 | (goto-char (match-end 0)) | |
2206 | (reftex-context-substring)) | |
2207 | "NO MATCH FOR CONTEXT REGEXP"))) | |
2208 | ((fboundp parse) | |
2209 | ;; A hook function. Call it. | |
2210 | (save-excursion | |
2211 | (condition-case error-var | |
2212 | (funcall parse env) | |
2213 | ('error (format "HOOK ERROR: %s" (cdr error-var)))))) | |
2214 | (t | |
2215 | "ILLEGAL VALUE OF PARSE")))) | |
2216 | ||
2217 | (defun reftex-context-substring () | |
2218 | ;; Return up to 100 chars from point | |
2219 | ;; When point is just after a { or [, limit string to matching parenthesis | |
2220 | (cond | |
2221 | ((or (= (preceding-char) ?\{) | |
2222 | (= (preceding-char) ?\[)) | |
2223 | ;; inside a list - get only the list, with modified syntax to be perfect | |
2224 | (buffer-substring | |
2225 | (point) | |
2226 | (min (+ 100 (point)) | |
2227 | (point-max) | |
2228 | (condition-case nil | |
2229 | (progn | |
2230 | (up-list 1) | |
2231 | (1- (point))) | |
2232 | ('error (point-max)))))) | |
2233 | (t | |
2234 | ;; no list - just grab 100 characters | |
2235 | (buffer-substring (point) (min (+ 100 (point)) (point-max)))))) | |
2236 | ||
2237 | (defun reftex-section-number (section-numbers &optional level star) | |
2238 | ;; Return a string with the current section number. | |
2239 | ;; When LEVEL is non-nil, increase section numbers on that level. | |
2240 | (let* ((depth 6) idx n (string "")) | |
2241 | (if level | |
2242 | (progn | |
2243 | (if (and (> level -1) (not star)) | |
2244 | (aset section-numbers level (1+ (aref section-numbers level)))) | |
2245 | (setq idx (1+ level)) | |
2246 | (while (<= idx depth) | |
2247 | (aset section-numbers idx 0) | |
2248 | (setq idx (1+ idx))))) | |
2249 | (setq idx 0) | |
2250 | (while (<= idx depth) | |
2251 | (setq n (aref section-numbers idx)) | |
2252 | (setq string (concat string (if (not (string= string "")) "." "") | |
2253 | (int-to-string n))) | |
2254 | (setq idx (1+ idx))) | |
2255 | (save-match-data | |
2256 | (if (string-match "\\`\\(0\\.\\)+" string) | |
2257 | (setq string (replace-match "" nil nil string))) | |
2258 | (if (string-match "\\(\\.0\\)+\\'" string) | |
2259 | (setq string (replace-match "" nil nil string)))) | |
2260 | (if star | |
2261 | (concat (make-string (1- (length string)) ?\ ) "*") | |
2262 | string))) | |
2263 | ||
2264 | ;; A variable to remember the index of the last label context shown | |
2265 | (defvar reftex-last-cnt 0) | |
2266 | ||
2267 | (defun reftex-select-label-callback (cnt) | |
2268 | ;; Callback function called from the label selection in order to | |
2269 | ;; show context in another window | |
2270 | (let* ((this-window (selected-window)) | |
2271 | index entry label file buffer) | |
2272 | ;; pop to original buffer in order to get correct variables | |
2273 | (catch 'exit | |
2274 | (save-excursion | |
2275 | (set-buffer reftex-call-back-to-this-buffer) | |
2276 | (setq index (nth (or cnt 1) reftex-label-index-list) | |
2277 | entry (nth index (symbol-value reftex-list-of-labels-symbol)) | |
2278 | label (nth 0 entry) | |
2279 | file (nth 3 entry))) | |
2280 | ||
2281 | ;; goto the file in another window | |
2282 | (setq buffer (reftex-get-file-buffer-force | |
2283 | file (not reftex-keep-temporary-buffers))) | |
2284 | (if buffer | |
2285 | ;; good - the file is available | |
2286 | (switch-to-buffer-other-window buffer) | |
2287 | ;; we have got a problem here. The file does not exist. | |
2288 | ;; Let' get out of here.. | |
2289 | (ding) | |
2290 | (throw 'exit nil)) | |
2291 | ||
2292 | ||
2293 | ;; search for that label | |
2294 | (if (not (and (integerp cnt) | |
2295 | (integerp reftex-last-cnt) | |
2296 | (if (> cnt reftex-last-cnt) | |
2297 | (search-forward (concat "\\label{" label "}") nil t) | |
2298 | (search-backward (concat "\\label{" label "}") nil t)))) | |
2299 | (progn | |
2300 | (goto-char 1) | |
2301 | (search-forward (concat "\\label{" label "}") nil t))) | |
2302 | (reftex-highlight 0 (match-beginning 0) (match-end 0)) | |
2303 | (reftex-show-entry) | |
2304 | (recenter (/ (window-height) 2)) | |
2305 | (select-window this-window)))) | |
2306 | ||
2307 | (defun reftex-pop-to-label (label file-list &optional mark-to-kill highlight) | |
2308 | ;; Find LABEL in any file in FILE-LIST in another window. | |
2309 | ;; If mark-to-kill is non-nil, mark new buffer for killing. | |
2310 | ;; If HIGHLIGHT is non-nil, highlight the label definition. | |
2311 | (let* ((re (concat "\\\\label{" (regexp-quote label) "}")) | |
2312 | file buf) | |
2313 | (catch 'exit | |
2314 | (while file-list | |
2315 | (setq file (car file-list) | |
2316 | file-list (cdr file-list)) | |
2317 | (if (not (setq buf (reftex-get-file-buffer-force file mark-to-kill))) | |
2318 | (error "No such file %s" file)) | |
2319 | (set-buffer buf) | |
2320 | (widen) | |
2321 | (goto-char (point-min)) | |
2322 | (if (re-search-forward re nil t) | |
2323 | (progn | |
2324 | (switch-to-buffer-other-window buf) | |
2325 | (goto-char (match-beginning 0)) | |
2326 | (recenter (/ (window-height) 2)) | |
2327 | (if highlight | |
2328 | (reftex-highlight 0 (match-beginning 0) (match-end 0))) | |
2329 | (throw 'exit (selected-window))))) | |
2330 | (error "Label %s not found" label)))) | |
2331 | ||
2332 | (defun reftex-find-duplicate-labels () | |
2333 | "Produce a list of all duplicate labels in the document." | |
2334 | ||
2335 | (interactive) | |
2336 | ||
2337 | ;; Rescan the document to make sure | |
2338 | (reftex-access-scan-info t) | |
2339 | ||
2340 | (let ((master (reftex-TeX-master-file)) | |
2341 | (dlist | |
2342 | (mapcar | |
2343 | '(lambda(x) | |
2344 | (let (x1) | |
2345 | (cond | |
2346 | ((car x) | |
2347 | (setq x1 (reftex-all-assoc-string | |
2348 | (car x) (symbol-value reftex-list-of-labels-symbol))) | |
2349 | (if (< 1 (length x1)) | |
2350 | (append (list (reftex-no-props (car x))) | |
2351 | (mapcar '(lambda(x) | |
2352 | (abbreviate-file-name (nth 3 x))) x1)) | |
2353 | (list nil))) | |
2354 | (t nil)))) | |
2355 | (reftex-uniquify (symbol-value reftex-list-of-labels-symbol))))) | |
2356 | (setq dlist (reftex-uniquify dlist)) | |
2357 | (if (null dlist) (error "No duplicate labels in document")) | |
2358 | (switch-to-buffer-other-window "*Help*") | |
2359 | (make-local-variable 'TeX-master) | |
2360 | (setq TeX-master master) | |
2361 | (erase-buffer) | |
2362 | (insert " MULTIPLE LABELS IN CURRENT DOCUMENT:\n") | |
2363 | (insert " Move point to label and type `M-x reftex-change-label'\n" | |
2364 | " This will run a query-replace on the label and its references\n") | |
2365 | (insert " LABEL FILE\n") | |
2366 | (insert " -------------------------------------------------------------\n") | |
2367 | (while dlist | |
2368 | (if (and (car (car dlist)) | |
2369 | (cdr (car dlist))) | |
2370 | (progn | |
2371 | (insert (mapconcat '(lambda(x) x) (car dlist) "\n ") "\n"))) | |
2372 | (setq dlist (cdr dlist))) | |
2373 | (goto-char (point-min)))) | |
2374 | ||
2375 | (defun reftex-all-assoc-string (key list) | |
2376 | ;; Return a list of all associations of KEY in LIST. Comparison with string= | |
2377 | (let (rtn) | |
2378 | (while list | |
2379 | (if (string= (car (car list)) key) | |
2380 | (setq rtn (cons (car list) rtn))) | |
2381 | (setq list (cdr list))) | |
2382 | (nreverse rtn))) | |
2383 | ||
2384 | (defun reftex-kill-temporary-buffers () | |
2385 | ;; Kill all buffers in the list reftex-kill-temporary-buffers. | |
2386 | (while reftex-buffers-to-kill | |
2387 | (if (bufferp (car reftex-buffers-to-kill)) | |
2388 | (progn | |
2389 | (and (buffer-modified-p (car reftex-buffers-to-kill)) | |
2390 | (y-or-n-p (format "Save file %s? " | |
2391 | (buffer-file-name | |
2392 | (car reftex-buffers-to-kill)))) | |
2393 | (save-excursion | |
2394 | (set-buffer (car reftex-buffers-to-kill)) | |
2395 | (save-buffer))) | |
2396 | (kill-buffer (car reftex-buffers-to-kill)))) | |
2397 | (setq reftex-buffers-to-kill (cdr reftex-buffers-to-kill)))) | |
2398 | ||
2399 | (defun reftex-show-entry () | |
2400 | ;; Show entry if point is hidden by outline mode | |
2401 | (let ((pos (point))) | |
2402 | (if (and reftex-auto-show-entry | |
2403 | (boundp 'outline-minor-mode) | |
2404 | outline-minor-mode | |
2405 | (looking-at "[^\n\r]*\r")) | |
2406 | (progn | |
2407 | (outline-back-to-heading) | |
2408 | (show-entry) | |
2409 | (goto-char pos))))) | |
2410 | ||
2411 | ||
2412 | (defun reftex-nicify-text (text) | |
2413 | ;; Make TEXT nice for inclusion into label menu | |
2414 | (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text) ; remove extra whitespace | |
2415 | (setq text (replace-match " " nil t text))) | |
2416 | (if (string-match "\\\\end{.*" text) ; nothing beyond \end{ | |
2417 | (setq text (replace-match "" nil t text))) | |
2418 | (if (string-match "\\\\label{[^}]*}" text) ; kill the label | |
2419 | (setq text (replace-match "" nil t text))) | |
2420 | (if (string-match "^ +" text) ; leading whitespace | |
2421 | (setq text (replace-match "" nil t text))) | |
2422 | (cond | |
2423 | ((> (length text) 100) ; not to long | |
2424 | (setq text (substring text 0 100))) | |
2425 | ((= (length text) 0) ; not empty | |
2426 | (setq text " "))) | |
2427 | text) | |
2428 | ||
2429 | (defun reftex-typekey-check (typekey conf-variable &optional n) | |
2430 | ;; Check if CONF-VARIABLE is true or contains TYPEKEY | |
2431 | (and n (setq conf-variable (nth n conf-variable))) | |
2432 | (or (equal conf-variable t) | |
2433 | (and (stringp conf-variable) | |
2434 | (string-match (concat "[" conf-variable "]") typekey)))) | |
2435 | ||
2436 | ;;; =========================================================================== | |
2437 | ;;; | |
2438 | ;;; Table of contents (contributed from Stephen Eglen, changed by C. Dominik) | |
2439 | ||
2440 | ;; We keep at most one *toc* buffer - it is easy to make them | |
2441 | ||
2442 | (defvar reftex-last-toc-master nil | |
2443 | "Stores the name of the tex file that `reftex-toc' was last run on.") | |
2444 | ||
2445 | (defvar reftex-last-toc-file nil | |
2446 | "Stores the file name from which `reftex-toc' was called. For redo command.") | |
2447 | ||
2448 | (defvar reftex-toc-return-marker (make-marker) | |
2449 | "Marker which makes it possible to return from toc to old position.") | |
2450 | ||
2451 | (defun reftex-toc () | |
2452 | "Show the table of contents for the current document. | |
2453 | To see the corresponding part of the LaTeX document, use within the | |
2454 | *toc* buffer: | |
2455 | ||
2456 | SPC Show the corresponding section of the LaTeX document | |
2457 | RET Goto the section and hide the *toc* buffer | |
2458 | q Hide the *toc* window and return to position of last reftex-toc command | |
2459 | Q Kill the *toc* buffer and return to position of last reftex-toc command | |
2460 | f Toggle follow mode on and off | |
2461 | ||
2462 | When called with a raw C-u prefix, rescan the document first." | |
2463 | ||
2464 | (interactive) | |
2465 | ||
2466 | (and (not (string= reftex-last-toc-master (reftex-TeX-master-file))) | |
2467 | (get-buffer "*toc*") | |
2468 | (kill-buffer "*toc*")) | |
2469 | ||
2470 | (setq reftex-last-toc-file (buffer-file-name)) | |
2471 | (setq reftex-last-toc-master (reftex-TeX-master-file)) | |
2472 | ||
2473 | (set-marker reftex-toc-return-marker (point)) | |
2474 | ||
2475 | ;; if follow mode is active, arrange to delay it one command | |
2476 | (if reftex-toc-follow-mode | |
2477 | (setq reftex-toc-follow-mode 1)) | |
2478 | ||
2479 | (if (and current-prefix-arg | |
2480 | (get-buffer "*toc*")) | |
2481 | (kill-buffer "*toc*")) | |
2482 | ||
2483 | ;; Ensure access to scanning info and rescan buffer if prefix are is '(4) | |
2484 | (reftex-access-scan-info current-prefix-arg) | |
2485 | ||
2486 | (let* ((all (symbol-value reftex-list-of-labels-symbol)) | |
2487 | (where (reftex-nearest-section)) | |
2488 | toc toc1 cell label file find startpos) | |
2489 | ||
2490 | (if (and (get-buffer "*toc*") | |
2491 | (get-buffer-window (get-buffer "*toc*"))) | |
2492 | (select-window (get-buffer-window (get-buffer "*toc*"))) | |
2493 | (delete-other-windows) | |
2494 | (switch-to-buffer-other-window (current-buffer)) | |
2495 | (switch-to-buffer-other-window (get-buffer-create "*toc*"))) | |
2496 | ||
2497 | (cond | |
2498 | ;; buffer is empty - fill it with the table of contents | |
2499 | ((= (buffer-size) 0) | |
2500 | ||
2501 | (local-set-key " " 'reftex-toc-view-line) | |
2502 | (local-set-key "\C-m" 'reftex-toc-goto-line-and-hide) | |
2503 | (local-set-key "r" 'reftex-toc-redo) | |
2504 | (local-set-key "q" 'reftex-toc-quit) | |
2505 | (local-set-key "Q" 'reftex-toc-quit-and-kill) | |
2506 | (local-set-key "f" 'reftex-toc-toggle-follow) | |
2507 | (setq truncate-lines t) | |
2508 | (make-local-hook 'post-command-hook) | |
2509 | (make-local-hook 'pre-command-hook) | |
2510 | (setq post-command-hook '(reftex-toc-post-command-hook)) | |
2511 | (setq pre-command-hook '(reftex-toc-pre-command-hook)) | |
2512 | ||
2513 | (insert (format | |
2514 | "TABLE-OF-CONTENTS on %s | |
2515 | MENU: SPC=view RET=goto [q]uit [Q]uit+kill [r]escan [f]ollow-mode on/off | |
2516 | ------------------------------------------------------------------------------- | |
2517 | " (abbreviate-file-name reftex-last-toc-master))) | |
2518 | (setq startpos (point)) | |
2519 | ||
2520 | (if (reftex-use-fonts) | |
2521 | (put-text-property 1 (point) 'face 'font-lock-keyword-face)) | |
2522 | (put-text-property 1 (point) 'intangible t) | |
2523 | ||
2524 | (while all | |
2525 | (setq cell (car all) | |
2526 | all (cdr all)) | |
2527 | (setq label (nth 0 cell) | |
2528 | toc (nth 2 cell) | |
2529 | file (nth 3 cell) | |
2530 | find (nth 4 cell)) | |
2531 | (if (not label) | |
2532 | (progn | |
2533 | (setq toc1 (concat toc "\n")) | |
2534 | (put-text-property 0 (length toc1) | |
2535 | 'file file toc1) | |
2536 | (put-text-property 0 (length toc1) | |
2537 | 'find find toc1) | |
2538 | (insert toc1) | |
2539 | ))) | |
2540 | ||
2541 | (backward-delete-char 1) | |
2542 | ||
2543 | (setq buffer-read-only t)) | |
2544 | (t | |
2545 | (goto-line 3) | |
2546 | (beginning-of-line) | |
2547 | (setq startpos (point)))) | |
2548 | ||
2549 | ;; Find the correct section | |
2550 | (goto-char (point-max)) | |
2551 | (beginning-of-line) | |
2552 | (while (and (> (point) startpos) | |
2553 | (or (not (string= (get-text-property (point) 'file) | |
2554 | (car where))) | |
2555 | (not (string= (get-text-property (point) 'find) | |
2556 | (cdr where))))) | |
2557 | (beginning-of-line 0)))) | |
2558 | ||
2559 | (defun reftex-nearest-section () | |
2560 | ;; Return (file . find) of nearest section command | |
2561 | (let (cell label rest) | |
2562 | (save-excursion | |
2563 | (cond | |
2564 | ;; Try to find a section heading | |
2565 | ((or (re-search-backward reftex-section-regexp nil t) | |
2566 | (re-search-forward reftex-section-regexp nil t)) | |
2567 | (goto-char (match-end 0)) | |
2568 | (cons (buffer-file-name) | |
2569 | (reftex-allow-for-ctrl-m | |
2570 | (concat (buffer-substring-no-properties | |
2571 | (1- (match-beginning 1)) (match-end 0)) | |
2572 | (reftex-context-substring))))) | |
2573 | ;; Try to find a label | |
2574 | ((and (or (re-search-backward "\\\\label{\\([^}]+\\)}" nil t) | |
2575 | (re-search-forward "\\\\label{\\([^}]+\\)}" nil t)) | |
2576 | (setq label (reftex-no-props (match-string 1))) | |
2577 | (setq cell (assoc label (symbol-value | |
2578 | reftex-list-of-labels-symbol))) | |
2579 | (setq rest (memq cell (symbol-value reftex-list-of-labels-symbol))) | |
2580 | (setq cell (car (memq (assoc nil rest) rest))) | |
2581 | (null (car cell))) | |
2582 | (cons (nth 3 cell) (nth 4 cell))) | |
2583 | (t nil))))) | |
2584 | ||
2585 | (defun reftex-toc-pre-command-hook () | |
2586 | ;; used as pre command hook in *toc* buffer | |
2587 | (reftex-unhighlight 0) | |
2588 | (reftex-unhighlight 1)) | |
2589 | ||
2590 | (defun reftex-toc-post-command-hook () | |
2591 | ;; used in the post-command-hook for the *toc* buffer | |
2592 | (and (> (point) 1) | |
2593 | (save-excursion | |
2594 | (reftex-highlight 1 | |
2595 | (progn (beginning-of-line) (point)) | |
2596 | (progn (end-of-line) (point))))) | |
2597 | (cond | |
2598 | ((integerp reftex-toc-follow-mode) | |
2599 | ;; remove delayed action | |
2600 | (setq reftex-toc-follow-mode t)) | |
2601 | (reftex-toc-follow-mode | |
2602 | ;; show context in other window | |
2603 | (condition-case nil | |
2604 | (reftex-toc-visit-line) | |
2605 | ('error t))))) | |
2606 | ||
2607 | (defun reftex-toc-toggle-follow () | |
2608 | "Toggle toc-follow mode. | |
2609 | (it is not really a mode, just a flag)." | |
2610 | (interactive) | |
2611 | (setq reftex-toc-follow-mode (not reftex-toc-follow-mode))) | |
2612 | (defun reftex-toc-view-line () | |
2613 | "View document location in other window." | |
2614 | (interactive) | |
2615 | (reftex-toc-visit-line)) | |
2616 | (defun reftex-toc-goto-line-and-hide () | |
2617 | "Go to document location in other window. Hide the *toc* window." | |
2618 | (interactive) | |
2619 | (reftex-toc-visit-line 'hide)) | |
2620 | (defun reftex-toc-quit () | |
2621 | "Hide the *toc* window and do not move point." | |
2622 | (interactive) | |
2623 | (delete-window) | |
2624 | (switch-to-buffer (marker-buffer reftex-toc-return-marker)) | |
2625 | (goto-char (marker-position reftex-toc-return-marker))) | |
2626 | (defun reftex-toc-quit-and-kill () | |
2627 | "Kill the *toc* buffer." | |
2628 | (interactive) | |
2629 | (kill-buffer "*toc*") | |
2630 | (delete-window) | |
2631 | (switch-to-buffer (marker-buffer reftex-toc-return-marker)) | |
2632 | (goto-char (marker-position reftex-toc-return-marker))) | |
2633 | (defun reftex-toc-redo () | |
2634 | "Regenerate the *toc* buffer. Call only from within the *toc* buffer" | |
2635 | (interactive) | |
2636 | (switch-to-buffer (reftex-get-file-buffer-force reftex-last-toc-file)) | |
2637 | (delete-other-windows) | |
2638 | (setq current-prefix-arg '(4)) | |
2639 | (reftex-toc)) | |
2640 | ||
2641 | (defun reftex-toc-visit-line (&optional final) | |
2642 | ;; Visit the tex file corresponding to the toc entry on the current line. | |
2643 | ;; If FINAL is t, stay there | |
2644 | ;; If FINAL is 'hide, hide the *toc* window. | |
2645 | ;; Otherwise, move cursor back into *toc* window | |
2646 | ||
2647 | (let (file find beg end (toc-window (selected-window)) show-window) | |
2648 | (save-excursion | |
2649 | (beginning-of-line) | |
2650 | (setq beg (point)) | |
2651 | (end-of-line) | |
2652 | (setq end (point))) | |
2653 | ||
2654 | ;; get the file and the search string | |
2655 | (setq file (get-text-property (point) 'file)) | |
2656 | (setq find (get-text-property (point) 'find)) | |
2657 | (if (or (not file) (not find)) | |
2658 | (error "Cannot visit line")) | |
2659 | ||
2660 | (switch-to-buffer-other-window (reftex-get-file-buffer-force file)) | |
2661 | (setq show-window (selected-window)) | |
2662 | (goto-char (point-min)) | |
2663 | ||
2664 | (if (not (re-search-forward find nil t)) | |
2665 | (error "Cannot visit line")) | |
2666 | ||
2667 | (setq beg (match-beginning 0) | |
2668 | end (match-end 0)) | |
2669 | ||
2670 | (goto-char beg) | |
2671 | (recenter 1) | |
2672 | (reftex-highlight 0 beg end (current-buffer)) | |
2673 | ||
2674 | (select-window toc-window) | |
2675 | ||
2676 | ;; use the `final' parameter to decide what to do next | |
2677 | (cond | |
2678 | ((equal final t) | |
2679 | (reftex-unhighlight 0) | |
2680 | (select-window show-window)) | |
2681 | ((eq final 'hide) | |
2682 | (reftex-unhighlight 0) | |
2683 | (delete-window)) | |
2684 | (t nil)))) | |
2685 | ||
2686 | ;;; =========================================================================== | |
2687 | ;;; | |
2688 | ;;; BibTeX citations. | |
2689 | ||
2690 | ;; Variables and constants | |
2691 | ||
2692 | ;; Internal variable, but used from different functions | |
2693 | (defvar reftex-cite-format1 nil) | |
2694 | ||
2695 | ;; The history list of regular expressions used for citations | |
2696 | (defvar reftex-cite-regexp-hist nil) | |
2697 | ||
2698 | ;; Help string for citation selection | |
2699 | (defconst reftex-citation-help | |
2700 | "AVAILABLE KEYS IN MAKE CITATION MENU | |
2701 | --------------------------------------- | |
2702 | n / p Go to next/previous entry (Cursor motion works as well) | |
2703 | r restrict selection with another regexp | |
2704 | SPACE Show full database entry in other window | |
2705 | f Toggle follow mode: Other window will follow with full db entry | |
2706 | q Quit without inserting \\cite macro into buffer | |
2707 | ? Display this help message | |
2708 | C-r Recursive edit into other window | |
2709 | RETURN ... Accept current entry and insert in format according to | |
2710 | reftex-cite-format") | |
2711 | ||
2712 | (defconst reftex-cite-format-default "\\cite{KEY}" | |
2713 | "The default value for reftex-cite-format. | |
2714 | Uses the string version of scitex-cite-format.") | |
2715 | ||
2716 | (defconst reftex-cite-format-1-author-simple | |
2717 | '( "\\cite{KEY}" "AUTHOR \\cite{KEY}" "AUTHOR {\it et al.} \\cite{KEY}") | |
2718 | "Value for reftex-cite format establishing a simple citation with name | |
2719 | of the first author. | |
2720 | Uses the list version of reftex-cite-format.") | |
2721 | ||
2722 | (defconst reftex-cite-format-2-authors | |
2723 | '((?\C-m | |
2724 | . ( "\\cite{KEY}" "AUTHOR \\cite{KEY}" | |
2725 | "AUTHOR \\& AUTHOR \\cite{KEY}" "AUTHOR \\etal{} \\cite{KEY}")) | |
2726 | (?\, | |
2727 | . ("\\cite{KEY}" "AUTHOR, \\cite{KEY}" | |
2728 | "AUTHOR \\& AUTHOR, \\cite{KEY}" "AUTHOR \\etal{}, \\cite{KEY}")) | |
2729 | (?\; | |
2730 | . ("\\cite{KEY}" "AUTHOR; \\cite{KEY}" | |
2731 | "AUTHOR \\& AUTHOR; \\cite{KEY}" "AUTHOR \\etal{}; \\cite{KEY}")) | |
2732 | (?\: | |
2733 | . ("\\cite{KEY}" "AUTHOR: \\cite{KEY}" | |
2734 | "AUTHOR \\& AUTHOR: \\cite{KEY}" "AUTHOR \\etal{}: \\cite{KEY}")) | |
2735 | (?\( | |
2736 | . ("(\\cite{KEY})" "AUTHOR (\\cite{KEY})" | |
2737 | "AUTHOR \\& AUTHOR (\\cite{KEY})" "AUTHOR \\etal{} (\\cite{KEY})")) | |
2738 | (?\[ | |
2739 | . ("[\\cite{KEY}]" "AUTHOR [\\cite{KEY}]" | |
2740 | "AUTHOR \\& AUTHOR [\\cite{KEY}]" "AUTHOR \\etal{} [\\cite{KEY}]"))) | |
2741 | "Value for reftex-cite-format that estabishes an Author/Year citation | |
2742 | where the year is supplied from BibTeX. Depending on which character | |
2743 | is used during selection to accept the label, an extra ,;: or pair of | |
2744 | parenthesis will be inserted. | |
2745 | Uses the list-of-cons-cells version of reftex-cite-format.") | |
2746 | ||
2747 | ;; Find bibtex files | |
2748 | ||
2749 | (defun reftex-get-bibfile-list () | |
2750 | ;; Return list of bibfiles for current document | |
2751 | ||
2752 | ;; Ensure access to scanning info | |
2753 | (reftex-access-scan-info) | |
2754 | ||
2755 | (or (symbol-value reftex-bibfile-list-symbol) | |
2756 | (error "No BibTeX files to parse. Add \\bibliography statment to document and reparse."))) | |
2757 | ||
2758 | (defun reftex-scan-buffer-for-bibliography-statement (bib-list-symbol) | |
2759 | ;; Scan buffer for bibliography macro and store file list in bib-list-symbol. | |
2760 | (let (file-list dir-list) | |
2761 | (setq dir-list | |
2762 | (reftex-split | |
2763 | (concat path-separator "+") | |
2764 | (mapconcat '(lambda(x) | |
2765 | (if (getenv x) (getenv x) "")) | |
2766 | reftex-bibpath-environment-variables | |
2767 | path-separator))) | |
2768 | (goto-char (point-min)) | |
2769 | (if (re-search-forward "^[ \t]*\\\\bibliography{[ \t]*\\([^}]+\\)" nil t) | |
2770 | (progn | |
2771 | (setq dir-list | |
2772 | (cons (file-name-directory | |
2773 | (get-text-property (match-beginning 0) 'file)) | |
2774 | dir-list)) | |
2775 | (setq file-list | |
2776 | (mapcar '(lambda (x) (concat x ".bib")) | |
2777 | (reftex-delete-list | |
2778 | reftex-bibfile-ignore-list | |
2779 | (reftex-split | |
2780 | "[ \t\n]*,[ \t\n]*" | |
2781 | (reftex-no-props (match-string 1))))))) | |
2782 | (message "No \\bibliography command in document.")) | |
2783 | (set bib-list-symbol | |
2784 | (if file-list | |
2785 | (reftex-find-files-on-path file-list dir-list | |
2786 | "While parsing \\bibliography{}:") | |
2787 | nil)))) | |
2788 | ||
2789 | (defun reftex-find-files-on-path (file-list path-list &optional error-string) | |
2790 | ;; Search for all files in FILE-LIST on the PATH-LIST. Return absolute names. | |
2791 | ;; A missing file throws an exception with the error message ERROR-STRING. | |
2792 | (let (found-list found file) | |
2793 | (while file-list | |
2794 | (setq file (car file-list) | |
2795 | file-list (cdr file-list) | |
2796 | found nil) | |
2797 | (if (file-name-absolute-p file) | |
2798 | (setq found (expand-file-name file)) | |
2799 | (let ((dirs path-list)) | |
2800 | (while (and dirs (not found)) | |
2801 | (if (and (not (string= (car dirs) "")) | |
2802 | (file-exists-p (expand-file-name file (car dirs)))) | |
2803 | (setq found (expand-file-name file (car dirs)))) | |
2804 | (setq dirs (cdr dirs))))) | |
2805 | (if (and found | |
2806 | (file-exists-p found)) | |
2807 | (add-to-list 'found-list (expand-file-name found)) | |
2808 | (error "%s No such file %s." | |
2809 | (or error-string "") file))) | |
2810 | (nreverse found-list))) | |
2811 | ||
2812 | ;; Find a certain reference in any of the BibTeX files. | |
2813 | ||
2814 | (defun reftex-pop-to-bibtex-entry (key file-list | |
2815 | &optional mark-to-kill highlight) | |
2816 | ;; Find BibTeX KEY in any file in FILE-LIST in another window. | |
2817 | ;; If mark-to-kill is non-nil, mark new buffer to kill." | |
2818 | ||
2819 | (let* ((re (concat "@[a-zA-Z]+[ \t\n\r]*{[ \t\n\r]*" (regexp-quote key) "[ \t\n\r,]")) | |
2820 | (window-conf (current-window-configuration)) | |
2821 | file buf) | |
2822 | (catch 'exit | |
2823 | (switch-to-buffer-other-window (current-buffer)) | |
2824 | (while file-list | |
2825 | (setq file (car file-list) | |
2826 | file-list (cdr file-list)) | |
2827 | (if (not (setq buf (reftex-get-file-buffer-force file mark-to-kill))) | |
2828 | (error "No such file %s" file)) | |
2829 | (switch-to-buffer buf) | |
2830 | (widen) | |
2831 | (goto-char 0) | |
2832 | (if (re-search-forward re nil t) | |
2833 | (progn | |
2834 | (goto-char (match-beginning 0)) | |
2835 | (recenter 0) | |
2836 | (if highlight | |
2837 | (reftex-highlight 0 (match-beginning 0) (match-end 0))) | |
2838 | (throw 'exit (selected-window))))) | |
2839 | (set-window-configuration window-conf) | |
2840 | (beep) | |
2841 | (message "No BibTeX entry with citation key %s" key)))) | |
2842 | ||
2843 | ;; Parse bibtex buffers | |
2844 | ||
2845 | (defun reftex-extract-bib-entries (buffers &optional get-word) | |
2846 | ;; Extract bib entries which match regexps from BUFFERS. | |
2847 | ;; BUFFERS is a list of buffers or file names. | |
2848 | ;; Return list with entries." | |
2849 | (let* (re-list first-re rest-re | |
2850 | ;; avoid fontification of lookup buffers | |
2851 | (lazy-lock-minimum-size 1) | |
2852 | (buffer-list (if (listp buffers) buffers (list buffers))) | |
2853 | found-list entry buffer1 buffer alist | |
2854 | key-point start-point end-point) | |
2855 | ||
2856 | (setq re-list (reftex-split "[ \t]*&&[ \t]*" | |
2857 | (read-string "RegExp [ && RegExp...]: " | |
2858 | nil 'reftex-cite-regexp-hist))) | |
2859 | ||
2860 | (setq first-re (car re-list) ; We'll use the first re to find things, | |
2861 | rest-re (cdr re-list)) ; the other to narrow down. | |
2862 | (if (string-match "\\`[ \t]*\\'" first-re) | |
2863 | (error "Empty regular expression")) | |
2864 | ||
2865 | (save-excursion | |
2866 | (save-window-excursion | |
2867 | ||
2868 | ;; walk through all bibtex files | |
2869 | (while buffer-list | |
2870 | (setq buffer (car buffer-list) | |
2871 | buffer-list (cdr buffer-list)) | |
2872 | (if (and (bufferp buffer) | |
2873 | (buffer-live-p buffer)) | |
2874 | (setq buffer1 buffer) | |
2875 | (setq buffer1 (reftex-get-file-buffer-force | |
2876 | buffer (not reftex-keep-temporary-buffers)))) | |
2877 | (if (not buffer1) | |
2878 | (error "Cannot find BibTeX file %s" buffer) | |
2879 | (message "Scanning bibliography database %s" buffer1)) | |
2880 | ||
2881 | (set-buffer buffer1) | |
2882 | (save-excursion | |
2883 | (goto-char (point-min)) | |
2884 | (while (re-search-forward first-re nil t) | |
2885 | (catch 'search-again | |
2886 | (setq key-point (point)) | |
2887 | (if (not (re-search-backward | |
2888 | "^[ \t]*@\\([a-zA-Z]+\\)[ \t\n\r]*{" nil t)) | |
2889 | (throw 'search-again nil)) | |
2890 | (setq start-point (point)) | |
2891 | (goto-char (match-end 0)) | |
2892 | (condition-case nil | |
2893 | (up-list 1) | |
2894 | ('error (goto-char key-point) | |
2895 | (throw 'search-again nil))) | |
2896 | (setq end-point (point)) | |
2897 | ||
2898 | ;; Ignore @string, @comment and @c entries or things | |
2899 | ;; outside entries | |
2900 | (if (or (string= (downcase (match-string 1)) "string") | |
2901 | (string= (downcase (match-string 1)) "comment") | |
2902 | (string= (downcase (match-string 1)) "c") | |
2903 | (< (point) key-point)) ; this means match not in {} | |
2904 | (progn | |
2905 | (goto-char key-point) | |
2906 | (throw 'search-again nil))) | |
2907 | ||
2908 | ;; Well, we have got a match | |
2909 | (setq entry (concat | |
2910 | (buffer-substring start-point (point)) "\n")) | |
2911 | ||
2912 | ;; Check if other regexp match as well | |
2913 | (setq re-list rest-re) | |
2914 | (while re-list | |
2915 | (if (not (string-match (car re-list) entry)) | |
2916 | ;; nope - move on | |
2917 | (throw 'search-again nil)) | |
2918 | (setq re-list (cdr re-list))) | |
2919 | ||
2920 | (setq alist (reftex-parse-bibtex-entry | |
2921 | nil start-point end-point)) | |
2922 | (setq alist (cons (cons "&entry" entry) alist)) | |
2923 | ||
2924 | ;; check for crossref entries | |
2925 | (if (assoc "crossref" alist) | |
2926 | (setq alist | |
2927 | (append | |
2928 | alist (reftex-get-crossref-alist alist)))) | |
2929 | ||
2930 | ;; format the entry | |
2931 | (setq alist | |
2932 | (cons | |
2933 | (cons "&formatted" | |
2934 | (reftex-format-bib-entry alist)) | |
2935 | alist)) | |
2936 | ||
2937 | ;; add it to the list | |
2938 | (setq found-list (cons alist found-list))))) | |
2939 | (reftex-kill-temporary-buffers)))) | |
2940 | (setq found-list (nreverse found-list)) | |
2941 | ||
2942 | ;; Sorting | |
2943 | (cond | |
2944 | ((eq 'author reftex-sort-bibtex-matches) | |
2945 | (sort found-list 'reftex-bib-sort-author)) | |
2946 | ((eq 'year reftex-sort-bibtex-matches) | |
2947 | (sort found-list 'reftex-bib-sort-year)) | |
2948 | ((eq 'reverse-year reftex-sort-bibtex-matches) | |
2949 | (sort found-list 'reftex-bib-sort-year-reverse)) | |
2950 | (t found-list)))) | |
2951 | ||
2952 | (defun reftex-bib-sort-author (e1 e2) | |
2953 | (let ((al1 (reftex-get-bib-authors e1)) (al2 (reftex-get-bib-authors e2))) | |
2954 | (while (and al1 al2 (string= (car al1) (car al2))) | |
2955 | (setq al1 (cdr al1) | |
2956 | al2 (cdr al2))) | |
2957 | (if (and (stringp (car al1)) | |
2958 | (stringp (car al2))) | |
2959 | (string< (car al1) (car al2)) | |
2960 | (not (stringp (car al1)))))) | |
2961 | ||
2962 | (defun reftex-bib-sort-year (e1 e2) | |
2963 | (< (string-to-int (cdr (assoc "year" e1))) | |
2964 | (string-to-int (cdr (assoc "year" e2))))) | |
2965 | ||
2966 | (defun reftex-bib-sort-year-reverse (e1 e2) | |
2967 | (> (string-to-int (or (cdr (assoc "year" e1)) "0")) | |
2968 | (string-to-int (or (cdr (assoc "year" e2)) "0")))) | |
2969 | ||
2970 | (defun reftex-get-crossref-alist (entry) | |
2971 | ;; return the alist from a crossref entry | |
2972 | (let ((crkey (cdr (assoc "crossref" entry))) | |
2973 | start) | |
2974 | (save-excursion | |
2975 | (save-restriction | |
2976 | (widen) | |
2977 | (if (re-search-forward | |
2978 | (concat "@\\w+{[ \t\n\r]*" (regexp-quote crkey) "[ \t\n\r]*,") nil t) | |
2979 | (progn | |
2980 | (setq start (match-beginning 0)) | |
2981 | (condition-case nil | |
2982 | (up-list 1) | |
2983 | ('error nil)) | |
2984 | (reftex-parse-bibtex-entry nil start (point))) | |
2985 | nil))))) | |
2986 | ||
2987 | ;; Parse and format individual entries | |
2988 | ||
2989 | (defun reftex-get-bib-authors (entry) | |
2990 | ;; Return a list with the author names in ENTRY | |
2991 | (let (authors) | |
2992 | (setq authors (reftex-get-bib-field "author" entry)) | |
2993 | (if (equal "" authors) | |
2994 | (setq authors (reftex-get-bib-field "editor" entry))) | |
2995 | (while (string-match "\\band\\b[ \t]*" authors) | |
2996 | (setq authors (replace-match "\n" nil t authors))) | |
2997 | (while (string-match "[\\.a-zA-Z\\-]+\\.[ \t]*\\|,.*\\|[{}]+" authors) | |
2998 | (setq authors (replace-match "" nil t authors))) | |
2999 | (while (string-match "^[ \t]+\\|[ \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 | (reftex-split "\n" authors))) | |
3004 | ||
3005 | (defun reftex-parse-bibtex-entry (entry &optional from to) | |
3006 | (let (alist key start field) | |
3007 | (save-excursion | |
3008 | (save-restriction | |
3009 | (if entry | |
3010 | (progn | |
3011 | (switch-to-buffer "*RefTeX-scratch*") | |
3012 | (fundamental-mode) | |
3013 | (erase-buffer) | |
3014 | (insert entry)) | |
3015 | (widen) | |
3016 | (narrow-to-region from to)) | |
3017 | (goto-char (point-min)) | |
3018 | ||
3019 | (if (re-search-forward | |
3020 | "@\\(\\w+\\)[ \t\n\r]*{[ \t\n\r]*\\([^ \t\n\r,]+\\)" nil t) | |
3021 | (setq alist | |
3022 | (list | |
3023 | (cons "&type" (downcase (reftex-no-props (match-string 1)))) | |
3024 | (cons "&key" (reftex-no-props (match-string 2)))))) | |
3025 | (while (re-search-forward "\\(\\w+\\)[ \t\n\r]*=[ \t\n\r]*" nil t) | |
3026 | (setq key (reftex-no-props (downcase (match-string 1)))) | |
3027 | (cond | |
3028 | ((= (following-char) ?{) | |
3029 | (forward-char 1) | |
3030 | (setq start (point)) | |
3031 | (condition-case nil | |
3032 | (up-list 1) | |
3033 | ('error nil))) | |
3034 | ((= (following-char) ?\") | |
3035 | (forward-char 1) | |
3036 | (setq start (point)) | |
3037 | (while (and (search-forward "\"" nil t) | |
3038 | (= ?\\ (char-after (- (point) 2)))))) | |
3039 | (t | |
3040 | (setq start (point)) | |
3041 | (re-search-forward "[ \t\n\r,}]" nil 1))) | |
3042 | (setq field (buffer-substring-no-properties start (1- (point)))) | |
3043 | ;; remove extra whitesp | |
3044 | (while (string-match "[\n\t\r]\\|[ \t][ \t]+" field) | |
3045 | (setq field (replace-match " " nil t field))) | |
3046 | ;; remove leading garbage | |
3047 | (if (string-match "^[ \t{]+" field) | |
3048 | (setq field (replace-match "" nil t field))) | |
3049 | ;; remove trailing garbage | |
3050 | (if (string-match "[ \t}]+$" field) | |
3051 | (setq field (replace-match "" nil t field))) | |
3052 | (setq alist (cons (cons key field) alist))) | |
3053 | alist)))) | |
3054 | ||
3055 | (defun reftex-get-bib-field (fieldname entry) | |
3056 | ;; Extract the field FIELDNAME from an ENTRY | |
3057 | (or (cdr (assoc fieldname entry)) | |
3058 | "")) | |
3059 | ||
3060 | (defun reftex-format-bib-entry (entry) | |
3061 | ;; Format a BibTeX ENTRY so that it is nice to look at | |
3062 | (let* | |
3063 | ((rtn nil) | |
3064 | (auth-list (reftex-get-bib-authors entry)) | |
3065 | (authors (mapconcat '(lambda (x) x) auth-list ", ")) | |
3066 | (year (reftex-get-bib-field "year" entry)) | |
3067 | (title (reftex-get-bib-field "title" entry)) | |
3068 | (type (reftex-get-bib-field "&type" entry)) | |
3069 | (key (reftex-get-bib-field "&key" entry)) | |
3070 | (extra | |
3071 | (cond | |
3072 | ((equal type "article") | |
3073 | (concat (reftex-get-bib-field "journal" entry) " " | |
3074 | (reftex-get-bib-field "volume" entry) ", " | |
3075 | (reftex-get-bib-field "pages" entry))) | |
3076 | ((equal type "book") | |
3077 | (concat "book (" (reftex-get-bib-field "publisher" entry) ")")) | |
3078 | ((equal type "phdthesis") | |
3079 | (concat "PhD: " (reftex-get-bib-field "school" entry))) | |
3080 | ((equal type "mastersthesis") | |
3081 | (concat "Master: " (reftex-get-bib-field "school" entry))) | |
3082 | ((equal type "inbook") | |
3083 | (concat "Chap: " (reftex-get-bib-field "chapter" entry) | |
3084 | ", pp. " (reftex-get-bib-field "pages" entry))) | |
3085 | ((or (equal type "conference") | |
3086 | (equal type "incollection") | |
3087 | (equal type "inproceedings")) | |
3088 | (concat "in: " (reftex-get-bib-field "booktitle" entry))) | |
3089 | (t "")))) | |
3090 | (setq authors | |
3091 | (if (> (length authors) 30) | |
3092 | (concat (substring authors 0 27) "...") | |
3093 | (format "%-30s" authors)) | |
3094 | title | |
3095 | (if (> (length title) 70) | |
3096 | (concat (substring title 0 67) "...") | |
3097 | (format "%-70s" title)) | |
3098 | extra | |
3099 | (if (> (length extra) 40) | |
3100 | (concat (substring extra 0 37) "...") | |
3101 | (format "%-40s" extra))) | |
3102 | (if (reftex-use-fonts) | |
3103 | (progn | |
3104 | (put-text-property 0 (length authors) 'face 'font-lock-keyword-face | |
3105 | authors) | |
3106 | (put-text-property 0 (length title) 'face 'font-lock-comment-face | |
3107 | title) | |
3108 | (put-text-property 0 (length extra) 'face 'font-lock-reference-face | |
3109 | extra))) | |
3110 | (setq rtn (concat key "\n " authors " " year " " extra | |
3111 | "\n " title "\n\n")) | |
3112 | rtn)) | |
3113 | ||
3114 | ;; Make a citation | |
3115 | ||
3116 | (defun reftex-citation (&optional arg no-insert) | |
3117 | "Make a citation unsing BibTeX database files. | |
3118 | After asking for a Regular Expression, it scans the buffers with | |
3119 | bibtex entries (taken from the \\bibliography command) and offers the | |
3120 | matching entries for selection. The selected entry is formated according | |
3121 | to reftex-cite-format and inserted into the buffer. | |
3122 | If NO-INSERT is non-nil, nothing is inserted, only the selected key returned. | |
3123 | The regular expression uses an expanded syntax: && is interpreted as 'and'. | |
3124 | Thus, aaaa&&bbb matches entries which contain both aaaa and bbb. | |
3125 | When this function is called with point inside the braces of a \\cite{} | |
3126 | command, it will add another key, ignoring the value of reftex-cite-format. | |
3127 | When called with a numeric prefix, that many citations will be made and all | |
3128 | put into the same \\cite{} command. | |
3129 | When called with just C-u as prefix, enforces rescan of buffer for | |
3130 | bibliography statement (e.g. if it was changed)." | |
3131 | ||
3132 | (interactive "P") | |
3133 | ||
3134 | ;; check for recursive edit | |
3135 | (reftex-check-recursive-edit) | |
3136 | ||
3137 | ;; if there is just 1 C-u prefix arg, force to rescan buffer | |
3138 | (if (and current-prefix-arg | |
3139 | (listp current-prefix-arg) | |
3140 | (= 4 (prefix-numeric-value arg))) | |
3141 | (reftex-reset-scanning-information)) | |
3142 | ||
3143 | ;; check if there is already a cite command at point and change cite format | |
3144 | ;; in order to only add another reference in the same cite command. | |
3145 | (let ((pos (point))) | |
3146 | (search-backward "\\" (point-min) 1) | |
3147 | (if (and (looking-at "\\\\[a-zA-Z]*cite\\*?\\(\\[[^]]*\\]\\)*{\\([^}]*\\)") | |
3148 | (>= (match-end 0) pos) | |
3149 | (>= pos (match-beginning 2))) | |
3150 | (progn | |
3151 | (goto-char pos) | |
3152 | (cond | |
3153 | ((or (not arg) | |
3154 | (not (listp arg))) | |
3155 | (setq reftex-cite-format1 | |
3156 | (concat | |
3157 | (if (not (or (= (preceding-char) ?{) | |
3158 | (= (preceding-char) ?,))) | |
3159 | "," | |
3160 | "") | |
3161 | "KEY" | |
3162 | (if (not (or (= (following-char) ?}) | |
3163 | (= (following-char) ?,))) | |
3164 | "," | |
3165 | "")))) | |
3166 | (t | |
3167 | (setq reftex-cite-format1 "KEY")))) | |
3168 | (setq reftex-cite-format1 | |
3169 | (if (symbolp reftex-cite-format) | |
3170 | (symbol-value reftex-cite-format) | |
3171 | reftex-cite-format)) | |
3172 | (goto-char pos))) | |
3173 | ||
3174 | (let* (key entry cnt rtn ins-string re-list re | |
3175 | ;; scan bibtex files | |
3176 | (lazy-lock-minimum-size 1) | |
3177 | (found-list (reftex-extract-bib-entries | |
3178 | (reftex-get-bibfile-list))) | |
3179 | (found-list-r nil) | |
3180 | (accept-keys | |
3181 | (if (and (listp reftex-cite-format1) | |
3182 | (listp (car reftex-cite-format1))) | |
3183 | (mapcar 'car reftex-cite-format1) | |
3184 | '(?\C-m)))) | |
3185 | (if (not found-list) | |
3186 | (error "Sorry, no matches found")) | |
3187 | ||
3188 | ;; remember where we came from | |
3189 | (setq reftex-call-back-to-this-buffer (current-buffer)) | |
3190 | ||
3191 | ;; offer selection | |
3192 | (save-window-excursion | |
3193 | (switch-to-buffer-other-window "*RefTeX Select*") | |
3194 | (erase-buffer) | |
3195 | (mapcar '(lambda (x) (insert (cdr (assoc "&formatted" x)))) | |
3196 | found-list) | |
3197 | (if (= 0 (buffer-size)) | |
3198 | (error "Sorry, no matches found")) | |
3199 | (setq truncate-lines t) | |
3200 | (goto-char 1) | |
3201 | (if (catch 'exit | |
3202 | (while t | |
3203 | (setq rtn | |
3204 | (reftex-select-item | |
3205 | nil | |
3206 | (concat | |
3207 | "Select: [n]ext [p]rev [r]estrict [q]uit [?]Help ||" | |
3208 | " RETURN " | |
3209 | (condition-case nil | |
3210 | (mapconcat 'char-to-string accept-keys " ") | |
3211 | (error (error "Illegal reftex-cite-format")))) | |
3212 | "^[^ \t\n]" | |
3213 | "\n\n" | |
3214 | 4 | |
3215 | reftex-citation-help | |
3216 | (cons ?r accept-keys) | |
3217 | nil | |
3218 | 'reftex-bibtex-selection-callback nil)) | |
3219 | (setq key (car rtn) | |
3220 | cnt (cdr rtn)) | |
3221 | (if (not key) (throw 'exit nil)) | |
3222 | (cond | |
3223 | ((equal key ?r) | |
3224 | ;; restrict with new regular expression | |
3225 | (setq re-list | |
3226 | (reftex-split "[ \t]*&&[ \t]*" | |
3227 | (read-string "RegExp [ && RegExp...]: " | |
3228 | nil 'reftex-cite-regexp-hist))) | |
3229 | (while re-list | |
3230 | (setq re (car re-list) | |
3231 | re-list (cdr re-list)) | |
3232 | (setq found-list-r | |
3233 | (delete "" | |
3234 | (mapcar | |
3235 | '(lambda (x) | |
3236 | (if (string-match re | |
3237 | (cdr (assoc "&entry" x))) | |
3238 | x | |
3239 | "")) | |
3240 | found-list)))) | |
3241 | (if found-list-r | |
3242 | (setq found-list found-list-r) | |
3243 | (ding)) | |
3244 | (erase-buffer) | |
3245 | (mapcar '(lambda (x) (insert (cdr (assoc "&formatted" x)))) | |
3246 | found-list) | |
3247 | (goto-char 1)) | |
3248 | ((or (member key accept-keys) | |
3249 | (equal key ?\C-m) | |
3250 | (equal key 'return)) | |
3251 | (setq entry (nth cnt found-list)) | |
3252 | (throw 'exit t)) | |
3253 | (t | |
3254 | (ding))))) | |
3255 | (progn | |
3256 | ;; format the entry | |
3257 | (if (not (integerp key)) (setq key ?\C-m)) | |
3258 | (setq ins-string (reftex-format-citation entry key))) | |
3259 | (setq ins-string "") | |
3260 | (message "Quit"))) | |
3261 | (kill-buffer "*RefTeX Select*") | |
3262 | ||
3263 | (if (not no-insert) | |
3264 | (insert ins-string)) | |
3265 | (message "") | |
3266 | ||
3267 | ;; Check if the prefix arg was numeric, and call reftex-citation recursively | |
3268 | (if (and (integerp arg) | |
3269 | (> arg 1) | |
3270 | (re-search-backward | |
3271 | "\\\\[a-zA-Z]*cite\\*?\\(\\[[^]]*\\]\\)*{\\([^}]*\\)" nil t)) | |
3272 | (progn | |
3273 | (goto-char (match-end 0)) | |
3274 | (setq arg (1- arg)) | |
3275 | (reftex-citation arg)) | |
3276 | (reftex-kill-temporary-buffers)) | |
3277 | ;; Return the citation key | |
3278 | (reftex-get-bib-field "&key" entry))) | |
3279 | ||
3280 | (defun reftex-format-citation (entry key) | |
3281 | ;; Format a citation from the info in the BibTeX ENTRY | |
3282 | (let* ((cite-key (reftex-get-bib-field "&key" entry)) | |
3283 | (year (reftex-get-bib-field "year" entry)) | |
3284 | (auth-list (reftex-get-bib-authors entry)) | |
3285 | (nauthors (length auth-list)) | |
3286 | format) | |
3287 | ||
3288 | (save-excursion | |
3289 | ;; Find the correct format | |
3290 | (if (and (listp reftex-cite-format1) | |
3291 | (listp (car reftex-cite-format1))) | |
3292 | (if (integerp (car (car reftex-cite-format1))) | |
3293 | (if (assoc key reftex-cite-format1) | |
3294 | (setq format (cdr (assoc key reftex-cite-format1))) | |
3295 | (if (or (equal key ?\C-m) | |
3296 | (equal key 'return)) | |
3297 | (setq format (cdr (car reftex-cite-format1))) | |
3298 | (error "Error in reftex-cite-format"))) | |
3299 | (error "Error in reftex-cite-format")) | |
3300 | (setq format reftex-cite-format1)) | |
3301 | ||
3302 | (if (listp format) | |
3303 | (let ((nn (min nauthors (1- (length format))))) | |
3304 | (while (and (> nn 0) (string= "" (nth nn format))) | |
3305 | (setq nn (1- nn))) | |
3306 | (setq format (nth nn format)))) | |
3307 | (if (stringp format) | |
3308 | (setq format format) | |
3309 | (setq format "\\cite{KEY}")) | |
3310 | ||
3311 | ;; Insert the author names | |
3312 | (while (string-match "\\bAUTHOR\\b" format) | |
3313 | (setq format (replace-match (car auth-list) t t format)) | |
3314 | (setq auth-list (cdr auth-list))) | |
3315 | (while (string-match "\\bKEY\\b" format) | |
3316 | (setq format (replace-match cite-key t t format))) | |
3317 | (while (string-match "\\bYEAR\\b" format) | |
3318 | (setq format (replace-match year t t format))) | |
3319 | format))) | |
3320 | ||
3321 | ;; this is slow and not recommended for follow mode | |
3322 | (defun reftex-bibtex-selection-callback (cnt) | |
3323 | ;; Callback function to be called from the BibTeX selection, in | |
3324 | ;; order to display context. This function is relatively slow and not | |
3325 | ;; recommended for follow mode, just for individual lookups. | |
3326 | ;; When compiled, this gives a warning about found-list. However, | |
3327 | ;; the calling function binds found-list with let. | |
3328 | (let ((win (selected-window)) | |
3329 | (key (reftex-get-bib-field "&key" (nth cnt found-list))) | |
3330 | (bibfile-list (save-excursion | |
3331 | (set-buffer reftex-call-back-to-this-buffer) | |
3332 | (reftex-get-bibfile-list)))) | |
3333 | (reftex-pop-to-bibtex-entry key bibfile-list | |
3334 | (not reftex-keep-temporary-buffers) t) | |
3335 | (select-window win))) | |
3336 | ||
3337 | ;;; =========================================================================== | |
3338 | ;;; | |
3339 | ;;; Here is the routine used for selection | |
3340 | ||
3341 | ;; Marker for return point from recursive edit | |
3342 | (defvar reftex-recursive-edit-marker (make-marker)) | |
3343 | ||
3344 | (defun reftex-check-recursive-edit () | |
3345 | ;; Check if we are already in a recursive edit. Abort with helpful | |
3346 | ;; message if so. | |
3347 | (if (marker-position reftex-recursive-edit-marker) | |
3348 | (error | |
3349 | (substitute-command-keys | |
3350 | "In unfinished recursive edit. Finish (\\[exit-recursive-edit]) or abort (\\[abort-recursive-edit]).")))) | |
3351 | ||
3352 | (defun reftex-select-item (buffer prompt next-re end-re size help-string | |
3353 | event-list &optional offset | |
3354 | call-back cb-flag) | |
3355 | ;; Select an item from the buffer BUFFER. Show PROMPT to user, find | |
3356 | ;; next item with NEXT-RE regular expression, return on any of the | |
3357 | ;; events listed in EVENT-LIST. The function returns the event along | |
3358 | ;; with an integer indicating which item was selected. When OFFSET is | |
3359 | ;; specified, starts at that item in the list. When CALL-BACK is | |
3360 | ;; given, it is a function which is called with the match of the | |
3361 | ;; NEXT-RE match and the index of the element. | |
3362 | (let* (key key-sq b e ev cnt cmd | |
3363 | (offset1 (or offset 1))) | |
3364 | (setq ev | |
3365 | (catch 'exit | |
3366 | (save-window-excursion | |
3367 | (if buffer | |
3368 | (switch-to-buffer-other-window buffer)) | |
3369 | (if (= 0 (buffer-size)) | |
3370 | (throw 'exit nil)) | |
3371 | (setq truncate-lines t) | |
3372 | (goto-char 1) | |
3373 | (if (not (re-search-forward next-re nil t offset1)) | |
3374 | (progn ; in case the offset is illegal | |
3375 | (setq offset1 1) | |
3376 | (if (not (re-search-forward next-re nil t offset1)) | |
3377 | (throw 'exit nil)))) | |
3378 | (beginning-of-line 1) | |
3379 | (setq cnt (if offset1 (1- offset1) 0)) | |
3380 | (while t | |
3381 | (if (and cb-flag call-back) | |
3382 | (funcall call-back cnt)) | |
3383 | (setq b (point) | |
3384 | e (save-excursion | |
3385 | (save-match-data | |
3386 | (re-search-forward end-re nil 1)) | |
3387 | (point))) | |
3388 | (reftex-highlight 1 b e) | |
3389 | (if (or (not (pos-visible-in-window-p b)) | |
3390 | (not (pos-visible-in-window-p e))) | |
3391 | (recenter (/ (window-height) 2))) | |
3392 | (setq key-sq (read-key-sequence prompt)) | |
3393 | (setq key (car | |
3394 | (cond | |
3395 | ((fboundp 'listify-key-sequence) ; Emacs | |
3396 | (listify-key-sequence key-sq)) | |
3397 | ((fboundp 'event-to-character) ; XEmacs | |
3398 | (mapcar 'event-to-character key-sq)) | |
3399 | (t (error "Please report this problem to dominik@strw.leidenuniv.nl"))))) | |
3400 | ||
3401 | (setq cmd (key-binding key-sq)) | |
3402 | ||
3403 | (reftex-unhighlight 0) | |
3404 | ||
3405 | (cond | |
3406 | ||
3407 | ((or (equal key ?n) | |
3408 | (equal key ?\C-i) | |
3409 | (equal cmd 'next-line)) | |
3410 | (if (re-search-forward next-re nil t 2) | |
3411 | (setq cnt (1+ cnt))) | |
3412 | (beginning-of-line 1)) | |
3413 | ||
3414 | ((equal cmd 'scroll-up) | |
3415 | (setq cnt (1- cnt)) | |
3416 | (while (and (pos-visible-in-window-p) | |
3417 | (re-search-forward next-re nil t)) | |
3418 | (setq cnt (1+ cnt))) | |
3419 | (beginning-of-line 1) | |
3420 | (recenter 1)) | |
3421 | ||
3422 | ((or (equal key ?p) | |
3423 | (equal cmd 'previous-line)) | |
3424 | (if (re-search-backward next-re nil t) | |
3425 | (setq cnt (1- cnt)))) | |
3426 | ||
3427 | ((equal cmd 'scroll-down) | |
3428 | (while (and (pos-visible-in-window-p) | |
3429 | (re-search-backward next-re nil t)) | |
3430 | (setq cnt (1- cnt))) | |
3431 | (recenter (- (window-height) size 2))) | |
3432 | ||
3433 | ((equal key ?q) | |
3434 | (throw 'exit nil)) | |
3435 | ||
3436 | ((equal key ?\C-g) | |
3437 | (bury-buffer) | |
3438 | (error "Abort")) | |
3439 | ||
3440 | ((or (equal key ?\C-m) | |
3441 | (equal key 'return) | |
3442 | (equal cmd 'newline)) | |
3443 | (throw 'exit 'return)) | |
3444 | ||
3445 | ((or (equal key ?C) ; backward compatibility | |
3446 | (equal key ?f)) | |
3447 | (setq cb-flag (not cb-flag))) | |
3448 | ||
3449 | ((equal key ?\ ) | |
3450 | (funcall call-back cnt)) | |
3451 | ||
3452 | ((equal key ?\?) | |
3453 | (save-window-excursion | |
3454 | (with-output-to-temp-buffer "*RefTeX Help*" | |
3455 | (princ help-string)) | |
3456 | (setq unread-command-events | |
3457 | (cons | |
3458 | (cond | |
3459 | ((fboundp 'read-event) ; Emacs | |
3460 | (read-event)) | |
3461 | ((fboundp 'next-command-event) ; XEmacs | |
3462 | (next-command-event)) | |
3463 | (t (error "Please report this problem to dominik@strw.leidenuniv.nl"))) | |
3464 | nil))) | |
3465 | (kill-buffer "*RefTeX Help*")) | |
3466 | ||
3467 | ((equal key ?\C-r) | |
3468 | ;; sje - code copied from ispell.el for | |
3469 | ;; performing recursive edit | |
3470 | (set-marker reftex-recursive-edit-marker (point)) | |
3471 | (unwind-protect | |
3472 | (progn | |
3473 | (save-window-excursion | |
3474 | (save-excursion | |
3475 | (other-window 1) | |
3476 | (message | |
3477 | (substitute-command-keys | |
3478 | "Recursive edit. Return to selection with \\[exit-recursive-edit]")) | |
3479 | (recursive-edit))) | |
3480 | (if (not (equal (marker-buffer | |
3481 | reftex-recursive-edit-marker) | |
3482 | (current-buffer))) | |
3483 | (error | |
3484 | "Cannot continue RefTeX from this buffer.")) | |
3485 | (goto-char reftex-recursive-edit-marker)) | |
3486 | (set-marker reftex-recursive-edit-marker nil))) | |
3487 | ||
3488 | ((member key event-list) | |
3489 | (throw 'exit key)) | |
3490 | (t | |
3491 | (ding))))))) | |
3492 | (message "") | |
3493 | (cons ev cnt))) | |
3494 | ||
3495 | ;;; =========================================================================== | |
3496 | ;;; | |
3497 | ;;; View cross references | |
3498 | ||
3499 | (defun reftex-view-crossref (&optional arg) | |
3500 | "View cross reference of \\ref{} or \\cite{} macro at point. | |
3501 | If the macro at point is a \\ref{}, show the corresponding label definition. | |
3502 | If it is a \\cite{}, show the BibTeX database entry. | |
3503 | If there is no such macro at point, search forward to find one. | |
3504 | When you call this function several times in direct successtion, point will | |
3505 | move to view subsequent cross references further down in the buffer. | |
3506 | With argument, actually select the window showing the cross reference." | |
3507 | ||
3508 | (interactive "P") | |
3509 | ||
3510 | ;; See where we are. | |
3511 | (let* ((pos (point)) | |
3512 | (re "\\\\[a-z]*\\(cite\\|ref\\)\\(\\[[^{}]*\\]\\)?{\\([^}]+\\)}") | |
3513 | (my-window (get-buffer-window (current-buffer))) | |
3514 | pop-window cmd args macro label entry key-start point) | |
3515 | ||
3516 | (if (save-excursion | |
3517 | (forward-char 1) | |
3518 | (and (search-backward "\\" nil t) | |
3519 | (looking-at re) | |
3520 | (< pos (match-end 0)))) | |
3521 | (setq macro (match-string 1) | |
3522 | key-start (match-beginning 3))) | |
3523 | ||
3524 | (if (and macro (eq last-command this-command)) | |
3525 | (if (and (string= macro "cite") | |
3526 | (skip-chars-forward "^}, \t\n\r") | |
3527 | (= (following-char) ?,)) | |
3528 | (setq key-start (1+ (point))) | |
3529 | (setq macro nil))) | |
3530 | ||
3531 | (if (not macro) | |
3532 | (if (re-search-forward re nil t) | |
3533 | (setq macro (match-string 1) | |
3534 | key-start (match-beginning 3)) | |
3535 | (error "No further cross references in buffer"))) | |
3536 | ||
3537 | (goto-char key-start) | |
3538 | ||
3539 | ;; Ensure access to scanning info | |
3540 | (reftex-access-scan-info) | |
3541 | ||
3542 | (cond | |
3543 | ((string= macro "cite") | |
3544 | (setq cmd 'reftex-pop-to-bibtex-entry | |
3545 | args (list | |
3546 | (reftex-no-props (reftex-this-word "^{},")) | |
3547 | (reftex-get-bibfile-list) nil t))) | |
3548 | ((string= macro "ref") | |
3549 | (let ((label (reftex-no-props (reftex-this-word "^{}"))) | |
3550 | (entry (assoc label (symbol-value reftex-list-of-labels-symbol)))) | |
3551 | (if entry | |
3552 | (setq cmd 'reftex-pop-to-label | |
3553 | args (list label (list (nth 3 entry)) nil t)) | |
3554 | (error "Label %s not known - reparse document might help" label)))) | |
3555 | (t (error "This should not happen"))) | |
3556 | (setq point (point)) | |
3557 | (apply cmd args) | |
3558 | (setq pop-window (selected-window)) | |
3559 | (add-hook 'pre-command-hook 'reftex-highlight-shall-die) | |
3560 | (select-window my-window) | |
3561 | (goto-char point) | |
3562 | (and arg (select-window pop-window)))) | |
3563 | ||
3564 | (defun reftex-mouse-view-crossref (ev) | |
3565 | "View cross reference of \\ref{} or \\cite{} macro where you click. | |
3566 | If the macro at point is a \\ref{}, show the corresponding label definition. | |
3567 | If it is a \\cite{}, show the BibTeX database entry. | |
3568 | If there is no such macro at point, search forward to find one. | |
3569 | When you call this function several times in direct successtion, point will | |
3570 | move to view subsequent cross references further down in the buffer. | |
3571 | With argument, actually select the window showing the cross reference." | |
3572 | (interactive "e") | |
3573 | (mouse-set-point ev) | |
3574 | (reftex-view-crossref current-prefix-arg)) | |
3575 | ||
3576 | ;;; =========================================================================== | |
3577 | ;;; | |
3578 | ;;; Functions that check out the surroundings | |
3579 | ||
3580 | (defun reftex-what-macro (which &optional bound) | |
3581 | ;; Find out if point is within the arguments of any TeX-macro. | |
3582 | ;; The return value is either (\"\\\\macro\" . (point)) or a list of them. | |
3583 | ||
3584 | ;; If WHICH is nil, immediately return nil. | |
3585 | ;; If WHICH is t, return list of all macros enclosing point. | |
3586 | ;; If WHICH is a list of macros, look only for those macros and return the | |
3587 | ;; name of the first macro in this list found to enclose point. | |
3588 | ;; If the optional BOUND is an integer, bound backwards directed | |
3589 | ;; searches to this point. If it is nil, limit to nearest \\section - | |
3590 | ;; like statement. | |
3591 | ||
3592 | ;; This function is pretty stable, but can be fooled if the text contains | |
3593 | ;; things like \\macro{aa}{bb} where \\macro is defined to take only one | |
3594 | ;; argument. As RefTeX cannot know this, the string \"bb\" would still be | |
3595 | ;; considered an argument of macro \\macro. | |
3596 | ||
3597 | (catch 'exit | |
3598 | (if (null which) (throw 'exit nil)) | |
3599 | (let ((bound (or bound (save-excursion (re-search-backward | |
3600 | reftex-section-regexp nil 1) | |
3601 | (point)))) | |
3602 | pos cmd-list cmd) | |
3603 | (save-restriction | |
3604 | (save-excursion | |
3605 | (narrow-to-region (max 1 bound) (point-max)) | |
3606 | ;; move back out of the current parenthesis | |
3607 | (while (condition-case nil | |
3608 | (progn (up-list -1) t) | |
3609 | (error nil)) | |
3610 | ;; move back over any touching sexps | |
3611 | (while (or (= (preceding-char) ?\]) | |
3612 | (= (preceding-char) ?\})) | |
3613 | (backward-sexp)) | |
3614 | (setq pos (point)) | |
3615 | (if (and (or (= (following-char) ?\[) | |
3616 | (= (following-char) ?\{)) | |
3617 | (and (re-search-backward "\\(\\\\[a-zA-Z]+\\)" nil t) | |
3618 | (= (match-end 0) pos))) | |
3619 | (progn | |
3620 | (setq cmd (buffer-substring-no-properties | |
3621 | (match-beginning 0) (match-end 0))) | |
3622 | (if (eq t which) | |
3623 | (setq cmd-list (cons (cons cmd (point)) cmd-list)) | |
3624 | (if (member cmd which) | |
3625 | (throw 'exit (cons cmd (point))))))) | |
3626 | (goto-char pos))) | |
3627 | (nreverse cmd-list))))) | |
3628 | ||
3629 | (defun reftex-what-environment (which &optional bound) | |
3630 | ;; Find out if point is inside a LaTeX environment. | |
3631 | ;; The return value is (e.g.) either (\"equation\" . (point)) or a list of | |
3632 | ;; them. | |
3633 | ||
3634 | ;; If WHICH is nil, immediately return nil. | |
3635 | ;; If WHICH is t, return list of all environments enclosing point. | |
3636 | ;; If WHICH is a list of environments, look only for those environments and | |
3637 | ;; return the name of the first environment in this list found to enclose | |
3638 | ;; point. | |
3639 | ||
3640 | ;; If the optional BOUND is an integer, bound backwards directed searches to | |
3641 | ;; this point. If it is nil, limit to nearest \\section - like statement. | |
3642 | ||
3643 | (catch 'exit | |
3644 | (save-excursion | |
3645 | (if (null which) (throw 'exit nil)) | |
3646 | (let ((bound (or bound (save-excursion (re-search-backward | |
3647 | reftex-section-regexp nil 1) | |
3648 | (point)))) | |
3649 | env-list end-list env) | |
3650 | (while (re-search-backward "\\\\\\(begin\\|end\\){\\([^}]+\\)}" | |
3651 | bound t) | |
3652 | (setq env (buffer-substring-no-properties | |
3653 | (match-beginning 2) (match-end 2))) | |
3654 | (cond | |
3655 | ((string= (match-string 1) "end") | |
3656 | (add-to-list 'end-list env)) | |
3657 | ((member env end-list) | |
3658 | (setq end-list (delete env end-list))) | |
3659 | ((eq t which) | |
3660 | (setq env-list (cons (cons env (point)) env-list))) | |
3661 | ((member env which) | |
3662 | (throw 'exit (cons env (point)))))) | |
3663 | (nreverse env-list))))) | |
3664 | ||
3665 | (defun reftex-word-before-point () | |
3666 | ;; Return the word before point. Word means here: | |
3667 | ;; Consists of [a-zA-Z0-9.:] and ends at point or whitespace. | |
3668 | (let ((pos (point))) | |
3669 | (save-excursion | |
3670 | (re-search-backward "[^ \t\n\r]" (point-min) 1) | |
3671 | (setq pos (1+ (point))) | |
3672 | (if (re-search-backward "[^a-zA-Z0-9\\\.:]" (point-min) 1) | |
3673 | (forward-char 1)) | |
3674 | (buffer-substring-no-properties (point) pos)))) | |
3675 | ||
3676 | ;; ============================================================================ | |
3677 | ;; | |
3678 | ;; Some generally useful functions | |
3679 | ||
3680 | (defun reftex-no-props (string) | |
3681 | ;; Return STRING with all text properties removed | |
3682 | (and (stringp string) | |
3683 | (set-text-properties 0 (length string) nil string)) | |
3684 | string) | |
3685 | ||
3686 | (defun reftex-split (regexp string) | |
3687 | ;; Split like perl | |
3688 | (let ((start 0) list) | |
3689 | (while (string-match regexp string start) | |
3690 | (setq list (cons (substring string start (match-beginning 0)) list)) | |
3691 | (setq start (match-end 0))) | |
3692 | (setq list (nreverse (cons (substring string start) list))))) | |
3693 | ||
3694 | (defun reftex-allow-for-ctrl-m (string) | |
3695 | ;; convert STRING into a regexp, allowing ^M for \n | |
3696 | (let ((start -2)) | |
3697 | (setq string (regexp-quote string)) | |
3698 | (while (setq start (string-match "[\n\r]" string (+ 3 start))) | |
3699 | (setq string (replace-match "[\n\r]" nil t string))) | |
3700 | string)) | |
3701 | ||
3702 | (defun reftex-delete-list (elt-list list) | |
3703 | ;; like delete, but with a list of things to delete | |
3704 | ;; (original code from Rory Molinari) | |
3705 | (while elt-list | |
3706 | (setq list (delete (car elt-list) list) | |
3707 | elt-list (cdr elt-list))) | |
3708 | list) | |
3709 | ||
3710 | (defun reftex-get-buffer-visiting (file) | |
3711 | ;; return a buffer visiting FILE | |
3712 | (cond | |
3713 | ((fboundp 'find-buffer-visiting) ; Emacs | |
3714 | (find-buffer-visiting file)) | |
3715 | ((boundp 'find-file-compare-truenames) ; XEmacs | |
3716 | (let ((find-file-compare-truenames t)) | |
3717 | (get-file-buffer file))) | |
3718 | (t (error "Please report this problem to dominik@strw.leidenuniv.nl")))) | |
3719 | ||
3720 | (defun reftex-get-file-buffer-force (file &optional mark-to-kill) | |
3721 | ;; Return a buffer visiting file. Make one, if necessary. | |
3722 | ;; If neither such a buffer no the file exist, return nil. | |
3723 | ;; If MARK-TO-KILL in non-nil, put any new buffers into the kill list." | |
3724 | ||
3725 | (let ((buf (reftex-get-buffer-visiting file))) | |
3726 | (cond | |
3727 | (buf buf) | |
3728 | ((file-exists-p file) | |
3729 | (setq buf (find-file-noselect file)) | |
3730 | (if mark-to-kill | |
3731 | (add-to-list 'reftex-buffers-to-kill buf)) | |
3732 | buf) | |
3733 | (t nil)))) | |
3734 | ||
3735 | (defun reftex-splice-symbols-into-list (list alist) | |
3736 | ;; Splice the association in ALIST of any symbols in LIST into the list. | |
3737 | ;; Return new list. | |
3738 | (let (rtn tmp) | |
3739 | (while list | |
3740 | (while (and (not (null (car list))) | |
3741 | (symbolp (car list))) | |
3742 | (setq tmp (car list)) | |
3743 | (cond | |
3744 | ((assoc tmp alist) | |
3745 | (setq list (append (cdr (cdr (assoc tmp alist))) (cdr list)))) | |
3746 | (t | |
3747 | (error "Cannot treat symbol %s in reftex-label-alist" | |
3748 | (symbol-name tmp))))) | |
3749 | (setq rtn (cons (car list) rtn) | |
3750 | list (cdr list))) | |
3751 | (nreverse rtn))) | |
3752 | ||
3753 | (defun reftex-uniquify (alist &optional keep-list) | |
3754 | ;; Return a list of all elements in ALIST, but each car only once | |
3755 | ;; Elements of KEEP-LIST are not removed even if duplicate | |
3756 | (let (new elm) | |
3757 | (while alist | |
3758 | (setq elm (car alist) | |
3759 | alist (cdr alist)) | |
3760 | (if (or (member (car elm) keep-list) | |
3761 | (not (assoc (car elm) new))) | |
3762 | (setq new (cons elm new)))) | |
3763 | (setq new (nreverse new)) | |
3764 | new)) | |
3765 | ||
3766 | (defun reftex-use-fonts () | |
3767 | ;; Return t if we can and want to use fonts | |
3768 | (and window-system | |
3769 | reftex-use-fonts | |
3770 | (boundp 'font-lock-keyword-face))) | |
3771 | ||
3772 | ;; Highlighting uses overlays. If this is for XEmacs, we need to load | |
3773 | ;; the overlay library, available in version 19.15 | |
3774 | (and (not (fboundp 'make-overlay)) | |
3775 | (condition-case nil | |
3776 | (require 'overlay) | |
3777 | ('error | |
3778 | (error "RefTeX needs overlay emulation (available in XEmacs 19.15)")))) | |
3779 | ||
3780 | ;; We keep a vector with several different overlays to do our highlighting. | |
3781 | (defvar reftex-highlight-overlays [nil nil]) | |
3782 | ||
3783 | ;; Initialize the overlays | |
3784 | (aset reftex-highlight-overlays 0 (make-overlay 1 1)) | |
3785 | (overlay-put (aref reftex-highlight-overlays 0) 'face 'highlight) | |
3786 | (aset reftex-highlight-overlays 1 (make-overlay 1 1)) | |
3787 | (overlay-put (aref reftex-highlight-overlays 1) 'face 'highlight) | |
3788 | ||
3789 | ;; Two functions for activating and deactivation highlight overlays | |
3790 | (defun reftex-highlight (index begin end &optional buffer) | |
3791 | "Highlight a region with overlay INDEX." | |
3792 | (move-overlay (aref reftex-highlight-overlays index) | |
3793 | begin end (or buffer (current-buffer)))) | |
3794 | (defun reftex-unhighlight (index) | |
3795 | "Detatch overlay INDEX." | |
3796 | (delete-overlay (aref reftex-highlight-overlays index))) | |
3797 | ||
3798 | (defun reftex-highlight-shall-die () | |
3799 | ;; Function used in pre-command-hook to remove highlights | |
3800 | (remove-hook 'pre-command-hook 'reftex-highlight-shall-die) | |
3801 | (reftex-unhighlight 0)) | |
3802 | ||
3803 | ;;; --------------------------------------------------------------------------- | |
3804 | ;;; | |
3805 | ;;; Cursor position after insertion of forms | |
3806 | ||
3807 | (defun reftex-position-cursor () | |
3808 | ;; Search back to question mark, delete it, leave point there | |
3809 | (if (search-backward "\?" (- (point) 100) t) | |
3810 | (delete-char 1))) | |
3811 | ||
3812 | (defun reftex-item () | |
3813 | "Insert an \\item and provide a label if the environments supports that." | |
3814 | (interactive) | |
3815 | (let ((env (car | |
3816 | (reftex-what-environment '("itemize" "enumerate" "eqnarray"))))) | |
3817 | ||
3818 | (if (and env (not (bolp))) (newline)) | |
3819 | ||
3820 | (cond | |
3821 | ||
3822 | ((string= env "eqnarray") | |
3823 | (if (not (bolp)) | |
3824 | (newline)) | |
3825 | (reftex-label env) | |
3826 | (insert "\n & & ") | |
3827 | (beginning-of-line 1)) | |
3828 | ||
3829 | ((string= env "itemize") | |
3830 | (newline) | |
3831 | (insert "\\item ")) | |
3832 | ||
3833 | ((string= env "enumerate") | |
3834 | (newline) | |
3835 | (insert "\\item") | |
3836 | (reftex-label env) | |
3837 | (insert " ")) | |
3838 | (t | |
3839 | (error "\\item command does not make sense here..."))))) | |
3840 | ||
3841 | ;;; --------------------------------------------------------------------------- | |
3842 | ;;; --------------------------------------------------------------------------- | |
3843 | ;;; --------------------------------------------------------------------------- | |
3844 | ;;; | |
3845 | ;;; Data Section: Definition of large constants | |
3846 | ||
3847 | ||
3848 | (defconst reftex-label-alist-builtin | |
3849 | '( | |
3850 | (LaTeX | |
3851 | "LaTeX default environments" | |
3852 | ("section" ?s "sec:" "~\\ref{%s}" t | |
3853 | ("Part" "Chapter" "Chap." "Section" "Sec." "Sect." "Paragraph" "Par." | |
3854 | "\\S" "Teil" "Kapitel" "Kap." "Abschnitt" )) | |
3855 | ||
3856 | ("enumerate" ?n "item:" "~\\ref{%s}" "\\\\item\\(\\[[^]]*\\]\\)?" | |
3857 | ("Item" "Punkt")) | |
3858 | ||
3859 | ("equation" ?e "eq:" "~(\\ref{%s})" t | |
3860 | ("Equation" "Eq." "Eqn." "Gleichung" "Gl.")) | |
3861 | ("eqnarray" ?e "eq:" nil "\\\\begin{eqnarray}\\|\\\\\\\\") | |
3862 | ||
3863 | ("figure" ?f "fig:" "~\\ref{%s}" "\\\\caption\\(\\[[^]]*\\]\\)?{" | |
3864 | ("Figure" "Fig." "Abbildung" "Abb.")) | |
3865 | ("figure*" ?f nil nil "\\\\caption\\(\\[[^]]*\\]\\)?{") | |
3866 | ||
3867 | ("table" ?t "tab:" "~\\ref{%s}" "\\\\caption\\(\\[[^]]*\\]\\)?{" | |
3868 | ("Table" "Tab." "Tabelle")) | |
3869 | ("table*" ?t nil nil "\\\\caption\\(\\[[^]]*\\]\\)?{") | |
3870 | ||
3871 | ("any" ?\ " " "\\ref{%s}" nil)) | |
3872 | ||
3873 | (Sideways | |
3874 | "Sidewaysfigure and sidewaystable" | |
3875 | ("sidewaysfigure" ?f nil nil "\\\\caption\\(\\[[^]]*\\]\\)?{") | |
3876 | ("sidewaystable" ?t nil nil "\\\\caption\\(\\[[^]]*\\]\\)?{")) | |
3877 | ||
3878 | (AMSTeX | |
3879 | "AMS-LaTeX: amsmath package environents" | |
3880 | ("align" ?e "eq:" "~\\eqref{%s}" "\\\\begin{align}\\|\\\\\\\\") | |
3881 | ("gather" ?e "eq:" nil "\\\\begin{gather}\\|\\\\\\\\") | |
3882 | ("multline" ?e "eq:" nil t) | |
3883 | ("flalign" ?e "eq:" nil "\\\\begin{flalign}\\|\\\\\\\\") | |
3884 | ("alignat" ?e "eq:" nil "\\\\begin{alignat}{[0-9]*}\\|\\\\\\\\")) | |
3885 | ||
3886 | (AASTeX | |
3887 | "AAS deluxetable environment" | |
3888 | ("deluxetable" ?t "tab:" nil "\\\\caption{"))) | |
3889 | "The default label environment descriptions.") | |
3890 | ||
3891 | ;;; --------------------------------------------------------------------------- | |
3892 | ;;; | |
3893 | ;;; Functions to compile the tables, reset the mode etc. | |
3894 | ||
3895 | (defun reftex-reset-mode () | |
3896 | "Reset RefTeX Mode. Required to implement changes to some list variables. | |
3897 | This function will compile the information in reftex-label-alist and similar | |
3898 | variables. It is called when RefTeX is first used, and after changes to | |
3899 | these variables via reftex-add-to-label-alist." | |
3900 | (interactive) | |
3901 | ||
3902 | ; record that we have done this | |
3903 | (setq reftex-tables-dirty nil) | |
3904 | ||
3905 | ;; To update buffer-local variables | |
3906 | (hack-local-variables) | |
3907 | (message "updating internal tables...") | |
3908 | (reftex-compute-ref-cite-tables) | |
3909 | (message "updating internal tables... done") | |
3910 | (reftex-reset-scanning-information)) | |
3911 | ||
3912 | (defun reftex-reset-scanning-information () | |
3913 | "Reset the symbols containing information from buffer scanning. | |
3914 | This enforces rescanning the buffer on next use." | |
3915 | (if (and (string= reftex-last-toc-master (reftex-TeX-master-file)) | |
3916 | (get-buffer "*toc*")) | |
3917 | (kill-buffer "*toc*")) | |
3918 | (let ((symlist reftex-multifile-symbols) | |
3919 | symbol) | |
3920 | (while symlist | |
3921 | (setq symbol (car symlist) | |
3922 | symlist (cdr symlist)) | |
3923 | (if (and (symbolp (symbol-value symbol)) | |
3924 | (not (null (symbol-value symbol)))) | |
3925 | (set (symbol-value symbol) nil))))) | |
3926 | ||
3927 | (defun reftex-compute-ref-cite-tables () | |
3928 | ;; Update ref and cite tables | |
3929 | ||
3930 | (interactive) | |
3931 | ||
3932 | ;; Compile information in reftex-label-alist | |
3933 | (let ((tmp (reftex-uniquify (reftex-splice-symbols-into-list | |
3934 | (append | |
3935 | reftex-label-alist | |
3936 | reftex-label-alist-external-add-ons | |
3937 | reftex-default-label-alist-entries) | |
3938 | reftex-label-alist-builtin) | |
3939 | '(nil))) | |
3940 | entry env-or-mac typekeychar typekey prefix regexp | |
3941 | fmt wordlist cmd qh-list) | |
3942 | ||
3943 | (setq reftex-words-to-typekey-alist nil | |
3944 | reftex-typekey-list nil | |
3945 | reftex-typekey-to-format-alist nil | |
3946 | reftex-typekey-to-prefix-alist nil | |
3947 | reftex-env-or-mac-alist nil | |
3948 | reftex-label-env-list nil | |
3949 | reftex-label-mac-list nil) | |
3950 | (while tmp | |
3951 | (catch 'next-entry | |
3952 | (setq entry (car tmp) | |
3953 | env-or-mac (car entry) | |
3954 | entry (cdr entry) | |
3955 | tmp (cdr tmp)) | |
3956 | (if (null env-or-mac) | |
3957 | (setq env-or-mac "")) | |
3958 | (if (stringp (car entry)) | |
3959 | ;; This is before version 2.00 - convert entry to new format | |
3960 | ;; This is just to keep old users happy | |
3961 | (setq entry (cons (string-to-char (car entry)) | |
3962 | (cons (concat (car entry) ":") | |
3963 | (cdr entry))))) | |
3964 | (setq typekeychar (nth 0 entry) | |
3965 | typekey (char-to-string typekeychar) | |
3966 | prefix (nth 1 entry) | |
3967 | fmt (nth 2 entry) | |
3968 | regexp (nth 3 entry) | |
3969 | wordlist (nth 4 entry)) | |
3970 | (if (stringp wordlist) | |
3971 | ;; This is before version 2.04 - convert to new format | |
3972 | (setq wordlist (nthcdr 4 entry))) | |
3973 | (if typekey | |
3974 | (add-to-list 'reftex-typekey-list typekey)) | |
3975 | (if (and typekey prefix) | |
3976 | (add-to-list 'reftex-typekey-to-prefix-alist (cons typekey prefix))) | |
3977 | (cond | |
3978 | ((string-match "\\`\\\\" env-or-mac) | |
3979 | ;; It's a macro | |
3980 | (add-to-list 'reftex-label-mac-list env-or-mac)) | |
3981 | (t | |
3982 | (or (string= env-or-mac "any") | |
3983 | (string= env-or-mac "") | |
3984 | (add-to-list 'reftex-label-env-list env-or-mac)))) | |
3985 | (and fmt | |
3986 | (not (assoc typekey reftex-typekey-to-format-alist)) | |
3987 | (setq reftex-typekey-to-format-alist | |
3988 | (cons (cons typekey fmt) | |
3989 | reftex-typekey-to-format-alist))) | |
3990 | (and (not (string= env-or-mac "any")) | |
3991 | (not (string= env-or-mac "")) | |
3992 | (not (assoc env-or-mac reftex-env-or-mac-alist)) | |
3993 | (setq reftex-env-or-mac-alist | |
3994 | (cons (list env-or-mac typekey regexp) | |
3995 | reftex-env-or-mac-alist))) | |
3996 | (while (and wordlist (stringp (car wordlist))) | |
3997 | (or (assoc (car wordlist) reftex-words-to-typekey-alist) | |
3998 | (setq reftex-words-to-typekey-alist | |
3999 | (cons (cons (downcase (car wordlist)) typekey) | |
4000 | reftex-words-to-typekey-alist))) | |
4001 | (setq wordlist (cdr wordlist))) | |
4002 | (cond | |
4003 | ((string= "" env-or-mac) nil) | |
4004 | ((assoc typekey qh-list) | |
4005 | (setcdr (assoc typekey qh-list) | |
4006 | (concat (cdr (assoc typekey qh-list)) " " env-or-mac))) | |
4007 | (t | |
4008 | (setq qh-list (cons (cons typekey env-or-mac) qh-list)))))) | |
4009 | ||
4010 | (setq qh-list (nreverse qh-list)) | |
4011 | (setq reftex-typekey-to-prefix-alist | |
4012 | (nreverse reftex-typekey-to-prefix-alist)) | |
4013 | (setq reftex-type-query-prompt | |
4014 | (concat "Label type: " | |
4015 | (mapconcat '(lambda(x) | |
4016 | (format "[%s]" (car x))) | |
4017 | qh-list " ") | |
4018 | " (?=Help)")) | |
4019 | (setq reftex-type-query-help | |
4020 | (concat "SELECT A LABEL TYPE:\n--------------------\n" | |
4021 | (mapconcat '(lambda(x) | |
4022 | (format " [%s] %s" | |
4023 | (car x) (cdr x))) | |
4024 | qh-list "\n"))))) | |
4025 | ||
4026 | ;;; Keybindings -------------------------------------------------------------- | |
4027 | ||
4028 | (define-key reftex-mode-map "\C-c-" 'reftex-item) | |
4029 | (define-key reftex-mode-map "\C-c=" 'reftex-toc) | |
4030 | (define-key reftex-mode-map "\C-c(" 'reftex-label) | |
4031 | (define-key reftex-mode-map "\C-c)" 'reftex-reference) | |
4032 | (define-key reftex-mode-map "\C-c[" 'reftex-citation) | |
4033 | (define-key reftex-mode-map "\C-c&" 'reftex-view-crossref) | |
4034 | ||
4035 | ;; If the user requests so, she can have a few more bindings: | |
4036 | (cond | |
4037 | (reftex-extra-bindings | |
4038 | (define-key reftex-mode-map "\C-ct" 'reftex-toc) | |
4039 | (define-key reftex-mode-map "\C-cl" 'reftex-label) | |
4040 | (define-key reftex-mode-map "\C-cr" 'reftex-reference) | |
4041 | (define-key reftex-mode-map "\C-cc" 'reftex-citation) | |
4042 | (define-key reftex-mode-map "\C-cv" 'reftex-view-crossref) | |
4043 | (define-key reftex-mode-map "\C-cg" 'reftex-grep-document) | |
4044 | (define-key reftex-mode-map "\C-cs" 'reftex-search-document))) | |
4045 | ||
4046 | ;;; Menus -------------------------------------------------------------------- | |
4047 | ||
4048 | ;; Define a menu for the menu bar if Emacs is running under X | |
4049 | ||
4050 | (require 'easymenu) | |
4051 | ||
4052 | (easy-menu-define | |
4053 | reftex-mode-menu reftex-mode-map | |
4054 | "Menu used in RefTeX mode" | |
4055 | '("Ref" | |
4056 | ["Table of Contents" reftex-toc t] | |
4057 | "----" | |
4058 | ["\\label{}" reftex-label t] | |
4059 | ["\\ref{}" reftex-reference t] | |
4060 | ["\\cite{}" reftex-citation t] | |
4061 | ["View crossref" reftex-view-crossref t] | |
4062 | "----" | |
4063 | ("Search and Replace" | |
4064 | ["Search whole document" reftex-search-document t] | |
4065 | ["Replace in document" reftex-query-replace-document t] | |
4066 | ["Grep on document" reftex-grep-document t] | |
4067 | "----" | |
4068 | ["Find duplicate labels" reftex-find-duplicate-labels t] | |
4069 | ["Change label and refs" reftex-change-label t] | |
4070 | "----" | |
4071 | ["Create TAGS file" reftex-create-tags-file t]) | |
4072 | "----" | |
4073 | ["Parse document" reftex-parse-document t] | |
4074 | ["Reset RefTeX Mode" reftex-reset-mode t] | |
4075 | ["Customize RefTeX" reftex-customize t])) | |
4076 | ||
4077 | ;;; Run Hook ------------------------------------------------------------------ | |
4078 | ||
4079 | (run-hooks 'reftex-load-hook) | |
4080 | ||
4081 | ;;; That's it! ---------------------------------------------------------------- | |
4082 | ||
4083 | ; Make sure tabels are compiled | |
4084 | (message "updating internal tables...") | |
4085 | (reftex-compute-ref-cite-tables) | |
4086 | (setq reftex-tables-dirty nil) | |
4087 | ||
4088 | (provide 'reftex) | |
4089 | ||
4090 | ;;;============================================================================ | |
4091 | ||
4092 | ;;; reftex.el end here |