1 ;;; reftex-cite.el --- creating citations with RefTeX
2 ;; Copyright (c) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
4 ;; Author: Carsten Dominik <dominik@strw.LeidenUniv.nl>
7 ;; This file is part of GNU Emacs.
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)
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.
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.
28 (eval-when-compile (require 'cl
))
29 (provide 'reftex-cite
)
33 ;; Variables and constants
35 ;; The history list of regular expressions used for citations
36 (defvar reftex-cite-regexp-hist nil
)
38 ;; Prompt and help string for citation selection
39 (defconst reftex-citation-prompt
40 "Select: [n]ext [p]revious [r]estrict [ ]full_entry [q]uit RET [?]Help+more")
42 (defconst reftex-citation-help
43 " n / p Go to next/previous entry (Cursor motion works as well).
44 g / r Start over with new regexp / Refine with additional regexp.
45 SPC Show full database entry in other window.
46 f Toggle follow mode: Other window will follow with full db entry.
47 . Show insertion point.
48 q Quit without inserting \\cite macro into buffer.
49 TAB Enter citation key with completion.
50 RET Accept current entry (also on mouse-2) and create \\cite macro.
51 m / u Mark/Unmark the entry.
52 a / A Put all (marked) entries into one/many \\cite commands.")
56 (defun reftex-default-bibliography ()
57 ;; Return the expanded value of `reftex-default-bibliography'.
58 ;; The expanded value is cached.
59 (unless (eq (get 'reftex-default-bibliography
:reftex-raw
)
60 reftex-default-bibliography
)
61 (put 'reftex-default-bibliography
:reftex-expanded
62 (reftex-locate-bibliography-files
63 default-directory reftex-default-bibliography
))
64 (put 'reftex-default-bibliography
:reftex-raw
65 reftex-default-bibliography
))
66 (get 'reftex-default-bibliography
:reftex-expanded
))
68 (defun reftex-get-bibfile-list ()
69 ;; Return list of bibfiles for current document.
70 ;; When using the chapterbib or bibunits package you should either
71 ;; use the same database files everywhere, or separate parts using
72 ;; different databases into different files (included into the mater file).
73 ;; Then this function will return the applicable database files.
75 ;; Ensure access to scanning info
76 (reftex-access-scan-info)
78 ;; Try inside this file (and its includes)
79 (cdr (reftex-last-assoc-before-elt
80 'bib
(list 'eof
(buffer-file-name))
81 (member (list 'bof
(buffer-file-name))
82 (symbol-value reftex-docstruct-symbol
))))
83 ;; Try after the beginning of this file
84 (cdr (assq 'bib
(member (list 'bof
(buffer-file-name))
85 (symbol-value reftex-docstruct-symbol
))))
86 ;; Anywhere in the entire document
87 (cdr (assq 'bib
(symbol-value reftex-docstruct-symbol
)))
88 (error "\\bibliography statement missing or .bib files not found")))
90 ;; Find a certain reference in any of the BibTeX files.
92 (defun reftex-pop-to-bibtex-entry (key file-list
&optional mark-to-kill
93 highlight item return
)
94 ;; Find BibTeX KEY in any file in FILE-LIST in another window.
95 ;; If MARK-TO-KILL is non-nil, mark new buffer to kill.
96 ;; If HIGHLIGHT is non-nil, highlight the match.
97 ;; If ITEM in non-nil, search for bibitem instead of database entry.
98 ;; If RETURN is non-nil, just return the entry.
102 (concat "\\\\bibitem\\(\\[[^]]*\\]\\)?{" (regexp-quote key
) "}")
103 (concat "@[a-zA-Z]+[ \t\n\r]*[{(][ \t\n\r]*" (regexp-quote key
)
105 (buffer-conf (current-buffer))
110 (setq file
(car file-list
)
111 file-list
(cdr file-list
))
112 (unless (setq buf
(reftex-get-file-buffer-force file mark-to-kill
))
113 (error "No such file %s" file
))
116 (goto-char (point-min))
117 (when (re-search-forward re nil t
)
118 (goto-char (match-beginning 0))
121 ;; Just return the relevant entry
122 (if item
(goto-char (match-end 0)))
123 (setq return
(buffer-substring
124 (point) (reftex-end-of-bib-entry item
)))
125 (set-buffer buffer-conf
)
126 (throw 'exit return
))
127 (switch-to-buffer-other-window buf
)
131 (reftex-highlight 0 (match-beginning 0) (match-end 0)))
132 (throw 'exit
(selected-window))))
133 (set-buffer buffer-conf
)
135 (error "No \\bibitem with citation key %s" key
)
136 (error "No BibTeX entry with citation key %s" key
)))))
138 (defun reftex-end-of-bib-entry (item)
144 "\\\\bibitem\\|\\end{thebibliography}")
145 (1- (match-beginning 0)))
146 (progn (forward-list 1) (point)))
147 (error (min (point-max) (+ 300 (point)))))))
149 ;; Parse bibtex buffers
151 (defun reftex-extract-bib-entries (buffers)
152 ;; Extract bib entries which match regexps from BUFFERS.
153 ;; BUFFERS is a list of buffers or file names.
154 ;; Return list with entries."
155 (let* (re-list first-re rest-re
156 (buffer-list (if (listp buffers
) buffers
(list buffers
)))
157 found-list entry buffer1 buffer alist
158 key-point start-point end-point
)
160 ;; Read a regexp, completing on known citation keys.
164 "RegExp [ && RegExp...]: "
166 (if (fboundp 'LaTeX-bibitem-list
)
168 (cdr (assoc 'bibview-cache
169 (symbol-value reftex-docstruct-symbol
))))
171 nil nil nil
'reftex-cite-regexp-hist
)
174 (setq first-re
(car re-list
) ; We'll use the first re to find things,
175 rest-re
(cdr re-list
)) ; the others to narrow down.
176 (if (string-match "\\`[ \t]*\\'" (or first-re
""))
177 (error "Empty regular expression"))
180 (save-window-excursion
182 ;; Walk through all bibtex files
184 (setq buffer
(car buffer-list
)
185 buffer-list
(cdr buffer-list
))
186 (if (and (bufferp buffer
)
187 (buffer-live-p buffer
))
188 (setq buffer1 buffer
)
189 (setq buffer1
(reftex-get-file-buffer-force
190 buffer
(not reftex-keep-temporary-buffers
))))
192 (message "No such BibTeX file %s (ignored)" buffer
)
193 (message "Scanning bibliography database %s" buffer1
))
197 (goto-char (point-min))
198 (while (re-search-forward first-re nil t
)
200 (setq key-point
(point))
201 (unless (re-search-backward
202 "\\(\\`\\|[\n\r]\\)[ \t]*@\\([a-zA-Z]+\\)[ \t\n\r]*[{(]" nil t
)
203 (throw 'search-again nil
))
204 (setq start-point
(point))
205 (goto-char (match-end 0))
208 (error (goto-char key-point
)
209 (throw 'search-again nil
)))
210 (setq end-point
(point))
212 ;; Ignore @string, @comment and @c entries or things
214 (when (or (string= (downcase (match-string 2)) "string")
215 (string= (downcase (match-string 2)) "comment")
216 (string= (downcase (match-string 2)) "c")
217 (< (point) key-point
)) ; this means match not in {}
218 (goto-char key-point
)
219 (throw 'search-again nil
))
221 ;; Well, we have got a match
223 (buffer-substring start-point
(point)) "\n"))
225 ;; Check if other regexp match as well
226 (setq re-list rest-re
)
228 (unless (string-match (car re-list
) entry
)
230 (throw 'search-again nil
))
233 (setq alist
(reftex-parse-bibtex-entry
234 nil start-point end-point
))
235 (push (cons "&entry" entry
) alist
)
237 ;; check for crossref entries
238 (if (assoc "crossref" alist
)
241 alist
(reftex-get-crossref-alist alist
))))
244 (push (cons "&formatted" (reftex-format-bib-entry alist
))
247 ;; make key the first element
248 (push (reftex-get-bib-field "&key" alist
) alist
)
250 ;; add it to the list
251 (push alist found-list
))))
252 (reftex-kill-temporary-buffers))))
253 (setq found-list
(nreverse found-list
))
257 ((eq 'author reftex-sort-bibtex-matches
)
258 (sort found-list
'reftex-bib-sort-author
))
259 ((eq 'year reftex-sort-bibtex-matches
)
260 (sort found-list
'reftex-bib-sort-year
))
261 ((eq 'reverse-year reftex-sort-bibtex-matches
)
262 (sort found-list
'reftex-bib-sort-year-reverse
))
265 (defun reftex-bib-sort-author (e1 e2
)
266 (let ((al1 (reftex-get-bib-names "author" e1
))
267 (al2 (reftex-get-bib-names "author" e2
)))
268 (while (and al1 al2
(string= (car al1
) (car al2
)))
271 (if (and (stringp (car al1
))
273 (string< (car al1
) (car al2
))
274 (not (stringp (car al1
))))))
276 (defun reftex-bib-sort-year (e1 e2
)
277 (< (string-to-int (cdr (assoc "year" e1
)))
278 (string-to-int (cdr (assoc "year" e2
)))))
280 (defun reftex-bib-sort-year-reverse (e1 e2
)
281 (> (string-to-int (or (cdr (assoc "year" e1
)) "0"))
282 (string-to-int (or (cdr (assoc "year" e2
)) "0"))))
284 (defun reftex-get-crossref-alist (entry)
285 ;; return the alist from a crossref entry
286 (let ((crkey (cdr (assoc "crossref" entry
)))
291 (if (re-search-forward
292 (concat "@\\w+[{(][ \t\n\r]*" (regexp-quote crkey
)
293 "[ \t\n\r]*,") nil t
)
295 (setq start
(match-beginning 0))
299 (reftex-parse-bibtex-entry nil start
(point)))
302 ;; Parse the thebibliography environment
303 (defun reftex-extract-bib-entries-from-thebibliography (files)
304 ;; Extract bib-entries from the \begin{thebibliography} environment.
305 ;; Parsing is not as good as for the BibTeX database stuff.
306 ;; The environment should be located in file FILE.
308 (let* (start end buf entries re re-list file
)
310 (error "Need file name to find thebibliography environment"))
311 (while (setq file
(pop files
))
312 (setq buf
(reftex-get-file-buffer-force
313 file
(not reftex-keep-temporary-buffers
)))
315 (error "No such file %s" file
))
316 (message "Scanning thebibliography environment in %s" file
)
322 (goto-char (point-min))
323 (while (re-search-forward
324 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\begin{thebibliography}" nil t
)
325 (beginning-of-line 2)
327 (if (re-search-forward
328 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\end{thebibliography}" nil t
)
330 (beginning-of-line 1)
332 (when (and start end
)
335 (mapcar 'reftex-parse-bibitem
338 (buffer-substring-no-properties start end
)
339 "[ \t\n\r]*\\\\bibitem\\(\\[[^]]*]\\)*"))))))
342 (error "No bibitems found"))
344 (setq re-list
(split-string
345 (read-string "RegExp [ && RegExp...]: "
346 nil
'reftex-cite-regexp-hist
)
348 (if (string-match "\\`[ \t]*\\'" (car re-list
))
349 (error "Empty regular expression"))
351 (while (and (setq re
(pop re-list
)) entries
)
355 (if (string-match re
(cdr (assoc "&entry" x
)))
361 (push (cons "&formatted" (reftex-format-bibitem x
)) x
)
362 (push (reftex-get-bib-field "&key" x
) x
)
368 ;; Parse and format individual entries
370 (defun reftex-get-bib-names (field entry
)
371 ;; Return a list with the author or editor names in ENTRY
372 (let ((names (reftex-get-bib-field field entry
)))
374 (setq names
(reftex-get-bib-field "editor" entry
)))
375 (while (string-match "\\band\\b[ \t]*" names
)
376 (setq names
(replace-match "\n" nil t names
)))
377 (while (string-match "[\\.a-zA-Z\\-]+\\.[ \t]*\\|,.*\\|[{}]+" names
)
378 (setq names
(replace-match "" nil t names
)))
379 (while (string-match "^[ \t]+\\|[ \t]+$" names
)
380 (setq names
(replace-match "" nil t names
)))
381 (while (string-match "[ \t][ \t]+" names
)
382 (setq names
(replace-match " " nil t names
)))
383 (split-string names
"\n")))
385 (defun reftex-parse-bibtex-entry (entry &optional from to
)
386 (let (alist key start field
)
391 (set-buffer (get-buffer-create " *RefTeX-scratch*"))
396 (narrow-to-region from to
))
397 (goto-char (point-min))
399 (if (re-search-forward
400 "@\\(\\w+\\)[ \t\n\r]*[{(][ \t\n\r]*\\([^ \t\n\r,]+\\)" nil t
)
403 (cons "&type" (downcase (reftex-match-string 1)))
404 (cons "&key" (reftex-match-string 2)))))
405 (while (re-search-forward "\\(\\w+\\)[ \t\n\r]*=[ \t\n\r]*" nil t
)
406 (setq key
(downcase (reftex-match-string 1)))
408 ((= (following-char) ?
{)
414 ((= (following-char) ?
\")
417 (while (and (search-forward "\"" nil t
)
418 (= ?
\\ (char-after (- (point) 2))))))
421 (re-search-forward "[ \t]*[\n\r,}]" nil
1)))
422 (setq field
(buffer-substring-no-properties start
(1- (point))))
423 ;; remove extra whitespace
424 (while (string-match "[\n\t\r]\\|[ \t][ \t]+" field
)
425 (setq field
(replace-match " " nil t field
)))
426 ;; remove leading garbage
427 (if (string-match "^[ \t{]+" field
)
428 (setq field
(replace-match "" nil t field
)))
429 ;; remove trailing garbage
430 (if (string-match "[ \t}]+$" field
)
431 (setq field
(replace-match "" nil t field
)))
432 (push (cons key field
) alist
))))
435 (defun reftex-get-bib-field (fieldname entry
&optional format
)
436 ;; Extract the field FIELDNAME from an ENTRY
437 (let ((cell (assoc fieldname entry
)))
440 (format format
(cdr cell
))
444 (defun reftex-format-bib-entry (entry)
445 ;; Format a BibTeX ENTRY so that it is nice to look at
447 ((auth-list (reftex-get-bib-names "author" entry
))
448 (authors (mapconcat 'identity auth-list
", "))
449 (year (reftex-get-bib-field "year" entry
))
450 (title (reftex-get-bib-field "title" entry
))
451 (type (reftex-get-bib-field "&type" entry
))
452 (key (reftex-get-bib-field "&key" entry
))
455 ((equal type
"article")
456 (concat (reftex-get-bib-field "journal" entry
) " "
457 (reftex-get-bib-field "volume" entry
) ", "
458 (reftex-get-bib-field "pages" entry
)))
460 (concat "book (" (reftex-get-bib-field "publisher" entry
) ")"))
461 ((equal type
"phdthesis")
462 (concat "PhD: " (reftex-get-bib-field "school" entry
)))
463 ((equal type
"mastersthesis")
464 (concat "Master: " (reftex-get-bib-field "school" entry
)))
465 ((equal type
"inbook")
466 (concat "Chap: " (reftex-get-bib-field "chapter" entry
)
467 ", pp. " (reftex-get-bib-field "pages" entry
)))
468 ((or (equal type
"conference")
469 (equal type
"incollection")
470 (equal type
"inproceedings"))
471 (reftex-get-bib-field "booktitle" entry
"in: %s"))
473 (setq authors
(reftex-truncate authors
30 t t
))
474 (when (reftex-use-fonts)
475 (put-text-property 0 (length key
) 'face
476 (reftex-verified-face reftex-label-face
477 'font-lock-constant-face
478 'font-lock-reference-face
)
480 (put-text-property 0 (length authors
) 'face reftex-bib-author-face
482 (put-text-property 0 (length year
) 'face reftex-bib-year-face
484 (put-text-property 0 (length title
) 'face reftex-bib-title-face
486 (put-text-property 0 (length extra
) 'face reftex-bib-extra-face
488 (concat key
"\n " authors
" " year
" " extra
"\n " title
"\n\n")))
490 (defun reftex-parse-bibitem (item)
491 ;; Parse a \bibitem entry
492 (let ((key "") (text ""))
493 (when (string-match "\\`{\\([^}]+\\)}\\([^\000]*\\)" item
)
494 (setq key
(match-string 1 item
)
495 text
(match-string 2 item
)))
496 ;; Clean up the text a little bit
497 (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text
)
498 (setq text
(replace-match " " nil t text
)))
499 (if (string-match "\\`[ \t]+" text
)
500 (setq text
(replace-match "" nil t text
)))
504 (cons "&entry" (concat key
" " text
)))))
506 (defun reftex-format-bibitem (item)
507 ;; Format a \bibitem entry so that it is (relatively) nice to look at.
508 (let ((text (reftex-get-bib-field "&text" item
))
509 (key (reftex-get-bib-field "&key" item
))
512 ;; Wrap the text into several lines.
513 (while (and (> (length text
) 70)
514 (string-match " " (substring text
60)))
515 (push (substring text
0 (+ 60 (match-beginning 0))) lines
)
516 (setq text
(substring text
(+ 61 (match-beginning 0)))))
518 (setq text
(mapconcat 'identity
(nreverse lines
) "\n "))
520 (when (reftex-use-fonts)
521 (put-text-property 0 (length text
) 'face reftex-bib-author-face text
))
522 (concat key
"\n " text
"\n\n")))
527 (defun reftex-citation (&optional no-insert format-key
)
528 "Make a citation using BibTeX database files.
529 After prompting for a regular expression, scans the buffers with
530 bibtex entries (taken from the \\bibliography command) and offers the
531 matching entries for selection. The selected entry is formated according
532 to `reftex-cite-format' and inserted into the buffer.
534 If NO-INSERT is non-nil, nothing is inserted, only the selected key returned.
536 FORAT-KEY can be used to pre-select a citation format.
538 When called with one or two `C-u' prefixes, first rescans the document.
539 When called with a numeric prefix, make that many citations. When
540 called with point inside the braces of a `\\cite' command, it will
541 add another key, ignoring the value of `reftex-cite-format'.
543 The regular expression uses an expanded syntax: && is interpreted as `and'.
544 Thus, `aaaa&&bbb' matches entries which contain both `aaaa' and `bbb'.
545 While entering the regexp, completion on knows citation keys is possible.
546 `=' is a good regular expression to match all entries in all files."
550 ;; check for recursive edit
551 (reftex-check-recursive-edit)
553 ;; This function may also be called outside reftex-mode.
554 ;; Thus look for the scanning info only if in reftex-mode.
557 (reftex-access-scan-info current-prefix-arg
))
559 ;; Call reftex-do-citation, but protected
561 (reftex-do-citation current-prefix-arg no-insert format-key
)
562 (reftex-kill-temporary-buffers)))
564 (defun reftex-do-citation (&optional arg no-insert format-key
)
565 ;; This really does the work of reftex-citation.
567 (let* ((format (reftex-figure-out-cite-format arg no-insert format-key
))
568 (docstruct-symbol reftex-docstruct-symbol
)
569 (selected-entries (reftex-offer-bib-menu))
570 (insert-entries selected-entries
)
571 entry string cite-view
)
573 (unless selected-entries
(error "Quit"))
575 (if (stringp selected-entries
)
577 (setq selected-entries nil
578 insert-entries
(list (list selected-entries
579 (cons "&key" selected-entries
))))
580 ;; It makes sense to compute the cite-view strings.
583 (when (eq (car selected-entries
) 'concat
)
584 ;; All keys go into a single command - we need to trick a little
585 (pop selected-entries
)
586 (let ((concat-keys (mapconcat 'car selected-entries
",")))
588 (list (list concat-keys
(cons "&key" concat-keys
))))))
592 ;; We shall insert this into the buffer...
593 (message "Formatting...")
595 (while (setq entry
(pop insert-entries
))
596 ;; Format the citation and insert it
597 (setq string
(if reftex-format-cite-function
598 (funcall reftex-format-cite-function
599 (reftex-get-bib-field "&key" entry
)
601 (reftex-format-citation entry format
)))
604 ;; Reposition cursor?
605 (when (string-match "\\?" string
)
606 (search-backward "?")
610 (when (and reftex-mode
611 (fboundp 'LaTeX-add-bibitems
)
612 reftex-plug-into-AUCTeX
)
613 (apply 'LaTeX-add-bibitems
(mapcar 'car selected-entries
)))
615 ;; Produce the cite-view strings
616 (when (and reftex-mode reftex-cache-cite-echo cite-view
)
617 (mapcar (lambda (entry)
618 (reftex-make-cite-echo-string entry docstruct-symbol
))
623 (set-marker reftex-select-return-marker nil
)
624 (reftex-kill-buffer "*RefTeX Select*")
626 ;; Check if the prefix arg was numeric, and call recursively
630 (skip-chars-backward "}")
632 (reftex-do-citation arg
))
635 ;; Return the citation key
636 (car (car selected-entries
))))
638 (defun reftex-figure-out-cite-format (arg &optional no-insert format-key
)
639 ;; Check if there is already a cite command at point and change cite format
640 ;; in order to only add another reference in the same cite command.
641 (let ((macro (car (reftex-what-macro 1)))
642 (cite-format-value (reftex-get-cite-format))
646 ;; Format does not really matter because nothing will be inserted.
649 ((and (stringp macro
)
650 (string-match "\\`\\\\cite\\|cite\\'" macro
))
651 ;; We are already inside a cite macro
652 (if (or (not arg
) (not (listp arg
)))
655 (if (member (preceding-char) '(?\
{ ?
,)) "" ",")
657 (if (member (following-char) '(?\
} ?
,)) "" ",")))
660 ;; Figure out the correct format
662 (if (and (symbolp cite-format-value
)
663 (assq cite-format-value reftex-cite-format-builtin
))
664 (nth 2 (assq cite-format-value reftex-cite-format-builtin
))
669 (reftex-select-with-char
670 "" (concat "SELECT A CITATION FORMAT\n\n"
673 (format "[%c] %s %s" (car x
)
674 (if (> (car x
) 31) " " "")
677 (if (assq key format
)
678 (setq format
(cdr (assq key format
)))
679 (error "No citation format associated with key `%c'" key
)))))
682 (defun reftex-citep ()
683 "Call `reftex-citation' with a format selector `?p'."
685 (reftex-citation nil ?p
))
687 (defun reftex-citet ()
688 "Call `reftex-citation' with a format selector `?t'."
690 (reftex-citation nil ?t
))
692 (defvar reftex-select-bib-map
)
693 (defun reftex-offer-bib-menu ()
694 ;; Offer bib menu and return list of selected items
696 (let (found-list rtn key data selected-entries
)
703 ((assq 'bib
(symbol-value reftex-docstruct-symbol
))
704 ;; using BibTeX database files.
705 (reftex-extract-bib-entries (reftex-get-bibfile-list)))
706 ((assq 'thebib
(symbol-value reftex-docstruct-symbol
))
707 ;; using thebibliography environment.
708 (reftex-extract-bib-entries-from-thebibliography
712 'thebib
(symbol-value reftex-docstruct-symbol
))))))
713 (reftex-default-bibliography
714 (message "Using default bibliography")
715 (reftex-extract-bib-entries (reftex-default-bibliography)))
716 (t (error "No valid bibliography in this document, and no default available"))))
719 (error "Sorry, no matches found"))
721 ;; Remember where we came from
722 (setq reftex-call-back-to-this-buffer
(current-buffer))
723 (set-marker reftex-select-return-marker
(point))
726 (save-window-excursion
727 (delete-other-windows)
728 (let ((default-major-mode 'reftex-select-bib-mode
))
729 (reftex-kill-buffer "*RefTeX Select*")
730 (switch-to-buffer-other-window "*RefTeX Select*")
731 (unless (eq major-mode
'reftex-select-bib-mode
)
732 (reftex-select-bib-mode))
733 (let ((buffer-read-only nil
))
735 (reftex-insert-bib-matches found-list
)))
736 (setq buffer-read-only t
)
737 (if (= 0 (buffer-size))
738 (error "No matches found"))
739 (setq truncate-lines t
)
744 reftex-citation-prompt
746 reftex-select-bib-map
748 'reftex-bibtex-selection-callback nil
))
751 (unless key
(throw 'done t
))
757 ;; Restrict with new regular expression
758 (setq found-list
(reftex-restrict-bib-matches found-list
))
759 (let ((buffer-read-only nil
))
761 (reftex-insert-bib-matches found-list
))
765 (setq selected-entries
766 (if reftex-select-marked
767 (mapcar 'car
(nreverse reftex-select-marked
))
771 ;; Take all (marked), and push the symbol 'concat
772 (setq selected-entries
774 (if reftex-select-marked
775 (mapcar 'car
(nreverse reftex-select-marked
))
781 (setq selected-entries
782 (if reftex-select-marked
784 (mapcar 'car
(nreverse reftex-select-marked
)))
785 (if data
(list data
) nil
)))
788 ;; Got this one with completion
789 (setq selected-entries key
)
795 (defun reftex-restrict-bib-matches (found-list)
796 ;; Limit FOUND-LIST with more regular expressions
797 (let ((re-list (split-string (read-string
798 "RegExp [ && RegExp...]: "
799 nil
'reftex-cite-regexp-hist
)
801 (found-list-r found-list
)
803 (while (setq re
(pop re-list
))
809 re
(cdr (assoc "&entry" x
)))
818 (defun reftex-insert-bib-matches (list)
819 ;; Insert the bib matches and number them correctly
821 (if (memq reftex-highlight-selection
'(mouse both
))
822 reftex-mouse-selected-face
827 (setq tmp
(cdr (assoc "&formatted" x
))
829 (put-text-property 0 len
:data x tmp
)
830 (put-text-property 0 (1- len
) 'mouse-face mouse-face tmp
)
833 (run-hooks 'reftex-display-copied-context-hook
))
835 (defun reftex-format-names (namelist n
)
836 (let (last (len (length namelist
)))
839 ((= 1 len
) (car namelist
))
840 ((> len n
) (concat (car namelist
) (nth 2 reftex-cite-punctuation
)))
843 last
(nth (1- n
) namelist
))
844 (setcdr (nthcdr (- n
2) namelist
) nil
)
846 (mapconcat 'identity namelist
(nth 0 reftex-cite-punctuation
))
847 (nth 1 reftex-cite-punctuation
)
850 (defun reftex-format-citation (entry format
)
851 ;; Format a citation from the info in the BibTeX ENTRY
853 (unless (stringp format
) (setq format
"\\cite{%l}"))
855 (if (and reftex-comment-citations
856 (string-match "%l" reftex-cite-comment-format
))
857 (error "reftex-cite-comment-format contains illegal %%l"))
860 "\\(\\`\\|[^%]\\)\\(\\(%\\([0-9]*\\)\\([a-zA-Z]\\)\\)[.,;: ]*\\)"
862 (let ((n (string-to-int (match-string 4 format
)))
863 (l (string-to-char (match-string 5 format
)))
869 (reftex-get-bib-field "&key" entry
)
870 (if reftex-comment-citations
871 reftex-cite-comment-format
873 ((= l ?a
) (reftex-format-names
874 (reftex-get-bib-names "author" entry
)
876 ((= l ?A
) (car (reftex-get-bib-names "author" entry
)))
877 ((= l ?b
) (reftex-get-bib-field "booktitle" entry
"in: %s"))
878 ((= l ?B
) (reftex-abbreviate-title
879 (reftex-get-bib-field "booktitle" entry
"in: %s")))
880 ((= l ?c
) (reftex-get-bib-field "chapter" entry
))
881 ((= l ?d
) (reftex-get-bib-field "edition" entry
))
882 ((= l ?e
) (reftex-format-names
883 (reftex-get-bib-names "editor" entry
)
885 ((= l ?E
) (car (reftex-get-bib-names "editor" entry
)))
886 ((= l ?h
) (reftex-get-bib-field "howpublished" entry
))
887 ((= l ?i
) (reftex-get-bib-field "institution" entry
))
888 ((= l ?j
) (reftex-get-bib-field "journal" entry
))
889 ((= l ?k
) (reftex-get-bib-field "key" entry
))
890 ((= l ?m
) (reftex-get-bib-field "month" entry
))
891 ((= l ?n
) (reftex-get-bib-field "number" entry
))
892 ((= l ?o
) (reftex-get-bib-field "organization" entry
))
893 ((= l ?p
) (reftex-get-bib-field "pages" entry
))
894 ((= l ?P
) (car (split-string
895 (reftex-get-bib-field "pages" entry
)
897 ((= l ?s
) (reftex-get-bib-field "school" entry
))
898 ((= l ?u
) (reftex-get-bib-field "publisher" entry
))
899 ((= l ?r
) (reftex-get-bib-field "address" entry
))
900 ((= l ?t
) (reftex-get-bib-field "title" entry
))
901 ((= l ?T
) (reftex-abbreviate-title
902 (reftex-get-bib-field "title" entry
)))
903 ((= l ?v
) (reftex-get-bib-field "volume" entry
))
904 ((= l ?y
) (reftex-get-bib-field "year" entry
)))))
907 (setq b
(match-beginning 2) e
(match-end 2))
908 (setq b
(match-beginning 3) e
(match-end 3)))
909 (setq format
(concat (substring format
0 b
) rpl
(substring format e
)))))
910 (while (string-match "%%" format
)
911 (setq format
(replace-match "%" t t format
)))
912 (while (string-match "[ ,.;:]*%<" format
)
913 (setq format
(replace-match "" t t format
)))
916 (defun reftex-make-cite-echo-string (entry docstruct-symbol
)
917 ;; Format a bibtex entry for the echo area and cache the result.
918 (let* ((key (reftex-get-bib-field "&key" entry
))
920 (let* ((reftex-cite-punctuation '(" " " & " " etal.")))
921 (reftex-format-citation entry reftex-cite-view-format
)))
922 (cache (assq 'bibview-cache
(symbol-value docstruct-symbol
)))
923 (cache-entry (assoc key
(cdr cache
))))
925 ;; This docstruct has no cache - make one.
926 (set docstruct-symbol
(cons (cons 'bibview-cache nil
)
927 (symbol-value docstruct-symbol
))))
928 (when reftex-cache-cite-echo
929 (setq key
(copy-sequence key
))
930 (set-text-properties 0 (length key
) nil key
)
931 (set-text-properties 0 (length string
) nil string
)
933 (unless (string= (cdr cache-entry
) string
)
934 (setcdr cache-entry string
)
935 (put reftex-docstruct-symbol
'modified t
))
936 (push (cons key string
) (cdr cache
))
937 (put reftex-docstruct-symbol
'modified t
)))
940 (defun reftex-bibtex-selection-callback (data ignore no-revisit
)
941 ;; Callback function to be called from the BibTeX selection, in
942 ;; order to display context. This function is relatively slow and not
943 ;; recommended for follow mode. It works OK for individual lookups.
944 (let ((win (selected-window))
945 (key (reftex-get-bib-field "&key" data
))
950 (set-buffer reftex-call-back-to-this-buffer
)
952 ((assq 'bib
(symbol-value reftex-docstruct-symbol
))
953 (setq bibfile-list
(reftex-get-bibfile-list)))
954 ((assq 'thebib
(symbol-value reftex-docstruct-symbol
))
959 'thebib
(symbol-value reftex-docstruct-symbol
))))
961 (reftex-default-bibliography
962 (setq bibfile-list
(reftex-default-bibliography)))
963 (t (ding) (throw 'exit nil
))))
966 (setq bibfile-list
(reftex-visited-files bibfile-list
)))
969 (reftex-pop-to-bibtex-entry
970 key bibfile-list
(not reftex-keep-temporary-buffers
) t item
)
973 (select-window win
)))
975 ;;; reftex-cite.el ends here