*** empty log message ***
[emacs.git] / lisp / textmodes / bibtex.el
blob2fd9889ff36096636e12eaf91348d07fa38927e8
1 ;;; bibtex.el --- BibTeX mode for GNU Emacs
3 ;; Author: Bengt Martensson <ubrinf!mond!bengt>
4 ;; Mark Shapiro <shapiro@corto.inria.fr>
5 ;; Mike Newton <newton@gumby.cs.caltech.edu>
6 ;; Aaron Larson <alarson@src.honeywell.com>
7 ;; Maintainer: Mark Shapiro <shapiro@corto.inria.fr>
8 ;; Keywords: tex, bib
10 ;; Copyright (C) 1992 Free Software Foundation, Inc.
12 ;; This file is part of GNU Emacs.
14 ;; GNU Emacs is free software; you can redistribute it and/or modify
15 ;; it under the terms of the GNU General Public License as published by
16 ;; the Free Software Foundation; either version 1, or (at your option)
17 ;; any later version.
19 ;; GNU Emacs is distributed in the hope that it will be useful,
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 ;; GNU General Public License for more details.
24 ;; You should have received a copy of the GNU General Public License
25 ;; along with GNU Emacs; see the file COPYING. If not, write to
26 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
28 ;;; Change Log:
30 ;;; alarson@src.honeywell.com 92-Jan-31
31 ;;; Added support for: ispell, beginning/end of entry movement, a simple
32 ;;; outline like mode (hide the bodies of bibtex entries), support for
33 ;;; sorting bibtex entries, and maintaining them in sorted order, and
34 ;;; simple buffer validation.
35 ;;; User visible functions added:
36 ;;; ispell-{abstract,bibtex-entry}, {beginning,end}-of-bibtex-entry
37 ;;; hide-bibtex-entry-bodies, sort-bibtex-entries, validate-bibtex-
38 ;;; buffer, find-bibtex-duplicates
39 ;;; user visible variables added:
40 ;;; bibtex-maintain-sorted-entries
41 ;;; new local keybindings:
42 ;;; " TeX-insert-quote
43 ;;; C-c$ ispell-bibtex-entry
44 ;;; M-C-a beginning-of-bibtex-entry
45 ;;; M-C-e end-of-bibtex-entry
46 ;;; Mike Newton (newton@gumby.cs.caltech.edu) 90.11.17
47 ;;; * Handle items like
48 ;;; title = poft # "Fifth Tri-quaterly" # random-conf,
49 ;;; and title = {This title is inside curlies}
50 ;;; * added user settable, always present, optional fields
51 ;;; * fixed 'bibtex-find-it's doc string's location
52 ;;; * bibtex-field-text made more general (it wouldnt handle the # construct)
53 ;;; and it now handles a small subset of the {} cases
55 ;;; Bengt Martensson, March 6
56 ;;; Adapted to Bibtex 0.99 by updating the optional fields according
57 ;;; to the document BibTeXing, Oren Patashnik, dated January 31, 1988.
58 ;;; Updated documentation strings accordingly. Added (provide 'bibtex).
59 ;;; If bibtex-include-OPT-crossref is non-nil, every entry will have
60 ;;; an OPTcrossref field, analogously for bibtex-include-OPTkey and
61 ;;; bibtex-include-OPTannote. Added bibtex-preamble, bound to ^C^EP,
62 ;;; and also found in X- and sun-menus. Cleaned up the sun-menu
63 ;;; stuff, and made it more uniform with the X-menu stuff. Marc: I
64 ;;; strongly suspect that I broke your parsing... (Or, more
65 ;;; correctly, BibTeX 0.99 broke it.)
66 ;;; Added bibtex-clean-entry-zap-empty-opts, defvar'd to t. If it
67 ;;; is nil, bibtex-clean-entry will leave empty optional fields alone.
69 ;;; Marc Shapiro 1-feb-89: integrated changes by Bengt Martensson 88-05-06:
70 ;;; Added Sun menu support. Locally bound to right mouse button in
71 ;;; bibtex-mode. Emacs 18.49 allows local mouse bindings!!
72 ;;; Commented out DEAthesis.
74 ;;; Marc Shapiro 6-oct-88
75 ;;; * skip-whitespace replaced by skip-chars-forward
76 ;;; * use indent-to-column instead of inserting tabs (changes to
77 ;;; bibtex-entry, bibtex-make-entry, bibtex-make-OPT-entry, renamed to
78 ;;; bibtex-make-optional-entry)
79 ;;; * C-c C-k deletes the current OPT entry entirely
80 ;;; * C-c C-d replaces text of field with ""
81 ;;; * renamed bibtex-find-it to bibtex-find-text. With arg, now goes to
82 ;;; start of text. Fixed bugs in it.
84 ;;; Marc Shapiro 23-sep-88
85 ;;; * bibtex-clean-entry moves past end of entry.
86 ;;; * bibtex-clean-entry signals mandatory fields left empty.
88 ;;; Marc Shapiro 18-jul-88
89 ;;; * Fixed bug in bibtex-flash-entry
90 ;;; * Moved all the entry type keystrokes to "C-c C-e something" (instead of
91 ;;; "C-c something" previously) to make room for more. C-c C-e is
92 ;;; supposed to stand for "entry" [idea taken from mail-mode]. Moved
93 ;;; bibtex-pop-previous to C-c C-p and bibtex-pop-next to C-c C-n.
94 ;;; * removed binding for "\e[25~"
95 ;;; * replaced bibtex-clean-optionals by bibtex-clean-entry, bound to
96 ;;; C-c C-c
98 ;;; Marc Shapiro 13-jul-88 [based on ideas by Sacha Krakowiak of IMAG]
99 ;;; * bibtex-pop-previous replaces current field with value of
100 ;;; similar field in previous entry. May be called n times in a row
101 ;;; (or with arg n) to pop similar field of n'th previous entry.
102 ;;; There is also a bibtex-pop-next to get similar field of next
103 ;;; entry.
104 ;;; * C-c C-k now kills all empty optional fields of current entry, and
105 ;;; removes "OPT" for those optional fields which have text.
107 ;;; Marc Shapiro 14-dec-87
108 ;;; Cosmetic fixes. Fixed small bug in bibtex-move-outside-of-entry.
109 ;;; Skip Montanaro <steinmetz!sprite!montanaro> 7-dec-87, Shapiro 10-dec-87
110 ;;; before inserting an entry, make sure we are outside of a bib entry
111 ;;; Marc Shapiro 3-nov-87
112 ;;; addition for France: DEAthesis
113 ;;; Marc Shapiro 19-oct-1987
114 ;;; add X window menu option; bug fixes. TAB, LFD, C-c " and C-c C-o now
115 ;;; behave consistently; deletion never occurs blindly.
116 ;;; Marc Shapiro <shapiro@inria.inria.fr> 15-oct-1986
117 ;;; align long lines nicely; C-c C-o checks for the "OPT" string;
118 ;;; TAB goes to the end of the string; use lower case; use
119 ;;; run-hooks
121 ;;; Bengt Martensson <ubrinf!mond!bengt> 87-06-28
122 ;;; Bengt Martensson <bengt@mathematik.uni-Bremen.de> 87-06-28
123 ;;; Original version
125 ;;; NOTE by Marc Shapiro, 14-dec-87:
126 ;;; (bibtex-x-environment) binds an X menu for bibtex mode to x-button-c-right.
127 ;;; Trouble is, in Emacs 18.44 you can't have a mode-specific mouse binding,
128 ;;; so it will remain active in all windows. Yuck!
130 ;;; Code:
132 (provide 'bibtex)
134 ;;; these guys typically don't have autoloads...[alarson:19920131.1548CST]
135 (if (not (fboundp 'TeX-insert-quote))
136 (autoload 'TeX-insert-quote "tex-mode"))
137 (if (not (fboundp 'sort-subr))
138 (autoload 'sort-subr "sort"))
142 (defvar bibtex-mode-syntax-table nil "")
143 (defvar bibtex-mode-abbrev-table nil "")
144 (define-abbrev-table 'bibtex-mode-abbrev-table ())
145 (defvar bibtex-mode-map (make-sparse-keymap) "")
147 (defvar bibtex-pop-previous-search-point nil
148 "Next point where bibtex-pop-previous should start looking for a similar
149 entry.")
151 (defvar bibtex-pop-next-search-point nil
152 "Next point where bibtex-pop-next should start looking for a similar
153 entry.")
155 (defvar bibtex-clean-entry-zap-empty-opts t
156 "*If non-nil, bibtex-clean-entry will delete all empty optional fields.")
158 (defvar bibtex-include-OPTcrossref t
159 "*If non-nil, all entries will have an OPTcrossref field.")
160 (defvar bibtex-include-OPTkey t
161 "*If non-nil, all entries will have an OPTkey field.")
162 (defvar bibtex-include-OPTannote t
163 "*If non-nil, all entries will have an OPTannote field.")
165 ;; note: the user should be allowed to have their own list of always
166 ;; available optional fields. exs: "keywords" "categories"
168 (defvar bibtex-mode-user-optional-fields nil ;no default value
169 "*List of optional fields that user want to have as always present
170 when making a bibtex entry. One possibility is for ``keywords''")
173 ;;; A bibtex file is a sequence of entries, either string definitions
174 ;;; or reference entries. A reference entry has a type part, a
175 ;;; key part, and a comma-separated sequence of fields. A string
176 ;;; entry has a single field. A field has a left and right part,
177 ;;; separated by a '='. The left part is the name, the right part is
178 ;;; the text. Here come the definitions allowing to create and/or parse
179 ;;; entries and fields:
181 ;;; fields
182 (defun bibtex-cfield (name text)
183 "Create a regexp for a bibtex field of name NAME and text TEXT"
184 (concat ",[ \t\n]*\\("
185 name
186 "\\)[ \t\n]*=[ \t\n]*\\("
187 text
188 "\\)"))
189 (defconst bibtex-name-in-cfield 1
190 "The regexp subexpression number of the name part in bibtex-cfield.")
191 (defconst bibtex-text-in-cfield 2
192 "The regexp subexpression number of the text part in bibtex-cfield.")
194 (defconst bibtex-field-name "[A-Za-z][---A-Za-z0-9:_+]*"
195 "Regexp defining the name part of a bibtex field.")
197 ;; bibtex-field-text must be able to handle
198 ;; title = "Proc. Fifteenth Annual" # STOC,
199 ;; month = "10~" # jan,
200 ;; year = "{\noopsort{1973c}}1981",
201 ;; month = apr # "-" # may,
202 ;; key = {Volume-2},
203 ;; note = "Volume~2 is listed under Knuth \cite{book-full}"
204 ;; i have added a few of these, but not all! -- MON
206 (defconst bibtex-field-const
207 "[0-9A-Za-z][---A-Za-z0-9:_+]*"
208 "Format of a bibtex field constant.")
210 (defconst bibtex-field-string
211 (concat
212 "\"[^\"]*[^\\\\]\"\\|\"\"")
213 "Match either a string or an empty string.")
215 (defconst bibtex-field-string-or-const
216 (concat bibtex-field-const "\\|" bibtex-field-string)
217 "Match either bibtex-field-string or bibtex-field-const.")
219 (defconst bibtex-field-text
220 (concat
221 "\\(" bibtex-field-string-or-const "\\)"
222 "\\([ \t\n]+#[ \t\n]+\\(" bibtex-field-string-or-const "\\)\\)*\\|"
223 "{[^{}]*[^\\\\]}")
224 "Regexp defining the text part of a bibtex field: either a string, or
225 an empty string, or a constant followed by one or more # / constant pairs.
226 Also matches simple {...} patterns.")
228 ;(defconst bibtex-field-text
229 ; "\"[^\"]*[^\\\\]\"\\|\"\"\\|[0-9A-Za-z][---A-Za-z0-9:_+]*"
230 ; "Regexp defining the text part of a bibtex field: either a string, or an empty string, or a constant.")
232 (defconst bibtex-field
233 (bibtex-cfield bibtex-field-name bibtex-field-text)
234 "Regexp defining the format of a bibtex field")
236 (defconst bibtex-name-in-field bibtex-name-in-cfield
237 "The regexp subexpression number of the name part in bibtex-field")
238 (defconst bibtex-text-in-field bibtex-text-in-cfield
239 "The regexp subexpression number of the text part in bibtex-field")
241 ;;; references
242 (defconst bibtex-reference-type
243 "@[A-Za-z]+"
244 "Regexp defining the type part of a bibtex reference entry")
245 (defconst bibtex-reference-head
246 (concat "^[ \t]*\\("
247 bibtex-reference-type
248 "\\)[ \t]*[({]\\("
249 bibtex-field-name
250 "\\)")
251 "Regexp defining format of the header line of a bibtex reference entry")
252 (defconst bibtex-type-in-head 1
253 "The regexp subexpression number of the type part in bibtex-reference-head")
254 (defconst bibtex-key-in-head 2
255 "The regexp subexpression number of the key part in
256 bibtex-reference-head")
258 (defconst bibtex-reference
259 (concat bibtex-reference-head
260 "\\([ \t\n]*" bibtex-field "\\)*"
261 "[ \t\n]*[})]")
262 "Regexp defining the format of a bibtex reference entry")
263 (defconst bibtex-type-in-reference bibtex-type-in-head
264 "The regexp subexpression number of the type part in bibtex-reference")
265 (defconst bibtex-key-in-reference bibtex-key-in-head
266 "The regexp subexpression number of the key part in
267 bibtex-reference")
269 ;;; strings
270 (defconst bibtex-string
271 (concat "^[ \t]*@[sS][tT][rR][iI][nN][gG][ \t\n]*[({][ \t\n]*\\("
272 bibtex-field-name
273 "\\)[ \t\n]*=[ \t\n]*\\("
274 bibtex-field-text
275 "\\)[ \t\n]*[})]")
276 "Regexp defining the format of a bibtex string entry")
277 (defconst bibtex-name-in-string 1
278 "The regexp subexpression of the name part in bibtex-string")
279 (defconst bibtex-text-in-string 2
280 "The regexp subexpression of the text part in bibtex-string")
282 (defconst bibtex-name-alignement 2
283 "Alignment for the name part in BibTeX fields.
284 Chosen on aesthetic grounds only.")
286 (defconst bibtex-text-alignment (length " organization = ")
287 "Alignment for the text part in BibTeX fields.
288 Equal to the space needed for the longest name part.")
290 ;;; bibtex mode:
292 (defun bibtex-mode ()
293 "Major mode for editing bibtex files.
295 \\{bibtex-mode-map}
297 A command such as \\[bibtex-Book] will outline the fields for a BibTeX book entry.
299 The optional fields start with the string OPT, and thus ignored by BibTeX.
300 The OPT string may be removed from a field with \\[bibtex-remove-OPT].
301 \\[bibtex-kill-optional-field] kills the current optional field entirely.
302 \\[bibtex-remove-double-quotes] removes the double-quotes around the text of
303 the current field. \\[bibtex-empty-field] replaces the text of the current
304 field with the default \"\".
306 The command \\[bibtex-clean-entry] cleans the current entry, i.e. (i) removes
307 double-quotes from entirely numerical fields, (ii) removes OPT from all
308 non-empty optional fields, (iii) removes all empty optional fields, and (iv)
309 checks that no non-optional fields are empty.
311 Use \\[bibtex-find-text] to position the dot at the end of the current field.
312 Use \\[bibtex-next-field] to move to end of the next field.
314 \\[bibtex-x-environment] binds a mode-specific X menu to control+right
315 mouse button.
316 \\[bibtex-sun-environment] binds a mode-specific Sun menu to right
317 mouse button.
319 Fields:
320 address
321 Publisher's address
322 annote
323 Long annotation used for annotated bibliographies (begins sentence)
324 author
325 Name(s) of author(s), in BibTeX name format
326 booktitle
327 Book title when the thing being referenced isn't the whole book.
328 For book entries, the title field should be used instead.
329 chapter
330 Chapter number
331 crossref
332 The database key of the entry being cross referenced.
333 edition
334 Edition of a book (e.g., ""second"")
335 editor
336 Name(s) of editor(s), in BibTeX name format.
337 If there is also an author field, then the editor field should be
338 for the book or collection that the work appears in
339 howpublished
340 How something strange has been published (begins sentence)
341 institution
342 Sponsoring institution
343 journal
344 Journal name (macros are provided for many)
346 Alphabetizing and labeling key (needed when no author or editor)
347 month
348 Month (macros are provided)
349 note
350 To help the reader find a reference (begins sentence)
351 number
352 Number of a journal or technical report
353 organization
354 Organization (sponsoring a conference)
355 pages
356 Page number or numbers (use `--' to separate a range)
357 publisher
358 Publisher name
359 school
360 School name (for theses)
361 series
362 The name of a series or set of books.
363 An individual book will will also have it's own title
364 title
365 The title of the thing being referenced
366 type
367 Type of a technical report (e.g., ""Research Note"") to be used
368 instead of the default ""Technical Report""
369 volume
370 Volume of a journal or multivolume work
371 year
372 Year---should contain only numerals
373 ---------------------------------------------------------
374 Entry to this mode calls the value of bibtex-mode-hook if that value is
375 non-nil."
376 (interactive)
377 (kill-all-local-variables)
378 (if bibtex-mode-syntax-table
379 (set-syntax-table bibtex-mode-syntax-table)
380 (setq bibtex-mode-syntax-table (make-syntax-table))
381 (set-syntax-table bibtex-mode-syntax-table)
382 (modify-syntax-entry ?\" ".")
383 (modify-syntax-entry ?$ "$$ ")
384 (modify-syntax-entry ?% "< ")
385 (modify-syntax-entry ?' "w ")
386 (modify-syntax-entry ?@ "w ")
387 (modify-syntax-entry ?\\ "\\")
388 (modify-syntax-entry ?\f "> ")
389 (modify-syntax-entry ?\n "> ")
390 (modify-syntax-entry ?~ " "))
391 (use-local-map bibtex-mode-map)
392 (setq major-mode 'bibtex-mode)
395 (setq mode-name "BibTeX")
396 (set-syntax-table bibtex-mode-syntax-table)
397 (setq local-abbrev-table bibtex-mode-abbrev-table)
398 (make-local-variable 'paragraph-start)
399 (setq paragraph-start "^[ \f\n\t]*$")
401 (define-key bibtex-mode-map "\t" 'bibtex-find-text)
402 (define-key bibtex-mode-map "\n" 'bibtex-next-field)
403 (define-key bibtex-mode-map "\C-c\"" 'bibtex-remove-double-quotes)
404 (define-key bibtex-mode-map "\C-c\C-c" 'bibtex-clean-entry)
405 (define-key bibtex-mode-map "\C-c?" 'describe-mode)
406 (define-key bibtex-mode-map "\C-c\C-p" 'bibtex-pop-previous)
407 (define-key bibtex-mode-map "\C-c\C-n" 'bibtex-pop-next)
408 (define-key bibtex-mode-map "\C-c\C-k" 'bibtex-kill-optional-field)
409 (define-key bibtex-mode-map "\C-c\C-d" 'bibtex-empty-field)
411 ;; [alarson:19920131.1543CST]
412 (define-key bibtex-mode-map "\"" 'TeX-insert-quote)
413 (define-key bibtex-mode-map "\C-c$" 'ispell-bibtex-entry)
414 (define-key bibtex-mode-map "\M-\C-a" 'beginning-of-bibtex-entry)
415 (define-key bibtex-mode-map "\M-\C-e" 'end-of-bibtex-entry)
417 (define-key bibtex-mode-map "\C-c\C-e\C-a" 'bibtex-Article)
418 (define-key bibtex-mode-map "\C-c\C-e\C-b" 'bibtex-Book)
419 (define-key bibtex-mode-map "\C-c\C-e\C-d" 'bibtex-DEAthesis)
420 (define-key bibtex-mode-map "\C-c\C-e\C-c" 'bibtex-InProceedings)
421 (define-key bibtex-mode-map "\C-c\C-e\C-i" 'bibtex-InBook)
422 (define-key bibtex-mode-map "\C-c\C-ei" 'bibtex-InCollection)
423 (define-key bibtex-mode-map "\C-c\C-eI" 'bibtex-InProceedings)
424 (define-key bibtex-mode-map "\C-c\C-e\C-m" 'bibtex-Manual)
425 (define-key bibtex-mode-map "\C-c\C-em" 'bibtex-MastersThesis)
426 (define-key bibtex-mode-map "\C-c\C-eM" 'bibtex-Misc)
427 (define-key bibtex-mode-map "\C-c\C-o" 'bibtex-remove-OPT)
428 (define-key bibtex-mode-map "\C-c\C-e\C-p" 'bibtex-PhdThesis)
429 (define-key bibtex-mode-map "\C-c\C-ep" 'bibtex-Proceedings)
430 (define-key bibtex-mode-map "\C-c\C-eP" 'bibtex-preamble)
431 (define-key bibtex-mode-map "\C-c\C-e\C-t" 'bibtex-TechReport)
432 (define-key bibtex-mode-map "\C-c\C-e\C-s" 'bibtex-string)
433 (define-key bibtex-mode-map "\C-c\C-e\C-u" 'bibtex-Unpublished)
435 (auto-fill-mode 1) ; nice alignements
436 (setq left-margin (+ bibtex-text-alignment 1))
438 (run-hooks 'bibtex-mode-hook))
440 (defun bibtex-move-outside-of-entry ()
441 "Make sure we are outside of a bib entry"
442 (cond ((or
443 (= (point) (point-max))
444 (= (point) (point-min))
445 (looking-at "[ \n]*@")
449 (backward-paragraph)
450 (forward-paragraph)))
451 (re-search-forward "[ \t\n]*" (point-max) t))
453 (defun ispell-abstract ()
454 (interactive)
455 (beginning-of-bibtex-entry)
456 (re-search-forward "^[ \t]*[OPT]*abstract[ \t]*=")
457 (ispell-region (point)
458 (save-excursion (forward-sexp) (point))))
460 (defun beginning-of-bibtex-entry ()
461 (interactive)
462 (re-search-backward "^@" nil 'move))
464 (defun end-of-bibtex-entry ()
465 (interactive)
466 (re-search-forward "}$" nil 'move))
468 (defun ispell-bibtex-entry ()
469 (interactive)
470 (ispell-region (progn (beginning-of-bibtex-entry) (point))
471 (progn (end-of-bibtex-entry) (point))))
473 (defun narrow-to-bibtex-entry ()
474 (interactive)
475 (save-excursion
476 (narrow-to-region (progn (beginning-of-bibtex-entry) (point))
477 (progn (end-of-bibtex-entry) (point)))))
480 (defun beginning-of-first-bibtex-entry ()
481 (goto-char (point-min))
482 (cond
483 ((re-search-forward "^@" nil 'move)
484 (beginning-of-line))
485 ((and (bobp) (eobp))
486 nil)
488 (message "Warning: No bibtex entries found!"))))
490 (defun hide-bibtex-entry-bodies (&optional arg)
491 "Hide all lines between first and last bibtex entries not beginning with @.
492 With argument, show all text."
493 (interactive "P")
494 (beginning-of-first-bibtex-entry)
495 ;; subst-char-in-region modifies the buffer, despite what the
496 ;; documentation says...
497 (let ((modifiedp (buffer-modified-p))
498 (buffer-read-only nil))
499 (if arg
500 (subst-char-in-region (point) (point-max) ?\r ?\n t)
501 (while (save-excursion (re-search-forward "\n[^@]" (point-max) t))
502 (save-excursion (replace-regexp "\n\\([^@]\\)" "\r\\1"))))
503 (setq selective-display (not arg))
504 (set-buffer-modified-p modifiedp)))
506 (defun sort-bibtex-entries ()
507 "Sort bibtex entries alphabetically by key.
508 Text before the first bibtex entry, and following the last is not effected.
509 Bugs:
510 1. Text between the closing brace ending one bibtex entry, and the @ starting
511 the next, is considered part of the PRECEEDING entry. Perhaps it should be
512 part of the following entry."
513 (interactive)
514 (save-restriction
515 (beginning-of-first-bibtex-entry)
516 (narrow-to-region (point)
517 (save-excursion
518 (goto-char (point-max))
519 (beginning-of-bibtex-entry)
520 (end-of-bibtex-entry)
521 (point)))
522 (sort-subr nil ; reversep
523 ;; begining of record function
524 'forward-line
525 ;; end of record function
526 (function (lambda () (and (re-search-forward "}[ \t]*\n[\n \t]*@" nil 'move)
527 (forward-char -2))))
528 ;; start of key function
529 (function (lambda () (re-search-forward "{[ \t]*") nil))
530 ;; end of key function
531 (function (lambda () (search-forward ",")))
534 (defun map-bibtex-entries (fun)
535 "Call FUN for each bibtex entry starting with the current, to the end of the file.
536 FUN is called with one argument, the key of the entry, and with point inside the entry."
537 (beginning-of-bibtex-entry)
538 (while (re-search-forward "^@[^{]*{[ \t]*\\([^,]*\\)" nil t)
539 (funcall fun (buffer-substring (match-beginning 1) (match-end 1)))))
541 (defun find-bibtex-entry-location (entry-name)
542 (interactive "sBibtex entry key: ")
543 "Searches from beginning of current buffer looking for place to put the
544 bibtex entry named ENTRY-NAME. Buffer is assumed to be in sorted order,
545 without duplicates (see \\[sort-bibtex-entries]), if it is not, an error will
546 be signalled."
547 (let ((previous nil)
548 point)
549 (beginning-of-first-bibtex-entry)
550 (or (catch 'done
551 (map-bibtex-entries (function (lambda (current)
552 (cond
553 ((string-equal entry-name current)
554 (error "Entry duplicates existing!"))
555 ((or (null previous)
556 (string< previous current))
557 (setq previous current
558 point (point))
559 (if (string< entry-name current)
560 (progn
561 (beginning-of-bibtex-entry)
562 ;; Many schemes append strings to
563 ;; existing entries to resolve them,
564 ;; so initial substring matches may
565 ;; indicate a duplicate entry.
566 (let ((idx (string-match (regexp-quote entry-name) current)))
567 (if (and (integerp idx)
568 (zerop idx))
569 (progn
570 (message "Warning: Entry %s may be a duplicate of %s!"
571 entry-name current)
572 (ding t))))
573 (throw 'done t))))
574 ((string-equal previous current)
575 (error "Duplicate here with previous!"))
576 (t (error "Entries out of order here!")))))))
577 (end-of-bibtex-entry))))
579 (defun validate-bibtex-buffer ()
580 "Find some typical errors in bibtex files.
581 1. At signs (@) not as first char of a line.
582 2. Double quotes (\") inside strings.
583 3. Closing braces (}) not the last character of a line."
584 (interactive)
585 (let ((point (point)))
586 (while (re-search-forward ".@" nil t)
587 (let* ((foo (parse-partial-sexp (save-excursion (beginning-of-bibtex-entry)
588 (point))
589 (point)))
590 (in-a-string (nth 3 foo)))
591 (if (not in-a-string)
592 (error "At sign (@) out of place!"))))
593 (goto-char point)
594 (while (search-forward "\"" nil t)
595 (or (looking-at "[,}][ \t]*$")
596 ;; some versions put closing brace on separate line.
597 (looking-at "[ \t]*\n}")
598 (save-excursion
599 (save-restriction
600 (narrow-to-region (point)
601 (progn (beginning-of-line) (point)))
602 (looking-at "^[ \t]*[a-zA-Z]+[ \t]*=[ \t]*\"$")))
603 (error "Quote out of place, or missing \",\" or \"}\"!")))
604 (goto-char point)
605 ;; This is only approximate, should actually search for close braces,
606 ;; then see if they are inside a string, or at the end of a line.
607 ;; This just gets the typical case of whitespace after a closing brace.
608 (while (search-forward "}[ \t]+$" nil t)
609 (error "Brace not last char of line!"))
610 (goto-char point)
611 (message "Bibtex buffer appears o.k.")))
613 (defun find-bibtex-duplicates ()
614 "Searches forward in current buffer looking for duplicate bibtex entries.
615 Buffer is assumed to be sorted, see \\[sort-bibtex-entries]"
616 (interactive)
617 (let ((point (point)))
618 ;; errors if things are not right...
619 (find-bibtex-entry-location (make-string 10 255))
620 (goto-char point)
621 (message "No duplicates found!")))
624 (defvar bibtex-maintain-sorted-entries nil
625 "*If true, bibtex-mode will attempt to maintain all bibtex entries in
626 sorted order.")
629 ;; note: this should really take lists of strings OR of lists. in the
630 ;; second case, one can use either list. (ie:
631 ;; "name" (("crossref") ("journal" "year")) )
634 (defun bibtex-entry (entry-type required optional)
635 (let (key)
636 (if bibtex-maintain-sorted-entries
637 (progn
638 (setq key (read-string (format "%s key: " entry-type)))
639 (find-bibtex-entry-location key)))
640 (bibtex-move-outside-of-entry)
641 (insert "@" entry-type "{")
642 (mapcar 'bibtex-make-field required)
643 (if bibtex-include-OPTcrossref
644 (bibtex-make-optional-field "crossref"))
645 (if bibtex-include-OPTkey
646 (bibtex-make-optional-field "key"))
647 (mapcar 'bibtex-make-optional-field optional)
648 (if bibtex-mode-user-optional-fields ;MON...
649 (mapcar 'bibtex-make-optional-field
650 bibtex-mode-user-optional-fields))
651 (if bibtex-include-OPTannote
652 (bibtex-make-optional-field "annote"))
653 (insert "\n}\n\n")
654 (forward-char -3)
655 (up-list -1)
656 (forward-char 1)
657 (if key
658 (progn
659 (insert key)
660 (bibtex-next-field t)))))
662 ;; (defun bibtex-entry (entry-type required optional)
663 ;; (bibtex-move-outside-of-entry)
664 ;; (insert (concat "@" entry-type "{,\n\n}\n\n"))
665 ;; (previous-line 3)
666 ;; (insert (mapconcat 'bibtex-make-entry required ",\n"))
667 ;; (if required
668 ;; (if optional
669 ;; (insert ",\n")))
670 ;; (insert (mapconcat 'bibtex-make-OPT-entry optional ",\n"))
671 ;; (if bibtex-mode-user-optional-fields ;MON...
672 ;; (progn
673 ;; (if optional
674 ;; (insert ",\n"))
675 ;; (insert (mapconcat 'bibtex-make-OPT-entry
676 ;; bibtex-mode-user-optional-fields
677 ;; ",\n")))) ;MON
678 ;; (up-list -1)
679 ;; (forward-char 1))
682 (defun bibtex-make-field (str)
683 (interactive "sBibTeX entry type: ")
684 (insert ",\n")
685 (indent-to-column bibtex-name-alignement)
686 (insert str " = ")
687 (indent-to-column bibtex-text-alignment)
688 (insert "\"\"")
689 nil)
691 (defun bibtex-make-optional-field (str)
692 (interactive "sOptional BibTeX entry type: ")
693 (insert ",\n")
694 (indent-to-column bibtex-name-alignement)
695 (insert "OPT" str " = ")
696 (indent-to-column bibtex-text-alignment)
697 (insert "\"\"")
698 nil)
700 ;; What to do about crossref? if present, journal and year are
701 ;; both optional. Due to this, i move all of them into optional. -- MON
703 (defun bibtex-Article ()
704 (interactive)
705 (if bibtex-include-OPTcrossref
706 (bibtex-entry "Article" '("author" "title")
707 '("journal" "year" "volume" "number" "pages"
708 "month" "note"))
709 (bibtex-entry "Article" '("author" "title" "journal" "year")
710 '("volume" "number" "pages" "month" "note"))))
713 (defun bibtex-Book ()
714 (interactive)
715 (bibtex-entry "Book" '("author" "title" "publisher" "year")
716 '("editor" "volume" "number" "series" "address"
717 "edition" "month" "note")))
719 (defun bibtex-Booklet ()
720 (interactive)
721 (bibtex-entry "Booklet" '("title")
722 '("author" "howpublished" "address" "month" "year" "note")))
724 ;; France: Dipl\^{o}me d'Etudes Approfondies (similar to Master's)
725 (defun bibtex-DEAthesis ()
726 (interactive)
727 (bibtex-entry "DEAthesis" '("author" "title" "school" "year")
728 '("address" "month" "note")))
730 (defun bibtex-InBook ()
731 (interactive)
732 (if bibtex-include-OPTcrossref
733 (bibtex-entry "InBook" '("author" "title" "chapter")
734 '("publisher" "year" "editor" "pages" "volume" "number"
735 "series" "address" "edition" "month" "type" "note"))
736 (bibtex-entry "InBook" '("author" "title" "chapter" "publisher" "year")
737 '("editor" "pages" "volume" "number" "series" "address"
738 "edition" "month" "type" "note"))))
740 (defun bibtex-InCollection ()
741 (interactive)
742 (if bibtex-include-OPTcrossref
743 (bibtex-entry "InCollection" '("author" "title")
744 '("booktitle" "publisher" "year"
745 "editor" "volume" "number" "series" "type" "chapter"
746 "pages" "address" "edition" "month" "note"))
747 (bibtex-entry "InCollection" '("author" "title"
748 "booktitle" "publisher" "year")
749 '("editor" "volume" "number" "series" "type" "chapter"
750 "pages" "address" "edition" "month" "note"))))
753 (defun bibtex-InProceedings ()
754 (interactive)
755 (if bibtex-include-OPTcrossref
756 (bibtex-entry "InProceedings" '("author" "title")
757 '("editor" "volume" "number" "series" "pages"
758 "booktitle" "year"
759 "organization" "publisher" "address" "month" "note"))
760 (bibtex-entry "InProceedings" '("author" "title" "booktitle" "year")
761 '("editor" "volume" "number" "series" "pages"
762 "organization" "publisher" "address" "month" "note"))))
765 (defun bibtex-Manual ()
766 (interactive)
767 (bibtex-entry "Manual" '("title")
768 '("author" "organization" "address" "edition" "year"
769 "month" "note")))
771 (defun bibtex-MastersThesis ()
772 (interactive)
773 (bibtex-entry "MastersThesis" '("author" "title" "school" "year")
774 '("address" "month" "note" "type")))
776 (defun bibtex-Misc ()
777 (interactive)
778 (bibtex-entry "Misc" '()
779 '("author" "title" "howpublished" "year" "month" "note")))
781 (defun bibtex-PhdThesis ()
782 (interactive)
783 (bibtex-entry "PhdThesis" '("author" "title" "school" "year")
784 '("address" "month" "type" "note")))
786 (defun bibtex-Proceedings ()
787 (interactive)
788 (bibtex-entry "Proceedings" '("title" "year")
789 '("editor" "volume" "number" "series" "publisher"
790 "organization" "address" "month" "note")))
792 (defun bibtex-TechReport ()
793 (interactive)
794 (bibtex-entry "TechReport" '("author" "title" "institution" "year")
795 '("type" "number" "address" "month" "note")))
797 (defun bibtex-Unpublished ()
798 (interactive)
799 (bibtex-entry "Unpublished" '("author" "title" "note")
800 '("year" "month")))
802 (defun bibtex-string ()
803 (interactive)
804 (bibtex-move-outside-of-entry)
805 (insert "@string{ = """"}\n")
806 (previous-line 1)
807 (forward-char 8))
809 (defun bibtex-preamble ()
810 (interactive)
811 (bibtex-move-outside-of-entry)
812 (insert "@Preamble{}\n")
813 (previous-line 1)
814 (forward-char 10))
816 (defun bibtex-next-field (arg)
817 "Finds end of text of next BibTeX field; with arg, to its beginning"
818 (interactive "P")
819 (bibtex-inside-field)
820 (let ((start (point)))
821 (condition-case ()
822 (progn
823 (bibtex-enclosing-field)
824 (goto-char (match-end 0))
825 (forward-char 2))
826 (error
827 (goto-char start)
828 (end-of-line)
829 (forward-char 1))))
830 (bibtex-find-text arg))
832 ;; (defun bibtex-next-field ()
833 ;; "Finds end of text of next field."
834 ;; (interactive)
835 ;; (condition-case ()
836 ;; (progn
837 ;; (bibtex-inside-field)
838 ;; (re-search-forward ",[ \t\n]*" (point-max) 1)
839 ;; (bibtex-enclosing-field)
840 ;; (bibtex-inside-field))
841 ;; (error nil)))
843 (defun bibtex-find-text (arg)
844 "Go to end of text of current field; with arg, go to beginning."
845 (interactive "P")
846 (bibtex-inside-field)
847 (bibtex-enclosing-field)
848 (if arg
849 (progn
850 (goto-char (match-beginning bibtex-text-in-field))
851 (if (looking-at "\"")
852 (forward-char 1)))
853 (goto-char (match-end bibtex-text-in-field))
854 (if (= (preceding-char) ?\")
855 (forward-char -1))))
857 ;; (defun bibtex-find-text ()
858 ;; "Go to end of text of current field."
859 ;; (interactive)
860 ;; (condition-case ()
861 ;; (progn
862 ;; (bibtex-inside-field)
863 ;; (bibtex-enclosing-field)
864 ;; (goto-char (match-end bibtex-text-in-field))
865 ;; (bibtex-inside-field))
866 ;; (error nil)))
868 (defun bibtex-remove-OPT ()
869 "Removes the 'OPT' starting optional arguments and goes to end of text"
870 (interactive)
871 (bibtex-inside-field)
872 (bibtex-enclosing-field)
873 (save-excursion
874 (goto-char (match-beginning bibtex-name-in-field))
875 (if (looking-at "OPT")
876 (delete-char (length "OPT"))))
877 (bibtex-inside-field))
879 (defun bibtex-inside-field ()
880 "Try to avoid point being at end of a bibtex field."
881 (interactive)
882 (end-of-line)
883 (skip-chars-backward " \t") ;MON - maybe delete these chars?
884 (cond ((= (preceding-char) ?,)
885 (forward-char -1)))
886 (cond ((= (preceding-char) ?\")
887 (forward-char -1)))) ;MON - only go back if quote
889 (defun bibtex-remove-double-quotes ()
890 "Removes """" around string."
891 (interactive)
892 (save-excursion
893 (bibtex-inside-field)
894 (bibtex-enclosing-field)
895 (let ((start (match-beginning bibtex-text-in-field))
896 (stop (match-end bibtex-text-in-field)))
897 (goto-char stop)
898 (forward-char -1)
899 (if (looking-at "\"")
900 (delete-char 1))
901 (goto-char start)
902 (if (looking-at "\"")
903 (delete-char 1)))))
905 (defun bibtex-kill-optional-field ()
906 "Kill the entire enclosing optional BibTeX field"
907 (interactive)
908 (bibtex-inside-field)
909 (bibtex-enclosing-field)
910 (goto-char (match-beginning bibtex-name-in-field))
911 (let ((the-end (match-end 0))
912 (the-beginning (match-beginning 0)))
913 (if (looking-at "OPT")
914 (progn
915 (goto-char the-end)
916 (skip-chars-forward " \t\n,")
917 (kill-region the-beginning the-end))
918 (error "Mandatory fields can't be killed"))))
920 (defun bibtex-empty-field ()
921 "Delete the text part of the current field, replace with empty text"
922 (interactive)
923 (bibtex-inside-field)
924 (bibtex-enclosing-field)
925 (goto-char (match-beginning bibtex-text-in-field))
926 (kill-region (point) (match-end bibtex-text-in-field))
927 (insert "\"\"")
928 (bibtex-find-text t))
931 (defun bibtex-pop-previous (arg)
932 "Replace text of current field with the text of similar field in previous entry.
933 With arg, go up ARG entries. Repeated, goes up so many times. May be
934 intermixed with \\[bibtex-pop-next] (bibtex-pop-next)."
935 (interactive "p")
936 (bibtex-inside-field)
937 (save-excursion
938 ; parse current field
939 (bibtex-enclosing-field)
940 (let ((start-old-text (match-beginning bibtex-text-in-field))
941 (stop-old-text (match-end bibtex-text-in-field))
942 (start-name (match-beginning bibtex-name-in-field))
943 (stop-name (match-end bibtex-name-in-field))
944 (new-text))
945 (goto-char start-name)
946 ; construct regexp for previous field with same name as this one
947 (let ((matching-entry
948 (bibtex-cfield
949 (buffer-substring (if (looking-at "OPT")
950 (+ (point) (length "OPT"))
951 (point))
952 stop-name)
953 bibtex-field-text)))
955 ; if executed several times in a row, start each search where the
956 ; last one finished
957 (cond ((or (eq last-command 'bibtex-pop-previous)
958 (eq last-command 'bibtex-pop-next))
962 (bibtex-enclosing-reference)
963 (setq bibtex-pop-previous-search-point (match-beginning 0))
964 (setq bibtex-pop-next-search-point (match-end 0))))
965 (goto-char bibtex-pop-previous-search-point)
967 ; Now search for arg'th previous similar field
968 (cond
969 ((re-search-backward matching-entry (point-min) t arg)
970 (setq new-text
971 (buffer-substring (match-beginning bibtex-text-in-cfield)
972 (match-end bibtex-text-in-cfield)))
973 ; Found a matching field. Remember boundaries.
974 (setq bibtex-pop-next-search-point (match-end 0))
975 (setq bibtex-pop-previous-search-point (match-beginning 0))
976 (bibtex-flash-head)
977 ; Go back to where we started, delete old text, and pop new.
978 (goto-char stop-old-text)
979 (delete-region start-old-text stop-old-text)
980 (insert new-text))
981 (t ; search failed
982 (error "No previous matching BibTeX field."))))))
983 (setq this-command 'bibtex-pop-previous))
985 (defun bibtex-pop-next (arg)
986 "Replace text of current field with the text of similar field in next entry.
987 With arg, go up ARG entries. Repeated, goes up so many times. May be
988 intermixed with \\[bibtex-pop-previous] (bibtex-pop-previous)."
989 (interactive "p")
990 (bibtex-inside-field)
991 (save-excursion
992 ; parse current field
993 (bibtex-enclosing-field)
994 (let ((start-old-text (match-beginning bibtex-text-in-field))
995 (stop-old-text (match-end bibtex-text-in-field))
996 (start-name (match-beginning bibtex-name-in-field))
997 (stop-name (match-end bibtex-name-in-field))
998 (new-text))
999 (goto-char start-name)
1000 ; construct regexp for next field with same name as this one,
1001 ; ignoring possible OPT's
1002 (let ((matching-entry
1003 (bibtex-cfield
1004 (buffer-substring (if (looking-at "OPT")
1005 (+ (point) (length "OPT"))
1006 (point))
1007 stop-name)
1008 bibtex-field-text)))
1010 ; if executed several times in a row, start each search where the
1011 ; last one finished
1012 (cond ((or (eq last-command 'bibtex-pop-next)
1013 (eq last-command 'bibtex-pop-previous))
1017 (bibtex-enclosing-reference)
1018 (setq bibtex-pop-previous-search-point (match-beginning 0))
1019 (setq bibtex-pop-next-search-point (match-end 0))))
1020 (goto-char bibtex-pop-next-search-point)
1022 ; Now search for arg'th next similar field
1023 (cond
1024 ((re-search-forward matching-entry (point-max) t arg)
1025 (setq new-text
1026 (buffer-substring (match-beginning bibtex-text-in-cfield)
1027 (match-end bibtex-text-in-cfield)))
1028 ; Found a matching field. Remember boundaries.
1029 (setq bibtex-pop-next-search-point (match-end 0))
1030 (setq bibtex-pop-previous-search-point (match-beginning 0))
1031 (bibtex-flash-head)
1032 ; Go back to where we started, delete old text, and pop new.
1033 (goto-char stop-old-text)
1034 (delete-region start-old-text stop-old-text)
1035 (insert new-text))
1036 (t ; search failed
1037 (error "No next matching BibTeX field."))))))
1038 (setq this-command 'bibtex-pop-next))
1040 (defun bibtex-flash-head ()
1041 "Flash at BibTeX reference head before point, if exists. (Moves point)."
1042 (let ((flash))
1043 (cond ((re-search-backward bibtex-reference-head (point-min) t)
1044 (goto-char (match-beginning bibtex-type-in-head))
1045 (setq flash (match-end bibtex-key-in-reference)))
1047 (end-of-line)
1048 (skip-chars-backward " \t")
1049 (setq flash (point))
1050 (beginning-of-line)
1051 (skip-chars-forward " \t")))
1052 (if (pos-visible-in-window-p (point))
1053 (sit-for 1)
1054 (message "From: %s"
1055 (buffer-substring (point) flash)))))
1059 (defun bibtex-enclosing-field ()
1060 "Search for BibTeX field enclosing point.
1061 Point moves to end of field; also, use match-beginning and match-end
1062 to parse the field."
1063 (condition-case errname
1064 (bibtex-enclosing-regexp bibtex-field)
1065 (search-failed
1066 (error "Can't find enclosing BibTeX field."))))
1068 (defun bibtex-enclosing-reference ()
1069 "Search for BibTeX reference enclosing point.
1070 Point moves to end of reference; also, use match-beginning and match-end
1071 to parse the reference."
1072 (condition-case errname
1073 (bibtex-enclosing-regexp bibtex-reference)
1074 (search-failed
1075 (error "Can't find enclosing BibTeX reference."))))
1077 (defun bibtex-enclosing-regexp (regexp)
1078 "Search for REGEXP enclosing point.
1079 Point moves to end of REGEXP. See also match-beginning and match-end.
1080 If an enclosing REGEXP is not found, signals search-failed; point is left in
1081 an undefined location.
1083 [Doesn't something like this exist already?]"
1085 (interactive "sRegexp: ")
1086 ; compute reasonable limits for the loop
1087 (let* ((initial (point))
1088 (right (if (re-search-forward regexp (point-max) t)
1089 (match-end 0)
1090 (point-max)))
1091 (left
1092 (progn
1093 (goto-char initial)
1094 (if (re-search-backward regexp (point-min) t)
1095 (match-beginning 0)
1096 (point-min)))))
1097 ; within the prescribed limits, loop until a match is found
1098 (goto-char left)
1099 (re-search-forward regexp right nil 1)
1100 (if (> (match-beginning 0) initial)
1101 (signal 'search-failed (list regexp)))
1102 (while (<= (match-end 0) initial)
1103 (re-search-forward regexp right nil 1)
1104 (if (> (match-beginning 0) initial)
1105 (signal 'search-failed (list regexp))))
1108 (defun bibtex-clean-entry ()
1109 "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."
1110 (interactive)
1111 (bibtex-enclosing-reference)
1112 (goto-char (match-beginning 0))
1113 (let ((start (point)))
1114 (save-restriction
1115 (narrow-to-region start (match-end 0))
1116 (while (re-search-forward bibtex-field (point-max) t 1)
1117 (let ((begin-field (match-beginning 0))
1118 (end-field (match-end 0))
1119 (begin-name (match-beginning bibtex-name-in-field))
1120 (end-name (match-end bibtex-name-in-field))
1121 (begin-text (match-beginning bibtex-text-in-field))
1122 (end-text (match-end bibtex-text-in-field))
1124 (goto-char begin-name)
1125 (cond ((and
1126 (looking-at "OPT")
1127 bibtex-clean-entry-zap-empty-opts)
1128 (goto-char begin-text)
1129 (if (looking-at "\"\"") ; empty: delete whole field
1130 (delete-region begin-field end-field)
1131 ; otherwise: not empty, delete "OPT"
1132 (goto-char begin-name)
1133 (delete-char (length "OPT"))
1134 (goto-char begin-field) ; and loop to go through next test
1137 (goto-char begin-text)
1138 (cond ((looking-at "\"[0-9]+\"") ; if numerical,
1139 (goto-char end-text)
1140 (delete-char -1) ; delete enclosing double-quotes
1141 (goto-char begin-text)
1142 (delete-char 1)
1143 (goto-char end-field) ; go to end for next search
1144 (forward-char -2) ; to compensate for the 2 quotes deleted
1146 ((looking-at "\"\"") ; if empty quotes, complain
1147 (forward-char 1)
1148 (if (not (or (equal (buffer-substring
1149 begin-name
1150 (+ begin-name 3))
1151 "OPT")
1152 (equal (buffer-substring
1153 begin-name
1154 (+ begin-name 3))
1155 "opt")))
1156 (error "Mandatory field ``%s'' is empty"
1157 (buffer-substring begin-name end-name))))
1159 (goto-char end-field))))))))
1160 (goto-char start)
1161 (skip-chars-forward "@a-zA-Z")
1162 (bibtex-enclosing-reference)
1163 (goto-char (match-end 0))
1164 (skip-chars-forward " \t\n\f")))
1168 ;;; X window menus for bibtex mode
1170 (defun bibtex-x-help (arg)
1171 "Mouse commands for BibTeX mode"
1173 (let ((selection
1174 (x-popup-menu
1176 '("BibTeX commands"
1177 ("BibTeX entry types"
1178 (" article in conference Proceedings " . bibtex-InProceedings)
1179 (" Article in journal " . bibtex-Article)
1180 (" Book " . bibtex-Book)
1181 (" Booklet " . bibtex-Booklet)
1182 (" Conference " . bibtex-InProceedings)
1183 (" Master's Thesis " . bibtex-MastersThesis)
1184 (" DEA Thesis " . bibtex-DEAthesis)
1185 (" Phd. Thesis " . bibtex-PhdThesis)
1186 (" Technical Report " . bibtex-TechReport)
1187 (" technical Manual " . bibtex-Manual)
1188 (" conference Proceedings " . bibtex-Proceedings)
1189 (" a chapter in a Book " . bibtex-InBook)
1190 (" an article in a Collection " . bibtex-InCollection)
1191 (" miscellaneous " . bibtex-Misc)
1192 (" unpublished " . bibtex-Unpublished)
1193 (" string " . bibtex-string)
1194 (" preamble " . bibtex-preamble)
1196 ("Moving around and editing"
1197 (" next field " . bibtex-next-field)
1198 (" to end of field " . bibtex-find-text)
1199 ("snatch from similar preceding field" . bibtex-pop-previous)
1200 ("snatch from similar following field" . bibtex-pop-next)
1201 (" remove OPT " . bibtex-remove-OPT)
1202 (" remove quotes "
1203 . bibtex-remove-double-quotes)
1204 (" clean up entry " . bibtex-clean-entry)
1206 ("help"
1207 (" describe BibTeX mode " . describe-mode)
1208 )))))
1209 (and selection (call-interactively selection))))
1211 (defun bibtex-x-environment ()
1212 "Set up X menus for BibTeX mode. Call it as bibtex-mode-hook, or interactively"
1213 (interactive)
1214 (require 'x-mouse)
1215 (define-key mouse-map x-button-c-right 'bibtex-x-help)
1220 ;; Please don't send anything to bug-gnu-emacs about these Sunwindows functions
1221 ;; since we aren't interested. See etc/SUN-SUPPORT for the reasons why
1222 ;; we consider this nothing but a distraction from our work.
1224 (defmacro eval-in-menu-window (&rest l)
1225 "Evaluates its argument in the window in which the mouse button was pressed."
1226 (list 'eval-in-window '*menu-window* l))
1228 ;(defmenu bibtex-sun-entry-menu
1229 ; ("Article In Conf. Proc." eval-in-menu-window bibtex-InProceedings)
1230 ; ("Article In Journal" eval-in-menu-window bibtex-Article)
1231 ; ("Book" eval-in-menu-window bibtex-Book)
1232 ; ("Booklet" eval-in-menu-window bibtex-Booklet)
1233 ; ("Master's Thesis" eval-in-menu-window bibtex-MastersThesis)
1234 ; ("PhD. Thesis" eval-in-menu-window bibtex-PhdThesis)
1235 ; ("Technical Report" eval-in-menu-window bibtex-TechReport)
1236 ; ("Technical Manual" eval-in-menu-window bibtex-Manual)
1237 ; ("Conference Proceedings" eval-in-menu-window bibtex-Proceedings)
1238 ; ("In A Book" eval-in-menu-window bibtex-InBook)
1239 ; ("In A Collection" eval-in-menu-window bibtex-InCollection)
1240 ; ("Miscellaneous" eval-in-menu-window bibtex-Misc)
1241 ; ("Unpublished" eval-in-menu-window bibtex-Unpublished)
1242 ; ("string" eval-in-menu-window bibtex-string)
1243 ; ("preamble" eval-in-menu-window bibtex-preamble))
1245 ;(defmenu bibtex-sun-menu
1246 ; ("BibTeX menu")
1247 ; ("add entry" . bibtex-sun-entry-menu)
1248 ; ("next field" eval-in-menu-window bibtex-next-field nil)
1249 ; ("to end of field" eval-in-menu-window bibtex-find-text nil)
1250 ; ("snatch similar preceding field" eval-in-menu-window bibtex-pop-previous 1)
1251 ; ("snatch similar following field" eval-in-menu-window bibtex-pop-next 1)
1252 ; ("remove OPT" eval-in-menu-window bibtex-remove-OPT)
1253 ; ("remove quotes" eval-in-menu-window bibtex-remove-double-quotes)
1254 ; ("clean entry" eval-in-menu-window bibtex-clean-entry)
1255 ; ("describe BibTeX mode" eval-in-menu-window describe-mode)
1256 ; ("Main Emacs menu" . emacs-menu))
1258 (defun bibtex-sun-menu-eval (window x y)
1259 "Pop-up menu of BibTeX commands."
1260 (sun-menu-evaluate window (1+ x) (1- y) 'bibtex-sun-menu))
1262 (defun bibtex-sun-environment ()
1263 "Set up sun menus for BibTeX mode. Call it as bibtex-mode-hook, or
1264 interactively"
1265 (interactive)
1266 (local-set-mouse '(text right) 'bibtex-sun-menu-eval))
1268 ;;; bibtex-mode.el ends here