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