]> code.delx.au - gnu-emacs/blob - lisp/textmodes/reftex-cite.el
Update to RefTeX 4.18
[gnu-emacs] / lisp / textmodes / reftex-cite.el
1 ;;; reftex-cite.el --- creating citations with RefTeX
2 ;; Copyright (c) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
3
4 ;; Author: Carsten Dominik <dominik@science.uva.nl>
5 ;; Version: 4.18
6
7 ;; This file is part of GNU Emacs.
8
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)
12 ;; any later version.
13
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.
18
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.
23
24 ;;; Commentary:
25
26 ;;; Code:
27
28 (eval-when-compile (require 'cl))
29 (provide 'reftex-cite)
30 (require 'reftex)
31 ;;;
32
33 ;; Variables and constants
34
35 ;; The history list of regular expressions used for citations
36 (defvar reftex-cite-regexp-hist nil)
37
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")
41
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.")
53
54 ;; Find bibtex files
55
56
57 (defmacro reftex-with-special-syntax-for-bib (&rest body)
58 `(let ((saved-syntax (syntax-table)))
59 (unwind-protect
60 (progn
61 (set-syntax-table reftex-syntax-table-for-bib)
62 ,@body)
63 (set-syntax-table saved-syntax))))
64
65 (defun reftex-default-bibliography ()
66 ;; Return the expanded value of `reftex-default-bibliography'.
67 ;; The expanded value is cached.
68 (unless (eq (get 'reftex-default-bibliography :reftex-raw)
69 reftex-default-bibliography)
70 (put 'reftex-default-bibliography :reftex-expanded
71 (reftex-locate-bibliography-files
72 default-directory reftex-default-bibliography))
73 (put 'reftex-default-bibliography :reftex-raw
74 reftex-default-bibliography))
75 (get 'reftex-default-bibliography :reftex-expanded))
76
77 (defun reftex-bib-or-thebib ()
78 ;; Tests if BibTeX or \begin{tehbibliography} should be used for the
79 ;; citation
80 ;; Find the bof of the current file
81 (let* ((docstruct (symbol-value reftex-docstruct-symbol))
82 (rest (or (member (list 'bof (buffer-file-name)) docstruct)
83 docstruct))
84 (bib (assq 'bib rest))
85 (thebib (assq 'thebib rest))
86 (bibmem (memq bib rest))
87 (thebibmem (memq thebib rest)))
88 (when (not (or thebib bib))
89 (setq bib (assq 'bib docstruct)
90 thebib (assq 'thebib docstruct)
91 bibmem (memq bib docstruct)
92 thebibmem (memq thebib docstruct)))
93 (if (> (length bibmem) (length thebibmem))
94 (if bib 'bib nil)
95 (if thebib 'thebib nil))))
96
97 (defun reftex-get-bibfile-list ()
98 ;; Return list of bibfiles for current document.
99 ;; When using the chapterbib or bibunits package you should either
100 ;; use the same database files everywhere, or separate parts using
101 ;; different databases into different files (included into the mater file).
102 ;; Then this function will return the applicable database files.
103
104 ;; Ensure access to scanning info
105 (reftex-access-scan-info)
106 (or
107 ;; Try inside this file (and its includes)
108 (cdr (reftex-last-assoc-before-elt
109 'bib (list 'eof (buffer-file-name))
110 (member (list 'bof (buffer-file-name))
111 (symbol-value reftex-docstruct-symbol))))
112 ;; Try after the beginning of this file
113 (cdr (assq 'bib (member (list 'bof (buffer-file-name))
114 (symbol-value reftex-docstruct-symbol))))
115 ;; Anywhere in the entire document
116 (cdr (assq 'bib (symbol-value reftex-docstruct-symbol)))
117 (error "\\bibliography statement missing or .bib files not found")))
118
119 ;; Find a certain reference in any of the BibTeX files.
120
121 (defun reftex-pop-to-bibtex-entry (key file-list &optional mark-to-kill
122 highlight item return)
123 ;; Find BibTeX KEY in any file in FILE-LIST in another window.
124 ;; If MARK-TO-KILL is non-nil, mark new buffer to kill.
125 ;; If HIGHLIGHT is non-nil, highlight the match.
126 ;; If ITEM in non-nil, search for bibitem instead of database entry.
127 ;; If RETURN is non-nil, just return the entry.
128
129 (let* ((re
130 (if item
131 (concat "\\\\bibitem\\(\\[[^]]*\\]\\)?{" (regexp-quote key) "}")
132 (concat "@[a-zA-Z]+[ \t\n\r]*[{(][ \t\n\r]*" (regexp-quote key)
133 "[, \t\r\n}]")))
134 (buffer-conf (current-buffer))
135 file buf pos)
136
137 (catch 'exit
138 (while file-list
139 (setq file (car file-list)
140 file-list (cdr file-list))
141 (unless (setq buf (reftex-get-file-buffer-force file mark-to-kill))
142 (error "No such file %s" file))
143 (set-buffer buf)
144 (widen)
145 (goto-char (point-min))
146 (when (re-search-forward re nil t)
147 (goto-char (match-beginning 0))
148 (setq pos (point))
149 (when return
150 ;; Just return the relevant entry
151 (if item (goto-char (match-end 0)))
152 (setq return (buffer-substring
153 (point) (reftex-end-of-bib-entry item)))
154 (set-buffer buffer-conf)
155 (throw 'exit return))
156 (switch-to-buffer-other-window buf)
157 (goto-char pos)
158 (recenter 0)
159 (if highlight
160 (reftex-highlight 0 (match-beginning 0) (match-end 0)))
161 (throw 'exit (selected-window))))
162 (set-buffer buffer-conf)
163 (if item
164 (error "No \\bibitem with citation key %s" key)
165 (error "No BibTeX entry with citation key %s" key)))))
166
167 (defun reftex-end-of-bib-entry (item)
168 (save-excursion
169 (condition-case nil
170 (if item
171 (progn (end-of-line)
172 (re-search-forward
173 "\\\\bibitem\\|\\end{thebibliography}")
174 (1- (match-beginning 0)))
175 (progn (forward-list 1) (point)))
176 (error (min (point-max) (+ 300 (point)))))))
177
178 ;; Parse bibtex buffers
179
180 (defun reftex-extract-bib-entries (buffers)
181 ;; Extract bib entries which match regexps from BUFFERS.
182 ;; BUFFERS is a list of buffers or file names.
183 ;; Return list with entries."
184 (let* (re-list first-re rest-re
185 (buffer-list (if (listp buffers) buffers (list buffers)))
186 found-list entry buffer1 buffer alist
187 key-point start-point end-point default)
188
189 ;; Read a regexp, completing on known citation keys.
190 (setq default (regexp-quote (reftex-get-bibkey-default)))
191 (setq re-list
192 (split-string
193 (completing-read
194 (concat
195 "Regex { && Regex...}: "
196 "[" default "]: ")
197 (if reftex-mode
198 (if (fboundp 'LaTeX-bibitem-list)
199 (LaTeX-bibitem-list)
200 (cdr (assoc 'bibview-cache
201 (symbol-value reftex-docstruct-symbol))))
202 nil)
203 nil nil nil 'reftex-cite-regexp-hist)
204 "[ \t]*&&[ \t]*"))
205
206 (if (or (null re-list ) (equal re-list '("")))
207 (setq re-list (list default)))
208
209 (setq first-re (car re-list) ; We'll use the first re to find things,
210 rest-re (cdr re-list)) ; the others to narrow down.
211 (if (string-match "\\`[ \t]*\\'" (or first-re ""))
212 (error "Empty regular expression"))
213
214 (save-excursion
215 (save-window-excursion
216
217 ;; Walk through all bibtex files
218 (while buffer-list
219 (setq buffer (car buffer-list)
220 buffer-list (cdr buffer-list))
221 (if (and (bufferp buffer)
222 (buffer-live-p buffer))
223 (setq buffer1 buffer)
224 (setq buffer1 (reftex-get-file-buffer-force
225 buffer (not reftex-keep-temporary-buffers))))
226 (if (not buffer1)
227 (message "No such BibTeX file %s (ignored)" buffer)
228 (message "Scanning bibliography database %s" buffer1))
229
230 (set-buffer buffer1)
231 (reftex-with-special-syntax-for-bib
232 (save-excursion
233 (goto-char (point-min))
234 (while (re-search-forward first-re nil t)
235 (catch 'search-again
236 (setq key-point (point))
237 (unless (re-search-backward
238 "\\(\\`\\|[\n\r]\\)[ \t]*@\\([a-zA-Z]+\\)[ \t\n\r]*[{(]" nil t)
239 (throw 'search-again nil))
240 (setq start-point (point))
241 (goto-char (match-end 0))
242 (condition-case nil
243 (up-list 1)
244 (error (goto-char key-point)
245 (throw 'search-again nil)))
246 (setq end-point (point))
247
248 ;; Ignore @string, @comment and @c entries or things
249 ;; outside entries
250 (when (or (string= (downcase (match-string 2)) "string")
251 (string= (downcase (match-string 2)) "comment")
252 (string= (downcase (match-string 2)) "c")
253 (< (point) key-point)) ; this means match not in {}
254 (goto-char key-point)
255 (throw 'search-again nil))
256
257 ;; Well, we have got a match
258 (setq entry (concat
259 (buffer-substring start-point (point)) "\n"))
260
261 ;; Check if other regexp match as well
262 (setq re-list rest-re)
263 (while re-list
264 (unless (string-match (car re-list) entry)
265 ;; nope - move on
266 (throw 'search-again nil))
267 (pop re-list))
268
269 (setq alist (reftex-parse-bibtex-entry
270 nil start-point end-point))
271 (push (cons "&entry" entry) alist)
272
273 ;; check for crossref entries
274 (if (assoc "crossref" alist)
275 (setq alist
276 (append
277 alist (reftex-get-crossref-alist alist))))
278
279 ;; format the entry
280 (push (cons "&formatted" (reftex-format-bib-entry alist))
281 alist)
282
283 ;; make key the first element
284 (push (reftex-get-bib-field "&key" alist) alist)
285
286 ;; add it to the list
287 (push alist found-list)))))
288 (reftex-kill-temporary-buffers))))
289 (setq found-list (nreverse found-list))
290
291 ;; Sorting
292 (cond
293 ((eq 'author reftex-sort-bibtex-matches)
294 (sort found-list 'reftex-bib-sort-author))
295 ((eq 'year reftex-sort-bibtex-matches)
296 (sort found-list 'reftex-bib-sort-year))
297 ((eq 'reverse-year reftex-sort-bibtex-matches)
298 (sort found-list 'reftex-bib-sort-year-reverse))
299 (t found-list))))
300
301 (defun reftex-bib-sort-author (e1 e2)
302 (let ((al1 (reftex-get-bib-names "author" e1))
303 (al2 (reftex-get-bib-names "author" e2)))
304 (while (and al1 al2 (string= (car al1) (car al2)))
305 (pop al1)
306 (pop al2))
307 (if (and (stringp (car al1))
308 (stringp (car al2)))
309 (string< (car al1) (car al2))
310 (not (stringp (car al1))))))
311
312 (defun reftex-bib-sort-year (e1 e2)
313 (< (string-to-int (cdr (assoc "year" e1)))
314 (string-to-int (cdr (assoc "year" e2)))))
315
316 (defun reftex-bib-sort-year-reverse (e1 e2)
317 (> (string-to-int (or (cdr (assoc "year" e1)) "0"))
318 (string-to-int (or (cdr (assoc "year" e2)) "0"))))
319
320 (defun reftex-get-crossref-alist (entry)
321 ;; return the alist from a crossref entry
322 (let ((crkey (cdr (assoc "crossref" entry)))
323 start)
324 (save-excursion
325 (save-restriction
326 (widen)
327 (if (re-search-forward
328 (concat "@\\w+[{(][ \t\n\r]*" (regexp-quote crkey)
329 "[ \t\n\r]*,") nil t)
330 (progn
331 (setq start (match-beginning 0))
332 (condition-case nil
333 (up-list 1)
334 (error nil))
335 (reftex-parse-bibtex-entry nil start (point)))
336 nil)))))
337
338 ;; Parse the bibliography environment
339 (defun reftex-extract-bib-entries-from-thebibliography (files)
340 ;; Extract bib-entries from the \begin{thebibliography} environment.
341 ;; Parsing is not as good as for the BibTeX database stuff.
342 ;; The environment should be located in file FILE.
343
344 (let* (start end buf entries re re-list file default)
345 (unless files
346 (error "Need file name to find thebibliography environment"))
347 (while (setq file (pop files))
348 (setq buf (reftex-get-file-buffer-force
349 file (not reftex-keep-temporary-buffers)))
350 (unless buf
351 (error "No such file %s" file))
352 (message "Scanning thebibliography environment in %s" file)
353
354 (save-excursion
355 (set-buffer buf)
356 (save-restriction
357 (widen)
358 (goto-char (point-min))
359 (while (re-search-forward
360 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\begin{thebibliography}" nil t)
361 (beginning-of-line 2)
362 (setq start (point))
363 (if (re-search-forward
364 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\end{thebibliography}" nil t)
365 (progn
366 (beginning-of-line 1)
367 (setq end (point))))
368 (when (and start end)
369 (setq entries
370 (append entries
371 (mapcar 'reftex-parse-bibitem
372 (delete ""
373 (split-string
374 (buffer-substring-no-properties start end)
375 "[ \t\n\r]*\\\\bibitem\\(\\[[^]]*]\\)*"))))))
376 (goto-char end)))))
377 (unless entries
378 (error "No bibitems found"))
379
380 ;; Read a regexp, completing on known citation keys.
381 (setq default (regexp-quote (reftex-get-bibkey-default)))
382 (setq re-list
383 (split-string
384 (completing-read
385 (concat
386 "Regex { && Regex...}: "
387 "[" default "]: ")
388 (if reftex-mode
389 (if (fboundp 'LaTeX-bibitem-list)
390 (LaTeX-bibitem-list)
391 (cdr (assoc 'bibview-cache
392 (symbol-value reftex-docstruct-symbol))))
393 nil)
394 nil nil nil 'reftex-cite-regexp-hist)
395 "[ \t]*&&[ \t]*"))
396
397 (if (or (null re-list ) (equal re-list '("")))
398 (setq re-list (list default)))
399
400 (if (string-match "\\`[ \t]*\\'" (car re-list))
401 (error "Empty regular expression"))
402
403 (while (and (setq re (pop re-list)) entries)
404 (setq entries
405 (delq nil (mapcar
406 (lambda (x)
407 (if (string-match re (cdr (assoc "&entry" x)))
408 x nil))
409 entries))))
410 (setq entries
411 (mapcar
412 (lambda (x)
413 (push (cons "&formatted" (reftex-format-bibitem x)) x)
414 (push (reftex-get-bib-field "&key" x) x)
415 x)
416 entries))
417
418 entries))
419
420 (defun reftex-get-bibkey-default ()
421 ;; Return the word before the cursor. If the cursor is in a
422 ;; citation macro, return the word before the macro.
423 (let* ((macro (reftex-what-macro 1)))
424 (save-excursion
425 (if (and macro (string-match "cite" (car macro)))
426 (goto-char (cdr macro)))
427 (skip-chars-backward "^a-zA-Z0-9")
428 (reftex-this-word))))
429
430 ;; Parse and format individual entries
431
432 (defun reftex-get-bib-names (field entry)
433 ;; Return a list with the author or editor names in ENTRY
434 (let ((names (reftex-get-bib-field field entry)))
435 (if (equal "" names)
436 (setq names (reftex-get-bib-field "editor" entry)))
437 (while (string-match "\\band\\b[ \t]*" names)
438 (setq names (replace-match "\n" nil t names)))
439 (while (string-match "[\\.a-zA-Z\\-]+\\.[ \t]*\\|,.*\\|[{}]+" names)
440 (setq names (replace-match "" nil t names)))
441 (while (string-match "^[ \t]+\\|[ \t]+$" names)
442 (setq names (replace-match "" nil t names)))
443 (while (string-match "[ \t][ \t]+" names)
444 (setq names (replace-match " " nil t names)))
445 (split-string names "\n")))
446
447 (defun reftex-parse-bibtex-entry (entry &optional from to)
448 (let (alist key start field)
449 (save-excursion
450 (save-restriction
451 (if entry
452 (progn
453 (set-buffer (get-buffer-create " *RefTeX-scratch*"))
454 (fundamental-mode)
455 (set-syntax-table reftex-syntax-table-for-bib)
456 (erase-buffer)
457 (insert entry))
458 (widen)
459 (narrow-to-region from to))
460 (goto-char (point-min))
461
462 (if (re-search-forward
463 "@\\(\\w+\\)[ \t\n\r]*[{(][ \t\n\r]*\\([^ \t\n\r,]+\\)" nil t)
464 (setq alist
465 (list
466 (cons "&type" (downcase (reftex-match-string 1)))
467 (cons "&key" (reftex-match-string 2)))))
468 (while (re-search-forward "\\(\\w+\\)[ \t\n\r]*=[ \t\n\r]*" nil t)
469 (setq key (downcase (reftex-match-string 1)))
470 (cond
471 ((= (following-char) ?{)
472 (forward-char 1)
473 (setq start (point))
474 (condition-case nil
475 (up-list 1)
476 (error nil)))
477 ((= (following-char) ?\")
478 (forward-char 1)
479 (setq start (point))
480 (while (and (search-forward "\"" nil t)
481 (= ?\\ (char-after (- (point) 2))))))
482 (t
483 (setq start (point))
484 (re-search-forward "[ \t]*[\n\r,}]" nil 1)))
485 (setq field (buffer-substring-no-properties start (1- (point))))
486 ;; remove extra whitespace
487 (while (string-match "[\n\t\r]\\|[ \t][ \t]+" field)
488 (setq field (replace-match " " nil t field)))
489 ;; remove leading garbage
490 (if (string-match "^[ \t{]+" field)
491 (setq field (replace-match "" nil t field)))
492 ;; remove trailing garbage
493 (if (string-match "[ \t}]+$" field)
494 (setq field (replace-match "" nil t field)))
495 (push (cons key field) alist))))
496 alist))
497
498 (defun reftex-get-bib-field (fieldname entry &optional format)
499 ;; Extract the field FIELDNAME from an ENTRY
500 (let ((cell (assoc fieldname entry)))
501 (if cell
502 (if format
503 (format format (cdr cell))
504 (cdr cell))
505 "")))
506
507 (defun reftex-format-bib-entry (entry)
508 ;; Format a BibTeX ENTRY so that it is nice to look at
509 (let*
510 ((auth-list (reftex-get-bib-names "author" entry))
511 (authors (mapconcat 'identity auth-list ", "))
512 (year (reftex-get-bib-field "year" entry))
513 (title (reftex-get-bib-field "title" entry))
514 (type (reftex-get-bib-field "&type" entry))
515 (key (reftex-get-bib-field "&key" entry))
516 (extra
517 (cond
518 ((equal type "article")
519 (concat (reftex-get-bib-field "journal" entry) " "
520 (reftex-get-bib-field "volume" entry) ", "
521 (reftex-get-bib-field "pages" entry)))
522 ((equal type "book")
523 (concat "book (" (reftex-get-bib-field "publisher" entry) ")"))
524 ((equal type "phdthesis")
525 (concat "PhD: " (reftex-get-bib-field "school" entry)))
526 ((equal type "mastersthesis")
527 (concat "Master: " (reftex-get-bib-field "school" entry)))
528 ((equal type "inbook")
529 (concat "Chap: " (reftex-get-bib-field "chapter" entry)
530 ", pp. " (reftex-get-bib-field "pages" entry)))
531 ((or (equal type "conference")
532 (equal type "incollection")
533 (equal type "inproceedings"))
534 (reftex-get-bib-field "booktitle" entry "in: %s"))
535 (t ""))))
536 (setq authors (reftex-truncate authors 30 t t))
537 (when (reftex-use-fonts)
538 (put-text-property 0 (length key) 'face
539 (reftex-verified-face reftex-label-face
540 'font-lock-constant-face
541 'font-lock-reference-face)
542 key)
543 (put-text-property 0 (length authors) 'face reftex-bib-author-face
544 authors)
545 (put-text-property 0 (length year) 'face reftex-bib-year-face
546 year)
547 (put-text-property 0 (length title) 'face reftex-bib-title-face
548 title)
549 (put-text-property 0 (length extra) 'face reftex-bib-extra-face
550 extra))
551 (concat key "\n " authors " " year " " extra "\n " title "\n\n")))
552
553 (defun reftex-parse-bibitem (item)
554 ;; Parse a \bibitem entry
555 (let ((key "") (text ""))
556 (when (string-match "\\`{\\([^}]+\\)}\\([^\000]*\\)" item)
557 (setq key (match-string 1 item)
558 text (match-string 2 item)))
559 ;; Clean up the text a little bit
560 (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text)
561 (setq text (replace-match " " nil t text)))
562 (if (string-match "\\`[ \t]+" text)
563 (setq text (replace-match "" nil t text)))
564 (list
565 (cons "&key" key)
566 (cons "&text" text)
567 (cons "&entry" (concat key " " text)))))
568
569 (defun reftex-format-bibitem (item)
570 ;; Format a \bibitem entry so that it is (relatively) nice to look at.
571 (let ((text (reftex-get-bib-field "&text" item))
572 (key (reftex-get-bib-field "&key" item))
573 (lines nil))
574
575 ;; Wrap the text into several lines.
576 (while (and (> (length text) 70)
577 (string-match " " (substring text 60)))
578 (push (substring text 0 (+ 60 (match-beginning 0))) lines)
579 (setq text (substring text (+ 61 (match-beginning 0)))))
580 (push text lines)
581 (setq text (mapconcat 'identity (nreverse lines) "\n "))
582
583 (when (reftex-use-fonts)
584 (put-text-property 0 (length text) 'face reftex-bib-author-face text))
585 (concat key "\n " text "\n\n")))
586
587 ;; Make a citation
588
589 ;;;###autoload
590 (defun reftex-citation (&optional no-insert format-key)
591 "Make a citation using BibTeX database files.
592 After prompting for a regular expression, scans the buffers with
593 bibtex entries (taken from the \\bibliography command) and offers the
594 matching entries for selection. The selected entry is formatted according
595 to `reftex-cite-format' and inserted into the buffer.
596
597 If NO-INSERT is non-nil, nothing is inserted, only the selected key returned.
598
599 FORAT-KEY can be used to pre-select a citation format.
600
601 When called with one or two `C-u' prefixes, first rescans the document.
602 When called with a numeric prefix, make that many citations. When
603 called with point inside the braces of a `\\cite' command, it will
604 add another key, ignoring the value of `reftex-cite-format'.
605
606 The regular expression uses an expanded syntax: && is interpreted as `and'.
607 Thus, `aaaa&&bbb' matches entries which contain both `aaaa' and `bbb'.
608 While entering the regexp, completion on knows citation keys is possible.
609 `=' is a good regular expression to match all entries in all files."
610
611 (interactive)
612
613 ;; check for recursive edit
614 (reftex-check-recursive-edit)
615
616 ;; This function may also be called outside reftex-mode.
617 ;; Thus look for the scanning info only if in reftex-mode.
618
619 (when reftex-mode
620 (reftex-access-scan-info current-prefix-arg))
621
622 ;; Call reftex-do-citation, but protected
623 (unwind-protect
624 (reftex-do-citation current-prefix-arg no-insert format-key)
625 (reftex-kill-temporary-buffers)))
626
627 (defun reftex-do-citation (&optional arg no-insert format-key)
628 ;; This really does the work of reftex-citation.
629
630 (let* ((format (reftex-figure-out-cite-format arg no-insert format-key))
631 (docstruct-symbol reftex-docstruct-symbol)
632 (selected-entries (reftex-offer-bib-menu))
633 (insert-entries selected-entries)
634 entry string cite-view)
635
636 (unless selected-entries (error "Quit"))
637
638 (if (stringp selected-entries)
639 ;; Nonexistent entry
640 (setq selected-entries nil
641 insert-entries (list (list selected-entries
642 (cons "&key" selected-entries))))
643 ;; It makes sense to compute the cite-view strings.
644 (setq cite-view t))
645
646 (when (eq (car selected-entries) 'concat)
647 ;; All keys go into a single command - we need to trick a little
648 (pop selected-entries)
649 (let ((concat-keys (mapconcat 'car selected-entries ",")))
650 (setq insert-entries
651 (list (list concat-keys (cons "&key" concat-keys))))))
652
653 (unless no-insert
654
655 ;; We shall insert this into the buffer...
656 (message "Formatting...")
657
658 (while (setq entry (pop insert-entries))
659 ;; Format the citation and insert it
660 (setq string (if reftex-format-cite-function
661 (funcall reftex-format-cite-function
662 (reftex-get-bib-field "&key" entry)
663 format)
664 (reftex-format-citation entry format)))
665 (insert string))
666
667 ;; Reposition cursor?
668 (when (string-match "\\?" string)
669 (search-backward "?")
670 (delete-char 1))
671
672 ;; Tell AUCTeX
673 (when (and reftex-mode
674 (fboundp 'LaTeX-add-bibitems)
675 reftex-plug-into-AUCTeX)
676 (apply 'LaTeX-add-bibitems (mapcar 'car selected-entries)))
677
678 ;; Produce the cite-view strings
679 (when (and reftex-mode reftex-cache-cite-echo cite-view)
680 (mapcar (lambda (entry)
681 (reftex-make-cite-echo-string entry docstruct-symbol))
682 selected-entries))
683
684 (message ""))
685
686 (set-marker reftex-select-return-marker nil)
687 (reftex-kill-buffer "*RefTeX Select*")
688
689 ;; Check if the prefix arg was numeric, and call recursively
690 (when (integerp arg)
691 (if (> arg 1)
692 (progn
693 (skip-chars-backward "}")
694 (decf arg)
695 (reftex-do-citation arg))
696 (forward-char 1)))
697
698 ;; Return the citation key
699 (car (car selected-entries))))
700
701 (defun reftex-figure-out-cite-format (arg &optional no-insert format-key)
702 ;; Check if there is already a cite command at point and change cite format
703 ;; in order to only add another reference in the same cite command.
704 (let ((macro (car (reftex-what-macro 1)))
705 (cite-format-value (reftex-get-cite-format))
706 key format)
707 (cond
708 (no-insert
709 ;; Format does not really matter because nothing will be inserted.
710 (setq format "%l"))
711
712 ((and (stringp macro)
713 (string-match "\\`\\\\cite\\|cite\\'" macro))
714 ;; We are already inside a cite macro
715 (if (or (not arg) (not (listp arg)))
716 (setq format
717 (concat
718 (if (member (preceding-char) '(?\{ ?,)) "" ",")
719 "%l"
720 (if (member (following-char) '(?\} ?,)) "" ",")))
721 (setq format "%l")))
722 (t
723 ;; Figure out the correct format
724 (setq format
725 (if (and (symbolp cite-format-value)
726 (assq cite-format-value reftex-cite-format-builtin))
727 (nth 2 (assq cite-format-value reftex-cite-format-builtin))
728 cite-format-value))
729 (when (listp format)
730 (setq key
731 (or format-key
732 (reftex-select-with-char
733 "" (concat "SELECT A CITATION FORMAT\n\n"
734 (mapconcat
735 (lambda (x)
736 (format "[%c] %s %s" (car x)
737 (if (> (car x) 31) " " "")
738 (cdr x)))
739 format "\n")))))
740 (if (assq key format)
741 (setq format (cdr (assq key format)))
742 (error "No citation format associated with key `%c'" key)))))
743 format))
744
745 (defun reftex-citep ()
746 "Call `reftex-citation' with a format selector `?p'."
747 (interactive)
748 (reftex-citation nil ?p))
749
750 (defun reftex-citet ()
751 "Call `reftex-citation' with a format selector `?t'."
752 (interactive)
753 (reftex-citation nil ?t))
754
755 (defvar reftex-select-bib-map)
756 (defun reftex-offer-bib-menu ()
757 ;; Offer bib menu and return list of selected items
758
759 (let ((bibtype (reftex-bib-or-thebib))
760 found-list rtn key data selected-entries)
761 (while
762 (not
763 (catch 'done
764 ;; Scan bibtex files
765 (setq found-list
766 (cond
767 ((eq bibtype 'bib)
768 ; ((assq 'bib (symbol-value reftex-docstruct-symbol))
769 ;; using BibTeX database files.
770 (reftex-extract-bib-entries (reftex-get-bibfile-list)))
771 ((eq bibtype 'thebib)
772 ; ((assq 'thebib (symbol-value reftex-docstruct-symbol))
773 ;; using thebibliography environment.
774 (reftex-extract-bib-entries-from-thebibliography
775 (reftex-uniquify
776 (mapcar 'cdr
777 (reftex-all-assq
778 'thebib (symbol-value reftex-docstruct-symbol))))))
779 (reftex-default-bibliography
780 (message "Using default bibliography")
781 (reftex-extract-bib-entries (reftex-default-bibliography)))
782 (t (error "No valid bibliography in this document, and no default available"))))
783
784 (unless found-list
785 (error "Sorry, no matches found"))
786
787 ;; Remember where we came from
788 (setq reftex-call-back-to-this-buffer (current-buffer))
789 (set-marker reftex-select-return-marker (point))
790
791 ;; Offer selection
792 (save-window-excursion
793 (delete-other-windows)
794 (let ((default-major-mode 'reftex-select-bib-mode))
795 (reftex-kill-buffer "*RefTeX Select*")
796 (switch-to-buffer-other-window "*RefTeX Select*")
797 (unless (eq major-mode 'reftex-select-bib-mode)
798 (reftex-select-bib-mode))
799 (let ((buffer-read-only nil))
800 (erase-buffer)
801 (reftex-insert-bib-matches found-list)))
802 (setq buffer-read-only t)
803 (if (= 0 (buffer-size))
804 (error "No matches found"))
805 (setq truncate-lines t)
806 (goto-char 1)
807 (while t
808 (setq rtn
809 (reftex-select-item
810 reftex-citation-prompt
811 reftex-citation-help
812 reftex-select-bib-map
813 nil
814 'reftex-bibtex-selection-callback nil))
815 (setq key (car rtn)
816 data (nth 1 rtn))
817 (unless key (throw 'done t))
818 (cond
819 ((eq key ?g)
820 ;; Start over
821 (throw 'done nil))
822 ((eq key ?r)
823 ;; Restrict with new regular expression
824 (setq found-list (reftex-restrict-bib-matches found-list))
825 (let ((buffer-read-only nil))
826 (erase-buffer)
827 (reftex-insert-bib-matches found-list))
828 (goto-char 1))
829 ((eq key ?A)
830 ;; Take all (marked)
831 (setq selected-entries
832 (if reftex-select-marked
833 (mapcar 'car (nreverse reftex-select-marked))
834 found-list))
835 (throw 'done t))
836 ((eq key ?a)
837 ;; Take all (marked), and push the symbol 'concat
838 (setq selected-entries
839 (cons 'concat
840 (if reftex-select-marked
841 (mapcar 'car (nreverse reftex-select-marked))
842 found-list)))
843 (throw 'done t))
844 ((or (eq key ?\C-m)
845 (eq key 'return))
846 ;; Take selected
847 (setq selected-entries
848 (if reftex-select-marked
849 (cons 'concat
850 (mapcar 'car (nreverse reftex-select-marked)))
851 (if data (list data) nil)))
852 (throw 'done t))
853 ((stringp key)
854 ;; Got this one with completion
855 (setq selected-entries key)
856 (throw 'done t))
857 (t
858 (ding))))))))
859 selected-entries))
860
861 (defun reftex-restrict-bib-matches (found-list)
862 ;; Limit FOUND-LIST with more regular expressions
863 (let ((re-list (split-string (read-string
864 "RegExp [ && RegExp...]: "
865 nil 'reftex-cite-regexp-hist)
866 "[ \t]*&&[ \t]*"))
867 (found-list-r found-list)
868 re)
869 (while (setq re (pop re-list))
870 (setq found-list-r
871 (delq nil
872 (mapcar
873 (lambda (x)
874 (if (string-match
875 re (cdr (assoc "&entry" x)))
876 x
877 nil))
878 found-list-r))))
879 (if found-list-r
880 found-list-r
881 (ding)
882 found-list)))
883
884 (defun reftex-insert-bib-matches (list)
885 ;; Insert the bib matches and number them correctly
886 (let ((mouse-face
887 (if (memq reftex-highlight-selection '(mouse both))
888 reftex-mouse-selected-face
889 nil))
890 tmp len)
891 (mapcar
892 (lambda (x)
893 (setq tmp (cdr (assoc "&formatted" x))
894 len (length tmp))
895 (put-text-property 0 len :data x tmp)
896 (put-text-property 0 (1- len) 'mouse-face mouse-face tmp)
897 (insert tmp))
898 list))
899 (run-hooks 'reftex-display-copied-context-hook))
900
901 (defun reftex-format-names (namelist n)
902 (let (last (len (length namelist)))
903 (if (= n 0) (setq n len))
904 (cond
905 ((< len 1) "")
906 ((= 1 len) (car namelist))
907 ((> len n) (concat (car namelist) (nth 2 reftex-cite-punctuation)))
908 (t
909 (setq n (min len n)
910 last (nth (1- n) namelist))
911 (setcdr (nthcdr (- n 2) namelist) nil)
912 (concat
913 (mapconcat 'identity namelist (nth 0 reftex-cite-punctuation))
914 (nth 1 reftex-cite-punctuation)
915 last)))))
916
917 (defun reftex-format-citation (entry format)
918 ;; Format a citation from the info in the BibTeX ENTRY
919
920 (unless (stringp format) (setq format "\\cite{%l}"))
921
922 (if (and reftex-comment-citations
923 (string-match "%l" reftex-cite-comment-format))
924 (error "reftex-cite-comment-format contains illegal %%l"))
925
926 (while (string-match
927 "\\(\\`\\|[^%]\\)\\(\\(%\\([0-9]*\\)\\([a-zA-Z]\\)\\)[.,;: ]*\\)"
928 format)
929 (let ((n (string-to-int (match-string 4 format)))
930 (l (string-to-char (match-string 5 format)))
931 rpl b e)
932 (save-match-data
933 (setq rpl
934 (cond
935 ((= l ?l) (concat
936 (reftex-get-bib-field "&key" entry)
937 (if reftex-comment-citations
938 reftex-cite-comment-format
939 "")))
940 ((= l ?a) (reftex-format-names
941 (reftex-get-bib-names "author" entry)
942 (or n 2)))
943 ((= l ?A) (car (reftex-get-bib-names "author" entry)))
944 ((= l ?b) (reftex-get-bib-field "booktitle" entry "in: %s"))
945 ((= l ?B) (reftex-abbreviate-title
946 (reftex-get-bib-field "booktitle" entry "in: %s")))
947 ((= l ?c) (reftex-get-bib-field "chapter" entry))
948 ((= l ?d) (reftex-get-bib-field "edition" entry))
949 ((= l ?e) (reftex-format-names
950 (reftex-get-bib-names "editor" entry)
951 (or n 2)))
952 ((= l ?E) (car (reftex-get-bib-names "editor" entry)))
953 ((= l ?h) (reftex-get-bib-field "howpublished" entry))
954 ((= l ?i) (reftex-get-bib-field "institution" entry))
955 ((= l ?j) (reftex-get-bib-field "journal" entry))
956 ((= l ?k) (reftex-get-bib-field "key" entry))
957 ((= l ?m) (reftex-get-bib-field "month" entry))
958 ((= l ?n) (reftex-get-bib-field "number" entry))
959 ((= l ?o) (reftex-get-bib-field "organization" entry))
960 ((= l ?p) (reftex-get-bib-field "pages" entry))
961 ((= l ?P) (car (split-string
962 (reftex-get-bib-field "pages" entry)
963 "[- .]+")))
964 ((= l ?s) (reftex-get-bib-field "school" entry))
965 ((= l ?u) (reftex-get-bib-field "publisher" entry))
966 ((= l ?r) (reftex-get-bib-field "address" entry))
967 ((= l ?t) (reftex-get-bib-field "title" entry))
968 ((= l ?T) (reftex-abbreviate-title
969 (reftex-get-bib-field "title" entry)))
970 ((= l ?v) (reftex-get-bib-field "volume" entry))
971 ((= l ?y) (reftex-get-bib-field "year" entry)))))
972
973 (if (string= rpl "")
974 (setq b (match-beginning 2) e (match-end 2))
975 (setq b (match-beginning 3) e (match-end 3)))
976 (setq format (concat (substring format 0 b) rpl (substring format e)))))
977 (while (string-match "%%" format)
978 (setq format (replace-match "%" t t format)))
979 (while (string-match "[ ,.;:]*%<" format)
980 (setq format (replace-match "" t t format)))
981 format)
982
983 (defun reftex-make-cite-echo-string (entry docstruct-symbol)
984 ;; Format a bibtex entry for the echo area and cache the result.
985 (let* ((key (reftex-get-bib-field "&key" entry))
986 (string
987 (let* ((reftex-cite-punctuation '(" " " & " " etal.")))
988 (reftex-format-citation entry reftex-cite-view-format)))
989 (cache (assq 'bibview-cache (symbol-value docstruct-symbol)))
990 (cache-entry (assoc key (cdr cache))))
991 (unless cache
992 ;; This docstruct has no cache - make one.
993 (set docstruct-symbol (cons (cons 'bibview-cache nil)
994 (symbol-value docstruct-symbol))))
995 (when reftex-cache-cite-echo
996 (setq key (copy-sequence key))
997 (set-text-properties 0 (length key) nil key)
998 (set-text-properties 0 (length string) nil string)
999 (if cache-entry
1000 (unless (string= (cdr cache-entry) string)
1001 (setcdr cache-entry string)
1002 (put reftex-docstruct-symbol 'modified t))
1003 (push (cons key string) (cdr cache))
1004 (put reftex-docstruct-symbol 'modified t)))
1005 string))
1006
1007 (defun reftex-bibtex-selection-callback (data ignore no-revisit)
1008 ;; Callback function to be called from the BibTeX selection, in
1009 ;; order to display context. This function is relatively slow and not
1010 ;; recommended for follow mode. It works OK for individual lookups.
1011 (let ((win (selected-window))
1012 (key (reftex-get-bib-field "&key" data))
1013 bibfile-list item bibtype)
1014
1015 (catch 'exit
1016 (save-excursion
1017 (set-buffer reftex-call-back-to-this-buffer)
1018 (setq bibtype (reftex-bib-or-thebib))
1019 (cond
1020 ((eq bibtype 'bib)
1021 ; ((assq 'bib (symbol-value reftex-docstruct-symbol))
1022 (setq bibfile-list (reftex-get-bibfile-list)))
1023 ((eq bibtype 'thebib)
1024 ; ((assq 'thebib (symbol-value reftex-docstruct-symbol))
1025 (setq bibfile-list
1026 (reftex-uniquify
1027 (mapcar 'cdr
1028 (reftex-all-assq
1029 'thebib (symbol-value reftex-docstruct-symbol))))
1030 item t))
1031 (reftex-default-bibliography
1032 (setq bibfile-list (reftex-default-bibliography)))
1033 (t (ding) (throw 'exit nil))))
1034
1035 (when no-revisit
1036 (setq bibfile-list (reftex-visited-files bibfile-list)))
1037
1038 (condition-case nil
1039 (reftex-pop-to-bibtex-entry
1040 key bibfile-list (not reftex-keep-temporary-buffers) t item)
1041 (error (ding))))
1042
1043 (select-window win)))
1044
1045 ;;; reftex-cite.el ends here