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