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