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