]> code.delx.au - gnu-emacs/blob - lisp/textmodes/reftex-cite.el
Merge branch 'map'
[gnu-emacs] / lisp / textmodes / reftex-cite.el
1 ;;; reftex-cite.el --- creating citations with RefTeX
2
3 ;; Copyright (C) 1997-2015 Free Software Foundation, Inc.
4
5 ;; Author: Carsten Dominik <dominik@science.uva.nl>
6 ;; Maintainer: auctex-devel@gnu.org
7
8 ;; This file is part of GNU Emacs.
9
10 ;; GNU Emacs is free software: you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation, either version 3 of the License, or
13 ;; (at your option) any later version.
14
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
22
23 ;;; Commentary:
24
25 ;;; Code:
26
27 (eval-when-compile (require 'cl))
28
29 (require 'reftex)
30
31 ;;; Variables and constants
32 (defvar reftex-cite-regexp-hist nil
33 "The history list of regular expressions used for citations")
34
35 (defconst reftex-citation-prompt
36 "Select: [n]ext [p]revious [r]estrict [ ]full_entry [q]uit RET [?]Help+more"
37 "Prompt and help string for citation selection")
38
39 (defconst reftex-citation-help
40 " n / p Go to next/previous entry (Cursor motion works as well).
41 g / r Start over with new regexp / Refine with additional regexp.
42 SPC Show full database entry in other window.
43 f Toggle follow mode: Other window will follow with full db entry.
44 . Show insertion point.
45 q Quit without inserting \\cite macro into buffer.
46 TAB Enter citation key with completion.
47 RET Accept current entry (also on mouse-2) and create \\cite macro.
48 m / u Mark/Unmark the entry.
49 e / E Create BibTeX file with all (marked/unmarked) entries
50 a / A Put all (marked) entries into one/many \\cite commands.")
51
52 ;;; Find bibtex files
53 (defmacro reftex-with-special-syntax-for-bib (&rest body)
54 `(let ((saved-syntax (syntax-table)))
55 (unwind-protect
56 (progn
57 (set-syntax-table reftex-syntax-table-for-bib)
58 ,@body)
59 (set-syntax-table saved-syntax))))
60
61 ;;;###autoload
62 (defun reftex-default-bibliography ()
63 "Return the expanded value of variable `reftex-default-bibliography'.
64 The expanded value is cached."
65 (unless (eq (get 'reftex-default-bibliography :reftex-raw)
66 reftex-default-bibliography)
67 (put 'reftex-default-bibliography :reftex-expanded
68 (reftex-locate-bibliography-files
69 default-directory reftex-default-bibliography))
70 (put 'reftex-default-bibliography :reftex-raw
71 reftex-default-bibliography))
72 (get 'reftex-default-bibliography :reftex-expanded))
73
74 ;;;###autoload
75 (defun reftex-bib-or-thebib ()
76 "Test if BibTeX or \begin{thebibliography} should be used for the citation.
77 Find the bof of the current file"
78 (let* ((docstruct (symbol-value reftex-docstruct-symbol))
79 (rest (or (member (list 'bof (buffer-file-name)) docstruct)
80 docstruct))
81 (bib (assq 'bib rest))
82 (thebib (assq 'thebib rest))
83 (bibmem (memq bib rest))
84 (thebibmem (memq thebib rest)))
85 (when (not (or thebib bib))
86 (setq bib (assq 'bib docstruct)
87 thebib (assq 'thebib docstruct)
88 bibmem (memq bib docstruct)
89 thebibmem (memq thebib docstruct)))
90 (if (> (length bibmem) (length thebibmem))
91 (if bib 'bib nil)
92 (if thebib 'thebib nil))))
93
94 ;;;###autoload
95 (defun reftex-get-bibfile-list ()
96 "Return list of bibfiles for current document.
97 When using the chapterbib or bibunits package you should either
98 use the same database files everywhere, or separate parts using
99 different databases into different files (included into the mater file).
100 Then this function will return the applicable database files."
101
102 ;; Ensure access to scanning info
103 (reftex-access-scan-info)
104 (or
105 ;; Try inside this file (and its includes)
106 (cdr (reftex-last-assoc-before-elt
107 'bib (list 'eof (buffer-file-name))
108 (member (list 'bof (buffer-file-name))
109 (symbol-value reftex-docstruct-symbol))))
110 ;; Try after the beginning of this file
111 (cdr (assq 'bib (member (list 'bof (buffer-file-name))
112 (symbol-value reftex-docstruct-symbol))))
113 ;; Anywhere in the entire document
114 (cdr (assq 'bib (symbol-value reftex-docstruct-symbol)))
115 (error "\\bibliography statement missing or .bib files not found")))
116
117 ;;; Find a certain reference in any of the BibTeX files.
118 ;;;###autoload
119 (defun reftex-pop-to-bibtex-entry (key file-list &optional mark-to-kill
120 highlight item return)
121 "Find BibTeX KEY in any file in FILE-LIST in another window.
122 If MARK-TO-KILL is non-nil, mark new buffer to kill.
123 If HIGHLIGHT is non-nil, highlight the match.
124 If ITEM in non-nil, search for bibitem instead of database entry.
125 If RETURN is non-nil, just return the entry and restore point."
126 (let* ((re
127 (if item
128 (concat "\\\\bibitem[ \t]*\\(\\[[^]]*\\]\\)?[ \t]*{"
129 (regexp-quote key) "}")
130 (concat "@\\(?:\\w\\|\\s_\\)+[ \t\n\r]*[{(][ \t\n\r]*"
131 (regexp-quote key) "[, \t\r\n}]")))
132 (buffer-conf (current-buffer))
133 file buf pos oldpos)
134
135 (catch 'exit
136 (while file-list
137 (setq file (car file-list)
138 file-list (cdr file-list))
139 (unless (setq buf (reftex-get-file-buffer-force file mark-to-kill))
140 (error "No such file %s" file))
141 (set-buffer buf)
142 (setq oldpos (point))
143 (widen)
144 (goto-char (point-min))
145 (if (not (re-search-forward re nil t))
146 (goto-char oldpos) ;; restore previous position of point
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 (goto-char oldpos) ;; restore point.
155 (set-buffer buffer-conf)
156 (throw 'exit return))
157 (switch-to-buffer-other-window buf)
158 (goto-char pos)
159 (recenter 0)
160 (if highlight
161 (reftex-highlight 0 (match-beginning 0) (match-end 0)))
162 (throw 'exit (selected-window))))
163 (set-buffer buffer-conf)
164 (if item
165 (error "No \\bibitem with citation key %s" key)
166 (error "No BibTeX entry with citation key %s" key)))))
167
168 ;;;###autoload
169 (defun reftex-end-of-bib-entry (item)
170 (save-excursion
171 (condition-case nil
172 (if item
173 (progn (end-of-line)
174 (re-search-forward
175 "\\\\bibitem\\|\\end{thebibliography}")
176 (1- (match-beginning 0)))
177 (progn (forward-list 1) (point)))
178 (error (min (point-max) (+ 300 (point)))))))
179
180 ;;; Parse bibtex buffers
181 (defun reftex-extract-bib-entries (buffers)
182 "Extract bib entries which match regexps from BUFFERS.
183 BUFFERS is a list of buffers or file names.
184 Return list with entries."
185 (let* (re-list first-re rest-re
186 (buffer-list (if (listp buffers) buffers (list buffers)))
187 found-list entry buffer1 buffer alist
188 key-point start-point end-point default)
189
190 ;; Read a regexp, completing on known citation keys.
191 (setq default (regexp-quote (reftex-get-bibkey-default)))
192 (setq re-list
193 (split-string
194 (completing-read
195 (concat
196 "Regex { && Regex...}: "
197 "[" default "]: ")
198 (if reftex-mode
199 (if (fboundp 'LaTeX-bibitem-list)
200 (or (LaTeX-bibitem-list) '(""))
201 (cdr (assoc 'bibview-cache
202 (symbol-value reftex-docstruct-symbol))))
203 nil)
204 nil nil nil 'reftex-cite-regexp-hist)
205 "[ \t]*&&[ \t]*"))
206
207 (if (or (null re-list ) (equal re-list '("")))
208 (setq re-list (list default)))
209
210 (setq first-re (car re-list) ; We'll use the first re to find things,
211 rest-re (cdr re-list)) ; the others to narrow down.
212 (if (string-match "\\`[ \t]*\\'" (or first-re ""))
213 (error "Empty regular expression"))
214
215 (save-excursion
216 (save-window-excursion
217
218 ;; Walk through all bibtex files
219 (while buffer-list
220 (setq buffer (car buffer-list)
221 buffer-list (cdr buffer-list))
222 (if (and (bufferp buffer)
223 (buffer-live-p buffer))
224 (setq buffer1 buffer)
225 (setq buffer1 (reftex-get-file-buffer-force
226 buffer (not reftex-keep-temporary-buffers))))
227 (if (not buffer1)
228 (message "No such BibTeX file %s (ignored)" buffer)
229 (message "Scanning bibliography database %s" buffer1)
230 (unless (verify-visited-file-modtime buffer1)
231 (when (y-or-n-p
232 (format "File %s changed on disk. Reread from disk? "
233 (file-name-nondirectory
234 (buffer-file-name buffer1))))
235 (with-current-buffer buffer1 (revert-buffer t t)))))
236
237 (set-buffer buffer1)
238 (reftex-with-special-syntax-for-bib
239 (save-excursion
240 (goto-char (point-min))
241 (while (re-search-forward first-re nil t)
242 (catch 'search-again
243 (setq key-point (point))
244 (unless (re-search-backward "\\(\\`\\|[\n\r]\\)[ \t]*\
245 @\\(\\(?:\\w\\|\\s_\\)+\\)[ \t\n\r]*[{(]" nil t)
246 (throw 'search-again nil))
247 (setq start-point (point))
248 (goto-char (match-end 0))
249 (condition-case nil
250 (up-list 1)
251 (error (goto-char key-point)
252 (throw 'search-again nil)))
253 (setq end-point (point))
254
255 ;; Ignore @string, @comment and @c entries or things
256 ;; outside entries
257 (when (or (string= (downcase (match-string 2)) "string")
258 (string= (downcase (match-string 2)) "comment")
259 (string= (downcase (match-string 2)) "c")
260 (< (point) key-point)) ; this means match not in {}
261 (goto-char key-point)
262 (throw 'search-again nil))
263
264 ;; Well, we have got a match
265 ;;(setq entry (concat
266 ;; (buffer-substring start-point (point)) "\n"))
267 (setq entry (buffer-substring start-point (point)))
268
269 ;; Check if other regexp match as well
270 (setq re-list rest-re)
271 (while re-list
272 (unless (string-match (car re-list) entry)
273 ;; nope - move on
274 (throw 'search-again nil))
275 (pop re-list))
276
277 (setq alist (reftex-parse-bibtex-entry
278 nil start-point end-point))
279 (push (cons "&entry" entry) alist)
280
281 ;; check for crossref entries
282 (if (assoc "crossref" alist)
283 (setq alist
284 (append
285 alist (reftex-get-crossref-alist alist))))
286
287 ;; format the entry
288 (push (cons "&formatted" (reftex-format-bib-entry alist))
289 alist)
290
291 ;; make key the first element
292 (push (reftex-get-bib-field "&key" alist) alist)
293
294 ;; add it to the list
295 (push alist found-list)))))
296 (reftex-kill-temporary-buffers))))
297 (setq found-list (nreverse found-list))
298
299 ;; Sorting
300 (cond
301 ((eq 'author reftex-sort-bibtex-matches)
302 (sort found-list 'reftex-bib-sort-author))
303 ((eq 'year reftex-sort-bibtex-matches)
304 (sort found-list 'reftex-bib-sort-year))
305 ((eq 'reverse-year reftex-sort-bibtex-matches)
306 (sort found-list 'reftex-bib-sort-year-reverse))
307 (t found-list))))
308
309 (defun reftex-bib-sort-author (e1 e2)
310 "Compare bib entries E1 and E2 by author.
311 The name of the first different author/editor is used."
312 (let ((al1 (reftex-get-bib-names "author" e1))
313 (al2 (reftex-get-bib-names "author" e2)))
314 (while (and al1 al2 (string= (car al1) (car al2)))
315 (pop al1)
316 (pop al2))
317 (if (and (stringp (car al1))
318 (stringp (car al2)))
319 (string< (car al1) (car al2))
320 (not (stringp (car al1))))))
321
322 (defun reftex-bib-sort-year (e1 e2)
323 "Compare bib entries E1 and E2 by year in ascending order."
324 (< (string-to-number (or (cdr (assoc "year" e1)) "0"))
325 (string-to-number (or (cdr (assoc "year" e2)) "0"))))
326
327 (defun reftex-bib-sort-year-reverse (e1 e2)
328 "Compare bib entries E1 and E2 by year in descending order."
329 (> (string-to-number (or (cdr (assoc "year" e1)) "0"))
330 (string-to-number (or (cdr (assoc "year" e2)) "0"))))
331
332 (defun reftex-get-crossref-alist (entry)
333 "Return the alist from a crossref ENTRY."
334 (let ((crkey (cdr (assoc "crossref" entry)))
335 start)
336 (save-excursion
337 (save-restriction
338 (widen)
339 (if (re-search-forward
340 (concat "@\\w+[{(][ \t\n\r]*" (regexp-quote crkey)
341 "[ \t\n\r]*,") nil t)
342 (progn
343 (setq start (match-beginning 0))
344 (condition-case nil
345 (up-list 1)
346 (error nil))
347 (reftex-parse-bibtex-entry nil start (point)))
348 nil)))))
349
350 ;; Parse the bibliography environment
351 (defun reftex-extract-bib-entries-from-thebibliography (files)
352 "Extract bib-entries from the \begin{thebibliography} environment.
353 Parsing is not as good as for the BibTeX database stuff.
354 The environment should be located in FILES."
355 (let* (start end buf entries re re-list file default)
356 (unless files
357 (error "Need file name to find thebibliography environment"))
358 (while (setq file (pop files))
359 (setq buf (reftex-get-file-buffer-force
360 file (not reftex-keep-temporary-buffers)))
361 (unless buf
362 (error "No such file %s" file))
363 (message "Scanning thebibliography environment in %s" file)
364
365 (with-current-buffer buf
366 (save-excursion
367 (save-restriction
368 (widen)
369 (goto-char (point-min))
370 (while (re-search-forward
371 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\begin{thebibliography}" nil t)
372 (beginning-of-line 2)
373 (setq start (point))
374 (if (re-search-forward
375 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\end{thebibliography}" nil t)
376 (progn
377 (beginning-of-line 1)
378 (setq end (point))))
379 (when (and start end)
380 (setq entries
381 (append entries
382 (mapcar 'reftex-parse-bibitem
383 (delete ""
384 (split-string
385 (buffer-substring-no-properties
386 start end)
387 "[ \t\n\r]*\\\\bibitem[ \t]*\
388 \\(\\[[^]]*]\\)*\[ \t]*"))))))
389 (goto-char end))))))
390 (unless entries
391 (error "No bibitems found"))
392
393 ;; Read a regexp, completing on known citation keys.
394 (setq default (regexp-quote (reftex-get-bibkey-default)))
395 (setq re-list
396 (split-string
397 (completing-read
398 (concat
399 "Regex { && Regex...}: "
400 "[" default "]: ")
401 (if reftex-mode
402 (if (fboundp 'LaTeX-bibitem-list)
403 (LaTeX-bibitem-list)
404 (cdr (assoc 'bibview-cache
405 (symbol-value reftex-docstruct-symbol))))
406 nil)
407 nil nil nil 'reftex-cite-regexp-hist)
408 "[ \t]*&&[ \t]*"))
409
410 (if (or (null re-list ) (equal re-list '("")))
411 (setq re-list (list default)))
412
413 (if (string-match "\\`[ \t]*\\'" (car re-list))
414 (error "Empty regular expression"))
415
416 (while (and (setq re (pop re-list)) entries)
417 (setq entries
418 (delq nil (mapcar
419 (lambda (x)
420 (if (string-match re (cdr (assoc "&entry" x)))
421 x nil))
422 entries))))
423 (setq entries
424 (mapcar
425 (lambda (x)
426 (push (cons "&formatted" (reftex-format-bibitem x)) x)
427 (push (reftex-get-bib-field "&key" x) x)
428 x)
429 entries))
430
431 entries))
432
433 (defun reftex-get-bibkey-default ()
434 "Return the word before the cursor.
435 If the cursor is in a citation macro, return the word before the macro."
436 (let* ((macro (reftex-what-macro 1)))
437 (save-excursion
438 (if (and macro (string-match "cite" (car macro)))
439 (goto-char (cdr macro)))
440 (skip-chars-backward "^a-zA-Z0-9")
441 (reftex-this-word))))
442
443 ;;; Parse and format individual entries
444 (defun reftex-get-bib-names (field entry)
445 "Return a list with the author or editor names in ENTRY.
446 If FIELD is empty try \"editor\" field."
447 (let ((names (reftex-get-bib-field field entry)))
448 (if (equal "" names)
449 (setq names (reftex-get-bib-field "editor" entry)))
450 (while (string-match "\\band\\b[ \t]*" names)
451 (setq names (replace-match "\n" nil t names)))
452 (while (string-match "[\\.a-zA-Z\\-]+\\.[ \t]*\\|,.*\\|[{}]+" names)
453 (setq names (replace-match "" nil t names)))
454 (while (string-match "^[ \t]+\\|[ \t]+$" names)
455 (setq names (replace-match "" nil t names)))
456 (while (string-match "[ \t][ \t]+" names)
457 (setq names (replace-match " " nil t names)))
458 (split-string names "\n")))
459
460 ;;;###autoload
461 (defun reftex-parse-bibtex-entry (entry &optional from to raw)
462 "Parse BibTeX ENTRY.
463 If ENTRY is nil then parse the entry in current buffer between FROM and TO.
464 If RAW is non-nil, keep double quotes/curly braces delimiting fields."
465 (let (alist key start field)
466 (save-excursion
467 (save-restriction
468 (if entry
469 (progn
470 (set-buffer (get-buffer-create " *RefTeX-scratch*"))
471 (fundamental-mode)
472 (set-syntax-table reftex-syntax-table-for-bib)
473 (erase-buffer)
474 (insert entry))
475 (widen)
476 (if (and from to) (narrow-to-region from to)))
477 (goto-char (point-min))
478
479 (if (re-search-forward "@\\(\\(?:\\w\\|\\s_\\)+\\)[ \t\n\r]*\
480 \[{(][ \t\n\r]*\\([^ \t\n\r,]+\\)" nil t)
481 (setq alist
482 (list
483 (cons "&type" (downcase (reftex-match-string 1)))
484 (cons "&key" (reftex-match-string 2)))))
485 (while (re-search-forward "\\(\\(?:\\w\\|-\\)+\\)[ \t\n\r]*=[ \t\n\r]*"
486 nil t)
487 (setq key (downcase (reftex-match-string 1)))
488 (cond
489 ((= (following-char) ?{)
490 (cond
491 (raw
492 (setq start (point))
493 (forward-char 1))
494 (t
495 (forward-char 1)
496 (setq start (point))
497 (condition-case nil
498 (up-list 1)
499 (error nil)))))
500 ((= (following-char) ?\")
501 (cond
502 (raw
503 (setq start (point))
504 (forward-char 1))
505 (t
506 (forward-char 1)
507 (setq start (point))))
508 (while (and (search-forward "\"" nil t)
509 (= ?\\ (char-after (- (point) 2))))))
510 (t
511 (setq start (point))
512 (re-search-forward "[ \t]*[\n\r,}]" nil 1)))
513 ;; extract field value, ignore trailing comma if in RAW mode
514 (let ((stop (if (and raw (not (= (char-after (1- (point))) ?,)))
515 (point)
516 (1- (point))) ))
517 (setq field (buffer-substring-no-properties start stop)))
518 ;; remove extra whitespace
519 (while (string-match "[\n\t\r]\\|[ \t][ \t]+" field)
520 (setq field (replace-match " " nil t field)))
521 (push (cons key field) alist))))
522 alist))
523
524 (defun reftex-get-bib-field (fieldname entry &optional format)
525 "Extract the field FIELDNAME from ENTRY.
526 If FORMAT is non-nil `format' entry accordingly."
527 (let ((cell (assoc fieldname entry)))
528 (if cell
529 (if format
530 (format format (cdr cell))
531 (cdr cell))
532 "")))
533
534 (defun reftex-format-bib-entry (entry)
535 "Format a BibTeX ENTRY so that it is nice to look at."
536 (let*
537 ((auth-list (reftex-get-bib-names "author" entry))
538 (authors (mapconcat 'identity auth-list ", "))
539 (year (reftex-get-bib-field "year" entry))
540 (title (reftex-get-bib-field "title" entry))
541 (type (reftex-get-bib-field "&type" entry))
542 (key (reftex-get-bib-field "&key" entry))
543 (extra
544 (cond
545 ((equal type "article")
546 (concat (let ((jt (reftex-get-bib-field "journal" entry)))
547 ;; biblatex prefers the alternative journaltitle
548 ;; field, so check if that exists in case journal
549 ;; is empty.
550 (if (zerop (length jt))
551 (reftex-get-bib-field "journaltitle" entry)
552 jt))
553 " "
554 (reftex-get-bib-field "volume" entry) ", "
555 (reftex-get-bib-field "pages" entry)))
556 ((equal type "book")
557 (concat "book (" (reftex-get-bib-field "publisher" entry) ")"))
558 ((equal type "phdthesis")
559 (concat "PhD: " (reftex-get-bib-field "school" entry)))
560 ((equal type "mastersthesis")
561 (concat "Master: " (reftex-get-bib-field "school" entry)))
562 ((equal type "inbook")
563 (concat "Chap: " (reftex-get-bib-field "chapter" entry)
564 ", pp. " (reftex-get-bib-field "pages" entry)))
565 ((or (equal type "conference")
566 (equal type "incollection")
567 (equal type "inproceedings"))
568 (reftex-get-bib-field "booktitle" entry "in: %s"))
569 (t ""))))
570 (setq authors (reftex-truncate authors 30 t t))
571 (when (reftex-use-fonts)
572 (put-text-property 0 (length key) 'face reftex-label-face
573 key)
574 (put-text-property 0 (length authors) 'face reftex-bib-author-face
575 authors)
576 (put-text-property 0 (length year) 'face reftex-bib-year-face
577 year)
578 (put-text-property 0 (length title) 'face reftex-bib-title-face
579 title)
580 (put-text-property 0 (length extra) 'face reftex-bib-extra-face
581 extra))
582 (concat key "\n " authors " " year " " extra "\n " title "\n\n")))
583
584 (defun reftex-parse-bibitem (item)
585 "Parse a \bibitem entry in ITEM."
586 (let ((key "") (text ""))
587 (when (string-match "\\`{\\([^}]+\\)}\\([^\000]*\\)" item)
588 (setq key (match-string 1 item)
589 text (match-string 2 item)))
590 ;; Clean up the text a little bit
591 (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text)
592 (setq text (replace-match " " nil t text)))
593 (if (string-match "\\`[ \t]+" text)
594 (setq text (replace-match "" nil t text)))
595 (list
596 (cons "&key" key)
597 (cons "&text" text)
598 (cons "&entry" (concat key " " text)))))
599
600 (defun reftex-format-bibitem (item)
601 "Format a \bibitem entry in ITEM so that it is (relatively) nice to look at."
602 (let ((text (reftex-get-bib-field "&text" item))
603 (key (reftex-get-bib-field "&key" item))
604 (lines nil))
605
606 ;; Wrap the text into several lines.
607 (while (and (> (length text) 70)
608 (string-match " " (substring text 60)))
609 (push (substring text 0 (+ 60 (match-beginning 0))) lines)
610 (setq text (substring text (+ 61 (match-beginning 0)))))
611 (push text lines)
612 (setq text (mapconcat 'identity (nreverse lines) "\n "))
613
614 (when (reftex-use-fonts)
615 (put-text-property 0 (length text) 'face reftex-bib-author-face text))
616 (concat key "\n " text "\n\n")))
617
618 ;;; Make a citation
619
620 ;; NB this is a global autoload - see reftex.el.
621 ;;;###autoload
622 (defun reftex-citation (&optional no-insert format-key)
623 "Make a citation using BibTeX database files.
624 After prompting for a regular expression, scans the buffers with
625 bibtex entries (taken from the \\bibliography command) and offers the
626 matching entries for selection. The selected entry is formatted according
627 to `reftex-cite-format' and inserted into the buffer.
628
629 If NO-INSERT is non-nil, nothing is inserted, only the selected key returned.
630
631 FORMAT-KEY can be used to pre-select a citation format.
632
633 When called with a `C-u' prefix, prompt for optional arguments in
634 cite macros. When called with a numeric prefix, make that many
635 citations. When called with point inside the braces of a `\\cite'
636 command, it will add another key, ignoring the value of
637 `reftex-cite-format'.
638
639 The regular expression uses an expanded syntax: && is interpreted as `and'.
640 Thus, `aaaa&&bbb' matches entries which contain both `aaaa' and `bbb'.
641 While entering the regexp, completion on knows citation keys is possible.
642 `=' is a good regular expression to match all entries in all files."
643 (interactive)
644
645 ;; check for recursive edit
646 (reftex-check-recursive-edit)
647
648 ;; This function may also be called outside reftex-mode.
649 ;; Thus look for the scanning info only if in reftex-mode.
650
651 (when reftex-mode
652 (reftex-access-scan-info nil))
653
654 ;; Call reftex-do-citation, but protected
655 (unwind-protect
656 (reftex-do-citation current-prefix-arg no-insert format-key)
657 (reftex-kill-temporary-buffers)))
658
659 (defun reftex-do-citation (&optional arg no-insert format-key)
660 "This really does the work of `reftex-citation'."
661 (let* ((format (reftex-figure-out-cite-format arg no-insert format-key))
662 (docstruct-symbol reftex-docstruct-symbol)
663 (selected-entries (reftex-offer-bib-menu))
664 (insert-entries selected-entries)
665 entry string cite-view)
666
667 (unless selected-entries (error "Quit"))
668
669 (if (stringp selected-entries)
670 ;; Nonexistent entry
671 (setq insert-entries (list (list selected-entries
672 (cons "&key" selected-entries)))
673 selected-entries nil)
674 ;; It makes sense to compute the cite-view strings.
675 (setq cite-view t))
676
677 (when (eq (car selected-entries) 'concat)
678 ;; All keys go into a single command - we need to trick a little
679 ;; FIXME: Unfortunately, this means that commenting does not work right.
680 (pop selected-entries)
681 (let ((concat-keys (mapconcat 'car selected-entries
682 reftex-cite-key-separator)))
683 (setq insert-entries
684 (list (list concat-keys (cons "&key" concat-keys))))))
685
686 (unless no-insert
687
688 ;; We shall insert this into the buffer...
689 (message "Formatting...")
690
691 (while (setq entry (pop insert-entries))
692 ;; Format the citation and insert it
693 (setq string (if reftex-format-cite-function
694 (funcall reftex-format-cite-function
695 (reftex-get-bib-field "&key" entry)
696 format)
697 (reftex-format-citation entry format)))
698 (when (or (eq reftex-cite-prompt-optional-args t)
699 (and reftex-cite-prompt-optional-args
700 (equal arg '(4))))
701 (let ((start 0) (nth 0) value)
702 (while (setq start (string-match "\\[\\]" string start))
703 (setq value (save-match-data
704 (read-string (format "Optional argument %d: "
705 (setq nth (1+ nth))))))
706 (setq string (replace-match (concat "[" value "]") t t string))
707 (setq start (1+ start)))))
708 ;; Should we cleanup empty optional arguments?
709 ;; if the first is empty, it can be removed. If the second is empty,
710 ;; it has to go. If there is only a single arg and empty, it can go
711 ;; as well.
712 (when reftex-cite-cleanup-optional-args
713 (cond
714 ((string-match "\\([a-zA-Z0-9]\\)\\[\\]{" string)
715 (setq string (replace-match "\\1{" nil nil string)))
716 ((string-match "\\[\\]\\(\\[[a-zA-Z0-9., ]+\\]\\)" string)
717 (setq string (replace-match "\\1" nil nil string)))
718 ((string-match "\\[\\]\\[\\]" string)
719 (setq string (replace-match "" t t string)))))
720 (insert string))
721
722 ;; Reposition cursor?
723 (when (string-match "\\?" string)
724 (search-backward "?")
725 (delete-char 1))
726
727 ;; Tell AUCTeX
728 (when (and reftex-mode
729 (fboundp 'LaTeX-add-bibitems)
730 reftex-plug-into-AUCTeX)
731 (apply 'LaTeX-add-bibitems (mapcar 'car selected-entries)))
732
733 ;; Produce the cite-view strings
734 (when (and reftex-mode reftex-cache-cite-echo cite-view)
735 (mapc (lambda (entry)
736 (reftex-make-cite-echo-string entry docstruct-symbol))
737 selected-entries))
738
739 (message ""))
740
741 (set-marker reftex-select-return-marker nil)
742 (reftex-kill-buffer "*RefTeX Select*")
743
744 ;; Check if the prefix arg was numeric, and call recursively
745 (when (integerp arg)
746 (if (> arg 1)
747 (progn
748 (skip-chars-backward "}")
749 (decf arg)
750 (reftex-do-citation arg))
751 (forward-char 1)))
752
753 ;; Return the citation key
754 (mapcar 'car selected-entries)))
755
756 (defun reftex-figure-out-cite-format (arg &optional no-insert format-key)
757 "Check if there is already a cite command at point and change cite format
758 in order to only add another reference in the same cite command."
759 (let ((macro (car (reftex-what-macro 1)))
760 (cite-format-value (reftex-get-cite-format))
761 key format)
762 (cond
763 (no-insert
764 ;; Format does not really matter because nothing will be inserted.
765 (setq format "%l"))
766
767 ((and (stringp macro)
768 (string-match "\\`\\\\cite\\|cite\\'" macro))
769 ;; We are already inside a cite macro
770 (if (or (not arg) (not (listp arg)))
771 (setq format
772 (concat
773 (if (member (preceding-char) '(?\{ ?,))
774 ""
775 reftex-cite-key-separator)
776 "%l"
777 (if (member (following-char) '(?\} ?,))
778 ""
779 reftex-cite-key-separator)))
780 (setq format "%l")))
781 (t
782 ;; Figure out the correct format
783 (setq format
784 (if (and (symbolp cite-format-value)
785 (assq cite-format-value reftex-cite-format-builtin))
786 (nth 2 (assq cite-format-value reftex-cite-format-builtin))
787 cite-format-value))
788 (when (listp format)
789 (setq key
790 (or format-key
791 (reftex-select-with-char
792 "" (concat "SELECT A CITATION FORMAT\n\n"
793 (mapconcat
794 (lambda (x)
795 (format "[%c] %s %s" (car x)
796 (if (> (car x) 31) " " "")
797 (cdr x)))
798 format "\n")))))
799 (if (assq key format)
800 (setq format (cdr (assq key format)))
801 (error "No citation format associated with key `%c'" key)))))
802 format))
803
804 ;;;###autoload
805 (defun reftex-citep ()
806 "Call `reftex-citation' with a format selector `?p'."
807 (interactive)
808 (reftex-citation nil ?p))
809
810 ;;;###autoload
811 (defun reftex-citet ()
812 "Call `reftex-citation' with a format selector `?t'."
813 (interactive)
814 (reftex-citation nil ?t))
815
816 (defvar reftex-select-bib-map)
817 (defun reftex-offer-bib-menu ()
818 "Offer bib menu and return list of selected items."
819 (let ((bibtype (reftex-bib-or-thebib))
820 found-list rtn key data selected-entries)
821 (while
822 (not
823 (catch 'done
824 ;; Scan bibtex files
825 (setq found-list
826 (cond
827 ((eq bibtype 'bib)
828 ; ((assq 'bib (symbol-value reftex-docstruct-symbol))
829 ;; using BibTeX database files.
830 (reftex-extract-bib-entries (reftex-get-bibfile-list)))
831 ((eq bibtype 'thebib)
832 ; ((assq 'thebib (symbol-value reftex-docstruct-symbol))
833 ;; using thebibliography environment.
834 (reftex-extract-bib-entries-from-thebibliography
835 (reftex-uniquify
836 (mapcar 'cdr
837 (reftex-all-assq
838 'thebib (symbol-value reftex-docstruct-symbol))))))
839 (reftex-default-bibliography
840 (message "Using default bibliography")
841 (reftex-extract-bib-entries (reftex-default-bibliography)))
842 (t (error "No valid bibliography in this document, and no default available"))))
843
844 (unless found-list
845 (error "Sorry, no matches found"))
846
847 ;; Remember where we came from
848 (setq reftex-call-back-to-this-buffer (current-buffer))
849 (set-marker reftex-select-return-marker (point))
850
851 ;; Offer selection
852 (save-window-excursion
853 (delete-other-windows)
854 (reftex-kill-buffer "*RefTeX Select*")
855 (switch-to-buffer-other-window "*RefTeX Select*")
856 (unless (eq major-mode 'reftex-select-bib-mode)
857 (reftex-select-bib-mode))
858 (let ((buffer-read-only nil))
859 (erase-buffer)
860 (reftex-insert-bib-matches found-list))
861 (setq buffer-read-only t)
862 (if (= 0 (buffer-size))
863 (error "No matches found"))
864 (setq truncate-lines t)
865 (goto-char 1)
866 (while t
867 (setq rtn
868 (reftex-select-item
869 reftex-citation-prompt
870 reftex-citation-help
871 reftex-select-bib-map
872 nil
873 'reftex-bibtex-selection-callback nil))
874 (setq key (car rtn)
875 data (nth 1 rtn))
876 (unless key (throw 'done t))
877 (cond
878 ((eq key ?g)
879 ;; Start over
880 (throw 'done nil))
881 ((eq key ?r)
882 ;; Restrict with new regular expression
883 (setq found-list (reftex-restrict-bib-matches found-list))
884 (let ((buffer-read-only nil))
885 (erase-buffer)
886 (reftex-insert-bib-matches found-list))
887 (goto-char 1))
888 ((eq key ?A)
889 ;; Take all (marked)
890 (setq selected-entries
891 (if reftex-select-marked
892 (mapcar 'car (nreverse reftex-select-marked))
893 found-list))
894 (throw 'done t))
895 ((eq key ?a)
896 ;; Take all (marked), and push the symbol 'concat
897 (setq selected-entries
898 (cons 'concat
899 (if reftex-select-marked
900 (mapcar 'car (nreverse reftex-select-marked))
901 found-list)))
902 (throw 'done t))
903 ((eq key ?e)
904 ;; Take all (marked), and push the symbol 'concat
905 (reftex-extract-bib-file found-list reftex-select-marked)
906 (setq selected-entries "BibTeX database file created")
907 (throw 'done t))
908 ((eq key ?E)
909 ;; Take all (marked), and push the symbol 'concat
910 (reftex-extract-bib-file found-list reftex-select-marked
911 'complement)
912 (setq selected-entries "BibTeX database file created")
913 (throw 'done t))
914 ((or (eq key ?\C-m)
915 (eq key 'return))
916 ;; Take selected
917 (setq selected-entries
918 (if reftex-select-marked
919 (cons 'concat
920 (mapcar 'car (nreverse reftex-select-marked)))
921 (if data (list data) nil)))
922 (throw 'done t))
923 ((stringp key)
924 ;; Got this one with completion
925 (setq selected-entries key)
926 (throw 'done t))
927 (t
928 (ding))))))))
929 selected-entries))
930
931 (defun reftex-restrict-bib-matches (found-list)
932 "Limit FOUND-LIST with more regular expressions."
933 (let ((re-list (split-string (read-string
934 "RegExp [ && RegExp...]: "
935 nil 'reftex-cite-regexp-hist)
936 "[ \t]*&&[ \t]*"))
937 (found-list-r found-list)
938 re)
939 (while (setq re (pop re-list))
940 (setq found-list-r
941 (delq nil
942 (mapcar
943 (lambda (x)
944 (if (string-match
945 re (cdr (assoc "&entry" x)))
946 x
947 nil))
948 found-list-r))))
949 (if found-list-r
950 found-list-r
951 (ding)
952 found-list)))
953
954 (defun reftex-extract-bib-file (all &optional marked complement)
955 "Limit FOUND-LIST with more regular expressions."
956 (let ((file (read-file-name "File to create: ")))
957 (find-file-other-window file)
958 (if (> (buffer-size) 0)
959 (unless (yes-or-no-p
960 (format "Overwrite non-empty file %s? " file))
961 (error "Abort")))
962 (erase-buffer)
963 (setq all (delq nil
964 (mapcar
965 (lambda (x)
966 (if marked
967 (if (or (and (assoc x marked) (not complement))
968 (and (not (assoc x marked)) complement))
969 (cdr (assoc "&entry" x))
970 nil)
971 (cdr (assoc "&entry" x))))
972 all)))
973 (insert (mapconcat 'identity all "\n\n"))
974 (save-buffer)
975 (goto-char (point-min))))
976
977 (defun reftex-insert-bib-matches (list)
978 "Insert the bib matches and number them correctly."
979 (let ((mouse-face
980 (if (memq reftex-highlight-selection '(mouse both))
981 reftex-mouse-selected-face
982 nil))
983 tmp len)
984 (mapc
985 (lambda (x)
986 (setq tmp (cdr (assoc "&formatted" x))
987 len (length tmp))
988 (put-text-property 0 len :data x tmp)
989 (put-text-property 0 (1- len) 'mouse-face mouse-face tmp)
990 (insert tmp))
991 list))
992 (run-hooks 'reftex-display-copied-context-hook))
993
994 (defun reftex-format-names (namelist n)
995 (let (last (len (length namelist)))
996 (if (= n 0) (setq n len))
997 (cond
998 ((< len 1) "")
999 ((= 1 len) (car namelist))
1000 ((> len n) (concat (car namelist) (nth 2 reftex-cite-punctuation)))
1001 (t
1002 (setq n (min len n)
1003 last (nth (1- n) namelist))
1004 (setcdr (nthcdr (- n 2) namelist) nil)
1005 (concat
1006 (mapconcat 'identity namelist (nth 0 reftex-cite-punctuation))
1007 (nth 1 reftex-cite-punctuation)
1008 last)))))
1009
1010 (defun reftex-format-citation (entry format)
1011 "Format a citation from the info in the BibTeX ENTRY according to FORMAT."
1012 (unless (stringp format) (setq format "\\cite{%l}"))
1013
1014 (if (and reftex-comment-citations
1015 (string-match "%l" reftex-cite-comment-format))
1016 (error "reftex-cite-comment-format contains invalid %%l"))
1017
1018 (while (string-match
1019 "\\(\\`\\|[^%]\\)\\(\\(%\\([0-9]*\\)\\([a-zA-Z]\\)\\)[.,;: ]*\\)"
1020 format)
1021 (let ((n (string-to-number (match-string 4 format)))
1022 (l (string-to-char (match-string 5 format)))
1023 rpl b e)
1024 (save-match-data
1025 (setq rpl
1026 (cond
1027 ((= l ?l) (concat
1028 (reftex-get-bib-field "&key" entry)
1029 (if reftex-comment-citations
1030 reftex-cite-comment-format
1031 "")))
1032 ((= l ?a) (reftex-format-names
1033 (reftex-get-bib-names "author" entry)
1034 (or n 2)))
1035 ((= l ?A) (car (reftex-get-bib-names "author" entry)))
1036 ((= l ?b) (reftex-get-bib-field "booktitle" entry "in: %s"))
1037 ((= l ?B) (reftex-abbreviate-title
1038 (reftex-get-bib-field "booktitle" entry "in: %s")))
1039 ((= l ?c) (reftex-get-bib-field "chapter" entry))
1040 ((= l ?d) (reftex-get-bib-field "edition" entry))
1041 ((= l ?e) (reftex-format-names
1042 (reftex-get-bib-names "editor" entry)
1043 (or n 2)))
1044 ((= l ?E) (car (reftex-get-bib-names "editor" entry)))
1045 ((= l ?h) (reftex-get-bib-field "howpublished" entry))
1046 ((= l ?i) (reftex-get-bib-field "institution" entry))
1047 ((= l ?j) (reftex-get-bib-field "journal" entry))
1048 ((= l ?k) (reftex-get-bib-field "key" entry))
1049 ((= l ?m) (reftex-get-bib-field "month" entry))
1050 ((= l ?n) (reftex-get-bib-field "number" entry))
1051 ((= l ?N) (reftex-get-bib-field "note" entry))
1052 ((= l ?o) (reftex-get-bib-field "organization" entry))
1053 ((= l ?p) (reftex-get-bib-field "pages" entry))
1054 ((= l ?P) (car (split-string
1055 (reftex-get-bib-field "pages" entry)
1056 "[- .]+")))
1057 ((= l ?s) (reftex-get-bib-field "school" entry))
1058 ((= l ?u) (reftex-get-bib-field "publisher" entry))
1059 ((= l ?U) (reftex-get-bib-field "url" entry))
1060 ((= l ?r) (reftex-get-bib-field "address" entry))
1061 ((= l ?t) (reftex-get-bib-field "title" entry))
1062 ((= l ?T) (reftex-abbreviate-title
1063 (reftex-get-bib-field "title" entry)))
1064 ((= l ?v) (reftex-get-bib-field "volume" entry))
1065 ((= l ?y) (reftex-get-bib-field "year" entry)))))
1066
1067 (if (string= rpl "")
1068 (setq b (match-beginning 2) e (match-end 2))
1069 (setq b (match-beginning 3) e (match-end 3)))
1070 (setq format (concat (substring format 0 b) rpl (substring format e)))))
1071 (while (string-match "%%" format)
1072 (setq format (replace-match "%" t t format)))
1073 (while (string-match "[ ,.;:]*%<" format)
1074 (setq format (replace-match "" t t format)))
1075 format)
1076
1077 ;;;###autoload
1078 (defun reftex-make-cite-echo-string (entry docstruct-symbol)
1079 "Format a bibtex ENTRY for the echo area and cache the result."
1080 (let* ((key (reftex-get-bib-field "&key" entry))
1081 (string
1082 (let* ((reftex-cite-punctuation '(" " " & " " etal.")))
1083 (reftex-format-citation entry reftex-cite-view-format)))
1084 (cache (assq 'bibview-cache (symbol-value docstruct-symbol)))
1085 (cache-entry (assoc key (cdr cache))))
1086 (unless cache
1087 ;; This docstruct has no cache - make one.
1088 (set docstruct-symbol (cons (cons 'bibview-cache nil)
1089 (symbol-value docstruct-symbol))))
1090 (when reftex-cache-cite-echo
1091 (setq key (copy-sequence key))
1092 (set-text-properties 0 (length key) nil key)
1093 (set-text-properties 0 (length string) nil string)
1094 (if cache-entry
1095 (unless (string= (cdr cache-entry) string)
1096 (setcdr cache-entry string)
1097 (put reftex-docstruct-symbol 'modified t))
1098 (push (cons key string) (cdr cache))
1099 (put reftex-docstruct-symbol 'modified t)))
1100 string))
1101
1102 (defun reftex-bibtex-selection-callback (data ignore no-revisit)
1103 "Callback function to be called from the BibTeX selection, in
1104 order to display context. This function is relatively slow and not
1105 recommended for follow mode. It works OK for individual lookups."
1106 (let ((win (selected-window))
1107 (key (reftex-get-bib-field "&key" data))
1108 bibfile-list item bibtype)
1109
1110 (catch 'exit
1111 (with-current-buffer reftex-call-back-to-this-buffer
1112 (setq bibtype (reftex-bib-or-thebib))
1113 (cond
1114 ((eq bibtype 'bib)
1115 ; ((assq 'bib (symbol-value reftex-docstruct-symbol))
1116 (setq bibfile-list (reftex-get-bibfile-list)))
1117 ((eq bibtype 'thebib)
1118 ; ((assq 'thebib (symbol-value reftex-docstruct-symbol))
1119 (setq bibfile-list
1120 (reftex-uniquify
1121 (mapcar 'cdr
1122 (reftex-all-assq
1123 'thebib (symbol-value reftex-docstruct-symbol))))
1124 item t))
1125 (reftex-default-bibliography
1126 (setq bibfile-list (reftex-default-bibliography)))
1127 (t (ding) (throw 'exit nil))))
1128
1129 (when no-revisit
1130 (setq bibfile-list (reftex-visited-files bibfile-list)))
1131
1132 (condition-case nil
1133 (reftex-pop-to-bibtex-entry
1134 key bibfile-list (not reftex-keep-temporary-buffers) t item)
1135 (error (ding))))
1136
1137 (select-window win)))
1138
1139 ;;; Global BibTeX file
1140 (defun reftex-all-used-citation-keys ()
1141 (reftex-access-scan-info)
1142 (let ((files (reftex-all-document-files)) file keys kk k)
1143 (save-current-buffer
1144 (while (setq file (pop files))
1145 (set-buffer (reftex-get-file-buffer-force file 'mark))
1146 (save-excursion
1147 (save-restriction
1148 (widen)
1149 (goto-char (point-min))
1150 (while (re-search-forward "\\(?:^\\|\\=\\)[^%\n\r]*?\\\\\\(bibentry\\|[a-zA-Z]*cite[a-zA-Z]*\\)\\(\\[[^]]*\\]\\)?{\\([^}]+\\)}" nil t)
1151 (setq kk (match-string-no-properties 3))
1152 (while (string-match "%.*\n?" kk)
1153 (setq kk (replace-match "" t t kk)))
1154 (setq kk (split-string kk "[, \t\r\n]+"))
1155 (while (setq k (pop kk))
1156 (or (member k keys)
1157 (setq keys (cons k keys)))))))))
1158 (reftex-kill-temporary-buffers)
1159 keys))
1160
1161 (defun reftex-get-string-refs (alist)
1162 "Return a list of BibTeX @string references that appear as values in ALIST."
1163 (reftex-remove-if (lambda (x) (string-match "^\\([\"{]\\|[0-9]+$\\)" x))
1164 ;; get list of values, discard keys
1165 (mapcar 'cdr
1166 ;; remove &key and &type entries
1167 (reftex-remove-if (lambda (pair)
1168 (string-match "^&" (car pair)))
1169 alist))))
1170
1171 ;;;###autoload
1172 (defun reftex-create-bibtex-file (bibfile)
1173 "Create a new BibTeX database BIBFILE with all entries referenced in document.
1174 The command prompts for a filename and writes the collected
1175 entries to that file. Only entries referenced in the current
1176 document with any \\cite-like macros are used. The sequence in
1177 the new file is the same as it was in the old database.
1178
1179 Entries referenced from other entries must appear after all
1180 referencing entries.
1181
1182 You can define strings to be used as header or footer for the
1183 created files in the variables `reftex-create-bibtex-header' or
1184 `reftex-create-bibtex-footer' respectively."
1185 (interactive "FNew BibTeX file: ")
1186 (let ((keys (reftex-all-used-citation-keys))
1187 (files (reftex-get-bibfile-list))
1188 file key entries beg end entry string-keys string-entries)
1189 (save-current-buffer
1190 (dolist (file files)
1191 (set-buffer (reftex-get-file-buffer-force file 'mark))
1192 (reftex-with-special-syntax-for-bib
1193 (save-excursion
1194 (save-restriction
1195 (widen)
1196 (goto-char (point-min))
1197 (while (re-search-forward "^[ \t]*@\\(?:\\w\\|\\s_\\)+[ \t\n\r]*\
1198 \[{(][ \t\n\r]*\\([^ \t\n\r,]+\\)" nil t)
1199 (setq key (match-string 1)
1200 beg (match-beginning 0)
1201 end (progn
1202 (goto-char (match-beginning 1))
1203 (condition-case nil
1204 (up-list 1)
1205 (error (goto-char (match-end 0))))
1206 (point)))
1207 (when (member key keys)
1208 (setq entry (buffer-substring beg end)
1209 entries (cons entry entries)
1210 keys (delete key keys))
1211
1212 ;; check for crossref entries
1213 (let* ((attr-list (reftex-parse-bibtex-entry nil beg end))
1214 (xref-key (cdr (assoc "crossref" attr-list))))
1215 (if xref-key (pushnew xref-key keys)))
1216 ;; check for string references
1217 (let* ((raw-fields (reftex-parse-bibtex-entry nil beg end t))
1218 (string-fields (reftex-get-string-refs raw-fields)))
1219 (dolist (skey string-fields)
1220 (unless (member skey string-keys)
1221 (push skey string-keys)))))))))))
1222 ;; second pass: grab @string references
1223 (if string-keys
1224 (save-current-buffer
1225 (dolist (file files)
1226 (set-buffer (reftex-get-file-buffer-force file 'mark))
1227 (reftex-with-special-syntax-for-bib
1228 (save-excursion
1229 (save-restriction
1230 (widen)
1231 (goto-char (point-min))
1232 (while (re-search-forward
1233 "^[ \t]*@[Ss][Tt][Rr][Ii][Nn][Gg][ \t]*{[ \t]*\\([^ \t\r\n]+\\)"
1234 nil t)
1235 (setq key (match-string 1)
1236 beg (match-beginning 0)
1237 end (progn
1238 (goto-char (match-beginning 1))
1239 (condition-case nil
1240 (up-list 1)
1241 (error (goto-char (match-end 0))))
1242 (point)))
1243 (when (member key string-keys)
1244 (setq entry (buffer-substring beg end)
1245 string-entries (cons entry string-entries)
1246 string-keys (delete key string-keys))))))))))
1247 (find-file-other-window bibfile)
1248 (if (> (buffer-size) 0)
1249 (unless (yes-or-no-p
1250 (format "Overwrite non-empty file %s? " bibfile))
1251 (error "Abort")))
1252 (erase-buffer)
1253 (if reftex-create-bibtex-header (insert reftex-create-bibtex-header "\n\n"))
1254 (insert (mapconcat 'identity (reverse string-entries) "\n\n"))
1255 (if string-entries (insert "\n\n\n"))
1256 (insert (mapconcat 'identity (reverse entries) "\n\n"))
1257 (if reftex-create-bibtex-footer (insert "\n\n" reftex-create-bibtex-footer))
1258 (goto-char (point-min))
1259 (save-buffer)
1260 (message "%d entries extracted and copied to new database"
1261 (length entries))))
1262
1263 (provide 'reftex-cite)
1264 ;;; reftex-cite.el ends here
1265
1266 ;; Local Variables:
1267 ;; generated-autoload-file: "reftex.el"
1268 ;; End: