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