(ispell-point): Do nothing if there's no word at START.
[bpt/emacs.git] / lisp / textmodes / bibtex.el
CommitLineData
c0274f38
ER
1;;; bibtex.el --- BibTeX mode for GNU Emacs
2
9750e079
ER
3;; Copyright (C) 1992 Free Software Foundation, Inc.
4
f961a17c
ER
5;; Author: Bengt Martensson <ubrinf!mond!bengt>
6;; Mark Shapiro <shapiro@corto.inria.fr>
7;; Mike Newton <newton@gumby.cs.caltech.edu>
8;; Aaron Larson <alarson@src.honeywell.com>
9ae11a89
ER
9;; Version: 1.3.1
10;; Maintainer:Aaron Larson <alarson@src.honeywell.com>
11;; Adapted-By: ESR
f961a17c
ER
12;; Keywords: tex, bib
13
745bc783
JB
14;; This file is part of GNU Emacs.
15
16;; GNU Emacs is free software; you can redistribute it and/or modify
17;; it under the terms of the GNU General Public License as published by
a1ddedc6 18;; the Free Software Foundation; either version 2, or (at your option)
745bc783
JB
19;; any later version.
20
21;; GNU Emacs is distributed in the hope that it will be useful,
22;; but WITHOUT ANY WARRANTY; without even the implied warranty of
23;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24;; GNU General Public License for more details.
25
26;; You should have received a copy of the GNU General Public License
27;; along with GNU Emacs; see the file COPYING. If not, write to
28;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
29
9ae11a89
ER
30;;; TODO distribute texinfo file.
31
32;;; LCD Archive Entry:
33;;; bibtex-mode|Bengt Martensson, Marc Shapiro, Aaron Larson|
34;;; alarson@src.honeywell.com|
35;;; Support for maintaining BibTeX format bibliography databases|
36;;; 93-03-29|version 1.3|~/modes/bibtex-mode.el.Z|
37
e41b2db1
ER
38;;; Commentary:
39
9ae11a89
ER
40;;; BUGS:
41;;; 1. using regular expressions to match the entire bibtex entry dies
42;;; on long bibtex entires (e.g. those containing abstracts) since
43;;; the length of regular expression matches is fairly limited.
44;;; 2. When inserting a string (with \C-C\C-E\s) hitting a TAB results
45;;; in the error message "Can't find enclosing Bibtex field" instead
46;;; of moving to the empty string. [reported by gernot@cs.unsw.oz.au]
47;;; 3. Function string-equalp should be in a library file, not in this
48;;; file.
49
50;;; (current keeper: alarson@src.honeywell.com
51;;; previous: shapiro@corto.inria.fr)
e41b2db1 52
f961a17c 53;;; Change Log:
e5167999 54
9ae11a89
ER
55;; Mon Mar 29 14:06:06 1993 Aaron Larson (alarson at gendibal)
56;;
57;; * bibtex.el: V1.3 released Mar 30, 1993
58;; (bibtex-field-name): Fix to match definition if latex manual,
59;; specifically letters, digits, and punctuation other than comma.
60;; Underscore is retained for historical reasons.
61;; (bibtex-make-field): Fix to work around bug in Lucid prin1-to-string
62;; function as reported by Martin Sjolin <marsj@ida.liu.se>.
63;; (bibtex-entry): minor code cleanup.
64;; (bibtex-mode-map): Remove key binding (C-c n) for
65;; narrow-to-bibtex-entry, previous binding violated emacs policy of
66;; reserving C-c followed by a letter for user customization.
67;; revise modification history to better conform to FSF changelog
68;; standards.
69;; (bibtex-refile-entry): Removed. Would need disclaimer papers to
70;; incorporate it into official sources, and unable to contact author.
71;; Fix minor "syntax" errors in documentation strings and such found
72;; by new byte compiler. Funs bibtex-mode, bibtex-remove-double-quotes
73;;
74;;
75;; Fri Jan 15 14:06:06 1993 Aaron Larson (alarson at gendibal)
76;;
77;; * bibtex.el: V1.2 released Feb 15 1993
78;; (find-bibtex-entry-location bibtex-make-field): Fixed placement of
79;; "interactive specification". [Bug report from
80;; mernst@theory.lcs.mit.edu]
81;; Fixed problem where bibtex-entry would fail if user typed entry
82;; name in wrong case.
83;; (bibtex-inside-field) Position the cursor _before_ the last comma
84;; on a line (the comma is not necessarily "inside" the field); this
85;; does not seem to break any existing code. ref sct@dcs.edinburgh.ac.uk
86;; (bibtex-enclosing-field, bibtex-enclosing-reference): leave
87;; point unmoved if no enclosing field/reference is found. As a
88;; result of changes (3) and (4) bibtex-next-field works properly,
89;; even when called from the entry key position.
90;; (bibtex-remove-OPT): realign the '=' after removing the 'opt'.
91;; (bibtex-clean-entry): always remove any trailing comma from the
92;; end of a bibtex entry (these commas get stripped automatically when
93;; optional fields are killed by bibtex-kill-optional-field, but can be
94;; left if optional fields are removed by other means).
95;; (bibtex-x-help) Replace tab with spaces in X menu as noted by
96;; khera@cs.duke.edu
97;; (bibtex-refile-entry): Added (from brannon@jove.cs.caltech.edu)
98;; (bibtex-sort-ignore-string-entries sort-bibtex-entries,
99;; map-bibtex-entries): Added variable as requested by
100;; gernot@cs.unsw.oz.au, required changes to funs.
101;; (bibtex-current-entry-label): Added at request of
102;; yasuro@maekawa.is.uec.ac.jp
103;; (bibtex-DEAthesis:) Deleted along with corresponding entry from
104;; bibtex-x-help per shapiro@corto.inria.fr
105;; Moved narrow-to-bibtex-entry from C-c C-n to C-c n (the previous
106;; binding was in conflict with the binding for bibtex-pop-next.
107;; bug report from [shapiro@corto.inria.fr]
108;;
109
110;;;
111;;; alarson@src.honeywell.com 92-Feb-13
112;;; 1. Made bibtex-entry user callable, now prompts for entry type (e.g.
113;;; Article), with completion, and bound it to a key. This is now my
114;;; preferred way to add most entries.
115;;; 2. Made fields of a bibtex entry derived from the alist bibtex-entry-
116;;; field-alist.
117;;; 3. Fixed handling of escaped double quotes, e.g. "Schr{\"o}dinger".
118;;; 4. Fixed bug where unhiding bibtex entries moved point.
119;;; 5. Made "field name" specs permit (name . value) for defaulting. E.g.
120;;; (setq bibtex-mode-user-optional-fields '(("library" . "alarson")))
121;;; will generate the field:
122;;; library = "alarson",
123;;; 6. Added binding for narrow-to-bibtex-entry
124;;; 7. Adding a bibtex entry now runs hook: bibtex-add-entry-hook
125;;; 8. Made bibtex-clean-entry fixup text alignment, and eliminated the
126;;; dependency on bibtex-enclosing-reference which has a problem with
127;;; long entries (e.g. those containing abstracts).
128;;;
e5167999
ER
129;;; alarson@src.honeywell.com 92-Jan-31
130;;; Added support for: ispell, beginning/end of entry movement, a simple
131;;; outline like mode (hide the bodies of bibtex entries), support for
132;;; sorting bibtex entries, and maintaining them in sorted order, and
133;;; simple buffer validation.
134;;; User visible functions added:
135;;; ispell-{abstract,bibtex-entry}, {beginning,end}-of-bibtex-entry
136;;; hide-bibtex-entry-bodies, sort-bibtex-entries, validate-bibtex-
137;;; buffer, find-bibtex-duplicates
138;;; user visible variables added:
139;;; bibtex-maintain-sorted-entries
140;;; new local keybindings:
a857ed13 141;;; " tex-insert-quote
e5167999
ER
142;;; C-c$ ispell-bibtex-entry
143;;; M-C-a beginning-of-bibtex-entry
144;;; M-C-e end-of-bibtex-entry
745bc783
JB
145;;; Mike Newton (newton@gumby.cs.caltech.edu) 90.11.17
146;;; * Handle items like
eb8c3be9 147;;; title = poft # "Fifth Tri-quarterly" # random-conf,
745bc783
JB
148;;; and title = {This title is inside curlies}
149;;; * added user settable, always present, optional fields
150;;; * fixed 'bibtex-find-it's doc string's location
eb8c3be9 151;;; * bibtex-field-text made more general (it wouldn't handle the # construct)
745bc783 152;;; and it now handles a small subset of the {} cases
745bc783
JB
153
154;;; Bengt Martensson, March 6
155;;; Adapted to Bibtex 0.99 by updating the optional fields according
156;;; to the document BibTeXing, Oren Patashnik, dated January 31, 1988.
e5167999 157;;; Updated documentation strings accordingly. Added (provide 'bibtex).
745bc783
JB
158;;; If bibtex-include-OPT-crossref is non-nil, every entry will have
159;;; an OPTcrossref field, analogously for bibtex-include-OPTkey and
160;;; bibtex-include-OPTannote. Added bibtex-preamble, bound to ^C^EP,
161;;; and also found in X- and sun-menus. Cleaned up the sun-menu
162;;; stuff, and made it more uniform with the X-menu stuff. Marc: I
163;;; strongly suspect that I broke your parsing... (Or, more
164;;; correctly, BibTeX 0.99 broke it.)
165;;; Added bibtex-clean-entry-zap-empty-opts, defvar'd to t. If it
166;;; is nil, bibtex-clean-entry will leave empty optional fields alone.
e5167999 167
745bc783
JB
168;;; Marc Shapiro 1-feb-89: integrated changes by Bengt Martensson 88-05-06:
169;;; Added Sun menu support. Locally bound to right mouse button in
170;;; bibtex-mode. Emacs 18.49 allows local mouse bindings!!
171;;; Commented out DEAthesis.
172
173;;; Marc Shapiro 6-oct-88
e5167999 174;;; * skip-whitespace replaced by skip-chars-forward
745bc783
JB
175;;; * use indent-to-column instead of inserting tabs (changes to
176;;; bibtex-entry, bibtex-make-entry, bibtex-make-OPT-entry, renamed to
177;;; bibtex-make-optional-entry)
178;;; * C-c C-k deletes the current OPT entry entirely
179;;; * C-c C-d replaces text of field with ""
180;;; * renamed bibtex-find-it to bibtex-find-text. With arg, now goes to
181;;; start of text. Fixed bugs in it.
182
183;;; Marc Shapiro 23-sep-88
184;;; * bibtex-clean-entry moves past end of entry.
185;;; * bibtex-clean-entry signals mandatory fields left empty.
186
187;;; Marc Shapiro 18-jul-88
e5167999 188;;; * Fixed bug in bibtex-flash-entry
745bc783
JB
189;;; * Moved all the entry type keystrokes to "C-c C-e something" (instead of
190;;; "C-c something" previously) to make room for more. C-c C-e is
191;;; supposed to stand for "entry" [idea taken from mail-mode]. Moved
192;;; bibtex-pop-previous to C-c C-p and bibtex-pop-next to C-c C-n.
193;;; * removed binding for "\e[25~"
194;;; * replaced bibtex-clean-optionals by bibtex-clean-entry, bound to
195;;; C-c C-c
196
197;;; Marc Shapiro 13-jul-88 [based on ideas by Sacha Krakowiak of IMAG]
198;;; * bibtex-pop-previous replaces current field with value of
199;;; similar field in previous entry. May be called n times in a row
200;;; (or with arg n) to pop similar field of n'th previous entry.
201;;; There is also a bibtex-pop-next to get similar field of next
202;;; entry.
203;;; * C-c C-k now kills all empty optional fields of current entry, and
204;;; removes "OPT" for those optional fields which have text.
205
206;;; Marc Shapiro 14-dec-87
207;;; Cosmetic fixes. Fixed small bug in bibtex-move-outside-of-entry.
208;;; Skip Montanaro <steinmetz!sprite!montanaro> 7-dec-87, Shapiro 10-dec-87
209;;; before inserting an entry, make sure we are outside of a bib entry
210;;; Marc Shapiro 3-nov-87
211;;; addition for France: DEAthesis
212;;; Marc Shapiro 19-oct-1987
213;;; add X window menu option; bug fixes. TAB, LFD, C-c " and C-c C-o now
214;;; behave consistently; deletion never occurs blindly.
215;;; Marc Shapiro <shapiro@inria.inria.fr> 15-oct-1986
216;;; align long lines nicely; C-c C-o checks for the "OPT" string;
217;;; TAB goes to the end of the string; use lower case; use
218;;; run-hooks
219
220;;; Bengt Martensson <ubrinf!mond!bengt> 87-06-28
e5167999 221;;; Bengt Martensson <bengt@mathematik.uni-Bremen.de> 87-06-28
745bc783
JB
222;;; Original version
223
9ae11a89
ER
224;;; Code:
225
745bc783
JB
226;;; NOTE by Marc Shapiro, 14-dec-87:
227;;; (bibtex-x-environment) binds an X menu for bibtex mode to x-button-c-right.
228;;; Trouble is, in Emacs 18.44 you can't have a mode-specific mouse binding,
229;;; so it will remain active in all windows. Yuck!
230
e5167999
ER
231(provide 'bibtex)
232
233;;; these guys typically don't have autoloads...[alarson:19920131.1548CST]
9ae11a89
ER
234;;; Check for fboundp first so that if user autoloads them from non standard
235;;; places, the users bindings will take precedence.
a857ed13
RS
236(if (not (fboundp 'tex-insert-quote))
237 (autoload 'tex-insert-quote "tex-mode"))
e5167999
ER
238(if (not (fboundp 'sort-subr))
239 (autoload 'sort-subr "sort"))
240
9ae11a89 241;;; These should be in a more generally accessible location.
e5167999 242
9ae11a89
ER
243(defun string-equalp (s1 s2)
244 "Like string= except differences in case are ignored."
245 (let ((ss1 (if (symbolp s1) (symbol-name s1) s1))
246 (ss2 (if (symbolp s2) (symbol-name s2) s2)))
247 (and (= (length ss1) (length ss2))
248 (string-equal (upcase ss1) (upcase ss2)))))
249
250;;; This should be moved into simple.el, and the functions there modified
251;;; to call it rather than doing it themselves.
252(defun put-string-on-kill-ring (string)
253 "Make STRING be the first element of the kill ring."
254 (setq kill-ring (cons string kill-ring))
255 (if (> (length kill-ring) kill-ring-max)
256 (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))
257 (setq kill-ring-yank-pointer kill-ring))
e5167999 258
e5167999 259
e5167999 260
745bc783
JB
261
262(defvar bibtex-clean-entry-zap-empty-opts t
d30bfc76 263 "*If non-nil, bibtex-clean-entry will delete all empty optional fields.")
e5167999 264
745bc783 265(defvar bibtex-include-OPTcrossref t
d30bfc76 266 "*If non-nil, all entries will have an OPTcrossref field.")
745bc783 267(defvar bibtex-include-OPTkey t
d30bfc76 268 "*If non-nil, all entries will have an OPTkey field.")
745bc783 269(defvar bibtex-include-OPTannote t
d30bfc76 270 "*If non-nil, all entries will have an OPTannote field.")
745bc783
JB
271
272;; note: the user should be allowed to have their own list of always
273;; available optional fields. exs: "keywords" "categories"
e5167999 274
745bc783 275(defvar bibtex-mode-user-optional-fields nil ;no default value
d30bfc76 276 "*List of optional fields that user want to have as always present
9ae11a89
ER
277when making a bibtex entry. One possibility is for ``keywords''.
278Entries can be either strings or conses, in which case the car should be
279string and the cdr the value to be inserted.")
280
281(defvar bibtex-mode-syntax-table
282 (let ((st (make-syntax-table)))
283 ;; [alarson:19920214.1004CST] make double quote a string quote
284 (modify-syntax-entry ?\" "\"" st)
285 (modify-syntax-entry ?$ "$$ " st)
286 (modify-syntax-entry ?% "< " st)
287 (modify-syntax-entry ?' "w " st)
288 (modify-syntax-entry ?@ "w " st)
289 (modify-syntax-entry ?\\ "\\" st)
290 (modify-syntax-entry ?\f "> " st)
291 (modify-syntax-entry ?\n "> " st)
292 (modify-syntax-entry ?~ " " st)
293 st))
294
295(defvar bibtex-mode-abbrev-table nil "")
296(define-abbrev-table 'bibtex-mode-abbrev-table ())
297(defvar bibtex-mode-map
298 (let ((km (make-sparse-keymap)))
299
300 (define-key km "\t" 'bibtex-find-text)
301 (define-key km "\n" 'bibtex-next-field)
302 (define-key km "\C-c\"" 'bibtex-remove-double-quotes)
303 (define-key km "\C-c\C-c" 'bibtex-clean-entry)
304 (define-key km "\C-c?" 'describe-mode)
305 (define-key km "\C-c\C-p" 'bibtex-pop-previous)
306 (define-key km "\C-c\C-n" 'bibtex-pop-next)
307 (define-key km "\C-c\C-k" 'bibtex-kill-optional-field)
308 (define-key km "\C-c\C-d" 'bibtex-empty-field)
309
310 ;; [alarson:19920131.1543CST]
a857ed13 311 (define-key km "\"" 'tex-insert-quote)
9ae11a89
ER
312 (define-key km "\C-c$" 'ispell-bibtex-entry)
313 (define-key km "\M-\C-a" 'beginning-of-bibtex-entry)
314 (define-key km "\M-\C-e" 'end-of-bibtex-entry)
315 (define-key km "\C-ce" 'bibtex-entry)
316; (define-key km "\C-cn" 'narrow-to-bibtex-entry)
317
318 (define-key km "\C-c\C-e\C-a" 'bibtex-Article)
319 (define-key km "\C-c\C-e\C-b" 'bibtex-Book)
320; (define-key km "\C-c\C-e\C-d" 'bibtex-DEAthesis)
321 (define-key km "\C-c\C-e\C-c" 'bibtex-InProceedings)
322 (define-key km "\C-c\C-e\C-i" 'bibtex-InBook)
323 (define-key km "\C-c\C-ei" 'bibtex-InCollection)
324 (define-key km "\C-c\C-eI" 'bibtex-InProceedings)
325 (define-key km "\C-c\C-e\C-m" 'bibtex-Manual)
326 (define-key km "\C-c\C-em" 'bibtex-MastersThesis)
327 (define-key km "\C-c\C-eM" 'bibtex-Misc)
328 (define-key km "\C-c\C-o" 'bibtex-remove-OPT)
329 (define-key km "\C-c\C-e\C-p" 'bibtex-PhdThesis)
330 (define-key km "\C-c\C-ep" 'bibtex-Proceedings)
331 (define-key km "\C-c\C-eP" 'bibtex-preamble)
332 (define-key km "\C-c\C-e\C-t" 'bibtex-TechReport)
333 (define-key km "\C-c\C-e\C-s" 'bibtex-string)
334 (define-key km "\C-c\C-e\C-u" 'bibtex-Unpublished)
335 km))
336
337(defvar bibtex-pop-previous-search-point nil
338 "Next point where bibtex-pop-previous should start looking for a similar
339entry.")
340
341(defvar bibtex-pop-next-search-point nil
342 "Next point where bibtex-pop-next should start looking for a similar
343entry.")
344
345(defvar bibtex-entry-field-alist
346 '(
347 ("Article" . ((("author" "title" "journal" "year")
348 ("volume" "number" "pages" "month" "note"))
349 (("author" "title")
350 ("journal" "year" "volume" "number" "pages"
351 "month" "note"))))
352 ("Book" . ((("author" "title" "publisher" "year")
353 ("editor" "volume" "number" "series" "address"
354 "edition" "month" "note"))))
355 ("Booklet" . ((("title")
356 ("author" "howpublished" "address" "month" "year" "note"))))
357
358 ;; France: Dipl\^{o}me d'Etudes Approfondies (similar to Master's)
359; ("DEAthesis" . ((("author" "title" "school" "year")
360; ("address" "month" "note"))))
361
362 ("InBook" . ((("author" "title" "chapter" "publisher" "year")
363 ("editor" "pages" "volume" "number" "series" "address"
364 "edition" "month" "type" "note"))
365 (("author" "title" "chapter")
366 ("publisher" "year" "editor" "pages" "volume" "number"
367 "series" "address" "edition" "month" "type" "note"))))
368
369
370 ("InCollection" . ((("author" "title"
371 "booktitle" "publisher" "year")
372 ("editor" "volume" "number" "series" "type" "chapter"
373 "pages" "address" "edition" "month" "note"))
374 (("author" "title")
375 ("booktitle" "publisher" "year"
376 "editor" "volume" "number" "series" "type" "chapter"
377 "pages" "address" "edition" "month" "note"))))
378
379
380 ("InProceedings" . ((("author" "title" "booktitle" "year")
381 ("editor" "volume" "number" "series" "pages"
382 "organization" "publisher" "address" "month" "note"))
383 (("author" "title")
384 ("editor" "volume" "number" "series" "pages"
385 "booktitle" "year"
386 "organization" "publisher" "address" "month" "note"))))
387
388
389 ("Manual" . ((("title")
390 ("author" "organization" "address" "edition" "year"
391 "month" "note"))))
392
393 ("MastersThesis" . ((("author" "title" "school" "year")
394 ("address" "month" "note" "type"))))
395
396 ("Misc" . ((()
397 ("author" "title" "howpublished" "year" "month" "note"))))
398
399 ("PhdThesis" . ((("author" "title" "school" "year")
400 ("address" "month" "type" "note"))))
401
402 ("Proceedings" . ((("title" "year")
403 ("editor" "volume" "number" "series" "publisher"
404 "organization" "address" "month" "note"))))
405
406 ("TechReport" . ((("author" "title" "institution" "year")
407 ("type" "number" "address" "month" "note"))))
408
409 ("Unpublished" . ((("author" "title" "note")
410 ("year" "month"))))
411 )
412
413 "List of (entry-name (required optional) (crossref-required crossref-optional))
414tripples. If the third element is nil, then the first pair can be used. Required
415and optional are lists of strings. All entry creation functions use this variable
416to generate entries, and bibtex-entry ensures the entry type is valid. This
417variable can be used for example to make bibtex manipulate a different set of entry
418types, e.g. a crossreference document of organization types.")
745bc783
JB
419
420
421;;; A bibtex file is a sequence of entries, either string definitions
422;;; or reference entries. A reference entry has a type part, a
423;;; key part, and a comma-separated sequence of fields. A string
424;;; entry has a single field. A field has a left and right part,
425;;; separated by a '='. The left part is the name, the right part is
426;;; the text. Here come the definitions allowing to create and/or parse
427;;; entries and fields:
428
429;;; fields
430(defun bibtex-cfield (name text)
d30bfc76 431 "Create a regexp for a bibtex field of name NAME and text TEXT"
745bc783
JB
432 (concat ",[ \t\n]*\\("
433 name
434 "\\)[ \t\n]*=[ \t\n]*\\("
435 text
436 "\\)"))
437(defconst bibtex-name-in-cfield 1
d30bfc76 438 "The regexp subexpression number of the name part in bibtex-cfield.")
745bc783 439(defconst bibtex-text-in-cfield 2
d30bfc76 440 "The regexp subexpression number of the text part in bibtex-cfield.")
745bc783 441
9ae11a89
ER
442;;; KAWATA Yasuro <yasuro@qqqq.maekawa.is.uec.ac.jp> reported bug that "/"
443;;; was not premitted in field names. The old value of this var was:
444;;; "[A-Za-z][---A-Za-z0-9:_+]*"
445;;; According to the LaTeX manual, page 71, the legal values are letters,
446;;; digits, and punctuation other than comma. Section 2.1 defines
447;;; punctuation as:
448;;; .:;,?!`'()[]-/*@
449;;; and says that += can be used in normal text. Specifically #$%&~_^\{}
450;;; are called out as special chars. Some experimentation with LaTeX
451;;; indicates that # and ~ definitely don't work, but that the following
452;;; citation does! \cite{a0.:;?!`'()[]-/*@_&$^+=|<>}. I chose here to
453;;; permit _ since it was previously allowed, but otherwise to only handle
454;;; punc and +=
455;;; Amendment: I couldn't get a regexp with both "[]"'s and hyphen to
456;;; work. It looks like you need them both to be the first entries in a
457;;; regexp pattern. [alarson:19930315.0900CST]
458
459(defconst bibtex-field-name "[A-Za-z][---A-Za-z0-9.:;?!`'()/*@_+=]*"
745bc783
JB
460 "Regexp defining the name part of a bibtex field.")
461
462;; bibtex-field-text must be able to handle
463;; title = "Proc. Fifteenth Annual" # STOC,
464;; month = "10~" # jan,
465;; year = "{\noopsort{1973c}}1981",
466;; month = apr # "-" # may,
467;; key = {Volume-2},
468;; note = "Volume~2 is listed under Knuth \cite{book-full}"
469;; i have added a few of these, but not all! -- MON
470
471(defconst bibtex-field-const
472 "[0-9A-Za-z][---A-Za-z0-9:_+]*"
473 "Format of a bibtex field constant.")
d30bfc76 474
e5167999 475(defconst bibtex-field-string
745bc783 476 (concat
e5167999
ER
477 "\"[^\"]*[^\\\\]\"\\|\"\"")
478 "Match either a string or an empty string.")
479
745bc783
JB
480(defconst bibtex-field-string-or-const
481 (concat bibtex-field-const "\\|" bibtex-field-string)
d30bfc76 482 "Match either bibtex-field-string or bibtex-field-const.")
745bc783 483
745bc783
JB
484(defconst bibtex-field-text
485 (concat
486 "\\(" bibtex-field-string-or-const "\\)"
487 "\\([ \t\n]+#[ \t\n]+\\(" bibtex-field-string-or-const "\\)\\)*\\|"
e5167999 488 "{[^{}]*[^\\\\]}")
745bc783
JB
489 "Regexp defining the text part of a bibtex field: either a string, or
490an empty string, or a constant followed by one or more # / constant pairs.
e5167999
ER
491Also matches simple {...} patterns.")
492
493;(defconst bibtex-field-text
494; "\"[^\"]*[^\\\\]\"\\|\"\"\\|[0-9A-Za-z][---A-Za-z0-9:_+]*"
495; "Regexp defining the text part of a bibtex field: either a string, or an empty string, or a constant.")
745bc783
JB
496
497(defconst bibtex-field
498 (bibtex-cfield bibtex-field-name bibtex-field-text)
499 "Regexp defining the format of a bibtex field")
500
501(defconst bibtex-name-in-field bibtex-name-in-cfield
d30bfc76 502 "The regexp subexpression number of the name part in bibtex-field")
745bc783 503(defconst bibtex-text-in-field bibtex-text-in-cfield
d30bfc76 504 "The regexp subexpression number of the text part in bibtex-field")
745bc783
JB
505
506;;; references
507(defconst bibtex-reference-type
508 "@[A-Za-z]+"
d30bfc76 509 "Regexp defining the type part of a bibtex reference entry")
745bc783
JB
510(defconst bibtex-reference-head
511 (concat "^[ \t]*\\("
512 bibtex-reference-type
513 "\\)[ \t]*[({]\\("
514 bibtex-field-name
515 "\\)")
d30bfc76 516 "Regexp defining format of the header line of a bibtex reference entry")
745bc783 517(defconst bibtex-type-in-head 1
d30bfc76 518 "The regexp subexpression number of the type part in bibtex-reference-head")
745bc783 519(defconst bibtex-key-in-head 2
d30bfc76
JB
520 "The regexp subexpression number of the key part in
521bibtex-reference-head")
745bc783
JB
522
523(defconst bibtex-reference
524 (concat bibtex-reference-head
525 "\\([ \t\n]*" bibtex-field "\\)*"
526 "[ \t\n]*[})]")
d30bfc76 527 "Regexp defining the format of a bibtex reference entry")
745bc783 528(defconst bibtex-type-in-reference bibtex-type-in-head
d30bfc76 529 "The regexp subexpression number of the type part in bibtex-reference")
745bc783 530(defconst bibtex-key-in-reference bibtex-key-in-head
d30bfc76
JB
531 "The regexp subexpression number of the key part in
532bibtex-reference")
745bc783 533
e5167999 534;;; strings
745bc783
JB
535(defconst bibtex-string
536 (concat "^[ \t]*@[sS][tT][rR][iI][nN][gG][ \t\n]*[({][ \t\n]*\\("
537 bibtex-field-name
538 "\\)[ \t\n]*=[ \t\n]*\\("
539 bibtex-field-text
540 "\\)[ \t\n]*[})]")
d30bfc76 541 "Regexp defining the format of a bibtex string entry")
745bc783 542(defconst bibtex-name-in-string 1
d30bfc76 543 "The regexp subexpression of the name part in bibtex-string")
745bc783 544(defconst bibtex-text-in-string 2
d30bfc76 545 "The regexp subexpression of the text part in bibtex-string")
745bc783 546
93d35499 547(defconst bibtex-name-alignment 2
745bc783
JB
548 "Alignment for the name part in BibTeX fields.
549Chosen on aesthetic grounds only.")
550
551(defconst bibtex-text-alignment (length " organization = ")
552 "Alignment for the text part in BibTeX fields.
553Equal to the space needed for the longest name part.")
554
9ae11a89 555(defun bibtex-current-entry-label (&optional include-cite kill)
eb8c3be9 556 "Return the label of the bibtex entry containing, or preceding point.
9ae11a89
ER
557Optional argument INCLUDE-CITE, if true means put a '\\cite{}' around the
558returned value. Second optional argument KILL, if true, means place the
559returned value in the kill buffer. Interactively; providing prefix
560argument makes INCLUDE-CITE true, and kill is true by default.
561
562Rationale:
563The intention is that someone will write a function that can be bound to
564a mouse key so that people entering TeX can just mouse on the bibtex entry
565and have the citation key inserted at the current point (which will almost
eb8c3be9 566certainly be in some other buffer). In the interim this function is
9ae11a89
ER
567marginally useful for keyboard binding and is not bound by default.
568Suggested binding is ^C-k."
569 (interactive (list current-prefix-arg t))
570 (save-excursion
571 (beginning-of-bibtex-entry)
572 (re-search-forward bibtex-reference-head (save-excursion (end-of-bibtex-entry) (point)))
573 (let* ((key (buffer-substring (match-beginning bibtex-key-in-head)
574 (match-end bibtex-key-in-head)))
575 (val (if include-cite
576 (format "\\cite{%s}" key)
577 key)))
578 (if kill
579 (put-string-on-kill-ring val))
580 val)))
581
745bc783
JB
582;;; bibtex mode:
583
81354e19 584;;;###autoload
745bc783
JB
585(defun bibtex-mode ()
586 "Major mode for editing bibtex files.
587
588\\{bibtex-mode-map}
589
590A command such as \\[bibtex-Book] will outline the fields for a BibTeX book entry.
591
592The optional fields start with the string OPT, and thus ignored by BibTeX.
593The OPT string may be removed from a field with \\[bibtex-remove-OPT].
594\\[bibtex-kill-optional-field] kills the current optional field entirely.
595\\[bibtex-remove-double-quotes] removes the double-quotes around the text of
596the current field. \\[bibtex-empty-field] replaces the text of the current
597field with the default \"\".
598
599The command \\[bibtex-clean-entry] cleans the current entry, i.e. (i) removes
600double-quotes from entirely numerical fields, (ii) removes OPT from all
601non-empty optional fields, (iii) removes all empty optional fields, and (iv)
602checks that no non-optional fields are empty.
603
604Use \\[bibtex-find-text] to position the dot at the end of the current field.
605Use \\[bibtex-next-field] to move to end of the next field.
606
9ae11a89
ER
607The following may be of interest as well:
608
609 Functions:
610 find-bibtex-duplicates
611 find-bibtex-entry-location
612 hide-bibtex-entry-bodies
613 sort-bibtex-entries
614 validate-bibtex-buffer
615
616 Variables:
617 bibtex-clean-entry-zap-empty-opts
618 bibtex-entry-field-alist
619 bibtex-include-OPTannote
620 bibtex-include-OPTcrossref
621 bibtex-include-OPTkey
622 bibtex-maintain-sorted-entries
623 bibtex-mode-user-optional-fields
624
745bc783
JB
625Fields:
626 address
e5167999 627 Publisher's address
745bc783
JB
628 annote
629 Long annotation used for annotated bibliographies (begins sentence)
630 author
631 Name(s) of author(s), in BibTeX name format
632 booktitle
633 Book title when the thing being referenced isn't the whole book.
634 For book entries, the title field should be used instead.
635 chapter
e5167999 636 Chapter number
745bc783
JB
637 crossref
638 The database key of the entry being cross referenced.
639 edition
9ae11a89 640 Edition of a book (e.g., \"second\")
745bc783
JB
641 editor
642 Name(s) of editor(s), in BibTeX name format.
643 If there is also an author field, then the editor field should be
644 for the book or collection that the work appears in
645 howpublished
646 How something strange has been published (begins sentence)
647 institution
648 Sponsoring institution
649 journal
650 Journal name (macros are provided for many)
651 key
e5167999 652 Alphabetizing and labeling key (needed when no author or editor)
745bc783
JB
653 month
654 Month (macros are provided)
655 note
656 To help the reader find a reference (begins sentence)
657 number
658 Number of a journal or technical report
659 organization
660 Organization (sponsoring a conference)
661 pages
662 Page number or numbers (use `--' to separate a range)
663 publisher
664 Publisher name
665 school
666 School name (for theses)
667 series
668 The name of a series or set of books.
669 An individual book will will also have it's own title
670 title
671 The title of the thing being referenced
672 type
9ae11a89
ER
673 Type of a technical report (e.g., \"Research Note\") to be used
674 instead of the default \"Technical Report\"
745bc783
JB
675 volume
676 Volume of a journal or multivolume work
677 year
678 Year---should contain only numerals
679---------------------------------------------------------
680Entry to this mode calls the value of bibtex-mode-hook if that value is
681non-nil."
682 (interactive)
683 (kill-all-local-variables)
9ae11a89 684 (set-syntax-table bibtex-mode-syntax-table)
745bc783
JB
685 (use-local-map bibtex-mode-map)
686 (setq major-mode 'bibtex-mode)
745bc783
JB
687 (setq mode-name "BibTeX")
688 (set-syntax-table bibtex-mode-syntax-table)
689 (setq local-abbrev-table bibtex-mode-abbrev-table)
690 (make-local-variable 'paragraph-start)
691 (setq paragraph-start "^[ \f\n\t]*$")
eb8c3be9 692 (auto-fill-mode 1) ; nice alignments
745bc783
JB
693 (setq left-margin (+ bibtex-text-alignment 1))
694
695 (run-hooks 'bibtex-mode-hook))
696
697(defun bibtex-move-outside-of-entry ()
698 "Make sure we are outside of a bib entry"
699 (cond ((or
700 (= (point) (point-max))
701 (= (point) (point-min))
702 (looking-at "[ \n]*@")
703 )
704 t)
705 (t
706 (backward-paragraph)
707 (forward-paragraph)))
e5167999
ER
708 (re-search-forward "[ \t\n]*" (point-max) t))
709
710(defun ispell-abstract ()
711 (interactive)
712 (beginning-of-bibtex-entry)
713 (re-search-forward "^[ \t]*[OPT]*abstract[ \t]*=")
714 (ispell-region (point)
715 (save-excursion (forward-sexp) (point))))
716
717(defun beginning-of-bibtex-entry ()
718 (interactive)
719 (re-search-backward "^@" nil 'move))
720
9ae11a89
ER
721(defun skip-whitespace-and-comments ()
722 ;; It might be a good idea to have forward-sexp with argument 0 do what
723 ;; this function tries to do, namely skip whitespace and comments.
724 ;; Maybe a better name for this would be skip-to-next-sexp.
725 ;; alternative implementation:
726 ;; (let ((parse-sexp-ignore-comments t))
727 ;; (forward-sexp 1)
728 ;; (forward-sexp -1))
729 ;; but I've had problems with this not getting the parse of comments
730 ;; right going backward if they contain unbalanced expressions or string
731 ;; quotes. [alarson:19920217.1021CST]
732 (let ((md (match-data)))
733 (unwind-protect
734 (while (cond ((looking-at "\\s>+\\|\\s +")
735 ;; was whitespace
736 ;; NOTE: also checked end-comment. In latex and
737 ;; lisp modes, newline is an end comment, but it
738 ;; should also be a whitespace char.
739 (goto-char (match-end 0)))
740 ;; If looking at beginning of comment, skip to end.
741 ((looking-at "\\s<")
742 (re-search-forward "\\s>"))))
743 (store-match-data md))))
744
745;;; [alarson:19920214.1007CST]
e5167999 746(defun end-of-bibtex-entry ()
9ae11a89
ER
747 "If inside an entry, move to the end of it, otherwise move to the end
748of the next entry."
e5167999 749 (interactive)
9ae11a89
ER
750 ;; if point was previously at the end of an entry, this puts us
751 ;; inside the next entry, otherwise we remain in the current one.
752 (progn
753 (skip-whitespace-and-comments)
754;;; (skip-chars-forward " \t\n")
755 (end-of-line))
756 (beginning-of-bibtex-entry)
757 (let ((parse-sexp-ignore-comments t))
758 (forward-sexp) ; skip entry type
759 (forward-sexp) ; skip entry body
760 ))
761;(defun end-of-bibtex-entry ()
762; (interactive)
763; (re-search-forward "}$" nil 'move))
e5167999
ER
764
765(defun ispell-bibtex-entry ()
766 (interactive)
767 (ispell-region (progn (beginning-of-bibtex-entry) (point))
768 (progn (end-of-bibtex-entry) (point))))
769
770(defun narrow-to-bibtex-entry ()
771 (interactive)
772 (save-excursion
773 (narrow-to-region (progn (beginning-of-bibtex-entry) (point))
774 (progn (end-of-bibtex-entry) (point)))))
775
776
777(defun beginning-of-first-bibtex-entry ()
778 (goto-char (point-min))
779 (cond
780 ((re-search-forward "^@" nil 'move)
781 (beginning-of-line))
782 ((and (bobp) (eobp))
783 nil)
784 (t
785 (message "Warning: No bibtex entries found!"))))
786
787(defun hide-bibtex-entry-bodies (&optional arg)
788 "Hide all lines between first and last bibtex entries not beginning with @.
789With argument, show all text."
790 (interactive "P")
9ae11a89
ER
791 (save-excursion
792 (beginning-of-first-bibtex-entry)
793 ;; subst-char-in-region modifies the buffer, despite what the
794 ;; documentation says...
795 (let ((modifiedp (buffer-modified-p))
796 (buffer-read-only nil))
797 (if arg
798 (subst-char-in-region (point) (point-max) ?\r ?\n t)
e5167999
ER
799 (while (save-excursion (re-search-forward "\n[^@]" (point-max) t))
800 (save-excursion (replace-regexp "\n\\([^@]\\)" "\r\\1"))))
9ae11a89
ER
801 (setq selective-display (not arg))
802 (set-buffer-modified-p modifiedp))))
803
804(defvar bibtex-sort-ignore-string-entries nil
805 "*If true, bibtex @STRING entries are ignored when determining ordering
806of the buffer (e.g. sorting, locating alphabetical position for new entries,
807etc.)")
e5167999
ER
808
809(defun sort-bibtex-entries ()
810 "Sort bibtex entries alphabetically by key.
9ae11a89
ER
811Text before the first bibtex entry, and following the last is not affected.
812If bibtex-sort-ignore-string-entries is true, @string entries will be ignored.
813
e5167999
ER
814Bugs:
815 1. Text between the closing brace ending one bibtex entry, and the @ starting
eb8c3be9 816 the next, is considered part of the PRECEDING entry. Perhaps it should be
e5167999
ER
817 part of the following entry."
818 (interactive)
819 (save-restriction
820 (beginning-of-first-bibtex-entry)
821 (narrow-to-region (point)
822 (save-excursion
823 (goto-char (point-max))
824 (beginning-of-bibtex-entry)
825 (end-of-bibtex-entry)
826 (point)))
827 (sort-subr nil ; reversep
eb8c3be9 828 ;; beginning of record function
e5167999
ER
829 'forward-line
830 ;; end of record function
9ae11a89 831 (function (lambda () (and (re-search-forward "}\\s-*\n[\n \t]*@" nil 'move)
e5167999
ER
832 (forward-char -2))))
833 ;; start of key function
9ae11a89
ER
834 (if bibtex-sort-ignore-string-entries
835 (function (lambda ()
836 (while (and (re-search-forward "^\\s-*\\([@a-zA-Z]*\\)\\s-*{\\s-*")
837 (string-equalp "@string"
838 (buffer-substring (match-beginning 1)
839 (match-end 1)))))
840 nil))
841 (function (lambda () (re-search-forward "{\\s-*") nil)))
e5167999
ER
842 ;; end of key function
843 (function (lambda () (search-forward ",")))
844 )))
845
846(defun map-bibtex-entries (fun)
847 "Call FUN for each bibtex entry starting with the current, to the end of the file.
9ae11a89
ER
848FUN is called with one argument, the key of the entry, and with point inside the entry.
849If bibtex-sort-ignore-string-entries is true, FUN will not be called for @string entries."
e5167999 850 (beginning-of-bibtex-entry)
9ae11a89
ER
851 (while (re-search-forward "^@[^{]*{[ \t]*\\([^, ]*\\)" nil t)
852 (if (and bibtex-sort-ignore-string-entries
853 (string-equalp "@string{"
854 (buffer-substring (match-beginning 0)
855 (match-beginning 1))))
856 nil ; ignore the @string entry.
857 (funcall fun (buffer-substring (match-beginning 1) (match-end 1))))))
e5167999
ER
858
859(defun find-bibtex-entry-location (entry-name)
e5167999
ER
860 "Searches from beginning of current buffer looking for place to put the
861bibtex entry named ENTRY-NAME. Buffer is assumed to be in sorted order,
862without duplicates (see \\[sort-bibtex-entries]), if it is not, an error will
863be signalled."
9ae11a89 864 (interactive "sBibtex entry key: ")
e5167999
ER
865 (let ((previous nil)
866 point)
867 (beginning-of-first-bibtex-entry)
868 (or (catch 'done
869 (map-bibtex-entries (function (lambda (current)
870 (cond
871 ((string-equal entry-name current)
872 (error "Entry duplicates existing!"))
873 ((or (null previous)
874 (string< previous current))
875 (setq previous current
876 point (point))
877 (if (string< entry-name current)
878 (progn
879 (beginning-of-bibtex-entry)
880 ;; Many schemes append strings to
881 ;; existing entries to resolve them,
882 ;; so initial substring matches may
883 ;; indicate a duplicate entry.
884 (let ((idx (string-match (regexp-quote entry-name) current)))
885 (if (and (integerp idx)
886 (zerop idx))
887 (progn
888 (message "Warning: Entry %s may be a duplicate of %s!"
889 entry-name current)
890 (ding t))))
891 (throw 'done t))))
892 ((string-equal previous current)
893 (error "Duplicate here with previous!"))
894 (t (error "Entries out of order here!")))))))
895 (end-of-bibtex-entry))))
896
897(defun validate-bibtex-buffer ()
898 "Find some typical errors in bibtex files.
899 1. At signs (@) not as first char of a line.
900 2. Double quotes (\") inside strings.
901 3. Closing braces (}) not the last character of a line."
902 (interactive)
903 (let ((point (point)))
904 (while (re-search-forward ".@" nil t)
905 (let* ((foo (parse-partial-sexp (save-excursion (beginning-of-bibtex-entry)
906 (point))
907 (point)))
908 (in-a-string (nth 3 foo)))
909 (if (not in-a-string)
910 (error "At sign (@) out of place!"))))
911 (goto-char point)
912 (while (search-forward "\"" nil t)
913 (or (looking-at "[,}][ \t]*$")
9ae11a89 914 (char-equal (preceding-char) ?\")
e5167999
ER
915 ;; some versions put closing brace on separate line.
916 (looking-at "[ \t]*\n}")
917 (save-excursion
918 (save-restriction
919 (narrow-to-region (point)
920 (progn (beginning-of-line) (point)))
921 (looking-at "^[ \t]*[a-zA-Z]+[ \t]*=[ \t]*\"$")))
922 (error "Quote out of place, or missing \",\" or \"}\"!")))
923 (goto-char point)
924 ;; This is only approximate, should actually search for close braces,
925 ;; then see if they are inside a string, or at the end of a line.
926 ;; This just gets the typical case of whitespace after a closing brace.
927 (while (search-forward "}[ \t]+$" nil t)
928 (error "Brace not last char of line!"))
929 (goto-char point)
930 (message "Bibtex buffer appears o.k.")))
931
932(defun find-bibtex-duplicates ()
933 "Searches forward in current buffer looking for duplicate bibtex entries.
934Buffer is assumed to be sorted, see \\[sort-bibtex-entries]"
935 (interactive)
936 (let ((point (point)))
937 ;; errors if things are not right...
938 (find-bibtex-entry-location (make-string 10 255))
939 (goto-char point)
940 (message "No duplicates found!")))
941
942
9ae11a89
ER
943;;; assoc doesn't ignore case, so we need an assoc that does...
944(defun assoc-string-equalp (thing alist)
945 (or (assoc thing alist)
946 (while (and alist
947 (not (string-equalp thing (car (car alist)))))
948 (setq alist (cdr alist)))
949 (car alist)))
950
e5167999
ER
951(defvar bibtex-maintain-sorted-entries nil
952 "*If true, bibtex-mode will attempt to maintain all bibtex entries in
9ae11a89
ER
953sorted order.
954
955Note that this is more a property of a file than a personal preference and
956as such should normally be set via a file local variable entry.")
957
958(defun bibtex-entry (entry-type &optional required optional)
959 (interactive (let* ((completion-ignore-case t)
960 (e-t (completing-read "Entry Type: " bibtex-entry-field-alist
961 nil t)))
962 (list e-t)))
963 (if (and (null required) (null optional))
964 (let* ((e (assoc-string-equalp entry-type bibtex-entry-field-alist))
965 (r-n-o (elt e 1))
966 (c-ref (elt e 2)))
967 (if (null e)
968 (error "Bibtex entry type %s not defined!"))
969 (if (and bibtex-include-OPTcrossref c-ref)
970 (setq required (elt c-ref 0)
971 optional (elt c-ref 1))
972 (setq required (elt r-n-o 0)
973 optional (elt r-n-o 1)))))
974 (let ((key (if bibtex-maintain-sorted-entries
975 (read-string (format "%s key: " entry-type)))))
976 (if key
977 (find-bibtex-entry-location key))
e5167999
ER
978 (bibtex-move-outside-of-entry)
979 (insert "@" entry-type "{")
e5167999 980 (if key
9ae11a89
ER
981 (insert key))
982 (save-excursion
983 (mapcar 'bibtex-make-field required)
984 (if bibtex-include-OPTcrossref
985 (bibtex-make-optional-field "crossref"))
986 (if bibtex-include-OPTkey
987 (bibtex-make-optional-field "key"))
988 (mapcar 'bibtex-make-optional-field optional)
989 (mapcar 'bibtex-make-optional-field
990 bibtex-mode-user-optional-fields)
991 (if bibtex-include-OPTannote
992 (bibtex-make-optional-field "annote"))
993 (insert "\n}\n\n"))
994 (if key
995 (bibtex-next-field t))
996 (run-hooks 'bibtex-add-entry-hook)))
e5167999
ER
997
998;; (defun bibtex-entry (entry-type required optional)
999;; (bibtex-move-outside-of-entry)
1000;; (insert (concat "@" entry-type "{,\n\n}\n\n"))
1001;; (previous-line 3)
1002;; (insert (mapconcat 'bibtex-make-entry required ",\n"))
1003;; (if required
1004;; (if optional
1005;; (insert ",\n")))
1006;; (insert (mapconcat 'bibtex-make-OPT-entry optional ",\n"))
1007;; (if bibtex-mode-user-optional-fields ;MON...
1008;; (progn
1009;; (if optional
1010;; (insert ",\n"))
1011;; (insert (mapconcat 'bibtex-make-OPT-entry
1012;; bibtex-mode-user-optional-fields
1013;; ",\n")))) ;MON
1014;; (up-list -1)
1015;; (forward-char 1))
1016
d30bfc76 1017
9ae11a89 1018(defun bibtex-make-field (e-t)
745bc783 1019 (interactive "sBibTeX entry type: ")
9ae11a89
ER
1020 (let ((name (if (consp e-t) (car e-t) e-t))
1021 (value (if (consp e-t) (cdr e-t) "")))
1022 (insert ",\n")
93d35499 1023 (indent-to-column bibtex-name-alignment)
9ae11a89
ER
1024 (insert name " = ")
1025 (indent-to-column bibtex-text-alignment)
1026 ;; lucid emacs prin1-to-string breaks the undo chain. When they fix
1027 ;; that, the hack can be removed. [alarson:19930316.0805CST]
1028; (insert (prin1-to-string value))
1029 ;; begin hack
1030 (insert (format (if (stringp value) "\"%s\"" "%s")
1031 value))
1032 ;; end hack
1033 nil))
1034
1035(defun bibtex-make-optional-field (e-t)
745bc783 1036 (interactive "sOptional BibTeX entry type: ")
9ae11a89
ER
1037 (if (consp e-t)
1038 (setq e-t (cons (concat "OPT" (car e-t)) (cdr e-t)))
1039 (setq e-t (concat "OPT" e-t)))
1040 (bibtex-make-field e-t))
745bc783
JB
1041
1042;; What to do about crossref? if present, journal and year are
1043;; both optional. Due to this, i move all of them into optional. -- MON
1044
1045(defun bibtex-Article ()
1046 (interactive)
9ae11a89 1047 (bibtex-entry "Article"))
e5167999 1048
745bc783
JB
1049(defun bibtex-Book ()
1050 (interactive)
9ae11a89 1051 (bibtex-entry "Book"))
745bc783
JB
1052
1053(defun bibtex-Booklet ()
1054 (interactive)
9ae11a89 1055 (bibtex-entry "Booklet"))
745bc783 1056
9ae11a89
ER
1057;(defun bibtex-DEAthesis ()
1058; (interactive)
1059; (bibtex-entry "DEAthesis"))
745bc783
JB
1060
1061(defun bibtex-InBook ()
1062 (interactive)
9ae11a89 1063 (bibtex-entry "InBook"))
745bc783 1064
745bc783
JB
1065(defun bibtex-InCollection ()
1066 (interactive)
9ae11a89 1067 (bibtex-entry "InCollection"))
e5167999 1068
745bc783
JB
1069(defun bibtex-InProceedings ()
1070 (interactive)
9ae11a89 1071 (bibtex-entry "InProceedings"))
e5167999 1072
745bc783
JB
1073(defun bibtex-Manual ()
1074 (interactive)
9ae11a89 1075 (bibtex-entry "Manual"))
745bc783
JB
1076
1077(defun bibtex-MastersThesis ()
1078 (interactive)
9ae11a89 1079 (bibtex-entry "MastersThesis"))
745bc783
JB
1080
1081(defun bibtex-Misc ()
1082 (interactive)
9ae11a89 1083 (bibtex-entry "Misc"))
745bc783
JB
1084
1085(defun bibtex-PhdThesis ()
1086 (interactive)
9ae11a89 1087 (bibtex-entry "PhdThesis"))
745bc783
JB
1088
1089(defun bibtex-Proceedings ()
1090 (interactive)
9ae11a89 1091 (bibtex-entry "Proceedings"))
745bc783
JB
1092
1093(defun bibtex-TechReport ()
1094 (interactive)
9ae11a89 1095 (bibtex-entry "TechReport"))
745bc783 1096
745bc783
JB
1097(defun bibtex-Unpublished ()
1098 (interactive)
9ae11a89 1099 (bibtex-entry "Unpublished"))
745bc783
JB
1100
1101(defun bibtex-string ()
1102 (interactive)
1103 (bibtex-move-outside-of-entry)
6f680efb 1104 (insert "@string{ = \"\"}\n")
745bc783
JB
1105 (previous-line 1)
1106 (forward-char 8))
1107
1108(defun bibtex-preamble ()
1109 (interactive)
1110 (bibtex-move-outside-of-entry)
1111 (insert "@Preamble{}\n")
1112 (previous-line 1)
1113 (forward-char 10))
1114\f
1115(defun bibtex-next-field (arg)
1116 "Finds end of text of next BibTeX field; with arg, to its beginning"
1117 (interactive "P")
1118 (bibtex-inside-field)
1119 (let ((start (point)))
1120 (condition-case ()
1121 (progn
1122 (bibtex-enclosing-field)
1123 (goto-char (match-end 0))
1124 (forward-char 2))
1125 (error
1126 (goto-char start)
1127 (end-of-line)
1128 (forward-char 1))))
1129 (bibtex-find-text arg))
1130
e5167999
ER
1131;; (defun bibtex-next-field ()
1132;; "Finds end of text of next field."
1133;; (interactive)
1134;; (condition-case ()
1135;; (progn
1136;; (bibtex-inside-field)
1137;; (re-search-forward ",[ \t\n]*" (point-max) 1)
1138;; (bibtex-enclosing-field)
1139;; (bibtex-inside-field))
1140;; (error nil)))
1141
745bc783
JB
1142(defun bibtex-find-text (arg)
1143 "Go to end of text of current field; with arg, go to beginning."
1144 (interactive "P")
1145 (bibtex-inside-field)
1146 (bibtex-enclosing-field)
1147 (if arg
1148 (progn
1149 (goto-char (match-beginning bibtex-text-in-field))
e5167999 1150 (if (looking-at "\"")
745bc783
JB
1151 (forward-char 1)))
1152 (goto-char (match-end bibtex-text-in-field))
e5167999 1153 (if (= (preceding-char) ?\")
745bc783
JB
1154 (forward-char -1))))
1155
e5167999
ER
1156;; (defun bibtex-find-text ()
1157;; "Go to end of text of current field."
1158;; (interactive)
1159;; (condition-case ()
1160;; (progn
1161;; (bibtex-inside-field)
1162;; (bibtex-enclosing-field)
1163;; (goto-char (match-end bibtex-text-in-field))
1164;; (bibtex-inside-field))
1165;; (error nil)))
1166
745bc783
JB
1167(defun bibtex-remove-OPT ()
1168 "Removes the 'OPT' starting optional arguments and goes to end of text"
1169 (interactive)
1170 (bibtex-inside-field)
1171 (bibtex-enclosing-field)
1172 (save-excursion
1173 (goto-char (match-beginning bibtex-name-in-field))
1174 (if (looking-at "OPT")
9ae11a89
ER
1175 ;; sct@dcs.edinburgh.ac.uk
1176 (progn
1177 (delete-char (length "OPT"))
1178 (search-forward "=")
1179 (delete-horizontal-space)
1180 (indent-to-column bibtex-text-alignment))))
745bc783
JB
1181 (bibtex-inside-field))
1182
1183(defun bibtex-inside-field ()
1184 "Try to avoid point being at end of a bibtex field."
1185 (interactive)
1186 (end-of-line)
e5167999 1187 (skip-chars-backward " \t") ;MON - maybe delete these chars?
745bc783 1188 (cond ((= (preceding-char) ?,)
9ae11a89 1189 (forward-char -2))) ; -1 --> -2 sct@dcs.edinburgh.ac.uk
e5167999
ER
1190 (cond ((= (preceding-char) ?\")
1191 (forward-char -1)))) ;MON - only go back if quote
745bc783
JB
1192
1193(defun bibtex-remove-double-quotes ()
9ae11a89 1194 "Removes \"\" around string."
745bc783
JB
1195 (interactive)
1196 (save-excursion
1197 (bibtex-inside-field)
1198 (bibtex-enclosing-field)
1199 (let ((start (match-beginning bibtex-text-in-field))
1200 (stop (match-end bibtex-text-in-field)))
1201 (goto-char stop)
1202 (forward-char -1)
1203 (if (looking-at "\"")
1204 (delete-char 1))
1205 (goto-char start)
1206 (if (looking-at "\"")
1207 (delete-char 1)))))
1208
1209(defun bibtex-kill-optional-field ()
1210 "Kill the entire enclosing optional BibTeX field"
1211 (interactive)
1212 (bibtex-inside-field)
1213 (bibtex-enclosing-field)
1214 (goto-char (match-beginning bibtex-name-in-field))
1215 (let ((the-end (match-end 0))
1216 (the-beginning (match-beginning 0)))
1217 (if (looking-at "OPT")
1218 (progn
1219 (goto-char the-end)
1220 (skip-chars-forward " \t\n,")
1221 (kill-region the-beginning the-end))
1222 (error "Mandatory fields can't be killed"))))
1223
1224(defun bibtex-empty-field ()
1225 "Delete the text part of the current field, replace with empty text"
1226 (interactive)
1227 (bibtex-inside-field)
1228 (bibtex-enclosing-field)
1229 (goto-char (match-beginning bibtex-text-in-field))
1230 (kill-region (point) (match-end bibtex-text-in-field))
1231 (insert "\"\"")
1232 (bibtex-find-text t))
1233
1234\f
1235(defun bibtex-pop-previous (arg)
1236 "Replace text of current field with the text of similar field in previous entry.
1237With arg, go up ARG entries. Repeated, goes up so many times. May be
1238intermixed with \\[bibtex-pop-next] (bibtex-pop-next)."
1239 (interactive "p")
1240 (bibtex-inside-field)
1241 (save-excursion
1242 ; parse current field
1243 (bibtex-enclosing-field)
1244 (let ((start-old-text (match-beginning bibtex-text-in-field))
1245 (stop-old-text (match-end bibtex-text-in-field))
1246 (start-name (match-beginning bibtex-name-in-field))
1247 (stop-name (match-end bibtex-name-in-field))
1248 (new-text))
1249 (goto-char start-name)
1250 ; construct regexp for previous field with same name as this one
1251 (let ((matching-entry
1252 (bibtex-cfield
1253 (buffer-substring (if (looking-at "OPT")
1254 (+ (point) (length "OPT"))
1255 (point))
1256 stop-name)
1257 bibtex-field-text)))
1258
1259 ; if executed several times in a row, start each search where the
1260 ; last one finished
1261 (cond ((or (eq last-command 'bibtex-pop-previous)
1262 (eq last-command 'bibtex-pop-next))
1263 t
1264 )
1265 (t
1266 (bibtex-enclosing-reference)
1267 (setq bibtex-pop-previous-search-point (match-beginning 0))
1268 (setq bibtex-pop-next-search-point (match-end 0))))
1269 (goto-char bibtex-pop-previous-search-point)
1270
1271 ; Now search for arg'th previous similar field
1272 (cond
1273 ((re-search-backward matching-entry (point-min) t arg)
1274 (setq new-text
1275 (buffer-substring (match-beginning bibtex-text-in-cfield)
1276 (match-end bibtex-text-in-cfield)))
1277 ; Found a matching field. Remember boundaries.
1278 (setq bibtex-pop-next-search-point (match-end 0))
1279 (setq bibtex-pop-previous-search-point (match-beginning 0))
1280 (bibtex-flash-head)
1281 ; Go back to where we started, delete old text, and pop new.
1282 (goto-char stop-old-text)
1283 (delete-region start-old-text stop-old-text)
1284 (insert new-text))
1285 (t ; search failed
1286 (error "No previous matching BibTeX field."))))))
1287 (setq this-command 'bibtex-pop-previous))
1288
1289(defun bibtex-pop-next (arg)
1290 "Replace text of current field with the text of similar field in next entry.
1291With arg, go up ARG entries. Repeated, goes up so many times. May be
1292intermixed with \\[bibtex-pop-previous] (bibtex-pop-previous)."
1293 (interactive "p")
1294 (bibtex-inside-field)
1295 (save-excursion
1296 ; parse current field
1297 (bibtex-enclosing-field)
1298 (let ((start-old-text (match-beginning bibtex-text-in-field))
1299 (stop-old-text (match-end bibtex-text-in-field))
1300 (start-name (match-beginning bibtex-name-in-field))
1301 (stop-name (match-end bibtex-name-in-field))
1302 (new-text))
1303 (goto-char start-name)
1304 ; construct regexp for next field with same name as this one,
1305 ; ignoring possible OPT's
1306 (let ((matching-entry
1307 (bibtex-cfield
1308 (buffer-substring (if (looking-at "OPT")
1309 (+ (point) (length "OPT"))
1310 (point))
1311 stop-name)
1312 bibtex-field-text)))
1313
1314 ; if executed several times in a row, start each search where the
1315 ; last one finished
1316 (cond ((or (eq last-command 'bibtex-pop-next)
1317 (eq last-command 'bibtex-pop-previous))
1318 t
1319 )
1320 (t
1321 (bibtex-enclosing-reference)
1322 (setq bibtex-pop-previous-search-point (match-beginning 0))
1323 (setq bibtex-pop-next-search-point (match-end 0))))
1324 (goto-char bibtex-pop-next-search-point)
1325
1326 ; Now search for arg'th next similar field
1327 (cond
1328 ((re-search-forward matching-entry (point-max) t arg)
1329 (setq new-text
1330 (buffer-substring (match-beginning bibtex-text-in-cfield)
1331 (match-end bibtex-text-in-cfield)))
1332 ; Found a matching field. Remember boundaries.
1333 (setq bibtex-pop-next-search-point (match-end 0))
1334 (setq bibtex-pop-previous-search-point (match-beginning 0))
1335 (bibtex-flash-head)
1336 ; Go back to where we started, delete old text, and pop new.
1337 (goto-char stop-old-text)
1338 (delete-region start-old-text stop-old-text)
1339 (insert new-text))
1340 (t ; search failed
1341 (error "No next matching BibTeX field."))))))
1342 (setq this-command 'bibtex-pop-next))
1343
1344(defun bibtex-flash-head ()
1345 "Flash at BibTeX reference head before point, if exists. (Moves point)."
1346 (let ((flash))
1347 (cond ((re-search-backward bibtex-reference-head (point-min) t)
1348 (goto-char (match-beginning bibtex-type-in-head))
1349 (setq flash (match-end bibtex-key-in-reference)))
1350 (t
1351 (end-of-line)
1352 (skip-chars-backward " \t")
1353 (setq flash (point))
1354 (beginning-of-line)
1355 (skip-chars-forward " \t")))
1356 (if (pos-visible-in-window-p (point))
1357 (sit-for 1)
1358 (message "From: %s"
1359 (buffer-substring (point) flash)))))
1360
1361
1362\f
1363(defun bibtex-enclosing-field ()
1364 "Search for BibTeX field enclosing point.
1365Point moves to end of field; also, use match-beginning and match-end
1366to parse the field."
9ae11a89
ER
1367 ;; sct@dcs.edinburgh.ac.uk
1368 (let ((old-point (point)))
1369 (condition-case errname
1370 (bibtex-enclosing-regexp bibtex-field)
1371 (search-failed
1372 (goto-char old-point)
1373 (error "Can't find enclosing BibTeX field.")))))
745bc783
JB
1374
1375(defun bibtex-enclosing-reference ()
1376 "Search for BibTeX reference enclosing point.
1377Point moves to end of reference; also, use match-beginning and match-end
1378to parse the reference."
9ae11a89
ER
1379 ;; sct@dcs.edinburgh.ac.uk
1380 (let ((old-point (point)))
1381 (condition-case errname
1382 (bibtex-enclosing-regexp bibtex-reference)
1383 (search-failed
1384 (goto-char old-point)
1385 (error "Can't find enclosing BibTeX reference.")))))
745bc783
JB
1386
1387(defun bibtex-enclosing-regexp (regexp)
1388 "Search for REGEXP enclosing point.
1389Point moves to end of REGEXP. See also match-beginning and match-end.
1390If an enclosing REGEXP is not found, signals search-failed; point is left in
1391an undefined location.
1392
1393[Doesn't something like this exist already?]"
1394
1395 (interactive "sRegexp: ")
1396 ; compute reasonable limits for the loop
1397 (let* ((initial (point))
1398 (right (if (re-search-forward regexp (point-max) t)
1399 (match-end 0)
1400 (point-max)))
1401 (left
1402 (progn
1403 (goto-char initial)
1404 (if (re-search-backward regexp (point-min) t)
1405 (match-beginning 0)
1406 (point-min)))))
1407 ; within the prescribed limits, loop until a match is found
1408 (goto-char left)
1409 (re-search-forward regexp right nil 1)
1410 (if (> (match-beginning 0) initial)
1411 (signal 'search-failed (list regexp)))
e5167999 1412 (while (<= (match-end 0) initial)
745bc783
JB
1413 (re-search-forward regexp right nil 1)
1414 (if (> (match-beginning 0) initial)
1415 (signal 'search-failed (list regexp))))
1416 ))
1417
1418(defun bibtex-clean-entry ()
1419 "For all optional fields of current BibTeX entry: if empty, kill the whole field; otherwise, remove the \"OPT\" string in the name; if text numerical, remove double-quotes. For all mandatory fields: if empty, signal error."
1420 (interactive)
9ae11a89 1421 (beginning-of-bibtex-entry)
745bc783
JB
1422 (let ((start (point)))
1423 (save-restriction
9ae11a89 1424 (narrow-to-region start (save-excursion (end-of-bibtex-entry) (point)))
745bc783
JB
1425 (while (re-search-forward bibtex-field (point-max) t 1)
1426 (let ((begin-field (match-beginning 0))
1427 (end-field (match-end 0))
1428 (begin-name (match-beginning bibtex-name-in-field))
1429 (end-name (match-end bibtex-name-in-field))
1430 (begin-text (match-beginning bibtex-text-in-field))
1431 (end-text (match-end bibtex-text-in-field))
1432 )
1433 (goto-char begin-name)
1434 (cond ((and
1435 (looking-at "OPT")
1436 bibtex-clean-entry-zap-empty-opts)
1437 (goto-char begin-text)
e5167999 1438 (if (looking-at "\"\"") ; empty: delete whole field
745bc783 1439 (delete-region begin-field end-field)
e5167999 1440 ; otherwise: not empty, delete "OPT"
745bc783
JB
1441 (goto-char begin-name)
1442 (delete-char (length "OPT"))
9ae11a89
ER
1443 (progn
1444 ;; fixup alignment. [alarson:19920309.2047CST]
1445 (search-forward "=")
1446 (delete-horizontal-space)
1447 (indent-to-column bibtex-text-alignment))
745bc783
JB
1448 (goto-char begin-field) ; and loop to go through next test
1449 ))
1450 (t
1451 (goto-char begin-text)
1452 (cond ((looking-at "\"[0-9]+\"") ; if numerical,
1453 (goto-char end-text)
1454 (delete-char -1) ; delete enclosing double-quotes
1455 (goto-char begin-text)
1456 (delete-char 1)
1457 (goto-char end-field) ; go to end for next search
1458 (forward-char -2) ; to compensate for the 2 quotes deleted
1459 )
1460 ((looking-at "\"\"") ; if empty quotes, complain
1461 (forward-char 1)
1462 (if (not (or (equal (buffer-substring
1463 begin-name
1464 (+ begin-name 3))
1465 "OPT")
1466 (equal (buffer-substring
1467 begin-name
1468 (+ begin-name 3))
e5167999 1469 "opt")))
745bc783
JB
1470 (error "Mandatory field ``%s'' is empty"
1471 (buffer-substring begin-name end-name))))
1472 (t
1473 (goto-char end-field))))))))
1474 (goto-char start)
9ae11a89
ER
1475 (end-of-bibtex-entry)
1476 ;; sct@dcs.edinburgh.ac.uk
1477 (save-excursion
1478 (previous-line 1)
1479 (end-of-line)
1480 (if (eq (preceding-char) ?,)
1481 (backward-delete-char 1)))
1482 (skip-whitespace-and-comments)))
745bc783
JB
1483
1484\f
2798dfd6
RS
1485;;; Menus for bibtex mode
1486
1487(define-key bibtex-mode-map [menu-bar entry-types]
93d35499 1488 (cons "Entry Types" (make-sparse-keymap "Entry Types")))
2798dfd6
RS
1489
1490(define-key bibtex-mode-map [menu-bar entry-types bibtex-InProceedings]
1491 '(" article in conference Proceedings " . bibtex-InProceedings))
1492(define-key bibtex-mode-map [menu-bar entry-types bibtex-Article]
1493 '(" Article in journal " . bibtex-Article))
1494(define-key bibtex-mode-map [menu-bar entry-types bibtex-Book]
1495 '(" Book " . bibtex-Book))
1496(define-key bibtex-mode-map [menu-bar entry-types bibtex-Booklet]
1497 '(" Booklet " . bibtex-Booklet))
1498(define-key bibtex-mode-map [menu-bar entry-types bibtex-InProceedings]
1499 '(" Conference " . bibtex-InProceedings))
1500(define-key bibtex-mode-map [menu-bar entry-types bibtex-MastersThesis]
1501 '(" Master's Thesis " . bibtex-MastersThesis))
1502;define-key bibtex-mode-map [menu-bar entry-types bibtex-DEAthesis]
93d35499 1503;'((" DEA Thesis " . bibtex-DEAthesis))
2798dfd6
RS
1504(define-key bibtex-mode-map [menu-bar entry-types bibtex-PhdThesis]
1505 '(" Phd. Thesis " . bibtex-PhdThesis))
1506(define-key bibtex-mode-map [menu-bar entry-types bibtex-TechReport]
1507 '(" Technical Report " . bibtex-TechReport))
1508(define-key bibtex-mode-map [menu-bar entry-types bibtex-Manual]
1509 '(" technical Manual " . bibtex-Manual))
1510(define-key bibtex-mode-map [menu-bar entry-types bibtex-Proceedings]
1511 '(" conference Proceedings " . bibtex-Proceedings))
1512(define-key bibtex-mode-map [menu-bar entry-types bibtex-InBook]
1513 '(" a chapter in a Book " . bibtex-InBook))
1514(define-key bibtex-mode-map [menu-bar entry-types bibtex-InCollection]
1515 '(" an article in a Collection " . bibtex-InCollection))
1516(define-key bibtex-mode-map [menu-bar entry-types bibtex-Misc]
1517 '(" miscellaneous " . bibtex-Misc))
1518(define-key bibtex-mode-map [menu-bar entry-types bibtex-Unpublished]
1519 '(" unpublished " . bibtex-Unpublished))
1520(define-key bibtex-mode-map [menu-bar entry-types bibtex-string]
1521 '(" string " . bibtex-string))
1522(define-key bibtex-mode-map [menu-bar entry-types bibtex-preamble]
1523 '(" preamble " . bibtex-preamble))
1524
1525(define-key bibtex-mode-map [menu-bar move/edit]
93d35499 1526 (cons "Bibtex Edit" (make-sparse-keymap "Bibtex Edit")))
2798dfd6
RS
1527
1528(define-key bibtex-mode-map [menu-bar move/edit bibtex-next-field]
1529 '(" next field " . bibtex-next-field))
1530(define-key bibtex-mode-map [menu-bar move/edit bibtex-find-text]
1531 '(" to end of field " . bibtex-find-text))
1532(define-key bibtex-mode-map [menu-bar move/edit bibtex-pop-previous]
1533 '("snatch from similar preceding field" . bibtex-pop-previous))
1534(define-key bibtex-mode-map [menu-bar move/edit bibtex-pop-next]
1535 '("snatch from similar following field" . bibtex-pop-next))
1536(define-key bibtex-mode-map [menu-bar move/edit bibtex-remove-OPT]
93d35499 1537 '(" remove OPT " . bibtex-remove-OPT))
2798dfd6
RS
1538(define-key bibtex-mode-map [menu-bar move/edit bibtex-remove-double-quotes]
1539 '(" remove quotes " . bibtex-remove-double-quotes))
1540(define-key bibtex-mode-map [menu-bar move/edit bibtex-clean-entry]
1541 '(" clean up entry " . bibtex-clean-entry))
93d35499
RS
1542(define-key bibtex-mode-map [menu-bar move/edit find-bibtex-duplicates]
1543 '(" find duplicates " . find-bibtex-duplicates))
1544(define-key bibtex-mode-map [menu-bar move/edit sort-bibtex-entries]
1545 '(" sort entries " . sort-bibtex-entries))
1546(define-key bibtex-mode-map [menu-bar move/edit validate-bibtex-buffer]
1547 '(" validate entries " . validate-bibtex-buffer))
745bc783
JB
1548\f
1549
1550;; Please don't send anything to bug-gnu-emacs about these Sunwindows functions
1551;; since we aren't interested. See etc/SUN-SUPPORT for the reasons why
1552;; we consider this nothing but a distraction from our work.
1553
9ae11a89
ER
1554;(defmacro eval-in-menu-window (&rest l)
1555; "Evaluates its argument in the window in which the mouse button was pressed."
1556; (list 'eval-in-window '*menu-window* l))
e5167999
ER
1557
1558;(defmenu bibtex-sun-entry-menu
1559; ("Article In Conf. Proc." eval-in-menu-window bibtex-InProceedings)
1560; ("Article In Journal" eval-in-menu-window bibtex-Article)
1561; ("Book" eval-in-menu-window bibtex-Book)
1562; ("Booklet" eval-in-menu-window bibtex-Booklet)
1563; ("Master's Thesis" eval-in-menu-window bibtex-MastersThesis)
1564; ("PhD. Thesis" eval-in-menu-window bibtex-PhdThesis)
1565; ("Technical Report" eval-in-menu-window bibtex-TechReport)
1566; ("Technical Manual" eval-in-menu-window bibtex-Manual)
1567; ("Conference Proceedings" eval-in-menu-window bibtex-Proceedings)
1568; ("In A Book" eval-in-menu-window bibtex-InBook)
1569; ("In A Collection" eval-in-menu-window bibtex-InCollection)
1570; ("Miscellaneous" eval-in-menu-window bibtex-Misc)
1571; ("Unpublished" eval-in-menu-window bibtex-Unpublished)
1572; ("string" eval-in-menu-window bibtex-string)
1573; ("preamble" eval-in-menu-window bibtex-preamble))
1574;
1575;(defmenu bibtex-sun-menu
1576; ("BibTeX menu")
1577; ("add entry" . bibtex-sun-entry-menu)
1578; ("next field" eval-in-menu-window bibtex-next-field nil)
1579; ("to end of field" eval-in-menu-window bibtex-find-text nil)
1580; ("snatch similar preceding field" eval-in-menu-window bibtex-pop-previous 1)
1581; ("snatch similar following field" eval-in-menu-window bibtex-pop-next 1)
1582; ("remove OPT" eval-in-menu-window bibtex-remove-OPT)
1583; ("remove quotes" eval-in-menu-window bibtex-remove-double-quotes)
1584; ("clean entry" eval-in-menu-window bibtex-clean-entry)
1585; ("describe BibTeX mode" eval-in-menu-window describe-mode)
1586; ("Main Emacs menu" . emacs-menu))
745bc783 1587
9ae11a89
ER
1588;(defun bibtex-sun-menu-eval (window x y)
1589; "Pop-up menu of BibTeX commands."
1590; (sun-menu-evaluate window (1+ x) (1- y) 'bibtex-sun-menu))
1591;
1592;(defun bibtex-sun-environment ()
1593; "Set up sun menus for BibTeX mode. Call it as bibtex-mode-hook, or
1594;interactively"
1595; (interactive)
1596; (local-set-mouse '(text right) 'bibtex-sun-menu-eval))
1597;
745bc783 1598
9ae11a89 1599;;; bibtex.el ends here