aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1996-10-26 18:15:32 +0000
committerRichard M. Stallman1996-10-26 18:15:32 +0000
commitb8a3aefac98afc8e6f1c13be6623c059161c6563 (patch)
tree76152807f1097194dc2798f2379e32f6f535b356
parent5b1bdb5f749369e487f668cbf4872632e5d44c60 (diff)
downloademacs-b8a3aefac98afc8e6f1c13be6623c059161c6563.tar.gz
emacs-b8a3aefac98afc8e6f1c13be6623c059161c6563.zip
(refer-bib-directory): New variable, list of
directories where to look for bib files. Special values `texinputs' and `bibinputs' mean take directory list from corresponding environment variable. (refer-bib-files): New special value `auto', for looking up all files in directories pointed to by refer-bib-directory. I have the feeling that this isn't really my code but came from the net (copylefted). However, I cannot trace this down any more. If it isn't mine, it's probably Ashwin's. (refer-get-bib-files): Support `auto' value of refer-bib-files. Support `texinputs', `bibinputs' value of refer-bib-directory. (refer-saved-state, refer-previous-keywords, refer-saved-pos, refer-same-file): Properly declared (defvar) these variables. (refer-yank-key): New function. (refer-find-entry-internal): Find bibliography entries in other window, with minimal reconfiguration of windows. (refer-expand-files): New function.
-rw-r--r--lisp/textmodes/refer.el333
1 files changed, 245 insertions, 88 deletions
diff --git a/lisp/textmodes/refer.el b/lisp/textmodes/refer.el
index d98228c2422..3234acf2d02 100644
--- a/lisp/textmodes/refer.el
+++ b/lisp/textmodes/refer.el
@@ -1,8 +1,9 @@
1;;; refer.el --- look up references in bibliography files. 1;;; refer.el --- look up references in bibliography files.
2 2
3;; Copyright (C) 1992 Free Software Foundation, Inc. 3;; Copyright (C) 1992, 1996 Free Software Foundation, Inc.
4 4
5;; Author: Ashwin Ram <Ram-Ashwin@cs.yale.edu> 5;; Author: Ashwin Ram <ashwin@cc.gatech.edu>
6;; Maintainer: Gernot Heiser <gernot@jungfrau.disy.cse.unsw.EDU.AU>
6;; Adapted-By: ESR 7;; Adapted-By: ESR
7;; Keywords: bib 8;; Keywords: bib
8 9
@@ -43,6 +44,13 @@
43;; of the keywords, use refer-find-next-entry, or invoke refer-find-entry 44;; of the keywords, use refer-find-next-entry, or invoke refer-find-entry
44;; with a prefix argument. 45;; with a prefix argument.
45;; 46;;
47;; Once you've found the entry you want to reference, invoke
48;; refer-yank-key to insert it at point in the current buffer
49;; (typically as the argument of a \cite{} command).
50;;
51;; I use (define-key tex-mode-map "\C-c\C-y" 'refer-yank-key)
52;; to bind this often-used function to a key in (la)tex-mode.
53;;
46;; If the list of bibliography files changes, reinitialize the variable 54;; If the list of bibliography files changes, reinitialize the variable
47;; refer-bib-files. 55;; refer-bib-files.
48;; 56;;
@@ -60,22 +68,35 @@
60;; entries, try setting the paragraph-start/separate variables, or changing 68;; entries, try setting the paragraph-start/separate variables, or changing
61;; the (forward-paragraph 1) call in refer-find-entry-in-file. 69;; the (forward-paragraph 1) call in refer-find-entry-in-file.
62 70
63;;; ChangeLog:
64
65;; 01/08/89 Ashwin Ram <Ram-Ashwin@cs.yale.edu>
66;; Initial release.
67;;
68
69;;; Code: 71;;; Code:
70 72
71(provide 'refer) 73(provide 'refer)
72 74
75(defvar refer-bib-directory nil
76 "Directory, or list of directories, to search for \\.bib files. Can
77be set to 'bibinputs or 'texinputs, in which case the environment
78variable BIBINPUTS or TEXINPUTS, respectively, is used to obtain a
79list of directories. Useful only if refer-bib-files is set to 'dir or
80a list of file names (without directory). A value of nil indicates the
81current working directory.
82
83If refer-bib-directory is 'bibinputs or 'texinputs, it is setq'd to
84the appropriate list of directories when it is first used.
85
86Note that an empty directory is interpreted by BibTeX as indicating
87the default search path. Since Refer does not know that default path,
88it cannot search it. Include that path explicitly in your BIBINPUTS
89environment if you really want it searched (which is not likely to
90happen anyway).")
91
73(defvar refer-bib-files 'dir 92(defvar refer-bib-files 'dir
74 "*List of \\.bib files to search for references, 93 "*List of \\.bib files to search for references,
75or one of the following special values: 94or one of the following special values:
76nil = prompt for \\.bib file (if visiting a \\.bib file, use it as default) 95nil = prompt for \\.bib file (if visiting a \\.bib file, use it as default)
77auto = read \\.bib file names from appropriate command in buffer (see refer-bib-files-regexp) 96auto = read \\.bib file names from appropriate command in buffer (see
78dir = use all \\.bib files in current directory. 97 refer-bib-files-regexp) unless the buffer's mode is bibtex-mode,
98 in which case only the buffer is searched
99dir = use all \\.bib files in directories referenced by refer-bib-directory.
79 100
80If a specified file doesn't exist and has no extension, a \\.bib extension 101If a specified file doesn't exist and has no extension, a \\.bib extension
81is automatically tried. 102is automatically tried.
@@ -96,7 +117,7 @@ each time it is needed.")
96The current buffer is expected to contain a line such as 117The current buffer is expected to contain a line such as
97\\bibliography{file1,file2,file3} 118\\bibliography{file1,file2,file3}
98which is read to set up refer-bib-files. The regexp must specify the command 119which is read to set up refer-bib-files. The regexp must specify the command
99\(such as \\bibliography) that is used to specify the list of bib files. The 120(such as \\bibliography) that is used to specify the list of bib files. The
100command is expected to specify a file name, or a list of comma-separated file 121command is expected to specify a file name, or a list of comma-separated file
101names, within curly braces. 122names, within curly braces.
102If a specified file doesn't exist and has no extension, a \\.bib extension 123If a specified file doesn't exist and has no extension, a \\.bib extension
@@ -104,6 +125,13 @@ is automatically tried.")
104 125
105(make-variable-buffer-local 'refer-bib-files) 126(make-variable-buffer-local 'refer-bib-files)
106(make-variable-buffer-local 'refer-cache-bib-files) 127(make-variable-buffer-local 'refer-cache-bib-files)
128(make-variable-buffer-local 'refer-bib-directory)
129
130;;; Internal variables
131(defvar refer-saved-state nil)
132(defvar refer-previous-keywords nil)
133(defvar refer-saved-pos nil)
134(defvar refer-same-file nil)
107 135
108(defun refer-find-entry (keywords &optional continue) 136(defun refer-find-entry (keywords &optional continue)
109 "Find entry in refer-bib-files containing KEYWORDS. 137 "Find entry in refer-bib-files containing KEYWORDS.
@@ -113,7 +141,7 @@ entry by continuing search from previous point."
113 (interactive (list nil current-prefix-arg)) 141 (interactive (list nil current-prefix-arg))
114 (or keywords (setq keywords (if continue 142 (or keywords (setq keywords (if continue
115 refer-previous-keywords 143 refer-previous-keywords
116 (read-string "Keywords: ")))) 144 (read-string "Keywords: "))))
117 (setq refer-previous-keywords keywords) 145 (setq refer-previous-keywords keywords)
118 (refer-find-entry-internal keywords continue)) 146 (refer-find-entry-internal keywords continue))
119 147
@@ -122,59 +150,113 @@ entry by continuing search from previous point."
122 (interactive) 150 (interactive)
123 (refer-find-entry-internal refer-previous-keywords t)) 151 (refer-find-entry-internal refer-previous-keywords t))
124 152
153(defun refer-yank-key ()
154 "Inserts at point in current buffer the \"key\" field of the entry
155found on the last refer-find-entry or refer-find-next-entry."
156 (interactive)
157 (let ((old-point (point)))
158 (insert
159 (save-window-excursion
160 (save-excursion
161 (find-file (car refer-saved-state))
162 (if (looking-at
163 "[ \t\n]*@\\s-*[a-zA-Z][a-zA-Z0-9]*\\s-*{\\s-*\\([^ \t\n,]+\\)\\s-*,")
164 (buffer-substring (match-beginning 1) (match-end 1))
165 (error "Cannot find key for entry in file %s."
166 (car refer-saved-state))))))
167 (if (not (= (point) old-point))
168 (set-mark old-point))))
169
125(defun refer-find-entry-internal (keywords continue) 170(defun refer-find-entry-internal (keywords continue)
126 (let ((keywords-list (refer-convert-string-to-list-of-strings keywords)) 171 (let ((keywords-list (refer-convert-string-to-list-of-strings keywords))
172 (old-buffer (current-buffer))
173 (old-window (selected-window))
174 (new-window (selected-window))
127 (files (if continue 175 (files (if continue
128 refer-saved-state 176 refer-saved-state
129 (refer-get-bib-files)))) 177 (setq refer-saved-pos nil)
130 (catch 'found 178 (refer-get-bib-files)))
131 (while files 179 (n 0)
132 (let ((file (cond ((file-exists-p (car files)) (car files)) 180 (found nil)
133 ((file-exists-p (concat (car files) ".bib")) (concat (car files) ".bib"))))) 181 (file nil))
134 (setq refer-saved-state files) 182 ;; find window in which to display bibliography file.
135 (if file 183 ;; if a bibliography file is already displayed in a window, use
136 (if (refer-find-entry-in-file keywords-list file continue) 184 ;; that one, otherwise use any window other than the current one
137 (throw 'found (find-file file)) 185 (while (not found)
138 (setq files (cdr files))) 186 (while (and (not (null (setq file (nth n files))))
139 (progn (message "Scanning %s... No such file" (car files) (ding)) 187 (setq n (1+ n))
140 (sit-for 1) 188 (not (string-equal file
141 (setq files (cdr files)))))) 189 (buffer-file-name
142 (message "Keywords \"%s\" not found in any \.bib file" keywords (ding))))) 190 (window-buffer new-window))))))
143 191 (setq found
144(defun refer-find-entry-in-file (keywords-list file &optional continue) 192 (if (null file)
145 (message "Scanning %s..." file) ; (expand-file-name file) 193 (eq (setq new-window (next-window new-window 'nomini))
194 old-window)
195 't)))
196 (if (null file) ; didn't find bib file in any window:
197 (progn (if (one-window-p 'nomini)
198 (setq old-window (split-window)))
199 (setq new-window (next-window old-window 'nomini))))
200 (select-window (if refer-same-file
201 old-window
202 new-window)) ; the window in which to show the bib file
203 (catch 'found
204 (while files
205 (let ((file (cond ((file-exists-p (car files)) (car files))
206 ((file-exists-p (concat (car files) ".bib"))
207 (concat (car files) ".bib")))))
208 (setq refer-saved-state files)
209 (if file
210 (if (refer-find-entry-in-file keywords-list file refer-saved-pos)
211 (progn
212 (setq refer-saved-pos (point))
213 (recenter 0)
214 (throw 'found (find-file file)))
215 (setq refer-saved-pos nil
216 files (cdr files)))
217 (progn (message "Scanning %s... No such file" (car files) (ding))
218 (sit-for 1)
219 (setq files (cdr files))))))
220 (message "Keywords \"%s\" not found in any \.bib file" keywords (ding)))
221 (select-window old-window)))
222
223(defun refer-find-entry-in-file (keywords-list file &optional old-pos)
224 (message "Scanning %s..." file)
225 (expand-file-name file)
146 (set-buffer (find-file-noselect file)) 226 (set-buffer (find-file-noselect file))
147 (if continue 227 (find-file file)
148 (forward-paragraph 1) 228 (if (not old-pos)
149 (goto-char (point-min))) 229 (goto-char (point-min))
230 (goto-char old-pos)
231 (forward-paragraph 1))
150 (let ((begin (point)) 232 (let ((begin (point))
151 (end 0) 233 (end 0)
152 (found nil)) 234 (found nil))
153 (while (and (not found) 235 (while (and (not found)
154 (not (eobp))) 236 (not (eobp)))
155 (forward-paragraph 1) 237 (forward-paragraph 1)
156 (setq end (point)) 238 (setq end (point))
157 (setq found 239 (setq found
158 (refer-every (function (lambda (keyword) 240 (refer-every (function (lambda (keyword)
159 (goto-char begin) 241 (goto-char begin)
160 (re-search-forward keyword end t))) 242 (re-search-forward keyword end t)))
161 keywords-list)) 243 keywords-list))
162 (if (not found) 244 (if (not found)
163 (progn 245 (progn
164 (setq begin end) 246 (setq begin end)
165 (goto-char begin)))) 247 (goto-char begin))))
166 (if found 248 (if found
167 (progn (goto-char begin) 249 (progn (goto-char begin)
168 (re-search-forward "\\W" nil t) 250 (re-search-forward "\\W" nil t)
169 (message "Scanning %s... found" file)) 251 (message "Scanning %s... found" file))
170 (progn (message "Scanning %s... not found" file) 252 (progn (message "Scanning %s... not found" file)
171 nil)))) 253 nil))))
172 254
173(defun refer-every (pred l) 255(defun refer-every (pred l)
174 (cond ((null l) nil) 256 (cond ((null l) nil)
175 ((funcall pred (car l)) 257 ((funcall pred (car l))
176 (or (null (cdr l)) 258 (or (null (cdr l))
177 (refer-every pred (cdr l)))))) 259 (refer-every pred (cdr l))))))
178 260
179(defun refer-convert-string-to-list-of-strings (s) 261(defun refer-convert-string-to-list-of-strings (s)
180 (let ((current (current-buffer)) 262 (let ((current (current-buffer))
@@ -192,39 +274,114 @@ entry by continuing search from previous point."
192 (prog1 (read temp-buffer) 274 (prog1 (read temp-buffer)
193 (set-buffer current)))) 275 (set-buffer current))))
194 276
277(defun refer-expand-files (file-list dir-list)
278 (let (file files dir dirs)
279 (while (setq file (car file-list))
280 (setq dirs (copy-alist dir-list))
281 (while (setq dir (car dirs))
282 (if (file-exists-p (expand-file-name file dir))
283 (setq files (append files (list (expand-file-name file dir)))
284 dirs nil)
285 (if (file-exists-p (expand-file-name (concat file ".bib") dir))
286 (setq files (append files (list (expand-file-name (concat file ".bib")
287 dir)))
288 dirs nil)
289 (setq dirs (cdr dirs)))))
290 (setq file-list (cdr file-list)))
291 files))
292
195(defun refer-get-bib-files () 293(defun refer-get-bib-files ()
196 (let ((files 294 (let* ((dir-list
197 (cond ((null refer-bib-files) 295 (cond
198 (list (expand-file-name 296 ((null refer-bib-directory)
199 (if (eq major-mode 'bibtex-mode) 297 '("."))
200 (read-file-name (format ".bib file: (default %s) " (file-name-nondirectory (buffer-file-name))) 298 ((or (eq refer-bib-directory 'texinputs)
201 (file-name-directory (buffer-file-name)) 299 (eq refer-bib-directory 'bibinputs))
202 (file-name-nondirectory (buffer-file-name)) 300 (let ((envvar (getenv (if (eq refer-bib-directory 'texinputs)
203 t) 301 "TEXINPUTS"
204 (read-file-name ".bib file: " nil nil t))))) 302 "BIBINPUTS")))
205 ((listp refer-bib-files) refer-bib-files) 303 (dirs nil))
206 ((eq refer-bib-files 'auto) 304 (if (null envvar)
207 (save-excursion 305 (setq envvar "."))
208 (if (progn (goto-char (point-min)) 306 (while (string-match ":" envvar)
209 (re-search-forward (concat refer-bib-files-regexp "\{") nil t)) 307 (let ((dir (substring envvar 0 (match-beginning 0))))
210 (let ((files (list (buffer-substring (point) 308 (if (and (not (string-equal "" dir))
211 (progn (re-search-forward "[,\}]" nil t) 309 (file-directory-p dir))
212 (backward-char 1) 310 (setq dirs (append (list (expand-file-name dir nil))
213 (point)))))) 311 dirs))))
214 (while (not (looking-at "\}")) 312 (setq envvar (substring envvar (match-end 0))))
215 (setq files (append files 313 (if (and (not (string-equal "" envvar))
216 (list (buffer-substring (progn (forward-char 1) 314 (file-directory-p envvar))
217 (point)) 315 (setq dirs (append (list envvar) dirs)))
218 (progn (re-search-forward "[,\}]" nil t) 316 (setq dirs (nreverse dirs))))
219 (backward-char 1) 317 ((listp refer-bib-directory)
220 (point))))))) 318 refer-bib-directory)
221 files) 319 (t
222 (error "No \\\\bibliography command in this buffer, can't read refer-bib-files")))) 320 (list refer-bib-directory))))
223 ((eq refer-bib-files 'dir) 321 (files
224 (directory-files "." t "\\.bib$")) 322 (cond
225 (t (error "Illegal value for refer-bib-files: %s" refer-bib-files))))) 323 ((null refer-bib-files)
226 (if refer-cache-bib-files 324 (list (expand-file-name
227 (setq refer-bib-files files)) 325 (if (eq major-mode 'bibtex-mode)
228 files)) 326 (read-file-name
327 (format ".bib file: (default %s) "
328 (file-name-nondirectory
329 (buffer-file-name)))
330 (file-name-directory (buffer-file-name))
331 (file-name-nondirectory (buffer-file-name))
332 t)
333 (read-file-name ".bib file: " nil nil t)))))
334 ((eq refer-bib-files 'auto)
335 (let ((files
336 (save-excursion
337 (if (setq refer-same-file (eq major-mode 'bibtex-mode))
338 (list buffer-file-name)
339 (if (progn
340 (goto-char (point-min))
341 (re-search-forward (concat refer-bib-files-regexp
342 "\\s-*\{") nil t))
343 (let ((files (list (buffer-substring
344 (point)
345 (progn
346 (re-search-forward "[,\}]"
347 nil t)
348 (backward-char 1)
349 (point))))))
350 (while (not (looking-at "\}"))
351 (setq files (append files
352 (list (buffer-substring
353 (progn (forward-char 1)
354 (point))
355 (progn (re-search-forward
356 "[,\}]" nil t)
357 (backward-char 1)
358 (point)))))))
359 files)
360 (error (concat "No \\\\bibliography command in this "
361 "buffer, can't read refer-bib-files")))))))
362 (refer-expand-files files dir-list)))
363 ((eq refer-bib-files 'dir)
364 (let ((dirs (nreverse dir-list))
365 dir files)
366 (while (setq dir (car dirs))
367 (setq files
368 (append (directory-files dir t "\\.bib$")
369 files))
370 (setq dirs (cdr dirs)))
371 files))
372 ((and (listp refer-bib-files)
373 (or (eq refer-bib-directory 'texinputs)
374 (eq refer-bib-directory 'bibinputs)))
375 (refer-expand-files refer-bib-files dir-list))
376 ((listp refer-bib-files) refer-bib-files)
377 (t (error "Illegal value for refer-bib-files: %s"
378 refer-bib-files)))))
379 (if (or (eq refer-bib-directory 'texinputs)
380 (eq refer-bib-directory 'bibinputs))
381 (setq refer-bib-directory dir-list))
382 (if refer-cache-bib-files
383 (setq refer-bib-files files))
384 files))
229 385
230;;; refer.el ends here 386;;; refer.el ends here
387