1 ;;; reftex-cite.el - Creating citations with RefTeX
4 ;;; See main file reftex.el for licensing information
10 ;; Variables and constants
12 ;; The history list of regular expressions used for citations
13 (defvar reftex-cite-regexp-hist nil
)
15 ;; Prompt and help string for citation selection
16 (defconst reftex-citation-prompt
17 "Select: [n]ext [p]revious [r]estrict [ ]full_entry [q]uit RET [?]Help+more")
19 (defconst reftex-citation-help
20 " n / p Go to next/previous entry (Cursor motion works as well).
21 g / r Start over with new regexp / Refine with additional regexp.
22 SPC Show full database entry in other window.
23 f Toggle follow mode: Other window will follow with full db entry.
24 . Show insertion point.
25 q Quit without inserting \\cite macro into buffer.
26 TAB Enter citation key with completion.
27 RET Accept current entry (also on mouse-2) and create \\cite macro.
28 m / u Mark/Unmark the entry.
29 a / A Put all (marked) entries into one/many \\cite commands.")
33 (defun reftex-default-bibliography ()
34 ;; Return the expanded value of `reftex-default-bibliography'.
35 ;; The expanded value is cached.
36 (unless (eq (get 'reftex-default-bibliography
:reftex-raw
)
37 reftex-default-bibliography
)
38 (put 'reftex-default-bibliography
:reftex-expanded
39 (reftex-locate-bibliography-files
40 default-directory reftex-default-bibliography
))
41 (put 'reftex-default-bibliography
:reftex-raw
42 reftex-default-bibliography
))
43 (get 'reftex-default-bibliography
:reftex-expanded
))
45 (defun reftex-get-bibfile-list ()
46 ;; Return list of bibfiles for current document.
47 ;; When using the chapterbib or bibunits package you should either
48 ;; use the same database files everywhere, or separate parts using
49 ;; different databases into different files (included into the mater file).
50 ;; Then this function will return the applicable database files.
52 ;; Ensure access to scanning info
53 (reftex-access-scan-info)
55 ;; Try inside this file (and its includes)
56 (cdr (reftex-last-assoc-before-elt
57 'bib
(list 'eof
(buffer-file-name))
58 (member (list 'bof
(buffer-file-name))
59 (symbol-value reftex-docstruct-symbol
))))
60 ;; Try after the beginning of this file
61 (cdr (assq 'bib
(member (list 'bof
(buffer-file-name))
62 (symbol-value reftex-docstruct-symbol
))))
63 ;; Anywhere in the entire document
64 (cdr (assq 'bib
(symbol-value reftex-docstruct-symbol
)))
65 (error "\\bibliography statement missing or .bib files not found")))
67 ;; Find a certain reference in any of the BibTeX files.
69 (defun reftex-pop-to-bibtex-entry (key file-list
&optional mark-to-kill
70 highlight item return
)
71 ;; Find BibTeX KEY in any file in FILE-LIST in another window.
72 ;; If MARK-TO-KILL is non-nil, mark new buffer to kill.
73 ;; If HIGHLIGHT is non-nil, highlight the match.
74 ;; If ITEM in non-nil, search for bibitem instead of database entry.
75 ;; If RETURN is non-nil, just return the entry.
79 (concat "\\\\bibitem\\(\\[[^]]*\\]\\)?{" (regexp-quote key
) "}")
80 (concat "@[a-zA-Z]+[ \t\n\r]*[{(][ \t\n\r]*" (regexp-quote key
)
82 (buffer-conf (current-buffer))
87 (setq file
(car file-list
)
88 file-list
(cdr file-list
))
89 (unless (setq buf
(reftex-get-file-buffer-force file mark-to-kill
))
90 (error "No such file %s" file
))
93 (goto-char (point-min))
94 (when (re-search-forward re nil t
)
95 (goto-char (match-beginning 0))
98 ;; Just return the relevant entry
99 (if item
(goto-char (match-end 0)))
100 (setq return
(buffer-substring
101 (point) (reftex-end-of-bib-entry item
)))
102 (set-buffer buffer-conf
)
103 (throw 'exit return
))
104 (switch-to-buffer-other-window buf
)
108 (reftex-highlight 0 (match-beginning 0) (match-end 0)))
109 (throw 'exit
(selected-window))))
110 (set-buffer buffer-conf
)
112 (error "No \\bibitem with citation key %s" key
)
113 (error "No BibTeX entry with citation key %s" key
)))))
115 (defun reftex-end-of-bib-entry (item)
121 "\\\\bibitem\\|\\end{thebibliography}")
122 (1- (match-beginning 0)))
123 (progn (forward-list 1) (point)))
124 (error (min (point-max) (+ 300 (point)))))))
126 ;; Parse bibtex buffers
128 (defun reftex-extract-bib-entries (buffers)
129 ;; Extract bib entries which match regexps from BUFFERS.
130 ;; BUFFERS is a list of buffers or file names.
131 ;; Return list with entries."
132 (let* (re-list first-re rest-re
133 (buffer-list (if (listp buffers
) buffers
(list buffers
)))
134 found-list entry buffer1 buffer alist
135 key-point start-point end-point
)
137 ;; Read a regexp, completing on known citation keys.
141 "RegExp [ && RegExp...]: "
143 (if (fboundp 'LaTeX-bibitem-list
)
145 (cdr (assoc 'bibview-cache
146 (symbol-value reftex-docstruct-symbol
))))
148 nil nil nil
'reftex-cite-regexp-hist
)
151 (setq first-re
(car re-list
) ; We'll use the first re to find things,
152 rest-re
(cdr re-list
)) ; the others to narrow down.
153 (if (string-match "\\`[ \t]*\\'" (or first-re
""))
154 (error "Empty regular expression"))
157 (save-window-excursion
159 ;; Walk through all bibtex files
161 (setq buffer
(car buffer-list
)
162 buffer-list
(cdr buffer-list
))
163 (if (and (bufferp buffer
)
164 (buffer-live-p buffer
))
165 (setq buffer1 buffer
)
166 (setq buffer1
(reftex-get-file-buffer-force
167 buffer
(not reftex-keep-temporary-buffers
))))
169 (message "No such BibTeX file %s (ignored)" buffer
)
170 (message "Scanning bibliography database %s" buffer1
))
174 (goto-char (point-min))
175 (while (re-search-forward first-re nil t
)
177 (setq key-point
(point))
178 (unless (re-search-backward
179 "\\(\\`\\|[\n\r]\\)[ \t]*@\\([a-zA-Z]+\\)[ \t\n\r]*[{(]" nil t
)
180 (throw 'search-again nil
))
181 (setq start-point
(point))
182 (goto-char (match-end 0))
185 (error (goto-char key-point
)
186 (throw 'search-again nil
)))
187 (setq end-point
(point))
189 ;; Ignore @string, @comment and @c entries or things
191 (when (or (string= (downcase (match-string 2)) "string")
192 (string= (downcase (match-string 2)) "comment")
193 (string= (downcase (match-string 2)) "c")
194 (< (point) key-point
)) ; this means match not in {}
195 (goto-char key-point
)
196 (throw 'search-again nil
))
198 ;; Well, we have got a match
200 (buffer-substring start-point
(point)) "\n"))
202 ;; Check if other regexp match as well
203 (setq re-list rest-re
)
205 (unless (string-match (car re-list
) entry
)
207 (throw 'search-again nil
))
210 (setq alist
(reftex-parse-bibtex-entry
211 nil start-point end-point
))
212 (push (cons "&entry" entry
) alist
)
214 ;; check for crossref entries
215 (if (assoc "crossref" alist
)
218 alist
(reftex-get-crossref-alist alist
))))
221 (push (cons "&formatted" (reftex-format-bib-entry alist
))
224 ;; make key the first element
225 (push (reftex-get-bib-field "&key" alist
) alist
)
227 ;; add it to the list
228 (push alist found-list
))))
229 (reftex-kill-temporary-buffers))))
230 (setq found-list
(nreverse found-list
))
234 ((eq 'author reftex-sort-bibtex-matches
)
235 (sort found-list
'reftex-bib-sort-author
))
236 ((eq 'year reftex-sort-bibtex-matches
)
237 (sort found-list
'reftex-bib-sort-year
))
238 ((eq 'reverse-year reftex-sort-bibtex-matches
)
239 (sort found-list
'reftex-bib-sort-year-reverse
))
242 (defun reftex-bib-sort-author (e1 e2
)
243 (let ((al1 (reftex-get-bib-names "author" e1
))
244 (al2 (reftex-get-bib-names "author" e2
)))
245 (while (and al1 al2
(string= (car al1
) (car al2
)))
248 (if (and (stringp (car al1
))
250 (string< (car al1
) (car al2
))
251 (not (stringp (car al1
))))))
253 (defun reftex-bib-sort-year (e1 e2
)
254 (< (string-to-int (cdr (assoc "year" e1
)))
255 (string-to-int (cdr (assoc "year" e2
)))))
257 (defun reftex-bib-sort-year-reverse (e1 e2
)
258 (> (string-to-int (or (cdr (assoc "year" e1
)) "0"))
259 (string-to-int (or (cdr (assoc "year" e2
)) "0"))))
261 (defun reftex-get-crossref-alist (entry)
262 ;; return the alist from a crossref entry
263 (let ((crkey (cdr (assoc "crossref" entry
)))
268 (if (re-search-forward
269 (concat "@\\w+[{(][ \t\n\r]*" (regexp-quote crkey
)
270 "[ \t\n\r]*,") nil t
)
272 (setq start
(match-beginning 0))
276 (reftex-parse-bibtex-entry nil start
(point)))
279 ;; Parse the thebibliography environment
280 (defun reftex-extract-bib-entries-from-thebibliography (files)
281 ;; Extract bib-entries from the \begin{thebibliography} environment.
282 ;; Parsing is not as good as for the BibTeX database stuff.
283 ;; The environment should be located in file FILE.
285 (let* (start end buf entries re re-list file
)
287 (error "Need file name to find thebibliography environment"))
288 (while (setq file
(pop files
))
289 (setq buf
(reftex-get-file-buffer-force
290 file
(not reftex-keep-temporary-buffers
)))
292 (error "No such file %s" file
))
293 (message "Scanning thebibliography environment in %s" file
)
299 (goto-char (point-min))
300 (while (re-search-forward
301 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\begin{thebibliography}" nil t
)
302 (beginning-of-line 2)
304 (if (re-search-forward
305 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\end{thebibliography}" nil t
)
307 (beginning-of-line 1)
309 (when (and start end
)
312 (mapcar 'reftex-parse-bibitem
315 (buffer-substring-no-properties start end
)
316 "[ \t\n\r]*\\\\bibitem\\(\\[[^]]*]\\)*"))))))
319 (error "No bibitems found"))
321 (setq re-list
(split-string
322 (read-string "RegExp [ && RegExp...]: "
323 nil
'reftex-cite-regexp-hist
)
325 (if (string-match "\\`[ \t]*\\'" (car re-list
))
326 (error "Empty regular expression"))
328 (while (and (setq re
(pop re-list
)) entries
)
332 (if (string-match re
(cdr (assoc "&entry" x
)))
338 (push (cons "&formatted" (reftex-format-bibitem x
)) x
)
339 (push (reftex-get-bib-field "&key" x
) x
)
345 ;; Parse and format individual entries
347 (defun reftex-get-bib-names (field entry
)
348 ;; Return a list with the author or editor names in ENTRY
349 (let ((names (reftex-get-bib-field field entry
)))
351 (setq names
(reftex-get-bib-field "editor" entry
)))
352 (while (string-match "\\band\\b[ \t]*" names
)
353 (setq names
(replace-match "\n" nil t names
)))
354 (while (string-match "[\\.a-zA-Z\\-]+\\.[ \t]*\\|,.*\\|[{}]+" names
)
355 (setq names
(replace-match "" nil t names
)))
356 (while (string-match "^[ \t]+\\|[ \t]+$" names
)
357 (setq names
(replace-match "" nil t names
)))
358 (while (string-match "[ \t][ \t]+" names
)
359 (setq names
(replace-match " " nil t names
)))
360 (split-string names
"\n")))
362 (defun reftex-parse-bibtex-entry (entry &optional from to
)
363 (let (alist key start field
)
368 (set-buffer (get-buffer-create " *RefTeX-scratch*"))
373 (narrow-to-region from to
))
374 (goto-char (point-min))
376 (if (re-search-forward
377 "@\\(\\w+\\)[ \t\n\r]*[{(][ \t\n\r]*\\([^ \t\n\r,]+\\)" nil t
)
380 (cons "&type" (downcase (reftex-match-string 1)))
381 (cons "&key" (reftex-match-string 2)))))
382 (while (re-search-forward "\\(\\w+\\)[ \t\n\r]*=[ \t\n\r]*" nil t
)
383 (setq key
(downcase (reftex-match-string 1)))
385 ((= (following-char) ?
{)
391 ((= (following-char) ?
\")
394 (while (and (search-forward "\"" nil t
)
395 (= ?
\\ (char-after (- (point) 2))))))
398 (re-search-forward "[ \t]*[\n\r,}]" nil
1)))
399 (setq field
(buffer-substring-no-properties start
(1- (point))))
400 ;; remove extra whitespace
401 (while (string-match "[\n\t\r]\\|[ \t][ \t]+" field
)
402 (setq field
(replace-match " " nil t field
)))
403 ;; remove leading garbage
404 (if (string-match "^[ \t{]+" field
)
405 (setq field
(replace-match "" nil t field
)))
406 ;; remove trailing garbage
407 (if (string-match "[ \t}]+$" field
)
408 (setq field
(replace-match "" nil t field
)))
409 (push (cons key field
) alist
))))
412 (defun reftex-get-bib-field (fieldname entry
&optional format
)
413 ;; Extract the field FIELDNAME from an ENTRY
414 (let ((cell (assoc fieldname entry
)))
417 (format format
(cdr cell
))
421 (defun reftex-format-bib-entry (entry)
422 ;; Format a BibTeX ENTRY so that it is nice to look at
424 ((auth-list (reftex-get-bib-names "author" entry
))
425 (authors (mapconcat 'identity auth-list
", "))
426 (year (reftex-get-bib-field "year" entry
))
427 (title (reftex-get-bib-field "title" entry
))
428 (type (reftex-get-bib-field "&type" entry
))
429 (key (reftex-get-bib-field "&key" entry
))
432 ((equal type
"article")
433 (concat (reftex-get-bib-field "journal" entry
) " "
434 (reftex-get-bib-field "volume" entry
) ", "
435 (reftex-get-bib-field "pages" entry
)))
437 (concat "book (" (reftex-get-bib-field "publisher" entry
) ")"))
438 ((equal type
"phdthesis")
439 (concat "PhD: " (reftex-get-bib-field "school" entry
)))
440 ((equal type
"mastersthesis")
441 (concat "Master: " (reftex-get-bib-field "school" entry
)))
442 ((equal type
"inbook")
443 (concat "Chap: " (reftex-get-bib-field "chapter" entry
)
444 ", pp. " (reftex-get-bib-field "pages" entry
)))
445 ((or (equal type
"conference")
446 (equal type
"incollection")
447 (equal type
"inproceedings"))
448 (reftex-get-bib-field "booktitle" entry
"in: %s"))
450 (setq authors
(reftex-truncate authors
30 t t
))
451 (when (reftex-use-fonts)
452 (put-text-property 0 (length key
) 'face
453 (reftex-verified-face reftex-label-face
454 'font-lock-constant-face
455 'font-lock-reference-face
)
457 (put-text-property 0 (length authors
) 'face reftex-bib-author-face
459 (put-text-property 0 (length year
) 'face reftex-bib-year-face
461 (put-text-property 0 (length title
) 'face reftex-bib-title-face
463 (put-text-property 0 (length extra
) 'face reftex-bib-extra-face
465 (concat key
"\n " authors
" " year
" " extra
"\n " title
"\n\n")))
467 (defun reftex-parse-bibitem (item)
468 ;; Parse a \bibitem entry
469 (let ((key "") (text ""))
470 (when (string-match "\\`{\\([^}]+\\)}\\([\001-\255]*\\)" item
)
471 (setq key
(match-string 1 item
)
472 text
(match-string 2 item
)))
473 ;; Clean up the text a little bit
474 (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text
)
475 (setq text
(replace-match " " nil t text
)))
476 (if (string-match "\\`[ \t]+" text
)
477 (setq text
(replace-match "" nil t text
)))
481 (cons "&entry" (concat key
" " text
)))))
483 (defun reftex-format-bibitem (item)
484 ;; Format a \bibitem entry so that it is (relatively) nice to look at.
485 (let ((text (reftex-get-bib-field "&text" item
))
486 (key (reftex-get-bib-field "&key" item
))
489 ;; Wrap the text into several lines.
490 (while (and (> (length text
) 70)
491 (string-match " " (substring text
60)))
492 (push (substring text
0 (+ 60 (match-beginning 0))) lines
)
493 (setq text
(substring text
(+ 61 (match-beginning 0)))))
495 (setq text
(mapconcat 'identity
(nreverse lines
) "\n "))
497 (when (reftex-use-fonts)
498 (put-text-property 0 (length text
) 'face reftex-bib-author-face text
))
499 (concat key
"\n " text
"\n\n")))
504 (defun reftex-citation (&optional no-insert
)
505 "Make a citation using BibTeX database files.
506 After prompting for a regular expression, scans the buffers with
507 bibtex entries (taken from the \\bibliography command) and offers the
508 matching entries for selection. The selected entry is formated according
509 to `reftex-cite-format' and inserted into the buffer.
511 If NO-INSERT is non-nil, nothing is inserted, only the selected key returned.
513 When called with one or two `C-u' prefixes, first rescans the document.
514 When called with a numeric prefix, make that many citations. When
515 called with point inside the braces of a `\cite' command, it will
516 add another key, ignoring the value of `reftex-cite-format'.
518 The regular expression uses an expanded syntax: && is interpreted as `and'.
519 Thus, `aaaa&&bbb' matches entries which contain both `aaaa' and `bbb'.
520 While entering the regexp, completion on knows citation keys is possible.
521 `=' is a good regular expression to match all entries in all files."
525 ;; check for recursive edit
526 (reftex-check-recursive-edit)
528 ;; This function may also be called outside reftex-mode.
529 ;; Thus look for the scanning info only if in reftex-mode.
532 (reftex-access-scan-info current-prefix-arg
))
534 ;; Call reftex-do-citation, but protected
536 (reftex-do-citation current-prefix-arg no-insert
)
537 (reftex-kill-temporary-buffers)))
539 (defun reftex-do-citation (&optional arg no-insert
)
540 ;; This really does the work of reftex-citation.
542 (let* ((format (reftex-figure-out-cite-format arg no-insert
))
543 (docstruct-symbol reftex-docstruct-symbol
)
544 (selected-entries (reftex-offer-bib-menu))
545 (insert-entries selected-entries
)
546 entry string cite-view
)
548 (unless selected-entries
(error "Quit"))
550 (if (stringp selected-entries
)
552 (setq selected-entries nil
553 insert-entries
(list (list selected-entries
554 (cons "&key" selected-entries
))))
555 ;; It makes sense to compute the cite-view strings.
558 (when (eq (car selected-entries
) 'concat
)
559 ;; All keys go into a single command - we need to trick a little
560 (pop selected-entries
)
561 (let ((concat-keys (mapconcat 'car selected-entries
",")))
563 (list (list concat-keys
(cons "&key" concat-keys
))))))
567 ;; We shall insert this into the buffer...
568 (message "Formatting...")
570 (while (setq entry
(pop insert-entries
))
571 ;; Format the citation and insert it
572 (setq string
(if reftex-format-cite-function
573 (funcall reftex-format-cite-function
574 (reftex-get-bib-field "&key" entry
)
576 (reftex-format-citation entry format
)))
579 ;; Reposition cursor?
580 (when (string-match "\\?" string
)
581 (search-backward "?")
585 (when (and reftex-mode
586 (fboundp 'LaTeX-add-bibitems
)
587 reftex-plug-into-AUCTeX
)
588 (apply 'LaTeX-add-bibitems
(mapcar 'car selected-entries
)))
590 ;; Produce the cite-view strings
591 (when (and reftex-mode reftex-cache-cite-echo cite-view
)
592 (mapcar (lambda (entry)
593 (reftex-make-cite-echo-string entry docstruct-symbol
))
598 (set-marker reftex-select-return-marker nil
)
599 (reftex-kill-buffer "*RefTeX Select*")
601 ;; Check if the prefix arg was numeric, and call recursively
605 (skip-chars-backward "}")
607 (reftex-do-citation arg
))
610 ;; Return the citation key
611 (car (car selected-entries
))))
613 (defun reftex-figure-out-cite-format (arg no-insert
)
614 ;; Check if there is already a cite command at point and change cite format
615 ;; in order to only add another reference in the same cite command.
616 (let ((macro (car (reftex-what-macro 1)))
617 (cite-format-value (reftex-get-cite-format))
621 ;; Format does not really matter because nothing will be inserted.
624 ((and (stringp macro
)
625 (string-match "\\`\\\\cite\\|cite\\'" macro
))
626 ;; We are already inside a cite macro
627 (if (or (not arg
) (not (listp arg
)))
630 (if (member (preceding-char) '(?\
{ ?
,)) "" ",")
632 (if (member (following-char) '(?\
} ?
,)) "" ",")))
635 ;; Figure out the correct format
637 (if (and (symbolp cite-format-value
)
638 (assq cite-format-value reftex-cite-format-builtin
))
639 (nth 2 (assq cite-format-value reftex-cite-format-builtin
))
643 (reftex-select-with-char
644 "" (concat "SELECT A CITATION FORMAT\n\n"
647 (format "[%c] %s %s" (car x
)
648 (if (> (car x
) 31) " " "")
651 (if (assq key format
)
652 (setq format
(cdr (assq key format
)))
653 (error "No citation format associated with key `%c'" key
)))))
656 (defvar reftex-select-bib-map
)
657 (defun reftex-offer-bib-menu ()
658 ;; Offer bib menu and return list of selected items
660 (let (found-list rtn key data selected-entries
)
667 ((assq 'bib
(symbol-value reftex-docstruct-symbol
))
668 ;; using BibTeX database files.
669 (reftex-extract-bib-entries (reftex-get-bibfile-list)))
670 ((assq 'thebib
(symbol-value reftex-docstruct-symbol
))
671 ;; using thebibliography environment.
672 (reftex-extract-bib-entries-from-thebibliography
676 'thebib
(symbol-value reftex-docstruct-symbol
))))))
677 (reftex-default-bibliography
678 (message "Using default bibliography")
679 (reftex-extract-bib-entries (reftex-default-bibliography)))
680 (t (error "No valid bibliography in this document, and no default available"))))
683 (error "Sorry, no matches found"))
685 ;; Remember where we came from
686 (setq reftex-call-back-to-this-buffer
(current-buffer))
687 (set-marker reftex-select-return-marker
(point))
690 (save-window-excursion
691 (delete-other-windows)
692 (let ((default-major-mode 'reftex-select-bib-mode
))
693 (reftex-kill-buffer "*RefTeX Select*")
694 (switch-to-buffer-other-window "*RefTeX Select*")
695 (unless (eq major-mode
'reftex-select-bib-mode
)
696 (reftex-select-bib-mode))
697 (let ((buffer-read-only nil
))
699 (reftex-insert-bib-matches found-list
)))
700 (setq buffer-read-only t
)
701 (if (= 0 (buffer-size))
702 (error "No matches found"))
703 (setq truncate-lines t
)
708 reftex-citation-prompt
710 reftex-select-bib-map
712 'reftex-bibtex-selection-callback nil
))
715 (unless key
(throw 'done t
))
721 ;; Restrict with new regular expression
722 (setq found-list
(reftex-restrict-bib-matches found-list
))
723 (let ((buffer-read-only nil
))
725 (reftex-insert-bib-matches found-list
))
729 (setq selected-entries
730 (if reftex-select-marked
731 (mapcar 'car
(nreverse reftex-select-marked
))
735 ;; Take all (marked), and push the symbol 'concat
736 (setq selected-entries
738 (if reftex-select-marked
739 (mapcar 'car
(nreverse reftex-select-marked
))
745 (setq selected-entries
746 (if reftex-select-marked
748 (mapcar 'car
(nreverse reftex-select-marked
)))
749 (if data
(list data
) nil
)))
752 ;; Got this one with completion
753 (setq selected-entries key
)
759 (defun reftex-restrict-bib-matches (found-list)
760 ;; Limit FOUND-LIST with more regular expressions
761 (let ((re-list (split-string (read-string
762 "RegExp [ && RegExp...]: "
763 nil
'reftex-cite-regexp-hist
)
765 (found-list-r found-list
)
767 (while (setq re
(pop re-list
))
773 re
(cdr (assoc "&entry" x
)))
782 (defun reftex-insert-bib-matches (list)
783 ;; Insert the bib matches and number them correctly
785 (if (memq reftex-highlight-selection
'(mouse both
))
786 reftex-mouse-selected-face
791 (setq tmp
(cdr (assoc "&formatted" x
))
793 (put-text-property 0 len
:data x tmp
)
794 (put-text-property 0 (1- len
) 'mouse-face mouse-face tmp
)
797 (run-hooks 'reftex-display-copied-context-hook
))
799 (defun reftex-format-names (namelist n
)
800 (let (last (len (length namelist
)))
803 ((= 1 len
) (car namelist
))
804 ((> len n
) (concat (car namelist
) (nth 2 reftex-cite-punctuation
)))
807 last
(nth (1- n
) namelist
))
808 (setcdr (nthcdr (- n
2) namelist
) nil
)
810 (mapconcat 'identity namelist
(nth 0 reftex-cite-punctuation
))
811 (nth 1 reftex-cite-punctuation
)
814 (defun reftex-format-citation (entry format
)
815 ;; Format a citation from the info in the BibTeX ENTRY
817 (unless (stringp format
) (setq format
"\\cite{%l}"))
819 (if (and reftex-comment-citations
820 (string-match "%l" reftex-cite-comment-format
))
821 (error "reftex-cite-comment-format contains illegal %%l"))
824 "\\(\\`\\|[^%]\\)\\(\\(%\\([0-9]*\\)\\([a-zA-Z]\\)\\)[.,;: ]*\\)"
826 (let ((n (string-to-int (match-string 4 format
)))
827 (l (string-to-char (match-string 5 format
)))
833 (reftex-get-bib-field "&key" entry
)
834 (if reftex-comment-citations
835 reftex-cite-comment-format
837 ((= l ?a
) (reftex-format-names
838 (reftex-get-bib-names "author" entry
)
840 ((= l ?A
) (car (reftex-get-bib-names "author" entry
)))
841 ((= l ?b
) (reftex-get-bib-field "booktitle" entry
"in: %s"))
842 ((= l ?B
) (reftex-abbreviate-title
843 (reftex-get-bib-field "booktitle" entry
"in: %s")))
844 ((= l ?c
) (reftex-get-bib-field "chapter" entry
))
845 ((= l ?d
) (reftex-get-bib-field "edition" entry
))
846 ((= l ?e
) (reftex-format-names
847 (reftex-get-bib-names "editor" entry
)
849 ((= l ?E
) (car (reftex-get-bib-names "editor" entry
)))
850 ((= l ?h
) (reftex-get-bib-field "howpublished" entry
))
851 ((= l ?i
) (reftex-get-bib-field "institution" entry
))
852 ((= l ?j
) (reftex-get-bib-field "journal" entry
))
853 ((= l ?k
) (reftex-get-bib-field "key" entry
))
854 ((= l ?m
) (reftex-get-bib-field "month" entry
))
855 ((= l ?n
) (reftex-get-bib-field "number" entry
))
856 ((= l ?o
) (reftex-get-bib-field "organization" entry
))
857 ((= l ?p
) (reftex-get-bib-field "pages" entry
))
858 ((= l ?P
) (car (split-string
859 (reftex-get-bib-field "pages" entry
)
861 ((= l ?s
) (reftex-get-bib-field "school" entry
))
862 ((= l ?u
) (reftex-get-bib-field "publisher" entry
))
863 ((= l ?r
) (reftex-get-bib-field "address" entry
))
864 ((= l ?t
) (reftex-get-bib-field "title" entry
))
865 ((= l ?T
) (reftex-abbreviate-title
866 (reftex-get-bib-field "title" entry
)))
867 ((= l ?v
) (reftex-get-bib-field "volume" entry
))
868 ((= l ?y
) (reftex-get-bib-field "year" entry
)))))
871 (setq b
(match-beginning 2) e
(match-end 2))
872 (setq b
(match-beginning 3) e
(match-end 3)))
873 (setq format
(concat (substring format
0 b
) rpl
(substring format e
)))))
874 (while (string-match "%%" format
)
875 (setq format
(replace-match "%" t t format
)))
876 (while (string-match "[ ,.;:]*%<" format
)
877 (setq format
(replace-match "" t t format
)))
880 (defun reftex-make-cite-echo-string (entry docstruct-symbol
)
881 ;; Format a bibtex entry for the echo area and cache the result.
882 (let* ((key (reftex-get-bib-field "&key" entry
))
884 (let* ((reftex-cite-punctuation '(" " " & " " etal.")))
885 (reftex-format-citation entry reftex-cite-view-format
)))
886 (cache (assq 'bibview-cache
(symbol-value docstruct-symbol
)))
887 (cache-entry (assoc key
(cdr cache
))))
889 ;; This docstruct has no cache - make one.
890 (set docstruct-symbol
(cons (cons 'bibview-cache nil
)
891 (symbol-value docstruct-symbol
))))
892 (when reftex-cache-cite-echo
893 (setq key
(copy-sequence key
))
894 (set-text-properties 0 (length key
) nil key
)
895 (set-text-properties 0 (length string
) nil string
)
897 (unless (string= (cdr cache-entry
) string
)
898 (setcdr cache-entry string
)
899 (put reftex-docstruct-symbol
'modified t
))
900 (push (cons key string
) (cdr cache
))
901 (put reftex-docstruct-symbol
'modified t
)))
904 (defun reftex-bibtex-selection-callback (data ignore no-revisit
)
905 ;; Callback function to be called from the BibTeX selection, in
906 ;; order to display context. This function is relatively slow and not
907 ;; recommended for follow mode. It works OK for individual lookups.
908 (let ((win (selected-window))
909 (key (reftex-get-bib-field "&key" data
))
914 (set-buffer reftex-call-back-to-this-buffer
)
916 ((assq 'bib
(symbol-value reftex-docstruct-symbol
))
917 (setq bibfile-list
(reftex-get-bibfile-list)))
918 ((assq 'thebib
(symbol-value reftex-docstruct-symbol
))
923 'thebib
(symbol-value reftex-docstruct-symbol
))))
925 (reftex-default-bibliography
926 (setq bibfile-list
(reftex-default-bibliography)))
927 (t (ding) (throw 'exit
))))
930 (setq bibfile-list
(reftex-visited-files bibfile-list
)))
933 (reftex-pop-to-bibtex-entry
934 key bibfile-list
(not reftex-keep-temporary-buffers
) t item
)
937 (select-window win
)))
939 ;;; reftex-cite.el ends here