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