Mercurial > emacs
comparison lisp/textmodes/reftex-cite.el @ 88155:d7ddb3e565de
sync with trunk
author | Henrik Enberg <henrik.enberg@telia.com> |
---|---|
date | Mon, 16 Jan 2006 00:03:54 +0000 |
parents | 5ade352e8d1c |
children |
comparison
equal
deleted
inserted
replaced
88154:8ce476d3ba36 | 88155:d7ddb3e565de |
---|---|
1 ;;; reftex-cite.el --- creating citations with RefTeX | 1 ;;; reftex-cite.el --- creating citations with RefTeX |
2 ;; Copyright (c) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. | 2 ;; Copyright (c) 1997, 1998, 1999, 2000, 2003, 2004, 2005 |
3 ;; Free Software Foundation, Inc. | |
3 | 4 |
4 ;; Author: Carsten Dominik <dominik@science.uva.nl> | 5 ;; Author: Carsten Dominik <dominik@science.uva.nl> |
5 ;; Version: 4.18 | 6 ;; Version: VERSIONTAG |
6 | 7 |
7 ;; This file is part of GNU Emacs. | 8 ;; This file is part of GNU Emacs. |
8 | 9 |
9 ;; GNU Emacs is free software; you can redistribute it and/or modify | 10 ;; 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 ;; it under the terms of the GNU General Public License as published by |
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 ;; GNU General Public License for more details. | 18 ;; GNU General Public License for more details. |
18 | 19 |
19 ;; You should have received a copy of the GNU General Public License | 20 ;; 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 ;; along with GNU Emacs; see the file COPYING. If not, write to the |
21 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 22 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
22 ;; Boston, MA 02111-1307, USA. | 23 ;; Boston, MA 02110-1301, USA. |
23 | 24 |
24 ;;; Commentary: | 25 ;;; Commentary: |
25 | 26 |
26 ;;; Code: | 27 ;;; Code: |
27 | 28 |
47 . Show insertion point. | 48 . Show insertion point. |
48 q Quit without inserting \\cite macro into buffer. | 49 q Quit without inserting \\cite macro into buffer. |
49 TAB Enter citation key with completion. | 50 TAB Enter citation key with completion. |
50 RET Accept current entry (also on mouse-2) and create \\cite macro. | 51 RET Accept current entry (also on mouse-2) and create \\cite macro. |
51 m / u Mark/Unmark the entry. | 52 m / u Mark/Unmark the entry. |
53 e / E Create BibTeX file with all (marked/unmarked) entries | |
52 a / A Put all (marked) entries into one/many \\cite commands.") | 54 a / A Put all (marked) entries into one/many \\cite commands.") |
53 | 55 |
54 ;; Find bibtex files | 56 ;; Find bibtex files |
55 | |
56 | 57 |
57 (defmacro reftex-with-special-syntax-for-bib (&rest body) | 58 (defmacro reftex-with-special-syntax-for-bib (&rest body) |
58 `(let ((saved-syntax (syntax-table))) | 59 `(let ((saved-syntax (syntax-table))) |
59 (unwind-protect | 60 (unwind-protect |
60 (progn | 61 (progn |
61 (set-syntax-table reftex-syntax-table-for-bib) | 62 (set-syntax-table reftex-syntax-table-for-bib) |
62 ,@body) | 63 ,@body) |
63 (set-syntax-table saved-syntax)))) | 64 (set-syntax-table saved-syntax)))) |
64 | 65 |
65 (defun reftex-default-bibliography () | 66 (defun reftex-default-bibliography () |
66 ;; Return the expanded value of `reftex-default-bibliography'. | 67 ;; Return the expanded value of `reftex-default-bibliography'. |
67 ;; The expanded value is cached. | 68 ;; The expanded value is cached. |
68 (unless (eq (get 'reftex-default-bibliography :reftex-raw) | 69 (unless (eq (get 'reftex-default-bibliography :reftex-raw) |
69 reftex-default-bibliography) | 70 reftex-default-bibliography) |
70 (put 'reftex-default-bibliography :reftex-expanded | 71 (put 'reftex-default-bibliography :reftex-expanded |
71 (reftex-locate-bibliography-files | 72 (reftex-locate-bibliography-files |
72 default-directory reftex-default-bibliography)) | 73 default-directory reftex-default-bibliography)) |
73 (put 'reftex-default-bibliography :reftex-raw | 74 (put 'reftex-default-bibliography :reftex-raw |
74 reftex-default-bibliography)) | 75 reftex-default-bibliography)) |
75 (get 'reftex-default-bibliography :reftex-expanded)) | 76 (get 'reftex-default-bibliography :reftex-expanded)) |
76 | 77 |
77 (defun reftex-bib-or-thebib () | 78 (defun reftex-bib-or-thebib () |
78 ;; Tests if BibTeX or \begin{tehbibliography} should be used for the | 79 ;; Tests if BibTeX or \begin{tehbibliography} should be used for the |
79 ;; citation | 80 ;; citation |
80 ;; Find the bof of the current file | 81 ;; Find the bof of the current file |
81 (let* ((docstruct (symbol-value reftex-docstruct-symbol)) | 82 (let* ((docstruct (symbol-value reftex-docstruct-symbol)) |
82 (rest (or (member (list 'bof (buffer-file-name)) docstruct) | 83 (rest (or (member (list 'bof (buffer-file-name)) docstruct) |
83 docstruct)) | 84 docstruct)) |
84 (bib (assq 'bib rest)) | 85 (bib (assq 'bib rest)) |
85 (thebib (assq 'thebib rest)) | 86 (thebib (assq 'thebib rest)) |
86 (bibmem (memq bib rest)) | 87 (bibmem (memq bib rest)) |
87 (thebibmem (memq thebib rest))) | 88 (thebibmem (memq thebib rest))) |
88 (when (not (or thebib bib)) | 89 (when (not (or thebib bib)) |
89 (setq bib (assq 'bib docstruct) | 90 (setq bib (assq 'bib docstruct) |
90 thebib (assq 'thebib docstruct) | 91 thebib (assq 'thebib docstruct) |
91 bibmem (memq bib docstruct) | 92 bibmem (memq bib docstruct) |
92 thebibmem (memq thebib docstruct))) | 93 thebibmem (memq thebib docstruct))) |
93 (if (> (length bibmem) (length thebibmem)) | 94 (if (> (length bibmem) (length thebibmem)) |
94 (if bib 'bib nil) | 95 (if bib 'bib nil) |
95 (if thebib 'thebib nil)))) | 96 (if thebib 'thebib nil)))) |
96 | 97 |
97 (defun reftex-get-bibfile-list () | 98 (defun reftex-get-bibfile-list () |
98 ;; Return list of bibfiles for current document. | 99 ;; Return list of bibfiles for current document. |
99 ;; When using the chapterbib or bibunits package you should either | 100 ;; When using the chapterbib or bibunits package you should either |
117 (error "\\bibliography statement missing or .bib files not found"))) | 118 (error "\\bibliography statement missing or .bib files not found"))) |
118 | 119 |
119 ;; Find a certain reference in any of the BibTeX files. | 120 ;; Find a certain reference in any of the BibTeX files. |
120 | 121 |
121 (defun reftex-pop-to-bibtex-entry (key file-list &optional mark-to-kill | 122 (defun reftex-pop-to-bibtex-entry (key file-list &optional mark-to-kill |
122 highlight item return) | 123 highlight item return) |
123 ;; Find BibTeX KEY in any file in FILE-LIST in another window. | 124 ;; 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 MARK-TO-KILL is non-nil, mark new buffer to kill. |
125 ;; If HIGHLIGHT is non-nil, highlight the match. | 126 ;; If HIGHLIGHT is non-nil, highlight the match. |
126 ;; If ITEM in non-nil, search for bibitem instead of database entry. | 127 ;; If ITEM in non-nil, search for bibitem instead of database entry. |
127 ;; If RETURN is non-nil, just return the entry. | 128 ;; If RETURN is non-nil, just return the entry. |
128 | 129 |
129 (let* ((re | 130 (let* ((re |
130 (if item | 131 (if item |
131 (concat "\\\\bibitem\\(\\[[^]]*\\]\\)?{" (regexp-quote key) "}") | 132 (concat "\\\\bibitem\\(\\[[^]]*\\]\\)?{" (regexp-quote key) "}") |
132 (concat "@[a-zA-Z]+[ \t\n\r]*[{(][ \t\n\r]*" (regexp-quote key) | 133 (concat "@[a-zA-Z]+[ \t\n\r]*[{(][ \t\n\r]*" (regexp-quote key) |
133 "[, \t\r\n}]"))) | 134 "[, \t\r\n}]"))) |
134 (buffer-conf (current-buffer)) | 135 (buffer-conf (current-buffer)) |
135 file buf pos) | 136 file buf pos) |
136 | 137 |
137 (catch 'exit | 138 (catch 'exit |
138 (while file-list | 139 (while file-list |
139 (setq file (car file-list) | 140 (setq file (car file-list) |
143 (set-buffer buf) | 144 (set-buffer buf) |
144 (widen) | 145 (widen) |
145 (goto-char (point-min)) | 146 (goto-char (point-min)) |
146 (when (re-search-forward re nil t) | 147 (when (re-search-forward re nil t) |
147 (goto-char (match-beginning 0)) | 148 (goto-char (match-beginning 0)) |
148 (setq pos (point)) | 149 (setq pos (point)) |
149 (when return | 150 (when return |
150 ;; Just return the relevant entry | 151 ;; Just return the relevant entry |
151 (if item (goto-char (match-end 0))) | 152 (if item (goto-char (match-end 0))) |
152 (setq return (buffer-substring | 153 (setq return (buffer-substring |
153 (point) (reftex-end-of-bib-entry item))) | 154 (point) (reftex-end-of-bib-entry item))) |
154 (set-buffer buffer-conf) | 155 (set-buffer buffer-conf) |
155 (throw 'exit return)) | 156 (throw 'exit return)) |
156 (switch-to-buffer-other-window buf) | 157 (switch-to-buffer-other-window buf) |
157 (goto-char pos) | 158 (goto-char pos) |
158 (recenter 0) | 159 (recenter 0) |
159 (if highlight | 160 (if highlight |
160 (reftex-highlight 0 (match-beginning 0) (match-end 0))) | 161 (reftex-highlight 0 (match-beginning 0) (match-end 0))) |
161 (throw 'exit (selected-window)))) | 162 (throw 'exit (selected-window)))) |
162 (set-buffer buffer-conf) | 163 (set-buffer buffer-conf) |
163 (if item | 164 (if item |
164 (error "No \\bibitem with citation key %s" key) | 165 (error "No \\bibitem with citation key %s" key) |
165 (error "No BibTeX entry with citation key %s" key))))) | 166 (error "No BibTeX entry with citation key %s" key))))) |
166 | 167 |
167 (defun reftex-end-of-bib-entry (item) | 168 (defun reftex-end-of-bib-entry (item) |
168 (save-excursion | 169 (save-excursion |
169 (condition-case nil | 170 (condition-case nil |
170 (if item | 171 (if item |
171 (progn (end-of-line) | 172 (progn (end-of-line) |
172 (re-search-forward | 173 (re-search-forward |
173 "\\\\bibitem\\|\\end{thebibliography}") | 174 "\\\\bibitem\\|\\end{thebibliography}") |
174 (1- (match-beginning 0))) | 175 (1- (match-beginning 0))) |
175 (progn (forward-list 1) (point))) | 176 (progn (forward-list 1) (point))) |
176 (error (min (point-max) (+ 300 (point))))))) | 177 (error (min (point-max) (+ 300 (point))))))) |
177 | 178 |
178 ;; Parse bibtex buffers | 179 ;; Parse bibtex buffers |
179 | 180 |
180 (defun reftex-extract-bib-entries (buffers) | 181 (defun reftex-extract-bib-entries (buffers) |
186 found-list entry buffer1 buffer alist | 187 found-list entry buffer1 buffer alist |
187 key-point start-point end-point default) | 188 key-point start-point end-point default) |
188 | 189 |
189 ;; Read a regexp, completing on known citation keys. | 190 ;; Read a regexp, completing on known citation keys. |
190 (setq default (regexp-quote (reftex-get-bibkey-default))) | 191 (setq default (regexp-quote (reftex-get-bibkey-default))) |
191 (setq re-list | 192 (setq re-list |
192 (split-string | 193 (split-string |
193 (completing-read | 194 (completing-read |
194 (concat | 195 (concat |
195 "Regex { && Regex...}: " | 196 "Regex { && Regex...}: " |
196 "[" default "]: ") | 197 "[" default "]: ") |
197 (if reftex-mode | 198 (if reftex-mode |
198 (if (fboundp 'LaTeX-bibitem-list) | 199 (if (fboundp 'LaTeX-bibitem-list) |
199 (LaTeX-bibitem-list) | 200 (LaTeX-bibitem-list) |
200 (cdr (assoc 'bibview-cache | 201 (cdr (assoc 'bibview-cache |
201 (symbol-value reftex-docstruct-symbol)))) | 202 (symbol-value reftex-docstruct-symbol)))) |
202 nil) | 203 nil) |
203 nil nil nil 'reftex-cite-regexp-hist) | 204 nil nil nil 'reftex-cite-regexp-hist) |
204 "[ \t]*&&[ \t]*")) | 205 "[ \t]*&&[ \t]*")) |
205 | 206 |
206 (if (or (null re-list ) (equal re-list '(""))) | 207 (if (or (null re-list ) (equal re-list '(""))) |
207 (setq re-list (list default))) | 208 (setq re-list (list default))) |
208 | 209 |
209 (setq first-re (car re-list) ; We'll use the first re to find things, | 210 (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 rest-re (cdr re-list)) ; the others to narrow down. |
211 (if (string-match "\\`[ \t]*\\'" (or first-re "")) | 212 (if (string-match "\\`[ \t]*\\'" (or first-re "")) |
212 (error "Empty regular expression")) | 213 (error "Empty regular expression")) |
226 (if (not buffer1) | 227 (if (not buffer1) |
227 (message "No such BibTeX file %s (ignored)" buffer) | 228 (message "No such BibTeX file %s (ignored)" buffer) |
228 (message "Scanning bibliography database %s" buffer1)) | 229 (message "Scanning bibliography database %s" buffer1)) |
229 | 230 |
230 (set-buffer buffer1) | 231 (set-buffer buffer1) |
231 (reftex-with-special-syntax-for-bib | 232 (reftex-with-special-syntax-for-bib |
232 (save-excursion | 233 (save-excursion |
233 (goto-char (point-min)) | 234 (goto-char (point-min)) |
234 (while (re-search-forward first-re nil t) | 235 (while (re-search-forward first-re nil t) |
235 (catch 'search-again | 236 (catch 'search-again |
236 (setq key-point (point)) | 237 (setq key-point (point)) |
237 (unless (re-search-backward | 238 (unless (re-search-backward |
238 "\\(\\`\\|[\n\r]\\)[ \t]*@\\([a-zA-Z]+\\)[ \t\n\r]*[{(]" nil t) | 239 "\\(\\`\\|[\n\r]\\)[ \t]*@\\([a-zA-Z]+\\)[ \t\n\r]*[{(]" nil t) |
239 (throw 'search-again nil)) | 240 (throw 'search-again nil)) |
240 (setq start-point (point)) | 241 (setq start-point (point)) |
241 (goto-char (match-end 0)) | 242 (goto-char (match-end 0)) |
242 (condition-case nil | 243 (condition-case nil |
243 (up-list 1) | 244 (up-list 1) |
244 (error (goto-char key-point) | 245 (error (goto-char key-point) |
245 (throw 'search-again nil))) | 246 (throw 'search-again nil))) |
246 (setq end-point (point)) | 247 (setq end-point (point)) |
247 | 248 |
248 ;; Ignore @string, @comment and @c entries or things | 249 ;; Ignore @string, @comment and @c entries or things |
249 ;; outside entries | 250 ;; outside entries |
250 (when (or (string= (downcase (match-string 2)) "string") | 251 (when (or (string= (downcase (match-string 2)) "string") |
251 (string= (downcase (match-string 2)) "comment") | 252 (string= (downcase (match-string 2)) "comment") |
252 (string= (downcase (match-string 2)) "c") | 253 (string= (downcase (match-string 2)) "c") |
253 (< (point) key-point)) ; this means match not in {} | 254 (< (point) key-point)) ; this means match not in {} |
254 (goto-char key-point) | 255 (goto-char key-point) |
255 (throw 'search-again nil)) | 256 (throw 'search-again nil)) |
256 | 257 |
257 ;; Well, we have got a match | 258 ;; Well, we have got a match |
258 (setq entry (concat | 259 ;;(setq entry (concat |
259 (buffer-substring start-point (point)) "\n")) | 260 ;; (buffer-substring start-point (point)) "\n")) |
260 | 261 (setq entry (buffer-substring start-point (point))) |
261 ;; Check if other regexp match as well | 262 |
262 (setq re-list rest-re) | 263 ;; Check if other regexp match as well |
263 (while re-list | 264 (setq re-list rest-re) |
264 (unless (string-match (car re-list) entry) | 265 (while re-list |
265 ;; nope - move on | 266 (unless (string-match (car re-list) entry) |
266 (throw 'search-again nil)) | 267 ;; nope - move on |
267 (pop re-list)) | 268 (throw 'search-again nil)) |
268 | 269 (pop re-list)) |
269 (setq alist (reftex-parse-bibtex-entry | 270 |
270 nil start-point end-point)) | 271 (setq alist (reftex-parse-bibtex-entry |
271 (push (cons "&entry" entry) alist) | 272 nil start-point end-point)) |
272 | 273 (push (cons "&entry" entry) alist) |
273 ;; check for crossref entries | 274 |
274 (if (assoc "crossref" alist) | 275 ;; check for crossref entries |
275 (setq alist | 276 (if (assoc "crossref" alist) |
276 (append | 277 (setq alist |
277 alist (reftex-get-crossref-alist alist)))) | 278 (append |
278 | 279 alist (reftex-get-crossref-alist alist)))) |
279 ;; format the entry | 280 |
280 (push (cons "&formatted" (reftex-format-bib-entry alist)) | 281 ;; format the entry |
281 alist) | 282 (push (cons "&formatted" (reftex-format-bib-entry alist)) |
282 | 283 alist) |
283 ;; make key the first element | 284 |
284 (push (reftex-get-bib-field "&key" alist) alist) | 285 ;; make key the first element |
285 | 286 (push (reftex-get-bib-field "&key" alist) alist) |
286 ;; add it to the list | 287 |
287 (push alist found-list))))) | 288 ;; add it to the list |
288 (reftex-kill-temporary-buffers)))) | 289 (push alist found-list))))) |
290 (reftex-kill-temporary-buffers)))) | |
289 (setq found-list (nreverse found-list)) | 291 (setq found-list (nreverse found-list)) |
290 | 292 |
291 ;; Sorting | 293 ;; Sorting |
292 (cond | 294 (cond |
293 ((eq 'author reftex-sort-bibtex-matches) | 295 ((eq 'author reftex-sort-bibtex-matches) |
308 (stringp (car al2))) | 310 (stringp (car al2))) |
309 (string< (car al1) (car al2)) | 311 (string< (car al1) (car al2)) |
310 (not (stringp (car al1)))))) | 312 (not (stringp (car al1)))))) |
311 | 313 |
312 (defun reftex-bib-sort-year (e1 e2) | 314 (defun reftex-bib-sort-year (e1 e2) |
313 (< (string-to-int (cdr (assoc "year" e1))) | 315 (< (string-to-number (or (cdr (assoc "year" e1)) "0")) |
314 (string-to-int (cdr (assoc "year" e2))))) | 316 (string-to-number (or (cdr (assoc "year" e2)) "0")))) |
315 | 317 |
316 (defun reftex-bib-sort-year-reverse (e1 e2) | 318 (defun reftex-bib-sort-year-reverse (e1 e2) |
317 (> (string-to-int (or (cdr (assoc "year" e1)) "0")) | 319 (> (string-to-number (or (cdr (assoc "year" e1)) "0")) |
318 (string-to-int (or (cdr (assoc "year" e2)) "0")))) | 320 (string-to-number (or (cdr (assoc "year" e2)) "0")))) |
319 | 321 |
320 (defun reftex-get-crossref-alist (entry) | 322 (defun reftex-get-crossref-alist (entry) |
321 ;; return the alist from a crossref entry | 323 ;; return the alist from a crossref entry |
322 (let ((crkey (cdr (assoc "crossref" entry))) | 324 (let ((crkey (cdr (assoc "crossref" entry))) |
323 start) | 325 start) |
343 | 345 |
344 (let* (start end buf entries re re-list file default) | 346 (let* (start end buf entries re re-list file default) |
345 (unless files | 347 (unless files |
346 (error "Need file name to find thebibliography environment")) | 348 (error "Need file name to find thebibliography environment")) |
347 (while (setq file (pop files)) | 349 (while (setq file (pop files)) |
348 (setq buf (reftex-get-file-buffer-force | 350 (setq buf (reftex-get-file-buffer-force |
349 file (not reftex-keep-temporary-buffers))) | 351 file (not reftex-keep-temporary-buffers))) |
350 (unless buf | 352 (unless buf |
351 (error "No such file %s" file)) | 353 (error "No such file %s" file)) |
352 (message "Scanning thebibliography environment in %s" file) | 354 (message "Scanning thebibliography environment in %s" file) |
353 | 355 |
354 (save-excursion | 356 (save-excursion |
355 (set-buffer buf) | 357 (set-buffer buf) |
356 (save-restriction | 358 (save-restriction |
357 (widen) | 359 (widen) |
358 (goto-char (point-min)) | 360 (goto-char (point-min)) |
359 (while (re-search-forward | 361 (while (re-search-forward |
360 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\begin{thebibliography}" nil t) | 362 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\begin{thebibliography}" nil t) |
361 (beginning-of-line 2) | 363 (beginning-of-line 2) |
362 (setq start (point)) | 364 (setq start (point)) |
363 (if (re-search-forward | 365 (if (re-search-forward |
364 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\end{thebibliography}" nil t) | 366 "\\(\\`\\|[\n\r]\\)[ \t]*\\\\end{thebibliography}" nil t) |
365 (progn | 367 (progn |
366 (beginning-of-line 1) | 368 (beginning-of-line 1) |
367 (setq end (point)))) | 369 (setq end (point)))) |
368 (when (and start end) | 370 (when (and start end) |
369 (setq entries | 371 (setq entries |
370 (append entries | 372 (append entries |
371 (mapcar 'reftex-parse-bibitem | 373 (mapcar 'reftex-parse-bibitem |
372 (delete "" | 374 (delete "" |
373 (split-string | 375 (split-string |
374 (buffer-substring-no-properties start end) | 376 (buffer-substring-no-properties start end) |
375 "[ \t\n\r]*\\\\bibitem\\(\\[[^]]*]\\)*")))))) | 377 "[ \t\n\r]*\\\\bibitem\\(\\[[^]]*]\\)*")))))) |
376 (goto-char end))))) | 378 (goto-char end))))) |
377 (unless entries | 379 (unless entries |
378 (error "No bibitems found")) | 380 (error "No bibitems found")) |
379 | 381 |
380 ;; Read a regexp, completing on known citation keys. | 382 ;; Read a regexp, completing on known citation keys. |
381 (setq default (regexp-quote (reftex-get-bibkey-default))) | 383 (setq default (regexp-quote (reftex-get-bibkey-default))) |
382 (setq re-list | 384 (setq re-list |
383 (split-string | 385 (split-string |
384 (completing-read | 386 (completing-read |
385 (concat | 387 (concat |
386 "Regex { && Regex...}: " | 388 "Regex { && Regex...}: " |
387 "[" default "]: ") | 389 "[" default "]: ") |
388 (if reftex-mode | 390 (if reftex-mode |
389 (if (fboundp 'LaTeX-bibitem-list) | 391 (if (fboundp 'LaTeX-bibitem-list) |
390 (LaTeX-bibitem-list) | 392 (LaTeX-bibitem-list) |
391 (cdr (assoc 'bibview-cache | 393 (cdr (assoc 'bibview-cache |
392 (symbol-value reftex-docstruct-symbol)))) | 394 (symbol-value reftex-docstruct-symbol)))) |
393 nil) | 395 nil) |
394 nil nil nil 'reftex-cite-regexp-hist) | 396 nil nil nil 'reftex-cite-regexp-hist) |
395 "[ \t]*&&[ \t]*")) | 397 "[ \t]*&&[ \t]*")) |
396 | 398 |
397 (if (or (null re-list ) (equal re-list '(""))) | 399 (if (or (null re-list ) (equal re-list '(""))) |
398 (setq re-list (list default))) | 400 (setq re-list (list default))) |
399 | 401 |
400 (if (string-match "\\`[ \t]*\\'" (car re-list)) | 402 (if (string-match "\\`[ \t]*\\'" (car re-list)) |
401 (error "Empty regular expression")) | 403 (error "Empty regular expression")) |
402 | 404 |
403 (while (and (setq re (pop re-list)) entries) | 405 (while (and (setq re (pop re-list)) entries) |
404 (setq entries | 406 (setq entries |
405 (delq nil (mapcar | 407 (delq nil (mapcar |
406 (lambda (x) | 408 (lambda (x) |
407 (if (string-match re (cdr (assoc "&entry" x))) | 409 (if (string-match re (cdr (assoc "&entry" x))) |
408 x nil)) | 410 x nil)) |
409 entries)))) | 411 entries)))) |
410 (setq entries | 412 (setq entries |
411 (mapcar | 413 (mapcar |
412 (lambda (x) | 414 (lambda (x) |
413 (push (cons "&formatted" (reftex-format-bibitem x)) x) | 415 (push (cons "&formatted" (reftex-format-bibitem x)) x) |
414 (push (reftex-get-bib-field "&key" x) x) | 416 (push (reftex-get-bib-field "&key" x) x) |
415 x) | 417 x) |
416 entries)) | 418 entries)) |
417 | 419 |
418 entries)) | 420 entries)) |
419 | 421 |
420 (defun reftex-get-bibkey-default () | 422 (defun reftex-get-bibkey-default () |
421 ;; Return the word before the cursor. If the cursor is in a | 423 ;; Return the word before the cursor. If the cursor is in a |
422 ;; citation macro, return the word before the macro. | 424 ;; citation macro, return the word before the macro. |
423 (let* ((macro (reftex-what-macro 1))) | 425 (let* ((macro (reftex-what-macro 1))) |
424 (save-excursion | 426 (save-excursion |
425 (if (and macro (string-match "cite" (car macro))) | 427 (if (and macro (string-match "cite" (car macro))) |
426 (goto-char (cdr macro))) | 428 (goto-char (cdr macro))) |
427 (skip-chars-backward "^a-zA-Z0-9") | 429 (skip-chars-backward "^a-zA-Z0-9") |
428 (reftex-this-word)))) | 430 (reftex-this-word)))) |
429 | 431 |
430 ;; Parse and format individual entries | 432 ;; Parse and format individual entries |
431 | 433 |
450 (save-restriction | 452 (save-restriction |
451 (if entry | 453 (if entry |
452 (progn | 454 (progn |
453 (set-buffer (get-buffer-create " *RefTeX-scratch*")) | 455 (set-buffer (get-buffer-create " *RefTeX-scratch*")) |
454 (fundamental-mode) | 456 (fundamental-mode) |
455 (set-syntax-table reftex-syntax-table-for-bib) | 457 (set-syntax-table reftex-syntax-table-for-bib) |
456 (erase-buffer) | 458 (erase-buffer) |
457 (insert entry)) | 459 (insert entry)) |
458 (widen) | 460 (widen) |
459 (narrow-to-region from to)) | 461 (narrow-to-region from to)) |
460 (goto-char (point-min)) | 462 (goto-char (point-min)) |
497 | 499 |
498 (defun reftex-get-bib-field (fieldname entry &optional format) | 500 (defun reftex-get-bib-field (fieldname entry &optional format) |
499 ;; Extract the field FIELDNAME from an ENTRY | 501 ;; Extract the field FIELDNAME from an ENTRY |
500 (let ((cell (assoc fieldname entry))) | 502 (let ((cell (assoc fieldname entry))) |
501 (if cell | 503 (if cell |
502 (if format | 504 (if format |
503 (format format (cdr cell)) | 505 (format format (cdr cell)) |
504 (cdr cell)) | 506 (cdr cell)) |
505 ""))) | 507 ""))) |
506 | 508 |
507 (defun reftex-format-bib-entry (entry) | 509 (defun reftex-format-bib-entry (entry) |
508 ;; Format a BibTeX ENTRY so that it is nice to look at | 510 ;; Format a BibTeX ENTRY so that it is nice to look at |
509 (let* | 511 (let* |
534 (reftex-get-bib-field "booktitle" entry "in: %s")) | 536 (reftex-get-bib-field "booktitle" entry "in: %s")) |
535 (t "")))) | 537 (t "")))) |
536 (setq authors (reftex-truncate authors 30 t t)) | 538 (setq authors (reftex-truncate authors 30 t t)) |
537 (when (reftex-use-fonts) | 539 (when (reftex-use-fonts) |
538 (put-text-property 0 (length key) 'face | 540 (put-text-property 0 (length key) 'face |
539 (reftex-verified-face reftex-label-face | 541 (reftex-verified-face reftex-label-face |
540 'font-lock-constant-face | 542 'font-lock-constant-face |
541 'font-lock-reference-face) | 543 'font-lock-reference-face) |
542 key) | 544 key) |
543 (put-text-property 0 (length authors) 'face reftex-bib-author-face | 545 (put-text-property 0 (length authors) 'face reftex-bib-author-face |
544 authors) | 546 authors) |
545 (put-text-property 0 (length year) 'face reftex-bib-year-face | 547 (put-text-property 0 (length year) 'face reftex-bib-year-face |
546 year) | 548 year) |
553 (defun reftex-parse-bibitem (item) | 555 (defun reftex-parse-bibitem (item) |
554 ;; Parse a \bibitem entry | 556 ;; Parse a \bibitem entry |
555 (let ((key "") (text "")) | 557 (let ((key "") (text "")) |
556 (when (string-match "\\`{\\([^}]+\\)}\\([^\000]*\\)" item) | 558 (when (string-match "\\`{\\([^}]+\\)}\\([^\000]*\\)" item) |
557 (setq key (match-string 1 item) | 559 (setq key (match-string 1 item) |
558 text (match-string 2 item))) | 560 text (match-string 2 item))) |
559 ;; Clean up the text a little bit | 561 ;; Clean up the text a little bit |
560 (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text) | 562 (while (string-match "[\n\r\t]\\|[ \t][ \t]+" text) |
561 (setq text (replace-match " " nil t text))) | 563 (setq text (replace-match " " nil t text))) |
562 (if (string-match "\\`[ \t]+" text) | 564 (if (string-match "\\`[ \t]+" text) |
563 (setq text (replace-match "" nil t text))) | 565 (setq text (replace-match "" nil t text))) |
564 (list | 566 (list |
565 (cons "&key" key) | 567 (cons "&key" key) |
566 (cons "&text" text) | 568 (cons "&text" text) |
567 (cons "&entry" (concat key " " text))))) | 569 (cons "&entry" (concat key " " text))))) |
568 | 570 |
569 (defun reftex-format-bibitem (item) | 571 (defun reftex-format-bibitem (item) |
570 ;; Format a \bibitem entry so that it is (relatively) nice to look at. | 572 ;; Format a \bibitem entry so that it is (relatively) nice to look at. |
571 (let ((text (reftex-get-bib-field "&text" item)) | 573 (let ((text (reftex-get-bib-field "&text" item)) |
572 (key (reftex-get-bib-field "&key" item)) | 574 (key (reftex-get-bib-field "&key" item)) |
573 (lines nil)) | 575 (lines nil)) |
574 | 576 |
575 ;; Wrap the text into several lines. | 577 ;; Wrap the text into several lines. |
576 (while (and (> (length text) 70) | 578 (while (and (> (length text) 70) |
577 (string-match " " (substring text 60))) | 579 (string-match " " (substring text 60))) |
578 (push (substring text 0 (+ 60 (match-beginning 0))) lines) | 580 (push (substring text 0 (+ 60 (match-beginning 0))) lines) |
579 (setq text (substring text (+ 61 (match-beginning 0))))) | 581 (setq text (substring text (+ 61 (match-beginning 0))))) |
580 (push text lines) | 582 (push text lines) |
581 (setq text (mapconcat 'identity (nreverse lines) "\n ")) | 583 (setq text (mapconcat 'identity (nreverse lines) "\n ")) |
582 | 584 |
583 (when (reftex-use-fonts) | 585 (when (reftex-use-fonts) |
584 (put-text-property 0 (length text) 'face reftex-bib-author-face text)) | 586 (put-text-property 0 (length text) 'face reftex-bib-author-face text)) |
594 matching entries for selection. The selected entry is formatted according | 596 matching entries for selection. The selected entry is formatted according |
595 to `reftex-cite-format' and inserted into the buffer. | 597 to `reftex-cite-format' and inserted into the buffer. |
596 | 598 |
597 If NO-INSERT is non-nil, nothing is inserted, only the selected key returned. | 599 If NO-INSERT is non-nil, nothing is inserted, only the selected key returned. |
598 | 600 |
599 FORAT-KEY can be used to pre-select a citation format. | 601 FORMAT-KEY can be used to pre-select a citation format. |
600 | 602 |
601 When called with one or two `C-u' prefixes, first rescans the document. | 603 When called with a `C-u' prefix, prompt for optional arguments in |
602 When called with a numeric prefix, make that many citations. When | 604 cite macros. When called with a numeric prefix, make that many |
603 called with point inside the braces of a `\\cite' command, it will | 605 citations. When called with point inside the braces of a `\\cite' |
604 add another key, ignoring the value of `reftex-cite-format'. | 606 command, it will add another key, ignoring the value of |
607 `reftex-cite-format'. | |
605 | 608 |
606 The regular expression uses an expanded syntax: && is interpreted as `and'. | 609 The regular expression uses an expanded syntax: && is interpreted as `and'. |
607 Thus, `aaaa&&bbb' matches entries which contain both `aaaa' and `bbb'. | 610 Thus, `aaaa&&bbb' matches entries which contain both `aaaa' and `bbb'. |
608 While entering the regexp, completion on knows citation keys is possible. | 611 While entering the regexp, completion on knows citation keys is possible. |
609 `=' is a good regular expression to match all entries in all files." | 612 `=' is a good regular expression to match all entries in all files." |
615 | 618 |
616 ;; This function may also be called outside reftex-mode. | 619 ;; This function may also be called outside reftex-mode. |
617 ;; Thus look for the scanning info only if in reftex-mode. | 620 ;; Thus look for the scanning info only if in reftex-mode. |
618 | 621 |
619 (when reftex-mode | 622 (when reftex-mode |
620 (reftex-access-scan-info current-prefix-arg)) | 623 (reftex-access-scan-info nil)) |
621 | 624 |
622 ;; Call reftex-do-citation, but protected | 625 ;; Call reftex-do-citation, but protected |
623 (unwind-protect | 626 (unwind-protect |
624 (reftex-do-citation current-prefix-arg no-insert format-key) | 627 (reftex-do-citation current-prefix-arg no-insert format-key) |
625 (reftex-kill-temporary-buffers))) | 628 (reftex-kill-temporary-buffers))) |
626 | 629 |
627 (defun reftex-do-citation (&optional arg no-insert format-key) | 630 (defun reftex-do-citation (&optional arg no-insert format-key) |
628 ;; This really does the work of reftex-citation. | 631 ;; This really does the work of reftex-citation. |
629 | 632 |
630 (let* ((format (reftex-figure-out-cite-format arg no-insert format-key)) | 633 (let* ((format (reftex-figure-out-cite-format arg no-insert format-key)) |
631 (docstruct-symbol reftex-docstruct-symbol) | 634 (docstruct-symbol reftex-docstruct-symbol) |
632 (selected-entries (reftex-offer-bib-menu)) | 635 (selected-entries (reftex-offer-bib-menu)) |
633 (insert-entries selected-entries) | 636 (insert-entries selected-entries) |
634 entry string cite-view) | 637 entry string cite-view) |
635 | 638 |
639 (when (stringp selected-entries) | |
640 (error selected-entries)) | |
636 (unless selected-entries (error "Quit")) | 641 (unless selected-entries (error "Quit")) |
637 | 642 |
638 (if (stringp selected-entries) | 643 (if (stringp selected-entries) |
639 ;; Nonexistent entry | 644 ;; Nonexistent entry |
640 (setq selected-entries nil | 645 (setq selected-entries nil |
641 insert-entries (list (list selected-entries | 646 insert-entries (list (list selected-entries |
642 (cons "&key" selected-entries)))) | 647 (cons "&key" selected-entries)))) |
643 ;; It makes sense to compute the cite-view strings. | 648 ;; It makes sense to compute the cite-view strings. |
644 (setq cite-view t)) | 649 (setq cite-view t)) |
645 | 650 |
646 (when (eq (car selected-entries) 'concat) | 651 (when (eq (car selected-entries) 'concat) |
647 ;; All keys go into a single command - we need to trick a little | 652 ;; All keys go into a single command - we need to trick a little |
653 ;; FIXME: Unfortunately, this meens that commenting does not work right. | |
648 (pop selected-entries) | 654 (pop selected-entries) |
649 (let ((concat-keys (mapconcat 'car selected-entries ","))) | 655 (let ((concat-keys (mapconcat 'car selected-entries ","))) |
650 (setq insert-entries | 656 (setq insert-entries |
651 (list (list concat-keys (cons "&key" concat-keys)))))) | 657 (list (list concat-keys (cons "&key" concat-keys)))))) |
652 | 658 |
653 (unless no-insert | 659 (unless no-insert |
654 | 660 |
655 ;; We shall insert this into the buffer... | 661 ;; We shall insert this into the buffer... |
656 (message "Formatting...") | 662 (message "Formatting...") |
657 | 663 |
658 (while (setq entry (pop insert-entries)) | 664 (while (setq entry (pop insert-entries)) |
659 ;; Format the citation and insert it | 665 ;; Format the citation and insert it |
660 (setq string (if reftex-format-cite-function | 666 (setq string (if reftex-format-cite-function |
661 (funcall reftex-format-cite-function | 667 (funcall reftex-format-cite-function |
662 (reftex-get-bib-field "&key" entry) | 668 (reftex-get-bib-field "&key" entry) |
663 format) | 669 format) |
664 (reftex-format-citation entry format))) | 670 (reftex-format-citation entry format))) |
665 (insert string)) | 671 (when (or (eq reftex-cite-prompt-optional-args t) |
672 (and reftex-cite-prompt-optional-args | |
673 (equal arg '(4)))) | |
674 (let ((start 0) (nth 0) value) | |
675 (while (setq start (string-match "\\[\\]" string start)) | |
676 (setq value (read-string (format "Optional argument %d: " | |
677 (setq nth (1+ nth))))) | |
678 (setq string (replace-match (concat "[" value "]") t t string)) | |
679 (setq start (1+ start))))) | |
680 ;; Should we cleanup empty optional arguments? | |
681 ;; if the first is empty, it can be removed. If the second is empty, | |
682 ;; it has to go. If there is only a single arg and empty, it can go | |
683 ;; as well. | |
684 (when reftex-cite-cleanup-optional-args | |
685 (cond | |
686 ((string-match "\\([a-zA-Z0-9]\\)\\[\\]{" string) | |
687 (setq string (replace-match "\\1{" nil nil string))) | |
688 ((string-match "\\[\\]\\(\\[[a-zA-Z0-9., ]+\\]\\)" string) | |
689 (setq string (replace-match "\\1" nil nil string))) | |
690 ((string-match "\\[\\]\\[\\]" string) | |
691 (setq string (replace-match "" t t string))))) | |
692 (insert string)) | |
666 | 693 |
667 ;; Reposition cursor? | 694 ;; Reposition cursor? |
668 (when (string-match "\\?" string) | 695 (when (string-match "\\?" string) |
669 (search-backward "?") | 696 (search-backward "?") |
670 (delete-char 1)) | 697 (delete-char 1)) |
671 | 698 |
672 ;; Tell AUCTeX | 699 ;; Tell AUCTeX |
673 (when (and reftex-mode | 700 (when (and reftex-mode |
674 (fboundp 'LaTeX-add-bibitems) | 701 (fboundp 'LaTeX-add-bibitems) |
675 reftex-plug-into-AUCTeX) | 702 reftex-plug-into-AUCTeX) |
676 (apply 'LaTeX-add-bibitems (mapcar 'car selected-entries))) | 703 (apply 'LaTeX-add-bibitems (mapcar 'car selected-entries))) |
677 | 704 |
678 ;; Produce the cite-view strings | 705 ;; Produce the cite-view strings |
679 (when (and reftex-mode reftex-cache-cite-echo cite-view) | 706 (when (and reftex-mode reftex-cache-cite-echo cite-view) |
680 (mapcar (lambda (entry) | 707 (mapcar (lambda (entry) |
681 (reftex-make-cite-echo-string entry docstruct-symbol)) | 708 (reftex-make-cite-echo-string entry docstruct-symbol)) |
682 selected-entries)) | 709 selected-entries)) |
683 | 710 |
684 (message "")) | 711 (message "")) |
685 | 712 |
686 (set-marker reftex-select-return-marker nil) | 713 (set-marker reftex-select-return-marker nil) |
687 (reftex-kill-buffer "*RefTeX Select*") | 714 (reftex-kill-buffer "*RefTeX Select*") |
688 | 715 |
689 ;; Check if the prefix arg was numeric, and call recursively | 716 ;; Check if the prefix arg was numeric, and call recursively |
690 (when (integerp arg) | 717 (when (integerp arg) |
691 (if (> arg 1) | 718 (if (> arg 1) |
692 (progn | 719 (progn |
693 (skip-chars-backward "}") | 720 (skip-chars-backward "}") |
694 (decf arg) | 721 (decf arg) |
695 (reftex-do-citation arg)) | 722 (reftex-do-citation arg)) |
696 (forward-char 1))) | 723 (forward-char 1))) |
697 | 724 |
698 ;; Return the citation key | 725 ;; Return the citation key |
699 (car (car selected-entries)))) | 726 (car (car selected-entries)))) |
700 | 727 |
701 (defun reftex-figure-out-cite-format (arg &optional no-insert format-key) | 728 (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 | 729 ;; 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. | 730 ;; in order to only add another reference in the same cite command. |
704 (let ((macro (car (reftex-what-macro 1))) | 731 (let ((macro (car (reftex-what-macro 1))) |
705 (cite-format-value (reftex-get-cite-format)) | 732 (cite-format-value (reftex-get-cite-format)) |
706 key format) | 733 key format) |
707 (cond | 734 (cond |
708 (no-insert | 735 (no-insert |
709 ;; Format does not really matter because nothing will be inserted. | 736 ;; Format does not really matter because nothing will be inserted. |
710 (setq format "%l")) | 737 (setq format "%l")) |
711 | 738 |
712 ((and (stringp macro) | 739 ((and (stringp macro) |
713 (string-match "\\`\\\\cite\\|cite\\'" macro)) | 740 (string-match "\\`\\\\cite\\|cite\\'" macro)) |
714 ;; We are already inside a cite macro | 741 ;; We are already inside a cite macro |
715 (if (or (not arg) (not (listp arg))) | 742 (if (or (not arg) (not (listp arg))) |
716 (setq format | 743 (setq format |
717 (concat | 744 (concat |
718 (if (member (preceding-char) '(?\{ ?,)) "" ",") | 745 (if (member (preceding-char) '(?\{ ?,)) "" ",") |
719 "%l" | 746 "%l" |
720 (if (member (following-char) '(?\} ?,)) "" ","))) | 747 (if (member (following-char) '(?\} ?,)) "" ","))) |
721 (setq format "%l"))) | 748 (setq format "%l"))) |
722 (t | 749 (t |
723 ;; Figure out the correct format | 750 ;; Figure out the correct format |
724 (setq format | 751 (setq format |
725 (if (and (symbolp cite-format-value) | 752 (if (and (symbolp cite-format-value) |
726 (assq cite-format-value reftex-cite-format-builtin)) | 753 (assq cite-format-value reftex-cite-format-builtin)) |
727 (nth 2 (assq cite-format-value reftex-cite-format-builtin)) | 754 (nth 2 (assq cite-format-value reftex-cite-format-builtin)) |
728 cite-format-value)) | 755 cite-format-value)) |
729 (when (listp format) | 756 (when (listp format) |
730 (setq key | 757 (setq key |
731 (or format-key | 758 (or format-key |
732 (reftex-select-with-char | 759 (reftex-select-with-char |
733 "" (concat "SELECT A CITATION FORMAT\n\n" | 760 "" (concat "SELECT A CITATION FORMAT\n\n" |
734 (mapconcat | 761 (mapconcat |
735 (lambda (x) | 762 (lambda (x) |
736 (format "[%c] %s %s" (car x) | 763 (format "[%c] %s %s" (car x) |
737 (if (> (car x) 31) " " "") | 764 (if (> (car x) 31) " " "") |
738 (cdr x))) | 765 (cdr x))) |
739 format "\n"))))) | 766 format "\n"))))) |
740 (if (assq key format) | 767 (if (assq key format) |
741 (setq format (cdr (assq key format))) | 768 (setq format (cdr (assq key format))) |
742 (error "No citation format associated with key `%c'" key))))) | 769 (error "No citation format associated with key `%c'" key))))) |
743 format)) | 770 format)) |
744 | 771 |
745 (defun reftex-citep () | 772 (defun reftex-citep () |
746 "Call `reftex-citation' with a format selector `?p'." | 773 "Call `reftex-citation' with a format selector `?p'." |
747 (interactive) | 774 (interactive) |
755 (defvar reftex-select-bib-map) | 782 (defvar reftex-select-bib-map) |
756 (defun reftex-offer-bib-menu () | 783 (defun reftex-offer-bib-menu () |
757 ;; Offer bib menu and return list of selected items | 784 ;; Offer bib menu and return list of selected items |
758 | 785 |
759 (let ((bibtype (reftex-bib-or-thebib)) | 786 (let ((bibtype (reftex-bib-or-thebib)) |
760 found-list rtn key data selected-entries) | 787 found-list rtn key data selected-entries) |
761 (while | 788 (while |
762 (not | 789 (not |
763 (catch 'done | 790 (catch 'done |
764 ;; Scan bibtex files | 791 ;; Scan bibtex files |
765 (setq found-list | 792 (setq found-list |
766 (cond | 793 (cond |
767 ((eq bibtype 'bib) | 794 ((eq bibtype 'bib) |
768 ; ((assq 'bib (symbol-value reftex-docstruct-symbol)) | 795 ; ((assq 'bib (symbol-value reftex-docstruct-symbol)) |
769 ;; using BibTeX database files. | 796 ;; using BibTeX database files. |
770 (reftex-extract-bib-entries (reftex-get-bibfile-list))) | 797 (reftex-extract-bib-entries (reftex-get-bibfile-list))) |
771 ((eq bibtype 'thebib) | 798 ((eq bibtype 'thebib) |
772 ; ((assq 'thebib (symbol-value reftex-docstruct-symbol)) | 799 ; ((assq 'thebib (symbol-value reftex-docstruct-symbol)) |
773 ;; using thebibliography environment. | 800 ;; using thebibliography environment. |
774 (reftex-extract-bib-entries-from-thebibliography | 801 (reftex-extract-bib-entries-from-thebibliography |
775 (reftex-uniquify | 802 (reftex-uniquify |
776 (mapcar 'cdr | 803 (mapcar 'cdr |
777 (reftex-all-assq | 804 (reftex-all-assq |
778 'thebib (symbol-value reftex-docstruct-symbol)))))) | 805 'thebib (symbol-value reftex-docstruct-symbol)))))) |
779 (reftex-default-bibliography | 806 (reftex-default-bibliography |
780 (message "Using default bibliography") | 807 (message "Using default bibliography") |
781 (reftex-extract-bib-entries (reftex-default-bibliography))) | 808 (reftex-extract-bib-entries (reftex-default-bibliography))) |
782 (t (error "No valid bibliography in this document, and no default available")))) | 809 (t (error "No valid bibliography in this document, and no default available")))) |
783 | 810 |
784 (unless found-list | 811 (unless found-list |
785 (error "Sorry, no matches found")) | 812 (error "Sorry, no matches found")) |
786 | 813 |
787 ;; Remember where we came from | 814 ;; Remember where we came from |
788 (setq reftex-call-back-to-this-buffer (current-buffer)) | 815 (setq reftex-call-back-to-this-buffer (current-buffer)) |
789 (set-marker reftex-select-return-marker (point)) | 816 (set-marker reftex-select-return-marker (point)) |
790 | 817 |
791 ;; Offer selection | 818 ;; Offer selection |
792 (save-window-excursion | 819 (save-window-excursion |
793 (delete-other-windows) | 820 (delete-other-windows) |
794 (let ((default-major-mode 'reftex-select-bib-mode)) | 821 (let ((default-major-mode 'reftex-select-bib-mode)) |
795 (reftex-kill-buffer "*RefTeX Select*") | 822 (reftex-kill-buffer "*RefTeX Select*") |
796 (switch-to-buffer-other-window "*RefTeX Select*") | 823 (switch-to-buffer-other-window "*RefTeX Select*") |
797 (unless (eq major-mode 'reftex-select-bib-mode) | 824 (unless (eq major-mode 'reftex-select-bib-mode) |
798 (reftex-select-bib-mode)) | 825 (reftex-select-bib-mode)) |
799 (let ((buffer-read-only nil)) | 826 (let ((buffer-read-only nil)) |
800 (erase-buffer) | 827 (erase-buffer) |
801 (reftex-insert-bib-matches found-list))) | 828 (reftex-insert-bib-matches found-list))) |
802 (setq buffer-read-only t) | 829 (setq buffer-read-only t) |
803 (if (= 0 (buffer-size)) | 830 (if (= 0 (buffer-size)) |
804 (error "No matches found")) | 831 (error "No matches found")) |
805 (setq truncate-lines t) | 832 (setq truncate-lines t) |
806 (goto-char 1) | 833 (goto-char 1) |
807 (while t | 834 (while t |
808 (setq rtn | 835 (setq rtn |
809 (reftex-select-item | 836 (reftex-select-item |
810 reftex-citation-prompt | 837 reftex-citation-prompt |
811 reftex-citation-help | 838 reftex-citation-help |
812 reftex-select-bib-map | 839 reftex-select-bib-map |
813 nil | 840 nil |
814 'reftex-bibtex-selection-callback nil)) | 841 'reftex-bibtex-selection-callback nil)) |
815 (setq key (car rtn) | 842 (setq key (car rtn) |
816 data (nth 1 rtn)) | 843 data (nth 1 rtn)) |
817 (unless key (throw 'done t)) | 844 (unless key (throw 'done t)) |
818 (cond | 845 (cond |
819 ((eq key ?g) | 846 ((eq key ?g) |
820 ;; Start over | 847 ;; Start over |
821 (throw 'done nil)) | 848 (throw 'done nil)) |
822 ((eq key ?r) | 849 ((eq key ?r) |
823 ;; Restrict with new regular expression | 850 ;; Restrict with new regular expression |
824 (setq found-list (reftex-restrict-bib-matches found-list)) | 851 (setq found-list (reftex-restrict-bib-matches found-list)) |
825 (let ((buffer-read-only nil)) | 852 (let ((buffer-read-only nil)) |
826 (erase-buffer) | 853 (erase-buffer) |
827 (reftex-insert-bib-matches found-list)) | 854 (reftex-insert-bib-matches found-list)) |
828 (goto-char 1)) | 855 (goto-char 1)) |
829 ((eq key ?A) | 856 ((eq key ?A) |
830 ;; Take all (marked) | 857 ;; Take all (marked) |
831 (setq selected-entries | 858 (setq selected-entries |
832 (if reftex-select-marked | 859 (if reftex-select-marked |
833 (mapcar 'car (nreverse reftex-select-marked)) | 860 (mapcar 'car (nreverse reftex-select-marked)) |
834 found-list)) | 861 found-list)) |
835 (throw 'done t)) | 862 (throw 'done t)) |
836 ((eq key ?a) | 863 ((eq key ?a) |
837 ;; Take all (marked), and push the symbol 'concat | 864 ;; Take all (marked), and push the symbol 'concat |
838 (setq selected-entries | 865 (setq selected-entries |
839 (cons 'concat | 866 (cons 'concat |
840 (if reftex-select-marked | 867 (if reftex-select-marked |
841 (mapcar 'car (nreverse reftex-select-marked)) | 868 (mapcar 'car (nreverse reftex-select-marked)) |
842 found-list))) | 869 found-list))) |
843 (throw 'done t)) | 870 (throw 'done t)) |
844 ((or (eq key ?\C-m) | 871 ((eq key ?e) |
845 (eq key 'return)) | 872 ;; Take all (marked), and push the symbol 'concat |
846 ;; Take selected | 873 (reftex-extract-bib-file found-list reftex-select-marked) |
847 (setq selected-entries | 874 (setq selected-entries "BibTeX database file created") |
848 (if reftex-select-marked | 875 (throw 'done t)) |
849 (cons 'concat | 876 ((eq key ?E) |
850 (mapcar 'car (nreverse reftex-select-marked))) | 877 ;; Take all (marked), and push the symbol 'concat |
851 (if data (list data) nil))) | 878 (reftex-extract-bib-file found-list reftex-select-marked |
852 (throw 'done t)) | 879 'complement) |
853 ((stringp key) | 880 (setq selected-entries "BibTeX database file created") |
854 ;; Got this one with completion | 881 (throw 'done t)) |
855 (setq selected-entries key) | 882 ((or (eq key ?\C-m) |
856 (throw 'done t)) | 883 (eq key 'return)) |
857 (t | 884 ;; Take selected |
858 (ding)))))))) | 885 (setq selected-entries |
886 (if reftex-select-marked | |
887 (cons 'concat | |
888 (mapcar 'car (nreverse reftex-select-marked))) | |
889 (if data (list data) nil))) | |
890 (throw 'done t)) | |
891 ((stringp key) | |
892 ;; Got this one with completion | |
893 (setq selected-entries key) | |
894 (throw 'done t)) | |
895 (t | |
896 (ding)))))))) | |
859 selected-entries)) | 897 selected-entries)) |
860 | 898 |
861 (defun reftex-restrict-bib-matches (found-list) | 899 (defun reftex-restrict-bib-matches (found-list) |
862 ;; Limit FOUND-LIST with more regular expressions | 900 ;; Limit FOUND-LIST with more regular expressions |
863 (let ((re-list (split-string (read-string | 901 (let ((re-list (split-string (read-string |
864 "RegExp [ && RegExp...]: " | 902 "RegExp [ && RegExp...]: " |
865 nil 'reftex-cite-regexp-hist) | 903 nil 'reftex-cite-regexp-hist) |
866 "[ \t]*&&[ \t]*")) | 904 "[ \t]*&&[ \t]*")) |
867 (found-list-r found-list) | 905 (found-list-r found-list) |
868 re) | 906 re) |
869 (while (setq re (pop re-list)) | 907 (while (setq re (pop re-list)) |
870 (setq found-list-r | 908 (setq found-list-r |
871 (delq nil | 909 (delq nil |
872 (mapcar | 910 (mapcar |
873 (lambda (x) | 911 (lambda (x) |
874 (if (string-match | 912 (if (string-match |
875 re (cdr (assoc "&entry" x))) | 913 re (cdr (assoc "&entry" x))) |
876 x | 914 x |
877 nil)) | 915 nil)) |
878 found-list-r)))) | 916 found-list-r)))) |
879 (if found-list-r | 917 (if found-list-r |
880 found-list-r | 918 found-list-r |
881 (ding) | 919 (ding) |
882 found-list))) | 920 found-list))) |
921 | |
922 (defun reftex-extract-bib-file (all &optional marked complement) | |
923 ;; Limit FOUND-LIST with more regular expressions | |
924 (let ((file (read-file-name "File to create: "))) | |
925 (find-file-other-window file) | |
926 (if (> (buffer-size) 0) | |
927 (unless (yes-or-no-p | |
928 (format "Overwrite non-empty file %s? " file)) | |
929 (error "Abort"))) | |
930 (erase-buffer) | |
931 (setq all (delq nil | |
932 (mapcar | |
933 (lambda (x) | |
934 (if marked | |
935 (if (or (and (assoc x marked) (not complement)) | |
936 (and (not (assoc x marked)) complement)) | |
937 (cdr (assoc "&entry" x)) | |
938 nil) | |
939 (cdr (assoc "&entry" x)))) | |
940 all))) | |
941 (insert (mapconcat 'identity all "\n\n")) | |
942 (save-buffer) | |
943 (goto-char (point-min)))) | |
883 | 944 |
884 (defun reftex-insert-bib-matches (list) | 945 (defun reftex-insert-bib-matches (list) |
885 ;; Insert the bib matches and number them correctly | 946 ;; Insert the bib matches and number them correctly |
886 (let ((mouse-face | 947 (let ((mouse-face |
887 (if (memq reftex-highlight-selection '(mouse both)) | 948 (if (memq reftex-highlight-selection '(mouse both)) |
888 reftex-mouse-selected-face | 949 reftex-mouse-selected-face |
889 nil)) | 950 nil)) |
890 tmp len) | 951 tmp len) |
891 (mapcar | 952 (mapcar |
892 (lambda (x) | 953 (lambda (x) |
893 (setq tmp (cdr (assoc "&formatted" x)) | 954 (setq tmp (cdr (assoc "&formatted" x)) |
894 len (length tmp)) | 955 len (length tmp)) |
895 (put-text-property 0 len :data x tmp) | 956 (put-text-property 0 len :data x tmp) |
896 (put-text-property 0 (1- len) 'mouse-face mouse-face tmp) | 957 (put-text-property 0 (1- len) 'mouse-face mouse-face tmp) |
897 (insert tmp)) | 958 (insert tmp)) |
898 list)) | 959 list)) |
899 (run-hooks 'reftex-display-copied-context-hook)) | 960 (run-hooks 'reftex-display-copied-context-hook)) |
919 | 980 |
920 (unless (stringp format) (setq format "\\cite{%l}")) | 981 (unless (stringp format) (setq format "\\cite{%l}")) |
921 | 982 |
922 (if (and reftex-comment-citations | 983 (if (and reftex-comment-citations |
923 (string-match "%l" reftex-cite-comment-format)) | 984 (string-match "%l" reftex-cite-comment-format)) |
924 (error "reftex-cite-comment-format contains illegal %%l")) | 985 (error "reftex-cite-comment-format contains invalid %%l")) |
925 | 986 |
926 (while (string-match | 987 (while (string-match |
927 "\\(\\`\\|[^%]\\)\\(\\(%\\([0-9]*\\)\\([a-zA-Z]\\)\\)[.,;: ]*\\)" | 988 "\\(\\`\\|[^%]\\)\\(\\(%\\([0-9]*\\)\\([a-zA-Z]\\)\\)[.,;: ]*\\)" |
928 format) | 989 format) |
929 (let ((n (string-to-int (match-string 4 format))) | 990 (let ((n (string-to-number (match-string 4 format))) |
930 (l (string-to-char (match-string 5 format))) | 991 (l (string-to-char (match-string 5 format))) |
931 rpl b e) | 992 rpl b e) |
932 (save-match-data | 993 (save-match-data |
933 (setq rpl | 994 (setq rpl |
934 (cond | 995 (cond |
941 (reftex-get-bib-names "author" entry) | 1002 (reftex-get-bib-names "author" entry) |
942 (or n 2))) | 1003 (or n 2))) |
943 ((= l ?A) (car (reftex-get-bib-names "author" entry))) | 1004 ((= l ?A) (car (reftex-get-bib-names "author" entry))) |
944 ((= l ?b) (reftex-get-bib-field "booktitle" entry "in: %s")) | 1005 ((= l ?b) (reftex-get-bib-field "booktitle" entry "in: %s")) |
945 ((= l ?B) (reftex-abbreviate-title | 1006 ((= l ?B) (reftex-abbreviate-title |
946 (reftex-get-bib-field "booktitle" entry "in: %s"))) | 1007 (reftex-get-bib-field "booktitle" entry "in: %s"))) |
947 ((= l ?c) (reftex-get-bib-field "chapter" entry)) | 1008 ((= l ?c) (reftex-get-bib-field "chapter" entry)) |
948 ((= l ?d) (reftex-get-bib-field "edition" entry)) | 1009 ((= l ?d) (reftex-get-bib-field "edition" entry)) |
949 ((= l ?e) (reftex-format-names | 1010 ((= l ?e) (reftex-format-names |
950 (reftex-get-bib-names "editor" entry) | 1011 (reftex-get-bib-names "editor" entry) |
951 (or n 2))) | 1012 (or n 2))) |
964 ((= l ?s) (reftex-get-bib-field "school" entry)) | 1025 ((= l ?s) (reftex-get-bib-field "school" entry)) |
965 ((= l ?u) (reftex-get-bib-field "publisher" entry)) | 1026 ((= l ?u) (reftex-get-bib-field "publisher" entry)) |
966 ((= l ?r) (reftex-get-bib-field "address" entry)) | 1027 ((= l ?r) (reftex-get-bib-field "address" entry)) |
967 ((= l ?t) (reftex-get-bib-field "title" entry)) | 1028 ((= l ?t) (reftex-get-bib-field "title" entry)) |
968 ((= l ?T) (reftex-abbreviate-title | 1029 ((= l ?T) (reftex-abbreviate-title |
969 (reftex-get-bib-field "title" entry))) | 1030 (reftex-get-bib-field "title" entry))) |
970 ((= l ?v) (reftex-get-bib-field "volume" entry)) | 1031 ((= l ?v) (reftex-get-bib-field "volume" entry)) |
971 ((= l ?y) (reftex-get-bib-field "year" entry))))) | 1032 ((= l ?y) (reftex-get-bib-field "year" entry))))) |
972 | 1033 |
973 (if (string= rpl "") | 1034 (if (string= rpl "") |
974 (setq b (match-beginning 2) e (match-end 2)) | 1035 (setq b (match-beginning 2) e (match-end 2)) |
981 format) | 1042 format) |
982 | 1043 |
983 (defun reftex-make-cite-echo-string (entry docstruct-symbol) | 1044 (defun reftex-make-cite-echo-string (entry docstruct-symbol) |
984 ;; Format a bibtex entry for the echo area and cache the result. | 1045 ;; Format a bibtex entry for the echo area and cache the result. |
985 (let* ((key (reftex-get-bib-field "&key" entry)) | 1046 (let* ((key (reftex-get-bib-field "&key" entry)) |
986 (string | 1047 (string |
987 (let* ((reftex-cite-punctuation '(" " " & " " etal."))) | 1048 (let* ((reftex-cite-punctuation '(" " " & " " etal."))) |
988 (reftex-format-citation entry reftex-cite-view-format))) | 1049 (reftex-format-citation entry reftex-cite-view-format))) |
989 (cache (assq 'bibview-cache (symbol-value docstruct-symbol))) | 1050 (cache (assq 'bibview-cache (symbol-value docstruct-symbol))) |
990 (cache-entry (assoc key (cdr cache)))) | 1051 (cache-entry (assoc key (cdr cache)))) |
991 (unless cache | 1052 (unless cache |
992 ;; This docstruct has no cache - make one. | 1053 ;; This docstruct has no cache - make one. |
993 (set docstruct-symbol (cons (cons 'bibview-cache nil) | 1054 (set docstruct-symbol (cons (cons 'bibview-cache nil) |
994 (symbol-value docstruct-symbol)))) | 1055 (symbol-value docstruct-symbol)))) |
995 (when reftex-cache-cite-echo | 1056 (when reftex-cache-cite-echo |
996 (setq key (copy-sequence key)) | 1057 (setq key (copy-sequence key)) |
997 (set-text-properties 0 (length key) nil key) | 1058 (set-text-properties 0 (length key) nil key) |
998 (set-text-properties 0 (length string) nil string) | 1059 (set-text-properties 0 (length string) nil string) |
999 (if cache-entry | 1060 (if cache-entry |
1000 (unless (string= (cdr cache-entry) string) | 1061 (unless (string= (cdr cache-entry) string) |
1001 (setcdr cache-entry string) | 1062 (setcdr cache-entry string) |
1002 (put reftex-docstruct-symbol 'modified t)) | 1063 (put reftex-docstruct-symbol 'modified t)) |
1003 (push (cons key string) (cdr cache)) | 1064 (push (cons key string) (cdr cache)) |
1004 (put reftex-docstruct-symbol 'modified t))) | 1065 (put reftex-docstruct-symbol 'modified t))) |
1005 string)) | 1066 string)) |
1006 | 1067 |
1007 (defun reftex-bibtex-selection-callback (data ignore no-revisit) | 1068 (defun reftex-bibtex-selection-callback (data ignore no-revisit) |
1008 ;; Callback function to be called from the BibTeX selection, in | 1069 ;; Callback function to be called from the BibTeX selection, in |
1009 ;; order to display context. This function is relatively slow and not | 1070 ;; order to display context. This function is relatively slow and not |
1012 (key (reftex-get-bib-field "&key" data)) | 1073 (key (reftex-get-bib-field "&key" data)) |
1013 bibfile-list item bibtype) | 1074 bibfile-list item bibtype) |
1014 | 1075 |
1015 (catch 'exit | 1076 (catch 'exit |
1016 (save-excursion | 1077 (save-excursion |
1017 (set-buffer reftex-call-back-to-this-buffer) | 1078 (set-buffer reftex-call-back-to-this-buffer) |
1018 (setq bibtype (reftex-bib-or-thebib)) | 1079 (setq bibtype (reftex-bib-or-thebib)) |
1019 (cond | 1080 (cond |
1020 ((eq bibtype 'bib) | 1081 ((eq bibtype 'bib) |
1021 ; ((assq 'bib (symbol-value reftex-docstruct-symbol)) | 1082 ; ((assq 'bib (symbol-value reftex-docstruct-symbol)) |
1022 (setq bibfile-list (reftex-get-bibfile-list))) | 1083 (setq bibfile-list (reftex-get-bibfile-list))) |
1023 ((eq bibtype 'thebib) | 1084 ((eq bibtype 'thebib) |
1024 ; ((assq 'thebib (symbol-value reftex-docstruct-symbol)) | 1085 ; ((assq 'thebib (symbol-value reftex-docstruct-symbol)) |
1025 (setq bibfile-list | 1086 (setq bibfile-list |
1026 (reftex-uniquify | 1087 (reftex-uniquify |
1027 (mapcar 'cdr | 1088 (mapcar 'cdr |
1028 (reftex-all-assq | 1089 (reftex-all-assq |
1029 'thebib (symbol-value reftex-docstruct-symbol)))) | 1090 'thebib (symbol-value reftex-docstruct-symbol)))) |
1030 item t)) | 1091 item t)) |
1031 (reftex-default-bibliography | 1092 (reftex-default-bibliography |
1032 (setq bibfile-list (reftex-default-bibliography))) | 1093 (setq bibfile-list (reftex-default-bibliography))) |
1033 (t (ding) (throw 'exit nil)))) | 1094 (t (ding) (throw 'exit nil)))) |
1034 | 1095 |
1035 (when no-revisit | 1096 (when no-revisit |
1036 (setq bibfile-list (reftex-visited-files bibfile-list))) | 1097 (setq bibfile-list (reftex-visited-files bibfile-list))) |
1037 | 1098 |
1038 (condition-case nil | 1099 (condition-case nil |
1039 (reftex-pop-to-bibtex-entry | 1100 (reftex-pop-to-bibtex-entry |
1040 key bibfile-list (not reftex-keep-temporary-buffers) t item) | 1101 key bibfile-list (not reftex-keep-temporary-buffers) t item) |
1041 (error (ding)))) | 1102 (error (ding)))) |
1042 | 1103 |
1043 (select-window win))) | 1104 (select-window win))) |
1044 | 1105 |
1106 ;;; Global BibTeX file | |
1107 (defun reftex-all-used-citation-keys () | |
1108 (reftex-access-scan-info) | |
1109 (let ((files (reftex-all-document-files)) file keys kk k) | |
1110 (save-excursion | |
1111 (while (setq file (pop files)) | |
1112 (set-buffer (reftex-get-file-buffer-force file 'mark)) | |
1113 (save-excursion | |
1114 (save-restriction | |
1115 (widen) | |
1116 (goto-char (point-min)) | |
1117 (while (re-search-forward "^[^%\n\r]*\\\\\\(bibentry\\|[a-zA-Z]*cite[a-zA-Z]*\\)\\(\\[[^\\]]*\\]\\)?{\\([^}]+\\)}" nil t) | |
1118 (setq kk (match-string-no-properties 3)) | |
1119 (while (string-match "%.*\n?" kk) | |
1120 (setq kk (replace-match "" t t kk))) | |
1121 (setq kk (split-string kk "[, \t\r\n]+")) | |
1122 (while (setq k (pop kk)) | |
1123 (or (member k keys) | |
1124 (setq keys (cons k keys))))))))) | |
1125 (reftex-kill-temporary-buffers) | |
1126 keys)) | |
1127 | |
1128 (defun reftex-create-bibtex-file (bibfile) | |
1129 "Create a new BibTeX database file with all entries referenced in document. | |
1130 The command prompts for a filename and writes the collected entries to | |
1131 that file. Only entries referenced in the current document with | |
1132 any \\cite-like macros are used. | |
1133 The sequence in the new file is the same as it was in the old database." | |
1134 (interactive "FNew BibTeX file: ") | |
1135 (let ((keys (reftex-all-used-citation-keys)) | |
1136 (files (reftex-get-bibfile-list)) | |
1137 file key entries beg end entry) | |
1138 (save-excursion | |
1139 (while (setq file (pop files)) | |
1140 (set-buffer (reftex-get-file-buffer-force file 'mark)) | |
1141 (reftex-with-special-syntax-for-bib | |
1142 (save-excursion | |
1143 (save-restriction | |
1144 (widen) | |
1145 (goto-char (point-min)) | |
1146 (while (re-search-forward | |
1147 "^[ \t]*@[a-zA-Z]+[ \t]*{\\([^ \t\r\n]+\\)," | |
1148 nil t) | |
1149 (setq key (match-string 1) | |
1150 beg (match-beginning 0) | |
1151 end (progn | |
1152 (goto-char (match-beginning 1)) | |
1153 (condition-case nil | |
1154 (up-list 1) | |
1155 (error (goto-char (match-end 0)))) | |
1156 (point))) | |
1157 (when (member key keys) | |
1158 (setq entry (buffer-substring beg end) | |
1159 entries (cons entry entries) | |
1160 keys (delete key keys))))))))) | |
1161 (find-file-other-window bibfile) | |
1162 (if (> (buffer-size) 0) | |
1163 (unless (yes-or-no-p | |
1164 (format "Overwrite non-empty file %s? " bibfile)) | |
1165 (error "Abort"))) | |
1166 (erase-buffer) | |
1167 (insert (mapconcat 'identity (reverse entries) "\n\n")) | |
1168 (goto-char (point-min)) | |
1169 (save-buffer) | |
1170 (message "%d entries extracted and copied to new database" | |
1171 (length entries)))) | |
1172 | |
1173 | |
1174 ;;; arch-tag: d53d0a5a-ab32-4b52-a846-2a7c3527cd89 | |
1045 ;;; reftex-cite.el ends here | 1175 ;;; reftex-cite.el ends here |