New directory
[bpt/emacs.git] / lisp / textmodes / reftex-ref.el
CommitLineData
3afbc435 1;;; reftex-ref.el --- code to create labels and references with RefTeX
463f5630 2;; Copyright (c) 1997, 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
3ba2590f 3
6fbeb429 4;; Author: Carsten Dominik <dominik@science.uva.nl>
463f5630 5;; Version: 4.18
3ba2590f
RS
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.
1a9461d0 23
3afbc435
PJ
24;;; Commentary:
25
26;;; Code:
27
7c4d13cc 28(eval-when-compile (require 'cl))
1a9461d0
CD
29(provide 'reftex-ref)
30(require 'reftex)
31;;;
32
33(defun reftex-label-location (&optional bound)
34 "Return the environment or macro which determines the label type at point.
35If optional BOUND is an integer, limit backward searches to that point."
36
37 (let* ((loc1 (reftex-what-macro reftex-label-mac-list bound))
38 (loc2 (reftex-what-environment reftex-label-env-list bound))
463f5630 39 (loc3 (reftex-what-special-env 1 bound))
1a9461d0
CD
40 (p1 (or (cdr loc1) 0))
41 (p2 (or (cdr loc2) 0))
463f5630
KH
42 (p3 (or (cdr loc3) 0))
43 (pmax (max p1 p2 p3)))
1a9461d0
CD
44
45 (setq reftex-location-start pmax)
46 (cond
47 ((= p1 pmax)
48 ;; A macro. Default context after macro name.
49 (setq reftex-default-context-position (+ p1 (length (car loc1))))
50 (or (car loc1) "section"))
51 ((= p2 pmax)
52 ;; An environment. Default context after \begin{name}.
53 (setq reftex-default-context-position (+ p2 8 (length (car loc2))))
54 (or (car loc2) "section"))
55 ((= p3 pmax)
56 ;; A special. Default context right there.
57 (setq reftex-default-context-position p3)
58 (setq loc3 (car loc3))
59 (cond ((null loc3) "section")
463f5630
KH
60 ((symbolp loc3) (symbol-name loc3))
61 ((stringp loc3) loc3)
62 (t "section")))
1a9461d0
CD
63 (t ;; This should not happen, I think?
64 "section"))))
65
66(defun reftex-label-info-update (cell)
67 ;; Update information about just one label in a different file.
68 ;; CELL contains the old info list
69 (let* ((label (nth 0 cell))
70 (typekey (nth 1 cell))
71 ;; (text (nth 2 cell))
72 (file (nth 3 cell))
73 (comment (nth 4 cell))
74 (note (nth 5 cell))
75 (buf (reftex-get-file-buffer-force
76 file (not (eq t reftex-keep-temporary-buffers)))))
77 (if (not buf)
78 (list label typekey "" file comment "LOST LABEL. RESCAN TO FIX.")
79 (save-excursion
80 (set-buffer buf)
81 (save-restriction
82 (widen)
83 (goto-char 1)
84
85 (if (or (re-search-forward
463f5630
KH
86 (format reftex-find-label-regexp-format
87 (regexp-quote label)) nil t)
88 (re-search-forward
89 (format reftex-find-label-regexp-format2
90 (regexp-quote label)) nil t))
1a9461d0
CD
91
92 (progn
93 (backward-char 1)
94 (append (reftex-label-info label file) (list note)))
95 (list label typekey "" file "LOST LABEL. RESCAN TO FIX.")))))))
96
97(defun reftex-label-info (label &optional file bound derive env-or-mac)
98 ;; Return info list on LABEL at point.
99 (let* ((env-or-mac (or env-or-mac (reftex-label-location bound)))
100 (typekey (nth 1 (assoc env-or-mac reftex-env-or-mac-alist)))
101 (file (or file (buffer-file-name)))
102 (parse (nth 2 (assoc env-or-mac reftex-env-or-mac-alist)))
103 (text (reftex-short-context env-or-mac parse reftex-location-start
104 derive))
463f5630 105 (in-comment (reftex-in-comment)))
1a9461d0
CD
106 (list label typekey text file in-comment)))
107
108;;; Creating labels ---------------------------------------------------------
109
110(defun reftex-label (&optional environment no-insert)
111 "Insert a unique label. Return the label.
112If ENVIRONMENT is given, don't bother to find out yourself.
113If NO-INSERT is non-nil, do not insert label into buffer.
114With prefix arg, force to rescan document first.
115When you are prompted to enter or confirm a label, and you reply with
116just the prefix or an empty string, no label at all will be inserted.
117A new label is also recorded into the label list.
118This function is controlled by the settings of reftex-insert-label-flags."
119
120 (interactive)
121
122 ;; Ensure access to scanning info and rescan buffer if prefix are is '(4).
123 (reftex-access-scan-info current-prefix-arg)
124
125 ;; Find out what kind of environment this is and abort if necessary.
126 (if (or (not environment)
127 (not (assoc environment reftex-env-or-mac-alist)))
128 (setq environment (reftex-label-location)))
129 (unless environment
130 (error "Can't figure out what kind of label should be inserted"))
131
132 ;; Ok, go ahead.
133 (catch 'exit
134 (let* ((entry (assoc environment reftex-env-or-mac-alist))
463f5630
KH
135 (typekey (nth 1 entry))
136 (format (nth 3 entry))
137 (macro-cell (reftex-what-macro 1))
138 (entry1 (assoc (car macro-cell) reftex-env-or-mac-alist))
139 label naked prefix valid default force-prompt rescan-is-useful)
1a9461d0 140 (when (and (or (nth 5 entry) (nth 5 entry1))
463f5630
KH
141 (memq (preceding-char) '(?\[ ?\{)))
142 ;; This is an argument of a label macro. Insert naked label.
143 (setq naked t format "%s"))
1a9461d0
CD
144
145 (setq prefix (or (cdr (assoc typekey reftex-typekey-to-prefix-alist))
463f5630 146 (concat typekey "-")))
1a9461d0
CD
147 ;; Replace any escapes in the prefix
148 (setq prefix (reftex-replace-prefix-escapes prefix))
149
150 ;; Make a default label.
151 (cond
152
153 ((reftex-typekey-check typekey (nth 0 reftex-insert-label-flags))
463f5630
KH
154 ;; Derive a label from context.
155 (setq reftex-active-toc (reftex-last-assoc-before-elt
156 'toc (car (reftex-where-am-I))
157 (symbol-value reftex-docstruct-symbol)))
158 (setq default (reftex-no-props
159 (nth 2 (reftex-label-info " " nil nil t))))
160 ;; Catch the cases where the is actually no context available.
161 (if (or (string-match "NO MATCH FOR CONTEXT REGEXP" default)
162 (string-match "ILLEGAL VALUE OF PARSE" default)
163 (string-match "SECTION HEADING NOT FOUND" default)
164 (string-match "HOOK ERROR" default)
165 (string-match "^[ \t]*$" default))
166 (setq default prefix
167 force-prompt t) ; need to prompt
168 (setq default
169 (concat prefix
170 (funcall reftex-string-to-label-function default)))
171
172 ;; Make it unique.
173 (setq default (reftex-uniquify-label default nil "-"))))
1a9461d0
CD
174
175 ((reftex-typekey-check typekey (nth 1 reftex-insert-label-flags))
463f5630
KH
176 ;; Minimal default: the user will be prompted.
177 (setq default prefix))
1a9461d0
CD
178
179 (t
463f5630
KH
180 ;; Make an automatic label.
181 (setq default (reftex-uniquify-label prefix t))))
1a9461d0
CD
182
183 ;; Should we ask the user?
184 (if (or (reftex-typekey-check typekey
463f5630
KH
185 (nth 1 reftex-insert-label-flags)) ; prompt
186 force-prompt)
187
188 (while (not valid)
189 ;; iterate until we get a legal label
190
191 (setq label (read-string
192 (if naked "Naked Label: " "Label: ")
193 default))
194
195 ;; Lets make sure that this is a legal label
196 (cond
197
198 ((string-match (concat "\\`\\(" (regexp-quote prefix)
199 "\\)?[ \t]*\\'")
200 label)
201 ;; No label at all, please
202 (message "No label inserted.")
203 (throw 'exit nil))
204
205 ;; Test if label contains strange characters
206 ((string-match reftex-label-illegal-re label)
207 (message "Label \"%s\" contains illegal characters" label)
208 (ding)
209 (sit-for 2))
210
211 ;; Look it up in the label list
212 ((setq entry (assoc label
213 (symbol-value reftex-docstruct-symbol)))
214 (ding)
215 (if (y-or-n-p
216 (format "Label '%s' exists. Use anyway? " label))
217 (setq valid t)))
218
219 ;; Label is ok
220 (t
221 (setq valid t))))
222 (setq label default))
1a9461d0
CD
223
224 ;; Insert the label into the label list
463f5630
KH
225 (let* ((here-I-am-info
226 (save-excursion
227 (if (and (or naked no-insert)
228 (integerp (cdr macro-cell)))
229 (goto-char (cdr macro-cell)))
230 (reftex-where-am-I)))
231 (here-I-am (car here-I-am-info))
232 (note (if (cdr here-I-am-info)
233 ""
234 "POSITION UNCERTAIN. RESCAN TO FIX."))
235 (file (buffer-file-name))
236 (text nil)
237 (tail (memq here-I-am (symbol-value reftex-docstruct-symbol))))
238
239 (or (cdr here-I-am-info) (setq rescan-is-useful t))
240
241 (when tail
242 (push (list label typekey text file nil note) (cdr tail))
243 (put reftex-docstruct-symbol 'modified t)))
1a9461d0
CD
244
245 ;; Insert the label into the buffer
246 (unless no-insert
463f5630
KH
247 (insert
248 (if reftex-format-label-function
249 (funcall reftex-format-label-function label format)
250 (format format label)))
251 (if (and reftex-plug-into-AUCTeX
252 (fboundp 'LaTeX-add-labels))
253 ;; Tell AUCTeX about this
254 (LaTeX-add-labels label)))
1a9461d0
CD
255
256 ;; Delete the corresponding selection buffers to force update on next use.
257 (when reftex-auto-update-selection-buffers
463f5630
KH
258 (reftex-erase-buffer (reftex-make-selection-buffer-name typekey))
259 (reftex-erase-buffer (reftex-make-selection-buffer-name " ")))
1a9461d0
CD
260
261 (when (and rescan-is-useful reftex-allow-automatic-rescan)
463f5630 262 (reftex-parse-one))
1a9461d0
CD
263
264 ;; return value of the function is the label
265 label)))
266
267(defun reftex-string-to-label (string)
268 "Convert a string (a sentence) to a label.
269Uses `reftex-derive-label-parameters' and `reftex-label-illegal-re'. It
270also applies `reftex-translate-to-ascii-function' to the string."
271 (when (and reftex-translate-to-ascii-function
463f5630 272 (fboundp reftex-translate-to-ascii-function))
1a9461d0
CD
273 (setq string (funcall reftex-translate-to-ascii-function string)))
274 (apply 'reftex-convert-string string
463f5630
KH
275 "[-~ \t\n\r,;]+" reftex-label-illegal-re nil nil
276 reftex-derive-label-parameters))
1a9461d0
CD
277
278(defun reftex-latin1-to-ascii (string)
279 ;; Translate the upper 128 chars in the Latin-1 charset to ASCII equivalents
280 (let ((tab "@@@@@@@@@@@@@@@@@@'@@@@@@@@@@@@@ icLxY|S\"ca<--R-o|23'uq..1o>423?AAAAAAACEEEEIIIIDNOOOOOXOUUUUYP3aaaaaaaceeeeiiiidnooooo:ouuuuypy")
463f5630
KH
281 (emacsp (not (featurep 'xemacs))))
282 (mapconcat
1a9461d0
CD
283 (lambda (c)
284 (cond ((and (> c 127) (< c 256)) ; 8 bit Latin-1
463f5630
KH
285 (char-to-string (aref tab (- c 128))))
286 ((and emacsp ; Not for XEmacs
287 (> c 2175) (< c 2304)) ; Mule Latin-1
288 (char-to-string (aref tab (- c 2176))))
289 (t (char-to-string c))))
1a9461d0
CD
290 string "")))
291
292(defun reftex-replace-prefix-escapes (prefix)
293 ;; Replace %escapes in a label prefix
294 (save-match-data
295 (let (letter (num 0) replace)
296 (while (string-match "\\%\\([a-zA-Z]\\)" prefix num)
297 (setq letter (match-string 1 prefix))
298 (setq replace
299 (cond
300 ((equal letter "f")
301 (file-name-sans-extension
302 (file-name-nondirectory (buffer-file-name))))
303 ((equal letter "F")
304 (let ((masterdir (file-name-directory (reftex-TeX-master-file)))
305 (file (file-name-sans-extension (buffer-file-name))))
306 (if (string-match (concat "\\`" (regexp-quote masterdir))
307 file)
308 (substring file (length masterdir))
309 file)))
310 ((equal letter "u")
311 (or (user-login-name) ""))
463f5630
KH
312 ((equal letter "S")
313 (let* (macro level-exp level)
314 (save-excursion
315 (save-match-data
316 (when (re-search-backward reftex-section-regexp nil t)
317 (setq macro (reftex-match-string 2)
318 level-exp (cdr (assoc macro reftex-section-levels-all))
319 level (if (symbolp level-exp)
320 (abs (save-match-data
321 (funcall level-exp)))
322 (abs level-exp))))
323 (cdr (or (assoc macro reftex-section-prefixes)
324 (assoc level reftex-section-prefixes)
325 (assq t reftex-section-prefixes)
326 (list t "sec:")))))))
1a9461d0
CD
327 (t "")))
328 (setq num (1- (+ (match-beginning 1) (length replace)))
329 prefix (replace-match replace nil nil prefix)))
330 prefix)))
331
332(defun reftex-uniquify-label (label &optional force separator)
333 ;; Make label unique by appending a number.
334 ;; Optional FORCE means, force appending a number, even if label is unique.
335 ;; Optional SEPARATOR is a string to stick between label and number.
336
337 ;; Ensure access to scanning info
338 (reftex-access-scan-info)
339
340 (cond
341 ((and (not force)
342 (not (assoc label (symbol-value reftex-docstruct-symbol))))
343 label)
344 (t
345 (let* ((label-numbers (assq 'label-numbers
346 (symbol-value reftex-docstruct-symbol)))
347 (label-numbers-alist (cdr label-numbers))
348 (cell (or (assoc label label-numbers-alist)
349 (car (setcdr label-numbers
350 (cons (cons label 0)
351 label-numbers-alist)))))
352 (num (1+ (cdr cell)))
353 (sep (or separator "")))
354 (while (assoc (concat label sep (int-to-string num))
355 (symbol-value reftex-docstruct-symbol))
356 (incf num))
357 (setcdr cell num)
358 (concat label sep (int-to-string num))))))
359
360;;; Referencing labels ------------------------------------------------------
361
362;; Help string for the reference label menu
363(defconst reftex-select-label-prompt
364 "Select: [n]ext [p]revious [r]escan [ ]context e[x]tern [q]uit RET [?]HELP+more")
365
366(defconst reftex-select-label-help
367 " n / p Go to next/previous label (Cursor motion works as well)
368 C-c C-n/p Go to next/previous section heading.
369 b / l Jump back to previous selection / Reuse last referenced label.
70d797cd 370 z Jump to a specific section, e.g. '3 z' jumps to section 3.
1a9461d0
CD
371 g / s Update menu / Switch label type.
372 r / C-u r Reparse document / Reparse entire document.
373 x Switch to label menu of external document (with LaTeX package `xr').
374 F t c Toggle: [F]ile borders, [t]able of contents, [c]ontext
375 # % Toggle: [#] label counters, [%] labels in comments
376 SPC / f Show full context in other window / Toggle follow mode.
377 . Show insertion point in other window.
378 v / V Toggle \\ref <-> \\vref / Rotate \\ref <=> \\fref <=> \\Fref
379 TAB Enter a label with completion.
380 m , - + Mark entry. `,-+' also assign a separator.
381 a / A Put all marked entries into one/many \\ref commands.
382 q / RET Quit without referencing / Accept current label (also on mouse-2).")
383
384(defun reftex-reference (&optional type no-insert cut)
385 "Make a LaTeX reference. Look only for labels of a certain TYPE.
386With prefix arg, force to rescan buffer for labels. This should only be
387necessary if you have recently entered labels yourself without using
388reftex-label. Rescanning of the buffer can also be requested from the
389label selection menu.
390The function returns the selected label or nil.
391If NO-INSERT is non-nil, do not insert \\ref command, just return label.
392When called with 2 C-u prefix args, disable magic word recognition."
393
394 (interactive)
395
396 ;; check for active recursive edits
397 (reftex-check-recursive-edit)
398
463f5630 399 ;; Ensure access to scanning info and rescan buffer if prefix arg is '(4)
1a9461d0
CD
400 (reftex-access-scan-info current-prefix-arg)
401
402 (unless type
403 ;; guess type from context
404 (if (and reftex-guess-label-type
405 (setq type (reftex-guess-label-type)))
463f5630
KH
406 (setq cut (cdr type)
407 type (car type))
1a9461d0
CD
408 (setq type (reftex-query-label-type))))
409
463f5630
KH
410 (let* ((refstyle
411 (cond ((reftex-typekey-check type reftex-vref-is-default) "\\vref")
412 ((reftex-typekey-check type reftex-fref-is-default) "\\fref")
413 (t "\\ref")))
414 (reftex-format-ref-function reftex-format-ref-function)
415 (form "\\ref{%s}")
416 label labels sep sep1)
1a9461d0
CD
417
418 ;; Have the user select a label
419 (set-marker reftex-select-return-marker (point))
420 (setq labels (save-excursion
463f5630 421 (reftex-offer-label-menu type)))
1a9461d0
CD
422 (reftex-ensure-compiled-variables)
423 (set-marker reftex-select-return-marker nil)
3b919c9f 424 ;; If the first entry is the symbol 'concat, concat all labels.
1a9461d0
CD
425 ;; We keep the cdr of the first label for typekey etc information.
426 (if (eq (car labels) 'concat)
463f5630
KH
427 (setq labels (list (list (mapconcat 'car (cdr labels) ",")
428 (cdr (nth 1 labels))))))
1a9461d0 429 (setq type (nth 1 (car labels))
463f5630
KH
430 form (or (cdr (assoc type reftex-typekey-to-format-alist))
431 form))
432
1a9461d0
CD
433 (cond
434 (no-insert
435 ;; Just return the first label
436 (car (car labels)))
437 ((null labels)
438 (message "Quit")
439 nil)
440 (t
441 (while labels
463f5630
KH
442 (setq label (car (car labels))
443 sep (nth 2 (car labels))
444 sep1 (cdr (assoc sep reftex-multiref-punctuation))
445 labels (cdr labels))
446 (when cut
447 (backward-delete-char cut)
448 (setq cut nil))
449
450 ;; remove ~ if we do already have a space
451 (when (and (= ?~ (string-to-char form))
452 (member (preceding-char) '(?\ ?\t ?\n)))
453 (setq form (substring form 1)))
454 ;; do we have a special format?
455 (setq reftex-format-ref-function
456 (cond
457 ((string= refstyle "\\vref") 'reftex-format-vref)
458 ((string= refstyle "\\fref") 'reftex-format-fref)
459 ((string= refstyle "\\Fref") 'reftex-format-Fref)
460 (t reftex-format-ref-function)))
461 ;; ok, insert the reference
462 (if sep1 (insert sep1))
463 (insert
464 (if reftex-format-ref-function
465 (funcall reftex-format-ref-function label form)
466 (format form label label)))
467 ;; take out the initial ~ for good
468 (and (= ?~ (string-to-char form))
469 (setq form (substring form 1))))
1a9461d0
CD
470 (message "")
471 label))))
472
473(defun reftex-guess-label-type ()
474 ;; Examine context to guess what a \ref might want to reference.
475 (let ((words reftex-words-to-typekey-alist)
463f5630
KH
476 (case-fold-search t)
477 (bound (max (point-min) (- (point) 35)))
478 matched cell)
1a9461d0
CD
479 (save-excursion
480 (while (and (setq cell (pop words))
463f5630
KH
481 (not (setq matched
482 (re-search-backward (car cell) bound t))))))
1a9461d0 483 (if matched
463f5630 484 (cons (cdr cell) (- (match-end 0) (match-end 1)))
1a9461d0
CD
485 nil)))
486
487(defvar reftex-select-label-map)
488(defun reftex-offer-label-menu (typekey)
489 ;; Offer a menu with the appropriate labels.
490 (let* ((buf (current-buffer))
463f5630
KH
491 (xr-data (assq 'xr (symbol-value reftex-docstruct-symbol)))
492 (xr-alist (cons (cons "" (buffer-file-name)) (nth 1 xr-data)))
493 (xr-index 0)
1a9461d0 494 (here-I-am (car (reftex-where-am-I)))
463f5630 495 (here-I-am1 here-I-am)
1a9461d0
CD
496 (toc (reftex-typekey-check typekey reftex-label-menu-flags 0))
497 (files (reftex-typekey-check typekey reftex-label-menu-flags 7))
498 (context (not (reftex-typekey-check
499 typekey reftex-label-menu-flags 3)))
500 (counter (reftex-typekey-check
501 typekey reftex-label-menu-flags 2))
502 (follow (reftex-typekey-check
503 typekey reftex-label-menu-flags 4))
504 (commented (nth 5 reftex-label-menu-flags))
463f5630
KH
505 (prefix "")
506 selection-buffers
1a9461d0
CD
507 offset rtn key data last-data entries)
508
509 (unwind-protect
510 (catch 'exit
511 (while t
512 (save-window-excursion
463f5630
KH
513 (delete-other-windows)
514 (setq reftex-call-back-to-this-buffer buf
515 reftex-latex-syntax-table (syntax-table))
516 (let ((default-major-mode 'reftex-select-label-mode))
517 (if reftex-use-multiple-selection-buffers
518 (switch-to-buffer-other-window
519 (save-excursion
520 (set-buffer buf)
521 (reftex-make-selection-buffer-name typekey)))
522 (switch-to-buffer-other-window "*RefTeX Select*")
523 (reftex-erase-buffer)))
524 (unless (eq major-mode 'reftex-select-label-mode)
525 (reftex-select-label-mode))
526 (add-to-list 'selection-buffers (current-buffer))
1a9461d0 527 (setq truncate-lines t)
463f5630
KH
528 (setq mode-line-format
529 (list "---- " 'mode-line-buffer-identification
530 " " 'global-mode-string " (" mode-name ")"
531 " S<" 'refstyle ">"
532 " -%-"))
533 (cond
534 ((= 0 (buffer-size))
535 (let ((buffer-read-only nil))
536 (message "Creating Selection Buffer...")
537 (setq offset (reftex-insert-docstruct
538 buf
539 toc
540 typekey
541 nil ; index
542 files
543 context
544 counter
545 commented
546 (or here-I-am offset)
547 prefix
548 nil ; no a toc buffer
549 ))))
550 (here-I-am
551 (setq offset (reftex-get-offset buf here-I-am typekey)))
552 (t (setq offset t)))
553 (setq buffer-read-only t)
554 (setq offset (or offset t))
1a9461d0
CD
555
556 (setq here-I-am nil) ; turn off determination of offset
557 (setq rtn
558 (reftex-select-item
559 reftex-select-label-prompt
560 reftex-select-label-help
463f5630 561 reftex-select-label-map
1a9461d0
CD
562 offset
563 'reftex-show-label-location follow))
564 (setq key (car rtn)
565 data (nth 1 rtn)
566 last-data (nth 2 rtn)
463f5630 567 offset t)
1a9461d0
CD
568 (unless key (throw 'exit nil))
569 (cond
463f5630
KH
570 ((eq key ?g)
571 ;; update buffer
572 (reftex-erase-buffer))
1a9461d0
CD
573 ((or (eq key ?r)
574 (eq key ?R))
575 ;; rescan buffer
463f5630
KH
576 (and current-prefix-arg (setq key ?R))
577 (reftex-erase-buffer)
1a9461d0
CD
578 (reftex-reparse-document buf last-data key))
579 ((eq key ?c)
580 ;; toggle context mode
463f5630 581 (reftex-erase-buffer)
1a9461d0
CD
582 (setq context (not context)))
583 ((eq key ?s)
584 ;; switch type
463f5630 585 (setq here-I-am here-I-am1)
1a9461d0
CD
586 (setq typekey (reftex-query-label-type)))
587 ((eq key ?t)
7c4d13cc 588 ;; toggle table of contents display, or change depth
463f5630
KH
589 (reftex-erase-buffer)
590 (if current-prefix-arg
591 (setq reftex-toc-max-level (prefix-numeric-value
592 current-prefix-arg))
593 (setq toc (not toc))))
1a9461d0
CD
594 ((eq key ?F)
595 ;; toggle display of included file borders
463f5630 596 (reftex-erase-buffer)
1a9461d0
CD
597 (setq files (not files)))
598 ((eq key ?#)
599 ;; toggle counter display
463f5630 600 (reftex-erase-buffer)
1a9461d0
CD
601 (setq counter (not counter)))
602 ((eq key ?%)
603 ;; toggle display of commented labels
463f5630 604 (reftex-erase-buffer)
1a9461d0
CD
605 (setq commented (not commented)))
606 ((eq key ?l)
607 ;; reuse the last referenced label again
608 (setq entries reftex-last-used-reference)
609 (throw 'exit t))
463f5630
KH
610 ((eq key ?x)
611 ;; select an external document
612 (setq xr-index (reftex-select-external-document
613 xr-alist xr-index))
614 (setq buf (or (reftex-get-file-buffer-force
615 (cdr (nth xr-index xr-alist)))
616 (error "Cannot switch document"))
617 prefix (or (car (nth xr-index xr-alist)) ""))
618 (set-buffer buf)
619 (reftex-access-scan-info))
620 ((stringp key)
621 (setq entries
622 (list
623 (list
624 (or (assoc key (symbol-value reftex-docstruct-symbol))
625 (list key typekey)))))
626 (throw 'exit t))
627 ((memq key '(?a ?A return))
628 (cond
629 (reftex-select-marked
630 (setq entries (nreverse reftex-select-marked)))
631 (data
632 (setq entries (list (list data))))
633 (t (setq entries nil)))
634 (when entries
635 (if (equal key ?a) (push 'concat entries))
636 (setq reftex-last-used-reference entries))
1a9461d0
CD
637 (set-buffer buf)
638 (throw 'exit t))
463f5630 639 (t (error "This should not happen (reftex-offer-label-menu)"))))))
1a9461d0 640 (save-excursion
463f5630
KH
641 (while reftex-buffers-with-changed-invisibility
642 (set-buffer (car (car reftex-buffers-with-changed-invisibility)))
643 (setq buffer-invisibility-spec
644 (cdr (pop reftex-buffers-with-changed-invisibility)))))
1a9461d0 645 (mapcar (lambda (buf) (and (buffer-live-p buf) (bury-buffer buf)))
463f5630 646 selection-buffers)
1a9461d0
CD
647 (reftex-kill-temporary-buffers))
648 ;; Add the prefixes, put together the relevant information in the form
7ac7387b 649 ;; (LABEL TYPEKEY SEPARATOR) and return a list of those.
1a9461d0 650 (mapcar (lambda (x)
463f5630
KH
651 (if (listp x)
652 (list (concat prefix (car (car x)))
653 (nth 1 (car x))
654 (nth 2 x))
655 x))
656 entries)))
1a9461d0
CD
657
658(defun reftex-reparse-document (&optional buffer data key)
659 ;; Rescan the document.
660 (save-window-excursion
661 (save-excursion
662 (if buffer
663 (if (not (bufferp buffer))
664 (error "No such buffer %s" (buffer-name buffer))
665 (set-buffer buffer)))
666 (let ((arg (if (eq key ?R) '(16) '(4)))
667 (file (nth 3 data)))
668 (reftex-access-scan-info arg file)))))
669
670(defun reftex-query-label-type ()
671 ;; Ask for label type
463f5630
KH
672 (let ((key (reftex-select-with-char
673 reftex-type-query-prompt reftex-type-query-help 3)))
1a9461d0
CD
674 (unless (member (char-to-string key) reftex-typekey-list)
675 (error "No such label type: %s" (char-to-string key)))
676 (char-to-string key)))
677
463f5630
KH
678(defun reftex-show-label-location (data forward no-revisit
679 &optional stay error)
1a9461d0
CD
680 ;; View the definition site of a label in another window.
681 ;; DATA is an entry from the docstruct list.
682 ;; FORWARD indicates if the label is likely forward from current point.
683 ;; NO-REVISIT means do not load a file to show this label.
684 ;; STAY means leave the new window selected.
685 ;; ERROR means throw an error exception when the label cannot be found.
686 ;; If ERROR is nil, the return value of this function indicates success.
687 (let* ((this-window (selected-window))
463f5630 688 (errorf (if error 'error 'message))
1a9461d0
CD
689 label file buffer re found)
690
691 (catch 'exit
692 (setq label (nth 0 data)
463f5630 693 file (nth 3 data))
1a9461d0
CD
694
695 (unless file
463f5630
KH
696 (funcall errorf "Unknown label - reparse might help")
697 (throw 'exit nil))
1a9461d0
CD
698
699 ;; Goto the file in another window
463f5630
KH
700 (setq buffer
701 (if no-revisit
702 (reftex-get-buffer-visiting file)
703 (reftex-get-file-buffer-force
704 file (not reftex-keep-temporary-buffers))))
1a9461d0
CD
705 (if buffer
706 ;; good - the file is available
707 (switch-to-buffer-other-window buffer)
708 ;; we have got a problem here. The file does not exist.
709 ;; Let' get out of here..
463f5630
KH
710 (funcall errorf "Label %s not found" label)
711 (throw 'exit nil))
1a9461d0
CD
712
713 ;; search for that label
714 (setq re (format reftex-find-label-regexp-format (regexp-quote label)))
715 (setq found
463f5630
KH
716 (if forward
717 (re-search-forward re nil t)
718 (re-search-backward re nil t)))
1a9461d0
CD
719 (unless found
720 (goto-char (point-min))
463f5630
KH
721 (unless (setq found (re-search-forward re nil t))
722 ;; Ooops. Must be in a macro with distributed args.
723 (setq found
724 (re-search-forward
725 (format reftex-find-label-regexp-format2
726 (regexp-quote label)) nil t))))
1a9461d0 727 (if (match-end 3)
463f5630
KH
728 (progn
729 (reftex-highlight 0 (match-beginning 3) (match-end 3))
730 (reftex-show-entry (match-beginning 3) (match-end 3))
731 (recenter '(4))
732 (unless stay (select-window this-window)))
733 (select-window this-window)
734 (funcall errorf "Label %s not found" label))
1a9461d0
CD
735 found)))
736
737(defvar font-lock-mode)
738(defun reftex-show-entry (beg-hlt end-hlt)
739 ;; Show entry if point is hidden
740 (let* ((n (/ (reftex-window-height) 2))
741 (beg (save-excursion
742 (re-search-backward "[\n\r]" nil 1 n) (point)))
743 (end (save-excursion
744 (re-search-forward "[\n\r]" nil 1 n) (point))))
745 (cond
746 ((and (boundp 'buffer-invisibility-spec) buffer-invisibility-spec
463f5630 747 (get-char-property (1+ beg-hlt) 'invisible))
1a9461d0
CD
748 ;; Invisible with text properties. That is easy to change.
749 (push (cons (current-buffer) buffer-invisibility-spec)
463f5630 750 reftex-buffers-with-changed-invisibility)
1a9461d0
CD
751 (setq buffer-invisibility-spec nil))
752 ((string-match "\r" (buffer-substring beg end))
753 ;; Invisible with selective display. We need to copy it.
754 (let ((string (buffer-substring-no-properties beg end)))
463f5630
KH
755 (switch-to-buffer "*RefTeX Context Copy*")
756 (setq buffer-read-only nil)
757 (erase-buffer)
758 (insert string)
759 (subst-char-in-region (point-min) (point-max) ?\r ?\n t)
760 (goto-char (- beg-hlt beg))
761 (reftex-highlight 0 (1+ (- beg-hlt beg)) (1+ (- end-hlt beg)))
762 (if (reftex-refontify)
763 (when (or (not (eq major-mode 'latex-mode))
764 (not font-lock-mode))
765 (latex-mode)
766 (run-hook-with-args
767 'reftex-pre-refontification-functions
768 reftex-call-back-to-this-buffer 'reftex-hidden)
769 (turn-on-font-lock))
770 (when (or (not (eq major-mode 'fundamental-mode))
771 font-lock-mode)
772 (fundamental-mode)))
773 (run-hooks 'reftex-display-copied-context-hook)
774 (setq buffer-read-only t))))))
1a9461d0
CD
775
776(defun reftex-varioref-vref ()
70d797cd 777 "Insert a reference using the `\\vref' macro from the varioref package."
1a9461d0
CD
778 (interactive)
779 (let ((reftex-format-ref-function 'reftex-format-vref))
780 (reftex-reference)))
781(defun reftex-fancyref-fref ()
70d797cd 782 "Insert a reference using the `\\fref' macro from the fancyref package."
1a9461d0
CD
783 (interactive)
784 (let ((reftex-format-ref-function 'reftex-format-fref)
463f5630
KH
785 ;;(reftex-guess-label-type nil) ;FIXME do we want this????
786 )
1a9461d0
CD
787 (reftex-reference)))
788(defun reftex-fancyref-Fref ()
70d797cd 789 "Insert a reference using the `\\Fref' macro from the fancyref package."
1a9461d0
CD
790 (interactive)
791 (let ((reftex-format-ref-function 'reftex-format-Fref)
463f5630
KH
792 ;;(reftex-guess-label-type nil) ;FIXME do we want this????
793 )
1a9461d0
CD
794 (reftex-reference)))
795
796(defun reftex-format-vref (label fmt)
797 (while (string-match "\\\\ref{" fmt)
798 (setq fmt (replace-match "\\vref{" t t fmt)))
799 (format fmt label label))
800(defun reftex-format-Fref (label def-fmt)
801 (format "\\Fref{%s}" label))
802(defun reftex-format-fref (label def-fmt)
803 (format "\\fref{%s}" label))
804
463f5630
KH
805
806;(defun reftex-goto-label ()
807; (interactive)
808; (reftex-access-scan-info)
809; (let* ((docstruct (symbol-value reftex-docstruct-symbol))
810; (label (completing-read "Label: " docstruct
811; (lambda (x) (stringp (car x))) t))
812; (selection (assoc label docstruct)))
813; (reftex-show-label-location selection t nil 'stay)
814; (reftex-unhighlight 0)))
815
3b919c9f
CD
816(defun reftex-goto-label (&optional other-window)
817 "Prompt for a label (with completion) and jump to the location of this label.
818Optional prefix argument OTHER-WINDOW goes to the label in another window."
819 (interactive "P")
820 (reftex-access-scan-info)
821 (let* ((wcfg (current-window-configuration))
463f5630
KH
822 (docstruct (symbol-value reftex-docstruct-symbol))
823 (label (completing-read "Label: " docstruct
824 (lambda (x) (stringp (car x))) t))
825 (selection (assoc label docstruct))
826 (where (progn
827 (reftex-show-label-location selection t nil 'stay)
828 (point-marker))))
3b919c9f
CD
829 (unless other-window
830 (set-window-configuration wcfg)
831 (switch-to-buffer (marker-buffer where))
463f5630 832 (goto-char where))
3b919c9f
CD
833 (reftex-unhighlight 0)))
834
835
836
1a9461d0 837;;; reftex-ref.el ends here