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>
8 ;; This file is part of GNU Emacs.
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)
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.
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.
25 (eval-when-compile (require 'cl
))
26 (provide 'reftex-cite
)
30 ;; Variables and constants
32 ;; The history list of regular expressions used for citations
33 (defvar reftex-cite-regexp-hist nil
)
35 ;; Prompt and help string for citation selection
36 (defconst reftex-citation-prompt
37 "Select: [n]ext [p]revious [r]estrict [ ]full_entry [q]uit RET [?]Help+more")
39 (defconst reftex-citation-help
40 " n / p Go to next/previous entry (Cursor motion works as well).
41 g / r Start over with new regexp / Refine with additional regexp.
42 SPC Show full database entry in other window.
43 f Toggle follow mode: Other window will follow with full db entry.
44 . Show insertion point.
45 q Quit without inserting \\cite macro into buffer.
46 TAB Enter citation key with completion.
47 RET Accept current entry (also on mouse-2) and create \\cite macro.
48 m / u Mark/Unmark the entry.
49 a / A Put all (marked) entries into one/many \\cite commands.")
53 (defun reftex-default-bibliography ()
54 ;; Return the expanded value of `reftex-default-bibliography'.
55 ;; The expanded value is cached.
56 (unless (eq (get 'reftex-default-bibliography
:reftex-raw
)
57 reftex-default-bibliography
)
58 (put 'reftex-default-bibliography
:reftex-expanded
59 (reftex-locate-bibliography-files
60 default-directory reftex-default-bibliography
))
61 (put 'reftex-default-bibliography
:reftex-raw
62 reftex-default-bibliography
))
63 (get 'reftex-default-bibliography
:reftex-expanded
))
65 (defun reftex-get-bibfile-list ()
66 ;; Return list of bibfiles for current document.
67 ;; When using the chapterbib or bibunits package you should either
68 ;; use the same database files everywhere, or separate parts using
69 ;; different databases into different files (included into the mater file).
70 ;; Then this function will return the applicable database files.
72 ;; Ensure access to scanning info
73 (reftex-access-scan-info)
75 ;; Try inside this file (and its includes)
76 (cdr (reftex-last-assoc-before-elt
77 'bib
(list 'eof
(buffer-file-name))
78 (member (list 'bof
(buffer-file-name))
79 (symbol-value reftex-docstruct-symbol
))))
80 ;; Try after the beginning of this file
81 (cdr (assq 'bib
(member (list 'bof
(buffer-file-name))
82 (symbol-value reftex-docstruct-symbol
))))
83 ;; Anywhere in the entire document
84 (cdr (assq 'bib
(symbol-value reftex-docstruct-symbol
)))
85 (error "\\bibliography statement missing or .bib files not found")))
87 ;; Find a certain reference in any of the BibTeX files.
89 (defun reftex-pop-to-bibtex-entry (key file-list
&optional mark-to-kill
90 highlight item return
)
91 ;; Find BibTeX KEY in any file in FILE-LIST in another window.
92 ;; If MARK-TO-KILL is non-nil, mark new buffer to kill.
93 ;; If HIGHLIGHT is non-nil, highlight the match.
94 ;; If ITEM in non-nil, search for bibitem instead of database entry.
95 ;; If RETURN is non-nil, just return the entry.
99 (concat "\\\\bibitem\\(\\[[^]]*\\]\\)?{" (regexp-quote key
) "}")
100 (concat "@[a-zA-Z]+[ \t\n\r]*[{(][ \t\n\r]*" (regexp-quote key
)
102 (buffer-conf (current-buffer))
107 (setq file
(car file-list
)
108 file-list
(cdr file-list
))
109 (unless (setq buf
(reftex-get-file-buffer-force file mark-to-kill
))
110 (error "No such file %s" file
))
113 (goto-char (point-min))
114 (when (re-search-forward re nil t
)
115 (goto-char (match-beginning 0))
118 ;; Just return the relevant entry
119 (if item
(goto-char (match-end 0)))
120 (setq return
(buffer-substring
121 (point) (reftex-end-of-bib-entry item
)))
122 (set-buffer buffer-conf
)
123 (throw 'exit return
))
124 (switch-to-buffer-other-window buf
)
128 (reftex-highlight 0 (match-beginning 0) (match-end 0)))
129 (throw 'exit
(selected-window))))
130 (set-buffer buffer-conf
)
132 (error "No \\bibitem with citation key %s" key
)
133 (error "No BibTeX entry with citation key %s" key
)))))
135 (defun reftex-end-of-bib-entry (item)
141 "\\\\bibitem\\|\\end{thebibliography}")
142 (1- (match-beginning 0)))
143 (progn (forward-list 1) (point)))
144 (error (min (point-max) (+ 300 (point)))))))
146 ;; Parse bibtex buffers
148 (defun reftex-extract-bib-entries (buffers)
149 ;; Extract bib entries which match regexps from BUFFERS.
150 ;; BUFFERS is a list of buffers or file names.
151 ;; Return list with entries."
152 (let* (re-list first-re rest-re
153 (buffer-list (if (listp buffers
) buffers
(list buffers
)))
154 found-list entry buffer1 buffer alist
155 key-point start-point end-point
)
157 ;; Read a regexp, completing on known citation keys.
161 "RegExp [ && RegExp...]: "
163 (if (fboundp 'LaTeX-bibitem-list
)
165 (cdr (assoc 'bibview-cache
166 (symbol-value reftex-docstruct-symbol
))))
168 nil nil nil
'reftex-cite-regexp-hist
)
171 (setq first-re
(car re-list
) ; We'll use the first re to find things,
172 rest-re
(cdr re-list
)) ; the others to narrow down.
173 (if (string-match "\\`[ \t]*\\'" (or first-re
""))
174 (error "Empty regular expression"))
177 (save-window-excursion
179 ;; Walk through all bibtex files
181 (setq buffer
(car buffer-list
)
182 buffer-list
(cdr buffer-list
))
183 (if (and (bufferp buffer
)
184 (buffer-live-p buffer
))
185 (setq buffer1 buffer
)
186 (setq buffer1
(reftex-get-file-buffer-force
187 buffer
(not reftex-keep-temporary-buffers
))))
189 (message "No such BibTeX file %s (ignored)" buffer
)
190 (message "Scanning bibliography database %s" buffer1
))
194 (goto-char (point-min))
195 (while (re-search-forward first-re nil t
)
197 (setq key-point
(point))
198 (unless (re-search-backward
199 "\\(\\`\\|[\n\r]\\)[ \t]*@\\([a-zA-Z]+\\)[ \t\n\r]*[{(]" nil t
)
200 (throw 'search-again nil
))
201 (setq start-point
(point))
202 (goto-char (match-end 0))
205 (error (goto-char key-point
)
206 (throw 'search-again nil
)))
207 (setq end-point
(point))
209 ;; Ignore @string, @comment and @c entries or things
211 (when (or (string= (downcase (match-string 2)) "string")
212 (string= (downcase (match-string 2)) "comment")
213 (string= (downcase (match-string 2)) "c")
214 (< (point) key-point
)) ; this means match not in {}
215 (goto-char key-point
)
216 (throw 'search-again nil
))
218 ;; Well, we have got a match
220 (buffer-substring start-point
(point)) "\n"))
222 ;; Check if other regexp match as well
223 (setq re-list rest-re
)
225 (unless (string-match (car re-list
) entry
)
227 (throw 'search-again nil
))
230 (setq alist
(reftex-parse-bibtex-entry
231 nil start-point end-point
))
232 (push (cons "&entry" entry
) alist
)
234 ;; check for crossref entries
235 (if (assoc "crossref" alist
)
238 alist
(reftex-get-crossref-alist alist
))))
241 (push (cons "&formatted" (reftex-format-bib-entry alist
))
244 ;; make key the first element
245 (push (reftex-get-bib-field "&key" alist
) alist
)
247 ;; add it to the list
248 (push alist found-list
))))
249 (reftex-kill-temporary-buffers))))
250 (setq found-list
(nreverse found-list
))
254 ((eq 'author reftex-sort-bibtex-matches
)
255 (sort found-list
'reftex-bib-sort-author
))
256 ((eq 'year reftex-sort-bibtex-matches
)
257 (sort found-list
'reftex-bib-sort-year
))
258 ((eq 'reverse-year reftex-sort-bibtex-matches
)
259 (sort found-list
'reftex-bib-sort-year-reverse
))
262 (defun reftex-bib-sort-author (e1 e2
)
263 (let ((al1 (reftex-get-bib-names "author" e1
))
264 (al2 (reftex-get-bib-names "author" e2
)))
265 (while (and al1 al2
(string= (car al1
) (car al2
)))
268 (if (and (stringp (car al1
))
270 (string< (car al1
) (car al2
))
271 (not (stringp (car al1
))))))
273 (defun reftex-bib-sort-year (e1 e2
)
274 (< (string-to-int (cdr (assoc "year" e1
)))
275 (string-to-int (cdr (assoc "year" e2
)))))
277 (defun reftex-bib-sort-year-reverse (e1 e2
)
278 (> (string-to-int (or (cdr (assoc "year" e1
)) "0"))
279 (string-to-int (or (cdr (assoc "year" e2
)) "0"))))
281 (defun reftex-get-crossref-alist (entry)
282 ;; return the alist from a crossref entry
283 (let ((crkey (cdr (assoc "crossref" entry
)))
288 (if (re-search-forward
289 (concat "@\\w+[{(][ \t\n\r]*" (regexp-quote crkey
)
290 "[ \t\n\r]*,") nil t
)
292 (setq start
(match-beginning 0))
296 (reftex-parse-bibtex-entry nil start
(point)))
299 ;; Parse the thebibliography environment
300 (defun reftex-extract-bib-entries-from-thebibliography (files)
301 ;; Extract bib-entries from the \begin{thebibliography} environment.
302 ;; Parsing is not as good as for the BibTeX database stuff.
303 ;; The environment should be located in file FILE.
305 (let* (start end buf entries re re-list file
)
307 (error "Need file name to find thebibliography environment"))
308 (while (setq file
(pop files
))
309 (setq buf
(reftex-get-file-buffer-force
310 file
(not reftex-keep-temporary-buffers
)))
312 (error "No such file %s" file
))
313 (message "Scanning thebibliography environment in %s" file
)
319 (goto-char (point-min))
320 (while (re-search-forward
321 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\begin{thebibliography}" nil t
)
322 (beginning-of-line 2)
324 (if (re-search-forward
325 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\end{thebibliography}" nil t
)
327 (beginning-of-line 1)
329 (when (and start end
)
332 (mapcar 'reftex-parse-bibitem
335 (buffer-substring-no-properties start end
)
336 "[ \t\n\r]*\\\\bibitem\\(\\[[^]]*]\\)*"))))))
339 (error "No bibitems found"))
341 (setq re-list
(split-string
342 (read-string "RegExp [ && RegExp...]: "
343 nil
'reftex-cite-regexp-hist
)
345 (if (string-match "\\`[ \t]*\\'" (car re-list
))
346 (error "Empty regular expression"))
348 (while (and (setq re
(pop re-list
)) entries
)
352 (if (string-match re
(cdr (assoc "&entry" x
)))
358 (push (cons "&formatted" (reftex-format-bibitem x
)) x
)
359 (push (reftex-get-bib-field "&key" x
) x
)
365 ;; Parse and format individual entries
367 (defun reftex-get-bib-names (field entry
)
368 ;; Return a list with the author or editor names in ENTRY
369 (let ((names (reftex-get-bib-field field entry
)))
371 (setq names
(reftex-get-bib-field "editor" entry
)))
372 (while (string-match "\\band\\b[ \t]*" names
)
373 (setq names
(replace-match "\n" nil t names
)))
374 (while (string-match "[\\.a-zA-Z\\-]+\\.[ \t]*\\|,.*\\|[{}]+" names
)
375 (setq names
(replace-match "" nil t names
)))
376 (while (string-match "^[ \t]+\\|[ \t]+$" names
)
377 (setq names
(replace-match "" nil t names
)))
378 (while (string-match "[ \t][ \t]+" names
)
379 (setq names
(replace-match " " nil t names
)))
380 (split-string names
"\n")))
382 (defun reftex-parse-bibtex-entry (entry &optional from to
)
383 (let (alist key start field
)
388 (set-buffer (get-buffer-create " *RefTeX-scratch*"))
393 (narrow-to-region from to
))
394 (goto-char (point-min))
396 (if (re-search-forward
397 "@\\(\\w+\\)[ \t\n\r]*[{(][ \t\n\r]*\\([^ \t\n\r,]+\\)" nil t
)
400 (cons "&type" (downcase (reftex-match-string 1)))
401 (cons "&key" (reftex-match-string 2)))))
402 (while (re-search-forward "\\(\\w+\\)[ \t\n\r]*=[ \t\n\r]*" nil t
)
403 (setq key
(downcase (reftex-match-string 1)))
405 ((= (following-char) ?
{)
411 ((= (following-char) ?
\")
414 (while (and (search-forward "\"" nil t
)
415 (= ?
\\ (char-after (- (point) 2))))))
418 (re-search-forward "[ \t]*[\n\r,}]" nil
1)))
419 (setq field
(buffer-substring-no-properties start
(1- (point))))
420 ;; remove extra whitespace
421 (while (string-match "[\n\t\r]\\|[ \t][ \t]+" field
)
422 (setq field
(replace-match " " nil t field
)))
423 ;; remove leading garbage
424 (if (string-match "^[ \t{]+" field
)
425 (setq field
(replace-match "" nil t field
)))
426 ;; remove trailing garbage
427 (if (string-match "[ \t}]+$" field
)
428 (setq field
(replace-match "" nil t field
)))
429 (push (cons key field
) alist
))))
432 (defun reftex-get-bib-field (fieldname entry
&optional format
)
433 ;; Extract the field FIELDNAME from an ENTRY
434 (let ((cell (assoc fieldname entry
)))
437 (format format
(cdr cell
))
441 (defun reftex-format-bib-entry (entry)
442 ;; Format a BibTeX ENTRY so that it is nice to look at
444 ((auth-list (reftex-get-bib-names "author" entry
))
445 (authors (mapconcat 'identity auth-list
", "))
446 (year (reftex-get-bib-field "year" entry
))
447 (title (reftex-get-bib-field "title" entry
))
448 (type (reftex-get-bib-field "&type" entry
))
449 (key (reftex-get-bib-field "&key" entry
))
452 ((equal type
"article")
453 (concat (reftex-get-bib-field "journal" entry
) " "
454 (reftex-get-bib-field "volume" entry
) ", "
455 (reftex-get-bib-field "pages" entry
)))
457 (concat "book (" (reftex-get-bib-field "publisher" entry
) ")"))
458 ((equal type
"phdthesis")
459 (concat "PhD: " (reftex-get-bib-field "school" entry
)))
460 ((equal type
"mastersthesis")
461 (concat "Master: " (reftex-get-bib-field "school" entry
)))
462 ((equal type
"inbook")
463 (concat "Chap: " (reftex-get-bib-field "chapter" entry
)
464 ", pp. " (reftex-get-bib-field "pages" entry
)))
465 ((or (equal type
"conference")
466 (equal type
"incollection")
467 (equal type
"inproceedings"))
468 (reftex-get-bib-field "booktitle" entry
"in: %s"))
470 (setq authors
(reftex-truncate authors
30 t t
))
471 (when (reftex-use-fonts)
472 (put-text-property 0 (length key
) 'face
473 (reftex-verified-face reftex-label-face
474 'font-lock-constant-face
475 'font-lock-reference-face
)
477 (put-text-property 0 (length authors
) 'face reftex-bib-author-face
479 (put-text-property 0 (length year
) 'face reftex-bib-year-face
481 (put-text-property 0 (length title
) 'face reftex-bib-title-face
483 (put-text-property 0 (length extra
) 'face reftex-bib-extra-face
485 (concat key
"\n " authors
" " year
" " extra
"\n " title
"\n\n")))
487 (defun reftex-parse-bibitem (item)
488 ;; Parse a \bibitem entry
489 (let ((key "") (text ""))
490 (when (string-match "\\`{\\([^}]+\\)}\\([\001-\255]*\\)" item
)
491 (setq key
(match-string 1 item
)
492 text
(match-string 2 item
)))
493 ;; Clean up the text a little bit
494 (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text
)
495 (setq text
(replace-match " " nil t text
)))
496 (if (string-match "\\`[ \t]+" text
)
497 (setq text
(replace-match "" nil t text
)))
501 (cons "&entry" (concat key
" " text
)))))
503 (defun reftex-format-bibitem (item)
504 ;; Format a \bibitem entry so that it is (relatively) nice to look at.
505 (let ((text (reftex-get-bib-field "&text" item
))
506 (key (reftex-get-bib-field "&key" item
))
509 ;; Wrap the text into several lines.
510 (while (and (> (length text
) 70)
511 (string-match " " (substring text
60)))
512 (push (substring text
0 (+ 60 (match-beginning 0))) lines
)
513 (setq text
(substring text
(+ 61 (match-beginning 0)))))
515 (setq text
(mapconcat 'identity
(nreverse lines
) "\n "))
517 (when (reftex-use-fonts)
518 (put-text-property 0 (length text
) 'face reftex-bib-author-face text
))
519 (concat key
"\n " text
"\n\n")))
524 (defun reftex-citation (&optional no-insert format-key
)
525 "Make a citation using BibTeX database files.
526 After prompting for a regular expression, scans the buffers with
527 bibtex entries (taken from the \\bibliography command) and offers the
528 matching entries for selection. The selected entry is formated according
529 to `reftex-cite-format' and inserted into the buffer.
531 If NO-INSERT is non-nil, nothing is inserted, only the selected key returned.
533 FORAT-KEY can be used to pre-select a citation format.
535 When called with one or two `C-u' prefixes, first rescans the document.
536 When called with a numeric prefix, make that many citations. When
537 called with point inside the braces of a `\cite' command, it will
538 add another key, ignoring the value of `reftex-cite-format'.
540 The regular expression uses an expanded syntax: && is interpreted as `and'.
541 Thus, `aaaa&&bbb' matches entries which contain both `aaaa' and `bbb'.
542 While entering the regexp, completion on knows citation keys is possible.
543 `=' is a good regular expression to match all entries in all files."
547 ;; check for recursive edit
548 (reftex-check-recursive-edit)
550 ;; This function may also be called outside reftex-mode.
551 ;; Thus look for the scanning info only if in reftex-mode.
554 (reftex-access-scan-info current-prefix-arg
))
556 ;; Call reftex-do-citation, but protected
558 (reftex-do-citation current-prefix-arg no-insert format-key
)
559 (reftex-kill-temporary-buffers)))
561 (defun reftex-do-citation (&optional arg no-insert format-key
)
562 ;; This really does the work of reftex-citation.
564 (let* ((format (reftex-figure-out-cite-format arg no-insert format-key
))
565 (docstruct-symbol reftex-docstruct-symbol
)
566 (selected-entries (reftex-offer-bib-menu))
567 (insert-entries selected-entries
)
568 entry string cite-view
)
570 (unless selected-entries
(error "Quit"))
572 (if (stringp selected-entries
)
574 (setq selected-entries nil
575 insert-entries
(list (list selected-entries
576 (cons "&key" selected-entries
))))
577 ;; It makes sense to compute the cite-view strings.
580 (when (eq (car selected-entries
) 'concat
)
581 ;; All keys go into a single command - we need to trick a little
582 (pop selected-entries
)
583 (let ((concat-keys (mapconcat 'car selected-entries
",")))
585 (list (list concat-keys
(cons "&key" concat-keys
))))))
589 ;; We shall insert this into the buffer...
590 (message "Formatting...")
592 (while (setq entry
(pop insert-entries
))
593 ;; Format the citation and insert it
594 (setq string
(if reftex-format-cite-function
595 (funcall reftex-format-cite-function
596 (reftex-get-bib-field "&key" entry
)
598 (reftex-format-citation entry format
)))
601 ;; Reposition cursor?
602 (when (string-match "\\?" string
)
603 (search-backward "?")
607 (when (and reftex-mode
608 (fboundp 'LaTeX-add-bibitems
)
609 reftex-plug-into-AUCTeX
)
610 (apply 'LaTeX-add-bibitems
(mapcar 'car selected-entries
)))
612 ;; Produce the cite-view strings
613 (when (and reftex-mode reftex-cache-cite-echo cite-view
)
614 (mapcar (lambda (entry)
615 (reftex-make-cite-echo-string entry docstruct-symbol
))
620 (set-marker reftex-select-return-marker nil
)
621 (reftex-kill-buffer "*RefTeX Select*")
623 ;; Check if the prefix arg was numeric, and call recursively
627 (skip-chars-backward "}")
629 (reftex-do-citation arg
))
632 ;; Return the citation key
633 (car (car selected-entries
))))
635 (defun reftex-figure-out-cite-format (arg &optional no-insert format-key
)
636 ;; Check if there is already a cite command at point and change cite format
637 ;; in order to only add another reference in the same cite command.
638 (let ((macro (car (reftex-what-macro 1)))
639 (cite-format-value (reftex-get-cite-format))
643 ;; Format does not really matter because nothing will be inserted.
646 ((and (stringp macro
)
647 (string-match "\\`\\\\cite\\|cite\\'" macro
))
648 ;; We are already inside a cite macro
649 (if (or (not arg
) (not (listp arg
)))
652 (if (member (preceding-char) '(?\
{ ?
,)) "" ",")
654 (if (member (following-char) '(?\
} ?
,)) "" ",")))
657 ;; Figure out the correct format
659 (if (and (symbolp cite-format-value
)
660 (assq cite-format-value reftex-cite-format-builtin
))
661 (nth 2 (assq cite-format-value reftex-cite-format-builtin
))
666 (reftex-select-with-char
667 "" (concat "SELECT A CITATION FORMAT\n\n"
670 (format "[%c] %s %s" (car x
)
671 (if (> (car x
) 31) " " "")
674 (if (assq key format
)
675 (setq format
(cdr (assq key format
)))
676 (error "No citation format associated with key `%c'" key
)))))
679 (defun reftex-citep ()
680 "Call `reftex-citation' with a format selector `?p'."
682 (reftex-citation nil ?p
))
684 (defun reftex-citet ()
685 "Call `reftex-citation' with a format selector `?t'."
687 (reftex-citation nil ?t
))
689 (defvar reftex-select-bib-map
)
690 (defun reftex-offer-bib-menu ()
691 ;; Offer bib menu and return list of selected items
693 (let (found-list rtn key data selected-entries
)
700 ((assq 'bib
(symbol-value reftex-docstruct-symbol
))
701 ;; using BibTeX database files.
702 (reftex-extract-bib-entries (reftex-get-bibfile-list)))
703 ((assq 'thebib
(symbol-value reftex-docstruct-symbol
))
704 ;; using thebibliography environment.
705 (reftex-extract-bib-entries-from-thebibliography
709 'thebib
(symbol-value reftex-docstruct-symbol
))))))
710 (reftex-default-bibliography
711 (message "Using default bibliography")
712 (reftex-extract-bib-entries (reftex-default-bibliography)))
713 (t (error "No valid bibliography in this document, and no default available"))))
716 (error "Sorry, no matches found"))
718 ;; Remember where we came from
719 (setq reftex-call-back-to-this-buffer
(current-buffer))
720 (set-marker reftex-select-return-marker
(point))
723 (save-window-excursion
724 (delete-other-windows)
725 (let ((default-major-mode 'reftex-select-bib-mode
))
726 (reftex-kill-buffer "*RefTeX Select*")
727 (switch-to-buffer-other-window "*RefTeX Select*")
728 (unless (eq major-mode
'reftex-select-bib-mode
)
729 (reftex-select-bib-mode))
730 (let ((buffer-read-only nil
))
732 (reftex-insert-bib-matches found-list
)))
733 (setq buffer-read-only t
)
734 (if (= 0 (buffer-size))
735 (error "No matches found"))
736 (setq truncate-lines t
)
741 reftex-citation-prompt
743 reftex-select-bib-map
745 'reftex-bibtex-selection-callback nil
))
748 (unless key
(throw 'done t
))
754 ;; Restrict with new regular expression
755 (setq found-list
(reftex-restrict-bib-matches found-list
))
756 (let ((buffer-read-only nil
))
758 (reftex-insert-bib-matches found-list
))
762 (setq selected-entries
763 (if reftex-select-marked
764 (mapcar 'car
(nreverse reftex-select-marked
))
768 ;; Take all (marked), and push the symbol 'concat
769 (setq selected-entries
771 (if reftex-select-marked
772 (mapcar 'car
(nreverse reftex-select-marked
))
778 (setq selected-entries
779 (if reftex-select-marked
781 (mapcar 'car
(nreverse reftex-select-marked
)))
782 (if data
(list data
) nil
)))
785 ;; Got this one with completion
786 (setq selected-entries key
)
792 (defun reftex-restrict-bib-matches (found-list)
793 ;; Limit FOUND-LIST with more regular expressions
794 (let ((re-list (split-string (read-string
795 "RegExp [ && RegExp...]: "
796 nil
'reftex-cite-regexp-hist
)
798 (found-list-r found-list
)
800 (while (setq re
(pop re-list
))
806 re
(cdr (assoc "&entry" x
)))
815 (defun reftex-insert-bib-matches (list)
816 ;; Insert the bib matches and number them correctly
818 (if (memq reftex-highlight-selection
'(mouse both
))
819 reftex-mouse-selected-face
824 (setq tmp
(cdr (assoc "&formatted" x
))
826 (put-text-property 0 len
:data x tmp
)
827 (put-text-property 0 (1- len
) 'mouse-face mouse-face tmp
)
830 (run-hooks 'reftex-display-copied-context-hook
))
832 (defun reftex-format-names (namelist n
)
833 (let (last (len (length namelist
)))
836 ((= 1 len
) (car namelist
))
837 ((> len n
) (concat (car namelist
) (nth 2 reftex-cite-punctuation
)))
840 last
(nth (1- n
) namelist
))
841 (setcdr (nthcdr (- n
2) namelist
) nil
)
843 (mapconcat 'identity namelist
(nth 0 reftex-cite-punctuation
))
844 (nth 1 reftex-cite-punctuation
)
847 (defun reftex-format-citation (entry format
)
848 ;; Format a citation from the info in the BibTeX ENTRY
850 (unless (stringp format
) (setq format
"\\cite{%l}"))
852 (if (and reftex-comment-citations
853 (string-match "%l" reftex-cite-comment-format
))
854 (error "reftex-cite-comment-format contains illegal %%l"))
857 "\\(\\`\\|[^%]\\)\\(\\(%\\([0-9]*\\)\\([a-zA-Z]\\)\\)[.,;: ]*\\)"
859 (let ((n (string-to-int (match-string 4 format
)))
860 (l (string-to-char (match-string 5 format
)))
866 (reftex-get-bib-field "&key" entry
)
867 (if reftex-comment-citations
868 reftex-cite-comment-format
870 ((= l ?a
) (reftex-format-names
871 (reftex-get-bib-names "author" entry
)
873 ((= l ?A
) (car (reftex-get-bib-names "author" entry
)))
874 ((= l ?b
) (reftex-get-bib-field "booktitle" entry
"in: %s"))
875 ((= l ?B
) (reftex-abbreviate-title
876 (reftex-get-bib-field "booktitle" entry
"in: %s")))
877 ((= l ?c
) (reftex-get-bib-field "chapter" entry
))
878 ((= l ?d
) (reftex-get-bib-field "edition" entry
))
879 ((= l ?e
) (reftex-format-names
880 (reftex-get-bib-names "editor" entry
)
882 ((= l ?E
) (car (reftex-get-bib-names "editor" entry
)))
883 ((= l ?h
) (reftex-get-bib-field "howpublished" entry
))
884 ((= l ?i
) (reftex-get-bib-field "institution" entry
))
885 ((= l ?j
) (reftex-get-bib-field "journal" entry
))
886 ((= l ?k
) (reftex-get-bib-field "key" entry
))
887 ((= l ?m
) (reftex-get-bib-field "month" entry
))
888 ((= l ?n
) (reftex-get-bib-field "number" entry
))
889 ((= l ?o
) (reftex-get-bib-field "organization" entry
))
890 ((= l ?p
) (reftex-get-bib-field "pages" entry
))
891 ((= l ?P
) (car (split-string
892 (reftex-get-bib-field "pages" entry
)
894 ((= l ?s
) (reftex-get-bib-field "school" entry
))
895 ((= l ?u
) (reftex-get-bib-field "publisher" entry
))
896 ((= l ?r
) (reftex-get-bib-field "address" entry
))
897 ((= l ?t
) (reftex-get-bib-field "title" entry
))
898 ((= l ?T
) (reftex-abbreviate-title
899 (reftex-get-bib-field "title" entry
)))
900 ((= l ?v
) (reftex-get-bib-field "volume" entry
))
901 ((= l ?y
) (reftex-get-bib-field "year" entry
)))))
904 (setq b
(match-beginning 2) e
(match-end 2))
905 (setq b
(match-beginning 3) e
(match-end 3)))
906 (setq format
(concat (substring format
0 b
) rpl
(substring format e
)))))
907 (while (string-match "%%" format
)
908 (setq format
(replace-match "%" t t format
)))
909 (while (string-match "[ ,.;:]*%<" format
)
910 (setq format
(replace-match "" t t format
)))
913 (defun reftex-make-cite-echo-string (entry docstruct-symbol
)
914 ;; Format a bibtex entry for the echo area and cache the result.
915 (let* ((key (reftex-get-bib-field "&key" entry
))
917 (let* ((reftex-cite-punctuation '(" " " & " " etal.")))
918 (reftex-format-citation entry reftex-cite-view-format
)))
919 (cache (assq 'bibview-cache
(symbol-value docstruct-symbol
)))
920 (cache-entry (assoc key
(cdr cache
))))
922 ;; This docstruct has no cache - make one.
923 (set docstruct-symbol
(cons (cons 'bibview-cache nil
)
924 (symbol-value docstruct-symbol
))))
925 (when reftex-cache-cite-echo
926 (setq key
(copy-sequence key
))
927 (set-text-properties 0 (length key
) nil key
)
928 (set-text-properties 0 (length string
) nil string
)
930 (unless (string= (cdr cache-entry
) string
)
931 (setcdr cache-entry string
)
932 (put reftex-docstruct-symbol
'modified t
))
933 (push (cons key string
) (cdr cache
))
934 (put reftex-docstruct-symbol
'modified t
)))
937 (defun reftex-bibtex-selection-callback (data ignore no-revisit
)
938 ;; Callback function to be called from the BibTeX selection, in
939 ;; order to display context. This function is relatively slow and not
940 ;; recommended for follow mode. It works OK for individual lookups.
941 (let ((win (selected-window))
942 (key (reftex-get-bib-field "&key" data
))
947 (set-buffer reftex-call-back-to-this-buffer
)
949 ((assq 'bib
(symbol-value reftex-docstruct-symbol
))
950 (setq bibfile-list
(reftex-get-bibfile-list)))
951 ((assq 'thebib
(symbol-value reftex-docstruct-symbol
))
956 'thebib
(symbol-value reftex-docstruct-symbol
))))
958 (reftex-default-bibliography
959 (setq bibfile-list
(reftex-default-bibliography)))
960 (t (ding) (throw 'exit
))))
963 (setq bibfile-list
(reftex-visited-files bibfile-list
)))
966 (reftex-pop-to-bibtex-entry
967 key bibfile-list
(not reftex-keep-temporary-buffers
) t item
)
970 (select-window win
)))
972 ;;; reftex-cite.el ends here