comparison lisp/auctex/bib-cite.el @ 24:4103f0995bd7 r19-15b95

Import from CVS: tag r19-15b95
author cvs
date Mon, 13 Aug 2007 08:51:03 +0200
parents
children ec9a17fef872
comparison
equal deleted inserted replaced
23:0edd3412f124 24:4103f0995bd7
1 ;; bib-cite.el - Display \cite, \ref or \label / Extract refs from BiBTeX file.
2
3 ;; Copyright (C) 1994, 1995, 1996, 1997 Peter S. Galbraith
4
5 ;; Author: Peter S. Galbraith <rhogee@bathybius.meteo.mcgill.ca>
6 ;; Created: 06 July 1994
7 ;; Version: 2.28 (22 January 97)
8 ;; Keywords: bibtex, cite, auctex, emacs, xemacs
9
10 ;; RCS $Id: bib-cite.el,v 1.1 1997/02/20 02:16:50 steve Exp $
11 ;; Note: RCS version number does not correspond to release number.
12
13 ;; Everyone is granted permission to copy, modify and redistribute this
14 ;; file provided:
15 ;; 1. All copies contain this copyright notice.
16 ;; 2. All modified copies shall carry a prominant notice stating who
17 ;; made modifications and the date of such modifications.
18 ;; 3. The name of the modified file be changed.
19 ;; 4. No charge is made for this software or works derived from it.
20 ;; This clause shall not be construed as constraining other software
21 ;; distributed on the same medium as this software, nor is a
22 ;; distribution fee considered a charge.
23
24 ;; LCD Archive Entry:
25 ;; bib-cite|Peter Galbraith|galbraith@mixing.qc.dfo.ca|
26 ;; Display \cite, \ref or \label / Extract refs from BiBTeX file.|
27 ;; 22-Jan-1997|2.28|~/misc/bib-cite.el.gz|
28
29 ;; ----------------------------------------------------------------------------
30 ;;; Commentary:
31
32 ;; New versions of this package (if they exist) may be found at:
33 ;; ftp://ftp.phys.ocean.dal.ca/users/rhogee/elisp/bib-cite.el
34
35 ;; Operating Systems:
36 ;; Works in unix, DOS and OS/2. Developped under Linux.
37 ;; VMS: I have no clue if this works under VMS. I don't know how emacs handle
38 ;; logical names (i.e. for BIBINPUTS) but I am willing to fix this package for
39 ;; VMS if someone if willing to test it and answer questions.
40
41 ;; AUC-TEX USERS:
42 ;; auc-tex is a super-charged LaTeX mode for emacs. Get it at:
43 ;; ftp://ftp.iesd.auc.dk/pub/emacs-lisp/auctex.tar.gz <-stable release
44 ;; ftp://ftp.dina.kvl.dk/pub/Staff/Per.Abrahamsen/auctex/ <-alpha release
45 ;;
46 ;; WWW users may want to check out the AUC TeX page at
47 ;; http://www.iesd.auc.dk/~amanda/auctex/
48 ;;
49 ;; bib-cite.el is included in the auc-tex distribution. Therefore, if
50 ;; you use auc-tex, you probably have an old version of bib-cite.el in
51 ;; your load-path which may get loaded instead of this file (unless this
52 ;; is the auc-tex file!). Make sure you replace that file, or rename it,
53 ;; or delete it!!!
54
55 ;; MS-DOS USERS:
56 ;; Multifile documents are supported by bib-cite by using etags (TAGS files)
57 ;; which contains a bug for MSDOS (at least for emacs 19.27 it does).
58 ;; Get the file
59 ;; ftp://ftp.phys.ocean.dal.ca/users/rhogee/elisp/bib-cite.etags-bug-report
60 ;; to see what patches to make to etags.c to fix it.
61
62 ;; Description:
63 ;; ~~~~~~~~~~~
64 ;; This package is used in various TeX modes to display or edit references
65 ;; associated with \cite commands, or matching \ref and \label commands.
66 ;; (so I actually overstep BiBTeX bounds here...)
67 ;; These are the functions:
68 ;;
69 ;; bib-display bib-display-mouse
70 ;; - Display citation, \ref or \label under point
71 ;; bib-find bib-find-mouse
72 ;; - Edit citation, \ref or \label under point
73 ;; bib-make-bibliography - Make BiBTeX file containing only cite keys used.
74 ;; bib-apropos - Search BiBTeX source files for keywords.
75 ;; bib-etags - Refreshes (or builds) the TAGS files for
76 ;; multi-file documents.
77 ;; bib-create-auto-file - Used in bibtex-mode to create cite key
78 ;; completion .el file for auctex.
79 ;; bib-highlight-mouse - Highlight \cite, \ref and \label commands in
80 ;; green when the mouse is over them.
81
82 ;; About Cite Commands and related functions:
83 ;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
84 ;; Various flavors of \cite commands are allowed (as long as they contain
85 ;; the word `cite') and they may optionally have bracketed [] options.
86 ;; Bibtex Cross-references are displayed, and @string abbreviations are
87 ;; substituted or included.
88 ;;
89 ;; The \cite text is found (by emacs) in the bibtex source files listed in the
90 ;; \bibliography command. The BiBTeX files can be located in a search path
91 ;; defined by an environment variable (typically BIBINPUTS, but you can change
92 ;; this).
93 ;;
94 ;; All citations used in a buffer can also be listed in a new bibtex buffer by
95 ;; using bib-make-bibliography. This is useful to make a bibtex file for a
96 ;; document from a large bibtex database. In this case, cross-references are
97 ;; included, as well as the @string commands used. The @string abbreviations
98 ;; are not substituted.
99 ;;
100 ;; The bibtex files can also be searched for entries matching a regular
101 ;; expression using bib-apropos.
102
103 ;; Usage instructions:
104 ;; ~~~~~~~~~~~~~~~~~~
105 ;; bib-display Bound to Mouse-3 when specially highlighted.
106 ;; In Hyperbole, bound to the Assist key.
107 ;; Bound to `\C-c b d'
108 ;;
109 ;; bib-display will show the bibtex entry or the corresponding label or
110 ;; ref commands from anywhere within a document.
111 ;; With cursor on the \cite command itslef
112 ;; -> display all citations of the cite command from the BiBTeX source.
113 ;; With cursor on a particular cite key within the brackets
114 ;; -> display that citation's text from the BiBTeX source file(s).
115 ;;
116 ;; Example:
117 ;;
118 ;; \cite{Wadhams81,Bourke.et.al87,SchneiderBudeus94}
119 ;; ^Cursor -> Display-all-citations ^Cursor -> Display-this-citation
120 ;;
121 ;; With cursor on a \label command
122 ;; -> Display first matching \ref command in the document
123 ;; With cursor on a \ref command
124 ;; -> Display environment associated with the matching \label command.
125 ;;
126 ;; Finding a ref or label within a multi-file document requires a TAGS file,
127 ;; which is automatically generated for you. This enables you to then use
128 ;; any tags related emacs features.
129 ;;
130 ;; bib-find Bound to Mouse-2 when specially highlighted.
131 ;; In Hyperbole, bound to the Action key.
132 ;; Bound to `\C-c b f'
133 ;;
134 ;; bib-find will select the buffer and move point to the BiBTeX source file
135 ;; at the proper citation for a cite command, or move point to anywhere
136 ;; within a document for a label or ref command. The ref chosen is the
137 ;; first occurrance within a document (using a TAGS file). If point is
138 ;; moved within the same buffer, mark is set before the move and a message
139 ;; stating so is given. If point is moved to another file, this is done in
140 ;; a new window using tag functions. Within a plain file, the search
141 ;; pattern is set for another similar \ref command (since TAGS file are not
142 ;; used). Within a multi-file document the following tag functions are
143 ;; appropriately setup:
144 ;;
145 ;; C-u M-. Find next alternate definition of last tag specified.
146 ;;
147 ;; C-u - M-. Go back to previous tag found.
148 ;;
149 ;;
150 ;; For multi-file documents, you must be using auctex (so that bib-cite can
151 ;; find the master file) and all \input and \include commands must be first
152 ;; on a line (not preceeded by any non-white text).
153 ;;
154 ;; imenu support (Suggested key binding: Shift-Mouse-3)
155 ;;
156 ;; If you want to bind imenu globally to Shift-Mouse-3, do so by adding the
157 ;; following to your ~/.emacs
158 ;;
159 ;; (require 'imenu)
160 ;; (define-key global-map [S-mouse-3] 'imenu)
161 ;;
162 ;; Another good place to define Imenu is in the menu-bar. You can try this
163 ;; manually with
164 ;;
165 ;; M-x imenu-add-to-menubar RET Imenu RET
166 ;;
167 ;; or in a hook such as:
168 ;;
169 ;; (add-hook 'LaTeX-mode-hook '(lambda () (imenu-add-to-menubar "Imenu")))
170 ;;
171 ;; The imenu facility (distributed with emacs) is supported by bib-cite to
172 ;; move point to a LaTeX section (or chapter) division or to a label
173 ;; declaration. When editing a multi-file document, all such declarations
174 ;; within the document are displayed in the menu (again using a TAGS file).
175 ;; If you do not want to load imenu.el and use these features, set
176 ;; bib-use-imenu to nil. (This feature is disabled in xemacs because I'm
177 ;; told it doesn't have imenu).
178 ;;
179 ;; bib-make-bibliography: Bound to `\C-c b m'
180 ;;
181 ;; Extract citations used in the current document from the \bibliography{}
182 ;; file(s). Put them into a new suitably-named buffer. In a auctex
183 ;; multi-file document, the .aux files are used to find the cite keys (for
184 ;; speed). You will be warned if these are out of date.
185 ;;
186 ;; This buffer is not saved to a file. It is your job to save it to whatever
187 ;; name you wish. Note that auctex has a unique name space for LaTeX and
188 ;; BiBTeX files, so you should *not* name the bib file associated with
189 ;; example.tex as example.bib! Rather, name it something like
190 ;; example-bib.bib.
191 ;;
192 ;; bib-apropos: Bound to `\C-c b a'
193 ;;
194 ;; Searches the \bibliography{} file(s) for entries containing a keyword and
195 ;; display them in the *help* buffer. You can trim down your search by using
196 ;; bib-apropos in the *Help* buffer after the first invocation. the current
197 ;; buffer is also searched for keyword matches if it is in bibtex-mode.
198 ;;
199 ;; It doesn't display cross-references nor does it substitute or display
200 ;; @string commands used. It could easily be added, but it's faster this
201 ;; way. Drop me a line if this would be a useful addition.
202 ;;
203 ;; If you find yourself entering a cite command and have forgotten which key
204 ;; you want, but have entered a few initial characters as in `\cite{Gal',
205 ;; then invoke bib-apropos. It will take that string (in this case `Gal') as
206 ;; an initial response to the apropos prompt. You are free to edit it, or
207 ;; simply press carriage return.
208 ;;
209 ;; bib-etags: Bound to `\C-c b e'
210 ;;
211 ;; Creates a TAGS file for auc-tex's multi-file document (or refreshes it).
212 ;; This is used by bib-find when editing multi-file documents. The TAGS file
213 ;; is created automatically, but it isn't refreshed automatically. So if
214 ;; bib-find can't find something, try running bib-etags again. The *rescan*
215 ;; in imenu also calls bib-etags to refresh the TAGS file, so that is another
216 ;; way to generate it.
217 ;;
218 ;; bib-create-auto-file:
219 ;;
220 ;; Use this when editing a BiBTeX buffer to generate the auc-tex .el file
221 ;; which tell emacs about all its cite keys. I've added this command to
222 ;; bibtex-mode pull-down menu.
223 ;;
224 ;; bib-highlight-mouse: Bound to `\C-c b h'
225 ;;
226 ;; Highlights \cite, \ref and \label commands in green when the mouse is over
227 ;; them. By default, a call to this function is added to LaTeX-mode-hook
228 ;; (via bib-cite-initialize) if you set bib-highlight-mouse-t to true. But
229 ;; you may want to run this command to refresh the highlighting for newly
230 ;; edited text.
231
232 ;; Installation instructions:
233 ;; ~~~~~~~~~~~~~~~~~~~~~~~~~
234 ;; If you use a menued environment (e.g. X Window System), bib-cite must be
235 ;; loaded *after* your LaTeX-mode menus are created in order to bypass an
236 ;; annoying bug in bib-cite. This is done by loading bib-cite via a
237 ;; mode-hook:
238 ;; - If you are using AUC-TeX (http://sunsite.auc.dk/auctex/), add the
239 ;; following lines to your ~/.emacs file:
240 ;;
241 ;; (defun my-LaTeX-mode-hook ()
242 ;; (require 'bib-cite))
243 ;; (add-hook 'LaTeX-mode-hook 'my-LaTeX-mode-hook)
244 ;;
245 ;; - If you are using Emacs' regulare LaTeX-mode, use instead:
246 ;;
247 ;; (defun my-LaTeX-mode-hook ()
248 ;; (require 'bib-cite))
249 ;; (add-hook 'latex-mode-hook 'my-TeX-mode-hook)
250 ;;
251 ;; If you do not use a windowed environment, all you need to do is add this
252 ;; line to your .emacs file:
253 ;;
254 ;; (require 'bib-cite)
255 ;;
256 ;; bib-cite can be used with auctex, or stand-alone. If used with auctex on a
257 ;; multi-file document (and auctex's parsing is used), then all \bibliography
258 ;; commands in the document will be found and used.
259 ;; ---
260 ;; The following variable can be unset (like shown) to tell bib-cite to
261 ;; not give advice messages about which commands to use to find the next
262 ;; occurrence of a search:
263 ;;
264 ;; (setq bib-novice nil)
265 ;; ---
266 ;; By default, bib-cite adds a menu-bar pull-down menu under a separate name.
267 ;; Under emacs' tex-mode and auctex's latex-mode, it can be placed within
268 ;; the existing menu if you set the following:
269 ;;
270 ;; (setq bib-cite-put-menu-separately nil)
271 ;;
272 ;; This variable has no effect under XEmacs. Should I change this?
273 ;; ---
274 ;; The imenu features will be disabled if you set this variable to nil
275 ;;
276 ;; (setq bib-use-imenu nil)
277 ;;
278 ;; This variable has no effect under XEmacs.
279 ;; ---
280 ;; If you use hilit19 (or hl319), then bib-display will use it to highlight
281 ;; the display unless you turn this off with:
282 ;;
283 ;; (setq bib-hilit-if-available nil)
284 ;;
285 ;; If you don't use hilit19, or if this is nil, and if you use font-lock
286 ;; then it will be used by bib-display.
287 ;; ---
288 ;; The variable bib-switch-to-buffer-function sets the function used to
289 ;; select buffers (if they differ from the original) in bib-cite commands
290 ;; bib-make-bibliography, bib-display, bib-find
291 ;; You may use `switch-to-buffer' `switch-to-buffer-other-window' or
292 ;; `switch-to-buffer-other-frame'.
293 ;; ---
294 ;; The following variable determines whether we will attempt to highlight
295 ;; citation, ref and label commands in green when they are under the
296 ;; mouse. When highlighted, the mouse keys work to call bib-display
297 ;; (bound to [mouse-3]) and bib-find (bound to [mouse-2]). If you use a
298 ;; mode other than LaTeX-mode, you'll want to call bib-highlight-mouse with
299 ;; a hook (See how we do this at the end of this file with the add-hook
300 ;; command).
301 ;;
302 ;; (setq bib-highlight-mouse-t nil)
303 ;; ---
304 ;; If you use DOS or OS/2, you may have to set the following variable:
305 ;;
306 ;; (setq bib-dos-or-os2-variable t)
307 ;;
308 ;; if bib-cite.el fails to determine that you are using DOS or OS/2.
309 ;; Try `C-h v bib-dos-or-os2-variable' to see if it needs to be set manually.
310 ;; ---
311 ;; bib-cite needs to call the etags program with its output file option
312 ;; and also with the append option (usually -a).
313 ;; I figured that DOS and OS/2 would use "etags /o=" instead of the unix
314 ;; variant "etags -o ", but users have reported differently. So while the
315 ;; unix notation is used here, you can reset it if you need to like so:
316 ;;
317 ;; (setq bib-etags-command "etags /o=")
318 ;; (setq bib-etags-append-command "etags /a /o=")
319 ;; ---
320 ;; For multi-file documents, a TAGS file is generated by etags.
321 ;; By default, its name is TAGS. You can change this like so:
322 ;;
323 ;; (setq bib-etags-filename "TAGSLaTeX")
324 ;; ---
325 ;; If your environment variable to find BiBTeX files is not BIBINPUTS, then
326 ;; reset it with the following variable (here, assuming it's TEXBIB instead):
327 ;;
328 ;; (setq bib-bibtex-env-variable "TEXBIB")
329 ;;
330 ;; Note that any directory ending in a double slash will cause bib-cite to
331 ;; search recursively through subdirectories for your .bib files. This can
332 ;; be slow, so use this judiciously.
333 ;; e.g. setenv BSTINPUTS .:/home/rhogee/LaTeX/bibinputs//
334 ;; -> all directories below /home/rhogee/LaTeX/bibinputs/ will be
335 ;; searched.
336 ;; ---
337 ;; If you do not wish bib-display to substitute @string abbreviations,
338 ;; then set the following variable like so:
339 ;;
340 ;; (setq bib-substitute-string-in-display nil)
341 ;; ---
342 ;; Warnings are given when @string abbreviations are not defined in your bib
343 ;; files. The exception is for months, usually defined in style files. If you
344 ;; use other definitions in styles file (e.g. journals), then you may add them
345 ;; to the `bib-substitute-string-in-display' list variable.
346
347 ;; If you find circumstances in which this package fails, please let me know.
348
349 ;; Things for me to do in later versions:
350 ;; - jmv@di.uminho.pt (Jose Manuel Valenca) wants:
351 ;; - prompt for \cite as well as \label and \ref
352 ;; (and use auctex's completion list)
353 ;; - implement string concatenation, with #[ \t\n]*STRING_NAME
354 ;; - Create new command to substitute @string text in any bibtex buffer.
355
356 ;; ----------------------------------------------------------------------------
357 ;;; Change log:
358 ;; V2.28 Jan 22 97 - Peter Galbraith (RCS V1.9)
359 ;; - Bug in bib-create-auto-file.
360 ;; V2.27 Dec 31 96 - Peter Galbraith (RCS V1.8)
361 ;; - allow spaces between cite keys.
362 ;; - Vladimir Alexiev <vladimir@cs.ualberta.ca>
363 ;; Allow () delimiters as well as {}.
364 ;; Better check on bibtex-menu
365 ;; Erase *bibtex-bibliography* buffer.
366 ;; V2.26 Sep 24 96 - Peter Galbraith (RCS V1.7)
367 ;; imenu bug fix.
368 ;; V2.25 Sep 23 96 - Anders Stenman <stenman@isy.liu.se> (RCS V1.6)
369 ;; XEmacs bib-cite-fontify-help-as-latex bug fix.
370 ;; V2.24 Aug 19 96 - Peter Galbraith (RCS V1.3)
371 ;; XEmacs bug fix, minor defvars - Vladimir Alexiev <vladimir@cs.ualberta.ca>
372 ;; V2.23 Aug 13 96 - Peter Galbraith (RCS V1.2)
373 ;; XEmacs - Add bib-cite entries to bibtex-mode popup menu.
374 ;; V2.22 July 22 96 - Peter Galbraith (RCS V1.1)
375 ;; local-map has `m' for bib-make-bibliography instead of `b'
376 ;; set-buffer-menubar in XEmacs so that menu disappears after use.
377 ;; V2.21 July 12 96 - Peter Galbraith
378 ;; Define `\C-c b' keymap for both plain tex and auctex, in XEmacs and emacs.
379 ;; Separate menu-bar menu in gnu emacs.
380 ;; font-lock support for bib-display'ed citations (bibtex fontification)
381 ;; and for matching \ref{} and \labels (latex fontification).
382 ;; buffer-substring-no-properties in bib-apropos
383 ;; (bug in completing-read with mouse faces)
384 ;; imenu-sort-function made local and nil.
385 ;; imenu--LaTeX-name-and-position fixed for section name containing "\"
386 ;; Various other things... (whitespace within label strings, etc...)
387 ;; V2.20 June 25 96 - Peter Galbraith
388 ;; imenu fixed for emacs-19.31.
389 ;; V2.19 May 13 96
390 ;; PSG:
391 ;; - @string substitution fixed; bib-edit-citation fixed when buffer exists;
392 ;; Christoph Wedler <wedler@fmi.uni-passau.de>:
393 ;; - Added bib-switch-to-buffer-function
394 ;; - (setq tags-always-exact nil) for xemacs
395 ;; - removed eval-after-load foe xemacs
396 ;; V2.18 May 06 96 - PSG
397 ;; New eval-after-load from Fred Devernay <Frederic.Devernay@sophia.inria.fr>
398 ;; V2.17 May 03 96 - PSG
399 ;; Fixed bug introduced in V2.16, reported by Dennis Dams <wsindd@win.tue.nl>
400 ;; V2.16 May 02 96 - Vladimir Alexiev <vladimir@cs.ualberta.ca>
401 ;; - somewhat compatible with Hyperbole by binding bib-find and bib-display to
402 ;; the Action and Assist keys inside the bib-highlight-mouse-keymap.
403 ;; - makes more liberal provisions for users with a tty.
404 ;; V2.15 Apr 09 96 -
405 ;; - fix "Buffer read-only" error caused by mouse-face text properties
406 ;; patch by Piet van Oostrum <piet@cs.ruu.nl>
407 ;; - Use tmm non-X menu, patch by Vladimir Alexiev <vladimir@cs.ualberta.ca>
408 ;; - input{file.txt} would not work.
409 ;; bug report: David Kastrup <dak@pool.informatik.rwth-aachen.de>
410 ;; V2.14 Feb 26 96 - PSG - define eval-after-load for xemacs
411 ;; Frederic Devernay's <Frederic.Devernay@sophia.inria.fr> suggestion.
412 ;; V2.13 Feb 08 96 - Peter Galbraith - Fixed recursive use of bib-apropos.
413 ;; V2.12 Jan 19 96 - Peter Galbraith
414 ;; emacs-19.30's [down-mouse-1] is defined (rather than [mouse-1]), so
415 ;; bib-highlight-mouse-keymap now has [down-mouse-1] defined to override it.
416 ;; V2.11 Nov 21 95 - Peter Galbraith
417 ;; - Fixed bib-create-auto-file when bib file loaded before LaTeX file.
418 ;; - Michal Mnuk's better imenu labels menu <Michal.Mnuk@risc.uni-linz.ac.at>
419 ;; - [mouse-1] and [mouse-2] key defs for highlighted regions.
420 ;; - Improve X menus.
421 ;; - Skip over style files in bib-document-TeX-files.
422 ;; - Add menus and mouse highlighting for xemacs
423 ;; Anders Stenman <stenman@isy.liu.se> Dima Barsky <D.Barsky@ee.surrey.ac.uk>
424 ;; - Check bib-use-imenu before calling LaTeX-hook-setq-imenu.
425 ;; From: Kurt Hornik <hornik@ci.tuwien.ac.at>
426 ;; - Remove mouse face properties before inserting new ones.
427 ;; From: Peter Whaite <peta@Whippet.McRCIM.McGill.EDU>
428 ;; V2.10 Aug 17 95 - Peter Galbraith - fatal bugs in bib-make-bibliography.
429 ;; V2.09 Jul 19 95 - Peter Galbraith
430 ;; - Had introduced bug in search-directory-tree. synced with ff-paths.el.
431 ;; V2.08 Jul 13 95 - Peter Galbraith
432 ;; Fred Douglis <douglis@research.att.com> says etags should be required
433 ;; V2.07 Jul 04 95 - Peter Galbraith
434 ;; - Minor changes with filename manipulations (careful with DOS...)
435 ;; - Problem if auc-tex not already loaded -> LaTeX-mode-map
436 ;; V2.06 Jul 03 95 - Peter Galbraith - Added recursion through BIBINPUTS path.
437 ;; V2.05 Jun 22 95 - Peter Galbraith Bug: Hanno Wirth <wirth@jake.igd.fhg.de>
438 ;; bib-get-citations would truncate @String{KEY ="J. {\"u} Res."}
439 ;; V2.04 Jun 19 95 - Peter Galbraith -
440 ;; - use bibtex-mode syntax table in bib buffer, else bib-apropos truncates
441 ;; an article if it contains an unbalanced closing parenthesis.
442 ;; - bib-highlight-mouse would mark a buffer modified
443 ;; V2.03 May 16 95 - Peter Galbraith -
444 ;; auc-tec menu compatible with old "AUC TeX" pull-down name
445 ;; V2.02 May 10 95 - Peter Galbraith -
446 ;; bug report by Bodo Huckestein <bh@thp.Uni-Koeln.DE> (getenv env) under DOS
447 ;; V2.01 Mar 27 95 - Peter Galbraith - No imenu on xemacs; check BIBINPUT also
448 ;; V2.00 Mar 27 95 - Peter Galbraith
449 ;; - bib-find and bib-display replace bib-edit-citation and
450 ;; bib-display-citation
451 ;; - bib-apropos now take initial guess from start of cite argument at point.
452 ;; - Multi-file support for bib-make-bibliography using .aux files.
453 ;; - \label and \ref functionality for bib-find and bib-display:
454 ;; - \label may appear within an \begin\end or to label a (sub-)section.
455 ;; - Cursor on \label, goto first \ref, set next i-search to pattern.
456 ;; - Cursor on \ref, goto \label or display it's environment or section.
457 ;; - Works on hidden code!
458 ;; V1.08 Jan 16 95 - Peter Galbraith
459 ;; bib-apropos can be used within *Help* buffer to trim a search.
460 ;; V1.07 Dec 13 94 - Peter Galbraith
461 ;; - Fixed: multi-line @string commands in non-inserted display.
462 ;; - Fixed: quoted \ character in @string commands.
463 ;; - BiBTeX comments should not affect bib-cite
464 ;; - Fixed bib-apropos (from Christoph Wedler <wedler@fmi.uni-passau.de>)
465 ;; Faster now, and avoids infinite loops.
466 ;; - Added bib-edit-citation to edit a bibtex files about current citation.
467 ;; - Allow space and newlines between citations: \cite{ entry1, entry2}
468 ;; - Added bib-substitute-string-in-display, bib-string-ignored-warning
469 ;; and bib-string-regexp.
470 ;; - bib-display-citation (from Markus Stricker <stricki@vision.ee.ethz.ch>)
471 ;; Could not find entry with trailing spaces
472 ;; V1.06 Nov 20 94 - Peter Galbraith
473 ;; - Fixed bib-apropos for:
474 ;; hilighting without invoking bibtex mode.
475 ;; display message when no matches found.
476 ;; would search only last bib file listed (forgot to `goto-char 1')
477 ;; - Fixed bib-make-bibliography that would only see first citation in a
478 ;; multi-key \cite command (found by Michail Rozman <roz@physik.uni-ulm.de>
479 ;; - bib-make-bibliography didn't see \cite[A-Z]* commands.
480 ;; Found by Richard Stanton <stanton@haas.berkeley.edu>
481 ;; **************************************************
482 ;; - * Completely rewritten code to support crossrefs *
483 ;; **************************************************
484 ;; - autodetection of OS/2 and DOS for bib-dos-or-os2-variable
485 ;; - Created bib-display-citation-mouse
486 ;; - bib-apropos works in bibtex-mode on the current buffer
487 ;; - bibtex entry may have comma on next line (!)
488 ;; @ARTICLE{Kiryati-91
489 ;; , YEAR = {1991 }
490 ;; ...
491 ;; V1.05 Nov 02 94 - Peter Galbraith
492 ;; - bug fix by rossmann@TI.Uni-Trier.DE (Jan Rossmann)
493 ;; for (boundp 'TeX-check-path) instead of fboundp. Thanks!
494 ;; - Translate environment variable set by bib-bibtex-env-variable.
495 ;; (suggested by Richard Stanton <stanton@haas.berkeley.edu>)
496 ;; - add bib-dos-or-os2-variable to set environment variable path separator
497 ;; - Add key-defs for any tex-mode and auc-tex menu-bar entries.
498 ;; [in auc-tec TeX-mode-map is common to both TeX and LaTeX at startup
499 ;; (but TeX-mode-map is only copied to LaTeX-mode-map at initilisation)
500 ;; in plain emacs, use tex-mode-map for both TeX and LaTeX.]
501 ;; - Add key def for bibtex-mode to create auc-tex's parsing file.
502 ;; - Fix bugs found by <thompson@loon.econ.wisc.edu>
503 ;; - fix bib-get-citation for options
504 ;; - fix bib-get-citation for commas preceeded citation command
505 ;; - better regexp for citations and their keys.
506 ;; - Added @string support for any entry (not just journal entries).
507 ;; (I had to disallow numbers in @string keys because of years.
508 ;; Is that ok?)
509 ;; - added bib-apropos
510 ;; V1.04 Oct 24 94 - Peter Galbraith
511 ;; - Don't require dired-aux, rather define the function we need from it.
512 ;; - Regexp-quote the re-search for keys.
513 ;; - Name the bib-make-bibliography buffer diffently than LaTeX buffer
514 ;; because auc-tex's parsing gets confused if same name base is used.
515 ;; V1.03 Oct 24 94 - Peter Galbraith - require dired-aux for dired-split
516 ;; V1.02 Oct 19 94 - Peter Galbraith
517 ;; - If using auc-tex with parsing activated, use auc-tex's functions
518 ;; to find all \bibliography files in a multi-file document.
519 ;; - Find bib files in pwd, BIBINPUTS environment variable path and
520 ;; TeX-check-path elisp variable path.
521 ;; - Have the parser ignore \bibliography that is on a commented `%' line.
522 ;; (patched by Karl Eichwalder <karl@pertron.central.de>)
523 ;; - Allow for spaces between entry type and key in bib files:
524 ;; (e.g @Article{ key} )
525 ;; (suggested by Nathan E. Doss <doss@ERC.MsState.Edu>)
526 ;; - Allows options in \cite command (e.g. agu++ package \cite[e.g.][]{key})
527 ;; - Includes @String{} abbreviations for `journal' entries
528 ;; V1.01 July 07 94 - Peter Galbraith - \bibliography command may have list of
529 ;; BibTeX files. All must be readable.
530 ;; V1.00 July 06 94 - Peter Galbraith - Created
531 ;; ----------------------------------------------------------------------------
532 ;;; Code:
533
534 ;;>>>>>>User-Modifiable variables start here:
535
536 (defvar bib-novice t
537 "*Give advice to novice users about what commands to use next.")
538
539 (defvar bib-use-imenu (not (string-match "XEmacs\\|Lucid" emacs-version))
540 "*Use imenu package for LaTeX modes (coded in bib-cite).")
541
542 (defvar bib-hilit-if-available t
543 "*Use hilit19 or hl319 to hilit bib-display if available")
544
545 (defvar bib-switch-to-buffer-function 'switch-to-buffer
546 "*Function used to select buffers if they differ from the original.
547 You may use `switch-to-buffer' `switch-to-buffer-other-window' or
548 `switch-to-buffer-other-frame'.")
549
550 (defvar bib-highlight-mouse-t t
551 "*Call bib-highlight-mouse from LaTeX-mode-hook to add green highlight.")
552
553 (defvar bib-bibtex-env-variable "BIBINPUTS"
554 "*Environment variable setting the path where BiBTeX input files are found.
555 BiBTeX 0.99b manual says this should be TEXBIB.
556 Another version says it should BSTINPUTS. I don't know anymore!
557
558 The colon character (:) is the default path separator in unix, but you may
559 use semi-colon (;) for DOS or OS/2 if you set bib-dos-or-os2-variable to `t'.")
560
561 (defvar bib-dos-or-os2-variable (or (equal 'emx system-type)
562 (equal 'ms-dos system-type))
563 ;; Under OS/2 system-type equals emx
564 ;; Under DOS system-type equals ms-dos
565 "*`t' if you use DOS or OS/2 for bib-make-bibliography/bib-display
566
567 It tells bib-make-bibliography and bib-display to translate
568 the BIBINPUTS environment variable using the \";\" character as
569 a path separator and to translate DOS' backslash to slash.
570
571 e.g. Use a path like \"c:\\emtex\\bibinput;c:\\latex\\bibinput\"
572
573 (You can change the environment variable which is searched by setting the
574 elisp variable bib-bibtex-env-variable)")
575
576 (defvar bib-etags-command "etags -o "
577 "*Variable for the etags command and its output option.
578 In unix, this is usually \"etags -o \"
579 In DOS and OS/2, this *may* be \"etags /o=\" If so, set it this variable.")
580
581 (defvar bib-etags-append-command "etags -a -o "
582 "*Variable for the etags command and its append and output option.
583 In unix, this is usually \"etags -a -o \"
584 In DOS and OS/2, this *may* be \"etags /a /o=\" If so, set it this variable.")
585
586 (defvar bib-etags-filename "TAGS"
587 "*Variable for the filename generated by etags, by defaults this TAGS
588 but you may want to change this to something like TAGSLaTeX such that it can
589 coexist with some other tags file in your master file directory.")
590
591 (defvar bib-substitute-string-in-display t
592 "*Determines if bib-display will substitute @string definitions.
593 If t, then the @string text is substituted.
594 If nil, the text is not substituted but the @string entry is included.")
595
596 (defvar bib-string-ignored-warning
597 '("jan" "feb" "mar" "apr" "may" "jun" "jul" "aug" "sep" "sept" "oct" "nov"
598 "dec")
599 "*List of @string abbreviations for which a warning is given if not defined.
600 These are usually month abbreviations (or journals) defined in a style file.")
601
602 ;;<<<<<<User-Modifiable variables end here.
603
604 ;; Following from bibtex.el
605 (defvar
606 bib-cite-bibtex-font-lock-keywords
607 '(("^\\( \\|\t\\)*\\(@[A-Za-z]+\\)[ \t]*[({]\\([][A-Za-z0-9.:;?!`'()/*@_+=|<>-]+\\)?"
608 (2 font-lock-function-name-face)
609 (3 font-lock-reference-face nil t))
610 ;; reference type and reference label
611 ("^[ \t]*\\(OPT[^\"#%'(),={} \t\n0-9][^\"#%'(),={} \t\n]*\\)[ \t]*="
612 1 font-lock-comment-face)
613 ;; optional field names (treated as comments)
614 ("^[ \t]*\\([^\"#%'(),={} \t\n0-9][^\"#%'(),={} \t\n]*\\)[ \t]*="
615 1 font-lock-variable-name-face)
616 ;; field names
617 "Default expressions to fontify in BibTeX mode."))
618
619 (defvar bib-cite-bibtex-mode-syntax-table
620 (let ((st (make-syntax-table)))
621 ;; [alarson:19920214.1004CST] make double quote a string quote
622 (modify-syntax-entry ?\" "\"" st)
623 (modify-syntax-entry ?$ "$$ " st)
624 (modify-syntax-entry ?% "< " st)
625 (modify-syntax-entry ?' "w " st)
626 (modify-syntax-entry ?@ "w " st)
627 (modify-syntax-entry ?\\ "\\" st)
628 (modify-syntax-entry ?\f "> " st)
629 (modify-syntax-entry ?\n "> " st)
630 (modify-syntax-entry ?~ " " st)
631 st))
632 ;; Code from bibtex.el ends
633
634 ;; @string starts with a letter and does not contain any of ""#%'(),={}
635 ;; Here we do not check that the field contains only one string field and
636 ;; nothing else.
637 (defvar bib-string-regexp
638 "^[, \t]*[a-zA-Z]+[ \t]*=[ \t]*\\([a-zA-Z][^#%'(),={}\" \t\n]*\\)"
639 "Regular expression for field containing a @string")
640
641 (defvar bib-ext-list nil
642 "xemacs buffer-local list of bib-cite extents.")
643 (make-variable-buffer-local 'bib-ext-list)
644
645 (defun bib-display ()
646 "Display BibTeX citation or matching \\ref or \\label command under point.
647
648 If text under cursor is a \\cite command, then display its BibTeX info from
649 \\bibliography input file.
650 Example with cursor located over cite command or arguments:
651 \cite{Wadhams81,Bourke.et.al87,SchneiderBudeus94}
652 ^Display-all-citations ^Display-this-citation
653
654 If text under cursor is a \\ref command, then display environment associated
655 with its matching \\label command.
656
657 If text under cursor is a \\label command, then display the text around
658 the first matching \\ref command.
659
660 The user is prompted for a \\label or \\ref is nothing suitable is found under
661 the cursor. The first prompt is for a label. If you answer with an empty
662 string, a second prompt for a ref will be given.
663
664 A TAGS file is created and used for multi-file documents under auctex."
665 (interactive)
666 (let ((cite))
667 (save-excursion
668 (if (not (looking-at "\\\\"))
669 (re-search-backward "[\\]" nil t))
670 (if (looking-at "\\\\[a-zA-Z]*cite")
671 (setq cite t)))
672 (if cite
673 (bib-display-citation)
674 (bib-display-label))))
675
676 (defun bib-find ()
677 "Edit BibTeX citation or find matching \\ref or \\label command under point.
678
679 For multi-entry cite commands, the cursor should be on the actual cite key
680 desired (otherwise a random entry will be selected).
681 e.g.: \cite{Wadhams81,Bourke.et.al87,SchneiderBudeus94}
682 ^Display-this-citation
683
684 If text under cursor is a \\ref command, then point is moved to its matching
685 \\label command.
686
687 If text under cursor is a \\label command, then point is moved to the first
688 matching \\ref command.
689
690 The user is prompted for a \\label or \\ref is nothing suitable is found under
691 the cursor. The first prompt is for a label. If you answer with an empty
692 string, a second prompt for a ref will be given.
693
694 A TAGS file is created and used for multi-file documents under auctex."
695 (interactive)
696 (let ((cite))
697 (save-excursion
698 (if (not (looking-at "\\\\"))
699 (re-search-backward "[ \\\n]" nil t))
700 (if (looking-at "\\\\[a-zA-Z]*cite")
701 (setq cite t)))
702 (if cite
703 (bib-edit-citation)
704 (bib-find-label))))
705
706 (defun bib-display-mouse (EVENT)
707 "Display BibTeX citation or matching \\ref or \\label command under mouse.
708 See bib-display."
709 (interactive "e")
710 (mouse-set-point EVENT)
711 (bib-display))
712
713 (defun bib-find-mouse (EVENT)
714 "Edit BibTeX citation or find matching \\ref or \\label command under mouse.
715 See bib-find."
716 (interactive "e")
717 (mouse-set-point EVENT)
718 (bib-find))
719
720 (defun bib-apropos ()
721 "Display BibTeX entries containing a keyword from bibliography file.
722 The files specified in the \\bibliography command are searched unless
723 the current buffer is in bibtex-mode or is the Help buffer. In those
724 cases, *it* is searched. This allows you to trim down a search further
725 by using bib-apropos sequentially."
726 ;;(interactive "sBibTeX apropos: ")
727 (interactive)
728 (let* ((keylist (and (boundp 'TeX-auto-update) ;Avoid error in FRAMEPOP
729 (fboundp 'LaTeX-bibitem-list) ;Use this if using auctex
730 (LaTeX-bibitem-list)))
731 (keyword (bib-apropos-keyword-at-point))
732 (keyword (completing-read "BiBTeX apropos: " keylist nil nil keyword))
733 (the-text)(key-point)(start-point)
734 (new-buffer-f (and (not (string-match "^bib" mode-name))
735 (not (string-equal "*Help*" (buffer-name)))))
736 (bib-buffer (or (and new-buffer-f (bib-get-bibliography nil))
737 (current-buffer))))
738 (save-excursion
739 (set-buffer bib-buffer)
740 (goto-char (point-min))
741 (while (and (re-search-forward "^[ \t]*@" nil t)
742 (re-search-forward keyword nil t))
743 (setq key-point (point)) ;To make sure this is within entry
744 (re-search-backward "^[ \t]*@" nil t)
745 (setq start-point (point))
746 (forward-list 1)
747 (if (< (point) key-point) ;And this is that test...
748 (goto-char key-point) ;Not within entry, skip it.
749 (setq the-text
750 (cons (concat (buffer-substring start-point (point)) "\n")
751 the-text))))
752 (if (not the-text)
753 (message "Sorry, no matches found.")
754 (with-output-to-temp-buffer "*Help*"
755 (mapcar 'princ (nreverse the-text)))
756 (if bib-novice
757 (message
758 (substitute-command-keys
759 (concat "Use \\[bib-apropos] again in the *help* buffer"
760 " to trim the search"))))
761 (cond
762 ((and bib-hilit-if-available
763 (fboundp 'hilit-highlight-region))
764 (set-buffer "*Help*")
765 (hilit-highlight-region (point-min) (point-max) 'bibtex-mode t))
766 ;; font-lock?
767 ((featurep 'font-lock)
768 (set-buffer "*Help*")
769 (set (make-local-variable 'font-lock-defaults)
770 '(bib-cite-bibtex-font-lock-keywords
771 nil t ((?$ . "\"")(?\" . "."))))
772 (font-lock-fontify-buffer))))
773 (if new-buffer-f
774 (kill-buffer bib-buffer)))))
775
776 (defvar bib-document-citekeys-obarray-warnings nil
777 "bib-cite internal variable")
778
779 (defun bib-make-bibliography ()
780 "Extract citations used in the current document from \bibliography{} file(s).
781 Put them into a buffer named after the current buffer, with extension .bib.
782
783 In an auc-tex multi-file document, parsing must be on and the citation keys
784 are extracted from the .aux files.
785
786 In a plain LaTeX buffer (not multi-file), the cite keys are extracted from
787 the text itself. Therefore the text need not have been previously processed
788 by LaTeX.
789
790 This function is useful when you want to share a LaTeX file, and therefore want
791 to create a bibtex file containing only the references used in the document."
792 (interactive)
793 (let* ((the-keys-obarray (or (bib-document-citekeys-obarray)
794 (bib-buffer-citekeys-obarray)))
795 ;1st in case of error
796 (new-buffer
797 (create-file-buffer
798 (concat (substring (buffer-name) 0
799 (or (string-match "\\." (buffer-name))
800 (length (buffer-name))))
801 "-bib.bib")))
802 (bib-buffer (bib-get-bibliography nil))
803 (the-warnings (bib-get-citations the-keys-obarray
804 bib-buffer
805 new-buffer
806 nil)))
807 (kill-buffer bib-buffer)
808 ;;; (switch-to-buffer new-buffer)
809 (funcall bib-switch-to-buffer-function new-buffer)
810 (bibtex-mode)
811 (cond
812 ((and bib-hilit-if-available
813 (fboundp 'hilit-highlight-region))
814 (hilit-highlight-buffer t))
815 ((featurep 'font-lock) ;Perhaps let the user's setup determine
816 (font-lock-fontify-buffer))) ; if font-lock fontifies?
817 (if (or bib-document-citekeys-obarray-warnings
818 the-warnings)
819 (progn
820 (cond
821 ((and bib-document-citekeys-obarray-warnings the-warnings)
822 (with-output-to-temp-buffer "*Help*"
823 (princ bib-document-citekeys-obarray-warnings the-warnings)))
824 (bib-document-citekeys-obarray-warnings
825 (with-output-to-temp-buffer "*Help*"
826 (princ bib-document-citekeys-obarray-warnings)))
827 (the-warnings
828 (with-output-to-temp-buffer "*Help*" (princ the-warnings))))
829 (setq bib-document-citekeys-obarray-warnings nil) ;Reset
830 (bib-cite-fontify-red)))
831 (if bib-novice
832 (message
833 (substitute-command-keys
834 "Use \\[save-buffer] to save this buffer to a file.")))))
835
836 (defun bib-cite-fontify-red (&optional limit)
837 "Fontify *Help* buffer in red-bold up to optional limit"
838 (if (and window-system ;Not exactly correct for XEmacs
839 (not (facep 'red-bold)))
840 (progn
841 (copy-face 'bold 'red-bold)
842 (set-face-foreground 'red-bold "red")))
843 (save-excursion
844 (set-buffer "*Help*")
845 (let ((before-change-functions) (after-change-functions))
846 (put-text-property (point-min)(or limit (point-max))
847 'face 'red-bold))))
848
849 (defun bib-cite-fontify-help-as-latex ()
850 (save-excursion
851 (cond
852 ((and bib-hilit-if-available
853 (fboundp 'hilit-highlight-region))
854 (set-buffer "*Help*")
855 (hilit-highlight-region (point-min) (point-max) 'LaTeX-mode t))
856 ;; font-lock?
857 ((and (featurep 'font-lock)
858 (featurep 'font-latex))
859 (set-buffer "*Help*")
860 (setq font-lock-defaults '(font-latex-keywords-2 nil nil ((?$ . "\""))))
861 ;; Add all syntax table for `proper' fontification?
862 (font-lock-fontify-buffer))
863 ((featurep 'font-lock)
864 (make-local-variable 'font-lock-defaults)
865 (setq font-lock-defaults '(tex-font-lock-keywords nil nil ((?$ . "\""))))
866 (set-buffer "*Help*")
867 (font-lock-fontify-buffer)))))
868
869 (defvar bib-document-TeX-files-warnings nil
870 "bib-cite internal variable")
871
872 (defun bib-etags (&optional masterdir)
873 "Invoke etags on all tex files of the document, storing the TAGS file
874 in the master-directory. Expect errors if you use this outside of auctex
875 or within a plain single-file document.
876 Also makes sure that the TAGS buffer is updated.
877 See variables bib-etags-command and bib-etags-filename"
878 (interactive)
879 (require 'etags)
880 (let* ((the-file-list (bib-document-TeX-files))
881 (the-file (car the-file-list))
882 (dir (or masterdir (bib-master-directory)))
883 (the-tags-file (expand-file-name bib-etags-filename dir))
884 (the-tags-buffer (get-file-buffer the-tags-file)))
885 ;; Create TAGS file with first TeX file (master file)
886 (shell-command (concat bib-etags-command the-tags-file " " the-file))
887 (setq the-file-list (cdr the-file-list))
888 ;; Append to TAGS file for all other TeX files.
889 (while the-file-list
890 (setq the-file (car the-file-list))
891 (shell-command
892 (concat bib-etags-append-command the-tags-file " " the-file))
893 (setq the-file-list (cdr the-file-list)))
894 (if the-tags-buffer ;buffer existed; we must refresh it.
895 (save-excursion
896 (set-buffer the-tags-buffer)
897 (revert-buffer t t)))
898
899 ;; Check value of tags-file-name against the-tags-file
900 (or (equal the-tags-file tags-file-name) ;make sure it's current
901 (visit-tags-table the-tags-file))
902
903 ;(set (make-local-variable 'tags-file-name) the-tags-file))
904 ;; above should not be needed
905
906 ;; Weird Bug:
907 ;; (visit-tags-table-buffer) seems to get called twice when called by
908 ;; find-tag on an undefined tag. The second time, it's in the TAGS
909 ;; buffer and returns an error because TAGS buffer does have
910 ;; tags-file-name set.
911 ;; To get around this. I'm setting this variable in the TAGS buffer.
912 ;; Skip this in XEmacs (Changed by Anders Stenman)
913 (if (not (string-match "XEmacs\\|Lucid" emacs-version))
914 (save-excursion
915 (set-buffer (get-file-buffer the-tags-file))
916 (set (make-local-variable 'tags-file-name) the-tags-file))))
917
918
919 (if bib-document-TeX-files-warnings ;free variable loose in emacs!
920 (progn
921 (with-output-to-temp-buffer "*Help*"
922 (princ bib-document-TeX-files-warnings))
923 (setq bib-document-TeX-files-warnings nil) ;Reset
924 (bib-cite-fontify-red)
925 ;;;(if (and bib-hilit-if-available
926 ;;; (fboundp 'hilit-region-set-face))
927 ;;; (save-excursion
928 ;;; (set-buffer "*Help*")
929 ;;; (hilit-region-set-face
930 ;;; 1 (point-max)
931 ;;; (cdr (assq 'error hilit-face-translation-table)))))
932 )))
933
934 (defun bib-Is-hidden ()
935 "Return true is current point is hidden"
936 (if (not selective-display)
937 nil ;Not hidden if not using this...
938 (save-excursion
939 (if (not (re-search-backward "[\n\^M]" nil t))
940 nil ;Play safe
941 (if (string-equal (buffer-substring (match-beginning 0)(match-end 0))
942 "\n")
943 nil
944 t)))))
945
946 (defun bib-highlight-mouse ()
947 "Make that nice green highlight when the mouse is over LaTeX commands"
948 (interactive)
949 ;;;Comment this out. User should be able to use bib-highlight-mouse
950 ;;;to try it out regardless of bib-highlight-mouse-t.
951 ;;;Check bib-highlight-mouse-t only in automated cases.
952 ;;;
953 ;;; (if (and bib-highlight-mouse-t
954 ;;; ;;window-system) ;Do nothing unless under X
955 ;;; )
956 ;;; *all of code was here*
957 ;;; )
958 (save-excursion
959 (let ((s)(e)(extent)
960 (inhibit-read-only t)
961 (modified (buffer-modified-p))) ;put-text-property changing this?
962 (goto-char (point-min))
963 ;; * peta Wed Nov 8 16:27:29 1995 -- better remove the mouse face
964 ;; properties first.
965 (if (string-match "XEmacs\\|Lucid" emacs-version)
966 (while bib-ext-list
967 (delete-extent (car bib-ext-list))
968 (setq bib-ext-list (cdr bib-ext-list)))
969 ;; Remove properties for regular emacs
970 ;; FIXME This detroys all mouse-faces and local-maps!
971 ;; FIXME Hope no other package is using them in this buffer!
972 (let ((before-change-functions) (after-change-functions))
973 (remove-text-properties (point-min) (point-max)
974 '(mouse-face t local-map t))))
975 (while
976 (re-search-forward
977 "\\\\\\(ref\\|label\\|[A-Za-z]*cite[A-Za-z]*\\(\\[.*\\]\\)?\\){[^}]*}"
978 nil t)
979 (setq s (match-beginning 0))
980 (setq e (match-end 0))
981 (cond
982 ((string-match "XEmacs\\|Lucid" emacs-version)
983 (setq extent (make-extent s e))
984 (setq bib-ext-list (cons extent bib-ext-list))
985 (set-extent-property extent 'highlight t)
986 (set-extent-property extent 'start-open t)
987 (set-extent-property extent 'keymap bib-highlight-mouse-keymap))
988 (t
989 (let ((before-change-functions) (after-change-functions)
990 ;;(this-overlay (make-overlay s e))
991 )
992 ;;; Even using overlays doens't help here. If bib-highlight-mouse-keymap
993 ;;; does not include the AucTeX menus, then these disappear when we click
994 ;;; onto a \cite command. Perhaps using bib-cite as a minor mode will fix
995 ;;; this? For now, bib-cite must be loaded after these menus are built.
996 ;;; It must therefore be loaded in a mode-hook.
997 (put-text-property s e 'local-map bib-highlight-mouse-keymap)
998 (put-text-property s e 'mouse-face 'highlight)
999 ;;(overlay-put this-overlay 'local-map bib-highlight-mouse-keymap)
1000 ;;(overlay-put this-overlay 'mouse-face 'highlight)
1001 ))))
1002 (set-buffer-modified-p modified))))
1003
1004 (defun bib-toggle-highlight ()
1005 (interactive)
1006 (if (setq bib-highlight-mouse-t (not bib-highlight-mouse-t))
1007 (bib-highlight-mouse)
1008 (let ((modified (buffer-modified-p))
1009 (inhibit-read-only t))
1010 (cond
1011 ((string-match "XEmacs\\|Lucid" emacs-version)
1012 (while bib-ext-list
1013 (delete-extent (car bib-ext-list))
1014 (setq bib-ext-list (cdr bib-ext-list))))
1015 (t
1016 (let ((before-change-functions) (after-change-functions))
1017 (remove-text-properties (point-min) (point-max)
1018 '(mouse-face local-map)))))
1019 (set-buffer-modified-p modified))))
1020
1021 ;;----------------------------------------------------------------------------
1022 ;; Routines to display or edit a citation's bibliography
1023
1024 (defun bib-display-citation ()
1025 "Do the displaying of cite info. Returns t if found cite key, nil otherwise.
1026 Example with cursor located over cite command or arguments:
1027 \cite{Wadhams81,Bourke.et.al87,SchneiderBudeus94}
1028 ^Display-all-citations ^Display-this-citation"
1029 (save-excursion
1030 (let* ((the-keys-obarray (bib-get-citekeys-obarray)) ;1st in case of error
1031 (work-buffer (get-buffer-create "*bibtex-work*"))
1032 (bib-buffer (bib-get-bibliography nil))
1033 (the-warnings (bib-get-citations
1034 the-keys-obarray
1035 bib-buffer
1036 work-buffer
1037 bib-substitute-string-in-display))
1038 (the-warn-point))
1039 (if the-warnings
1040 (progn
1041 (set-buffer work-buffer)
1042 (goto-char 1)
1043 (insert the-warnings)
1044 (setq the-warn-point (point))))
1045 (with-output-to-temp-buffer
1046 "*Help*"
1047 (set-buffer work-buffer)
1048 (princ (buffer-substring 1 (point-max))))
1049 (cond
1050 ((and bib-hilit-if-available
1051 (fboundp 'hilit-highlight-region))
1052 (set-buffer "*Help*")
1053 (hilit-highlight-region (point-min) (point-max) 'bibtex-mode t)
1054 (if the-warn-point
1055 (hilit-region-set-face
1056 1 the-warn-point
1057 (cdr (assq 'error hilit-face-translation-table)))))
1058 ((featurep 'font-lock)
1059 (set-buffer "*Help*")
1060 (set (make-local-variable 'font-lock-defaults)
1061 '(bib-cite-bibtex-font-lock-keywords
1062 nil t ((?$ . "\"")(?\" . "."))))
1063 (font-lock-fontify-buffer)
1064 (if the-warn-point
1065 (bib-cite-fontify-red the-warn-point))))
1066 (kill-buffer bib-buffer)
1067 (kill-buffer work-buffer))))
1068
1069 (defun bib-edit-citation ()
1070 "Do the edit of cite info. Returns t if found cite key, nil otherwise.
1071 Find and and put edit point in bib file associated with a BibTeX citation
1072 under cursor from \bibliography input file.
1073 In a multi-entry cite command, the cursor should be on the actual cite key
1074 desired (otherwise a random entry will be selected).
1075 e.g.: \cite{Wadhams81,Bourke.et.al87,SchneiderBudeus94}
1076 ^Display-this-citation"
1077 (let ((the-keys-obarray (bib-get-citekeys-obarray)) ;1st in case of error
1078 (bib-buffer (bib-get-bibliography t))
1079 (the-key)(the-file))
1080 (save-excursion
1081 (mapatoms ;Do this for each cite-key found...
1082 (function (lambda (cite-key)
1083 (setq the-key (symbol-name cite-key))))
1084 the-keys-obarray)
1085 (set-buffer bib-buffer)
1086 (goto-char (point-min))
1087 (if (not (re-search-forward
1088 (concat "@[^{(]+[{(][\t ]*" the-key "[ ,\n]") nil t))
1089 (progn
1090 (kill-buffer bib-buffer)
1091 (error "Sorry, could not find bib entry for %s" the-key))
1092 (re-search-backward "%%%Filename: \\([^\n]*\\)" nil t)
1093 (setq the-file (buffer-substring (match-beginning 1)(match-end 1)))
1094 (kill-buffer bib-buffer)))
1095 ;;; (find-file the-file)
1096 (funcall bib-switch-to-buffer-function (find-file-noselect the-file))
1097 (goto-char (point-min)) ;V2.19 fix
1098 (re-search-forward (concat "@[^{(]+[{(][\t ]*" the-key "[ ,\n]") nil t)))
1099
1100 ;;--------------------------------------------------------------------------
1101 ;; Function for bib-apropos
1102
1103 (defun bib-apropos-keyword-at-point ()
1104 ;; Returns the keyword under point for initial input to bib-apropos prompt
1105 (save-excursion
1106 (let ((here (point)))
1107 (cond
1108 ((and (re-search-backward "[\n{, ]" nil t)
1109 (string-equal "{" (buffer-substring (match-beginning 0)
1110 (match-end 0))))
1111 (if (fboundp 'buffer-substring-no-properties)
1112 (buffer-substring-no-properties (1+ (point)) here)
1113 (buffer-substring (1+ (point)) here)))))))
1114
1115 ;;--------------------------------------------------------------------------
1116 ;; Functions for Displaying or moving to matching \ref or \label command
1117
1118 (defun bib-display-label ()
1119 ;; "Display environment associated with a label or first ref assoc. with label
1120 ;;The label or ref name is extracted from the text under the cursor, or the
1121 ;;user is prompted is nothing suitable is found. The first prompt is for a
1122 ;;label. If you answer with an empty string, a second prompt for a ref will
1123 ;;be given."
1124 (let ((the-name (bib-guess-or-prompt-for-label)))
1125 (if (not the-name)
1126 (message "No name given")
1127 (bib-display-or-find-label the-name t))))
1128
1129 (defun bib-find-label ()
1130 "Move to a label, or the first occurance of a ref.
1131 The label or ref name is extracted from the text under the cursor.
1132 ;;If nothing suitable is found, the user is prompted. The first prompt is for a
1133 ;;label. If you answer with an empty string, a second prompt for a ref will be
1134 ;;given.
1135 ;;
1136 ;;If within a single file document:
1137 ;; You can move back with C-x C-x as the mark is set before moving.
1138 ;; You can search for next occurrances of a ref command with C-s C-s.
1139 ;;
1140 ;;If within a multi-file document (in auctex only)
1141 ;; You can move back with C-x C-x if within the same buffer. If not, just
1142 ;; select your previous buffer.
1143 ;; You can search for next occurrances of a ref command with tag commands:
1144 ;; C-u M-. Find next alternate definition of last tag specified.
1145 ;; C-u - M-. Go back to previous tag found."
1146 (let ((the-name (bib-guess-or-prompt-for-label)))
1147 (if (not the-name)
1148 (message "No name given")
1149 (bib-display-or-find-label the-name nil))))
1150
1151 ;;--------------------------------------------------------------------------
1152 ;; Functions for Displaying or moving to matching \ref or \label command
1153
1154 (defun bib-display-or-find-label (the-name displayf)
1155 ;; work horse for bib-find-label and bib-display-label
1156 (let* ((masterfile (bib-master-file))
1157 (masterdir (and masterfile
1158 (file-name-directory masterfile)))
1159 (new-point)(new-buffer))
1160 (save-excursion
1161 ;; Now we are either in a simple file, or with a multi-file document
1162 (cond
1163 (masterfile ;Multi-file document
1164 (cond
1165 (displayf ;Display only
1166 (set-buffer (bib-etags-find-noselect the-name masterdir))
1167 (re-search-forward the-name nil t) ;'cos tags puts point line begin
1168 (if (string-match "^\\\\label" the-name)
1169 (bib-display-this-environment) ;display the label's environment
1170 (bib-display-this-ref))) ; display the ref's context
1171 (t ;Move to it
1172 (setq new-buffer (bib-etags-find-noselect the-name masterdir))
1173 (if bib-novice
1174 (message
1175 (substitute-command-keys
1176 (concat "Use C-u \\[find-tag] to find the next occurrence; "
1177 "Use C-u - \\[find-tag] to find the previous."))))
1178 (if (equal new-buffer (current-buffer))
1179 (setq new-point (point))) ;Moving with the same buffer
1180 (and (string-match "^\\\\ref" the-name)
1181 (setq search-ring (cons the-name search-ring))))))
1182 (t ;Single-file document
1183 (goto-char (point-min))
1184 (if (search-forward the-name nil t)
1185 (if displayf
1186 (if (string-match "^\\\\label" the-name)
1187 (bib-display-this-environment) ;Display the environment
1188 (bib-display-this-ref)) ; display the ref's context
1189 (setq new-point (match-beginning 0)) ;or move there
1190 (if bib-novice
1191 (message
1192 (substitute-command-keys
1193 (concat
1194 "Use \\[isearch-forward] \\[isearch-forward] to find the "
1195 "next occurrence; Use C-x C-x to go back."))))
1196 (if (string-match "^\\\\ref" the-name)
1197 (setq search-ring (cons the-name search-ring))
1198 (setq search-ring (cons (concat "\\ref" (substring the-name 6))
1199 search-ring))))
1200 (message "Sorry, cannot find %s" the-name)))))
1201 (if new-point
1202 (progn
1203 (push-mark (point) t nil) ;We've moving there... push mark
1204 (goto-char new-point))
1205 (if new-buffer ;We've changing buffer
1206 ;; (switch-to-buffer new-buffer)
1207 (funcall bib-switch-to-buffer-function new-buffer)))
1208 (if (bib-Is-hidden)
1209 (save-excursion
1210 (beginning-of-line)
1211 (show-entry)))))
1212
1213 (defvar bib-label-prompt-map nil)
1214 (if bib-label-prompt-map
1215 ()
1216 (setq bib-label-prompt-map (copy-keymap minibuffer-local-completion-map))
1217 (define-key bib-label-prompt-map " " 'self-insert-command))
1218
1219 (defun bib-guess-or-prompt-for-label ()
1220 ;; Guess from context, or prompt the user for a label command
1221 (save-excursion
1222 (if (not (looking-at "\\\\")) ;If not on beginning of a command
1223 (re-search-backward "[\\]"
1224 (save-excursion (beginning-of-line)(point))
1225 t))
1226 (cond
1227 ((looking-at "\\\\ref{") ;On \ref, looking for matching \label
1228 (let ((b (progn (search-forward "{" nil t)(forward-char -1)(point)))
1229 (e (progn (forward-sexp 1)(point))))
1230 (concat "\\label" (buffer-substring b e))))
1231 ((looking-at "\\\\label{") ;On \label, looking for matching \ref
1232 (let ((b (progn (search-forward "{" nil t)(forward-char -1)(point)))
1233 (e (progn (forward-sexp 1)(point))))
1234 (concat "\\ref" (buffer-substring b e))))
1235 (t ;Prompt the user
1236 (let* ((minibuffer-local-completion-map bib-label-prompt-map)
1237 (the-alist (create-alist-from-list
1238 (cdr (reverse LaTeX-label-list))))
1239 ;;; LaTeX-label-list example:
1240 ;;; '(("label3" "label4")("label1" "label2") nil)
1241 ;; so let's get rid of that nil part in embedded list.
1242 (the-name
1243 (if (string-equal "18" (substring emacs-version 0 2))
1244 (completing-read "Label: " the-alist nil nil nil)
1245 (completing-read "Label: " the-alist nil nil nil
1246 'LaTeX-find-label-hist-alist))))
1247 (if (not (equal the-name ""))
1248 (concat "\\label{" the-name "}")
1249 ;; else try to get a \ref
1250 (if (string-equal "18" (substring emacs-version 0 2))
1251 (setq the-name (completing-read "Ref: " the-alist nil nil nil))
1252 (setq the-name (completing-read "Ref: " the-alist nil nil nil
1253 'LaTeX-find-label-hist-alist)))
1254 (if (not (equal the-name ""))
1255 (concat "\\ref{" the-name "}")
1256 nil)))))))
1257
1258 (defun bib-display-this-ref ()
1259 "Display a few lines around current point"
1260 (cond
1261 ((bib-Is-hidden)
1262 (with-output-to-temp-buffer "*BiBTemp*"
1263 (princ
1264 (buffer-substring
1265 (save-excursion
1266 (let ((i 3))
1267 (while (and (> i 0)
1268 (re-search-backward "[\n\^M]" nil t)
1269 (setq i (1- i)))))
1270 (point))
1271 (save-excursion
1272 (let ((i 3))
1273 (while (and (> i 0)
1274 (re-search-forward "[\n\^M]" nil t)
1275 (setq i (1- i)))))
1276 (point)))))
1277 (set-buffer "*BiBTemp*")
1278 (while (search-forward "\^M" nil t)
1279 (replace-match "\n" nil t))
1280 (goto-char 1)
1281 (if (looking-at "\n") ;Remove first empty line...
1282 (delete-char 1))
1283 (with-output-to-temp-buffer "*Help*"
1284 (princ (buffer-substring 1 (point-max))))
1285 (bib-cite-fontify-help-as-latex)
1286 (kill-buffer "*BiBTemp*"))
1287 (t
1288 (with-output-to-temp-buffer ; display the ref's context
1289 "*Help*"
1290 (princ
1291 (buffer-substring (save-excursion (forward-line -2)(point))
1292 (save-excursion (forward-line 3)(point)))))
1293 (bib-cite-fontify-help-as-latex))))
1294
1295 (defun bib-display-this-environment ()
1296 "Display the environment associated with a label, or its section name
1297 Assumes point is already on the label.
1298 Does not save excursion."
1299 ;; Bugs: The method used here to detect the environment is *not* foolproof.
1300 ;; It will get confused, for example, between two figure environments,
1301 ;; picking out both instead of the section label above them. But since
1302 ;; users typically puts their labels next to the section declaration,
1303 ;; I'm satisfied with this... for now.
1304 ;; I could have used the following auc-tex functions:
1305 ;; LaTeX-current-environment
1306 ;; Function: Return the name (a string) of the enclosing LaTeX environment.
1307 ;; LaTeX-current-section
1308 ;; Function: Return the level of the section that contain point.
1309 ;; but then this code would only work as part of auc-tex...
1310 (let ((the-point (point))
1311 (end-point (point))
1312 (the-environment)(foundf))
1313 (while (and (not foundf)
1314 (goto-char end-point) ;Past end of last search
1315 (re-search-forward "\\(^\\|\^M\\)[ \t]*\\\\end{\\([^}]*\\)}"
1316 nil t))
1317 (setq end-point (point))
1318 (setq the-environment (buffer-substring (match-beginning 2)
1319 (match-end 2)))
1320 (and (not (string-match "document" the-environment))
1321 (re-search-backward (concat "\\(^\\|\^M\\)[ \t]*\\\\begin{"
1322 (regexp-quote the-environment) "}"))
1323 (<= (point) the-point)
1324 (setq foundf t)))
1325 (if foundf ;A good environment
1326 (progn
1327 (cond ((bib-Is-hidden) ;Better way is: replace-within-string
1328 (with-output-to-temp-buffer "*BiBTemp*"
1329 (princ (buffer-substring (point) end-point)))
1330 (set-buffer "*BiBTemp*")
1331 (while (search-forward "\^M" nil t)
1332 (replace-match "\n" nil t))
1333 (goto-char 1)
1334 (if (looking-at "\n") ;Remove first empty line...
1335 (delete-char 1))
1336 (with-output-to-temp-buffer "*Help*"
1337 (princ (buffer-substring 1 (point-max))))
1338 (kill-buffer "*BiBTemp*"))
1339 (t
1340 (with-output-to-temp-buffer "*Help*"
1341 (princ (buffer-substring (point) end-point)))))
1342 (bib-cite-fontify-help-as-latex))
1343 ;; Just find the section declaration
1344 (goto-char the-point)
1345 (if (re-search-backward
1346 "\\(^\\|\^M\\)[ \t]*\\\\\\(sub\\)*section{\\([^}]*\\)}" nil t)
1347 (message (buffer-substring (match-beginning 0)(match-end 0)))
1348 (error
1349 "Sorry, could not find an environment or section declaration")))))
1350
1351 (defvar LaTeX-find-label-hist-alist nil "History list for LaTeX-find-label")
1352 (defvar LaTeX-label-list nil "Used by auc-tex to store label names")
1353
1354
1355 (defun create-alist-from-list (the-list)
1356 ;;; Return a single list from a list that may contain either items
1357 ;;; or any number of list levels containing items.
1358 ;;; e.g. turns
1359 ;;; '(("label3" "label4")("label1" "label2") "label")
1360 ;;; into
1361 ;;; '(("label3") ("label4") ("label1") ("label2") ("label"))
1362 (mapcar 'list (bib-cite-mh-list-to-string the-list)))
1363
1364 ;;;
1365 ;;; Following two functions from mh-utils.el (part of GNU emacs)
1366 ;;; I have changed the names in case these functions change what they do.
1367 ;;;
1368
1369 (defun bib-cite-mh-list-to-string (l)
1370 ;; Flattens the list L and makes every element of the new list into a string.
1371 (nreverse (bib-cite-mh-list-to-string-1 l)))
1372
1373 (defun bib-cite-mh-list-to-string-1 (l)
1374 (let ((new-list nil))
1375 (while l
1376 (cond ((null (car l)))
1377 ((symbolp (car l))
1378 (setq new-list (cons (symbol-name (car l)) new-list)))
1379 ((numberp (car l))
1380 (setq new-list (cons (int-to-string (car l)) new-list)))
1381 ((equal (car l) ""))
1382 ((stringp (car l)) (setq new-list (cons (car l) new-list)))
1383 ((listp (car l))
1384 (setq new-list (nconc (bib-cite-mh-list-to-string-1 (car l))
1385 new-list)))
1386 (t (error "Bad element in mh-list-to-string: %s" (car l))))
1387 (setq l (cdr l)))
1388 new-list))
1389
1390 ;; -------------------------------------------------------------------------
1391 ;; Routines to extract cite keys from text
1392
1393 ;; ... is truly remarkable, as shown in \citeN{Thomson77,Test56}. Every
1394 ;; \cite[{\it e.g.}]{Thomson77,Test56}
1395
1396 (defun bib-get-citations (keys-obarray bib-buffer new-buffer substitute)
1397 "Put citations of KEYS-OBARRAY from BIB-BUFFER into NEW-BUFFER,
1398 Substitute strings if SUBSTITUTE is t
1399 Return the-warnings as text."
1400 (let ((the-warnings) ;The only variable to remember...
1401 (case-fold-search t)) ;All other results go into new-buffer
1402 ;; bibtex is not case-sensitive for keys.
1403 (save-excursion
1404 (let ((the-text))
1405 (set-buffer bib-buffer)
1406 (mapatoms ;Do this for each cite-key found...
1407 (function
1408 (lambda (cite-key)
1409 (goto-char (point-min))
1410 (if (re-search-forward
1411 (concat "@[^{(]+[{(][\t ]*"
1412 (regexp-quote (symbol-name cite-key))
1413 "\\([, ]\\\|$\\)")
1414 ;; ^^ ^ comma, space or end-of-line
1415 nil t)
1416 (setq the-text (concat the-text
1417 (buffer-substring
1418 (progn (beginning-of-line)(point))
1419 (progn (forward-sexp 2)(point)))
1420 "\n\n"))
1421 (setq the-warnings (concat the-warnings
1422 "Cannot find entry for: "
1423 (symbol-name cite-key) "\n")))))
1424 keys-obarray)
1425 (if (not the-text)
1426 (error "Sorry, could not find any of the references"))
1427 ;; Insert the citations in the new buffer
1428 (set-buffer new-buffer)
1429 (insert the-text)
1430 (goto-char 1))
1431
1432 ;; We are at beginning of new-buffer.
1433 ;; Now handle crossrefs
1434 (let ((crossref-obarray (make-vector 201 0)))
1435 (while (re-search-forward
1436 "[, \t]*crossref[ \t]*=[ \t]*\\(\"\\|\{\\)" nil t)
1437 ;;handle {text} or "text" cases
1438 (if (string-equal "{" (buffer-substring (match-beginning 1)
1439 (match-end 1)))
1440 (re-search-forward "[^\}]+" nil t)
1441 (re-search-forward "[^\"]+" nil t))
1442 (intern (buffer-substring (match-beginning 0)(match-end 0))
1443 crossref-obarray))
1444 ;; Now find the corresponding keys,
1445 ;; but add them only if not already in `keys-obarray'
1446 (set-buffer bib-buffer)
1447 (goto-char 1)
1448 (let ((the-text))
1449 (mapatoms ;Do this for each crossref key found...
1450 (function
1451 (lambda (crossref-key)
1452 (if (not (intern-soft (symbol-name crossref-key) keys-obarray))
1453 (progn
1454 ;; Not in keys-obarray, so not yet displayed.
1455 (goto-char (point-min))
1456 (if (re-search-forward
1457 (concat "@[^{(]+[{(][\t ]*"
1458 (regexp-quote (symbol-name crossref-key))
1459 "\\(,\\|$\\)")
1460 nil t)
1461 (setq the-text
1462 (concat the-text
1463 (buffer-substring
1464 (progn (beginning-of-line)(point))
1465 (progn (forward-sexp 2)(point)))
1466 "\n\n"))
1467 (setq the-warnings
1468 (concat the-warnings
1469 "Cannot find crossref entry for: "
1470 (symbol-name crossref-key) "\n")))))))
1471 crossref-obarray)
1472 ;; Insert the citations in the new buffer
1473 (set-buffer new-buffer)
1474 (goto-char (point-max))
1475 (if the-text
1476 (insert the-text)))
1477 (goto-char 1))
1478
1479 ;; Now we have all citations in new-buffer, collect all used @String keys
1480 ;; Ex: journal = JPO,
1481 (let ((strings-obarray (make-vector 201 0)))
1482 (while (re-search-forward bib-string-regexp nil t)
1483 (intern (buffer-substring (match-beginning 1)(match-end 1))
1484 strings-obarray))
1485 ;; Now find the corresponding @String commands
1486 ;; Collect either the @string commands, or the string to substitute
1487 (set-buffer bib-buffer)
1488 (goto-char 1)
1489 (let ((string-alist)
1490 (the-text))
1491 (mapatoms ;Do this for each string-key found...
1492 (function
1493 (lambda (string-key)
1494 (goto-char (point-min))
1495 ;; search for @string{ key = {text}} or @string{ key = "text"}
1496 (if (re-search-forward
1497 (concat "^[ \t]*@string[{(]"
1498 (regexp-quote (symbol-name string-key))
1499 "[\t ]*=[\t ]*\\(\"\\|\{\\)")
1500 nil t)
1501 (let ((the-string-start (1- (match-end 1))) ;catch bracket
1502 ;;handle {text} or "text" cases
1503 (the-string-end
1504 (cond
1505 ((string-equal "\""
1506 (buffer-substring (match-beginning 1)
1507 (match-end 1)))
1508
1509 (re-search-forward "[^\\]\"" nil t)
1510 (point))
1511 (t
1512 (forward-char -1)
1513 (forward-list 1)
1514 (point)))))
1515 (if substitute ;Collect substitutions
1516 (setq string-alist
1517 (append
1518 string-alist
1519 (list
1520 (cons (symbol-name string-key)
1521 (regexp-quote
1522 (buffer-substring the-string-start
1523 the-string-end))))))
1524 ;;Collect the strings command themseves
1525 (setq the-text
1526 (concat the-text
1527 (buffer-substring
1528 (progn (forward-char 1)(point))
1529 (re-search-backward "^[ \t]*@string[{(]"
1530 nil t))
1531 "\n"))))
1532 ;; @string entry not found
1533 (if (not (member (symbol-name string-key)
1534 bib-string-ignored-warning))
1535 (setq the-warnings
1536 (concat the-warnings
1537 "Cannot find @String entry for: "
1538 (symbol-name string-key) "\n"))))))
1539 strings-obarray)
1540 ;; Now we have `the-text' of @string commands,
1541 ;; or the `string-alist' to substitute.
1542 (set-buffer new-buffer)
1543 (if substitute
1544 (while string-alist
1545 (goto-char 1)
1546 (let ((the-key (car (car string-alist)))
1547 (the-string (cdr (car string-alist))))
1548 (while (re-search-forward
1549 (concat "\\(^[, \t]*[a-zA-Z]+[ \t]*=[ \t]*\\)"
1550 the-key
1551 "\\([, \t\n]\\)")
1552 nil t)
1553 (replace-match (concat "\\1" the-string "\\2") t)))
1554 (setq string-alist (cdr string-alist)))
1555 ;; substitute is nil; Simply insert text of @string commands
1556 (goto-char 1)
1557 (if the-text
1558 (insert the-text "\n")))
1559 (goto-char 1))))
1560
1561 ;; We are done!
1562 ;; Return the warnings...
1563 the-warnings))
1564
1565 (defun bib-get-citekeys-obarray ()
1566 "Return obarray of citation key (within curly brackets) under cursor."
1567 (save-excursion
1568 ;; First find *only* a key *within a cite command
1569 (let ((the-point (point))
1570 (keys-obarray (make-vector 201 0)))
1571 ;; First try to match a cite command
1572 (if (and (skip-chars-backward "a-zA-Z") ;Stops on \ or {
1573 (looking-at "[a-zA-Z]*cite[a-zA-Z]*"))
1574 (progn
1575 ;;skip over any optional arguments to \cite[][]{key} command
1576 (skip-chars-forward "a-zA-Z")
1577 (while (looking-at "\\[")
1578 (forward-list 1))
1579 (re-search-forward "{[ \n]*\\([^,} \n]+\\)" nil t)
1580 (intern (buffer-substring (match-beginning 1)(match-end 1))
1581 keys-obarray)
1582 (while (and (skip-chars-forward " \n") ;no effect on while
1583 (looking-at ","))
1584 (forward-char 1)
1585 ;;The following re-search skips over leading spaces
1586 (re-search-forward "\\([^,} \n]+\\)" nil t)
1587 (intern (buffer-substring (match-beginning 1)(match-end 1))
1588 keys-obarray)))
1589
1590 ;; Assume we are on the keyword
1591 (goto-char the-point)
1592 (let ((the-start (re-search-backward "[\n{, ]" nil t))
1593 (the-end (progn (goto-char the-point)
1594 (re-search-forward "[\n}, ]" nil t))))
1595 (if (and the-start the-end)
1596 (intern (buffer-substring (1+ the-start) (1- the-end))
1597 keys-obarray)
1598 ;; Neither...
1599 (error "Sorry, can't find a reference here"))))
1600 keys-obarray)))
1601
1602 (defun bib-buffer-citekeys-obarray ()
1603 "Extract citations keys used in the current buffer"
1604 (let ((keys-obarray (make-vector 201 0)))
1605 (save-excursion
1606 (goto-char (point-min))
1607 ;; Following must allow for \cite[e.g.][]{key} !!!
1608 ;; regexp for \cite{key1,key2} was "\\\\[a-Z]*cite[a-Z]*{\\([^,}]+\\)"
1609 (while (re-search-forward "\\\\[a-zA-Z]*cite[a-zA-Z]*\\(\\[\\|{\\)"
1610 nil t)
1611 (backward-char 1)
1612 (while (looking-at "\\[") ; ...so skip all bracketted options
1613 (forward-sexp 1))
1614 ;; then lookup first key
1615 (if (looking-at "{[ \n]*\\([^,} \n]+\\)")
1616 (progn
1617 (intern (buffer-substring (match-beginning 1)(match-end 1))
1618 keys-obarray)
1619 (goto-char (match-end 1))
1620 (while (and (skip-chars-forward " \n")
1621 (looking-at ","))
1622 (forward-char 1)
1623 (re-search-forward "\\([^,} \n]+\\)" nil t)
1624 (intern (buffer-substring (match-beginning 1)(match-end 1))
1625 keys-obarray)))))
1626 (if keys-obarray
1627 keys-obarray
1628 (error "Sorry, could not find any citation keys in this buffer.")))))
1629
1630 ;;---------------------------------------------------------------------------
1631 ;; Multi-file document programming requirements:
1632 ;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1633 ;; bib-make-bibliography
1634 ;; bib-document-citekeys-obarray needs the master .aux file to extract
1635 ;; citation keys.
1636 ;; Included .aux files (corresponding to \include'd LaTeX files) are
1637 ;; then specified relative to the master-file-directory.
1638 ;;
1639 ;; bib-get-bibliography (used by interactive commands to extract bib sources)
1640 ;;
1641 ;; bibtex source filenames are returned from (LaTeX-bibliography-list)
1642 ;; unformatted. Since only a single \bibliogragrphy command is allowed
1643 ;; by BiBTeX in a document, it is safe to assume that their path is
1644 ;; relative to the master file's directory (since the path is relative
1645 ;; to where the BiBTeX program is actually ran).
1646 ;;
1647 ;; imenu
1648 ;;
1649 ;; Requires list of all tex files (complete with paths) to call etags on
1650 ;; them.
1651 ;; I used (TeX-style-list) to get the list of possible tex files, but
1652 ;; they are not in sorted order. Therefore the imenu would be somewhat
1653 ;; confusing. I'll have to do the scan myself, except that I'll only be
1654 ;; looking at the master file for \include statements.
1655
1656 ;; (See TeX-check-files, used in TeX-save-document. All documents related
1657 ;; files are returned by (TeX-style-list) and stored in TeX-active-styles.
1658 ;; Original idea was to search TeX-check-path for files listed in
1659 ;; TeX-active-styles (with possible relative or full paths) that end in .tex.)
1660
1661 (defun bib-master-directory ()
1662 ;; Returns the directory associated with the master file.
1663 ;; If no master file, then return current default.
1664 (let ((masterfile (bib-master-file)))
1665 (if masterfile
1666 (file-name-directory (expand-file-name (TeX-master-file)))
1667 default-directory)))
1668
1669 (defun bib-master-file ()
1670 ;; return master file full path, or nil if not a multi-file document
1671 ;; I wish there were a better way to tell about non multi-file documents...
1672 (let ((master
1673 (cond
1674 ((not (boundp 'TeX-master))
1675 ;; This buffer doesn't know what a master file is, so return now.
1676 nil)
1677 ((and TeX-master ;Set, but not to t
1678 (not (eq TeX-master 't))) ; then we have an actual name
1679 (expand-file-name TeX-master))
1680 ((and (eq TeX-master 't) ;Test if master file itself
1681 (progn ;But also require at least one \include
1682 (save-excursion
1683 (goto-char 1) ;Too bad I have to do this search...
1684 ;; Require that user uses \input{file}
1685 ;; rather than \input file
1686 (re-search-forward "^[ \t]*\\\\\\(include\\|input\\){"
1687 nil t))))
1688 (buffer-file-name))
1689 (t
1690 nil))))
1691 (cond
1692 ((not master)
1693 nil)
1694 ((string-match ".tex$" master)
1695 master)
1696 (t
1697 (concat master ".tex")))))
1698
1699 ;; I don't use this one because files are not returned in order...
1700 ;; (defun bib-document-TeX-files ()
1701 ;; ;; Return all tex input files associated with a known multi-file document.
1702 ;; (let ((master-directory (bib-master-directory))
1703 ;; (the-list (cons (file-name-nondirectory (TeX-master-file))
1704 ;; (TeX-style-list)))
1705 ;; ;; TeX-style-list returns "../master" for the main file if TeX-master
1706 ;; ;; was set like that. "../master" would not be found relative
1707 ;; ;; to the master-directory! So let's add it to the list w/o directory.
1708 ;; (the-result)
1709 ;; (the-file))
1710 ;; (while the-list
1711 ;; (setq the-file (expand-file-name (car the-list) master-directory))
1712 ;; (setq the-list (cdr the-list))
1713 ;; (and (not (string-match ".tex$" the-file))
1714 ;; (setq the-file (concat the-file ".tex")))
1715 ;; (and (file-readable-p the-file)
1716 ;; (not (member the-file the-result)) ;listed already?
1717 ;; (setq the-result (cons the-file the-result))))
1718 ;; the-result))
1719
1720 (defun bib-document-TeX-files ()
1721 ;; For a multi-file document in auctex only.
1722 ;; Return all tex input files associated with a *known* multi-file document.
1723 ;; No checking is done that this is a real multi-file document.
1724
1725 ;; sets global variable bib-document-TeX-files-warnings
1726
1727 (setq bib-document-TeX-files-warnings nil)
1728 (let* ((masterfile (bib-master-file))
1729 (dir (and masterfile (file-name-directory masterfile)))
1730 (tex-buffer (get-buffer-create "*tex-document*"))
1731 (the-list (list masterfile))
1732 (the-file))
1733 (if (not masterfile)
1734 (progn
1735 (kill-buffer tex-buffer)
1736 (error
1737 "Sorry, but this is not a multi-file document (Try C-u C-c C-n if using auctex)")))
1738 (save-excursion
1739 (set-buffer tex-buffer)
1740 ;; set its directory so relative includes work without expanding
1741 (setq default-directory dir)
1742 (insert-file-contents masterfile)
1743 (goto-char (point-min))
1744 (while (re-search-forward "^[ \t]*\\\\\\(input\\|include\\){\\(.*\\)}"
1745 nil t)
1746 (let ((the-file (buffer-substring (match-beginning 2)(match-end 2))))
1747 (if (string-match ".sty$" the-file) ;Skip over style files!
1748 nil
1749 (if (and (not (file-readable-p (expand-file-name the-file dir)))
1750 (not (string-match ".tex$" the-file)))
1751 (setq the-file (concat the-file ".tex")))
1752 (setq the-file (expand-file-name the-file dir))
1753 (if (not (file-readable-p the-file))
1754 (setq bib-document-TeX-files-warnings
1755 (concat
1756 bib-document-TeX-files-warnings
1757 (format "Warning: File not found: %s" the-file)))
1758 (setq the-list (cons (expand-file-name the-file dir) the-list))
1759 (end-of-line)(insert "\n")
1760 (insert-file-contents the-file))))))
1761 (kill-buffer tex-buffer)
1762 (nreverse the-list)))
1763
1764 (defun bib-document-citekeys-obarray ()
1765 ;; Return cite keys obarray for multi-file document, or nil if not a multi-file
1766 ;; document. This is a auc-tex supported feature only.
1767 ;; Also, see bib-buffer-citekeys-obarray.
1768 ;; Sets global variable bib-document-citekeys-obarray-warnings.
1769 (setq bib-document-citekeys-obarray-warnings nil)
1770 (let ((master-tex (bib-master-file))
1771 (master-aux))
1772 (if (not master-tex)
1773 nil ;Not a multifile document. No need...
1774 (setq master-aux (bib-return-aux-file-from-tex master-tex "aux"))
1775 (or (file-readable-p master-aux)
1776 (error "Sorry, cannot read file %s" master-aux))
1777 (and (file-newer-than-file-p master-tex master-aux)
1778 (setq bib-document-citekeys-obarray-warnings
1779 (format "Warning: %s is out of date relative to %s.\n"
1780 master-aux master-tex)))
1781 (let ((work-buffer (get-buffer-create "*bib-cite-work*"))
1782 (keys-obarray (make-vector 201 0)))
1783 (save-excursion
1784 (set-buffer work-buffer)
1785 (insert-file-contents master-aux)
1786 ;; Because we will be looking for \input statements, we need to set
1787 ;; the default directory to that of the master file.
1788 (setq default-directory (file-name-directory master-tex))
1789 ;; bib-make-bibliography will need this also to find .bib files
1790 ;; look for \@input{chap1/part1.aux}
1791 (while (re-search-forward "^\\\\@input{\\(.*\\)}$" nil t)
1792 (let* ((auxfile (buffer-substring(match-beginning 1)(match-end 1)))
1793 (texfile (bib-return-aux-file-from-tex auxfile "tex")))
1794 (if (not (file-readable-p auxfile))
1795 (setq bib-document-citekeys-obarray-warnings
1796 (concat
1797 bib-document-citekeys-obarray-warnings
1798 (format "Warning: %s is not found or readable.\n"
1799 auxfile)))
1800 (if (file-newer-than-file-p texfile auxfile)
1801 (setq bib-document-citekeys-obarray-warnings
1802 (concat
1803 bib-document-citekeys-obarray-warnings
1804 (format
1805 "Warning: %s is out of date relative to %s.\n"
1806 auxfile texfile))))
1807 (end-of-line)(insert "\n")
1808 (insert-file-contents (buffer-substring (match-beginning 1)
1809 (match-end 1))))))
1810 (goto-char 1)
1811 ;; look for \citation{gertsenshtein59}
1812 (while (re-search-forward "^\\\\citation{\\(.*\\)}$" nil t)
1813 (intern (buffer-substring (match-beginning 1)(match-end 1))
1814 keys-obarray)))
1815 (kill-buffer work-buffer)
1816 keys-obarray))))
1817
1818 (defun bib-return-aux-file-from-tex (texname ext)
1819 ;; given name.name.XXX return name.name.ext
1820 (concat (substring texname 0 -3) ext))
1821
1822 (defun bib-etags-find-noselect (tag &optional masterdir)
1823 ;; Returns a buffer with point on `tag'. buffer is not selected.
1824 ;; Makes sure TAGS file exists, etc.
1825 (require 'etags)
1826 (let* ((master (or masterdir (bib-master-directory)))
1827 (the-buffer (current-buffer))
1828 (new-buffer)
1829 (the-tags-file-name (expand-file-name bib-etags-filename master)))
1830 (or (file-exists-p the-tags-file-name) ;make sure TAGS exists
1831 (bib-etags master))
1832 (or (equal the-tags-file-name tags-file-name) ;make sure it's current
1833 (visit-tags-table the-tags-file-name))
1834 ;; find-tag-noselect should set the TAGS file for the new buffer
1835 ;; that's what C-h f visit-tags-table says...
1836 (if (string-match "XEmacs\\|Lucid" emacs-version)
1837 (progn
1838 (find-tag tag)
1839 (setq new-buffer (current-buffer))
1840 (set-buffer the-buffer))
1841 (setq new-buffer (find-tag-noselect tag)) ;Seems to set buffer to TAGS
1842 (set-buffer the-buffer))
1843 new-buffer))
1844
1845 ;;---------------------------------------------------------------------------
1846 ;; imenu stuff
1847 ;; All of this should only be loaded if imenu is *already* loaded because
1848 ;; we redefine imenu here.
1849
1850 (cond
1851 (bib-use-imenu
1852 (require 'imenu)
1853 (require 'cl)
1854 ;;; Now done at end of this file:
1855 ;;(add-hook 'LaTeX-mode-hook 'LaTeX-hook-setq-imenu)
1856
1857 (defvar bib-imenu-document-counter nil
1858 "bib-cite internal variable")
1859
1860 ;; FIXME: If bib-cite becomes a minor mode, then this hook will go away
1861 ;; and this will be done in the minor-mode function.
1862 (defun LaTeX-hook-setq-imenu ()
1863 ;; User who *never* uses multi-file documents could change this to:
1864 ;; 'imenu--create-LaTeX-index-for-buffer
1865 (setq imenu-create-index-function 'imenu--create-LaTeX-index))
1866
1867 (defun imenu--create-LaTeX-index ()
1868 ;; dispatch to proper function, depending on whether a multi-file document.
1869 (let ((masterfile (bib-master-file)))
1870 (if masterfile
1871 (imenu--create-LaTeX-index-for-document masterfile)
1872 (imenu--create-LaTeX-index-for-buffer))))
1873
1874 (defun imenu--create-LaTeX-index-for-document (masterfile)
1875 ;; For a multi-file document in auctex only.
1876 ;; Create imenu--index-alist for master file buffer and use the same
1877 ;; for all input files? This would be faster... Maybe in next version?
1878 (bib-etags) ;Create a new TAGS file, user needs it.
1879 (let ((tex-buffer (get-buffer-create "*imenu-tex*"))
1880 (index-alist '())
1881 (index-label-alist '())
1882 (prev-pos))
1883 (save-excursion
1884 (set-buffer tex-buffer)
1885 ;; set its directory so relative includes work without expanding
1886 (setq default-directory (file-name-directory masterfile))
1887 (insert-file-contents masterfile)
1888 (goto-char (point-min))
1889 (while (re-search-forward
1890 "^[ \t]*\\\\\\(input\\|include\\){\\([^}]*\\)}" nil t)
1891 (let ((the-file (buffer-substring (match-beginning 2)(match-end 2))))
1892 (if (and (not (file-readable-p
1893 (expand-file-name the-file default-directory)))
1894 (not (string-match ".tex$" the-file)))
1895 (setq the-file (concat the-file ".tex")))
1896 (end-of-line)(insert "\n")
1897 (insert-file-contents the-file)))
1898 ;; Now, the document is like any other tex file
1899 (setq bib-imenu-document-counter -99) ;IDs menu entries start at -100
1900 (goto-char (point-max))
1901 (imenu-progress-message prev-pos 0 t)
1902 (while
1903 (re-search-backward
1904 ;;; "\\\\\\(\\(sub\\)*section\\|chapter\\|label\\){[^}]+}"
1905 "\\(\\\\label\\)\\|\\(^[ ]*\\\\\\(\\(sub\\)*section\\|chapter\\)\\){[^}]+}"
1906 nil t)
1907 (imenu-progress-message prev-pos nil t)
1908 (save-match-data
1909 (save-excursion
1910 (cond
1911 ((looking-at "\\\\label")
1912 (push (imenu--LaTeX-name-and-etags)
1913 index-label-alist))
1914 (t
1915 (push (imenu--LaTeX-name-and-etags)
1916 index-alist))))))
1917 (kill-buffer tex-buffer)
1918 (imenu-progress-message prev-pos 100 t)
1919 ;;Michal Mnuk's add-on removes \label <Michal.Mnuk@risc.uni-linz.ac.at>
1920 ;;Plus PSG's fix for 19.31 w/o imenu-create-submenu-name
1921 (and index-label-alist
1922 (push (cons (or (and (fboundp 'imenu-create-submenu-name)
1923 (imenu-create-submenu-name "Labels"))
1924 "Labels")
1925 (sort (imenu--remove-LaTeX-keyword-list
1926 index-label-alist) 'imenu--label-cmp))
1927 index-alist))
1928 ;;(and index-label-alist
1929 ;; (push (cons (imenu-create-submenu-name "Labels")
1930 ;; index-label-alist)
1931 ;; index-alist))
1932 index-alist)))
1933
1934 (defun imenu--create-LaTeX-index-for-buffer ()
1935 ;; For non-multi-file documents.
1936 (let ((index-alist '())
1937 (index-label-alist '())
1938 prev-pos)
1939 (setq bib-imenu-document-counter -99) ;IDs menu entries starting at -100
1940 (goto-char (point-max))
1941 (imenu-progress-message prev-pos 0 t)
1942 (while
1943 (re-search-backward
1944 ;;; Better regexp, but slow
1945 ;;; "^[^;]*\\(\\\\\\)\\(\\(sub\\)*section\\|chapter\\|label\\){[^}]+}"
1946 ;;; Original regexp that would catch commented-out stuff
1947 ;;; "\\\\\\(\\(sub\\)*section\\|chapter\\|label\\){[^}]+}"
1948 "\\(\\\\label\\)\\|\\(^[ ]*\\\\\\(\\(sub\\)*section\\|chapter\\)\\){[^}]+}"
1949 nil t)
1950 (imenu-progress-message prev-pos nil t)
1951 (save-match-data
1952 (save-excursion
1953 (cond
1954 ((looking-at "\\\\label")
1955 (push (imenu--LaTeX-name-and-position)
1956 index-label-alist))
1957 (t
1958 (push (imenu--LaTeX-name-and-position)
1959 index-alist))))))
1960 (imenu-progress-message prev-pos 100 t)
1961 ;;Michal Mnuk's add-on removes \label <Michal.Mnuk@risc.uni-linz.ac.at>
1962 ;;Plus PSG's fix for 19.31 w/o imenu-create-submenu-name
1963 (and index-label-alist
1964 (push (cons (or (and (fboundp 'imenu-create-submenu-name)
1965 (imenu-create-submenu-name "Labels"))
1966 "Labels")
1967 (sort (imenu--remove-LaTeX-keyword-list
1968 index-label-alist) 'imenu--label-cmp))
1969 index-alist))
1970 ;;(and index-label-alist
1971 ;; (push (cons (imenu-create-submenu-name "Labels")
1972 ;; index-label-alist)
1973 ;; index-alist))
1974 index-alist))
1975
1976 ;;Michal Mnuk's three routines:
1977 (defun imenu--remove-LaTeX-keyword-list (llist)
1978 "Remove the LaTeX KEYWORD from car's of all elements in LLIST."
1979 (mapcar
1980 (function (lambda (element)
1981 (imenu--remove-LaTeX-keyword-el element "label")))
1982 llist))
1983
1984 (defun imenu--remove-LaTeX-keyword-el (element keyword)
1985 "Remove the LaTeX KEYWORD from car of ELEMENT."
1986 (save-match-data
1987 ;; Shouls I have extra option here: "[
1988 (string-match (concat "\\\\" keyword "{\\(.*\\)}") (car element))
1989 (cons
1990 (substring (car element) (match-beginning 1) (match-end 1))
1991 (cdr element))))
1992
1993 (defun imenu--label-cmp (el1 el2)
1994 "Predicate to compare labels in lists produced by
1995 imenu--create-LaTeX-index."
1996 (string< (car el1) (car el2)))
1997
1998 (defun imenu--LaTeX-name-and-position ()
1999 (save-excursion
2000 ;; We're on the opening slash
2001 (let ((beg (point))
2002 (end (progn (search-forward "{" nil t)
2003 (forward-char -1)
2004 (forward-sexp 1)
2005 (point)))
2006 (marker (make-marker)))
2007 (set-marker marker beg)
2008 (cons (buffer-substring beg end) marker))))
2009
2010 (defun imenu--LaTeX-name-and-etags ()
2011 (save-excursion
2012 (setq bib-imenu-document-counter (1- bib-imenu-document-counter))
2013 (cons (buffer-substring (point)
2014 (progn (search-forward "{")
2015 (forward-char -1)
2016 (forward-sexp 1)
2017 (point)))
2018 bib-imenu-document-counter)))
2019
2020 ;; Updated to imenu in Emacs 19.33
2021 (defun imenu (index-item)
2022 "Jump to a place in the buffer chosen using a buffer menu or mouse menu.
2023 See `imenu-choose-buffer-index' for more information."
2024 (interactive
2025 (list (save-restriction
2026 (widen)
2027 (imenu-choose-buffer-index))))
2028 ;; Convert a string to an alist element.
2029 (if (stringp index-item)
2030 (setq index-item (assoc index-item (imenu--make-index-alist))))
2031 (and index-item
2032 (progn
2033 (push-mark)
2034 (cond
2035 ((markerp (cdr index-item))
2036 (if (or ( > (marker-position (cdr index-item)) (point-min))
2037 ( < (marker-position (cdr index-item)) (point-max)))
2038 ;; widen if outside narrowing
2039 (widen))
2040 (goto-char (marker-position (cdr index-item))))
2041 ;; PSG - Handle tags
2042 ((and (numberp (cdr index-item))
2043 (< (cdr index-item) -99))
2044 (find-tag (car index-item)))
2045 (t
2046 (if (or ( > (cdr index-item) (point-min))
2047 ( < (cdr index-item) (point-max)))
2048 ;; widen if outside narrowing
2049 (widen))
2050 (goto-char (cdr index-item)))))))
2051 ;;; end of bib-use-imenu stuff
2052 ))
2053 ;; --------------------------------------------------------------------------
2054 ;; The following routines make a temporary bibliography buffer
2055 ;; holding all bibtex files found.
2056
2057 (defun bib-get-bibliography (include-filenames-f)
2058 "Returns a new bibliography buffer holding all bibtex files in the document.
2059
2060 If using auc-tex, and either TeX-parse-self is set or C-c C-n is used to
2061 parse the document, then the entire multifile document will be searched
2062 for \bibliography commands.
2063
2064 If this fails, the current buffer is searched for the first \bibliography
2065 command.
2066
2067 If include-filenames-f is true, include as a special header the filename
2068 of each bib file.
2069
2070 Puts the buffer in text-mode such that forward-sexp works with german \"
2071 accents embeded in bibtex entries."
2072 (let ((bib-list (or (and (fboundp 'LaTeX-bibliography-list)
2073 (boundp 'TeX-auto-update)
2074 (LaTeX-bibliography-list))
2075 ;; LaTeX-bibliography-list (if bound) returns an unformatted list of
2076 ;; bib files used in the document, but only if parsing is turned on
2077 ;; or C-c C-n was used.
2078 (bib-bibliography-list)))
2079 (bib-buffer (get-buffer-create "*bibtex-bibliography*"))
2080 ;; Path is relative to the master directory
2081 (default-directory (bib-master-directory))
2082 (the-name)(the-warnings)(the-file))
2083 (save-excursion
2084 ;; such that forward-sexp works with embeeded \" in german,
2085 ;; and unbalanced ()
2086 (set-buffer bib-buffer)
2087 (erase-buffer)
2088 (set-syntax-table text-mode-syntax-table)
2089 ;; (if (boundp 'bibtex-mode-syntax-table)
2090 ;; (set-syntax-table bibtex-mode-syntax-table)
2091 ;; (text-mode))
2092 )
2093 ;;We have a list of bib files
2094 ;;Search for them, include them, list those not readable
2095 (while bib-list
2096 (setq the-name (car (car bib-list))) ;Extract the string only
2097 (setq bib-list (cdr bib-list))
2098 (setq the-name
2099 (substring the-name
2100 (string-match "[^ ]+" the-name) ;remove leading spaces
2101 (string-match "[ ]+$" the-name))) ;remove trailing space
2102 (if (not (string-match "\\.bib$" the-name))
2103 (setq the-name (concat the-name ".bib")))
2104 (setq the-file
2105 (or
2106 (and (file-readable-p (expand-file-name (concat "./" the-name)))
2107 (expand-file-name (concat "./" the-name)))
2108 (psg-checkfor-file-list the-name
2109 (psg-list-env bib-bibtex-env-variable))
2110 ;; Check for BIBINPUT env variable as well (by popular demand!)
2111 (psg-checkfor-file-list the-name (psg-list-env "BIBINPUT"))
2112 (and (boundp 'TeX-check-path)
2113 (psg-checkfor-file-list the-name TeX-check-path))))
2114 (if the-file
2115 (progn
2116 (save-excursion
2117 (set-buffer bib-buffer)
2118 (goto-char (point-max))
2119 (if include-filenames-f
2120 (insert "%%%Filename: " the-file "\n"))
2121 (insert-file-contents the-file nil)
2122 (goto-char 1)))
2123 (setq the-warnings
2124 (concat the-warnings "Could not read file: " the-name "\n"))))
2125 (if the-warnings
2126 (progn
2127 (with-output-to-temp-buffer "*Help*"
2128 (princ the-warnings))
2129 (kill-buffer bib-buffer)
2130 (error
2131 "Sorry, can't find all bibtex files in \\bibliography command"))
2132 bib-buffer)))
2133
2134 (defun bib-bibliography-list ()
2135 "Return list of bib files listed in first \\bibliography command in buffer
2136 Similar output to auc-tex's LaTeX-bibliography-list
2137 The first element may contain trailing whitespace (if there was any in input)
2138 although BiBTeX doesn't allow it!"
2139 (save-excursion
2140 (goto-char 1)
2141 (if (not (re-search-forward "^[ \t]*\\\\bibliography{[ \t]*\\([^},]+\\)"
2142 nil t))
2143 (error "Sorry, can't find \\bibliography command anywhere")
2144 (let ((the-list (list (buffer-substring
2145 (match-beginning 1)(match-end 1))))
2146 (doNext t))
2147 (while doNext
2148 (if (looking-at ",")
2149 (setq the-list
2150 (append the-list
2151 (list (buffer-substring
2152 (progn (skip-chars-forward ", ")(point))
2153 (progn (re-search-forward "[,}]" nil t)
2154 (backward-char 1)
2155 (skip-chars-backward ", ")
2156 (point))))))
2157 (setq doNext nil)))
2158 (mapcar 'list the-list)))))
2159
2160 ;; BibTeX-mode key def to create auc-tex's parsing file.
2161 (defun bib-create-auto-file ()
2162 "Force the creation of the auc-tex auto file for a bibtex buffer"
2163 (interactive)
2164 (if (not (require 'latex))
2165 (error "Sorry, This is only useful if you have auc-tex"))
2166 (let ((TeX-auto-save t)
2167 (TeX-auto-update t)
2168 (TeX-auto-regexp-list BibTeX-auto-regexp-list))
2169 ;; TeX-auto-write
2170 ;; -> calls TeX-auto-store
2171 ;; -> calls TeX-auto-parse
2172 ;; clears LaTeX-auto-bibtem (temporary holding space for bibitems)
2173 ;; searches buffer using regexp in TeX-auto-regexp-list
2174 ;; -> if LaTeX-auto-bibtem (the temporary holding space for bibitems)
2175 ;; holds stuffs like
2176 ;; ("Zimmermann:1991" "Anger_et_al:1993")
2177 ;; as determined by
2178 ;; (member nil (mapcar 'TeX-auto-entry-clear-p TeX-auto-parser))
2179 ;; then it creates the auto file.
2180
2181 ;; TeX-auto-write may call TeX-master-file which may fail if
2182 ;; TeX-header-end is unset (by LaTeX-common-initialization in latex-mode)
2183 (if (not TeX-header-end)
2184 (setq TeX-header-end LaTeX-header-end))
2185
2186 (TeX-auto-write)))
2187
2188 ;; ---------------------------------------------------------------------------
2189 ;; Key definitions start here...
2190
2191 ;; Christoph Wedler <wedler@fmi.uni-passau.de>
2192 ;; Replace eval-after-load (which doesn't work with efs anyway)
2193 ;; with add-submenu in bib-cite-initialize
2194
2195 ;;(if ((and (string-match "XEmacs\\|Lucid" emacs-version)
2196 ;; (or window-system
2197 ;; (fboundp 'smart-menu)) ;text menus by Bob Weiner
2198 ;; (not (fboundp 'eval-after-load))))
2199 ;; ;; define eval-after-load for XEmacs
2200 ;; (defun eval-after-load (file form)
2201 ;; "Arrange that, if FILE is ever loaded, FORM will be run at that
2202 ;;time.
2203 ;;This makes or adds to an entry on `after-load-alist'.
2204 ;;It does nothing if FORM is already on the list for FILE.
2205 ;;FILE should be the name of a library, with no directory name."
2206 ;; (or (assoc file after-load-alist)
2207 ;; (setq after-load-alist (cons (list file) after-load-alist)))
2208 ;; (let ((elt (assoc file after-load-alist)))
2209 ;; (or (member form (cdr elt))
2210 ;; (nconc elt (list form))))
2211 ;; form))
2212
2213 (defvar bib-cite-map
2214 (let ((map (make-sparse-keymap)))
2215 (define-key map "a" 'bib-apropos)
2216 (define-key map "m" 'bib-make-bibliography)
2217 (define-key map "d" 'bib-display)
2218 (define-key map "e" 'bib-etags)
2219 (define-key map "f" 'bib-find)
2220 (define-key map "h" 'bib-highlight-mouse)
2221 map)
2222 "Keymap to bind to \\C-cb in latex keymap")
2223
2224 (cond
2225 ((and (string-match "XEmacs\\|Lucid" emacs-version)
2226 (or window-system
2227 (fboundp 'smart-menu))) ;text menus by Bob Weiner
2228 ;;
2229 ;; xemacs under X with auc-tex
2230 ;;
2231
2232 ;; Christoph Wedler <wedler@fmi.uni-passau.de>
2233 (defvar bib-cite-xemacs-menu
2234 '("Bib-Cite"
2235 ;;"---"
2236 ["Make BibTeX bibliography buffer" bib-make-bibliography t]
2237 ["Display citation or matching \\ref or \\label" bib-display t]
2238 ["Find BibTeX citation or matching \\ref or \\label" bib-find t]
2239 ["Search apropos BibTeX files" bib-apropos t]
2240 ["Build TAGS file for multi-file document" bib-etags (bib-master-file)]
2241 ["Refresh \\cite, \\ref and \\label mouse highlight"
2242 bib-highlight-mouse t])
2243 "Submenu of LaTeX menu, used by bib-cite.")
2244
2245 ;;; Add to bibtex.el's popup menu
2246 (defvar bib-cite-xemacs-bibtex-mode-menu
2247 '("---"
2248 "Bib-Cite"
2249 "---"
2250 ["Search apropos BibTeX files" bib-apropos t]
2251 ["Create auc-tex auto parsing file" bib-create-auto-file t])
2252 "Submenu of bibtex-mode menu, used by bib-cite.")
2253
2254 (if (boundp 'bibtex-menu)
2255 ;; Add menu now
2256 (setq bibtex-menu
2257 (append
2258 bibtex-menu
2259 bib-cite-xemacs-bibtex-mode-menu))
2260 ;; Setup to add menu later
2261 (defun bib-cite-bibtex-mode-hook ()
2262 (if (boundp 'bibtex-menu)
2263 (progn
2264 (setq bibtex-menu
2265 (append
2266 bibtex-menu
2267 bib-cite-xemacs-bibtex-mode-menu))
2268 (remove-hook 'bibtex-mode-hook 'bib-cite-bibtex-mode-hook))))
2269 (add-hook 'bibtex-mode-hook 'bib-cite-bibtex-mode-hook))
2270 ;;; Done - Add to bibtex.el's popup menu
2271
2272 ;; (eval-after-load
2273 ;; "latex"
2274 ;; '(progn
2275 ;; (add-menu-button '("LaTeX") ["----" nil t])
2276 ;; (add-menu-button
2277 ;; '("LaTeX") ["Make BibTeX bibliography buffer" bib-make-bibliography t])
2278 ;; (add-menu-button
2279 ;; '("LaTeX") ["Display citation or matching \\ref or \\label"
2280 ;; bib-display t])
2281 ;; (add-menu-button
2282 ;; '("LaTeX") ["Find BibTeX citation or matching \\ref or \\label"
2283 ;; bib-find t])
2284 ;; (add-menu-button
2285 ;; '("LaTeX") ["Search apropos BibTeX files" bib-apropos t])
2286 ;; (add-menu-button
2287 ;; '("LaTeX") ["Build TAGS file for multi-file document" bib-etags t])
2288 ;; (add-menu-button
2289 ;; '("LaTeX")
2290 ;; ["Refresh \\cite, \\ref and \\label mouse highlight"
2291 ;; bib-highlight-mouse t])
2292
2293 )
2294
2295 ((and (not (string-match "XEmacs\\|Lucid" emacs-version))
2296 (string-equal "19" (substring emacs-version 0 2))
2297 (or window-system
2298 (fboundp 'tmm-menubar))) ; 19.30 - Will autoload if necessary
2299 ;;
2300 ;; emacs-19 under X-windows (or non-X with tmm)
2301 ;;
2302
2303 ;; This *almost* makes me want to switch over to XEmacs...
2304
2305 ;; to auc-tex auto file for a bibtex buffer
2306 (eval-after-load
2307 "bibtex"
2308 '(progn
2309 (cond
2310 ((lookup-key bibtex-mode-map [menu-bar move/edit])
2311 (define-key-after
2312 (lookup-key bibtex-mode-map [menu-bar move/edit])
2313 [bib-nil] '("---" . nil) '"--")
2314 (define-key-after
2315 (lookup-key bibtex-mode-map [menu-bar move/edit])
2316 [bib-apropos] '("Search Apropos" . bib-apropos) 'bib-nil)
2317 (define-key-after
2318 (lookup-key bibtex-mode-map [menu-bar move/edit])
2319 [auc-tex-parse]
2320 '("Create auc-tex auto parsing file" . bib-create-auto-file)
2321 'bib-apropos))
2322 ((lookup-key bibtex-mode-map [menu-bar bibtex-edit])
2323 (define-key-after
2324 (lookup-key bibtex-mode-map [menu-bar bibtex-edit])
2325 [bib-nil] '("---" . nil) '"--")
2326 (define-key-after
2327 (lookup-key bibtex-mode-map [menu-bar bibtex-edit])
2328 [bib-apropos] '("Search Apropos" . bib-apropos) 'bib-nil)
2329 (define-key-after
2330 (lookup-key bibtex-mode-map [menu-bar bibtex-edit])
2331 [auc-tex-parse]
2332 '("Create auc-tex auto parsing file" . bib-create-auto-file)
2333 'bib-apropos)))))
2334
2335 (defvar bib-cite-put-menu-separately t
2336 "*Put bib-cite menubar menu separately, not within LaTeX pull-down menu")
2337 (cond
2338 ((not bib-cite-put-menu-separately) ;Old method - Destroy code?
2339 (defun bib-add-menu-keys (the-key)
2340 (cond
2341 (the-key ;make sure keymap exists
2342 (define-key-after the-key [bib-nil] '("---" . nil) '"--")
2343 (define-key-after the-key [bib-make-bibliography]
2344 '("Make BiBTeX bibliography buffer" . bib-make-bibliography)
2345 'bib-nil)
2346 (define-key-after the-key [bib-display]
2347 '("Display citation or matching \\ref or \\label" . bib-display)
2348 'bib-make-bibliography)
2349 (define-key-after the-key [bib-find]
2350 '("Find BiBTeX citation or matching \\ref or \\label" . bib-find)
2351 'bib-display)
2352 (define-key-after the-key [bib-apropos]
2353 '("Search apropos BiBTeX files" . bib-apropos) 'bib-find)
2354 ;;;(put 'ps-print-region-with-faces 'menu-enable 'mark-active)
2355 ;;;(define-key menu-bar-tools-menu [ps-print-buffer]
2356 ;;; '("Postscript Print Buffer" . ps-print-buffer-with-faces))
2357 (put 'bib-etags 'menu-enable '(bib-master-file))
2358 (define-key-after the-key [bib-etags]
2359 '("Build TAGS file for multi-file document" . bib-etags)
2360 'bib-apropos)
2361 (define-key-after the-key [bib-highlight-mouse]
2362 '("Refresh \\cite, \\ref and \\label mouse highlight" .
2363 bib-highlight-mouse)
2364 'bib-etags))))
2365
2366 ;;for auc-tex's LaTeX-mode
2367 (eval-after-load
2368 "latex"
2369 '(let ((the-key (or (lookup-key LaTeX-mode-map [menu-bar LaTeX])
2370 (lookup-key LaTeX-mode-map [menu-bar AUC\ TeX]))))
2371 ;;;(define-key LaTeX-mode-map [S-mouse-1] 'bib-display-mouse)
2372 ;;;(define-key LaTeX-mode-map [S-mouse-2] 'bib-find-mouse)
2373 (define-key LaTeX-mode-map "\C-cb" bib-cite-map)
2374 (bib-add-menu-keys the-key)))
2375
2376 ;;for auc-tex's TeX-mode
2377 (eval-after-load
2378 "tex"
2379 '(let ((the-key (lookup-key TeX-mode-map [menu-bar TeX])))
2380 ;;;(define-key TeX-mode-map [S-mouse-1] 'bib-display-mouse)
2381 ;;;(define-key TeX-mode-map [S-mouse-2] 'bib-find-mouse)
2382 (define-key TeX-mode-map "\C-cb" bib-cite-map)
2383 (bib-add-menu-keys the-key)))
2384
2385 ;;for plain tex-mode
2386 (eval-after-load
2387 "tex-mode"
2388 '(progn
2389 (let ((the-key (lookup-key tex-mode-map [menu-bar tex])))
2390 ;;;(define-key tex-mode-map [S-mouse-1] 'bib-display-mouse)
2391 ;;;(define-key tex-mode-map [S-mouse-2] 'bib-find-mouse)
2392 (define-key tex-mode-map "\C-cb" bib-cite-map)
2393 (bib-add-menu-keys the-key)
2394 (define-key tex-mode-map [menu-bar tex bib-etags]
2395 'undefined)))))
2396
2397 (t ;New method - separate menu
2398 (setq bib-cite-menu-map (make-sparse-keymap "bib-cite"))
2399 (define-key bib-cite-menu-map [bib-display]
2400 '("Display citation or matching \\ref or \\label" . bib-display))
2401 (define-key bib-cite-menu-map [bib-find]
2402 '("Find BiBTeX citation or matching \\ref or \\label" . bib-find))
2403 (define-key bib-cite-menu-map [bib-make-bibliography]
2404 '("Make BiBTeX bibliography buffer" . bib-make-bibliography))
2405 (put 'bib-etags 'menu-enable '(bib-master-file))
2406 (define-key bib-cite-menu-map [bib-etags]
2407 '("Build TAGS file for multi-file document" . bib-etags))
2408 (define-key bib-cite-menu-map [bib-apropos]
2409 '("Search apropos BiBTeX files" . bib-apropos))
2410 (define-key bib-cite-menu-map [bib-highlight-mouse]
2411 '("Refresh \\cite, \\ref and \\label mouse highlight"
2412 . bib-highlight-mouse))
2413
2414 (eval-after-load
2415 "tex-mode"
2416 '(progn
2417 ;;;(define-key tex-mode-map [S-mouse-1] 'bib-display-mouse)
2418 ;;;(define-key tex-mode-map [S-mouse-2] 'bib-find-mouse)
2419 (define-key tex-mode-map "\C-cb" bib-cite-map)
2420 (define-key tex-mode-map [menu-bar bib-cite-menu-map]
2421 (cons "Bib-Cite" bib-cite-menu-map))
2422 (define-key tex-mode-map [menu-bar bib-cite-menu-map bib-etags]
2423 'undefined)))
2424
2425 ;;for auc-tex's LaTeX-mode
2426 (eval-after-load
2427 "latex"
2428 '(progn
2429 ;;;(define-key LaTeX-mode-map [S-mouse-1] 'bib-display-mouse)
2430 ;;;(define-key LaTeX-mode-map [S-mouse-2] 'bib-find-mouse)
2431 (define-key LaTeX-mode-map "\C-cb" bib-cite-map)
2432 (define-key LaTeX-mode-map [menu-bar bib-cite-menu-map]
2433 (cons "Bib-Cite" bib-cite-menu-map))))
2434
2435 ;;for auc-tex's TeX-mode
2436 (eval-after-load
2437 "tex"
2438 '(progn
2439 ;;;(define-key TeX-mode-map [S-mouse-1] 'bib-display-mouse)
2440 ;;;(define-key TeX-mode-map [S-mouse-2] 'bib-find-mouse)
2441 (define-key TeX-mode-map "\C-cb" bib-cite-map)))
2442 ))))
2443
2444 ;; This must be after adding to LaTeX-mode-map because we copy it here.
2445 (defvar bib-highlight-mouse-keymap
2446 ;; First, copy the local keymap so we don't have `disappearing' menus
2447 ;; when the mouse is moved over a \ref, \label or \cite command.
2448 ;; FIXME: **This only works if bib-cite is loaded after TeX keymaps
2449 ;; are constructed. Thus, if bib-cite is loaded in a hook.
2450
2451 ;; FIXME: Check out (mouse-major-mode-menu) to see how it grabs the local
2452 ;; menus to display. Maybe on `highlighted' commands we could only
2453 ;; display the bib-cite stuff (or a subset of it).
2454 (let ((m (cond
2455 ((boundp 'LaTeX-mode-map)
2456 (copy-keymap LaTeX-mode-map))
2457 ((boundp 'tex-mode-map)
2458 (copy-keymap tex-mode-map))
2459 (t
2460 (make-sparse-keymap)))))
2461 (cond
2462 ((string-match "XEmacs\\|Lucid" emacs-version)
2463 (set-keymap-name m 'bib-highlight-mouse-keymap)
2464 (cond
2465 ;; action-key stuff from Vladimir Alexiev <vladimir@cs.ualberta.ca>
2466 ((commandp 'action-key)
2467 ;; for hyperbole. The Right Way is to define implicit buttons
2468 ;; (defib) bib-cite and label-ref instead of overriding action-key and
2469 ;; assist key, so that eg smart key help can be obtained, but I'm
2470 ;; lazy.
2471 (substitute-key-definition 'action-key 'bib-find m global-map)
2472 (substitute-key-definition 'assist-key 'bib-display m global-map)
2473 (substitute-key-definition 'action-key-depress
2474 'bib-find-mouse m global-map)
2475 (substitute-key-definition 'assist-key-depress
2476 'bib-display-mouse m global-map)
2477 (substitute-key-definition 'action-mouse-key nil m global-map)
2478 (substitute-key-definition 'assist-mouse-key nil m global-map))
2479 (t ; xemacs, not hyperbole
2480 (define-key m "\e\r" 'bib-find-mouse) ; bug Fixed in V2.17
2481 (define-key m "\e\n" 'bib-display-mouse) ;bug Fixed in V2.17
2482 ;;(define-key m [(shift button1)] 'bib-display-mouse)
2483 (define-key m [button3] 'bib-display-mouse)
2484 (define-key m [button2] 'bib-find-mouse))))
2485 (t ; emacs 19
2486 (cond
2487 ((commandp 'action-key)
2488 (substitute-key-definition 'action-key 'bib-find m global-map)
2489 (substitute-key-definition 'assist-key 'bib-display m global-map)
2490 (substitute-key-definition 'action-mouse-key-emacs19
2491 'bib-find-mouse m global-map)
2492 (substitute-key-definition 'assist-mouse-key-emacs19
2493 'bib-display-mouse m global-map)
2494 (substitute-key-definition 'action-key-depress-emacs19
2495 nil m global-map)
2496 (substitute-key-definition 'assist-key-depress-emacs19
2497 nil m global-map))
2498 (t ; emacs 19, not hyperbole
2499 (define-key m [down-mouse-3] 'bib-display-mouse)
2500 (define-key m [mouse-2] 'bib-find-mouse)))))
2501 m))
2502 ;; --------------------------------------------------------------------------
2503 ;; The following routines are also defined in other packages...
2504
2505 ;; Must be in sync with function of same name in ff-paths.el
2506 (defun psg-checkfor-file-list (filename list)
2507 "Check for presence of FILENAME in directory LIST. Return 1st found path."
2508 ;;USAGE: (psg-checkfor-file-list "gri.cmd" (psg-list-env "PATH"))
2509 ;;USAGE: (psg-checkfor-file-list "gri-mode.el" load-path)
2510 ;;USAGE: (psg-checkfor-file-list "gri.cmd" (psg-translate-ff-list "gri.tmp"))
2511 (let ((the-list list)
2512 (filespec))
2513 (while the-list
2514 (if (not (car the-list)) ; it is nil
2515 (setq filespec (expand-file-name filename "~"))
2516 (setq filespec
2517 (concat (file-name-as-directory (car the-list)) filename)))
2518 (if (file-exists-p filespec)
2519 (setq the-list nil)
2520 (setq filespec nil)
2521 (setq the-list (cdr the-list))))
2522 (if filespec
2523 filespec
2524 ;; If I have not found a file yet, then check if some directories
2525 ;; ended in // and recurse through them.
2526 (let ((the-list list))
2527 (while the-list
2528 (if (not (string-match "//$" (car the-list))) nil
2529 (setq filespec (car
2530 (search-directory-tree
2531 (substring (car the-list) 0 (match-beginning 0))
2532 (concat "^" filename "$")
2533 t
2534 t)))
2535 (if filespec ;Success!
2536 (setq the-list nil)))
2537 (setq the-list (cdr the-list)))
2538 filespec))))
2539
2540
2541 (defun search-directory-tree (directories extension-regexp recurse first-file)
2542 "Return a list of all reachable files in DIRECTORIES ending with EXTENSION.
2543 DIRECTORIES is a list or a single-directory string
2544 EXTENSION is actually (any) regexp, usually \\\\.bib$
2545 If RECURSE is t, then we will recurse into the directory tree,
2546 nil, we will only search the list given.
2547 If FIRST-FILE is t, stop after first file is found."
2548 (or (listp directories)
2549 (setq directories (list directories)))
2550
2551 (let (match)
2552 (while directories
2553 (let* ((directory (file-name-as-directory (car directories)))
2554 (content (and directory
2555 (file-readable-p directory)
2556 (file-directory-p directory)
2557 (directory-files directory))))
2558 (setq directories (cdr directories))
2559 (while content
2560 (let ((file (expand-file-name (car content) directory)))
2561 (cond ((string-match "[.]+$" (car content))) ;This or parent dir
2562 ((not (file-readable-p file)))
2563 ((and recurse
2564 (file-directory-p file))
2565 (setq directories
2566 (cons (file-name-as-directory file) directories)))
2567 ((string-match extension-regexp
2568 (file-name-nondirectory file))
2569 (and first-file
2570 (setq content nil
2571 directories nil))
2572 (setq match (cons file match)))))
2573 (setq content (cdr content)))))
2574
2575 match))
2576
2577 ;;; (defun psg-checkfor-file-list (filename list)
2578 ;;; (let ((the-list list)
2579 ;;; (filespec))
2580 ;;; (while the-list
2581 ;;; (if (not (car the-list)) ; it is nil
2582 ;;; (setq filespec (concat "~/" filename))
2583 ;;; (setq filespec
2584 ;;; (concat (file-name-as-directory (car the-list)) filename)))
2585 ;;; (if (file-exists-p filespec)
2586 ;;; (setq the-list nil)
2587 ;;; (setq filespec nil)
2588 ;;; (setq the-list (cdr the-list))))
2589 ;;; filespec))
2590
2591 (or (fboundp 'dired-replace-in-string)
2592 ;; This code is part of GNU emacs
2593 (defun dired-replace-in-string (regexp newtext string)
2594 ;; Replace REGEXP with NEWTEXT everywhere in STRING and return result.
2595 ;; NEWTEXT is taken literally---no \\DIGIT escapes will be recognized.
2596 (let ((result "") (start 0) mb me)
2597 (while (string-match regexp string start)
2598 (setq mb (match-beginning 0)
2599 me (match-end 0)
2600 result (concat result (substring string start mb) newtext)
2601 start me))
2602 (concat result (substring string start)))))
2603
2604
2605 ;; Could use fset here to equal TeX-split-string to dired-split if only
2606 ;; dired-split is defined. That would eliminate a check in psg-list-env.
2607 (and (not (fboundp 'TeX-split-string))
2608 (not (fboundp 'dired-split))
2609 ;; This code is part of auc-tex
2610 (defun TeX-split-string (char string)
2611 "Returns a list of strings. given REGEXP the STRING is split into
2612 sections which in string was seperated by REGEXP.
2613
2614 Examples:
2615
2616 (TeX-split-string \"\:\" \"abc:def:ghi\")
2617 -> (\"abc\" \"def\" \"ghi\")
2618
2619 (TeX-split-string \" *\" \"dvips -Plw -p3 -c4 testfile.dvi\")
2620
2621 -> (\"dvips\" \"-Plw\" \"-p3\" \"-c4\" \"testfile.dvi\")
2622
2623 If CHAR is nil, or \"\", an error will occur."
2624
2625 (let ((regexp char)
2626 (start 0)
2627 (result '()))
2628 (while (string-match regexp string start)
2629 (let ((match (string-match regexp string start)))
2630 (setq result (cons (substring string start match) result))
2631 (setq start (match-end 0))))
2632 (setq result (cons (substring string start nil) result))
2633 (nreverse result))))
2634
2635 ;; Must be in sync with function of same name in ff-paths.el
2636 ;; (See also PC-include-file-path in standard emacs ditsribution.)
2637 (defun psg-list-env (env)
2638 "Return a list of directory elements in ENVIRONMENT variable (w/o leading $)
2639 argument may consist of environment variable plus a trailing directory, e.g.
2640 HOME or HOME/bin (trailing directory not supported in dos or OS/2).
2641
2642 bib-dos-or-os2-variable affects:
2643 path separator used (: or ;)
2644 whether backslashes are converted to slashes"
2645 (if (not (getenv env))
2646 nil ;Because dired-replace-in-string fails
2647 (let* ((value (if bib-dos-or-os2-variable
2648 (dired-replace-in-string "\\\\" "/" (getenv env))
2649 (getenv env)))
2650 (sep-char (or (and bib-dos-or-os2-variable ";") ":"))
2651 (entries (and value
2652 (or (and (fboundp 'TeX-split-string)
2653 (TeX-split-string sep-char value))
2654 (dired-split sep-char value))))
2655 entry
2656 answers)
2657 (while entries
2658 (setq entry (car entries))
2659 (setq entries (cdr entries))
2660 (if (file-directory-p entry)
2661 (setq answers (cons entry answers))))
2662 (nreverse answers))))
2663
2664 ;;
2665 ;; Create the unified hook to call from LaTeX-mode-hook
2666 ;;
2667 (defun bib-cite-initialize ()
2668 ;; Christoph Wedler's <wedler@fmi.uni-passau.de> suggestion for xemacs
2669 ;; Added for version 2.19
2670 (if (boundp 'tags-always-exact)
2671 (progn
2672 (make-local-variable 'tags-always-exact)
2673 (setq tags-always-exact nil)))
2674
2675 ;; Christoph Wedler <wedler@fmi.uni-passau.de>
2676 (and (boundp 'bib-cite-xemacs-menu)
2677 bib-cite-xemacs-menu
2678 (fboundp 'add-submenu) ;Insurance for emacs
2679 ;;;FIXME: I can do this to add a main menu.
2680 ;;(add-submenu nil bib-cite-xemacs-menu)
2681 ;; This makes it buffer-specific so I don't need to remove it.
2682 (set-buffer-menubar (copy-sequence current-menubar))
2683 (add-submenu '("LaTeX") bib-cite-xemacs-menu))
2684
2685 (cond
2686 ((string-match "XEmacs\\|Lucid" emacs-version)
2687 ;; Define keys for XEmacs
2688 ;; Could do all modes like this for emacs also...
2689 (local-set-key "\C-cba" 'bib-apropos)
2690 (local-set-key "\C-cbm" 'bib-make-bibliography)
2691 (local-set-key "\C-cbd" 'bib-display)
2692 (local-set-key "\C-cbe" 'bib-etags)
2693 (local-set-key "\C-cbf" 'bib-find)
2694 (local-set-key "\C-cbh" 'bib-highlight-mouse)))
2695
2696 (if bib-highlight-mouse-t
2697 (bib-highlight-mouse))
2698 (if bib-use-imenu
2699 (LaTeX-hook-setq-imenu))
2700
2701 ;; Make sure that imenu-sort-function is nil
2702 (and (boundp 'imenu-sort-function)
2703 imenu-sort-function
2704 (make-local-variable 'imenu-sort-function)
2705 (setq imenu-sort-function nil))
2706 )
2707
2708 (add-hook 'LaTeX-mode-hook 'bib-cite-initialize t) ;auctex's latex-mode
2709 (add-hook 'latex-mode-hook 'bib-cite-initialize t) ;emacs' plain latex-mode
2710
2711 ;; If bib-cite.el is loaded in a mode hook, bib-highlight-mouse and
2712 ;; LaTeX-hook-setq-imenu are not called on the buffer...
2713 ;; so invoke it now for .tex buffers. Same for imenu.
2714 ;(if (string-match ".tex$" (buffer-name))
2715 ; (bib-cite-initialize))
2716
2717 (if (or (eq major-mode 'latex-mode)
2718 (eq major-mode 'plain-tex-mode))
2719 (bib-cite-initialize))
2720
2721 (provide 'bib-cite)
2722 ;;; bib-cite.el ends here