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