emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] Changes to emacs/lisp/textmodes/bibtex.el [lexbind]


From: Miles Bader
Subject: [Emacs-diffs] Changes to emacs/lisp/textmodes/bibtex.el [lexbind]
Date: Tue, 14 Oct 2003 19:30:33 -0400

Index: emacs/lisp/textmodes/bibtex.el
diff -c emacs/lisp/textmodes/bibtex.el:1.69.2.1 
emacs/lisp/textmodes/bibtex.el:1.69.2.2
*** emacs/lisp/textmodes/bibtex.el:1.69.2.1     Fri Apr  4 01:20:37 2003
--- emacs/lisp/textmodes/bibtex.el      Tue Oct 14 19:30:21 2003
***************
*** 1,12 ****
  ;;; bibtex.el --- BibTeX mode for GNU Emacs
  
! ;; Copyright (C) 1992, 1994, 1995, 1996, 1997, 1998, 1999 Free Software 
Foundation, Inc.
  
  ;; Author: Stefan Schoef <address@hidden>
! ;;    Bengt Martensson <address@hidden>
! ;;    Mark Shapiro <address@hidden>
! ;;    Mike Newton <address@hidden>
! ;;    Aaron Larson <address@hidden>
  ;; Maintainer: Roland Winkler <address@hidden>
  ;; Keywords: BibTeX, LaTeX, TeX
  
--- 1,13 ----
  ;;; bibtex.el --- BibTeX mode for GNU Emacs
  
! ;; Copyright (C) 1992,94,95,96,97,98,1999,2003  Free Software Foundation, Inc.
  
  ;; Author: Stefan Schoef <address@hidden>
! ;;      Bengt Martensson <address@hidden>
! ;;      Mark Shapiro <address@hidden>
! ;;      Mike Newton <address@hidden>
! ;;      Aaron Larson <address@hidden>
! ;;      Dirk Herrmann <address@hidden>
  ;; Maintainer: Roland Winkler <address@hidden>
  ;; Keywords: BibTeX, LaTeX, TeX
  
***************
*** 40,73 ****
  
  ;;; Code:
  
- (eval-when-compile
-   (require 'compile))
- 
- 
- ;; Bug Reporting
- 
- (defconst
-   bibtex-maintainer-address "Dirk Herrmann <address@hidden>")
- ;; current maintainer
- 
- (defconst
-   bibtex-maintainer-salutation "Hallo Dirk,")
- ;; current maintainer
- 
- (defconst
-   bibtex-version "(emacs 20.4)")
- ;; current version of the bibtex.el file
- 
  
  ;; User Options:
  
  (defgroup bibtex nil
!   "BibTeX mode."
    :group 'tex
    :prefix "bibtex-")
  
  (defgroup bibtex-autokey nil
!   "Generates automatically a key from the author/editor and the title field"
    :group 'bibtex
    :prefix "bibtex-autokey-")
  
--- 41,56 ----
  
  ;;; Code:
  
  
  ;; User Options:
  
  (defgroup bibtex nil
!   "BibTeX mode"
    :group 'tex
    :prefix "bibtex-")
  
  (defgroup bibtex-autokey nil
!   "Generate automatically a key from the author/editor and the title field"
    :group 'bibtex
    :prefix "bibtex-autokey-")
  
***************
*** 77,101 ****
    :type 'hook)
  
  (defcustom bibtex-field-delimiters 'braces
!   "*Controls type of field delimiters used.
! Set this to `braces' or `double-quotes' according to your personal
! preferences.  This variable is buffer-local."
    :group 'bibtex
    :type '(choice (const braces)
!                (const double-quotes)))
! (make-variable-buffer-local 'bibtex-field-delimiters)
  
  (defcustom bibtex-entry-delimiters 'braces
!   "*Controls type of entry delimiters used.
! Set this to `braces' or `parentheses' according to your personal
! preferences.  This variable is buffer-local."
    :group 'bibtex
    :type '(choice (const braces)
!                (const parentheses)))
! (make-variable-buffer-local 'bibtex-entry-delimiters)
  
  (defcustom bibtex-include-OPTcrossref '("InProceedings" "InCollection")
!   "*All entries listed here will have an OPTcrossref field."
    :group 'bibtex
    :type '(repeat string))
  
--- 60,78 ----
    :type 'hook)
  
  (defcustom bibtex-field-delimiters 'braces
!   "*Type of field delimiters. Allowed values are `braces' or `double-quotes'."
    :group 'bibtex
    :type '(choice (const braces)
!                  (const double-quotes)))
  
  (defcustom bibtex-entry-delimiters 'braces
!   "*Type of entry delimiters. Allowed values are `braces' or `parentheses'."
    :group 'bibtex
    :type '(choice (const braces)
!                  (const parentheses)))
  
  (defcustom bibtex-include-OPTcrossref '("InProceedings" "InCollection")
!   "*List of entries that get an OPTcrossref field."
    :group 'bibtex
    :type '(repeat string))
  
***************
*** 105,113 ****
  If this is a function, it will be called to generate the initial field text."
    :group 'bibtex
    :type '(choice (const :tag "None" nil)
!                (string :tag "Initial text")
!                (function :tag "Initialize Function" :value fun)
!                (other :tag "Default" t)))
  
  (defcustom bibtex-user-optional-fields
    '(("annote" "Personal annotation (ignored)"))
--- 82,90 ----
  If this is a function, it will be called to generate the initial field text."
    :group 'bibtex
    :type '(choice (const :tag "None" nil)
!                  (string :tag "Initial text")
!                  (function :tag "Initialize Function" :value fun)
!                  (other :tag "Default" t)))
  
  (defcustom bibtex-user-optional-fields
    '(("annote" "Personal annotation (ignored)"))
***************
*** 116,135 ****
  CROSSREF-OPTIONAL lists in `bibtex-entry-field-alist' (see documentation
  of this variable for details)."
    :group 'bibtex
!   :type '(repeat
!         (group (string :tag "Field")
!                (string :tag "Comment")
!                (option (group :inline t
!                               :extra-offset -4
!                               (choice :tag "Init" :value ""
!                                       string
!                                       function))))))
! 
! (defcustom bibtex-entry-format '(opts-or-alts numerical-fields)
!   "*Controls type of formatting performed by `bibtex-clean-entry'.
  It may be t, nil, or a list of symbols out of the following:
  opts-or-alts        Delete empty optional and alternative fields and
                        remove OPT and ALT prefixes from used fields.
  numerical-fields    Delete delimiters around numeral fields.
  page-dashes         Change double dashes in page field to single dash
                        (for scribe compatibility).
--- 93,113 ----
  CROSSREF-OPTIONAL lists in `bibtex-entry-field-alist' (see documentation
  of this variable for details)."
    :group 'bibtex
!   :type '(repeat (group (string :tag "Field")
!                         (string :tag "Comment")
!                         (option (group :inline t
!                                        :extra-offset -4
!                                        (choice :tag "Init" :value ""
!                                                string
!                                                function))))))
! 
! (defcustom bibtex-entry-format
!   '(opts-or-alts required-fields numerical-fields)
!   "*Type of formatting performed by `bibtex-clean-entry'.
  It may be t, nil, or a list of symbols out of the following:
  opts-or-alts        Delete empty optional and alternative fields and
                        remove OPT and ALT prefixes from used fields.
+ required-fields     Signal an error if a required field is missing.
  numerical-fields    Delete delimiters around numeral fields.
  page-dashes         Change double dashes in page field to single dash
                        (for scribe compatibility).
***************
*** 151,166 ****
  The value nil means do no formatting at all."
    :group 'bibtex
    :type '(choice (const :tag "None" nil)
!                (const :tag "All" t)
!                (set :menu-tag "Some"
!                     (const opts-or-alts)
!                     (const numerical-fields)
!                     (const page-dashes)
!                     (const inherit-booktitle)
!                     (const realign)
!                     (const last-comma)
!                     (const delimiters)
!                     (const unify-case))))
  
  (defcustom bibtex-clean-entry-hook nil
    "*List of functions to call when entry has been cleaned.
--- 129,145 ----
  The value nil means do no formatting at all."
    :group 'bibtex
    :type '(choice (const :tag "None" nil)
!                  (const :tag "All" t)
!                  (set :menu-tag "Some"
!                       (const opts-or-alts)
!                       (const required-fields)
!                       (const numerical-fields)
!                       (const page-dashes)
!                       (const inherit-booktitle)
!                       (const realign)
!                       (const last-comma)
!                       (const delimiters)
!                       (const unify-case))))
  
  (defcustom bibtex-clean-entry-hook nil
    "*List of functions to call when entry has been cleaned.
***************
*** 169,192 ****
    :group 'bibtex
    :type 'hook)
  
  (defcustom bibtex-sort-ignore-string-entries t
    "*If non-nil, BibTeX @String entries are not sort-significant.
  That means they are ignored when determining ordering of the buffer
! \(e.g., sorting, locating alphabetical position for new entries, etc.).
! This variable is buffer-local."
!   :group 'bibtex
!   :type 'boolean)
! (make-variable-buffer-local 'bibtex-sort-ignore-string-entries)
! 
! (defcustom bibtex-maintain-sorted-entries nil
!   "*If non-nil, BibTeX mode maintains all BibTeX entries in sorted order.
! Setting this variable to nil will strip off some comfort (e.g., TAB
! completion for reference keys in minibuffer, automatic detection of
! duplicates) from BibTeX mode.  See also `bibtex-sort-ignore-string-entries'.
! This variable is buffer-local."
    :group 'bibtex
    :type 'boolean)
- (make-variable-buffer-local 'bibtex-maintain-sorted-entries)
  
  (defcustom bibtex-field-kill-ring-max 20
    "*Max length of `bibtex-field-kill-ring' before discarding oldest elements."
--- 148,186 ----
    :group 'bibtex
    :type 'hook)
  
+ (defcustom bibtex-maintain-sorted-entries nil
+   "*If non-nil, BibTeX mode maintains all BibTeX entries in sorted order.
+ Allowed non-nil values are:
+ plain        All entries are sorted alphabetically.
+ crossref     All entries are sorted alphabetically unless an entry has a
+              crossref field. These crossrefed entries are placed in
+              alphabetical order immediately preceding the main entry.
+ entry-class  The entries are divided into classes according to their
+              entry name, see `bibtex-sort-entry-class'. Within each class
+              the entries are sorted alphabetically.
+ See also `bibtex-sort-ignore-string-entries'."
+   :group 'bibtex
+   :type '(choice (const nil)
+                  (const plain)
+                  (const crossref)
+                  (const entry-class)))
+ 
+ (defvar bibtex-sort-entry-class
+   '(("String")
+     (catch-all)
+     ("Book" "Proceedings"))
+   "*List of classes of BibTeX entry names, used for sorting entries.
+ If value of `bibtex-maintain-sorted-entries' is `entry-class'
+ entries are ordered according to the classes they belong to. Each
+ class contains a list of entry names. An entry `catch-all' applies
+ to all entries not explicitely mentioned.")
+ 
  (defcustom bibtex-sort-ignore-string-entries t
    "*If non-nil, BibTeX @String entries are not sort-significant.
  That means they are ignored when determining ordering of the buffer
! \(e.g., sorting, locating alphabetical position for new entries, etc.)."
    :group 'bibtex
    :type 'boolean)
  
  (defcustom bibtex-field-kill-ring-max 20
    "*Max length of `bibtex-field-kill-ring' before discarding oldest elements."
***************
*** 199,409 ****
    :type 'integer)
  
  (defcustom bibtex-parse-keys-timeout 60
!   "*Specifies interval for parsing buffers.
  All BibTeX buffers in Emacs are parsed if Emacs has been idle
  `bibtex-parse-keys-timeout' seconds.  Only buffers which were modified
  after last parsing and which are maintained in sorted order are parsed."
    :group 'bibtex
    :type 'integer)
  
  (defvar bibtex-entry-field-alist
    '(
!     ("Article" . (((("author" "Author1 [and Author2 ...] [and others]")
!                     ("title" "Title of the article (BibTeX converts it to 
lowercase)")
!                     ("journal" "Name of the journal (use string, remove 
braces)")
!                     ("year" "Year of publication"))
!                  (("volume" "Volume of the journal")
!                     ("number" "Number of the journal (only allowed if entry 
contains volume)")
!                     ("pages" "Pages in the journal")
!                     ("month" "Month of the publication as a string (remove 
braces)")
!                     ("note" "Remarks to be put at the end of the \\bibitem")))
!                 ((("author" "Author1 [and Author2 ...] [and others]")
!                     ("title" "Title of the article (BibTeX converts it to 
lowercase)"))
!                  (("pages" "Pages in the journal")
!                     ("journal" "Name of the journal (use string, remove 
braces)")
!                     ("year" "Year of publication")
!                     ("volume" "Volume of the journal")
!                     ("number" "Number of the journal")
!                   ("month" "Month of the publication as a string (remove 
braces)")
!                     ("note" "Remarks to be put at the end of the 
\\bibitem")))))
!     ("Book" . (((("author" "Author1 [and Author2 ...] [and others]" "" t)
!                  ("editor" "Editor1 [and Editor2 ...] [and others]" "" t)
!                  ("title" "Title of the book")
!                  ("publisher" "Publishing company")
!                  ("year" "Year of publication"))
!               (("volume" "Volume of the book in the series")
!                  ("number" "Number of the book in a small series (overwritten 
by volume)")
!                  ("series" "Series in which the book appeared")
!                  ("address" "Address of the publisher")
!                ("edition" "Edition of the book as a capitalized English word")
!                  ("month" "Month of the publication as a string (remove 
braces)")
!                  ("note" "Remarks to be put at the end of the \\bibitem")))
!                ((("author" "Author1 [and Author2 ...] [and others]" "" t)
!                  ("editor" "Editor1 [and Editor2 ...] [and others]" "" t)
!                  ("title" "Title of the book"))
!                 (("publisher" "Publishing company")
!                  ("year" "Year of publication")
!                  ("volume" "Volume of the book in the series")
!                  ("number" "Number of the book in a small series (overwritten 
by volume)")
!                  ("series" "Series in which the book appeared")
!                  ("address" "Address of the publisher")
!                ("edition" "Edition of the book as a capitalized English word")
!                  ("month" "Month of the publication as a string (remove 
braces)")
!                  ("note" "Remarks to be put at the end of the \\bibitem")))))
!     ("Booklet" . (((("title" "Title of the booklet (BibTeX converts it to 
lowercase)"))
!                  (("author" "Author1 [and Author2 ...] [and others]")
!                     ("howpublished" "The way in which the booklet was 
published")
!                     ("address" "Address of the publisher")
!                     ("month" "Month of the publication as a string (remove 
braces)")
!                     ("year" "Year of publication")
!                     ("note" "Remarks to be put at the end of the 
\\bibitem")))))
!     ("InBook" . (((("author" "Author1 [and Author2 ...] [and others]" "" t)
!                    ("editor" "Editor1 [and Editor2 ...] [and others]" "" t)
!                    ("title" "Title of the book")
!                    ("chapter" "Chapter in the book")
!                    ("publisher" "Publishing company")
!                    ("year" "Year of publication"))
!                 (("volume" "Volume of the book in the series")
!                    ("number" "Number of the book in a small series 
(overwritten by volume)")
!                    ("series" "Series in which the book appeared")
!                    ("type" "Word to use instead of \"chapter\"")
!                    ("address" "Address of the publisher")
!                  ("edition" "Edition of the book as a capitalized English 
word")
!                    ("month" "Month of the publication as a string (remove 
braces)")
!                    ("pages" "Pages in the book")
!                    ("note" "Remarks to be put at the end of the \\bibitem")))
!                ((("author" "Author1 [and Author2 ...] [and others]" "" t)
!                    ("editor" "Editor1 [and Editor2 ...] [and others]" "" t)
!                    ("title" "Title of the book")
!                    ("chapter" "Chapter in the book"))
!                 (("pages" "Pages in the book")
!                    ("publisher" "Publishing company")
!                    ("year" "Year of publication")
!                    ("volume" "Volume of the book in the series")
!                    ("number" "Number of the book in a small series 
(overwritten by volume)")
!                  ("series" "Series in which the book appeared")
!                    ("type" "Word to use instead of \"chapter\"")
!                    ("address" "Address of the publisher")
!                    ("edition" "Edition of the book as a capitalized English 
word")
!                    ("month" "Month of the publication as a string (remove 
braces)")
!                    ("note" "Remarks to be put at the end of the 
\\bibitem")))))
!     ("InCollection" . (((("author" "Author1 [and Author2 ...] [and others]")
!                          ("title" "Title of the article in book (BibTeX 
converts it to lowercase)")
!                        ("booktitle" "Name of the book")
!                          ("publisher" "Publishing company")
!                          ("year" "Year of publication"))
!                       (("editor" "Editor1 [and Editor2 ...] [and others]")
!                          ("volume" "Volume of the book in the series")
!                          ("number" "Number of the book in a small series 
(overwritten by volume)")
!                          ("series" "Series in which the book appeared")
!                          ("type" "Word to use instead of \"chapter\"")
!                          ("chapter" "Chapter in the book")
!                        ("pages" "Pages in the book")
!                          ("address" "Address of the publisher")
!                          ("edition" "Edition of the book as a capitalized 
English word")
!                          ("month" "Month of the publication as a string 
(remove braces)")
!                          ("note" "Remarks to be put at the end of the 
\\bibitem")))
!                      ((("author" "Author1 [and Author2 ...] [and others]")
!                          ("title" "Title of the article in book (BibTeX 
converts it to lowercase)")
!                          ("booktitle" "Name of the book"))
!                       (("pages" "Pages in the book")
!                          ("publisher" "Publishing company")
!                          ("year" "Year of publication")
!                        ("editor" "Editor1 [and Editor2 ...] [and others]")
!                          ("volume" "Volume of the book in the series")
!                          ("number" "Number of the book in a small series 
(overwritten by volume)")
!                          ("series" "Series in which the book appeared")
!                          ("type" "Word to use instead of \"chapter\"")
!                          ("chapter" "Chapter in the book")
!                          ("address" "Address of the publisher")
!                          ("edition" "Edition of the book as a capitalized 
English word")
!                          ("month" "Month of the publication as a string 
(remove braces)")
!                          ("note" "Remarks to be put at the end of the 
\\bibitem")))))
!     ("InProceedings" . (((("author" "Author1 [and Author2 ...] [and others]")
!                           ("title" "Title of the article in proceedings 
(BibTeX converts it to lowercase)")
!                           ("booktitle" "Name of the conference proceedings")
!                           ("year" "Year of publication"))
!                        (("editor" "Editor1 [and Editor2 ...] [and others]")
!                           ("volume" "Volume of the conference proceedings in 
the series")
!                           ("number" "Number of the conference proceedings in 
a small series (overwritten by volume)")
!                           ("series" "Series in which the conference 
proceedings appeared")
!                           ("pages" "Pages in the conference proceedings")
!                           ("address" "Location of the Proceedings")
!                           ("month" "Month of the publication as a string 
(remove braces)")
!                         ("organization" "Sponsoring organization of the 
conference")
!                           ("publisher" "Publishing company, its location")
!                           ("note" "Remarks to be put at the end of the 
\\bibitem")))
!                       ((("author" "Author1 [and Author2 ...] [and others]")
!                           ("title" "Title of the article in proceedings 
(BibTeX converts it to lowercase)"))
!                        (("booktitle" "Name of the conference proceedings")
!                         ("pages" "Pages in the conference proceedings")
!                           ("year" "Year of publication")
!                           ("editor" "Editor1 [and Editor2 ...] [and others]")
!                           ("volume" "Volume of the conference proceedings in 
the series")
!                           ("number" "Number of the conference proceedings in 
a small series (overwritten by volume)")
!                           ("series" "Series in which the conference 
proceedings appeared")
!                           ("address" "Location of the Proceedings")
!                           ("month" "Month of the publication as a string 
(remove braces)")
!                         ("organization" "Sponsoring organization of the 
conference")
!                           ("publisher" "Publishing company, its location")
!                           ("note" "Remarks to be put at the end of the 
\\bibitem")))))
!     ("Manual" . (((("title" "Title of the manual"))
!                 (("author" "Author1 [and Author2 ...] [and others]")
!                    ("organization" "Publishing organization of the manual")
!                    ("address" "Address of the organization")
!                    ("edition" "Edition of the manual as a capitalized English 
word")
!                  ("month" "Month of the publication as a string (remove 
braces)")
!                    ("year" "Year of publication")
!                    ("note" "Remarks to be put at the end of the 
\\bibitem")))))
!     ("MastersThesis" . (((("author" "Author1 [and Author2 ...] [and others]")
!                           ("title" "Title of the master\'s thesis (BibTeX 
converts it to lowercase)")
!                           ("school" "School where the master\'s thesis was 
written")
!                           ("year" "Year of publication"))
!                          (("type" "Type of the master\'s thesis (if other 
than \"Master\'s thesis\")")
!                         ("address" "Address of the school (if not part of 
field \"school\") or country")
!                           ("month" "Month of the publication as a string 
(remove braces)")
!                           ("note" "Remarks to be put at the end of the 
\\bibitem")))))
!     ("Misc" . ((()
!               (("author" "Author1 [and Author2 ...] [and others]")
!                  ("title" "Title of the work (BibTeX converts it to 
lowercase)")
!                  ("howpublished" "The way in which the work was published")
!                  ("month" "Month of the publication as a string (remove 
braces)")
!                  ("year" "Year of publication")
!                  ("note" "Remarks to be put at the end of the \\bibitem")))))
!     ("PhdThesis" . (((("author" "Author1 [and Author2 ...] [and others]")
!                       ("title" "Title of the PhD. thesis")
!                       ("school" "School where the PhD. thesis was written")
!                       ("year" "Year of publication"))
!                      (("type" "Type of the PhD. thesis")
!                       ("address" "Address of the school (if not part of field 
\"school\") or country")
!                       ("month" "Month of the publication as a string (remove 
braces)")
!                       ("note" "Remarks to be put at the end of the 
\\bibitem")))))
!     ("Proceedings" . (((("title" "Title of the conference proceedings")
!                         ("year" "Year of publication"))
!                      (("booktitle" "Title of the proceedings for cross 
references")
!                       ("editor" "Editor1 [and Editor2 ...] [and others]")
!                         ("volume" "Volume of the conference proceedings in 
the series")
!                         ("number" "Number of the conference proceedings in a 
small series (overwritten by volume)")
!                         ("series" "Series in which the conference proceedings 
appeared")
!                         ("address" "Location of the Proceedings")
!                         ("month" "Month of the publication as a string 
(remove braces)")
!                       ("organization" "Sponsoring organization of the 
conference")
!                         ("publisher" "Publishing company, its location")
!                         ("note" "Remarks to be put at the end of the 
\\bibitem")))))
!     ("TechReport" . (((("author" "Author1 [and Author2 ...] [and others]")
!                        ("title" "Title of the technical report (BibTeX 
converts it to lowercase)")
!                        ("institution" "Sponsoring institution of the report")
!                        ("year" "Year of publication"))
!                     (("type" "Type of the report (if other than \"technical 
report\")")
!                        ("number" "Number of the technical report")
!                        ("address" "Address of the institution (if not part of 
field \"institution\") or country")
!                        ("month" "Month of the publication as a string (remove 
braces)")
!                        ("note" "Remarks to be put at the end of the 
\\bibitem")))))
!     ("Unpublished" . (((("author" "Author1 [and Author2 ...] [and others]")
!                         ("title" "Title of the unpublished work (BibTeX 
converts it to lowercase)")
!                         ("note" "Remarks to be put at the end of the 
\\bibitem"))
!                      (("month" "Month of the publication as a string (remove 
braces)")
!                         ("year" "Year of publication")))))
      )
  
    "Defines entry types and their associated fields.
--- 193,422 ----
    :type 'integer)
  
  (defcustom bibtex-parse-keys-timeout 60
!   "*Specify interval for parsing BibTeX buffers.
  All BibTeX buffers in Emacs are parsed if Emacs has been idle
  `bibtex-parse-keys-timeout' seconds.  Only buffers which were modified
  after last parsing and which are maintained in sorted order are parsed."
    :group 'bibtex
    :type 'integer)
  
+ (defcustom bibtex-parse-keys-fast t
+   "*If non-nil, use fast but simplified algorithm for parsing BibTeX keys.
+ If parsing fails, try to set this variable to nil."
+   :group 'bibtex
+   :type 'boolean)
+ 
  (defvar bibtex-entry-field-alist
    '(
!     ("Article"
!      ((("author" "Author1 [and Author2 ...] [and others]")
!        ("title" "Title of the article (BibTeX converts it to lowercase)")
!        ("journal" "Name of the journal (use string, remove braces)")
!        ("year" "Year of publication"))
!       (("volume" "Volume of the journal")
!        ("number" "Number of the journal (only allowed if entry contains 
volume)")
!        ("pages" "Pages in the journal")
!        ("month" "Month of the publication as a string (remove braces)")
!        ("note" "Remarks to be put at the end of the \\bibitem")))
!      ((("author" "Author1 [and Author2 ...] [and others]")
!        ("title" "Title of the article (BibTeX converts it to lowercase)"))
!       (("pages" "Pages in the journal")
!        ("journal" "Name of the journal (use string, remove braces)")
!        ("year" "Year of publication")
!        ("volume" "Volume of the journal")
!        ("number" "Number of the journal")
!        ("month" "Month of the publication as a string (remove braces)")
!        ("note" "Remarks to be put at the end of the \\bibitem"))))
!     ("Book"
!      ((("author" "Author1 [and Author2 ...] [and others]" "" t)
!        ("editor" "Editor1 [and Editor2 ...] [and others]" "" t)
!        ("title" "Title of the book")
!        ("publisher" "Publishing company")
!        ("year" "Year of publication"))
!       (("volume" "Volume of the book in the series")
!        ("number" "Number of the book in a small series (overwritten by 
volume)")
!        ("series" "Series in which the book appeared")
!        ("address" "Address of the publisher")
!        ("edition" "Edition of the book as a capitalized English word")
!        ("month" "Month of the publication as a string (remove braces)")
!        ("note" "Remarks to be put at the end of the \\bibitem")))
!      ((("author" "Author1 [and Author2 ...] [and others]" "" t)
!        ("editor" "Editor1 [and Editor2 ...] [and others]" "" t)
!        ("title" "Title of the book"))
!       (("publisher" "Publishing company")
!        ("year" "Year of publication")
!        ("volume" "Volume of the book in the series")
!        ("number" "Number of the book in a small series (overwritten by 
volume)")
!        ("series" "Series in which the book appeared")
!        ("address" "Address of the publisher")
!        ("edition" "Edition of the book as a capitalized English word")
!        ("month" "Month of the publication as a string (remove braces)")
!        ("note" "Remarks to be put at the end of the \\bibitem"))))
!     ("Booklet"
!      ((("title" "Title of the booklet (BibTeX converts it to lowercase)"))
!       (("author" "Author1 [and Author2 ...] [and others]")
!        ("howpublished" "The way in which the booklet was published")
!        ("address" "Address of the publisher")
!        ("month" "Month of the publication as a string (remove braces)")
!        ("year" "Year of publication")
!        ("note" "Remarks to be put at the end of the \\bibitem"))))
!     ("InBook"
!      ((("author" "Author1 [and Author2 ...] [and others]" "" t)
!        ("editor" "Editor1 [and Editor2 ...] [and others]" "" t)
!        ("title" "Title of the book")
!        ("chapter" "Chapter in the book")
!        ("publisher" "Publishing company")
!        ("year" "Year of publication"))
!       (("volume" "Volume of the book in the series")
!        ("number" "Number of the book in a small series (overwritten by 
volume)")
!        ("series" "Series in which the book appeared")
!        ("type" "Word to use instead of \"chapter\"")
!        ("address" "Address of the publisher")
!        ("edition" "Edition of the book as a capitalized English word")
!        ("month" "Month of the publication as a string (remove braces)")
!        ("pages" "Pages in the book")
!        ("note" "Remarks to be put at the end of the \\bibitem")))
!      ((("author" "Author1 [and Author2 ...] [and others]" "" t)
!        ("editor" "Editor1 [and Editor2 ...] [and others]" "" t)
!        ("title" "Title of the book")
!        ("chapter" "Chapter in the book"))
!       (("pages" "Pages in the book")
!        ("publisher" "Publishing company")
!        ("year" "Year of publication")
!        ("volume" "Volume of the book in the series")
!        ("number" "Number of the book in a small series (overwritten by 
volume)")
!        ("series" "Series in which the book appeared")
!        ("type" "Word to use instead of \"chapter\"")
!        ("address" "Address of the publisher")
!        ("edition" "Edition of the book as a capitalized English word")
!        ("month" "Month of the publication as a string (remove braces)")
!        ("note" "Remarks to be put at the end of the \\bibitem"))))
!     ("InCollection"
!      ((("author" "Author1 [and Author2 ...] [and others]")
!        ("title" "Title of the article in book (BibTeX converts it to 
lowercase)")
!        ("booktitle" "Name of the book")
!        ("publisher" "Publishing company")
!        ("year" "Year of publication"))
!       (("editor" "Editor1 [and Editor2 ...] [and others]")
!        ("volume" "Volume of the book in the series")
!        ("number" "Number of the book in a small series (overwritten by 
volume)")
!        ("series" "Series in which the book appeared")
!        ("type" "Word to use instead of \"chapter\"")
!        ("chapter" "Chapter in the book")
!        ("pages" "Pages in the book")
!        ("address" "Address of the publisher")
!        ("edition" "Edition of the book as a capitalized English word")
!        ("month" "Month of the publication as a string (remove braces)")
!        ("note" "Remarks to be put at the end of the \\bibitem")))
!      ((("author" "Author1 [and Author2 ...] [and others]")
!        ("title" "Title of the article in book (BibTeX converts it to 
lowercase)")
!        ("booktitle" "Name of the book"))
!       (("pages" "Pages in the book")
!        ("publisher" "Publishing company")
!        ("year" "Year of publication")
!        ("editor" "Editor1 [and Editor2 ...] [and others]")
!        ("volume" "Volume of the book in the series")
!        ("number" "Number of the book in a small series (overwritten by 
volume)")
!        ("series" "Series in which the book appeared")
!        ("type" "Word to use instead of \"chapter\"")
!        ("chapter" "Chapter in the book")
!        ("address" "Address of the publisher")
!        ("edition" "Edition of the book as a capitalized English word")
!        ("month" "Month of the publication as a string (remove braces)")
!        ("note" "Remarks to be put at the end of the \\bibitem"))))
!     ("InProceedings"
!      ((("author" "Author1 [and Author2 ...] [and others]")
!        ("title" "Title of the article in proceedings (BibTeX converts it to 
lowercase)")
!        ("booktitle" "Name of the conference proceedings")
!        ("year" "Year of publication"))
!       (("editor" "Editor1 [and Editor2 ...] [and others]")
!        ("volume" "Volume of the conference proceedings in the series")
!        ("number" "Number of the conference proceedings in a small series 
(overwritten by volume)")
!        ("series" "Series in which the conference proceedings appeared")
!        ("pages" "Pages in the conference proceedings")
!        ("address" "Location of the Proceedings")
!        ("month" "Month of the publication as a string (remove braces)")
!        ("organization" "Sponsoring organization of the conference")
!        ("publisher" "Publishing company, its location")
!        ("note" "Remarks to be put at the end of the \\bibitem")))
!      ((("author" "Author1 [and Author2 ...] [and others]")
!        ("title" "Title of the article in proceedings (BibTeX converts it to 
lowercase)"))
!       (("booktitle" "Name of the conference proceedings")
!        ("pages" "Pages in the conference proceedings")
!        ("year" "Year of publication")
!        ("editor" "Editor1 [and Editor2 ...] [and others]")
!        ("volume" "Volume of the conference proceedings in the series")
!        ("number" "Number of the conference proceedings in a small series 
(overwritten by volume)")
!        ("series" "Series in which the conference proceedings appeared")
!        ("address" "Location of the Proceedings")
!        ("month" "Month of the publication as a string (remove braces)")
!        ("organization" "Sponsoring organization of the conference")
!        ("publisher" "Publishing company, its location")
!        ("note" "Remarks to be put at the end of the \\bibitem"))))
!     ("Manual"
!      ((("title" "Title of the manual"))
!       (("author" "Author1 [and Author2 ...] [and others]")
!        ("organization" "Publishing organization of the manual")
!        ("address" "Address of the organization")
!        ("edition" "Edition of the manual as a capitalized English word")
!        ("month" "Month of the publication as a string (remove braces)")
!        ("year" "Year of publication")
!        ("note" "Remarks to be put at the end of the \\bibitem"))))
!     ("MastersThesis"
!      ((("author" "Author1 [and Author2 ...] [and others]")
!        ("title" "Title of the master\'s thesis (BibTeX converts it to 
lowercase)")
!        ("school" "School where the master\'s thesis was written")
!        ("year" "Year of publication"))
!       (("type" "Type of the master\'s thesis (if other than \"Master\'s 
thesis\")")
!        ("address" "Address of the school (if not part of field \"school\") or 
country")
!        ("month" "Month of the publication as a string (remove braces)")
!        ("note" "Remarks to be put at the end of the \\bibitem"))))
!     ("Misc"
!      (()
!       (("author" "Author1 [and Author2 ...] [and others]")
!        ("title" "Title of the work (BibTeX converts it to lowercase)")
!        ("howpublished" "The way in which the work was published")
!        ("month" "Month of the publication as a string (remove braces)")
!        ("year" "Year of publication")
!        ("note" "Remarks to be put at the end of the \\bibitem"))))
!     ("PhdThesis"
!      ((("author" "Author1 [and Author2 ...] [and others]")
!        ("title" "Title of the PhD. thesis")
!        ("school" "School where the PhD. thesis was written")
!        ("year" "Year of publication"))
!       (("type" "Type of the PhD. thesis")
!        ("address" "Address of the school (if not part of field \"school\") or 
country")
!        ("month" "Month of the publication as a string (remove braces)")
!        ("note" "Remarks to be put at the end of the \\bibitem"))))
!     ("Proceedings"
!      ((("title" "Title of the conference proceedings")
!        ("year" "Year of publication"))
!       (("booktitle" "Title of the proceedings for cross references")
!        ("editor" "Editor1 [and Editor2 ...] [and others]")
!        ("volume" "Volume of the conference proceedings in the series")
!        ("number" "Number of the conference proceedings in a small series 
(overwritten by volume)")
!        ("series" "Series in which the conference proceedings appeared")
!        ("address" "Location of the Proceedings")
!        ("month" "Month of the publication as a string (remove braces)")
!        ("organization" "Sponsoring organization of the conference")
!        ("publisher" "Publishing company, its location")
!        ("note" "Remarks to be put at the end of the \\bibitem"))))
!     ("TechReport"
!      ((("author" "Author1 [and Author2 ...] [and others]")
!        ("title" "Title of the technical report (BibTeX converts it to 
lowercase)")
!        ("institution" "Sponsoring institution of the report")
!        ("year" "Year of publication"))
!       (("type" "Type of the report (if other than \"technical report\")")
!        ("number" "Number of the technical report")
!        ("address" "Address of the institution (if not part of field 
\"institution\") or country")
!        ("month" "Month of the publication as a string (remove braces)")
!        ("note" "Remarks to be put at the end of the \\bibitem"))))
!     ("Unpublished"
!      ((("author" "Author1 [and Author2 ...] [and others]")
!        ("title" "Title of the unpublished work (BibTeX converts it to 
lowercase)")
!        ("note" "Remarks to be put at the end of the \\bibitem"))
!       (("month" "Month of the publication as a string (remove braces)")
!        ("year" "Year of publication"))))
      )
  
    "Defines entry types and their associated fields.
***************
*** 424,430 ****
  field is an alternative.  ALTERNATIVE-FLAG may be t only in the
  REQUIRED or CROSSREF-REQUIRED lists.")
  
! (defvar bibtex-comment-start "@Comment ")
  
  (defcustom bibtex-add-entry-hook nil
    "List of functions to call when entry has been inserted."
--- 437,444 ----
  field is an alternative.  ALTERNATIVE-FLAG may be t only in the
  REQUIRED or CROSSREF-REQUIRED lists.")
  
! (defvar bibtex-comment-start "@Comment"
!   "String starting a BibTeX comment.")
  
  (defcustom bibtex-add-entry-hook nil
    "List of functions to call when entry has been inserted."
***************
*** 432,470 ****
    :type 'hook)
  
  (defcustom bibtex-predefined-month-strings
!   '(
!     ("jan") ("feb") ("mar") ("apr") ("may") ("jun")
!     ("jul") ("aug") ("sep") ("oct") ("nov") ("dec")
!     )
!   "Alist of month string definitions.
! Should contain all strings used for months in the BibTeX style files.
! Each element is a list with just one element: the string."
    :group 'bibtex
!   :type '(repeat
!         (list string)))
  
  (defcustom bibtex-predefined-strings
    (append
     bibtex-predefined-month-strings
!    '(
!      ("acmcs") ("acta") ("cacm") ("ibmjrd") ("ibmsj") ("ieeese")
!      ("ieeetc") ("ieeetcad") ("ipl") ("jacm") ("jcss") ("scp")
!      ("sicomp") ("tcs") ("tocs") ("tods") ("tog") ("toms") ("toois")
!      ("toplas")
!      ))
!   "Alist of string definitions.
! Should contain the strings defined in the BibTeX style files.  Each
! element is a list with just one element: the string."
    :group 'bibtex
!   :type '(repeat
!         (list string)))
  
  (defcustom bibtex-string-files nil
    "*List of BibTeX files containing string definitions.
  Those files must be specified using pathnames relative to the
! directories specified in `bibtex-string-file-path'.  This variable is only
! evaluated when BibTeX mode is entered (i.e., when loading the BibTeX
! file)."
    :group 'bibtex
    :type '(repeat file))
  
--- 446,502 ----
    :type 'hook)
  
  (defcustom bibtex-predefined-month-strings
!   '(("jan" . "January")
!     ("feb" . "February")
!     ("mar" . "March")
!     ("apr" . "April")
!     ("may" . "May")
!     ("jun" . "June")
!     ("jul" . "July")
!     ("aug" . "August")
!     ("sep" . "September")
!     ("oct" . "October")
!     ("nov" . "November")
!     ("dec" . "December"))
!   "Alist of month string definitions used in the BibTeX style files.
! Each element is a pair of strings (ABBREVIATION . EXPANSION)."
    :group 'bibtex
!   :type '(repeat (cons (string :tag "Month abbreviation")
!                        (string :tag "Month expansion"))))
  
  (defcustom bibtex-predefined-strings
    (append
     bibtex-predefined-month-strings
!    '(("acmcs"    . "ACM Computing Surveys")
!      ("acta"     . "Acta Informatica")
!      ("cacm"     . "Communications of the ACM")
!      ("ibmjrd"   . "IBM Journal of Research and Development")
!      ("ibmsj"    . "IBM Systems Journal")
!      ("ieeese"   . "IEEE Transactions on Software Engineering")
!      ("ieeetc"   . "IEEE Transactions on Computers")
!      ("ieeetcad" . "IEEE Transactions on Computer-Aided Design of Integrated 
Circuits")
!      ("ipl"      . "Information Processing Letters")
!      ("jacm"     . "Journal of the ACM")
!      ("jcss"     . "Journal of Computer and System Sciences")
!      ("scp"      . "Science of Computer Programming")
!      ("sicomp"   . "SIAM Journal on Computing")
!      ("tcs"      . "Theoretical Computer Science")
!      ("tocs"     . "ACM Transactions on Computer Systems")
!      ("tods"     . "ACM Transactions on Database Systems")
!      ("tog"      . "ACM Transactions on Graphics")
!      ("toms"     . "ACM Transactions on Mathematical Software")
!      ("toois"    . "ACM Transactions on Office Information Systems")
!      ("toplas"   . "ACM Transactions on Programming Languages and Systems")))
!   "Alist of string definitions used in the BibTeX style files.
! Each element is a pair of strings (ABBREVIATION . EXPANSION)."
    :group 'bibtex
!   :type '(repeat (cons (string :tag "String")
!                        (string :tag "String expansion"))))
  
  (defcustom bibtex-string-files nil
    "*List of BibTeX files containing string definitions.
  Those files must be specified using pathnames relative to the
! directories specified in `bibtex-string-file-path'."
    :group 'bibtex
    :type '(repeat file))
  
***************
*** 472,530 ****
    "*Colon separated list of paths to search for `bibtex-string-files'.")
  
  (defcustom bibtex-help-message t
!   "*If not nil print help messages in the echo area on entering a new field."
    :group 'bibtex
    :type 'boolean)
  
  (defcustom bibtex-autokey-prefix-string ""
    "*String to use as a prefix for all generated keys.
! See the documentation of function `bibtex-generate-autokey' for more detail."
    :group 'bibtex-autokey
    :type 'string)
  
  (defcustom bibtex-autokey-names 1
    "*Number of names to use for the automatically generated reference key.
- If this is variable is nil, all names are used.
  Possibly more names are used according to `bibtex-autokey-names-stretch'.
! See the documentation of function `bibtex-generate-autokey' for more detail."
    :group 'bibtex-autokey
    :type '(choice (const :tag "All" infty)
!                integer))
  
  (defcustom bibtex-autokey-names-stretch 0
    "*Number of names that can additionally be used.
  These names are used only, if all names are used then.
! See the documentation of function `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type 'integer)
  
  (defcustom bibtex-autokey-additional-names ""
    "*String to prepend to the generated key if not all names could be used.
! See the documentation of function `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type 'string)
  
  (defvar bibtex-autokey-transcriptions
!   '(
!     ;; language specific characters
!     ("\\\\aa" "a")
!     ("\\\\AA" "A")
!     ("\\\"a\\|\\\\\\\"a\\|\\\\ae" "ae")
!     ("\\\"A\\|\\\\\\\"A\\|\\\\AE" "Ae")
!     ("\\\\i" "i")
!     ("\\\\j" "j")
!     ("\\\\l" "l")
!     ("\\\\L" "L")
!     ("\\\"o\\|\\\\\\\"o\\|\\\\o\\|\\\\oe" "oe")
!     ("\\\"O\\|\\\\\\\"O\\|\\\\O\\|\\\\OE" "Oe")
!     ("\\\"s\\|\\\\\\\"s" "ss")
!     ("\\\"u\\|\\\\\\\"u" "ue")
!     ("\\\"U\\|\\\\\\\"U" "Ue")
      ;; accents
!     
("\\\\`\\|\\\\'\\|\\\\\\^\\|\\\\~\\|\\\\=\\|\\\\\\.\\|\\\\u\\|\\\\v\\|\\\\H\\|\\\\t\\|\\\\c\\|\\\\d\\|\\\\b"
 "")
!     ;; braces
!     ("{" "") ("}" ""))
!   "Alist of (old-regexp new-string) pairs.
  Used by the default values of `bibtex-autokey-name-change-strings' and
  `bibtex-autokey-titleword-change-strings'.  Defaults to translating some
  language specific characters to their ASCII transcriptions, and
--- 504,563 ----
    "*Colon separated list of paths to search for `bibtex-string-files'.")
  
  (defcustom bibtex-help-message t
!   "*If non-nil print help messages in the echo area on entering a new field."
    :group 'bibtex
    :type 'boolean)
  
  (defcustom bibtex-autokey-prefix-string ""
    "*String to use as a prefix for all generated keys.
! See `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type 'string)
  
  (defcustom bibtex-autokey-names 1
    "*Number of names to use for the automatically generated reference key.
  Possibly more names are used according to `bibtex-autokey-names-stretch'.
! If this variable is nil, all names are used.
! See `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type '(choice (const :tag "All" infty)
!                  integer))
  
  (defcustom bibtex-autokey-names-stretch 0
    "*Number of names that can additionally be used.
  These names are used only, if all names are used then.
! See `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type 'integer)
  
  (defcustom bibtex-autokey-additional-names ""
    "*String to prepend to the generated key if not all names could be used.
! See `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type 'string)
  
  (defvar bibtex-autokey-transcriptions
!   '(;; language specific characters
!     ("\\\\aa" . "a")                      ; \aa           -> a
!     ("\\\\AA" . "A")                      ; \AA           -> A
!     ("\\\"a\\|\\\\\\\"a\\|\\\\ae" . "ae") ; "a,\"a,\ae    -> ae
!     ("\\\"A\\|\\\\\\\"A\\|\\\\AE" . "Ae") ; "A,\"A,\AE    -> Ae
!     ("\\\\i" . "i")                       ; \i            -> i
!     ("\\\\j" . "j")                       ; \j            -> j
!     ("\\\\l" . "l")                       ; \l            -> l
!     ("\\\\L" . "L")                       ; \L            -> L
!     ("\\\"o\\|\\\\\\\"o\\|\\\\o\\|\\\\oe" . "oe") ; "o,\"o,\o,\oe -> oe
!     ("\\\"O\\|\\\\\\\"O\\|\\\\O\\|\\\\OE" . "Oe") ; "O,\"O,\O,\OE -> Oe
!     ("\\\"s\\|\\\\\\\"s\\|\\\\3" . "ss")  ; "s,\"s,\3     -> ss
!     ("\\\"u\\|\\\\\\\"u" . "ue")          ; "u,\"u        -> ue
!     ("\\\"U\\|\\\\\\\"U" . "Ue")          ; "U,\"U        -> Ue
      ;; accents
!     
("\\\\`\\|\\\\'\\|\\\\\\^\\|\\\\~\\|\\\\=\\|\\\\\\.\\|\\\\u\\|\\\\v\\|\\\\H\\|\\\\t\\|\\\\c\\|\\\\d\\|\\\\b"
 . "")
!     ;; braces, quotes, concatenation.
!     ("[`'\"{}#]" . "")
!     ;; spaces
!     ("[ \t\n]+" . " "))
!   "Alist of (OLD-REGEXP . NEW-STRING) pairs.
  Used by the default values of `bibtex-autokey-name-change-strings' and
  `bibtex-autokey-titleword-change-strings'.  Defaults to translating some
  language specific characters to their ASCII transcriptions, and
***************
*** 532,584 ****
  
  (defcustom bibtex-autokey-name-change-strings
    bibtex-autokey-transcriptions
!   "Alist of (OLD-REGEXP NEW-STRING) pairs.
  Any part of name matching a OLD-REGEXP is replaced by NEW-STRING.
  Case is significant in OLD-REGEXP.  All regexps are tried in the
! order in which they appear in the list, so be sure to avoid inifinite
! loops here.
! See the documentation of function `bibtex-generate-autokey' for details."
!   :group 'bibtex-autokey
!   :type '(repeat
!         (list (regexp :tag "Old")
!               (string :tag "New"))))
  
  (defcustom bibtex-autokey-name-case-convert 'downcase
    "*Function called for each name to perform case conversion.
! See the documentation of function `bibtex-generate-autokey' for more detail."
    :group 'bibtex-autokey
    :type '(choice (const :tag "Preserve case" identity)
!                (const :tag "Downcase" downcase)
!                (const :tag "Capitalize" capitalize)
!                (const :tag "Upcase" upcase)
!                (function :tag "Conversion function")))
  
  (defcustom bibtex-autokey-name-length 'infty
    "*Number of characters from name to incorporate into key.
  If this is set to anything but a number, all characters are used.
! See the documentation of function `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type '(choice (const :tag "All" infty)
!                integer))
  
  (defcustom bibtex-autokey-name-separator ""
    "*String that comes between any two names in the key.
! See the documentation of function `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type 'string)
  
  (defcustom bibtex-autokey-year-length 2
    "*Number of rightmost digits from the year field to incorporate into key.
! See the documentation of function `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type 'integer)
  
! (defcustom bibtex-autokey-year-use-crossref-entry t
!   "*If non-nil use year field from crossreferenced entry if necessary.
! If this variable is non-nil and the current entry has no year, but a
! valid crossref entry, the year field from the crossreferenced entry is
! used.
! See the documentation of function `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type 'boolean)
  
--- 565,614 ----
  
  (defcustom bibtex-autokey-name-change-strings
    bibtex-autokey-transcriptions
!   "Alist of (OLD-REGEXP . NEW-STRING) pairs.
  Any part of name matching a OLD-REGEXP is replaced by NEW-STRING.
  Case is significant in OLD-REGEXP.  All regexps are tried in the
! order in which they appear in the list.
! See `bibtex-generate-autokey' for details."
!   :group 'bibtex-autokey
!   :type '(repeat (cons (regexp :tag "Old")
!                        (string :tag "New"))))
  
  (defcustom bibtex-autokey-name-case-convert 'downcase
    "*Function called for each name to perform case conversion.
! See `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type '(choice (const :tag "Preserve case" identity)
!                  (const :tag "Downcase" downcase)
!                  (const :tag "Capitalize" capitalize)
!                  (const :tag "Upcase" upcase)
!                  (function :tag "Conversion function")))
  
  (defcustom bibtex-autokey-name-length 'infty
    "*Number of characters from name to incorporate into key.
  If this is set to anything but a number, all characters are used.
! See `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type '(choice (const :tag "All" infty)
!                  integer))
  
  (defcustom bibtex-autokey-name-separator ""
    "*String that comes between any two names in the key.
! See `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type 'string)
  
  (defcustom bibtex-autokey-year-length 2
    "*Number of rightmost digits from the year field to incorporate into key.
! See `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type 'integer)
  
! (defcustom bibtex-autokey-use-crossref t
!   "*If non-nil use fields from crossreferenced entry if necessary.
! If this variable is non-nil and some field has no entry, but a
! valid crossref entry, the field from the crossreferenced entry is used.
! See `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type 'boolean)
  
***************
*** 587,609 ****
  If this is set to anything but a number, all title words are used.
  Possibly more words from the title are used according to
  `bibtex-autokey-titlewords-stretch'.
! See the documentation of function `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type '(choice (const :tag "All" infty)
!                integer))
  
  (defcustom bibtex-autokey-title-terminators
    '("\\." "!"  "\\?" ":" ";" "--")
    "*Regexp list defining the termination of the main part of the title.
  Case of the regexps is ignored.
! See the documentation of function `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type '(repeat regexp))
  
  (defcustom bibtex-autokey-titlewords-stretch 2
    "*Number of words that can additionally be used from the title.
  These words are used only, if a sentence from the title can be ended then.
! See the documentation of function `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type 'integer)
  
--- 617,639 ----
  If this is set to anything but a number, all title words are used.
  Possibly more words from the title are used according to
  `bibtex-autokey-titlewords-stretch'.
! See `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type '(choice (const :tag "All" infty)
!                  integer))
  
  (defcustom bibtex-autokey-title-terminators
    '("\\." "!"  "\\?" ":" ";" "--")
    "*Regexp list defining the termination of the main part of the title.
  Case of the regexps is ignored.
! See `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type '(repeat regexp))
  
  (defcustom bibtex-autokey-titlewords-stretch 2
    "*Number of words that can additionally be used from the title.
  These words are used only, if a sentence from the title can be ended then.
! See `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type 'integer)
  
***************
*** 613,674 ****
    "*Determines words from the title that are not to be used in the key.
  Each item of the list is a regexp.  If a word of the title matchs a
  regexp from that list, it is not included in the title part of the key.
! See the documentation of function `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type '(repeat regexp))
  
  (defcustom bibtex-autokey-titleword-case-convert 'downcase
    "*Function called for each titleword to perform case conversion.
! See the documentation of function `bibtex-generate-autokey' for more detail."
    :group 'bibtex-autokey
    :type '(choice (const :tag "Preserve case" identity)
!                (const :tag "Downcase" downcase)
!                (const :tag "Capitalize" capitalize)
!                (const :tag "Upcase" upcase)
!                (function :tag "Conversion function")))
  
  (defcustom bibtex-autokey-titleword-abbrevs nil
    "*Determines exceptions to the usual abbreviation mechanism.
! An alist of (OLD-REGEXP NEW-STRING) pairs.  Case is ignored
  in matching against OLD-REGEXP, and the first matching pair is used.
! See the documentation of function `bibtex-generate-autokey' for details.")
  
  (defcustom bibtex-autokey-titleword-change-strings
    bibtex-autokey-transcriptions
!   "Alist of (OLD-REGEXP NEW-STRING) pairs.
  Any part of title word matching a OLD-REGEXP is replaced by NEW-STRING.
  Case is significant in OLD-REGEXP.  All regexps are tried in the
! order in which they appear in the list, so be sure to avoid inifinite
! loops here.
! See the documentation of function `bibtex-generate-autokey' for details."
!   :group 'bibtex-autokey
!   :type '(repeat
!         (list (regexp :tag "Old")
!               (string :tag "New"))))
  
  (defcustom bibtex-autokey-titleword-length 5
    "*Number of characters from title words to incorporate into key.
  If this is set to anything but a number, all characters are used.
! See the documentation of function `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type '(choice (const :tag "All" infty)
!                integer))
  
  (defcustom bibtex-autokey-titleword-separator "_"
    "*String to be put between the title words.
! See the documentation of function `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type 'string)
  
  (defcustom bibtex-autokey-name-year-separator ""
    "*String to be put between name part and year part of key.
! See the documentation of function `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type 'string)
  
  (defcustom bibtex-autokey-year-title-separator ":_"
    "*String to be put between name part and year part of key.
! See the documentation of function `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type 'string)
  
--- 643,705 ----
    "*Determines words from the title that are not to be used in the key.
  Each item of the list is a regexp.  If a word of the title matchs a
  regexp from that list, it is not included in the title part of the key.
! See `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type '(repeat regexp))
  
  (defcustom bibtex-autokey-titleword-case-convert 'downcase
    "*Function called for each titleword to perform case conversion.
! See `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type '(choice (const :tag "Preserve case" identity)
!                  (const :tag "Downcase" downcase)
!                  (const :tag "Capitalize" capitalize)
!                  (const :tag "Upcase" upcase)
!                  (function :tag "Conversion function")))
  
  (defcustom bibtex-autokey-titleword-abbrevs nil
    "*Determines exceptions to the usual abbreviation mechanism.
! An alist of (OLD-REGEXP . NEW-STRING) pairs.  Case is ignored
  in matching against OLD-REGEXP, and the first matching pair is used.
! See `bibtex-generate-autokey' for details."
!   :group 'bibtex-autokey
!   :type '(repeat (cons (regexp :tag "Old")
!                        (string :tag "New"))))
  
  (defcustom bibtex-autokey-titleword-change-strings
    bibtex-autokey-transcriptions
!   "Alist of (OLD-REGEXP . NEW-STRING) pairs.
  Any part of title word matching a OLD-REGEXP is replaced by NEW-STRING.
  Case is significant in OLD-REGEXP.  All regexps are tried in the
! order in which they appear in the list.
! See `bibtex-generate-autokey' for details."
!   :group 'bibtex-autokey
!   :type '(repeat (cons (regexp :tag "Old")
!                        (string :tag "New"))))
  
  (defcustom bibtex-autokey-titleword-length 5
    "*Number of characters from title words to incorporate into key.
  If this is set to anything but a number, all characters are used.
! See `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type '(choice (const :tag "All" infty)
!                  integer))
  
  (defcustom bibtex-autokey-titleword-separator "_"
    "*String to be put between the title words.
! See `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type 'string)
  
  (defcustom bibtex-autokey-name-year-separator ""
    "*String to be put between name part and year part of key.
! See `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type 'string)
  
  (defcustom bibtex-autokey-year-title-separator ":_"
    "*String to be put between name part and year part of key.
! See `bibtex-generate-autokey' for details."
    :group 'bibtex-autokey
    :type 'string)
  
***************
*** 678,689 ****
    :type 'boolean)
  
  (defcustom bibtex-autokey-before-presentation-function nil
!   "Function to call before the generated key is presented.
! If non-nil this should be a single function, which is called before
! the generated key is presented (in entry or, if
! `bibtex-autokey-edit-before-use' is t, in minibuffer).  This function
! must take one argument (the automatically generated key), and must
! return with a string (the key to use)."
    :group 'bibtex-autokey
    :type '(choice (const nil) function))
  
--- 709,718 ----
    :type 'boolean)
  
  (defcustom bibtex-autokey-before-presentation-function nil
!   "*Function to call before the generated key is presented.
! If non-nil this should be a function which is called before the generated key
! is presented.  The function must take one argument (the automatically
! generated key), and must return a string (the key to use)."
    :group 'bibtex-autokey
    :type '(choice (const nil) function))
  
***************
*** 699,707 ****
    :type 'integer)
  
  (defcustom bibtex-text-indentation
!   (+
!    bibtex-field-indentation
!    (length "organization = "))
    "*Starting column for the text part in BibTeX fields.
  Should be equal to the space needed for the longest name part."
    :group 'bibtex
--- 728,735 ----
    :type 'integer)
  
  (defcustom bibtex-text-indentation
!   (+ bibtex-field-indentation
!      (length "organization = "))
    "*Starting column for the text part in BibTeX fields.
  Should be equal to the space needed for the longest name part."
    :group 'bibtex
***************
*** 715,722 ****
  
  (defcustom bibtex-align-at-equal-sign nil
    "*If non-nil, align fields at equal sign instead of field text.
! If non-nil, the column for the equal sign is
! the value of `bibtex-text-indentation', minus 2."
    :group 'bibtex
    :type 'boolean)
  
--- 743,750 ----
  
  (defcustom bibtex-align-at-equal-sign nil
    "*If non-nil, align fields at equal sign instead of field text.
! If non-nil, the column for the equal sign is the value of
! `bibtex-text-indentation', minus 2."
    :group 'bibtex
    :type 'boolean)
  
***************
*** 725,768 ****
    :group 'bibtex
    :type 'boolean)
  
! ;; bibtex-font-lock-keywords is a user option as well, but since the
! ;; patterns used to define this variable are defined in a later
! ;; section of this file, it is defined later.
! 
! ;; Special support taking care of variants
! (if (boundp 'mark-active)
!     (defun bibtex-mark-active ()
!       ;; In Emacs mark-active indicates if mark is active.
!       mark-active)
!   (defun bibtex-mark-active ()
!     ;; In XEmacs (mark) returns nil when not active.
!     (if zmacs-regions (mark) (mark t))))
  
! (if (fboundp 'run-with-idle-timer)
!     ;; timer.el is distributed with Emacs
!     (fset 'bibtex-run-with-idle-timer 'run-with-idle-timer)
!   ;; timer.el is not distributed with XEmacs
!   ;; Notice that this does not (yet) pass the arguments, but they
!   ;; are not used (yet) in bibtex.el. Fix if needed.
!   (defun bibtex-run-with-idle-timer (secs repeat function &rest args)
!     (start-itimer "bibtex" function secs (if repeat secs nil) t)))
  
! 
! ;; Support for hideshow minor mode
! (defun bibtex-hs-forward-sexp (arg)
!   "Replacement for `forward-sexp' to be used by `hs-minor-mode'."
!   (if (< arg 0)
!       (backward-sexp 1)
!     (if (looking-at "@\\S(*\\s(")
!       (progn
!         (goto-char (match-end 0))
!         (forward-char -1)
!         (forward-sexp 1))
!       (forward-sexp 1))))
  
! (add-to-list
!  'hs-special-modes-alist
!  '(bibtex-mode "@\\S(*\\s(" "\\s)" nil bibtex-hs-forward-sexp nil))
  
  
  ;; Syntax Table, Keybindings and BibTeX Entry List
--- 753,775 ----
    :group 'bibtex
    :type 'boolean)
  
! (defcustom bibtex-autoadd-commas t
!   "If non-nil automatically add missing commas at end of BibTeX fields."
!   :type 'boolean)
  
! (defcustom bibtex-autofill-types '("Proceedings")
!   "Automatically fill fields if possible for those BibTeX entry types."
!   :type '(repeat string))
  
! (defcustom bibtex-complete-key-cleanup nil
!   "*Function called by `bibtex-complete' after insertion of a key fragment."
!   :group 'bibtex-autokey
!   :type '(choice (const :tag "None" nil)
!                  (function :tag "Cleanup function")))
  
! ;; bibtex-font-lock-keywords is a user option as well, but since the
! ;; patterns used to define this variable are defined in a later
! ;; section of this file, it is defined later.
  
  
  ;; Syntax Table, Keybindings and BibTeX Entry List
***************
*** 776,791 ****
      (modify-syntax-entry ?\\ "\\" st)
      (modify-syntax-entry ?\f ">   " st)
      (modify-syntax-entry ?\n ">   " st)
      (modify-syntax-entry ?~ " " st)
!     st))
  
  (defvar bibtex-mode-map
    (let ((km (make-sparse-keymap)))
      ;; The Key `C-c&' is reserved for reftex.el
      (define-key km "\t" 'bibtex-find-text)
      (define-key km "\n" 'bibtex-next-field)
!     (define-key km "\M-\t" 'bibtex-complete-string)
!     (define-key km [(meta tab)] 'bibtex-complete-key)
      (define-key km "\C-c\"" 'bibtex-remove-delimiters)
      (define-key km "\C-c{" 'bibtex-remove-delimiters)
      (define-key km "\C-c}" 'bibtex-remove-delimiters)
--- 783,800 ----
      (modify-syntax-entry ?\\ "\\" st)
      (modify-syntax-entry ?\f ">   " st)
      (modify-syntax-entry ?\n ">   " st)
+     ;; Keys cannot have = in them (wrong font-lock of @string{foo=bar}).
+     (modify-syntax-entry ?= "." st)
      (modify-syntax-entry ?~ " " st)
!     st)
!   "Syntax table used in BibTeX mode buffers.")
  
  (defvar bibtex-mode-map
    (let ((km (make-sparse-keymap)))
      ;; The Key `C-c&' is reserved for reftex.el
      (define-key km "\t" 'bibtex-find-text)
      (define-key km "\n" 'bibtex-next-field)
!     (define-key km "\M-\t" 'bibtex-complete)
      (define-key km "\C-c\"" 'bibtex-remove-delimiters)
      (define-key km "\C-c{" 'bibtex-remove-delimiters)
      (define-key km "\C-c}" 'bibtex-remove-delimiters)
***************
*** 829,1682 ****
      (define-key km "\C-c\C-e\C-s" 'bibtex-String)
      (define-key km "\C-c\C-e\C-t" 'bibtex-TechReport)
      (define-key km "\C-c\C-e\C-u" 'bibtex-Unpublished)
!     km))
  
  (easy-menu-define
!  bibtex-edit-menu bibtex-mode-map "BibTeX-Edit Menu in BibTeX mode"
!  '("BibTeX-Edit"
!    ("Moving inside an Entry"
!     ["End of Field" bibtex-find-text t]
!     ["Next Field" bibtex-next-field t]
!     ["Beginning of Entry" bibtex-beginning-of-entry t]
!     ["End of Entry" bibtex-end-of-entry t])
!    ("Operating on Current Entry"
!     ["Fill Entry" bibtex-fill-entry t]
!     ["Clean Entry" bibtex-clean-entry t]
!     "--"
!     ["Kill Entry" bibtex-kill-entry t]
!     ["Copy Entry to Kill Ring" bibtex-copy-entry-as-kill t]
!     ["Paste Most Recently Killed Entry" bibtex-yank t]
!     ["Paste Previously Killed Entry" bibtex-yank-pop t]
!     "--"
!     ["Ispell Entry" bibtex-ispell-entry t]
!     ["Ispell Entry Abstract" bibtex-ispell-abstract t]
!     ["Narrow to Entry" bibtex-narrow-to-entry t]
!     "--"
!     ["View Cite Locations (RefTeX)" reftex-view-crossref-from-bibtex
!      (fboundp 'reftex-view-crossref-from-bibtex)])
!    ("Operating on Current Field"
!     ["Remove Delimiters" bibtex-remove-delimiters t]
!     ["Remove OPT or ALT Prefix" bibtex-remove-OPT-or-ALT t]
!     ["Clear Field" bibtex-empty-field t]
!     "--"
!     ["Kill Field" bibtex-kill-field t]
!     ["Copy Field to Kill Ring" bibtex-copy-field-as-kill t]
!     ["Paste Most Recently Killed Field" bibtex-yank t]
!     ["Paste Previously Killed Field" bibtex-yank-pop t]
!     "--"
!     ["Make New Field" bibtex-make-field t]
!     "--"
!     ["Snatch from Similar Following Field" bibtex-pop-next t]
!     ["Snatch from Similar Preceding Field" bibtex-pop-previous t]
!     "--"
!     ["String Complete" bibtex-complete-string t]
!     ["Key Complete" bibtex-complete-key t]
!     "--"
!     ["Help about Current Field" bibtex-print-help-message t])
!    ("Operating on Buffer or Region"
!     ["Validate Entries" bibtex-validate t]
!     ["Sort Entries" bibtex-sort-buffer t]
!     ["Reformat Entries" bibtex-reformat t]
!     ["Count Entries" bibtex-count-entries t])
!    ("Miscellaneous"
!     ["Convert Alien Buffer" bibtex-convert-alien t]
!     ["Submit Bug Report" bibtex-submit-bug-report t])))
  
  (easy-menu-define
!  bibtex-entry-menu bibtex-mode-map "Entry-Types Menu in BibTeX mode"
!  (list "Entry-Types"
!        ["Article in Journal" bibtex-Article t]
!        ["Article in Conference Proceedings" bibtex-InProceedings t]
!        ["Article in a Collection" bibtex-InCollection t]
!        ["Chapter or Pages in a Book" bibtex-InBook t]
!        ["Conference Proceedings" bibtex-Proceedings t]
!        ["Book" bibtex-Book t]
!        ["Booklet (Bound, but no Publisher/Institution)" bibtex-Booklet t]
!        ["PhD. Thesis" bibtex-PhdThesis t]
!        ["Master's Thesis" bibtex-MastersThesis t]
!        ["Technical Report" bibtex-TechReport t]
!        ["Technical Manual" bibtex-Manual t]
!        ["Unpublished" bibtex-Unpublished t]
!        ["Miscellaneous" bibtex-Misc t]
!        ["String" bibtex-String t]
!        ["Preamble" bibtex-Preamble t]))
  
  
  ;; Internal Variables
  
! (defvar bibtex-pop-previous-search-point nil)
! ;; Next point where bibtex-pop-previous starts looking for a similar
! ;; entry.
  
! (defvar bibtex-pop-next-search-point nil)
! ;; Next point where bibtex-pop-next starts looking for a similar entry.
  
! (defvar bibtex-field-kill-ring nil)
! ;; Ring of least recently killed fields. At most
! ;; bibtex-field-kill-ring-max items are kept here.
  
! (defvar bibtex-field-kill-ring-yank-pointer nil)
! ;; The tail of bibtex-field-kill-ring whose car is the last item yanked.
  
! (defvar bibtex-entry-kill-ring nil)
! ;; Ring of least recently killed entries. At most
! ;; bibtex-entry-kill-ring-max items are kept here.
  
! (defvar bibtex-entry-kill-ring-yank-pointer nil)
! ;; The tail of bibtex-entry-kill-ring whose car is the last item yanked.
  
! (defvar bibtex-last-kill-command nil)
! ;; Holds the type of the last kill command (either 'field or 'entry)
  
! (defvar bibtex-strings nil)
! ;; Candidates for bibtex-complete-string. Initialized from
! ;; bibtex-predefined-strings and bibtex-string-files.
! (make-variable-buffer-local 'bibtex-strings)
  
! (defvar bibtex-reference-keys nil)
! ;; Candidates for TAB completion when entering a reference key using
! ;; the minibuffer. Also used for bibtex-complete-key. Initialized in
! ;; bibtex-mode and updated for each new entry.
! (make-variable-buffer-local 'bibtex-reference-keys)
  
! (defvar bibtex-buffer-last-parsed-tick nil)
! ;; Remembers the value returned by buffer-modified-tick when buffer
! ;; was parsed for keys the last time.
! (make-variable-buffer-local 'bibtex-buffer-last-parsed-tick)
  
! (defvar bibtex-parse-idle-timer nil)
! ;; Stores if timer is already installed
  
! (defvar bibtex-progress-lastperc nil)
! ;; Holds the last reported percentage for the progress message
  
! (defvar bibtex-progress-lastmes nil)
! ;; Holds the last reported progress message
  
! (defvar bibtex-progress-interval nil)
! ;; Holds the chosen interval
  
! (defvar bibtex-key-history nil)
! ;; Used to store the history list for reading keys
  
! (defvar bibtex-entry-type-history nil)
! ;; Used to store the history list for reading entry types
  
! (defvar bibtex-field-history nil)
! ;; Used to store the history list for reading field names
  
! (defvar bibtex-reformat-previous-options nil)
! ;; Used to store the last reformat options given
  
! (defvar bibtex-reformat-previous-reference-keys nil)
! ;; Used to store the last reformat reference keys option given
  
  
! ;; Functions to Parse the BibTeX Entries
  
! (defconst bibtex-field-name "[^\"#%'(),={} \t\n0-9][^\"#%'(),={} \t\n]*")
! ;; Regexp defining the name part of a BibTeX field.
  
! (defconst bibtex-entry-type (concat "@" bibtex-field-name))
! ;; Regexp defining the type part of a BibTeX entry.
  
! (defconst bibtex-reference-key 
"[][a-zA-Z0-9.:;?!`'/address@hidden|()<>&_^$-]+")
! ;; Regexp defining the reference key part of a BibTeX entry
! 
! (defun bibtex-parse-nested-braces (nesting-level)
!   "*Starting on an opening brace, find the corresponding closing brace.
! When the function is called, NESTING-LEVEL has to be set to `0'."
!   (cond ((looking-at "{")
!        (search-forward-regexp "{[^{}]*")
!        (bibtex-parse-nested-braces (+ nesting-level 1)))
!       ((looking-at "}")
!        (forward-char 1)
!        (if (= nesting-level 1)
!            (point)
!          (search-forward-regexp "[^{}]*")
!          (bibtex-parse-nested-braces (- nesting-level 1))))
!       (t nil)))
! 
! (defun bibtex-parse-field-string-braced ()
!   "*Parse a field string enclosed by braces.
! The field string has to be syntactically correct, which means that the number
! of opening and closing braces has to match.  If this is the case, a pair
! containing the start and end position of the field string is returned, nil
! otherwise."
!   (save-match-data
!     (let ((starting-point (point))
!         (end-point nil))
!       (if (looking-at "{")
!         (setq end-point (bibtex-parse-nested-braces 0)))
!       (goto-char starting-point)
!       (if end-point
!         (cons starting-point end-point)
!       nil))))
! 
! (defun bibtex-parse-quoted-string ()
!   "*Starting on an opening quote, find the corresponding closing quote."
!   (let ((rx (concat "\""
!                       "\\("
!                           "[^\"\\]"               ;; anything but quote or 
backslash
!                           "\\|"
!                           "\\("
!                               "\\\\\\(.\\|\n\\)"  ;; any backslash quoted 
character
!                           "\\)"
!                       "\\)*"
!                   "\"")))
!     (if (looking-at rx)
!       (search-forward-regexp rx nil t)
!       nil)))
  
! (defun bibtex-parse-field-string-quoted ()
!   "*Parse a field string enclosed by quotes.
! If a syntactically correct string is found, a pair containing the start and
! end position of the field string is returned, nil otherwise."
!   (save-match-data
!     (let ((starting-point (point))
!         (end-point nil))
!       (if (looking-at "\"")
!         (setq end-point (bibtex-parse-quoted-string)))
!       (goto-char starting-point)
!       (if end-point
!         (cons starting-point end-point)
!       nil))))
  
  (defun bibtex-parse-field-string ()
!   "*Parse a field string enclosed by braces or quotes.
  If a syntactically correct string is found, a pair containing the start and
  end position of the field string is returned, nil otherwise."
!   (save-match-data
!     (let ((starting-point (point))
!         (boundaries (or (bibtex-parse-field-string-braced)
!                         (bibtex-parse-field-string-quoted))))
!       (goto-char starting-point)
!       boundaries)))
! 
! (defun bibtex-search-forward-field-string (bound)
!   "*Search forward to find a field string enclosed by braces or quotes.
! If a syntactically correct string is found, a pair containing the start and
! end position of the field string is returned, nil otherwise.  The search is
! delimited by BOUND."
!   (save-match-data
!     (let ((starting-point (point))
!         (boundaries nil))
!       (while (and (not boundaries) (< (point) bound))
!       (if (search-forward-regexp "[{\"]" bound 'move)
!           (progn
!             (goto-char (match-beginning 0))
!             (let ((temp-boundaries (or (bibtex-parse-field-string-braced)
!                                        (bibtex-parse-field-string-quoted))))
!               (if (and temp-boundaries (<= (cdr temp-boundaries) bound))
!                   (setq boundaries temp-boundaries)
!                 (forward-char 1))))))
!       (goto-char starting-point)
!       boundaries)))
  
  (defun bibtex-parse-association (parse-lhs parse-rhs)
!   "*Parse a string of the format <left hand side = right-hand-side>.
  The functions PARSE-LHS and PARSE-RHS are used to parse the corresponding
  substrings.  These functions are expected to return nil if parsing is not
  successfull.  If both functions return non-nil, a pair containing the returned
! values of the functions PARSE-LHS and PARSE-RHSis returned."
    (save-match-data
!     (let ((starting-point (point))
!         (left (funcall parse-lhs))
!         (right nil))
!       (if (and left (looking-at "[ \t\n]*=[ \t\n]*"))
!         (progn
!           (goto-char (match-end 0))
!           (setq right (funcall parse-rhs))))
!       (goto-char starting-point)
!       (if (and left right)
!         (cons left right)
!       nil))))
! 
! (defvar bibtex-field-name-for-parsing nil)
! ;; Temporary variable storing the name string to be parsed by the callback
! ;; function bibtex-parse-field-name.
! (make-variable-buffer-local 'bibtex-field-name-for-parsing)
  
  (defun bibtex-parse-field-name ()
!   "*Parse the field name stored in bibtex-field-name-for-parsing.
  If the field name is found, return a triple consisting of the position of the
  very first character of the match, the actual starting position of the name
! part and end position of the match."
!   (if (looking-at ",[ \t\n]*")
!       (let ((start (point)))
!       (goto-char (match-end 0))
!       (if (looking-at bibtex-field-name-for-parsing)
!           (let ((boundaries (list start (match-beginning 0) (match-end 0))))
!             (goto-char (match-end 0))
!             boundaries)))))
! 
! (defconst bibtex-field-const "[][a-zA-Z0-9.:;?!`'/address@hidden|<>&_^$-]+")
! ;; Regexp defining a bibtex field constant
  
  (defun bibtex-parse-field-text ()
!   "*Parse the text part of a BibTeX field.
  The text part is either a string, or an empty string, or a constant followed
  by one or more <# (string|constant)> pairs.  If a syntactically correct text
  is found, a pair containing the start and end position of the text is
! returned, nil otherwise."
    (let ((starting-point (point))
!       (end-point nil)
!       (failure nil))
!     (while (and (not end-point) (not failure))
!       (if (looking-at bibtex-field-const)
!         (goto-char (match-end 0))
!       (let ((boundaries (bibtex-parse-field-string)))
!         (if boundaries
!             (goto-char (cdr boundaries))
!           (setq failure t))))
        (if (not (looking-at "[ \t\n]*#[ \t\n]*"))
!         (setq end-point (point))
!       (goto-char (match-end 0))))
!     (if (and (not failure) end-point)
!       (cons starting-point end-point)
!       nil)))
  
  (defun bibtex-parse-field (name)
!   "*Parse a BibTeX field of regexp NAME.
  If a syntactically correct field is found, a pair containing the boundaries of
  the name and text parts of the field is returned."
!   (setq bibtex-field-name-for-parsing name)
!   (bibtex-parse-association 'bibtex-parse-field-name
!                           'bibtex-parse-field-text))
  
! (defun bibtex-search-forward-field (name bound)
!   "*Search forward to find a field of name NAME.
  If a syntactically correct field is found, a pair containing the boundaries of
  the name and text parts of the field is returned.  The search is limited by
! BOUND."
    (save-match-data
!     (setq bibtex-field-name-for-parsing name)
!     (let ((starting-point (point))
!         (boundaries nil))
!       (while (and (not boundaries)
!                 (< (point) bound)
!                 (search-forward "," bound t))
!       (goto-char (match-beginning 0))
!       (let ((temp-boundaries
!              (bibtex-parse-association 'bibtex-parse-field-name
!                                        'bibtex-parse-field-text)))
!         (if (and temp-boundaries (<= (cdr (cdr temp-boundaries)) bound))
!             (setq boundaries temp-boundaries)
!           (forward-char 1))))
!       (goto-char starting-point)
!       boundaries)))
  
! (defun bibtex-search-backward-field (name bound)
!   "*Search backward to find a field of name NAME.
  If a syntactically correct field is found, a pair containing the boundaries of
  the name and text parts of the field is returned.  The search is limited by
! BOUND."
    (save-match-data
!     (setq bibtex-field-name-for-parsing name)
!     (let ((starting-point (point))
!         (boundaries nil))
!       (while (and (not boundaries)
!                 (>= (point) bound)
!                 (search-backward "," bound t))
!       (let ((temp-boundaries
!              (bibtex-parse-association 'bibtex-parse-field-name
!                                        'bibtex-parse-field-text)))
!         (if temp-boundaries
!             (setq boundaries temp-boundaries))))
!       (goto-char starting-point)
!       boundaries)))
! 
! (defun bibtex-start-of-field (bounds)
!   (car (car bounds)))
! (defun bibtex-end-of-field (bounds)
!   (cdr (cdr bounds)))
! (defun bibtex-start-of-name-in-field (bounds)
!   (car (cdr (car bounds))))
! (defun bibtex-end-of-name-in-field (bounds)
!   (car (cdr (cdr (car bounds)))))
! (defun bibtex-start-of-text-in-field (bounds)
!   (car (cdr bounds)))
! (defun bibtex-end-of-text-in-field (bounds)
!   (cdr (cdr bounds)))
  
  (defun bibtex-parse-string-prefix ()
!   "*Parse the prefix part of a bibtex string, including the reference key.
  If the string prefix is found, return a triple consisting of the position of
  the very first character of the match, the actual starting position of the
  reference key and the end position of the match."
!   (let* ((case-fold-search t))
      (if (looking-at "^[ address@hidden \t\n]*[({][ \t\n]*")
!       (let ((start (point)))
!         (goto-char (match-end 0))
!         (if (looking-at bibtex-reference-key)
!             (let ((boundaries (list start (match-beginning 0) (match-end 0))))
!               (goto-char (match-end 0))
!               boundaries))))))
  
  (defun bibtex-parse-string-postfix ()
!   "*Parse the postfix part of a bibtex string, including the text.
  If the string postfix is found, return a triple consisting of the position of
  the actual starting and ending position of the text and the very last
! character of the string entry."
    (let* ((case-fold-search t)
!        (text-boundaries (bibtex-parse-field-text)))
!     (if text-boundaries
!       (progn
!         (goto-char (cdr text-boundaries))
!         (if (looking-at "[ \t\n]*[})]")
!             (let ((boundaries (list (car text-boundaries)
!                                     (cdr text-boundaries)
!                                     (match-end 0))))
!               (goto-char (match-end 0))
!               boundaries))))))
  
  (defun bibtex-parse-string ()
!   "*Parse a BibTeX string entry.
  If a syntactically correct entry is found, a pair containing the boundaries of
! the reference key and text parts of the entry is returned."
    (bibtex-parse-association 'bibtex-parse-string-prefix
!                           'bibtex-parse-string-postfix))
  
  (defun bibtex-search-forward-string ()
!   "*Search forward to find a bibtex string entry.
  If a syntactically correct entry is found, a pair containing the boundaries of
! the reference key and text parts of the string is returned."
!   (save-match-data
!     (let* ((case-fold-search t)
!          (starting-point (point))
!          (boundaries nil))
!       (while (and (not boundaries)
!                 (search-forward-regexp
!                  "^[ address@hidden \t\n]*[({][ \t\n]*" nil t))
!       (goto-char (match-beginning 0))
!       (let ((temp-boundaries (bibtex-parse-string)))
!         (if temp-boundaries
!             (setq boundaries temp-boundaries)
!           (forward-char 1))))
!       (goto-char starting-point)
!       boundaries)))
  
  (defun bibtex-search-backward-string ()
!   "*Search backward to find a bibtex string entry.
  If a syntactically correct entry is found, a pair containing the boundaries of
! the reference key and text parts of the field is returned."
!   (save-match-data
!     (let* ((case-fold-search t)
!          (starting-point (point))
!          (boundaries nil))
!       (while (and (not boundaries)
!                 (search-backward-regexp
!                  "^[ address@hidden \t\n]*[({][ \t\n]*" nil t))
!       (goto-char (match-beginning 0))
!       (let ((temp-boundaries (bibtex-parse-string)))
!         (if temp-boundaries
!             (setq boundaries temp-boundaries))))
!       (goto-char starting-point)
!       boundaries)))
! 
! (defun bibtex-end-of-string (bounds)
!   (car (cdr (cdr (cdr bounds)))))
! (defun bibtex-start-of-reference-key-in-string (bounds)
!   (car (cdr (car bounds))))
! (defun bibtex-end-of-reference-key-in-string (bounds)
!   (car (cdr (cdr (car bounds)))))
! (defun bibtex-start-of-text-in-string (bounds)
!   (car (cdr bounds)))
! (defun bibtex-end-of-text-in-string (bounds)
!   (car (cdr (cdr bounds))))
! 
! (defconst bibtex-entry-head
!   (concat "^[ \t]*\\("
!         bibtex-entry-type
!         "\\)[ \t]*[({][ \t\n]*\\("
!         bibtex-reference-key
!         "\\)"))
! ;; Regexp defining format of the header line of a BibTeX entry.
! 
! (defconst bibtex-entry-maybe-empty-head
!   (concat bibtex-entry-head "?"))
! ;; Regexp defining format of the header line of a maybe empty
! ;; BibTeX entry (possibly without reference key).
! 
! (defconst bibtex-type-in-head 1)
! ;; The regexp subexpression number of the type part in
! ;; bibtex-entry-head.
! 
! (defconst bibtex-key-in-head 2)
! ;; The regexp subexpression number of the key part in
! ;; bibtex-entry-head.
! 
! (defconst bibtex-entry-postfix "[ \t\n]*,?[ \t\n]*[})]")
! ;; Regexp defining the postfix of a bibtex entry
! 
! (defconst bibtex-key-in-entry bibtex-key-in-head)
! ;; The regexp subexpression number of the key part in a bibtex entry.
! 
! (defvar bibtex-font-lock-keywords
!   (list
!    ;; entry type and reference key
!    (list bibtex-entry-maybe-empty-head
!          (list bibtex-type-in-head 'font-lock-function-name-face)
!          (list bibtex-key-in-head 'font-lock-constant-face nil t))
!    ;; comments
!    (list
!     (concat "^\\([ \t]*" bibtex-comment-start ".*\\)$")
!     1 'font-lock-comment-face)
!    ;; optional field names (treated as comments)
!    (list
!     (concat "^[ \t]*\\(OPT" bibtex-field-name "\\)[ \t]*=")
!     1 'font-lock-comment-face)
!    ;; field names
!    (list (concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=")
!          1 'font-lock-variable-name-face)
!    "*Default expressions to highlight in BibTeX mode."))
! ;; now all needed patterns are defined
! 
  
- 
  ;; Helper Functions
  
  (defun bibtex-delete-whitespace ()
!   ;; Delete all whitespace starting at point
    (if (looking-at "[ \t\n]+")
        (delete-region (point) (match-end 0))))
  
  (defun bibtex-current-line ()
!   ;; this computes line number of point regardless whether the buffer
!   ;; is narrowed
    (+ (count-lines 1 (point))
       (if (equal (current-column) 0) 1 0)))
  
  (defun bibtex-member-of-regexp (string list)
!   ;; Return non-nil if STRING is exactly matched by an element of
!   ;; LIST. The value is actually the tail of LIST whose
!   ;; car matches STRING.
!   (let* (case-fold-search)
!     (while
!         (and list (not (string-match (concat "^" (car list) "$") string)))
        (setq list (cdr list)))
      list))
  
  (defun bibtex-assoc-of-regexp (string alist)
!   ;; Return non-nil if STRING is exactly matched by the car of an
!   ;; element of LIST (case ignored). The value is actually the element
!   ;; of LIST whose car matches STRING.
!   (let* ((case-fold-search t))
!     (while
!         (and alist
!              (not (string-match (concat "^" (car (car alist)) "$") string)))
        (setq alist (cdr alist)))
      (car alist)))
  
  (defun bibtex-skip-to-valid-entry (&optional backward)
!   ;; If not at beginning of valid BibTeX entry, move to beginning of
!   ;; the next valid one. With argument backward non-nil, move backward
!   ;; to beginning of previous valid one. A valid entry is a
!   ;; syntactical correct one with type contained in
!   ;; bibtex-entry-field-alist or, if bibtex-sort-ignore-string-entries
!   ;; is nil, a syntactical correct string entry.
!   (let* ((case-fold-search t)
!        (valid-bibtex-entry
!         (concat
!          "@[ \t]*\\("
!          (mapconcat
!           (lambda (type)
!             (concat "\\(" (car type) "\\)"))
!           bibtex-entry-field-alist
!           "\\|")
!          "\\)"))
!        found)
!     (while (and (not found)
!                 (not (if backward
!                          (bobp)
!                        (eobp))))
!       (let ((pnt (point)))
!         (cond
!          ((looking-at valid-bibtex-entry)
!           (if (and
!                (bibtex-search-entry nil nil t)
!                (equal (match-beginning 0) pnt))
!               (setq found t)))
!          ((and (not bibtex-sort-ignore-string-entries)
!                (bibtex-parse-string))
!           (setq found t)))
!         (if found
!             (goto-char pnt)
!           (if backward
!               (progn
!                 (goto-char (1- pnt))
!                 (if (re-search-backward "^[ \t]*\\(@\\)" nil 'move)
!                     (goto-char (match-beginning 1))))
!             (goto-char (1+ pnt))
!             (if (re-search-forward "^[ \t]*@" nil 'move)
!                 (forward-char -1))))))))
  
  (defun bibtex-map-entries (fun)
!   ;; Call FUN for each BibTeX entry starting with the current. Do this
!   ;; to the end of the file. FUN is called with one argument, the key
!   ;; of the entry, and with point inside the entry. If
!   ;; bibtex-sort-ignore-string-entries is non-nil, FUN will not be
!   ;; called for @String entries.
!   (let* ((case-fold-search t))
      (bibtex-beginning-of-entry)
!     (while (re-search-forward bibtex-entry-maybe-empty-head nil t)
!       (let ((pnt (point))
!             (entry-type
!              (downcase (buffer-substring-no-properties
!                         (1+ (match-beginning bibtex-type-in-head))
!                         (match-end bibtex-type-in-head))))
!             (reference-key
!              (if (match-beginning bibtex-key-in-head)
!                  (buffer-substring-no-properties
!                   (match-beginning bibtex-key-in-head)
!                   (match-end bibtex-key-in-head))
!                "")))
!         (if (or
!              (and
!               (not bibtex-sort-ignore-string-entries)
!               (string-equal "string" (downcase entry-type)))
!              (assoc-ignore-case entry-type bibtex-entry-field-alist))
!             (funcall fun reference-key))
!         (goto-char pnt)
!         (bibtex-end-of-entry)))))
  
  (defun bibtex-progress-message (&optional flag interval)
!   ;; echos a message about progress of current buffer
!   ;; if flag is a string, the message is initialized (in this case a
!   ;; value for INTERVAL may be given as well (if not this is set to 5))
!   ;; if flag is done, the message is deinitialized
!   ;; if flag is absent, a message is echoed if point was incremented
!   ;; at least INTERVAL percent since last message was echoed
!   (let* ((size (- (point-max) (point-min)))
!          (perc (if (= size 0)
!                    100
!                  (/ (* 100 (- (point) (point-min))) size))))
!     (if (or (and (not flag)
!                  (>= perc
!                      (+ bibtex-progress-interval bibtex-progress-lastperc)))
!             (stringp flag))
!         (progn
!           (if (stringp flag)
!               (progn
!                 (setq bibtex-progress-lastmes flag)
!                 (if interval
!                     (setq bibtex-progress-interval interval)
!                   (setq bibtex-progress-interval 5))))
!           (setq bibtex-progress-lastperc perc)
!           (message (concat bibtex-progress-lastmes " (%d%%)") perc))
!       (if (equal flag 'done)
!           (progn
!             (message (concat bibtex-progress-lastmes " (done)"))
!             (setq bibtex-progress-lastmes nil))))))
! 
  
  (defun bibtex-field-left-delimiter ()
!   ;; returns a string dependent on bibtex-field-delimiters
    (if (equal bibtex-field-delimiters 'braces)
        "{"
      "\""))
  
  (defun bibtex-field-right-delimiter ()
!   ;; returns a string dependent on bibtex-field-delimiters
    (if (equal bibtex-field-delimiters 'braces)
        "}"
      "\""))
  
  (defun bibtex-entry-left-delimiter ()
!   ;; returns a string dependent on bibtex-field-delimiters
    (if (equal bibtex-entry-delimiters 'braces)
        "{"
      "("))
  
  (defun bibtex-entry-right-delimiter ()
!   ;; returns a string dependent on bibtex-field-delimiters
    (if (equal bibtex-entry-delimiters 'braces)
        "}"
      ")"))
  
! (defun bibtex-search-entry
!   (empty-head &optional bound noerror backward)
!   ;; A helper function necessary since the failure stack size limit for
!   ;; regexps was reduced in emacs 19.32.
!   ;; It searches for a BibTeX entry (maybe without a reference key if
!   ;; EMPTY-HEAD is t).
!   ;; BOUND and NOERROR are exactly as in re-search-forward. If
!   ;; BACKWARD is non-nil, search is done in reverse direction. After
!   ;; call to this function MATCH-BEGINNING and MATCH-END functions are
!   ;; defined, but only for the head part of the entry (especially
!   ;; (match-end 0) just gives the end of the head part).
    (let ((pnt (point))
!         (prefix (if empty-head
!                     bibtex-entry-maybe-empty-head
!                   bibtex-entry-head)))
      (if backward
          (let (found)
            (while (and (not found)
!                       (re-search-backward prefix bound noerror))
              (setq found (bibtex-search-entry empty-head pnt t)))
            (if found
!               (goto-char (match-beginning 0))
!             (if (equal noerror nil)
!                 ;; yell
!                 (error "Search of BibTeX entry failed"))
!             (if (equal noerror t)
!                 ;; don't move
!                 (goto-char pnt))
              nil))
!       (let ((limit (if bound bound (point-max)))
!             md
              found)
          (while (and (not found)
!                     (re-search-forward prefix bound noerror))
!           (setq md (match-data))
!           ;; save match-data of prefix regexp
!           (let ((entry-closer
!                  (if (save-excursion
!                        (goto-char (match-end bibtex-type-in-head))
!                        (looking-at "[ \t]*("))
!                      ;; entry opened with parenthesis
!                      ")"
!                    "}")))
!           (let ((infix-start (point))
!                 (finished nil))
!             (while (not finished)
!               (if (and (looking-at "[ \t\n]*")
!                        (<= (match-end 0) limit))
!                   (goto-char (match-end 0)))
!               (let ((bounds (bibtex-parse-field bibtex-field-name)))
!                 (if (and bounds (<= (bibtex-end-of-field bounds) limit))
!                     (progn
!                       (goto-char (bibtex-end-of-field bounds))
!                       (setq infix-start (point)))
!                   (goto-char infix-start)
!                   (setq finished t)))))
!             ;; This matches the infix* part. The AND construction assures
!             ;; that BOUND is respected.
!             (if (and (looking-at bibtex-entry-postfix)
!                      (string-equal
!                       (buffer-substring-no-properties
!                        (1- (match-end 0)) (match-end 0))
!                       entry-closer)
!                      (<= (match-end 0) limit))
!                 (progn
!                   (re-search-forward bibtex-entry-postfix)
!                   (setq found t)))))
          (if found
!             (progn
!               (set-match-data md)
!               ;; to set match-beginning/end again
!               (point))
!           (if (equal noerror nil)
!               ;; yell
!               (error "Search of BibTeX entry failed"))
!           (if (equal noerror t)
!               ;; don't move
!               (goto-char pnt))
            nil)))))
  
  (defun bibtex-flash-head ()
!   ;; Flash at BibTeX entry head before point, if exists.
!   (let* ((case-fold-search t)
!        flash)
      (cond ((re-search-backward bibtex-entry-head nil t)
!          (goto-char (match-beginning bibtex-type-in-head))
!          (setq flash (match-end bibtex-key-in-entry)))
!         (t
!          (end-of-line)
!          (skip-chars-backward " \t")
!          (setq flash (point))
!          (beginning-of-line)
!          (skip-chars-forward " \t")))
      (if (pos-visible-in-window-p (point))
!       (sit-for 1)
        (message "From: %s"
!              (buffer-substring (point) flash)))))
  
! (defun bibtex-make-optional-field (e-t)
!   "Makes an optional field named E-T in current BibTeX entry."
!   (if (consp e-t)
!       (bibtex-make-field (cons (concat "OPT" (car e-t)) (cdr e-t)))
!     (bibtex-make-field (concat "OPT" e-t))))
  
  (defun bibtex-move-outside-of-entry ()
!   ;; Make sure we are outside of a BibTeX entry.
    (let ((orig-point (point)))
      (bibtex-end-of-entry)
!     (if (< (point) orig-point)
!         ;; We moved backward, so we weren't inside an entry to begin with.
!         ;; Leave point at the beginning of a line, and preferably
!         ;; at the beginning of a paragraph.
!         (progn
!           (goto-char orig-point)
!           (beginning-of-line 1)
!           (if (not (= ?\n (char-before (1- (point)))))
!               (progn
!                 (re-search-forward "^[ address@hidden" nil 'move)
!                 (backward-char 1)))))
      (skip-chars-forward " \t\n")))
  
  (defun bibtex-beginning-of-first-entry ()
!   ;; Go to the beginning of the first BibTeX entry in buffer. Return
!   ;; point.
    (goto-char (point-min))
    (if (re-search-forward "^[ \t]*@" nil 'move)
        (beginning-of-line))
    (point))
  
  (defun bibtex-beginning-of-last-entry ()
!   ;; Go to the beginning of the last BibTeX entry in buffer.
    (goto-char (point-max))
    (if (re-search-backward "^[ \t]*@" nil 'move)
        (beginning-of-line))
    (point))
  
  (defun bibtex-inside-field ()
!   ;; Try to avoid point being at end of a BibTeX field.
    (end-of-line)
    (skip-chars-backward " \t")
    (cond ((= (preceding-char) ?,)
!        (forward-char -2)))
!   (cond ((or
!           (= (preceding-char) ?})
!           (= (preceding-char) ?\"))
           (forward-char -1))))
  
  (defun bibtex-enclosing-field (&optional noerr)
!   ;; Search for BibTeX field enclosing point. Point moves to end of
!   ;; field. Use match-beginning and match-end to parse the field. If
!   ;; NOERR is non-nil, no error is signalled. In this case, t is
!   ;; returned on success, nil otherwise.
!   (let* ((case-fold-search t)
!        (old-point (point))
!        (boe (bibtex-beginning-of-entry)))
!     (goto-char old-point)
!     (let ((bounds (bibtex-search-backward-field bibtex-field-name boe)))
!       (if (and bounds
!              (<= (bibtex-start-of-field bounds) old-point)
!              (>= (bibtex-end-of-field bounds) old-point))
!         bounds
!       (if noerr
!           nil
!         (error "Can't find enclosing BibTeX field"))))))
  
  (defun bibtex-enclosing-entry-maybe-empty-head ()
!   ;; Search for BibTeX entry enclosing point. Point moves to
!   ;; end of entry. Beginning (but not end) of entry is given
!   ;; by (match-beginning 0).
!   (let* ((case-fold-search t)
!        (old-point (point)))
!     (if (not
!          (re-search-backward
!           bibtex-entry-maybe-empty-head nil t))
!         (progn
!           (error "Can't find enclosing BibTeX entry")
!           (goto-char old-point)))
      (goto-char (match-beginning bibtex-type-in-head))
!     (if (not
!          (bibtex-search-entry t nil t))
!         (progn
!           (error "Can't find enclosing BibTeX entry")
!           (goto-char old-point)))))
  
  (defun bibtex-insert-current-kill (n)
    (if (not bibtex-last-kill-command)
--- 838,1722 ----
      (define-key km "\C-c\C-e\C-s" 'bibtex-String)
      (define-key km "\C-c\C-e\C-t" 'bibtex-TechReport)
      (define-key km "\C-c\C-e\C-u" 'bibtex-Unpublished)
!     km)
!   "Keymap used in BibTeX mode.")
  
  (easy-menu-define
!   bibtex-edit-menu bibtex-mode-map "BibTeX-Edit Menu in BibTeX mode"
!   '("BibTeX-Edit"
!     ("Moving inside an Entry"
!      ["End of Field" bibtex-find-text t]
!      ["Next Field" bibtex-next-field t]
!      ["Beginning of Entry" bibtex-beginning-of-entry t]
!      ["End of Entry" bibtex-end-of-entry t])
!     ("Moving in BibTeX Buffer"
!      ["Find Entry" bibtex-find-entry t]
!      ["Find Crossref Entry" bibtex-find-crossref t])
!     ("Operating on Current Entry"
!      ["Fill Entry" bibtex-fill-entry t]
!      ["Clean Entry" bibtex-clean-entry t]
!      "--"
!      ["Kill Entry" bibtex-kill-entry t]
!      ["Copy Entry to Kill Ring" bibtex-copy-entry-as-kill t]
!      ["Paste Most Recently Killed Entry" bibtex-yank t]
!      ["Paste Previously Killed Entry" bibtex-yank-pop t]
!      "--"
!      ["Ispell Entry" bibtex-ispell-entry t]
!      ["Ispell Entry Abstract" bibtex-ispell-abstract t]
!      ["Narrow to Entry" bibtex-narrow-to-entry t]
!      "--"
!      ["View Cite Locations (RefTeX)" reftex-view-crossref-from-bibtex
!       (fboundp 'reftex-view-crossref-from-bibtex)])
!     ("Operating on Current Field"
!      ["Fill Field" fill-paragraph t]
!      ["Remove Delimiters" bibtex-remove-delimiters t]
!      ["Remove OPT or ALT Prefix" bibtex-remove-OPT-or-ALT t]
!      ["Clear Field" bibtex-empty-field t]
!      "--"
!      ["Kill Field" bibtex-kill-field t]
!      ["Copy Field to Kill Ring" bibtex-copy-field-as-kill t]
!      ["Paste Most Recently Killed Field" bibtex-yank t]
!      ["Paste Previously Killed Field" bibtex-yank-pop t]
!      "--"
!      ["Make New Field" bibtex-make-field t]
!      "--"
!      ["Snatch from Similar Following Field" bibtex-pop-next t]
!      ["Snatch from Similar Preceding Field" bibtex-pop-previous t]
!      "--"
!      ["String or Key Complete" bibtex-complete t]
!      "--"
!      ["Help about Current Field" bibtex-print-help-message t])
!     ("Operating on Buffer or Region"
!      ["Validate Entries" bibtex-validate t]
!      ["Sort Entries" bibtex-sort-buffer t]
!      ["Reformat Entries" bibtex-reformat t]
!      ["Count Entries" bibtex-count-entries t])
!     ("Miscellaneous"
!      ["Convert Alien Buffer" bibtex-convert-alien t])))
  
  (easy-menu-define
!   bibtex-entry-menu bibtex-mode-map "Entry-Types Menu in BibTeX mode"
!   (list "Entry-Types"
!         ["Article in Journal" bibtex-Article t]
!         ["Article in Conference Proceedings" bibtex-InProceedings t]
!         ["Article in a Collection" bibtex-InCollection t]
!         ["Chapter or Pages in a Book" bibtex-InBook t]
!         ["Conference Proceedings" bibtex-Proceedings t]
!         ["Book" bibtex-Book t]
!         ["Booklet (Bound, but no Publisher/Institution)" bibtex-Booklet t]
!         ["PhD. Thesis" bibtex-PhdThesis t]
!         ["Master's Thesis" bibtex-MastersThesis t]
!         ["Technical Report" bibtex-TechReport t]
!         ["Technical Manual" bibtex-Manual t]
!         ["Unpublished" bibtex-Unpublished t]
!         ["Miscellaneous" bibtex-Misc t]
!         ["String" bibtex-String t]
!         ["Preamble" bibtex-Preamble t]))
  
  
  ;; Internal Variables
  
! (defvar bibtex-pop-previous-search-point nil
!   "Next point where `bibtex-pop-previous' starts looking for a similar 
entry.")
  
! (defvar bibtex-pop-next-search-point nil
!   "Next point where `bibtex-pop-next' starts looking for a similar entry.")
  
! (defvar bibtex-field-kill-ring nil
!   "Ring of least recently killed fields.
! At most `bibtex-field-kill-ring-max' items are kept here.")
! 
! (defvar bibtex-field-kill-ring-yank-pointer nil
!   "The tail of `bibtex-field-kill-ring' whose car is the last item yanked.")
! 
! (defvar bibtex-entry-kill-ring nil
!   "Ring of least recently killed entries.
! At most `bibtex-entry-kill-ring-max' items are kept here.")
! 
! (defvar bibtex-entry-kill-ring-yank-pointer nil
!   "The tail of `bibtex-entry-kill-ring' whose car is the last item yanked.")
! 
! (defvar bibtex-last-kill-command nil
!   "Type of the last kill command (either 'field or 'entry).")
! 
! (defvar bibtex-strings
!   (lazy-completion-table bibtex-strings
!                          bibtex-parse-strings (bibtex-string-files-init))
!   "Completion table for BibTeX string keys.
! Initialized from `bibtex-predefined-strings' and `bibtex-string-files'.")
! (make-variable-buffer-local 'bibtex-strings)
  
! (defvar bibtex-reference-keys
!   (lazy-completion-table bibtex-reference-keys bibtex-parse-keys nil nil t)
!   "Completion table for BibTeX reference keys.")
! (make-variable-buffer-local 'bibtex-reference-keys)
  
! (defvar bibtex-buffer-last-parsed-tick nil
!   "Last value returned by `buffer-modified-tick' when buffer
! was parsed for keys the last time.")
  
! (defvar bibtex-parse-idle-timer nil
!   "Stores if timer is already installed.")
  
! (defvar bibtex-progress-lastperc nil
!   "Last reported percentage for the progress message.")
  
! (defvar bibtex-progress-lastmes nil
!   "Last reported progress message.")
  
! (defvar bibtex-progress-interval nil
!   "Interval for progress messages.")
  
! (defvar bibtex-key-history nil
!   "History list for reading keys.")
  
! (defvar bibtex-entry-type-history nil
!   "History list for reading entry types.")
  
! (defvar bibtex-field-history nil
!   "History list for reading field names.")
  
! (defvar bibtex-reformat-previous-options nil
!   "Last reformat options given.")
  
! (defvar bibtex-reformat-previous-reference-keys nil
!   "Last reformat reference keys option given.")
  
! (defconst bibtex-field-name "[^\"#%'(),={} \t\n0-9][^\"#%'(),={} \t\n]*"
!   "Regexp matching the name part of a BibTeX field.")
  
! (defconst bibtex-entry-type (concat "@" bibtex-field-name)
!   "Regexp matching the type part of a BibTeX entry.")
  
! (defconst bibtex-reference-key 
"[][a-zA-Z0-9.:;?!`'/address@hidden|()<>&_^$-]+"
!   "Regexp matching the reference key part of a BibTeX entry.")
  
! (defconst bibtex-field-const "[][a-zA-Z0-9.:;?!`'/address@hidden|<>&_^$-]+"
!   "Regexp matching a BibTeX field constant.")
  
! (defconst bibtex-entry-head
!   (concat "^[ \t]*\\("
!           bibtex-entry-type
!           "\\)[ \t]*[({][ \t\n]*\\("
!           bibtex-reference-key
!           "\\)")
!   "Regexp matching the header line of a BibTeX entry.")
! 
! (defconst bibtex-entry-maybe-empty-head
!   (concat bibtex-entry-head "?")
!   "Regexp matching the header line of a BibTeX entry (possibly without key).")
! 
! (defconst bibtex-type-in-head 1
!   "Regexp subexpression number of the type part in `bibtex-entry-head'.")
! 
! (defconst bibtex-key-in-head 2
!   "Regexp subexpression number of the key part in `bibtex-entry-head'.")
! 
! (defconst bibtex-entry-postfix "[ \t\n]*,?[ \t\n]*[})]"
!   "Regexp matching the postfix of a BibTeX entry.")
! 
! (defvar bibtex-known-entry-type-re
!   (regexp-opt (mapcar 'car bibtex-entry-field-alist))
!   "Regexp matching the name of a BibTeX entry type.")
! 
! (defvar bibtex-valid-entry-re
!   (concat "@[ \t]*\\(" bibtex-known-entry-type-re "\\)")
!   "Regexp matching the name of a valid BibTeX entry.")
! 
! (defvar bibtex-valid-entry-whitespace-re
!   (concat "[ \t\n]*\\(" bibtex-valid-entry-re "\\)")
!   "Regexp matching the name of a valid BibTeX entry preceded by whitespace.")
! 
! (defvar bibtex-any-valid-entry-re
!   (concat "@[ \t]*"
!           (regexp-opt (append '("String")
!                               (mapcar 'car bibtex-entry-field-alist))
!                       t))
!   "Regexp matching the name of any valid BibTeX entry (including string).")
! 
! 
! (defconst bibtex-empty-field-re "\"\"\\|{}"
!   "Regexp matching an empty field.")
! 
! (defconst bibtex-quoted-string-re
!   (concat "\""
!           "\\("
!           "[^\"\\]"          ; anything but quote or backslash
!           "\\|"
!           "\\("
!           "\\\\\\(.\\|\n\\)" ; any backslash quoted character
!           "\\)"
!           "\\)*"
!           "\"")
!   "Regexp matching a field string enclosed by quotes.")
! 
! (defconst bibtex-font-lock-syntactic-keywords
!   `((,(concat "^[ \t]*\\(" (substring bibtex-comment-start 0 1) "\\)"
!               (substring bibtex-comment-start 1) "\\>")
!      1 '(11))))
! 
! (defvar bibtex-font-lock-keywords
!   (list
!    ;; entry type and reference key
!    (list bibtex-entry-maybe-empty-head
!          (list bibtex-type-in-head 'font-lock-function-name-face)
!          (list bibtex-key-in-head 'font-lock-constant-face nil t))
!    ;; optional field names (treated as comments)
!    (list
!     (concat "^[ \t]*\\(OPT" bibtex-field-name "\\)[ \t]*=")
!     1 'font-lock-comment-face)
!    ;; field names
!    (list (concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=")
!          1 'font-lock-variable-name-face))
!   "*Default expressions to highlight in BibTeX mode.")
! 
! (defvar bibtex-field-name-for-parsing nil
!   "Temporary variable storing the name string to be parsed by the callback
! function `bibtex-parse-field-name'.")
! 
! (defvar bibtex-sort-entry-class-alist
!   (let ((i -1) alist)
!     (dolist (class bibtex-sort-entry-class alist)
!       (setq i (1+ i))
!       (dolist (entry class)
!         ;; all entry names should be downcase (for ease of comparison)
!         (push (cons (if (stringp entry) (downcase entry) entry) i) alist))))
!   "Alist for the classes of the entry types if the value of
! `bibtex-maintain-sorted-entries' is `entry-class'.")
  
  
! ;; Special support taking care of variants
! (defvar zmacs-regions)
! (if (boundp 'mark-active)
!     (defun bibtex-mark-active ()
!       ;; In Emacs mark-active indicates if mark is active.
!       mark-active)
!   (defun bibtex-mark-active ()
!     ;; In XEmacs (mark) returns nil when not active.
!     (if zmacs-regions (mark) (mark t))))
! 
! (if (fboundp 'run-with-idle-timer)
!     ;; timer.el is distributed with Emacs
!     (fset 'bibtex-run-with-idle-timer 'run-with-idle-timer)
!   ;; timer.el is not distributed with XEmacs
!   ;; Notice that this does not (yet) pass the arguments, but they
!   ;; are not used (yet) in bibtex.el. Fix if needed.
!   (defun bibtex-run-with-idle-timer (secs repeat function &rest args)
!     (start-itimer "bibtex" function secs (if repeat secs nil) t)))
  
! 
! ;; Support for hideshow minor mode
! (defun bibtex-hs-forward-sexp (arg)
!   "Replacement for `forward-sexp' to be used by `hs-minor-mode'."
!   (if (< arg 0)
!       (backward-sexp 1)
!     (if (looking-at "@\\S(*\\s(")
!         (progn
!           (goto-char (match-end 0))
!           (forward-char -1)
!           (forward-sexp 1))
!       (forward-sexp 1))))
  
! (add-to-list
!  'hs-special-modes-alist
!  '(bibtex-mode "@\\S(*\\s(" "\\s)" nil bibtex-hs-forward-sexp nil))
  
! 
! (defconst bibtex-braced-string-syntax-table
!   (let ((st (make-syntax-table)))
!     (modify-syntax-entry ?\{ "(}" st)
!     (modify-syntax-entry ?\} "){" st)
!     (modify-syntax-entry ?\[ "." st)
!     (modify-syntax-entry ?\] "." st)
!     (modify-syntax-entry ?\( "." st)
!     (modify-syntax-entry ?\) "." st)
!     (modify-syntax-entry ?\\ "." st)
!     (modify-syntax-entry ?\" "." st)
!     st)
!   "Syntax-table to parse matched braces.")
  
! (defconst bibtex-quoted-string-syntax-table
!   (let ((st (make-syntax-table)))
!     (modify-syntax-entry ?\\ "\\" st)
!     (modify-syntax-entry ?\" "\"" st)
!     st)
!   "Syntax-table to parse matched quotes.")
  
  (defun bibtex-parse-field-string ()
!   "Parse a field string enclosed by braces or quotes.
  If a syntactically correct string is found, a pair containing the start and
  end position of the field string is returned, nil otherwise."
!   (let ((end-point
!          (or (and (eq (following-char) ?\")
!                   (save-excursion
!                     (with-syntax-table bibtex-quoted-string-syntax-table
!                       (forward-sexp 1))
!                     (point)))
!              (and (eq (following-char) ?\{)
!                   (save-excursion
!                     (with-syntax-table bibtex-braced-string-syntax-table
!                       (forward-sexp 1))
!                     (point))))))
!     (if end-point
!         (cons (point) end-point))))
  
  (defun bibtex-parse-association (parse-lhs parse-rhs)
!   "Parse a string of the format <left-hand-side = right-hand-side>.
  The functions PARSE-LHS and PARSE-RHS are used to parse the corresponding
  substrings.  These functions are expected to return nil if parsing is not
  successfull.  If both functions return non-nil, a pair containing the returned
! values of the functions PARSE-LHS and PARSE-RHS is returned."
    (save-match-data
!     (save-excursion
!       (let ((left (funcall parse-lhs))
!             right)
!         (if (and left
!                  (looking-at "[ \t\n]*=[ \t\n]*")
!                  (goto-char (match-end 0))
!                  (setq right (funcall parse-rhs)))
!             (cons left right))))))
  
  (defun bibtex-parse-field-name ()
!   "Parse the field name stored in `bibtex-field-name-for-parsing'.
  If the field name is found, return a triple consisting of the position of the
  very first character of the match, the actual starting position of the name
! part and end position of the match. Move point to end of field name.
! If `bibtex-autoadd-commas' is non-nil add missing comma at end of preceeding
! BibTeX field as necessary."
!   (cond ((looking-at ",[ \t\n]*")
!          (let ((start (point)))
!            (goto-char (match-end 0))
!            (when (looking-at bibtex-field-name-for-parsing)
!              (goto-char (match-end 0))
!              (list start (match-beginning 0) (match-end 0)))))
!         ;; Maybe add a missing comma.
!         ((and bibtex-autoadd-commas
!               (looking-at (concat "[ \t\n]*\\(?:" 
bibtex-field-name-for-parsing
!                                   "\\)[ \t\n]*=")))
!          (skip-chars-backward " \t\n")
!          (insert ",")
!          (forward-char -1)
!          ;; Now try again.
!          (bibtex-parse-field-name))))
  
  (defun bibtex-parse-field-text ()
!   "Parse the text part of a BibTeX field.
  The text part is either a string, or an empty string, or a constant followed
  by one or more <# (string|constant)> pairs.  If a syntactically correct text
  is found, a pair containing the start and end position of the text is
! returned, nil otherwise. Move point to end of field text."
    (let ((starting-point (point))
!         end-point failure boundaries)
!     (while (not (or end-point failure))
!       (cond ((looking-at bibtex-field-const)
!              (goto-char (match-end 0)))
!             ((setq boundaries (bibtex-parse-field-string))
!              (goto-char (cdr boundaries)))
!             ((setq failure t)))
        (if (not (looking-at "[ \t\n]*#[ \t\n]*"))
!           (setq end-point (point))
!         (goto-char (match-end 0))))
!     (if (and (not failure)
!              end-point)
!         (cons starting-point end-point))))
  
  (defun bibtex-parse-field (name)
!   "Parse a BibTeX field of regexp NAME.
  If a syntactically correct field is found, a pair containing the boundaries of
  the name and text parts of the field is returned."
!   (let ((bibtex-field-name-for-parsing name))
!     (bibtex-parse-association 'bibtex-parse-field-name
!                               'bibtex-parse-field-text)))
  
! (defun bibtex-search-forward-field (name &optional bound)
!   "Search forward to find a field of name NAME.
  If a syntactically correct field is found, a pair containing the boundaries of
  the name and text parts of the field is returned.  The search is limited by
! optional arg BOUND. If BOUND is t the search is limited by the end of the 
current
! entry. Do not move point."
    (save-match-data
!     (save-excursion
!       (unless (integer-or-marker-p bound)
!         (setq bound (if bound
!                         (save-excursion (bibtex-end-of-entry))
!                       (point-max))))
!       (let ((case-fold-search t)
!             (bibtex-field-name-for-parsing name)
!             boundaries temp-boundaries)
!         (while (and (not boundaries)
!                     (< (point) bound)
!                     (search-forward "," bound t))
!           (goto-char (match-beginning 0))
!           (if (and (setq temp-boundaries
!                          (bibtex-parse-association 'bibtex-parse-field-name
!                                                    'bibtex-parse-field-text))
!                    (<= (cddr temp-boundaries) bound))
!               (setq boundaries temp-boundaries)
!             (forward-char 1)))
!         boundaries))))
  
! (defun bibtex-search-backward-field (name &optional bound)
!   "Search backward to find a field of name NAME.
  If a syntactically correct field is found, a pair containing the boundaries of
  the name and text parts of the field is returned.  The search is limited by
! optional arg BOUND. If BOUND is t the search is limited by the beginning of 
the
! current entry. Do not move point."
    (save-match-data
!     (save-excursion
!       (unless (integer-or-marker-p bound)
!         (setq bound (if bound
!                         (save-excursion (bibtex-beginning-of-entry))
!                       (point-min))))
!       (let ((case-fold-search t)
!             (bibtex-field-name-for-parsing name)
!             boundaries temp-boundaries)
!         (while (and (not boundaries)
!                     (>= (point) bound)
!                     (search-backward "," bound t))
!           (if (setq temp-boundaries
!                     (bibtex-parse-association 'bibtex-parse-field-name
!                                               'bibtex-parse-field-text))
!               (setq boundaries temp-boundaries)))
!         boundaries))))
! 
! (defsubst bibtex-start-of-field (bounds)
!   (nth 0 (car bounds)))
! (defsubst bibtex-start-of-name-in-field (bounds)
!   (nth 1 (car bounds)))
! (defsubst bibtex-end-of-name-in-field (bounds)
!   (nth 2 (car bounds)))
! (defsubst bibtex-end-of-field (bounds)
!   (cddr bounds))
! (defsubst bibtex-start-of-text-in-field (bounds)
!   (cadr bounds))
! (defsubst bibtex-end-of-text-in-field (bounds)
!   (cddr bounds))
! 
! (defun bibtex-name-in-field (bounds)
!   "Get content of name in BibTeX field defined via BOUNDS."
!   (buffer-substring-no-properties (nth 1 (car bounds))
!                                   (nth 2 (car bounds))))
! 
! (defun bibtex-text-in-field-bounds (bounds &optional remove-delim)
!   "Get content of text in BibTeX field defined via BOUNDS.
! If optional arg REMOVE-DELIM is non-nil remove enclosing field delimiters
! if present."
!   (let ((content (buffer-substring-no-properties (cadr bounds)
!                                                  (cddr bounds))))
!     (if (and remove-delim
!              (string-match "\\`[{\"]\\(.*\\)[}\"]\\'" content))
!         (substring content (match-beginning 1) (match-end 1))
!       content)))
! 
! (defun bibtex-text-in-field (field &optional follow-crossref)
!   "Get content of field FIELD of current BibTeX entry. Return nil if not 
found.
! If optional arg FOLLOW-CROSSREF is non-nil, follow crossref."
!   (save-excursion
!     (save-restriction
!       ;; We want to jump back and forth while searching FIELD
!       (bibtex-narrow-to-entry)
!       (goto-char (point-min))
!       (let ((bounds (bibtex-search-forward-field field))
!             crossref-field)
!         (cond (bounds (bibtex-text-in-field-bounds bounds t))
!               ((and follow-crossref
!                     (progn (goto-char (point-min))
!                            (setq bounds (bibtex-search-forward-field
!                                          "\\(OPT\\)?crossref"))))
!                (setq crossref-field (bibtex-text-in-field-bounds bounds t))
!                (widen)
!                (if (bibtex-find-crossref crossref-field)
!                    ;; Do not pass FOLLOW-CROSSREF because we want
!                    ;; to follow crossrefs only one level of recursion.
!                    (bibtex-text-in-field field))))))))
  
  (defun bibtex-parse-string-prefix ()
!   "Parse the prefix part of a BibTeX string entry, including reference key.
  If the string prefix is found, return a triple consisting of the position of
  the very first character of the match, the actual starting position of the
  reference key and the end position of the match."
!   (let ((case-fold-search t))
      (if (looking-at "^[ address@hidden \t\n]*[({][ \t\n]*")
!         (let ((start (point)))
!           (goto-char (match-end 0))
!           (when (looking-at bibtex-reference-key)
!             (goto-char (match-end 0))
!             (list start
!                   (match-beginning 0)
!                   (match-end 0)))))))
  
  (defun bibtex-parse-string-postfix ()
!   "Parse the postfix part of a BibTeX string entry, including the text.
  If the string postfix is found, return a triple consisting of the position of
  the actual starting and ending position of the text and the very last
! character of the string entry. Move point past BibTeX string entry."
    (let* ((case-fold-search t)
!          (bounds (bibtex-parse-field-text)))
!     (when bounds
!       (goto-char (cdr bounds))
!       (when (looking-at "[ \t\n]*[})]")
!         (goto-char (match-end 0))
!         (list (car bounds)
!               (cdr bounds)
!               (match-end 0))))))
  
  (defun bibtex-parse-string ()
!   "Parse a BibTeX string entry.
  If a syntactically correct entry is found, a pair containing the boundaries of
! the reference key and text parts of the entry is returned.
! Move point past BibTeX string entry."
    (bibtex-parse-association 'bibtex-parse-string-prefix
!                             'bibtex-parse-string-postfix))
  
  (defun bibtex-search-forward-string ()
!   "Search forward to find a BibTeX string entry.
  If a syntactically correct entry is found, a pair containing the boundaries of
! the reference key and text parts of the string is returned. Do not move 
point."
!   (save-excursion
!     (save-match-data
!       (let ((case-fold-search t)
!             boundaries)
!         (while (and (not boundaries)
!                     (search-forward-regexp
!                      "^[ address@hidden \t\n]*[({][ \t\n]*" nil t))
!           (goto-char (match-beginning 0))
!           (unless (setq boundaries (bibtex-parse-string))
!             (forward-char 1)))
!         boundaries))))
  
  (defun bibtex-search-backward-string ()
!   "Search backward to find a BibTeX string entry.
  If a syntactically correct entry is found, a pair containing the boundaries of
! the reference key and text parts of the field is returned. Do not move point."
!   (save-excursion
!     (save-match-data
!       (let ((case-fold-search t)
!             boundaries)
!         (while (and (not boundaries)
!                     (search-backward-regexp
!                      "^[ address@hidden \t\n]*[({][ \t\n]*" nil t))
!           (goto-char (match-beginning 0))
!           (setq boundaries (bibtex-parse-string)))
!         boundaries))))
! 
! (defun bibtex-reference-key-in-string (bounds)
!   (buffer-substring-no-properties (nth 1 (car bounds))
!                                   (nth 2 (car bounds))))
! 
! (defun bibtex-text-in-string (bounds &optional remove-delim)
!   "Get content of text in BibTeX string field defined via BOUNDS.
! If optional arg REMOVE-DELIM is non-nil remove enclosing field
! delimiters if present."
!   (let ((content (buffer-substring-no-properties (nth 0 (cdr bounds))
!                                                  (nth 1 (cdr bounds)))))
!     (if (and remove-delim
!              (string-match "\\`{\\(.*\\)}\\'" content))
!         (substring content (match-beginning 1) (match-end 1))
!       content)))
! 
! (defsubst bibtex-start-of-text-in-string (bounds)
!   (nth 0 (cdr bounds)))
! (defsubst bibtex-end-of-text-in-string (bounds)
!   (nth 1 (cdr bounds)))
! (defsubst bibtex-end-of-string (bounds)
!   (nth 2 (cdr bounds)))
! 
! (defsubst bibtex-type-in-head ()
!   "Extract BibTeX type in head."
!   ;;                              ignore @
!   (buffer-substring-no-properties (1+ (match-beginning bibtex-type-in-head))
!                                   (match-end bibtex-type-in-head)))
! 
! (defun bibtex-key-in-head (&optional empty)
!   "Extract BibTeX key in head. Return optional arg EMPTY if key is empty."
!   (if (match-beginning bibtex-key-in-head)
!       (buffer-substring-no-properties (match-beginning bibtex-key-in-head)
!                                       (match-end bibtex-key-in-head))
!     empty))
  
  ;; Helper Functions
  
  (defun bibtex-delete-whitespace ()
!   "Delete all whitespace starting at point."
    (if (looking-at "[ \t\n]+")
        (delete-region (point) (match-end 0))))
  
  (defun bibtex-current-line ()
!   "Compute line number of point regardless whether the buffer is narrowed."
    (+ (count-lines 1 (point))
       (if (equal (current-column) 0) 1 0)))
  
  (defun bibtex-member-of-regexp (string list)
!   "Return non-nil if STRING is exactly matched by an element of LIST.
! The value is actually the tail of LIST whose car matches STRING."
!   (let (case-fold-search)
!     (while (and list
!                 (not (string-match (concat "\\`\\(?:" (car list) "\\)\\'") 
string)))
        (setq list (cdr list)))
      list))
  
  (defun bibtex-assoc-of-regexp (string alist)
!   "Return non-nil if STRING is exactly matched by the car of an
! element of ALIST (case ignored). The value is actually the element
! of LIST whose car matches STRING."
!   (let ((case-fold-search t))
!     (while (and alist
!                 (not (string-match (concat "\\`\\(?:" (caar alist) "\\)\\'") 
string)))
        (setq alist (cdr alist)))
      (car alist)))
  
  (defun bibtex-skip-to-valid-entry (&optional backward)
!   "Unless at beginning of a valid BibTeX entry, move point to beginning of the
! next valid one. With optional argument BACKWARD non-nil, move backward to
! beginning of previous valid one. A valid entry is a syntactical correct one
! with type contained in `bibtex-entry-field-alist' or, if
! `bibtex-sort-ignore-string-entries' is nil, a syntactical correct string
! entry. Return buffer position of beginning and ending of entry if a valid
! entry is found, nil otherwise."
!   (interactive "P")
!   (let ((case-fold-search t)
!         found)
!     (while (not (or found (if backward (bobp) (eobp))))
!       (let ((pnt (point))
!             bounds)
!         (cond ((or (and (looking-at bibtex-valid-entry-re)
!                         (setq found (bibtex-search-entry nil nil t))
!                         (equal (match-beginning 0) pnt))
!                    (and (not bibtex-sort-ignore-string-entries)
!                         (setq bounds (bibtex-parse-string))
!                         (setq found (cons (bibtex-start-of-field bounds)
!                                           (bibtex-end-of-string bounds)))))
!                (goto-char pnt))
!               (backward
!                (if (re-search-backward "^[ \t]*\\(@\\)" nil 'move)
!                    (goto-char (match-beginning 1))))
!               (t (if (re-search-forward "\n[ \t]*@" nil 'move)
!                      (forward-char -1))))))
!     found))
  
  (defun bibtex-map-entries (fun)
!   "Call FUN for each BibTeX entry starting with the current.
! Do this to the end of the file. FUN is called with three arguments, the key of
! the entry and the buffer positions (marker) of beginning and end of entry.
! Point is inside the entry. If `bibtex-sort-ignore-string-entries' is non-nil,
! FUN will not be called for @String entries."
!   (let ((case-fold-search t))
      (bibtex-beginning-of-entry)
!     (while (re-search-forward bibtex-entry-head nil t)
!       (let ((entry-type (bibtex-type-in-head))
!             (key (bibtex-key-in-head ""))
!             (beg (copy-marker (match-beginning 0)))
!             (end (copy-marker (save-excursion (bibtex-end-of-entry)))))
!         (save-excursion
!           (if (or (and (not bibtex-sort-ignore-string-entries)
!                        (string-equal "string" (downcase entry-type)))
!                   (assoc-ignore-case entry-type bibtex-entry-field-alist))
!               (funcall fun key beg end)))
!         (goto-char end)))))
  
  (defun bibtex-progress-message (&optional flag interval)
!   "Echo a message about progress of current buffer.
! If FLAG is a string, the message is initialized (in this case a
! value for INTERVAL may be given as well (if not this is set to 5)).
! If FLAG is done, the message is deinitialized.
! If FLAG is absent, a message is echoed if point was incremented
! at least INTERVAL percent since last message was echoed."
!   (cond ((stringp flag)
!          (setq bibtex-progress-lastmes flag)
!          (setq bibtex-progress-interval (or interval 5)
!                bibtex-progress-lastperc 0))
!         ((equal flag 'done)
!          (message  "%s (done)" bibtex-progress-lastmes)
!          (setq bibtex-progress-lastmes nil))
!         (t
!          (let* ((size (- (point-max) (point-min)))
!                 (perc (if (= size 0)
!                           100
!                         (/ (* 100 (- (point) (point-min))) size))))
!            (when (>= perc (+ bibtex-progress-lastperc
!                              bibtex-progress-interval))
!              (setq bibtex-progress-lastperc perc)
!              (message "%s (%d%%)" bibtex-progress-lastmes perc))))))
  
  (defun bibtex-field-left-delimiter ()
!   "Return a string dependent on `bibtex-field-delimiters'."
    (if (equal bibtex-field-delimiters 'braces)
        "{"
      "\""))
  
  (defun bibtex-field-right-delimiter ()
!   "Return a string dependent on `bibtex-field-delimiters'."
    (if (equal bibtex-field-delimiters 'braces)
        "}"
      "\""))
  
  (defun bibtex-entry-left-delimiter ()
!   "Return a string dependent on `bibtex-field-delimiters'."
    (if (equal bibtex-entry-delimiters 'braces)
        "{"
      "("))
  
  (defun bibtex-entry-right-delimiter ()
!   "Return a string dependent on `bibtex-field-delimiters'."
    (if (equal bibtex-entry-delimiters 'braces)
        "}"
      ")"))
  
! (defun bibtex-search-entry (empty-head &optional bound noerror backward)
!   "Search for a BibTeX entry (maybe without reference key if EMPTY-HEAD is t).
! BOUND and NOERROR are exactly as in `re-search-forward'. If BACKWARD
! is non-nil, search is done in reverse direction. Point is moved past the
! closing delimiter (at the beginning of entry if BACKWARD is non-nil).
! Return a cons pair with buffer positions of beginning and end of entry.
! After call to this function MATCH-BEGINNING and MATCH-END functions
! are defined, but only for the head part of the entry
! \(especially (match-end 0) just gives the end of the head part)."
    (let ((pnt (point))
!         (entry-head-re (if empty-head
!                            bibtex-entry-maybe-empty-head
!                          bibtex-entry-head)))
      (if backward
          (let (found)
            (while (and (not found)
!                       (re-search-backward entry-head-re bound noerror))
              (setq found (bibtex-search-entry empty-head pnt t)))
            (if found
!               (progn (goto-char (match-beginning 0))
!                      found)
!             (cond ((equal noerror nil)
!                    ;; yell
!                    (error "Backward search of BibTeX entry failed"))
!                   ((equal noerror t)
!                    ;; don't move
!                    (goto-char pnt)))
              nil))
!       (let ((limit (or bound (point-max)))
              found)
          (while (and (not found)
!                     (re-search-forward entry-head-re bound noerror))
!           (save-match-data
!             (let ((entry-closer
!                    (if (save-excursion
!                          (goto-char (match-end bibtex-type-in-head))
!                          (looking-at "[ \t]*("))
!                        ;; entry opened with parenthesis
!                        ?\)
!                      ?\}))
!                   (infix-start (point))
!                   finished bounds)
!               (while (not finished)
!                 (skip-chars-forward " \t\n" limit)
!                 (if (and (setq bounds (bibtex-parse-field bibtex-field-name))
!                          (<= (bibtex-end-of-field bounds) limit))
!                     (setq infix-start (bibtex-end-of-field bounds))
!                   (setq finished t))
!                 (goto-char infix-start))
!               ;; This matches the infix* part. The AND construction assures
!               ;; that BOUND is respected.
!               (when (and (looking-at bibtex-entry-postfix)
!                          (eq (char-before (match-end 0)) entry-closer)
!                          (<= (match-end 0) limit))
!                 (goto-char (match-end 0))
!                 (setq found t)))))
          (if found
!             (cons (match-beginning 0) (point))
!           (cond ((not noerror)
!                  ;; yell
!                  (error "Search of BibTeX entry failed"))
!                 ((equal noerror t)
!                  ;; don't move
!                  (goto-char pnt)))
            nil)))))
  
  (defun bibtex-flash-head ()
!   "Flash at BibTeX entry head before point, if exists."
!   (let ((case-fold-search t)
!         flash)
      (cond ((re-search-backward bibtex-entry-head nil t)
!            (goto-char (match-beginning bibtex-type-in-head))
!            (setq flash (match-end bibtex-key-in-head)))
!           (t
!            (end-of-line)
!            (skip-chars-backward " \t")
!            (setq flash (point))
!            (beginning-of-line)
!            (skip-chars-forward " \t")))
      (if (pos-visible-in-window-p (point))
!         (sit-for 1)
        (message "From: %s"
!                (buffer-substring (point) flash)))))
  
! (defun bibtex-make-optional-field (field)
!   "Make an optional field named FIELD in current BibTeX entry."
!   (if (consp field)
!       (bibtex-make-field (cons (concat "OPT" (car field)) (cdr field)))
!     (bibtex-make-field (concat "OPT" field))))
  
  (defun bibtex-move-outside-of-entry ()
!   "Make sure point is outside of a BibTeX entry."
    (let ((orig-point (point)))
      (bibtex-end-of-entry)
!     (when (<= (point) orig-point)
!       ;; We moved backward, so we weren't inside an entry to begin with.
!       ;; Leave point at the beginning of a line, and preferably
!       ;; at the beginning of a paragraph.
!       (goto-char orig-point)
!       (beginning-of-line 1)
!       (let ((cb (char-before (1- (point)))))
!         (unless (and cb (= ?\n cb))
!           (re-search-forward "^[ address@hidden" nil 'move)
!           (backward-char 1))))
      (skip-chars-forward " \t\n")))
  
  (defun bibtex-beginning-of-first-entry ()
!   "Go to the beginning of the first BibTeX entry in buffer. Return point."
    (goto-char (point-min))
    (if (re-search-forward "^[ \t]*@" nil 'move)
        (beginning-of-line))
    (point))
  
  (defun bibtex-beginning-of-last-entry ()
!   "Go to the beginning of the last BibTeX entry in buffer."
    (goto-char (point-max))
    (if (re-search-backward "^[ \t]*@" nil 'move)
        (beginning-of-line))
    (point))
  
  (defun bibtex-inside-field ()
!   "Try to avoid point being at end of a BibTeX field."
    (end-of-line)
    (skip-chars-backward " \t")
    (cond ((= (preceding-char) ?,)
!          (forward-char -2)))
!   (cond ((or (= (preceding-char) ?})
!              (= (preceding-char) ?\"))
           (forward-char -1))))
  
  (defun bibtex-enclosing-field (&optional noerr)
!   "Search for BibTeX field enclosing point. Point moves to end of field.
! Use `match-beginning' and `match-end' to parse the field. If NOERR is non-nil,
! no error is signalled. In this case, bounds are returned on success,
! nil otherwise."
!   (let ((bounds (bibtex-search-backward-field bibtex-field-name t)))
!     (if (and bounds
!              (<= (bibtex-start-of-field bounds) (point))
!              (>= (bibtex-end-of-field bounds) (point)))
!         bounds
!       (unless noerr
!         (error "Can't find enclosing BibTeX field")))))
  
  (defun bibtex-enclosing-entry-maybe-empty-head ()
!   "Search for BibTeX entry enclosing point. Move point to end of entry.
! Beginning (but not end) of entry is given by (`match-beginning' 0)."
!   (let ((case-fold-search t)
!         (old-point (point)))
!     (unless (re-search-backward bibtex-entry-maybe-empty-head nil t)
!       (goto-char old-point)
!       (error "Can't find beginning of enclosing BibTeX entry"))
      (goto-char (match-beginning bibtex-type-in-head))
!     (unless (bibtex-search-entry t nil t)
!       (goto-char old-point)
!       (error "Can't find end of enclosing BibTeX entry"))))
  
  (defun bibtex-insert-current-kill (n)
    (if (not bibtex-last-kill-command)
***************
*** 1687,1696 ****
             (kryp (if (equal bibtex-last-kill-command 'field)
                       'bibtex-field-kill-ring-yank-pointer
                     'bibtex-entry-kill-ring-yank-pointer))
!            (ARGth-kill-element
!             (nthcdr
!              (mod (- n (length (eval kryp))) (length (eval kr)))
!              (eval kr)))
             (current (car (set kryp ARGth-kill-element))))
        (cond
         ((equal bibtex-last-kill-command 'field)
--- 1727,1735 ----
             (kryp (if (equal bibtex-last-kill-command 'field)
                       'bibtex-field-kill-ring-yank-pointer
                     'bibtex-entry-kill-ring-yank-pointer))
!            (ARGth-kill-element (nthcdr (mod (- n (length (eval kryp)))
!                                             (length (eval kr)))
!                                        (eval kr)))
             (current (car (set kryp ARGth-kill-element))))
        (cond
         ((equal bibtex-last-kill-command 'field)
***************
*** 1708,2184 ****
          (message "Mark set")
          (insert (elt current 1)))
         (t
!         (error
!          "Unknown tag field: %s.  Please submit a bug report"
!          bibtex-last-kill-command))))))
! 
! (defun bibtex-format-field-delimiters (start stop)
!   "*Replaces delimiters for field strings between START and STOP.
! If the current delimiters equal the new delimiters, the buffer is not
! changed."
!   (goto-char start)
!   (let ((boundaries (bibtex-search-forward-field-string stop)))
!     (while boundaries
!       (goto-char (car boundaries))
!       (if (not (looking-at (bibtex-field-left-delimiter)))
!         (progn
!           (delete-char 1)
!           (insert (bibtex-field-left-delimiter))))
!       (goto-char (- (cdr boundaries) 1))
!       (if (not (looking-at (bibtex-field-right-delimiter)))
!         (progn
!           (delete-char 1)
!           (insert (bibtex-field-right-delimiter))))
!       (setq boundaries (bibtex-search-forward-field-string stop)))))
  
  (defun bibtex-format-entry ()
!   ;; Helper function for bibtex-clean-entry. Formats current entry
!   ;; according to variable bibtex-entry-format.
!   (let* ((case-fold-search t)
!        (beg (point))
!        (start (bibtex-beginning-of-entry))
!        crossref-there
!        alternatives-there
!        non-empty-alternative)
!     (let ((end (copy-marker (bibtex-end-of-entry))))
!       (if (equal start (marker-position end))
!           (error "Not on a known BibTeX entry")
!         (goto-char start)
!       (let ((bounds (bibtex-search-forward-field bibtex-field-name end)))
!         (while bounds
!           ;; determine if entry has crossref field and if at least
!           ;; one alternative is non-empty
!           (let ((begin-name (bibtex-start-of-name-in-field bounds))
!                 (end-name (bibtex-end-of-name-in-field bounds))
!                 (begin-text (bibtex-start-of-text-in-field bounds))
!                 (end-text (bibtex-end-of-text-in-field bounds)))
!             (goto-char begin-name)
!             (if (looking-at "ALT")
!                 (progn
!                   (setq alternatives-there t)
!                   (goto-char begin-text)
!                   (if (not (looking-at "\\(\"\"\\)\\|\\({}\\)"))
!                       (setq non-empty-alternative t))))
!             (if (string-match
!                  "\\(OPT\\)?crossref"
!                  (buffer-substring-no-properties begin-name end-name))
!                 (progn
!                   (setq
!                    crossref-there
!                    (buffer-substring-no-properties
!                     (1+ begin-text) (1- end-text)))
!                   (if (equal crossref-there "")
!                       (setq crossref-there nil)))))
!           (goto-char (bibtex-end-of-field bounds))
!           (setq bounds (bibtex-search-forward-field bibtex-field-name end))))
          (if (and alternatives-there
!                  (not non-empty-alternative))
!             (progn
!               (goto-char beg)
!               (error "All alternatives are empty")))
!         (goto-char start)
!         (re-search-forward bibtex-entry-type end)
!         (let* ((begin-type (1+ (match-beginning 0)))
!                (end-type (match-end 0))
!                (entry-type
!                 (downcase
!                  (buffer-substring-no-properties begin-type end-type)))
!                (entry-list
!                 (assoc-ignore-case entry-type bibtex-entry-field-alist))
!                (req (elt (elt entry-list 1) 0))
!                (creq (elt (elt entry-list 2) 0))
!                (format (if (equal bibtex-entry-format t)
!                            '(realign opts-or-alts numerical-fields
!                                      last-comma page-dashes delimiters
!                                      unify-case inherit-booktitle)
!                          bibtex-entry-format))
!                field-done)
!           (if (memq 'unify-case format)
!               (progn
!                 (delete-region begin-type end-type)
!                 (insert (car entry-list))))
!           (if (memq 'delimiters format)
!               (progn
!                 (goto-char end-type)
!                 (skip-chars-forward " \t\n")
!                 (delete-char 1)
!                 (insert (bibtex-entry-left-delimiter))))
!           (goto-char start)
!           (let ((bounds (bibtex-search-forward-field bibtex-field-name end)))
!           (while bounds
!             (let* ((begin-field (copy-marker (bibtex-start-of-field bounds)))
!                    (end-field (copy-marker (bibtex-end-of-field bounds)))
!                    (begin-name (copy-marker (bibtex-start-of-name-in-field 
bounds)))
!                    (end-name (copy-marker (bibtex-end-of-name-in-field 
bounds)))
!                    (begin-text (copy-marker (bibtex-start-of-text-in-field 
bounds)))
!                    (end-text (copy-marker (bibtex-end-of-text-in-field 
bounds)))
!                    (field-name
!                     (buffer-substring-no-properties
!                      (if (string-match
!                           "^\\(OPT\\)\\|\\(ALT\\)$"
!                           (buffer-substring-no-properties
!                            begin-name (+ begin-name 3)))
!                          (+ begin-name 3)
!                        begin-name)
!                      end-name)))
!               (cond
!                ((and
!                  (memq 'opts-or-alts format)
!                  (progn (goto-char begin-name)
!                         (looking-at "OPT\\|ALT")))
!                 (goto-char begin-text)
!                 (if (looking-at "\\(\"\"\\)\\|\\({}\\)")
!                     ;; empty: delete whole field if really optional
!                     ;; (missing crossref handled) or complain
!                     (if (and
!                          (progn
!                            (goto-char begin-name)
!                            (looking-at "OPT"))
!                          (not crossref-there)
!                          (assoc-ignore-case field-name req))
!                         ;; field is not really optional
!                         (progn
!                           (goto-char begin-name)
!                           (bibtex-remove-OPT-or-ALT)
!                           (error
!                            "Mandatory field ``%s'' is empty" field-name))
!                       ;; field is optional
!                       (delete-region begin-field end-field))
!                   ;; otherwise: not empty, delete "OPT"
!                   (goto-char begin-name)
!                   (bibtex-remove-OPT-or-ALT)))
!                ((and
!                  (memq 'numerical-fields format)
!                  (progn
!                    (goto-char begin-text)
!                    (looking-at "\\(\"[0-9]+\"\\)\\|\\({[0-9]+}\\)")))
!                 (goto-char end-text)
!                 (delete-char -1)
!                 (goto-char begin-text)
!                 (delete-char 1))
!                (t
!                 (if (memq 'delimiters format)
!                     (bibtex-format-field-delimiters begin-text end-text))
!                 (if (and
!                      (memq 'page-dashes format)
!                      (string-match "^\\(OPT\\)?pages$" (downcase field-name))
!                      (progn
!                        (goto-char begin-text)
!                        (looking-at
!                         "\\([\"{][0-9]+\\)[ \t\n]*--?[ 
\t\n]*\\([0-9]+[\"}]\\)")))
!                     (replace-match "\\1-\\2"))
!                 (if (and
!                      (memq 'inherit-booktitle format)
!                      (equal (downcase field-name) "booktitle")
!                      (progn
!                        (goto-char begin-text)
!                        (looking-at "\\(\"\"\\)\\|\\({}\\)"))
!                      crossref-there
!                      (not (bibtex-find-entry-location crossref-there t)))
!                     ;; booktitle field empty and crossref entry found
!                     ;; --> insert title field of crossreferenced entry if 
there
!                     (let ((stop (bibtex-end-of-entry)))
!                       (bibtex-beginning-of-entry)
!                       (let ((bounds (bibtex-search-forward-field "title" 
stop)))
!                         (if bounds
!                             (progn
!                               (goto-char begin-text)
!                               (forward-char)
!                               (insert
!                                (buffer-substring-no-properties
!                                 (1+ (bibtex-start-of-text-in-field bounds))
!                                 (1- (bibtex-end-of-text-in-field 
bounds)))))))))
!                 (if (progn
!                       (goto-char begin-text)
!                       (looking-at "\\(\"\"\\)\\|\\({}\\)"))
!                     ;; if empty field, complain
!                     (progn
!                       (forward-char)
!                       (if (or (and
!                                crossref-there
!                                (assoc-ignore-case
!                                 field-name creq))
!                               (and
!                                (not crossref-there)
!                                (assoc-ignore-case
!                                 field-name req)))
!                           (error
!                            "Mandatory field ``%s'' is empty" field-name))))
!                 (if (memq 'unify-case format)
!                     (let* ((fl
!                             (car (cdr (assoc-ignore-case
!                                        entry-type
!                                        bibtex-entry-field-alist))))
!                            (field-list
!                             (append
!                              (elt fl 0)
!                              (elt fl 1)
!                              bibtex-user-optional-fields))
!                            (new-field-name
!                             (car
!                              (assoc-ignore-case field-name field-list))))
!                       (goto-char begin-name)
!                       (if new-field-name
!                           (progn
!                             (delete-region begin-name end-name)
!                             (insert new-field-name))
!                         (downcase-region begin-name end-name))))
!                 (setq field-done t)))
!               (if (not field-done)
!                   (goto-char begin-field)
!                 (setq field-done nil)
!                 (goto-char end-field)))
!             (setq bounds (bibtex-search-forward-field bibtex-field-name 
end))))
!           (if (looking-at (bibtex-field-right-delimiter))
!               (forward-char))
!           (if (memq 'last-comma format)
!               (cond ((and
!                       bibtex-comma-after-last-field
!                       (not (looking-at ",")))
!                      (insert ","))
!                     ((and
!                       (not bibtex-comma-after-last-field)
!                       (looking-at ","))
!                      (delete-char 1))))
!           (if (looking-at ",")
!               (forward-char))
!           (if (memq 'delimiters format)
!               (progn
!                 (skip-chars-forward " \t\n")
!                 (delete-char 1)
!                 (insert (bibtex-entry-right-delimiter))))
!           (if (memq 'realign format)
!               (bibtex-fill-entry)))))))
! 
! (defun bibtex-autokey-change (string change-list)
!   ;; Returns a string where some regexps are changed according to
!   ;; change-list. Every item of change-list is an (old-regexp
!   ;; new-string) pair.
!   (let* (case-fold-search
!        (return-string string)
!        (index 0)
!        (len (length change-list))
!        change-item)
!     (while (< index len)
!       (setq change-item (elt change-list index))
!       (while (string-match (car change-item) return-string)
!         (setq
!          return-string
!          (concat (substring return-string 0 (match-beginning 0))
!                  (elt change-item 1)
!                  (substring return-string (match-end 0)))))
!       (setq index (1+ index)))
!     return-string))
  
  (defun bibtex-autokey-abbrev (string len)
!   ;; Returns an abbreviation of string with at least len
!   ;; characters.  String is aborted only after a consonant or at the
!   ;; word end.  If len is not a number, string is returned unchanged.
!   (cond ((or
!           (not (numberp len))
!           (<= (length string) len))
           string)
          ((equal len 0)
           "")
!         (t
!          (let* ((case-fold-search t)
!                 (abort-char
!                  (string-match "[^aeiou]" string (1- len))))
!            (if abort-char
!                (substring string 0 (1+ abort-char))
!              string)))))
! 
! (defun bibtex-autokey-get-namefield (min max)
!   ;; returns the contents of the name field of the current entry
!   ;; does some modifications based on `bibtex-autokey-name-change-strings'
!   ;; and removes newlines unconditionally
!   (goto-char min)
!   (let* ((case-fold-search t)
!        (author-or-editor "\\(author\\)\\|\\(editor\\)")
!        (bounds (bibtex-search-forward-field author-or-editor max)))
!     (if bounds
!         (bibtex-autokey-change
!          (buffer-substring-no-properties
!           (1+ (bibtex-start-of-text-in-field bounds))
!           (1- (bibtex-end-of-text-in-field bounds)))
!          (append bibtex-autokey-name-change-strings '(("\n" " "))))
!       "")))
! 
! (defun bibtex-autokey-get-names (namefield)
!   ;; gathers all names in namefield into a list
!   (let* ((case-fold-search t)
!        names)
!     (while (not (equal namefield ""))
!       (let (name)
!         (if (string-match "[ \t\n]and[ \t\n]" namefield)
!             (setq name (substring namefield 0 (match-beginning 0))
!                   namefield (substring namefield (match-end 0)))
!           (setq name namefield
!                 namefield ""))
!         (setq names (append names (list name)))))
!     names))
  
  (defun bibtex-autokey-demangle-name (fullname)
!   ;; gets the `last' part from a well-formed name
!   (let* (case-fold-search
!          (lastname
!           (if (string-match "," fullname)
!               ;; name is of the form "von Last, First" or
!               ;; "von Last, Jr, First"
!               ;; --> take only the part before the comma
!               (let ((von-last
!                      (substring fullname 0 (match-beginning 0))))
!                 (if (string-match "^[a-z]" von-last)
!                     ;; von-last has a "von" part --> take the "last" part
!                     (if (string-match "[ \t][A-Z]" von-last)
!                         (substring von-last (1+ (match-beginning 0)))
!                       (error
!                        "Name %s is incorrectly formed" fullname))
!                   ;; von-last has no "von" part --> take all
!                   von-last))
!             ;; name is of the form "First von Last"
!             (if (string-match "[ \t]" fullname)
!                 ;; more than one token
!                 (if (string-match "[ \t][a-z]" fullname)
!                     ;; there is a "von" part
!                     ;; --> take everything after that
!                     (if (string-match
!                          "[ \t][A-Z]" fullname (match-end 0))
!                         (substring fullname (1+ (match-beginning 0)))
!                       (error
!                        "Name %s is incorrectly formed" fullname))
!                   ;; there is no "von" part --> take only the last token
!                   (if (string-match " [^ ]*$" fullname)
!                       (substring fullname (1+ (match-beginning 0)))
!                     (error "Name %s is incorrectly formed" fullname)))
!               ;; only one token --> take it
!               fullname)))
!          (usename
!           (if (string-match "[ \t]+" lastname)
!               ;; lastname consists of two or more tokens
!               ;; --> take only the first one
!               (substring lastname 0 (match-beginning 0))
!             lastname)))
!     (funcall bibtex-autokey-name-case-convert usename)))
! 
! (defun bibtex-autokey-get-namelist (namefield)
!   ;; gets namefield, performs abbreviations on the last parts, and
!   ;; return results as a list
!   (mapcar
!    (lambda (fullname)
!      (setq
!       fullname (substring fullname (string-match "[^ \t]" fullname)))
!      (bibtex-autokey-abbrev
!       (bibtex-autokey-demangle-name fullname)
!       bibtex-autokey-name-length))
!    (bibtex-autokey-get-names namefield)))
! 
! (defun bibtex-autokey-get-yearfield-digits (max)
!   ;; get digit substring from year field.
!   (let ((bounds (bibtex-search-forward-field "year" max)))
!     (if bounds
!       (let ((year (buffer-substring-no-properties
!                    (bibtex-start-of-text-in-field bounds)
!                    (bibtex-end-of-text-in-field bounds))))
!         (string-match "[^0-9]*\\([0-9]+\\)" year)
!         (substring year (match-beginning 1) (match-end 1)))
!       "")))
! 
! (defun bibtex-autokey-get-yearfield (min max)
!   ;; get year field from current or maybe crossreferenced entry
!   (goto-char min)
!   (let* ((case-fold-search t)
!        (year (bibtex-autokey-get-yearfield-digits max)))
!     (if (and (string= year "") bibtex-autokey-year-use-crossref-entry)
!       (let* ((bounds
!               (bibtex-search-forward-field "\\(OPT\\)?crossref" max))
!              (crossref-field
!               (if bounds
!                   (buffer-substring-no-properties
!                    (1+ (bibtex-start-of-text-in-field bounds))
!                    (1- (bibtex-end-of-text-in-field bounds))))))
!         (if (not (bibtex-find-entry-location crossref-field t))
!             (let ((stop (bibtex-end-of-entry)))
!               (bibtex-beginning-of-entry)
!               (bibtex-autokey-get-yearfield-digits stop))
!           ""))
!       year)))
! 
! (defun bibtex-autokey-get-titlestring (min max)
!   ;; get title field contents up to a terminator
!   (goto-char min)
!   (let* ((case-fold-search t)
!        (bounds (bibtex-search-forward-field "title" max))
!        (titlefield
!         (if bounds
!             (bibtex-autokey-change
!              (buffer-substring-no-properties
!               (1+ (bibtex-start-of-text-in-field bounds))
!               (1- (bibtex-end-of-text-in-field bounds)))
!              bibtex-autokey-titleword-change-strings)
!           ""))
!        (title-terminators bibtex-autokey-title-terminators))
!     (while (not (null title-terminators))
!       (if (string-match (car title-terminators) titlefield)
!         (setq titlefield (substring titlefield 0 (match-beginning 0))))
!       (setq title-terminators (cdr title-terminators)))
!     titlefield))
! 
! (defun bibtex-autokey-get-titles (titlestring)
!   ;; gathers words from titlestring into a list. Ignores
!   ;; specific words and uses only a specific amount of words.
    (let* (case-fold-search
!        titlewords
!        titlewords-extra
!        (counter 0))
!     (while (and
!             (not (equal titlestring ""))
!             (or
!              (not (numberp bibtex-autokey-titlewords))
!              (< counter
!                 (+ bibtex-autokey-titlewords
!                    bibtex-autokey-titlewords-stretch))))
!       (if (string-match "\\b\\w+" titlestring)
!           (let* ((end-match (match-end 0))
!                  (titleword
!                 (substring titlestring (match-beginning 0) end-match)))
!           (if (bibtex-member-of-regexp
!                titleword
!                bibtex-autokey-titleword-ignore)
!               (setq counter (1- counter))
!               (setq
!              titleword
!              (funcall bibtex-autokey-titleword-case-convert titleword))
!             (if (or (not (numberp bibtex-autokey-titlewords))
!                     (< counter bibtex-autokey-titlewords))
!                 (setq titlewords (append titlewords (list titleword)))
!               (setq titlewords-extra
!                     (append titlewords-extra (list titleword)))))
!             (setq
!              titlestring (substring titlestring end-match)))
!         (setq titlestring ""))
!       (setq counter (1+ counter)))
!     (if (string-match "\\b\\w+" titlestring)
!         titlewords
!       (append titlewords titlewords-extra))))
! 
! (defun bibtex-autokey-get-titlelist (titlestring)
!   ;; returns all words in titlestring as a list
!   ;; does some abbreviation on the found words
!   (mapcar
!    (lambda (titleword)
!      (let ((abbrev
!             (bibtex-assoc-of-regexp
!              titleword bibtex-autokey-titleword-abbrevs)))
!        (if abbrev
!            (elt abbrev 1)
!          (bibtex-autokey-abbrev
!           titleword
!           bibtex-autokey-titleword-length))))
!    (bibtex-autokey-get-titles titlestring)))
  
  (defun bibtex-generate-autokey ()
!   "Generates automatically a key from the author/editor and the title field.
  This will only work for entries where each field begins on a separate line.
  The generation algorithm works as follows:
   1. Use the value of `bibtex-autokey-prefix-string' as a prefix.
--- 1747,2094 ----
          (message "Mark set")
          (insert (elt current 1)))
         (t
!         (error "Unknown tag field: %s.  Please submit a bug report"
!                bibtex-last-kill-command))))))
  
  (defun bibtex-format-entry ()
!   "Helper function for `bibtex-clean-entry'.
! Formats current entry according to variable `bibtex-entry-format'."
!   (save-excursion
!     (save-restriction
!       (bibtex-narrow-to-entry)
!       (let ((case-fold-search t)
!             (format (if (equal bibtex-entry-format t)
!                         '(realign opts-or-alts required-fields
!                                   numerical-fields
!                                   last-comma page-dashes delimiters
!                                   unify-case inherit-booktitle)
!                       bibtex-entry-format))
!             crossref-key bounds alternatives-there non-empty-alternative
!             entry-list req creq field-done field-list)
! 
!         ;; identify entry type
!         (goto-char (point-min))
!         (re-search-forward bibtex-entry-type)
!         (let ((beg-type (1+ (match-beginning 0)))
!               (end-type (match-end 0)))
!           (setq entry-list (assoc-ignore-case (buffer-substring-no-properties
!                                                beg-type end-type)
!                                               bibtex-entry-field-alist)
!                 req  (nth 0 (nth 1 entry-list))  ; required part
!                 creq (nth 0 (nth 2 entry-list))) ; crossref part
! 
!           ;; unify case of entry name
!           (when (memq 'unify-case format)
!             (delete-region beg-type end-type)
!             (insert (car entry-list)))
! 
!           ;; update left entry delimiter
!           (when (memq 'delimiters format)
!             (goto-char end-type)
!             (skip-chars-forward " \t\n")
!             (delete-char 1)
!             (insert (bibtex-entry-left-delimiter))))
! 
!         ;; determine if entry has crossref field and if at least
!         ;; one alternative is non-empty
!         (goto-char (point-min))
!         (while (setq bounds (bibtex-search-forward-field
!                              bibtex-field-name))
!           (goto-char (bibtex-start-of-name-in-field bounds))
!           (cond ((looking-at "ALT")
!                  (setq alternatives-there t)
!                  (goto-char (bibtex-start-of-text-in-field bounds))
!                  (if (not (looking-at bibtex-empty-field-re))
!                      (setq non-empty-alternative t)))
!                 ((and (looking-at "\\(OPT\\)?crossref\\>")
!                       (progn (goto-char (bibtex-start-of-text-in-field 
bounds))
!                              (not (looking-at bibtex-empty-field-re))))
!                  (setq crossref-key
!                        (bibtex-text-in-field-bounds bounds t))))
!           (goto-char (bibtex-end-of-field bounds)))
          (if (and alternatives-there
!                  (not non-empty-alternative)
!                  (memq 'required-fields format))
!             (error "All alternatives are empty"))
! 
!         ;; process all fields
!         (goto-char (point-min))
!         (while (setq bounds (bibtex-search-forward-field bibtex-field-name))
!           (let* ((beg-field (copy-marker (bibtex-start-of-field bounds)))
!                  (end-field (copy-marker (bibtex-end-of-field bounds)))
!                  (beg-name  (copy-marker (bibtex-start-of-name-in-field 
bounds)))
!                  (end-name  (copy-marker (bibtex-end-of-name-in-field 
bounds)))
!                  (beg-text  (copy-marker (bibtex-start-of-text-in-field 
bounds)))
!                  (end-text  (copy-marker (bibtex-end-of-text-in-field 
bounds)))
!                  (opt-alt   (string-match "OPT\\|ALT"
!                                           (buffer-substring-no-properties 
beg-name (+ beg-name 3))))
!                  (field-name (buffer-substring-no-properties
!                               (if opt-alt (+ beg-name 3) beg-name) end-name))
!                  (empty-field (string-match bibtex-empty-field-re
!                                             (buffer-substring-no-properties 
beg-field end-field)))
!                  deleted)
! 
!             ;; We have more elegant high-level functions for several
!             ;; tasks done by bibtex-format-entry. However, they contain
!             ;; quite some redundancy compared with what we need to do
!             ;; anyway. So for speed-up we avoid using them.
! 
!             (when (and opt-alt
!                        (memq 'opts-or-alts format))
!               (if empty-field
!                   ;; Either it is an empty ALT field. Then we have checked
!                   ;; already that we have one non-empty alternative.
!                   ;; Or it is an empty OPT field that we do not miss anyway.
!                   ;; So we can safely delete this field.
!                   (progn (delete-region beg-field end-field)
!                          (setq deleted t))
!                 ;; otherwise: not empty, delete "OPT" or "ALT"
!                 (goto-char beg-name)
!                 (delete-char 3)))
! 
!             (unless deleted
!               (push field-name field-list)
! 
!               ;; remove delimiters from purely numerical fields
!               (when (and (memq 'numerical-fields format)
!                          (progn (goto-char beg-text)
!                                 (looking-at 
"\\(\"[0-9]+\"\\)\\|\\({[0-9]+}\\)")))
!                 (goto-char end-text)
!                 (delete-char -1)
!                 (goto-char beg-text)
!                 (delete-char 1))
! 
!               ;; update delimiters
!               (when (memq 'delimiters format)
!                 (goto-char beg-text)
!                 (when (looking-at "[{\"]")
!                   (delete-char 1)
!                   (insert (bibtex-field-left-delimiter)))
!                 (goto-char (1- (marker-position end-text)))
!                 (when (looking-at "[}\"]")
!                   (delete-char 1)
!                   (insert (bibtex-field-right-delimiter))))
! 
!               ;; update page dashes
!               (if (and (memq 'page-dashes format)
!                        (string-match "\\`\\(OPT\\)?pages\\'" field-name)
!                        (progn (goto-char beg-text)
!                               (looking-at
!                                "\\([\"{][0-9]+\\)[ \t\n]*--?[ 
\t\n]*\\([0-9]+[\"}]\\)")))
!                   (replace-match "\\1-\\2"))
! 
!               ;; use book title of crossref'd entry
!               (if (and (memq 'inherit-booktitle format)
!                        empty-field
!                        (equal (downcase field-name) "booktitle")
!                        crossref-key)
!                   (let ((title (save-restriction
!                                  (widen)
!                                  (if (bibtex-find-entry crossref-key)
!                                      (bibtex-text-in-field "title")))))
!                     (when title
!                       (setq empty-field nil)
!                       (goto-char (1+ beg-text))
!                       (insert title))))
! 
!             ;; Use booktitle to set a missing title.
!             (if (and empty-field
!                      (equal (downcase field-name) "title"))
!                 (let ((booktitle (bibtex-text-in-field "booktitle")))
!                   (when booktitle
!                     (setq empty-field nil)
!                     (goto-char (1+ beg-text))
!                     (insert booktitle))))
! 
!               ;; if empty field, complain
!               (if (and empty-field
!                        (memq 'required-fields format)
!                        (assoc-ignore-case field-name
!                                           (if crossref-key creq req)))
!                   (error "Mandatory field `%s' is empty" field-name))
! 
!               ;; unify case of field name
!               (if (memq 'unify-case format)
!                   (let ((fname (car (assoc-ignore-case
!                                      field-name (append (nth 0 (nth 1 
entry-list))
!                                                         (nth 1 (nth 1 
entry-list))
!                                                         
bibtex-user-optional-fields)))))
!                     (if fname
!                         (progn
!                           (delete-region beg-name end-name)
!                           (goto-char beg-name)
!                           (insert fname))
!                       ;; there are no rules we could follow
!                       (downcase-region beg-name end-name))))
! 
!               ;; update point
!               (goto-char end-field))))
! 
!         ;; check whether all required fields are present
!         (if (memq 'required-fields format)
!             (let (altlist (found 0))
!               (dolist (fname (if crossref-key creq req))
!                 (if (nth 3 fname)
!                     (push (car fname) altlist))
!                 (unless (or (member (car fname) field-list)
!                             (nth 3 fname))
!                   (error "Mandatory field `%s' is missing" (car fname))))
!               (when altlist
!                 (dolist (fname altlist)
!                   (if (member fname field-list)
!                       (setq found (1+ found))))
!                 (cond ((= found 0)
!                        (error "Alternative mandatory field `%s' is missing"
!                               altlist))
!                       ((> found 1)
!                        (error "Alternative fields `%s' is defined %s times"
!                               altlist found))))))
! 
!         ;; update point
!         (if (looking-at (bibtex-field-right-delimiter))
!             (forward-char))
! 
!         ;; update comma after last field
!         (if (memq 'last-comma format)
!             (cond ((and bibtex-comma-after-last-field
!                         (not (looking-at ",")))
!                    (insert ","))
!                   ((and (not bibtex-comma-after-last-field)
!                         (looking-at ","))
!                    (delete-char 1))))
! 
!         ;; update right entry delimiter
!         (if (looking-at ",")
!             (forward-char))
!         (when (memq 'delimiters format)
!           (skip-chars-forward " \t\n")
!           (delete-char 1)
!           (insert (bibtex-entry-right-delimiter)))
! 
!         ;; fill entry
!         (if (memq 'realign format)
!             (bibtex-fill-entry))))))
  
+ 
  (defun bibtex-autokey-abbrev (string len)
!   "Return an abbreviation of STRING with at least LEN characters.
! If LEN is positive the abbreviation is terminated only after a consonant
! or at the word end. If LEN is negative the abbreviation is strictly
! enforced using abs (LEN) characters. If LEN is not a number, STRING
! is returned unchanged."
!   (cond ((or (not (numberp len))
!              (<= (length string) (abs len)))
           string)
          ((equal len 0)
           "")
!         ((< len 0)
!          (substring string 0 (abs len)))
!         (t (let* ((case-fold-search t)
!                   (abort-char (string-match "[^aeiou]" string (1- len))))
!              (if abort-char
!                  (substring string 0 (1+ abort-char))
!                string)))))
! 
! (defun bibtex-autokey-get-field (field &optional change-list)
!   "Get content of BibTeX field FIELD. Return empty string if not found.
! Optional arg CHANGE-LIST is a list of substitution patterns that is
! applied to the content of FIELD. It is an alist with pairs
! \(OLD-REGEXP . NEW-STRING\)."
!   (let ((content (bibtex-text-in-field field bibtex-autokey-use-crossref))
!         case-fold-search)
!     (unless content (setq content ""))
!     (dolist (pattern change-list content)
!       (setq content (replace-regexp-in-string (car pattern)
!                                               (cdr pattern)
!                                               content)))))
! 
! (defun bibtex-autokey-get-names ()
!   "Get contents of the name field of the current entry.
! Do some modifications based on `bibtex-autokey-name-change-strings'
! and return results as a list."
!   (let ((case-fold-search t))
!     (mapcar 'bibtex-autokey-demangle-name
!             (split-string (bibtex-autokey-get-field
!                            "author\\|editor"
!                            bibtex-autokey-name-change-strings)
!                           "[ \t\n]+and[ \t\n]+"))))
  
  (defun bibtex-autokey-demangle-name (fullname)
!   "Get the last part from a well-formed name and perform abbreviations."
    (let* (case-fold-search
!          (name (cond ((string-match "\\([A-Z][^, ]*\\)[^,]*," fullname)
!                       ;; Name is of the form "von Last, First" or
!                       ;; "von Last, Jr, First"
!                       ;; --> Take the first capital part before the comma
!                       (match-string 1 fullname))
!                      ((string-match "\\([^, ]*\\)," fullname)
!                       ;; Strange name: we have a comma, but nothing capital
!                       ;; So we accept even lowercase names
!                       (match-string 1 fullname))
!                      ((string-match "\\(\\<[a-z][^ ]* +\\)+\\([A-Z][^ ]*\\)"
!                                     fullname)
!                       ;; name is of the form "First von Last", "von Last",
!                       ;; "First von von Last", or "d'Last"
!                       ;; --> take the first capital part after the "von" parts
!                       (match-string 2 fullname))
!                      ((string-match "\\([^ ]+\\) *\\'" fullname)
!                       ;; name is of the form "First Middle Last" or "Last"
!                       ;; --> take the last token
!                       (match-string 1 fullname))
!                      (t (error "Name `%s' is incorrectly formed" fullname)))))
!     (bibtex-autokey-abbrev
!      (funcall bibtex-autokey-name-case-convert name)
!      bibtex-autokey-name-length)))
! 
! (defun bibtex-autokey-get-title ()
!   "Get title field contents up to a terminator."
!   (let ((titlestring
!          (bibtex-autokey-get-field "title"
!                                    bibtex-autokey-titleword-change-strings)))
!     ;; ignore everything past a terminator
!     (let ((case-fold-search t))
!       (dolist (terminator bibtex-autokey-title-terminators)
!         (if (string-match terminator titlestring)
!             (setq titlestring (substring titlestring 0 (match-beginning 
0))))))
!     ;; gather words from titlestring into a list. Ignore
!     ;; specific words and use only a specific amount of words.
!     (let (case-fold-search titlewords titlewords-extra titleword end-match
!                            (counter 0))
!       (while (and (or (not (numberp bibtex-autokey-titlewords))
!                       (< counter (+ bibtex-autokey-titlewords
!                                     bibtex-autokey-titlewords-stretch)))
!                   (string-match "\\b\\w+" titlestring))
!         (setq end-match (match-end 0)
!               titleword (substring titlestring
!                                    (match-beginning 0) end-match))
!         (unless (bibtex-member-of-regexp titleword
!                                          bibtex-autokey-titleword-ignore)
!           (setq titleword
!                 (funcall bibtex-autokey-titleword-case-convert titleword))
!           (if (or (not (numberp bibtex-autokey-titlewords))
!                   (< counter bibtex-autokey-titlewords))
!               (setq titlewords (append titlewords (list titleword)))
!             (setq titlewords-extra
!                   (append titlewords-extra (list titleword))))
!           (setq counter (1+ counter)))
!         (setq titlestring (substring titlestring end-match)))
!       (unless (string-match "\\b\\w+" titlestring)
!         (setq titlewords (append titlewords titlewords-extra)))
!       (mapcar 'bibtex-autokey-demangle-title titlewords))))
! 
! (defun bibtex-autokey-demangle-title (titleword)
!   "Do some abbreviations on TITLEWORD.
! The rules are defined in `bibtex-autokey-titleword-abbrevs'
! and `bibtex-autokey-titleword-length'."
!   (let ((abbrev (bibtex-assoc-of-regexp
!                  titleword bibtex-autokey-titleword-abbrevs)))
!     (if abbrev
!         (cdr abbrev)
!       (bibtex-autokey-abbrev titleword
!                              bibtex-autokey-titleword-length))))
  
  (defun bibtex-generate-autokey ()
!   "Generate automatically a key from the author/editor and the title field.
  This will only work for entries where each field begins on a separate line.
  The generation algorithm works as follows:
   1. Use the value of `bibtex-autokey-prefix-string' as a prefix.
***************
*** 2191,2199 ****
      the name field, determine the last name. If there are maximal
      `bibtex-autokey-names' + `bibtex-autokey-names-stretch'
      names, all names are used.
!  5. From every last name, take at least
!     `bibtex-autokey-name-length' characters (abort only after a
!     consonant or at a word end).
   6. Convert all last names according to the conversion function
      `bibtex-autokey-name-case-convert'.
   7. Build the name part of the key by concatenating all
--- 2101,2108 ----
      the name field, determine the last name. If there are maximal
      `bibtex-autokey-names' + `bibtex-autokey-names-stretch'
      names, all names are used.
!  5. From every last name, take at least `bibtex-autokey-name-length'
!     characters (abort only after a consonant or at a word end).
   6. Convert all last names according to the conversion function
      `bibtex-autokey-name-case-convert'.
   7. Build the name part of the key by concatenating all
***************
*** 2203,2212 ****
      contained in `bibtex-autokey-additional-names'.
   8. Build the year part of the key by truncating the contents of
      the year field to the rightmost `bibtex-autokey-year-length'
!     digits (useful values are 2 and 4). If the year field is
!     absent, but the entry has a valid crossref field and the
!     variable `bibtex-autokey-year-use-crossref-entry' is non-nil,
!     use the year field of the crossreferenced entry instead.
   9. For the title part of the key change the contents of the
      title field of the entry according to
      `bibtex-autokey-titleword-change-strings' to the
--- 2112,2122 ----
      contained in `bibtex-autokey-additional-names'.
   8. Build the year part of the key by truncating the contents of
      the year field to the rightmost `bibtex-autokey-year-length'
!     digits (useful values are 2 and 4). If the year field (or any
!     other field required to generate the key) is absent, but the entry
!     has a valid crossref field and the variable
!     `bibtex-autokey-use-crossref' is non-nil, use the field of the
!     crossreferenced entry instead.
   9. For the title part of the key change the contents of the
      title field of the entry according to
      `bibtex-autokey-titleword-change-strings' to the
***************
*** 2251,2552 ****
      the key is then presented in the minibuffer to the user,
      where it can be edited.  The key given by the user is then
      used."
!   (let* ((pnt (point))
!          (min (bibtex-beginning-of-entry))
!          (max (bibtex-end-of-entry))
!          (namefield (bibtex-autokey-get-namefield min max))
!          (name-etal "")
           (namelist
!           (let ((nl (bibtex-autokey-get-namelist namefield)))
              (if (or (not (numberp bibtex-autokey-names))
                      (<= (length nl)
                          (+ bibtex-autokey-names
                             bibtex-autokey-names-stretch)))
                  nl
                (setq name-etal bibtex-autokey-additional-names)
!               (let (nnl)
!                 (while (< (length nnl) bibtex-autokey-names)
!                   (setq nnl (append nnl (list (car nl)))
!                         nl (cdr nl)))
!                 nnl))))
!          (namepart
!           (concat
!            (mapconcat (lambda (name) name)
!                       namelist
!                       bibtex-autokey-name-separator)
!            name-etal))
!          (yearfield (bibtex-autokey-get-yearfield min max))
!          (yearpart
!           (if (equal yearfield "")
!               ""
!             (substring
!              yearfield
!              (- (length yearfield) bibtex-autokey-year-length))))
!          (titlestring (bibtex-autokey-get-titlestring min max))
!          (titlelist (bibtex-autokey-get-titlelist titlestring))
!          (titlepart
!           (mapconcat
!            (lambda (name) name)
!            titlelist
!            bibtex-autokey-titleword-separator))
!          (autokey
!           (concat
!            bibtex-autokey-prefix-string
!            namepart
!            (if (not
!                 (or
!                  (equal namepart "")
!                  (equal yearpart "")))
!                bibtex-autokey-name-year-separator)
!            yearpart
!            (if (not
!                 (or
!                  (and
!                   (equal namepart "")
!                   (equal yearpart ""))
!                  (equal titlepart "")))
!                bibtex-autokey-year-title-separator)
!            titlepart)))
      (if bibtex-autokey-before-presentation-function
!         (setq
!          autokey
!          (funcall bibtex-autokey-before-presentation-function autokey)))
!     (goto-char pnt)
!     autokey))
! 
! (defun bibtex-parse-keys (add verbose &optional abortable)
!   ;; Sets bibtex-reference-keys to the keys used in the whole (possibly
!   ;; restricted) buffer (either as entry keys or as crossref entries).
!   ;; If ADD is non-nil adds the new keys to bibtex-reference-keys instead of
!   ;; simply resetting it. If VERBOSE is non-nil gives messages about
!   ;; progress. If ABORTABLE is non-nil abort on user input.
!   (if bibtex-maintain-sorted-entries
!       (let* ((case-fold-search t)
!            (reference-keys (if add bibtex-reference-keys)))
!         (save-excursion
!           (save-match-data
!             (goto-char (point-min))
!             (if verbose
!                 (bibtex-progress-message
!                  (concat (buffer-name) ": parsing reference keys")))
!             (if (catch 'userkey
!                   (bibtex-skip-to-valid-entry)
!                   (while (not (eobp))
!                     (if (and
!                          abortable
!                          (input-pending-p))
!                         (throw 'userkey t))
!                     (if verbose
!                         (bibtex-progress-message))
!                     (let (reference-key
!                           xrefd-reference-key)
!                       (cond
!                        ((looking-at bibtex-entry-head)
!                         (setq
!                          reference-key
!                          (buffer-substring-no-properties
!                           (match-beginning bibtex-key-in-head)
!                           (match-end bibtex-key-in-head)))
!                         (let ((p (point))
!                               (m (bibtex-end-of-entry)))
!                           (goto-char p)
!                           (let ((bounds (bibtex-search-forward-field 
"crossref" m)))
!                             (if bounds
!                                 (setq
!                                  xrefd-reference-key
!                                  (buffer-substring-no-properties
!                                   (1+ (bibtex-start-of-text-in-field bounds))
!                                   (1- (bibtex-end-of-text-in-field 
bounds))))))))
!                        ((bibtex-parse-string)
!                         (let ((bounds (bibtex-parse-string)))
!                           (setq
!                            reference-key
!                            (buffer-substring-no-properties
!                             (bibtex-start-of-reference-key-in-string bounds)
!                             (bibtex-end-of-reference-key-in-string 
bounds))))))
!                       (forward-char)
!                       (bibtex-skip-to-valid-entry)
!                       (if (not (assoc reference-key reference-keys))
!                           (setq reference-keys
!                                 (cons (list reference-key) reference-keys)))
!                       (if (and xrefd-reference-key
!                                (not (assoc xrefd-reference-key 
reference-keys)))
!                           (setq reference-keys
!                                 (cons (list xrefd-reference-key) 
reference-keys))))))
!                 ;; user has aborted by typing a key --> return nil
!                 nil
!               ;; successful operation --> return t
!               (setq
!                bibtex-buffer-last-parsed-tick (buffer-modified-tick)
!                bibtex-reference-keys reference-keys)
!               (if verbose
!                   (bibtex-progress-message 'done))
!               t))))))
  
! (defun bibtex-parse-buffers-stealthily ()
!   ;; Called by bibtex-run-with-idle-timer. Whenever emacs has been idle
!   ;; for bibtex-parse-keys-timeout seconds, all BibTeX buffers (starting
!   ;; with the current) are parsed.
!   (let ((buffers (buffer-list)))
      (save-excursion
        (while (and buffers (not (input-pending-p)))
          (set-buffer (car buffers))
!         (save-restriction
!           (widen)
!           (if (and
!                (eq major-mode 'bibtex-mode)
!                bibtex-maintain-sorted-entries
!                (not
!                 (eq (buffer-modified-tick)
!                     bibtex-buffer-last-parsed-tick)))
!             ;; Output no progress messages in bibtex-parse-keys
!             ;; because when in y-or-n-p that can hide the question.
!               (if (bibtex-parse-keys nil nil t)
!                   ;; successful operation --> remove buffer from list
!                   (setq buffers (cdr buffers)))
!             ;; buffer is no BibTeX buffer or needs no parsing
!             (setq buffers (cdr buffers))))))))
! 
! (defun bibtex-complete (string-list &optional complete-strings)
!   ;; Complete word fragment before point to longest prefix of one
!   ;; string defined in STRING-LIST. If point is not after the part of
!   ;; a word, all strings are listed. If COMPLETE-STRINGS is non-nil,
!   ;; add the strings defined in this buffer before cursor to
!   ;; STRING-LIST and remove surrounding delimiters if complete string
!   ;; could be expanded.
    (let* ((case-fold-search t)
-          (end (point))
           (beg (save-excursion
                  (re-search-backward "[ \t{\"]")
                  (forward-char)
                  (point)))
           (part-of-word (buffer-substring-no-properties beg end))
!          (completions (copy-sequence string-list))
!          (completion (save-excursion
!                        (if complete-strings
!                            (while (bibtex-search-backward-string)
!                            (let ((bounds (bibtex-search-backward-string)))
!                              (setq completions
!                                    (cons
!                                     (list
!                                      (buffer-substring-no-properties
!                                       
(bibtex-start-of-reference-key-in-string bounds)
!                                       (bibtex-end-of-reference-key-in-string 
bounds)))
!                                     completions)))))
!                        (setq completions
!                              (sort completions
!                                    (lambda(x y)
!                                      (string-lessp
!                                       (car x)
!                                       (car y)))))
!                        (try-completion part-of-word completions))))
!     (cond ((eq completion t)
!            (if complete-strings
!                ;; remove double-quotes or braces if field is no concatenation
!                (save-excursion
!                  (bibtex-inside-field)
!                  (let* ((bounds (bibtex-enclosing-field)))
!                  (goto-char (bibtex-start-of-text-in-field bounds))
!                  (let ((boundaries (bibtex-parse-field-string)))
!                    (if (and boundaries (equal (cdr boundaries) 
(bibtex-end-of-text-in-field bounds)))
!                        (bibtex-remove-delimiters)))))))
!           ((not completion)
!            (error "Can't find completion for \"%s\"" part-of-word))
            ((not (string= part-of-word completion))
             (delete-region beg end)
             (insert completion)
!            (if (and (assoc completion completions)
!                     complete-strings)
!                ;; remove double-quotes or braces if field is no concatenation
!                (save-excursion
!                  (bibtex-inside-field)
!                (let* ((bounds (bibtex-enclosing-field)))
!                  (goto-char (bibtex-start-of-text-in-field bounds))
!                  (let ((boundaries (bibtex-parse-field-string)))
!                    (if (and boundaries (equal (cdr boundaries) 
(bibtex-end-of-text-in-field bounds)))
!                        (bibtex-remove-delimiters)))))))
            (t
             (message "Making completion list...")
!            (let ((list (all-completions part-of-word completions)))
!              (with-output-to-temp-buffer "*Completions*"
!                (display-completion-list list)))
!            (message "Making completion list...done")))))
! 
! (defun bibtex-do-auto-fill ()
!   (let ((fill-prefix
!          (make-string
!           (+ bibtex-entry-offset bibtex-contline-indentation) ? )))
!     (do-auto-fill)))
  
  (defun bibtex-pop (arg direction)
!   ;; generic function to be used by bibtex-pop-previous and bibtex-pop-next
    (let (bibtex-help-message)
      (bibtex-find-text nil))
    (save-excursion
      ;; parse current field
      (bibtex-inside-field)
      (let* ((case-fold-search t)
!          (bounds (bibtex-enclosing-field))
!          (start-old-text (bibtex-start-of-text-in-field bounds))
!          (stop-old-text (bibtex-end-of-text-in-field bounds))
!          (start-name (bibtex-start-of-name-in-field bounds))
!          (stop-name (bibtex-end-of-name-in-field bounds))
!          (new-text))
!       (goto-char start-name)
!       ;; construct regexp for field with same name as this one,
!       ;; ignoring possible OPT's or ALT's
!       (let* ((field-name
!             (buffer-substring-no-properties
!              (if (looking-at "\\(OPT\\)\\|\\(ALT\\)")
!                  (match-end 0)
!                (point))
!              stop-name)))
!       ;; if executed several times in a row, start each search where
!         ;; the last one was finished
!       (cond ((eq last-command 'bibtex-pop) t)
!             (t
!              (bibtex-enclosing-entry-maybe-empty-head)
!              (setq
!                 bibtex-pop-previous-search-point (match-beginning 0)
!                 bibtex-pop-next-search-point (point))))
!       (if (eq direction 'previous)
!             (goto-char bibtex-pop-previous-search-point)
!           (goto-char bibtex-pop-next-search-point))
!         ;; Now search for arg'th previous/next similar field
!       (let ((bounds nil)
!             (failure nil))
!         (while (and (not failure) (> arg 0))
!           (cond ((eq direction 'previous)
!                  (setq bounds (bibtex-search-backward-field field-name 
(point-min)))
!                  (if bounds
!                      (goto-char (bibtex-start-of-field bounds))
!                    (setq failure t)))
!                 ((eq direction 'next)
!                  (setq bounds (bibtex-search-forward-field field-name 
(point-max)))
!                  (if bounds
!                      (goto-char (bibtex-end-of-field bounds))
!                    (setq failure t))))
!           (setq arg (- arg 1)))
!         (if failure
!             (error (if (eq direction 'previous)
!                        "No previous matching BibTeX field."
!                      "No next matching BibTeX field."))
!           ;; Found a matching field. Remember boundaries.
!           (setq bibtex-pop-previous-search-point (bibtex-start-of-field 
bounds))
!           (setq bibtex-pop-next-search-point (bibtex-end-of-field bounds))
!           (setq new-text
!                 (buffer-substring-no-properties
!                  (bibtex-start-of-text-in-field bounds)
!                  (bibtex-end-of-text-in-field bounds)))
!           (bibtex-flash-head)
!           ;; Go back to where we started, delete old text, and pop new.
!           (goto-char stop-old-text)
!           (delete-region start-old-text stop-old-text)
!           (insert new-text))))))
    (let (bibtex-help-message)
      (bibtex-find-text nil))
    (setq this-command 'bibtex-pop))
  
  
  ;; Interactive Functions:
  
--- 2161,2496 ----
      the key is then presented in the minibuffer to the user,
      where it can be edited.  The key given by the user is then
      used."
!   (let* ((name-etal "")
           (namelist
!           (let ((nl (bibtex-autokey-get-names))
!                 nnl)
              (if (or (not (numberp bibtex-autokey-names))
                      (<= (length nl)
                          (+ bibtex-autokey-names
                             bibtex-autokey-names-stretch)))
                  nl
                (setq name-etal bibtex-autokey-additional-names)
!               (while (< (length nnl) bibtex-autokey-names)
!                 (setq nnl (append nnl (list (car nl)))
!                       nl (cdr nl)))
!               nnl)))
!          (namepart (concat (mapconcat 'identity
!                                       namelist
!                                       bibtex-autokey-name-separator)
!                            name-etal))
!          (yearfield (bibtex-autokey-get-field "year"))
!          (yearpart (if (equal yearfield "")
!                        ""
!                      (substring yearfield
!                                 (- (length yearfield)
!                                    bibtex-autokey-year-length))))
!          (titlepart (mapconcat 'identity
!                                (bibtex-autokey-get-title)
!                                bibtex-autokey-titleword-separator))
!          (autokey (concat bibtex-autokey-prefix-string
!                           namepart
!                           (unless (or (equal namepart "")
!                                       (equal yearpart ""))
!                             bibtex-autokey-name-year-separator)
!                           yearpart
!                           (unless (or (and (equal namepart "")
!                                            (equal yearpart ""))
!                                       (equal titlepart ""))
!                             bibtex-autokey-year-title-separator)
!                           titlepart)))
      (if bibtex-autokey-before-presentation-function
!         (funcall bibtex-autokey-before-presentation-function autokey)
!       autokey)))
  
! 
! (defun bibtex-parse-keys (&optional add abortable verbose)
!   "Set `bibtex-reference-keys' to the keys used in the whole buffer.
! The buffer might possibly be restricted.
! Find both entry keys and crossref entries.
! If ADD is non-nil add the new keys to `bibtex-reference-keys' instead of
! simply resetting it. If ADD is an alist of keys, also add ADD to
! `bibtex-reference-keys'. If ABORTABLE is non-nil abort on user
! input. If VERBOSE is non-nil gives messages about progress.
! Return alist of keys if parsing was completed, `aborted' otherwise."
!   (let ((reference-keys (if (and add
!                                  (listp bibtex-reference-keys))
!                             bibtex-reference-keys)))
!     (if (listp add)
!         (dolist (key add)
!           (unless (assoc (car key) reference-keys)
!                       (push key reference-keys))))
      (save-excursion
+       (save-match-data
+         (if verbose
+             (bibtex-progress-message
+              (concat (buffer-name) ": parsing reference keys")))
+         (catch 'userkey
+           (goto-char (point-min))
+           (if bibtex-parse-keys-fast
+               (let ((case-fold-search t)
+                     (re (concat bibtex-entry-head "\\|"
+                                 ",[ \t\n]*crossref[ \t\n]*=[ \t\n]*"
+                                 "\\(\"[^\"]*\"\\|{[^}]*}\\)[ \t\n]*[,})]")))
+                 (while (re-search-forward re nil t)
+                   (if (and abortable (input-pending-p))
+                       ;; user has aborted by typing a key --> return `aborted'
+                       (throw 'userkey 'aborted))
+                   (let ((key (cond ((match-end 3)
+                                     ;; This is a crossref.
+                                     (buffer-substring-no-properties
+                                      (1+ (match-beginning 3)) (1- (match-end 
3))))
+                                    ((assoc-ignore-case (bibtex-type-in-head)
+                                                        
bibtex-entry-field-alist)
+                                     ;; This is an entry.
+                                     (match-string-no-properties 
bibtex-key-in-head)))))
+                     (if (and (stringp key)
+                              (not (assoc key reference-keys)))
+                       (push (list key) reference-keys)))))
+ 
+             (let (;; ignore @String entries because they are handled
+                   ;; separately by bibtex-parse-strings
+                   (bibtex-sort-ignore-string-entries t)
+                   crossref-key bounds)
+               (bibtex-map-entries
+                (lambda (key beg end)
+                  (if (and abortable
+                           (input-pending-p))
+                      ;; user has aborted by typing a key --> return `aborted'
+                      (throw 'userkey 'aborted))
+                  (if verbose (bibtex-progress-message))
+                  (unless (assoc key reference-keys)
+                    (push (list key) reference-keys))
+                  (if (and (setq bounds (bibtex-search-forward-field 
"crossref" end))
+                           (setq crossref-key (bibtex-text-in-field-bounds 
bounds t))
+                           (not (assoc crossref-key reference-keys)))
+                      (push (list crossref-key) reference-keys))))))
+ 
+           (if verbose
+               (bibtex-progress-message 'done))
+           ;; successful operation --> return `bibtex-reference-keys'
+           (setq bibtex-reference-keys reference-keys))))))
+ 
+ (defun bibtex-parse-strings (&optional add abortable)
+   "Set `bibtex-strings' to the string definitions in the whole buffer.
+ The buffer might possibly be restricted.
+ If ADD is non-nil add the new strings to `bibtex-strings' instead of
+ simply resetting it. If ADD is an alist of strings, also add ADD to
+ `bibtex-strings'. If ABORTABLE is non-nil abort on user input.
+ Return alist of strings if parsing was completed, `aborted' otherwise."
+   (save-excursion
+     (save-match-data
+       (goto-char (point-min))
+       (let ((strings (if (and add
+                               (listp bibtex-strings))
+                          bibtex-strings))
+             bounds key)
+         (if (listp add)
+             (dolist (string add)
+               (unless (assoc (car string) strings)
+                 (push string strings))))
+         (catch 'userkey
+           (while (setq bounds (bibtex-search-forward-string))
+             (if (and abortable
+                      (input-pending-p))
+                 ;; user has aborted by typing a key --> return `aborted'
+                 (throw 'userkey 'aborted))
+             (setq key (bibtex-reference-key-in-string bounds))
+             (if (not (assoc-ignore-case key strings))
+                 (push (cons key (bibtex-text-in-string bounds t))
+                       strings))
+             (goto-char (bibtex-end-of-text-in-string bounds)))
+           ;; successful operation --> return `bibtex-strings'
+           (setq bibtex-strings strings))))))
+ 
+ (defun bibtex-string-files-init ()
+   "Return initialization for `bibtex-strings'.
+ Use `bibtex-predefined-strings' and bib files `bibtex-string-files'."
+   (save-match-data
+     ;; collect pathnames
+     (let ((dirlist (split-string (or bibtex-string-file-path ".")
+                                  ":+"))
+           (case-fold-search)
+           compl)
+       (dolist (filename bibtex-string-files)
+         (unless (string-match "\\.bib\\'" filename)
+           (setq filename (concat filename ".bib")))
+         ;; test filenames
+         (let (fullfilename bounds found)
+           (dolist (dir dirlist)
+             (when (file-readable-p
+                    (setq fullfilename (expand-file-name filename dir)))
+               ;; file was found
+               (with-temp-buffer
+                 (insert-file-contents fullfilename)
+                 (goto-char (point-min))
+                 (while (setq bounds (bibtex-search-forward-string))
+                   (push (cons (bibtex-reference-key-in-string bounds)
+                               (bibtex-text-in-string bounds t))
+                         compl)
+                   (goto-char (bibtex-end-of-string bounds))))
+               (setq found t)))
+           (unless found
+             (error "File %s not in paths defined via bibtex-string-file-path"
+                    filename))))
+       (append bibtex-predefined-strings (nreverse compl)))))
+ 
+ (defun bibtex-parse-buffers-stealthily ()
+   "Called by `bibtex-run-with-idle-timer'. Whenever emacs has been idle
+ for `bibtex-parse-keys-timeout' seconds, all BibTeX buffers (starting
+ with the current) are parsed."
+   (save-excursion
+     (let ((buffers (buffer-list))
+           (strings-init (bibtex-string-files-init)))
        (while (and buffers (not (input-pending-p)))
          (set-buffer (car buffers))
!         (if (and (eq major-mode 'bibtex-mode)
!                  (not (eq (buffer-modified-tick)
!                           bibtex-buffer-last-parsed-tick)))
!             (save-restriction
!               (widen)
!               ;; Output no progress messages in bibtex-parse-keys
!               ;; because when in y-or-n-p that can hide the question.
!               (if (and (listp (bibtex-parse-keys nil t))
!                        ;; update bibtex-strings
!                        (listp (bibtex-parse-strings strings-init t)))
! 
!                   ;; remember that parsing was successful
!                   (setq bibtex-buffer-last-parsed-tick 
(buffer-modified-tick)))))
!         (setq buffers (cdr buffers))))))
! 
! (defun bibtex-complete-internal (completions)
!   "Complete word fragment before point to longest prefix of one
! string defined in list COMPLETIONS.  If point is not after the part
! of a word, all strings are listed. Return completion."
    (let* ((case-fold-search t)
           (beg (save-excursion
                  (re-search-backward "[ \t{\"]")
                  (forward-char)
                  (point)))
+          (end (point))
           (part-of-word (buffer-substring-no-properties beg end))
!          (completion (try-completion part-of-word completions)))
!     (cond ((not completion)
!            (error "Can't find completion for `%s'" part-of-word))
!           ((eq completion t)
!            part-of-word)
            ((not (string= part-of-word completion))
             (delete-region beg end)
             (insert completion)
!            completion)
            (t
             (message "Making completion list...")
!            (with-output-to-temp-buffer "*Completions*"
!              (display-completion-list (all-completions part-of-word
!                                                        completions)))
!            (message "Making completion list...done")
!            nil))))
! 
! (defun bibtex-complete-string-cleanup (str)
!   "Cleanup after inserting string STR.
! Remove enclosing field delimiters for string STR. Display message with
! expansion of STR."
!   (let ((pair (assoc str bibtex-strings)))
!     (when pair
!       (if (cdr pair)
!           (message "Abbreviation for `%s'" (cdr pair)))
!       (save-excursion
!         (bibtex-inside-field)
!         (let ((bounds (bibtex-enclosing-field)))
!           (goto-char (bibtex-start-of-text-in-field bounds))
!           (let ((boundaries (bibtex-parse-field-string)))
!             (if (and boundaries
!                      (equal (cdr boundaries)
!                             (bibtex-end-of-text-in-field bounds)))
!                 (bibtex-remove-delimiters))))))))
! 
! (defun bibtex-choose-completion-string (choice buffer mini-p base-size)
!   ;; Code borrowed from choose-completion-string:
!   ;; We must duplicate the code from choose-completion-string
!   ;; because it runs the hook choose-completion-string-functions
!   ;; before it inserts the completion. But we want to do something
!   ;; after the completion has been inserted.
!   ;;
!   ;; Insert the completion into the buffer where it was requested.
!   (set-buffer buffer)
!   (if base-size
!       (delete-region (+ base-size (point-min))
!                      (point))
!     ;; Delete the longest partial match for CHOICE
!     ;; that can be found before point.
!    (choose-completion-delete-max-match choice))
!   (insert choice)
!   (remove-text-properties (- (point) (length choice)) (point)
!                           '(mouse-face nil))
!   ;; Update point in the window that BUFFER is showing in.
!   (let ((window (get-buffer-window buffer t)))
!     (set-window-point window (point))))
  
  (defun bibtex-pop (arg direction)
!   "Generic function used by `bibtex-pop-previous' and `bibtex-pop-next'."
    (let (bibtex-help-message)
      (bibtex-find-text nil))
    (save-excursion
      ;; parse current field
      (bibtex-inside-field)
      (let* ((case-fold-search t)
!            (bounds (bibtex-enclosing-field))
!            (start-old-text (bibtex-start-of-text-in-field bounds))
!            (stop-old-text (bibtex-end-of-text-in-field bounds))
!            (start-name (bibtex-start-of-name-in-field bounds))
!            (stop-name (bibtex-end-of-name-in-field bounds))
!            ;; construct regexp for field with same name as this one,
!            ;; ignoring possible OPT's or ALT's
!            (field-name (progn
!                          (goto-char start-name)
!                          (buffer-substring-no-properties
!                           (if (looking-at "\\(OPT\\)\\|\\(ALT\\)")
!                               (match-end 0)
!                             (point))
!                           stop-name))))
!       ;; if executed several times in a row, start each search where
!       ;; the last one was finished
!       (unless (eq last-command 'bibtex-pop)
!         (bibtex-enclosing-entry-maybe-empty-head)
!         (setq bibtex-pop-previous-search-point (match-beginning 0)
!               bibtex-pop-next-search-point (point)))
!       (if (eq direction 'previous)
!           (goto-char bibtex-pop-previous-search-point)
!         (goto-char bibtex-pop-next-search-point))
!       ;; Now search for arg'th previous/next similar field
!       (let (bounds failure new-text)
!         (while (and (not failure)
!                     (> arg 0))
!           (cond ((eq direction 'previous)
!                  (if (setq bounds (bibtex-search-backward-field field-name))
!                      (goto-char (bibtex-start-of-field bounds))
!                    (setq failure t)))
!                 ((eq direction 'next)
!                  (if (setq bounds (bibtex-search-forward-field field-name))
!                      (goto-char (bibtex-end-of-field bounds))
!                    (setq failure t))))
!           (setq arg (- arg 1)))
!         (if failure
!             (error "No %s matching BibTeX field"
!                    (if (eq direction 'previous) "previous" "next"))
!           ;; Found a matching field. Remember boundaries.
!           (setq bibtex-pop-previous-search-point (bibtex-start-of-field 
bounds)
!                 bibtex-pop-next-search-point (bibtex-end-of-field bounds)
!                 new-text (bibtex-text-in-field-bounds bounds))
!           (bibtex-flash-head)
!           ;; Go back to where we started, delete old text, and pop new.
!           (goto-char stop-old-text)
!           (delete-region start-old-text stop-old-text)
!           (insert new-text)))))
    (let (bibtex-help-message)
      (bibtex-find-text nil))
    (setq this-command 'bibtex-pop))
  
+ (defsubst bibtex-read-key (prompt &optional key)
+   "Read BibTeX key from minibuffer using PROMPT and default KEY."
+   (completing-read prompt bibtex-reference-keys
+                    nil nil key 'bibtex-key-history))
  
  ;; Interactive Functions:
  
***************
*** 2554,2584 ****
  (defun bibtex-mode ()
    "Major mode for editing BibTeX files.
  
- To submit a problem report, enter \\[bibtex-submit-bug-report] from a
- BibTeX mode buffer.  This automatically sets up a mail buffer with
- version information already added.  You just need to add a description
- of the problem, including a reproducible test case and send the
- message.
- 
- 
  General information on working with BibTeX mode:
  
! You should use commands as \\[bibtex-Book] to get a template for a
  specific entry. You should then fill in all desired fields using
  \\[bibtex-next-field] to jump from field to field. After having filled
  in all desired fields in the entry, you should clean the new entry
! with command \\[bibtex-clean-entry].
  
! Some features of BibTeX mode are available only by setting variable
! bibtex-maintain-sorted-entries to t. However, then BibTeX mode will
! work with buffer containing only valid (syntactical correct) entries
  and with entries being sorted. This is usually the case, if you have
  created a buffer completely with BibTeX mode and finished every new
  entry with \\[bibtex-clean-entry].
  
! For third party BibTeX buffers, please call the function
! `bibtex-convert-alien' to fully take advantage of all features of
! BibTeX mode.
  
  
  Special information:
--- 2498,2520 ----
  (defun bibtex-mode ()
    "Major mode for editing BibTeX files.
  
  General information on working with BibTeX mode:
  
! You should use commands such as \\[bibtex-Book] to get a template for a
  specific entry. You should then fill in all desired fields using
  \\[bibtex-next-field] to jump from field to field. After having filled
  in all desired fields in the entry, you should clean the new entry
! with the command \\[bibtex-clean-entry].
  
! Some features of BibTeX mode are available only by setting the variable
! `bibtex-maintain-sorted-entries' to non-nil. However, then BibTeX mode will
! work only with buffers containing valid (syntactical correct) entries
  and with entries being sorted. This is usually the case, if you have
  created a buffer completely with BibTeX mode and finished every new
  entry with \\[bibtex-clean-entry].
  
! For third party BibTeX files, call the function `bibtex-convert-alien'
! to fully take advantage of all features of BibTeX mode.
  
  
  Special information:
***************
*** 2590,2607 ****
  The OPT or ALT string may be removed from a field with 
\\[bibtex-remove-OPT-or-ALT].
  \\[bibtex-make-field] inserts a new field after the current one.
  \\[bibtex-kill-field] kills the current field entirely.
! \\[bibtex-yank] will yank the last recently killed field after the
! current field.
  \\[bibtex-remove-delimiters] removes the double-quotes or braces around the 
text of the current field.
   \\[bibtex-empty-field] replaces the text of the current field with the 
default \"\" or {}.
  
  The command \\[bibtex-clean-entry] cleans the current entry, i.e. it removes 
OPT/ALT
  from all non-empty optional or alternative fields, checks that no required
  fields are empty, and does some formatting dependent on the value of
! bibtex-entry-format.
  Note: some functions in BibTeX mode depend on entries being in a special
  format (all fields beginning on separate lines), so it is usually a bad
! idea to remove `realign' from bibtex-entry-format.
  
  Use \\[bibtex-find-text] to position the cursor at the end of the current 
field.
  Use \\[bibtex-next-field] to move to end of the next field.
--- 2526,2542 ----
  The OPT or ALT string may be removed from a field with 
\\[bibtex-remove-OPT-or-ALT].
  \\[bibtex-make-field] inserts a new field after the current one.
  \\[bibtex-kill-field] kills the current field entirely.
! \\[bibtex-yank] yanks the last recently killed field after the current field.
  \\[bibtex-remove-delimiters] removes the double-quotes or braces around the 
text of the current field.
   \\[bibtex-empty-field] replaces the text of the current field with the 
default \"\" or {}.
  
  The command \\[bibtex-clean-entry] cleans the current entry, i.e. it removes 
OPT/ALT
  from all non-empty optional or alternative fields, checks that no required
  fields are empty, and does some formatting dependent on the value of
! `bibtex-entry-format'.
  Note: some functions in BibTeX mode depend on entries being in a special
  format (all fields beginning on separate lines), so it is usually a bad
! idea to remove `realign' from `bibtex-entry-format'.
  
  Use \\[bibtex-find-text] to position the cursor at the end of the current 
field.
  Use \\[bibtex-next-field] to move to end of the next field.
***************
*** 2609,2648 ****
  The following may be of interest as well:
  
    Functions:
!     bibtex-entry
!     bibtex-kill-entry
!     bibtex-yank-pop
!     bibtex-pop-previous
!     bibtex-pop-next
!     bibtex-complete-string
!     bibtex-complete-key
!     bibtex-print-help-message
!     bibtex-generate-autokey
!     bibtex-beginning-of-entry
!     bibtex-end-of-entry
!     bibtex-reposition-window
!     bibtex-mark-entry
!     bibtex-ispell-abstract
!     bibtex-ispell-entry
!     bibtex-narrow-to-entry
!     bibtex-sort-buffer
!     bibtex-validate
!     bibtex-count
!     bibtex-fill-entry
!     bibtex-reformat
!     bibtex-convert-alien
  
    Variables:
!     bibtex-field-delimiters
!     bibtex-include-OPTcrossref
!     bibtex-include-OPTkey
!     bibtex-user-optional-fields
!     bibtex-entry-format
!     bibtex-sort-ignore-string-entries
!     bibtex-maintain-sorted-entries
!     bibtex-entry-field-alist
!     bibtex-predefined-strings
!     bibtex-string-files
  
  ---------------------------------------------------------
  Entry to BibTeX mode calls the value of `bibtex-mode-hook' if that value is
--- 2544,2582 ----
  The following may be of interest as well:
  
    Functions:
!     `bibtex-entry'
!     `bibtex-kill-entry'
!     `bibtex-yank-pop'
!     `bibtex-pop-previous'
!     `bibtex-pop-next'
!     `bibtex-complete'
!     `bibtex-print-help-message'
!     `bibtex-generate-autokey'
!     `bibtex-beginning-of-entry'
!     `bibtex-end-of-entry'
!     `bibtex-reposition-window'
!     `bibtex-mark-entry'
!     `bibtex-ispell-abstract'
!     `bibtex-ispell-entry'
!     `bibtex-narrow-to-entry'
!     `bibtex-sort-buffer'
!     `bibtex-validate'
!     `bibtex-count'
!     `bibtex-fill-entry'
!     `bibtex-reformat'
!     `bibtex-convert-alien'
  
    Variables:
!     `bibtex-field-delimiters'
!     `bibtex-include-OPTcrossref'
!     `bibtex-include-OPTkey'
!     `bibtex-user-optional-fields'
!     `bibtex-entry-format'
!     `bibtex-sort-ignore-string-entries'
!     `bibtex-maintain-sorted-entries'
!     `bibtex-entry-field-alist'
!     `bibtex-predefined-strings'
!     `bibtex-string-files'
  
  ---------------------------------------------------------
  Entry to BibTeX mode calls the value of `bibtex-mode-hook' if that value is
***************
*** 2655,2885 ****
    (setq major-mode 'bibtex-mode)
    (setq mode-name "BibTeX")
    (set-syntax-table bibtex-mode-syntax-table)
!   (setq bibtex-strings bibtex-predefined-strings)
!   (mapcar
!    (lambda (filename)
!      ;; collect pathnames
!      (let* ((path (if bibtex-string-file-path
!                       bibtex-string-file-path
!                     "."))
!             (dirs (split-string path ":+"))
!             (filename (if (string-match "\.bib$" filename)
!                           filename
!                         (concat filename ".bib")))
!             fullfilename
!             (item 0)
!             (size (length dirs)))
!        ;; test filenames
!        (while (and
!                (< item size)
!                (not (file-readable-p
!                      (setq fullfilename
!                            (concat (elt dirs item) "/" filename)))))
!          (setq item (1+ item)))
!        (if (< item size)
!            ;; file was found
!            (let* ((case-fold-search t)
!                 (compl nil))
!            (with-temp-buffer
!              (insert-file-contents fullfilename)
!              (goto-char (point-min))
!              (let ((bounds (bibtex-search-forward-string)))
!                (while bounds
!                  (setq compl
!                        (cons (list (buffer-substring-no-properties
!                                     (bibtex-start-of-reference-key-in-string 
bounds)
!                                     (bibtex-end-of-reference-key-in-string 
bounds)))
!                              compl))
!                  (goto-char (bibtex-end-of-string bounds))
!                  (setq bounds (bibtex-search-forward-string)))))
!            (setq bibtex-strings (append bibtex-strings (nreverse compl))))
!          (error
!           "File %s not in paths defined by bibtex-string-file-path variable"
!           filename))))
!    bibtex-string-files)
!   (if bibtex-maintain-sorted-entries
!       (bibtex-run-with-idle-timer
!        1 nil
!        (lambda ()
!          (bibtex-parse-keys nil nil t))))
!   ;; to get buffer parsed once if everything else (including things
!   ;; installed in bibtex-mode-hook) has done its work
!   (if (not bibtex-parse-idle-timer)
!       (setq bibtex-parse-idle-timer
!             (bibtex-run-with-idle-timer
!              bibtex-parse-keys-timeout t
!              'bibtex-parse-buffers-stealthily)))
    ;; Install stealthy parse function if not already installed
!   (make-local-variable 'paragraph-start)
!   (setq paragraph-start "[ \f\n\t]*$")
!   (make-local-variable 'comment-start)
!   (setq comment-start bibtex-comment-start)
!   (make-local-variable 'comment-start-skip)
!   (setq comment-start-skip bibtex-comment-start)
!   (make-local-variable 'comment-column)
!   (setq comment-column 0)
!   (make-local-variable 'defun-prompt-regexp)
!   (setq defun-prompt-regexp "address@hidden")
!   (make-local-variable 'outline-regexp)
!   (setq outline-regexp "@")
!   (make-local-variable 'normal-auto-fill-function)
!   (setq normal-auto-fill-function 'bibtex-do-auto-fill)
!   (make-local-variable 'font-lock-defaults)
!   (setq font-lock-defaults
!       '(bibtex-font-lock-keywords
!         nil t ((?$ . "\"")
!                ;; Mathematical expressions should be fontified as strings
!                (?\" . ".")
!                ;; Quotes are field delimiters and quote-delimited
!                ;; entries should be fontified in the same way as
!                ;; brace-delimited ones
!                )))
!   (make-local-variable 'font-lock-mark-block-function)
!   (setq font-lock-mark-block-function
!       (lambda ()
!         (set-mark (bibtex-end-of-entry))
!         (bibtex-beginning-of-entry)))
    (setq imenu-generic-expression
!       (list (list nil bibtex-entry-head bibtex-key-in-head)))
    (setq imenu-case-fold-search t)
    ;; XEmacs needs easy-menu-add, Emacs does not care
    (easy-menu-add bibtex-edit-menu)
    (easy-menu-add bibtex-entry-menu)
    (run-hooks 'bibtex-mode-hook))
  
- (defun bibtex-submit-bug-report ()
-   "Submit via mail a bug report on bibtex.el."
-   (interactive)
-   (if (y-or-n-p "Do you want to submit a bug report on BibTeX mode? ")
-       (progn
-         (require 'reporter)
-         (let ((reporter-prompt-for-summary-p t))
-           (reporter-submit-bug-report
-            bibtex-maintainer-address
-            "bibtex.el"
-            (list
-             'system-configuration
-             'system-configuration-options
-             'bibtex-mode-hook
-             'bibtex-parse-keys-timeout
-             ;; possible general errors
-             'bibtex-sort-ignore-string-entries
-             'bibtex-maintain-sorted-entries
-             'bibtex-entry-delimiters
-             'bibtex-field-delimiters
-             'bibtex-comma-after-last-field
-             'bibtex-entry-offset
-             'bibtex-field-indentation
-             'bibtex-text-indentation
-             'bibtex-contline-indentation
-             'bibtex-align-at-equal-sign
-             ;; possible sorting and parsing bugs
-             'bibtex-entry-format
-             'bibtex-add-entry-hook
-             'bibtex-clean-entry-hook
-             ;; possible cleaning error
-             'bibtex-user-optional-fields
-             ;; possible format error
-             'bibtex-predefined-month-strings
-             'bibtex-predefined-strings
-             'bibtex-string-files
-             'bibtex-string-file-path
-             ;; possible format error
-             'bibtex-font-lock-keywords
-             ;; possible bugs regarding fontlocking
-             'bibtex-autokey-prefix-string
-             'bibtex-autokey-names
-             'bibtex-autokey-names-stretch
-             'bibtex-autokey-additional-names
-             'bibtex-autokey-transcriptions
-             'bibtex-autokey-name-change-strings
-             'bibtex-autokey-name-case-convert
-             'bibtex-autokey-name-length
-             'bibtex-autokey-name-separator
-             'bibtex-autokey-year-length
-             'bibtex-autokey-year-use-crossref-entry
-             'bibtex-autokey-titlewords
-             'bibtex-autokey-title-terminators
-             'bibtex-autokey-titlewords-stretch
-             'bibtex-autokey-titleword-ignore
-             'bibtex-autokey-titleword-case-convert
-             'bibtex-autokey-titleword-abbrevs
-             'bibtex-autokey-titleword-change-strings
-             'bibtex-autokey-titleword-length
-             'bibtex-autokey-titleword-separator
-             'bibtex-autokey-name-year-separator
-             'bibtex-autokey-year-title-separator
-             'bibtex-autokey-edit-before-use
-             'bibtex-autokey-before-presentation-function
-             ;; possible bugs regarding automatic reference keys
-             'bibtex-entry-field-alist
-             ;; possible format error
-             'bibtex-help-message
-             'bibtex-include-OPTcrossref
-             'bibtex-include-OPTkey
-             'bibtex-field-kill-ring-max
-             'bibtex-entry-kill-ring-max
-             ;; user variables which shouldn't cause any errors
-             )
-            nil nil
-            (concat bibtex-maintainer-salutation "
- 
- I want to report a bug on Emacs BibTeX mode.
- 
- I've read the `Bugs' section in the `Emacs' info page, so I know how
- to make a clear and unambiguous report. I have started a fresh Emacs
- via `"invocation-name " --no-init-file --no-site-file', thereafter (in
- case I'm reporting on a version of `bibtex.el' which is not part of
- the standard emacs distribution) I loaded the questionable version
- of `bibtex.el' with `M-x load-file', and then, to produce the buggy
- behaviour, I did the following:")))
-         (message nil))))
- 
  (defun bibtex-entry (entry-type)
    "Insert a new BibTeX entry.
  After insertion it calls the functions in `bibtex-add-entry-hook'."
    (interactive (let* ((completion-ignore-case t)
!                     (e-t (completing-read
                              "Entry Type: "
                              bibtex-entry-field-alist
                              nil t nil 'bibtex-entry-type-history)))
!                (list e-t)))
!   (if (not bibtex-reference-keys)
!       (bibtex-parse-keys nil t))
!   (let* (required
!          optional
!          (key
!           (if bibtex-maintain-sorted-entries
!               (completing-read
!                (format "%s key: " entry-type)
!                bibtex-reference-keys nil nil nil 'bibtex-key-history)))
           (e (assoc-ignore-case entry-type bibtex-entry-field-alist))
           (r-n-o (elt e 1))
           (c-ref (elt e 2)))
      (if (not e)
          (error "Bibtex entry type %s not defined" entry-type))
!     (if (and
!          (member entry-type bibtex-include-OPTcrossref)
!          c-ref)
          (setq required (elt c-ref 0)
                optional (elt c-ref 1))
        (setq required (elt r-n-o 0)
              optional (elt r-n-o 1)))
!     (if bibtex-maintain-sorted-entries
!       (bibtex-find-entry-location key)
!       (bibtex-move-outside-of-entry))
      (indent-to-column bibtex-entry-offset)
      (insert "@" entry-type (bibtex-entry-left-delimiter))
      (if key
!       (insert key))
      (save-excursion
        (mapcar 'bibtex-make-field required)
        (if (member entry-type bibtex-include-OPTcrossref)
!         (bibtex-make-optional-field '("crossref")))
        (if bibtex-include-OPTkey
!           (if (or
!                (stringp bibtex-include-OPTkey)
!                (fboundp bibtex-include-OPTkey))
                (bibtex-make-optional-field
                 (list "key" nil bibtex-include-OPTkey))
              (bibtex-make-optional-field '("key"))))
--- 2589,2671 ----
    (setq major-mode 'bibtex-mode)
    (setq mode-name "BibTeX")
    (set-syntax-table bibtex-mode-syntax-table)
!   (make-local-variable 'bibtex-buffer-last-parsed-tick)
    ;; Install stealthy parse function if not already installed
!   (unless bibtex-parse-idle-timer
!     (setq bibtex-parse-idle-timer (bibtex-run-with-idle-timer
!                                    bibtex-parse-keys-timeout t
!                                    'bibtex-parse-buffers-stealthily)))
!   (set (make-local-variable 'paragraph-start) "[ \f\n\t]*$")
!   (set (make-local-variable 'comment-start) bibtex-comment-start)
!   (set (make-local-variable 'comment-start-skip)
!        (concat (regexp-quote bibtex-comment-start) "\\>[ \t]*"))
!   (set (make-local-variable 'comment-column) 0)
!   (set (make-local-variable 'defun-prompt-regexp) "^[ address@hidden \t]*")
!   (set (make-local-variable 'outline-regexp) "[ \t]*@")
!   (set (make-local-variable 'fill-paragraph-function) 'bibtex-fill-field)
!   (set (make-local-variable 'fill-prefix) (make-string (+ bibtex-entry-offset
!                                                          
bibtex-contline-indentation)
!                                                       ? ))
!   (set (make-local-variable 'font-lock-defaults)
!        '(bibtex-font-lock-keywords
!          nil t ((?$ . "\"")
!                 ;; Mathematical expressions should be fontified as strings
!                 (?\" . ".")
!                 ;; Quotes are field delimiters and quote-delimited
!                 ;; entries should be fontified in the same way as
!                 ;; brace-delimited ones
!                 )
!          nil
!          (font-lock-syntactic-keywords . bibtex-font-lock-syntactic-keywords)
!        (font-lock-mark-block-function
!         . (lambda ()
!          (set-mark (bibtex-end-of-entry))
!             (bibtex-beginning-of-entry)))))
    (setq imenu-generic-expression
!         (list (list nil bibtex-entry-head bibtex-key-in-head)))
!   (make-local-variable 'choose-completion-string-functions)
    (setq imenu-case-fold-search t)
    ;; XEmacs needs easy-menu-add, Emacs does not care
    (easy-menu-add bibtex-edit-menu)
    (easy-menu-add bibtex-entry-menu)
    (run-hooks 'bibtex-mode-hook))
  
  (defun bibtex-entry (entry-type)
    "Insert a new BibTeX entry.
  After insertion it calls the functions in `bibtex-add-entry-hook'."
    (interactive (let* ((completion-ignore-case t)
!                       (e-t (completing-read
                              "Entry Type: "
                              bibtex-entry-field-alist
                              nil t nil 'bibtex-entry-type-history)))
!                  (list e-t)))
!   (let* (required optional
!          (key (if bibtex-maintain-sorted-entries
!                   (bibtex-read-key (format "%s key: " entry-type))))
           (e (assoc-ignore-case entry-type bibtex-entry-field-alist))
           (r-n-o (elt e 1))
           (c-ref (elt e 2)))
      (if (not e)
          (error "Bibtex entry type %s not defined" entry-type))
!     (if (and (member entry-type bibtex-include-OPTcrossref)
!              c-ref)
          (setq required (elt c-ref 0)
                optional (elt c-ref 1))
        (setq required (elt r-n-o 0)
              optional (elt r-n-o 1)))
!     (unless (bibtex-prepare-new-entry (list key nil entry-type))
!       (error "Entry with key `%s' already exists" key))
      (indent-to-column bibtex-entry-offset)
      (insert "@" entry-type (bibtex-entry-left-delimiter))
      (if key
!         (insert key))
      (save-excursion
        (mapcar 'bibtex-make-field required)
        (if (member entry-type bibtex-include-OPTcrossref)
!           (bibtex-make-optional-field '("crossref")))
        (if bibtex-include-OPTkey
!           (if (or (stringp bibtex-include-OPTkey)
!                   (fboundp bibtex-include-OPTkey))
                (bibtex-make-optional-field
                 (list "key" nil bibtex-include-OPTkey))
              (bibtex-make-optional-field '("key"))))
***************
*** 2891,3081 ****
        (indent-to-column bibtex-entry-offset)
        (insert (bibtex-entry-right-delimiter) "\n\n"))
      (bibtex-next-field t)
      (run-hooks 'bibtex-add-entry-hook)))
  
  (defun bibtex-print-help-message ()
!   "Prints helpful information about current field in current BibTeX entry."
    (interactive)
!   (let* ((case-fold-search t)
!          (pnt (point))
!          (field-name
!         (let* ((bounds (bibtex-enclosing-field))
!                (mb (bibtex-start-of-name-in-field bounds))
!                (me (bibtex-end-of-name-in-field bounds)))
!           (goto-char mb)
!           (buffer-substring-no-properties
!            (if (looking-at "OPT\\|ALT")
!                (+ 3 mb)
!              mb)
!            me)))
!          (entry-type
!           (progn
!             (re-search-backward
!              bibtex-entry-maybe-empty-head nil t)
!             (buffer-substring-no-properties
!              (1+ (match-beginning bibtex-type-in-head))
!              (match-end bibtex-type-in-head))))
!          (entry-list
!           (assoc-ignore-case entry-type
!                                bibtex-entry-field-alist))
!          (c-r-list (elt entry-list 2))
!          (req-opt-list
!           (if (and
!                (member entry-type bibtex-include-OPTcrossref)
!                c-r-list)
!               c-r-list
!             (elt entry-list 1)))
!          (list-of-entries (append
!                            (elt req-opt-list 0)
!                            (elt req-opt-list 1)
!                            bibtex-user-optional-fields
!                            (if (member
!                                 entry-type
!                                 bibtex-include-OPTcrossref)
!                                '(("crossref"
!                                   "Reference key of the crossreferenced 
entry")))
!                            (if bibtex-include-OPTkey
!                                '(("key"
!                                   "Used for reference key creation if author 
and editor fields are missing"))))))
!     (goto-char pnt)
!     (let ((comment (assoc-ignore-case field-name list-of-entries)))
        (if comment
            (message (elt comment 1))
!         (message "NO COMMENT AVAILABLE")))))
  
! (defun bibtex-make-field (e-t &optional called-by-yank)
!   "Makes a field named E-T in current BibTeX entry.
! This function is for interactive and non-interactive purposes.  To call
! it interactively, just give it no arguments and enter the field name
! using the minibuffer."
!   (interactive "*P")
!   (if (not e-t)
!       (setq
!        e-t
!        (let* ((entry-type
!                (save-excursion
!                  (bibtex-enclosing-entry-maybe-empty-head)
!                  (buffer-substring-no-properties
!                   (1+ (match-beginning bibtex-type-in-head))
!                   (match-end bibtex-type-in-head))))
!               (fl
!                (car (cdr (assoc-ignore-case
!                           entry-type bibtex-entry-field-alist))))
!               (field-list
!                (append
!                 (elt fl 0) (elt fl 1) bibtex-user-optional-fields
!                 (if bibtex-include-OPTcrossref '(("crossref" nil)))
!                 (if bibtex-include-OPTkey '(("key" nil)))))
!               (completion-ignore-case t))
!          (completing-read
!           "BibTeX field name: " field-list
!           nil nil nil bibtex-field-history))))
!   (if (not (consp e-t))
!       (setq e-t (list e-t)))
!   (if (equal (length e-t) 1)
!       (setq e-t (append e-t (list ""))))
!   (if (equal (length e-t) 2)
!       (setq e-t (append e-t (list ""))))
!   (let ((name (if (elt e-t 3)
!                   (concat "ALT" (car e-t))
!                 (car e-t))))
!     (if (or (interactive-p) called-by-yank)
!         (let (bibtex-help-message)
!           (bibtex-find-text nil t t)
!           (if (looking-at "[}\"]")
!               (forward-char))))
!     (insert ",\n")
!     (indent-to-column
!      (+ bibtex-entry-offset bibtex-field-indentation))
!     (insert name " ")
!     (if bibtex-align-at-equal-sign
!         (indent-to-column
!          (+ bibtex-entry-offset (- bibtex-text-indentation 2))))
!     (insert "= ")
!     (if (not bibtex-align-at-equal-sign)
!         (indent-to-column
!          (+ bibtex-entry-offset bibtex-text-indentation)))
!     (insert (if called-by-yank
!                 ""
!               (bibtex-field-left-delimiter))
!             (let ((init (elt e-t 2)))
!               (cond
!                ((stringp init)
!                 init)
!                ((fboundp init)
!                 (funcall init))
!                (t
!                 (error "%s is neither a string nor a function" init))))
!             (if called-by-yank
!                 ""
!               (bibtex-field-right-delimiter)))
!     (if (interactive-p)
!         (forward-char -1))))
  
  (defun bibtex-beginning-of-entry ()
!   "Move to beginning of BibTeX entry.
  If inside an entry, move to the beginning of it, otherwise move to the
! beginning of the previous entry.
! If called from a program, this function returns the new location of point."
    (interactive)
    (skip-chars-forward " \t")
    (if (looking-at "@")
        (forward-char))
!   (re-search-backward "^[ \t]*@" nil 'move))
  
  (defun bibtex-end-of-entry ()
!   "Move to end of BibTeX entry.
  If inside an entry, move to the end of it, otherwise move to the end
! of the previous entry.
! If called from a program, this function returns the new location of point."
    (interactive)
!   (let* ((case-fold-search t)
!        (valid-entry-head
!         (concat "[ address@hidden \t]*\\("
!                 (mapconcat
!                  (lambda (type)
!                    (concat "\\(" (car type) "\\)"))
!                  bibtex-entry-field-alist
!                  "\\|")
!                 "\\)"))
!        (org (point))
!        (pnt (bibtex-beginning-of-entry))
!        err)
!     (cond
!      ((bibtex-parse-string)
!       (let ((bounds (bibtex-parse-string)))
!       (goto-char (bibtex-end-of-string bounds))))
!      ((looking-at "[ address@hidden \t]*preamble[ \t\n]*")
!       (goto-char (match-end 0))
!       (cond
!        ((looking-at "(")
!         (if (not (re-search-forward ")[ \t]*\n\n" nil 'move))
!             (setq err t)))
!        ((looking-at "{")
!         (if (not (re-search-forward "}[ \t]*\n\n" nil 'move))
!             (setq err t)))
!        (t
!         (setq err t)))
!       (if (not err)
!           (progn
!             (goto-char (match-beginning 0))
!             (forward-char))))
!      ((looking-at valid-entry-head)
!       (bibtex-search-entry t nil t)
!       (if (not (equal (match-beginning 0) pnt))
!           (setq err t)))
!      (t
!       (if (interactive-p)
!           (message "Not on a known BibTeX entry."))
!       (goto-char org)))
!     (if err
!         (progn
!           (goto-char pnt)
!           (error "Syntactical incorrect entry starts here"))))
    (point))
  
! (defun bibtex-reposition-window (arg)
!   "Make the current BibTeX entry visible."
    (interactive "P")
    (save-excursion
      (goto-char
--- 2677,2910 ----
        (indent-to-column bibtex-entry-offset)
        (insert (bibtex-entry-right-delimiter) "\n\n"))
      (bibtex-next-field t)
+     (if (member-ignore-case entry-type bibtex-autofill-types)
+       (bibtex-autofill-entry))
      (run-hooks 'bibtex-add-entry-hook)))
  
+ (defun bibtex-parse-entry ()
+   "Parse entry at point, return an alist.
+ The alist elements have the form (FIELD . TEXT), where FIELD can also be
+ the special strings \"=type=\" and \"=key=\"."
+   (let (alist bounds)
+     (when (looking-at bibtex-entry-head)
+       (push (cons "=type=" (match-string bibtex-type-in-head)) alist)
+       (push (cons "=key=" (match-string bibtex-key-in-head)) alist)
+       (goto-char (match-end bibtex-key-in-head))
+       (while (setq bounds (bibtex-parse-field bibtex-field-name))
+       (push (cons (bibtex-name-in-field bounds)
+                   (bibtex-text-in-field-bounds bounds))
+             alist)
+       (goto-char (bibtex-end-of-field bounds))))
+     alist))
+ 
+ (defun bibtex-autofill-entry ()
+   "Try to fill fields based on surrounding entries."
+   (interactive)
+   (undo-boundary)     ;So you can easily undo it, if it didn't work right.
+   (bibtex-beginning-of-entry)
+   (when (looking-at bibtex-entry-head)
+     (let ((type (match-string bibtex-type-in-head))
+         (key (match-string bibtex-key-in-head))
+         (key-end (match-end bibtex-key-in-head))
+           (case-fold-search t)
+         tmp other-key other bounds)
+       ;; The fields we want to change start right after the key.
+       (goto-char key-end)
+       ;; First see whether to use the previous or the next entry
+       ;; for "inspiration".
+       (save-excursion
+       (goto-char (1- (match-beginning 0)))
+       (bibtex-beginning-of-entry)
+       (when (and
+              (looking-at bibtex-entry-head)
+              (equal type (match-string bibtex-type-in-head))
+              ;; In case we found ourselves :-(
+              (not (equal key (setq tmp (match-string bibtex-key-in-head)))))
+         (setq other-key tmp)
+         (setq other (point))))
+       (save-excursion
+       (bibtex-end-of-entry)
+       (bibtex-skip-to-valid-entry)
+       (when (and
+              (looking-at bibtex-entry-head)
+              (equal type (match-string bibtex-type-in-head))
+              ;; In case we found ourselves :-(
+              (not (equal key (setq tmp (match-string bibtex-key-in-head))))
+              (or (not other-key)
+                  ;; Check which is the best match.
+                  (< (length (try-completion "" (list key other-key)))
+                     (length (try-completion "" (list key tmp))))))
+         (setq other-key tmp)
+         (setq other (point))))
+       ;; Then fill the new entry's fields with the chosen other entry.
+       (when other
+       (setq other (save-excursion (goto-char other) (bibtex-parse-entry)))
+       (setq key-end (point))      ;In case parse-entry changed the buffer.
+       (while (setq bounds (bibtex-parse-field bibtex-field-name))
+         (goto-char (bibtex-start-of-name-in-field bounds))
+         (let* ((name (buffer-substring
+                       (if (looking-at "ALT\\|OPT") (match-end 0) (point))
+                       (bibtex-end-of-name-in-field bounds)))
+                (text (assoc-ignore-case name other)))
+           (goto-char (bibtex-start-of-text-in-field bounds))
+           (if (not (and (looking-at bibtex-empty-field-re) text))
+               (goto-char (bibtex-end-of-field bounds))
+             (delete-region (point) (bibtex-end-of-text-in-field bounds))
+             (insert (cdr text)))))
+       ;; Finally try to update the text based on the difference between
+       ;; the two keys.
+       (let* ((prefix (try-completion "" (list key other-key)))
+              ;; If the keys are foo91 and foo92, don't replace 1 for 2
+              ;; but 91 for 92 instead.
+              (_ (if (string-match "[0-9]+\\'" prefix)
+                     (setq prefix (substring prefix 0 (match-beginning 0)))))
+              (suffix (substring key (length prefix)))
+              (other-suffix (substring other-key (length prefix))))
+         (while (re-search-backward (regexp-quote other-suffix) key-end 'move)
+           (replace-match suffix)))))))
+ 
  (defun bibtex-print-help-message ()
!   "Print helpful information about current field in current BibTeX entry."
    (interactive)
!   (save-excursion
!     (let* ((case-fold-search t)
!            (bounds (bibtex-enclosing-field))
!            (mb (bibtex-start-of-name-in-field bounds))
!            (field-name (buffer-substring-no-properties
!                         (if (progn (goto-char mb)
!                                    (looking-at "OPT\\|ALT"))
!                             (match-end 0) mb)
!                         (bibtex-end-of-name-in-field bounds)))
!            (entry-type (progn (re-search-backward
!                                bibtex-entry-maybe-empty-head nil t)
!                               (bibtex-type-in-head)))
!            (entry-list (assoc-ignore-case entry-type
!                                           bibtex-entry-field-alist))
!            (c-r-list (elt entry-list 2))
!            (req-opt-list (if (and (member entry-type
!                                           bibtex-include-OPTcrossref)
!                                   c-r-list)
!                              c-r-list
!                            (elt entry-list 1)))
!            (list-of-entries (append (elt req-opt-list 0)
!                                     (elt req-opt-list 1)
!                                     bibtex-user-optional-fields
!                                     (if (member entry-type
!                                                 bibtex-include-OPTcrossref)
!                                         '(("crossref" "Reference key of the 
cross-referenced entry")))
!                                     (if bibtex-include-OPTkey
!                                         '(("key" "Used for reference key 
creation if author and editor fields are missing")))))
!            (comment (assoc-ignore-case field-name list-of-entries)))
        (if comment
            (message (elt comment 1))
!         (message "No comment available")))))
  
! (defun bibtex-make-field (field &optional called-by-yank)
!   "Make a field named FIELD in current BibTeX entry.
! FIELD is either a string or a list of the form
! \(FIELD-NAME COMMENT-STRING INIT ALTERNATIVE-FLAG) as in
! `bibtex-entry-field-alist'."
!   (interactive
!    (list (let* ((entry-type
!                  (save-excursion
!                    (bibtex-enclosing-entry-maybe-empty-head)
!                    (bibtex-type-in-head)))
!                 ;; "preliminary" completion list
!                 (fl (nth 1 (assoc-ignore-case
!                             entry-type bibtex-entry-field-alist)))
!                 ;; "full" completion list
!                 (field-list (append (nth 0 fl)
!                                     (nth 1 fl)
!                                     bibtex-user-optional-fields
!                                     (if (member entry-type
!                                                 bibtex-include-OPTcrossref)
!                                         '(("crossref")))
!                                     (if bibtex-include-OPTkey
!                                         '(("key")))))
!                 (completion-ignore-case t))
!            (completing-read "BibTeX field name: " field-list
!                             nil nil nil bibtex-field-history))))
!   (unless (consp field)
!     (setq field (list field)))
!   (if (or (interactive-p) called-by-yank)
!       (let (bibtex-help-message)
!         (bibtex-find-text nil t t)
!         (if (looking-at "[}\"]")
!             (forward-char))))
!   (insert ",\n")
!   (indent-to-column (+ bibtex-entry-offset bibtex-field-indentation))
!   (if (nth 3 field) (insert "ALT"))
!   (insert (car field) " ")
!   (if bibtex-align-at-equal-sign
!       (indent-to-column (+ bibtex-entry-offset
!                            (- bibtex-text-indentation 2))))
!   (insert "= ")
!   (if (not bibtex-align-at-equal-sign)
!       (indent-to-column (+ bibtex-entry-offset
!                            bibtex-text-indentation)))
!   (if (not called-by-yank) (insert (bibtex-field-left-delimiter)))
!   (let ((init (nth 2 field)))
!     (cond ((stringp init)
!            (insert init))
!           ((fboundp init)
!            (insert (funcall init)))))
!   (if (not called-by-yank) (insert (bibtex-field-right-delimiter)))
!   (if (interactive-p)
!       (forward-char -1)))
  
  (defun bibtex-beginning-of-entry ()
!   "Move to beginning of BibTeX entry (beginning of line).
  If inside an entry, move to the beginning of it, otherwise move to the
! beginning of the previous entry. If point is ahead of all BibTeX entries
! move point to the beginning of buffer. Return the new location of point."
    (interactive)
    (skip-chars-forward " \t")
    (if (looking-at "@")
        (forward-char))
!   (re-search-backward "^[ \t]*@" nil 'move)
!   (point))
  
  (defun bibtex-end-of-entry ()
!   "Move to end of BibTeX entry (past the closing brace).
  If inside an entry, move to the end of it, otherwise move to the end
! of the previous entry. Do not move if ahead of first entry.
! Return the new location of point."
    (interactive)
!   (let ((case-fold-search t)
!         (org (point))
!         (pnt (bibtex-beginning-of-entry))
!         err bounds)
!     (cond ((looking-at bibtex-valid-entry-whitespace-re)
!            (bibtex-search-entry t nil t)
!            (unless (equal (match-beginning 0) pnt)
!              (setq err t)))
!           ((setq bounds (bibtex-parse-string))
!            (goto-char (bibtex-end-of-string bounds)))
!           ((looking-at "[ address@hidden \t]*preamble[ \t\n]*")
!            (goto-char (match-end 0))
!            (cond ((looking-at "(")
!                   (unless (re-search-forward ")[ \t]*\n\n" nil 'move)
!                     (setq err t)))
!                  ((looking-at "{")
!                   (unless (re-search-forward "}[ \t]*\n\n" nil 'move)
!                     (setq err t)))
!                  (t
!                   (setq err t)))
!            (unless err
!              (goto-char (match-beginning 0))
!              (forward-char)))
!           (t
!            (if (interactive-p)
!                (message "Not on a known BibTeX entry."))
!            (goto-char org)))
!     (when err
!       (goto-char pnt)
!       (error "Syntactically incorrect BibTeX entry starts here")))
    (point))
  
! (defun bibtex-reposition-window (&optional arg)
!   "Make the current BibTeX entry visible.
! Optional argument ARG is exactly as in `recenter'."
    (interactive "P")
    (save-excursion
      (goto-char
***************
*** 3094,3248 ****
  otherwise it counts all except Strings.
  If mark is active it counts entries in region, if not in whole buffer."
    (interactive "P")
!   (let ((pnt (point))
!         (start-point
!          (if (bibtex-mark-active)
!              (region-beginning)
!            (bibtex-beginning-of-first-entry)))
!         (end-point
!          (if (bibtex-mark-active)
!              (region-end)
!            (point-max)))
!         (number 0)
          (bibtex-sort-ignore-string-entries
           (not count-string-entries)))
!     (save-restriction
!       (narrow-to-region start-point end-point)
!       (goto-char start-point)
!       (bibtex-map-entries
!        (lambda (current)
!          (setq number (1+ number)))))
!     (message (concat (if (bibtex-mark-active) "Region" "Buffer")
!                      " contains %d entries.") number)
!     (goto-char pnt)))
  
  (defun bibtex-ispell-entry ()
    "Spell whole BibTeX entry."
    (interactive)
!   (ispell-region (bibtex-beginning-of-entry) (bibtex-end-of-entry)))
  
  (defun bibtex-ispell-abstract ()
    "Spell abstract of BibTeX entry."
    (interactive)
!   (let* ((case-fold-search t)
!        (pnt (bibtex-end-of-entry)))
!     (bibtex-beginning-of-entry)
!     (let ((bounds (bibtex-search-forward-field "abstract" pnt)))
!       (if bounds
!         (ispell-region (bibtex-start-of-text-in-field bounds) 
(bibtex-end-of-text-in-field bounds))
!       (error "No abstract in entry")))))
  
  (defun bibtex-narrow-to-entry ()
    "Narrow buffer to current BibTeX entry."
    (interactive)
    (save-excursion
!     (narrow-to-region
!      (bibtex-beginning-of-entry) (bibtex-end-of-entry))))
  
  (defun bibtex-sort-buffer ()
    "Sort BibTeX buffer alphabetically by key.
  Text outside of BibTeX entries is not affected.  If
  `bibtex-sort-ignore-string-entries' is non-nil, @String entries will be
  ignored."
    (interactive)
    (save-restriction
!     (narrow-to-region
!      (bibtex-beginning-of-first-entry)
!      (save-excursion
!        (goto-char (point-max))
!        (bibtex-end-of-entry)))
      (bibtex-skip-to-valid-entry)
!     (sort-subr
!      nil
!      ;; NEXTREC function
!      'bibtex-skip-to-valid-entry
!      ;; ENDREC function
!      'bibtex-end-of-entry
!      ;; STARTKEY function
!      (lambda ()
!        (let* ((case-fold-search t))
!          (re-search-forward bibtex-entry-head)
!          (buffer-substring-no-properties
!           (match-beginning bibtex-key-in-head)
!           (match-end bibtex-key-in-head)))))))
! 
! (defun bibtex-find-entry-location (entry-name &optional ignore-dups)
!   "Looking for place to put the BibTeX entry named ENTRY-NAME.
! Performs a binary search (therefore, buffer is assumed to be in sorted
! order, without duplicates (see \\[bibtex-validate]), if it is
! not, `bibtex-find-entry-location' will fail).  If entry-name is already
! used as a reference key, an error is signaled.  However, if optional
! variable IGNORE-DUPS is non-nil, no error messages about duplicate
! entries are signaled, but the error handling is assumed to be made in
! the calling function.
! The value is nil if a duplicate entry error occurred,
! and t in all other cases."
!   (let* ((case-fold-search t)
!          (left
!           (progn
!             (bibtex-beginning-of-first-entry)
!             (bibtex-skip-to-valid-entry)
!             (bibtex-end-of-entry)))
!          (right
!           (progn
!             (bibtex-beginning-of-last-entry)
!             (bibtex-skip-to-valid-entry t)
!             (point)))
!          actual-point
!          actual-key
!          (done (>= left right))
!          new
!          dup)
!     (while (not done)
!       (setq actual-point (/ (+ left right) 2))
!       (goto-char actual-point)
!       (bibtex-skip-to-valid-entry t)
!       (setq actual-key
!             (progn
!               (re-search-forward bibtex-entry-head)
!               (buffer-substring-no-properties
!                (match-beginning bibtex-key-in-head)
!                (match-end bibtex-key-in-head))))
!       (cond
!        ((string-lessp entry-name actual-key)
!         (setq new (bibtex-beginning-of-entry))
!         (if (equal right new)
!             (setq done t)
!           (setq right new)))
!        ((string-lessp actual-key entry-name)
!         (setq new (bibtex-end-of-entry))
!         (if (equal left new)
!             (setq done t)
!           (setq left new)))
!        ((string-equal actual-key entry-name)
!         (setq dup t
!               done t)
!         (if (not ignore-dups)
!             (progn
!               (bibtex-beginning-of-entry)
!               (error "Entry with key `%s' already exists" entry-name))))))
!     (if dup
!         (progn
!           (bibtex-beginning-of-entry)
!           nil)
!       (goto-char right)
!       (setq actual-key
!             (if (looking-at bibtex-entry-head)
!                 (buffer-substring-no-properties
!                  (match-beginning bibtex-key-in-entry)
!                  (match-end bibtex-key-in-entry))))
!       (if (or
!            (not actual-key)
!            (string-lessp actual-key entry-name))
!           ;; buffer contains no valid entries or
!           ;; greater than last entry --> append
!           (progn
!             (bibtex-end-of-entry)
!             (if (not (bobp))
!                 (newline (forward-line 2)))
!             (beginning-of-line))
!         (goto-char right))
!       t)))
  
  (defun bibtex-validate (&optional test-thoroughly)
    "Validate if buffer or region is syntactically correct.
--- 2923,3137 ----
  otherwise it counts all except Strings.
  If mark is active it counts entries in region, if not in whole buffer."
    (interactive "P")
!   (let ((number 0)
          (bibtex-sort-ignore-string-entries
           (not count-string-entries)))
!     (save-excursion
!       (save-restriction
!         (narrow-to-region (if (bibtex-mark-active)
!                               (region-beginning)
!                             (bibtex-beginning-of-first-entry))
!                           (if (bibtex-mark-active)
!                               (region-end)
!                             (point-max)))
!         (goto-char (point-min))
!         (bibtex-map-entries (lambda (key beg end)
!                               (setq number (1+ number))))))
!     (message "%s contains %d entries."
!              (if (bibtex-mark-active) "Region" "Buffer")
!              number)))
  
  (defun bibtex-ispell-entry ()
    "Spell whole BibTeX entry."
    (interactive)
!   (ispell-region (save-excursion (bibtex-beginning-of-entry))
!                  (save-excursion (bibtex-end-of-entry))))
  
  (defun bibtex-ispell-abstract ()
    "Spell abstract of BibTeX entry."
    (interactive)
!   (let ((bounds (save-excursion
!                   (bibtex-beginning-of-entry)
!                   (bibtex-search-forward-field "abstract" t))))
!     (if bounds
!         (ispell-region (bibtex-start-of-text-in-field bounds)
!                        (bibtex-end-of-text-in-field bounds))
!       (error "No abstract in entry"))))
  
  (defun bibtex-narrow-to-entry ()
    "Narrow buffer to current BibTeX entry."
    (interactive)
    (save-excursion
!     (widen)
!     (narrow-to-region (bibtex-beginning-of-entry)
!                       (bibtex-end-of-entry))))
! 
! (defun bibtex-entry-index ()
!   "Return the index of the BibTeX entry at point. Move point.
! The index is a list (KEY CROSSREF-KEY ENTRY-NAME) that is used for sorting
! the entries of the BibTeX buffer. Return nil if no entry found."
!   (let ((case-fold-search t))
!     (if (re-search-forward bibtex-entry-maybe-empty-head nil t)
!         (let ((key (bibtex-key-in-head))
!               ;; all entry names should be downcase (for ease of comparison)
!               (entry-name (downcase (bibtex-type-in-head))))
!           ;; Don't search CROSSREF-KEY if we don't need it.
!           (if (equal bibtex-maintain-sorted-entries 'crossref)
!               (save-excursion
!                 (bibtex-beginning-of-entry)
!                 (let ((bounds (bibtex-search-forward-field
!                                "\\(OPT\\)?crossref" t)))
!                   (list key
!                         (if bounds (bibtex-text-in-field-bounds bounds t))
!                         entry-name))))
!           (list key nil entry-name)))))
! 
! (defun bibtex-lessp (index1 index2)
!   "Predicate for sorting BibTeX entries with indices INDEX1 and INDEX2.
! Each index is a list (KEY CROSSREF-KEY ENTRY-NAME).
! The predicate depends on the variable `bibtex-maintain-sorted-entries'."
!   (cond ((not index1) (not index2)) ; indices can be nil
!         ((not index2) nil)
!         ((equal bibtex-maintain-sorted-entries 'crossref)
!          (if (nth 1 index1)
!              (if (nth 1 index2)
!                  (or (string-lessp (nth 1 index1) (nth 1 index2))
!                      (and (string-equal (nth 1 index1) (nth 1 index2))
!                           (string-lessp (nth 0 index1) (nth 0 index2))))
!                (not (string-lessp (nth 0 index2) (nth 1 index1))))
!            (if (nth 1 index2)
!                (string-lessp (nth 0 index1) (nth 1 index2))
!              (string-lessp (nth 0 index1) (nth 0 index2)))))
!         ((equal bibtex-maintain-sorted-entries 'entry-class)
!          (let ((n1 (cdr (or (assoc (nth 2 index1) 
bibtex-sort-entry-class-alist)
!                             (assoc 'catch-all bibtex-sort-entry-class-alist)
!                             '(nil . 1000))))  ; if there is nothing else
!                (n2 (cdr (or (assoc (nth 2 index2) 
bibtex-sort-entry-class-alist)
!                             (assoc 'catch-all bibtex-sort-entry-class-alist)
!                             '(nil . 1000))))) ; if there is nothing else
!            (or (< n1 n2)
!                (and (= n1 n2)
!                     (string-lessp (car index1) (car index2))))))
!         (t ; (equal bibtex-maintain-sorted-entries 'plain)
!          (string-lessp (car index1) (car index2)))))
  
  (defun bibtex-sort-buffer ()
    "Sort BibTeX buffer alphabetically by key.
+ The predicate for sorting is defined via `bibtex-maintain-sorted-entries'.
  Text outside of BibTeX entries is not affected.  If
  `bibtex-sort-ignore-string-entries' is non-nil, @String entries will be
  ignored."
    (interactive)
+   (unless bibtex-maintain-sorted-entries
+     (error "You must choose a sorting scheme"))
    (save-restriction
!     (narrow-to-region (bibtex-beginning-of-first-entry)
!                       (save-excursion (goto-char (point-max))
!                                       (bibtex-end-of-entry)))
      (bibtex-skip-to-valid-entry)
!     (sort-subr nil
!                'bibtex-skip-to-valid-entry ; NEXTREC function
!                'bibtex-end-of-entry        ; ENDREC function
!                'bibtex-entry-index         ; STARTKEY function
!                nil                         ; ENDKEY function
!                'bibtex-lessp)))            ; PREDICATE
! 
! (defun bibtex-find-crossref (crossref-key)
!   "Move point to the beginning of BibTeX entry CROSSREF-KEY.
! Return position of entry if CROSSREF-KEY is found and nil otherwise.
! If position of current entry is after CROSSREF-KEY an error is signaled.
! If called interactively, CROSSREF-KEY defaults to crossref key of current
! entry."
!   (interactive
!    (let ((crossref-key
!           (save-excursion
!             (bibtex-beginning-of-entry)
!             (let ((bounds (bibtex-search-forward-field "crossref" t)))
!               (if bounds
!                   (bibtex-text-in-field-bounds bounds t))))))
!      (list (bibtex-read-key "Find crossref key: " crossref-key))))
!   (let ((pos (save-excursion (bibtex-find-entry crossref-key))))
!     (if (and pos (> (point) pos))
!         (error "This entry must not follow the crossrefed entry!"))
!     (goto-char pos)))
! 
! (defun bibtex-find-entry (key)
!   "Move point to the beginning of BibTeX entry named KEY.
! Return position of entry if KEY is found or nil if not found."
!   (interactive (list (bibtex-read-key "Find key: ")))
!   (let* (case-fold-search
!          (pnt (save-excursion
!                 (goto-char (point-min))
!                 (if (re-search-forward (concat "^[ \t]*\\("
!                                                bibtex-entry-type
!                                                "\\)[ \t]*[({][ \t\n]*\\("
!                                                (regexp-quote key)
!                                                "\\)[ \t\n]*[,=]")
!                                        nil t)
!                     (match-beginning 0)))))
!     (cond (pnt
!            (goto-char pnt))
!           ((interactive-p)
!            (message "Key `%s' not found" key)))))
! 
! (defun bibtex-prepare-new-entry (index)
!   "Prepare a new BibTeX entry with index INDEX.
! INDEX is a list (KEY CROSSREF-KEY ENTRY-NAME).
! Move point where the entry KEY should be placed.
! If `bibtex-maintain-sorted-entries' is non-nil, perform a binary
! search to look for place for KEY. This will fail if buffer is not in
! sorted order, see \\[bibtex-validate].)
! Return t if preparation was successful or nil if entry KEY already exists."
!   (let ((key (nth 0 index))
!         key-exist)
!     (cond ((or (null key)
!                (and (stringp key)
!                     (string-equal key ""))
!                (and (not (setq key-exist (bibtex-find-entry key)))
!                     (not bibtex-maintain-sorted-entries)))
!            (bibtex-move-outside-of-entry))
!           ;; if key-exist is non-nil due to the previous cond clause
!           ;; then point will be at beginning of entry named key.
!           (key-exist)
!           (t             ; bibtex-maintain-sorted-entries is non-nil
!            (let* ((case-fold-search t)
!                   (left (save-excursion (bibtex-beginning-of-first-entry)
!                                         (bibtex-skip-to-valid-entry)
!                                         (point)))
!                   (right (save-excursion (bibtex-beginning-of-last-entry)
!                                          (bibtex-end-of-entry)))
!                   (found (if (>= left right) left))
!                   actual-index new)
!              (save-excursion
!                ;; Binary search
!                (while (not found)
!                  (goto-char (/ (+ left right) 2))
!                  (bibtex-skip-to-valid-entry t)
!                  (setq actual-index (bibtex-entry-index))
!                  (cond ((bibtex-lessp index actual-index)
!                         (setq new (bibtex-beginning-of-entry))
!                         (if (equal right new)
!                             (setq found right)
!                           (setq right new)))
!                        (t
!                         (bibtex-end-of-entry)
!                         (bibtex-skip-to-valid-entry)
!                         (setq new (point))
!                         (if (equal left new)
!                             (setq found right)
!                           (setq left new))))))
!              (goto-char found)
!              (bibtex-beginning-of-entry)
!              (setq actual-index (save-excursion (bibtex-entry-index)))
!              (when (or (not actual-index)
!                        (bibtex-lessp actual-index index))
!                ;; buffer contains no valid entries or
!                ;; greater than last entry --> append
!                (bibtex-end-of-entry)
!                (if (not (bobp))
!                    (newline (forward-line 2)))
!                (beginning-of-line)))))
!     (unless key-exist t)))
  
  (defun bibtex-validate (&optional test-thoroughly)
    "Validate if buffer or region is syntactically correct.
***************
*** 3250,3416 ****
  outside of entries.
  With optional argument TEST-THOROUGHLY non-nil it checks for absence of
  required fields and questionable month fields as well.
! If mark is active, it validates current region, if not whole buffer.
  Returns t if test was successful, nil otherwise."
    (interactive "P")
!   (let* (error-list
!        syntax-error
!        (case-fold-search t)
!        (valid-bibtex-entry
!         (concat
!          "@[ \t]*\\(\\(string\\)\\|"
!          (mapconcat
!           (lambda (type)
!             (concat "\\(" (car type) "\\)"))
!           bibtex-entry-field-alist
!           "\\|")
!          "\\)"))
!        (pnt (point))
!        (start-point
!         (if (bibtex-mark-active)
!             (region-beginning)
!           (bibtex-beginning-of-first-entry)))
!        (end-point
!         (if (bibtex-mark-active)
!             (region-end)
!           (point-max))))
!     (save-restriction
!       (narrow-to-region start-point end-point)
!       ;; looking if entries fit syntactical structure
!       (goto-char start-point)
!       (bibtex-progress-message "Checking syntactical structure")
!       (while (re-search-forward "^[ \t]*@" nil t)
!         (bibtex-progress-message)
!         (forward-char -1)
!         (let ((p (point))
!               (must-match
!                (looking-at valid-bibtex-entry)))
!           (if (not must-match)
!               (forward-char)
!             (let (bibtex-sort-ignore-string-entries)
!               (bibtex-skip-to-valid-entry))
!             (if (equal (point) p)
!                 (forward-char)
!               (goto-char p)
!               (setq
!                error-list
!                (cons (list
!                       (bibtex-current-line)
!                       "Syntax error (check esp. commas, braces, and quotes)")
!                      error-list))
!               (forward-char)))))
!       (bibtex-progress-message 'done)
!       (if error-list
!           (setq syntax-error t)
!         ;; looking for correct sort order and duplicates (only if
!         ;; there were no syntax errors)
!         (if bibtex-maintain-sorted-entries
!             (let (previous)
!               (goto-char start-point)
!               (bibtex-progress-message "Checking correct sort order")
!               (bibtex-map-entries
!                (lambda (current)
!                  (bibtex-progress-message)
!                  (cond ((or (not previous)
!                             (string< previous current))
!                         (setq previous current))
!                        ((string-equal previous current)
!                         (setq
!                          error-list
!                          (cons (list (bibtex-current-line)
!                                      "Duplicate key with previous")
!                                error-list)))
!                        (t
!                         (setq previous current
!                               error-list
!                               (cons (list (bibtex-current-line)
!                                           "Entries out of order")
!                                     error-list))))))
!               (bibtex-progress-message 'done)))
!         (if test-thoroughly
!             (progn
!               (goto-char start-point)
!               (bibtex-progress-message
!                "Checking required fields and month fields")
!               (let ((bibtex-sort-ignore-string-entries t)
!                     (questionable-month
!                      (concat
!                       "[{\"]\\("
!                       (mapconcat
!                        (lambda (mon)
!                          (concat "\\(" (car mon) "\\)"))
!                        bibtex-predefined-month-strings
!                        "\\|")
!                       "\\)[}\"]")))
                  (bibtex-map-entries
!                  (lambda (current)
                     (bibtex-progress-message)
!                    (let* ((beg (bibtex-beginning-of-entry))
!                           (end (bibtex-end-of-entry))
!                           (entry-list
!                            (progn
!                              (goto-char beg)
!                              (bibtex-search-entry nil end)
!                              (assoc-ignore-case
!                               (buffer-substring-no-properties
!                                (1+ (match-beginning bibtex-type-in-head))
!                                (match-end bibtex-type-in-head))
!                               bibtex-entry-field-alist)))
!                           (req (copy-sequence (elt (elt entry-list 1) 0)))
!                           (creq (copy-sequence (elt (elt entry-list 2) 0)))
!                           crossref-there)
!                      (goto-char beg)
!                    (let ((bounds (bibtex-search-forward-field 
bibtex-field-name end)))
!                      (while bounds
!                        (let ((field-name
!                               (buffer-substring-no-properties
!                                (bibtex-start-of-name-in-field bounds)
!                                (bibtex-end-of-name-in-field bounds))))
!                          (if (and (equal (downcase field-name) "month")
!                                   (string-match
!                                    questionable-month
!                                    (buffer-substring-no-properties
!                                     (bibtex-start-of-text-in-field bounds)
!                                     (bibtex-end-of-text-in-field bounds))))
!                              (setq
!                               error-list
!                               (cons
!                                (list
!                                 (bibtex-current-line)
!                                 "Questionable month field (delimited string)")
!                                error-list)))
!                          (setq
!                           req
!                           (delete (assoc-ignore-case field-name req) req)
!                           creq
!                           (delete (assoc-ignore-case field-name creq) creq))
!                          (if (equal (downcase field-name) "crossref")
!                              (setq crossref-there t)))
!                        (goto-char (bibtex-end-of-field bounds))
!                        (setq bounds (bibtex-search-forward-field 
bibtex-field-name end))))
!                      (if crossref-there
!                          (setq req creq))
!                      (if (or (> (length req) 1)
!                              (and (= (length req) 1)
!                                   (not (elt (car req) 3))))
!                          ;; two (or more) fields missed or one field
!                          ;; missed and this isn't flagged alternative
!                          ;; (notice that this fails if there are more
!                          ;; than two alternatives in a BibTeX entry,
!                          ;; which isn't the case momentarily)
!                          (setq
!                           error-list
!                           (cons
!                            (list (save-excursion
!                                    (bibtex-beginning-of-entry)
!                                    (bibtex-current-line))
!                                  (concat
!                                   "Required field \""
!                                   (car (car req))
!                                   "\" missing"))
!                            error-list)))))))
!               (bibtex-progress-message 'done)))))
!     (goto-char pnt)
      (if error-list
          (let ((bufnam (buffer-name))
                (dir default-directory))
--- 3139,3255 ----
  outside of entries.
  With optional argument TEST-THOROUGHLY non-nil it checks for absence of
  required fields and questionable month fields as well.
! If mark is active, validate current region, if not the whole buffer.
  Returns t if test was successful, nil otherwise."
    (interactive "P")
!   (let* ((case-fold-search t)
!          error-list syntax-error)
!     (save-excursion
!       (save-restriction
!         (narrow-to-region (if (bibtex-mark-active)
!                               (region-beginning)
!                             (bibtex-beginning-of-first-entry))
!                           (if (bibtex-mark-active)
!                               (region-end)
!                             (point-max)))
! 
!         ;; looking if entries fit syntactical structure
!         (goto-char (point-min))
!         (bibtex-progress-message "Checking syntactical structure")
!         (let (bibtex-sort-ignore-string-entries)
!           (while (re-search-forward "^[ \t]*@" nil t)
!             (bibtex-progress-message)
!             (forward-char -1)
!             (let ((pnt (point)))
!               (if (not (looking-at bibtex-any-valid-entry-re))
!                   (forward-char)
!                 (bibtex-skip-to-valid-entry)
!                 (if (equal (point) pnt)
!                     (forward-char)
!                   (goto-char pnt)
!                   (push (list (bibtex-current-line)
!                               "Syntax error (check esp. commas, braces, and 
quotes)")
!                         error-list)
!                   (forward-char))))))
!         (bibtex-progress-message 'done)
! 
!         (if error-list
!             (setq syntax-error t)
!           ;; looking for correct sort order and duplicates (only if
!           ;; there were no syntax errors)
!           (if bibtex-maintain-sorted-entries
!               (let (previous current)
!                 (goto-char (point-min))
!                 (bibtex-progress-message "Checking correct sort order")
                  (bibtex-map-entries
!                  (lambda (key beg end)
                     (bibtex-progress-message)
!                    (goto-char beg)
!                    (setq current (bibtex-entry-index))
!                    (cond ((or (not previous)
!                               (bibtex-lessp previous current))
!                           (setq previous current))
!                          ((string-equal (car previous) (car current))
!                           (push (list (bibtex-current-line)
!                                       "Duplicate key with previous")
!                                 error-list))
!                          (t
!                           (setq previous current)
!                           (push (list (bibtex-current-line)
!                                       "Entries out of order")
!                                 error-list)))))
!                 (bibtex-progress-message 'done)))
! 
!           (when test-thoroughly
!             (goto-char (point-min))
!             (bibtex-progress-message
!              "Checking required fields and month fields")
!             (let ((bibtex-sort-ignore-string-entries t)
!                   (questionable-month
!                    (regexp-opt (mapcar 'car 
bibtex-predefined-month-strings))))
!               (bibtex-map-entries
!                (lambda (key beg end)
!                  (bibtex-progress-message)
!                  (let* ((entry-list (progn
!                                       (goto-char beg)
!                                       (bibtex-search-entry nil end)
!                                       (assoc-ignore-case (bibtex-type-in-head)
!                                                          
bibtex-entry-field-alist)))
!                         (req (copy-sequence (elt (elt entry-list 1) 0)))
!                         (creq (copy-sequence (elt (elt entry-list 2) 0)))
!                         crossref-there bounds)
!                    (goto-char beg)
!                    (while (setq bounds (bibtex-search-forward-field
!                                         bibtex-field-name end))
!                      (goto-char (bibtex-start-of-text-in-field bounds))
!                      (let ((field-name (downcase (bibtex-name-in-field 
bounds)))
!                            case-fold-search)
!                        (if (and (equal field-name "month")
!                                 (not (string-match questionable-month
!                                                    
(bibtex-text-in-field-bounds bounds))))
!                            (push (list (bibtex-current-line)
!                                        "Questionable month field")
!                                  error-list))
!                        (setq req (delete (assoc-ignore-case field-name req) 
req)
!                              creq (delete (assoc-ignore-case field-name creq) 
creq))
!                        (if (equal field-name "crossref")
!                            (setq crossref-there t))))
!                    (if crossref-there
!                        (setq req creq))
!                    (if (or (> (length req) 1)
!                            (and (= (length req) 1)
!                                 (not (elt (car req) 3))))
!                        ;; two (or more) fields missed or one field
!                        ;; missed and this isn't flagged alternative
!                        ;; (notice that this fails if there are more
!                        ;; than two alternatives in a BibTeX entry,
!                        ;; which isn't the case momentarily)
!                        (push (list (save-excursion
!                                      (bibtex-beginning-of-entry)
!                                      (bibtex-current-line))
!                                    (concat "Required field `" (caar req) "' 
missing"))
!                              error-list))))))
!             (bibtex-progress-message 'done)))))
      (if error-list
          (let ((bufnam (buffer-name))
                (dir default-directory))
***************
*** 3429,3450 ****
            (compilation-mode)
            (delete-region (point-min) (point-max))
            (goto-char (point-min))
!           (insert
!            "BibTeX mode command `bibtex-validate'\n"
!            (if syntax-error
!                "Maybe undetected errors due to syntax errors. Correct and 
validate again."
!              "")
!            "\n")
!           (while error-list
!             (insert
!              bufnam ":" (number-to-string (elt (car error-list) 0))
!              ": " (elt (car error-list) 1) "\n")
!             (setq error-list (cdr error-list)))
            (compilation-parse-errors nil nil)
            (setq compilation-old-error-list compilation-error-list)
            ;; this is necessary to avoid reparsing of buffer if you
!           ;; switch to compilation buffer and enter
!           ;; `compile-goto-error'
            (set-buffer-modified-p nil)
            (toggle-read-only 1)
            (goto-char (point-min))
--- 3268,3285 ----
            (compilation-mode)
            (delete-region (point-min) (point-max))
            (goto-char (point-min))
!           (insert "BibTeX mode command `bibtex-validate'\n"
!                   (if syntax-error
!                       "Maybe undetected errors due to syntax errors. Correct 
and validate again."
!                     "")
!                   "\n")
!           (dolist (err error-list)
!             (insert bufnam ":" (number-to-string (elt err 0))
!                     ": " (elt err 1) "\n"))
            (compilation-parse-errors nil nil)
            (setq compilation-old-error-list compilation-error-list)
            ;; this is necessary to avoid reparsing of buffer if you
!           ;; switch to compilation buffer and enter `compile-goto-error'
            (set-buffer-modified-p nil)
            (toggle-read-only 1)
            (goto-char (point-min))
***************
*** 3457,3591 ****
        t)))
  
  (defun bibtex-next-field (arg)
!   "Finds end of text of next BibTeX field; with ARG, to its beginning."
    (interactive "P")
    (bibtex-inside-field)
    (let ((start (point)))
      (condition-case ()
!       (let ((bounds (bibtex-enclosing-field)))
!         (goto-char (bibtex-end-of-field bounds))
!         (forward-char 2))
        (error
         (goto-char start)
         (end-of-line)
         (forward-char))))
    (bibtex-find-text arg t))
  
! (defun bibtex-find-text (arg &optional as-if-interactive silent)
    "Go to end of text of current field; with ARG, go to beginning."
    (interactive "P")
    (bibtex-inside-field)
!   (let ((bounds (bibtex-enclosing-field (or (interactive-p) 
as-if-interactive))))
      (if bounds
!       (progn
!         (if arg
!             (progn
!               (goto-char (bibtex-start-of-text-in-field bounds))
!               (if (looking-at "[{\"]")
!                   (forward-char)))
!           (goto-char (bibtex-end-of-text-in-field bounds))
!           (if (or
!                (= (preceding-char) ?})
!                (= (preceding-char) ?\"))
!               (forward-char -1)))
!         (if bibtex-help-message
!             (bibtex-print-help-message)))
        (beginning-of-line)
!       (cond
!        ((bibtex-parse-string)
!       (let ((bounds (bibtex-parse-string)))
!         (goto-char
!          (if arg
!              (bibtex-start-of-text-in-string bounds)
!            (bibtex-end-of-text-in-string bounds)))))
!        ((looking-at bibtex-entry-maybe-empty-head)
!       (goto-char
!        (if arg
!            (match-beginning bibtex-key-in-head)
!          (match-end 0))))
!        (t
!       (if (not silent)
!           (error "Not on BibTeX field")))))))
  
  (defun bibtex-remove-OPT-or-ALT ()
!   "Removes the string starting optional/alternative fields.
! Aligns text and goes thereafter to end of text."
    (interactive)
    (bibtex-inside-field)
!   (let* ((case-fold-search t)
!        (bounds (bibtex-enclosing-field)))
      (save-excursion
        (goto-char (bibtex-start-of-name-in-field bounds))
!       (if (looking-at "OPT\\|ALT")
!           (progn
!             (delete-char (length "OPT"))
!             ;; make field non-OPT
!             (search-forward "=")
!             (forward-char -1)
!             (delete-horizontal-space)
!             (if bibtex-align-at-equal-sign
!                 (indent-to-column (- bibtex-text-indentation 2))
!               (insert " "))
!             (search-forward "=")
!             (delete-horizontal-space)
!             (if bibtex-align-at-equal-sign
!                 (insert " ")
!               (indent-to-column bibtex-text-indentation)))))
      (bibtex-inside-field)))
  
  (defun bibtex-remove-delimiters ()
!   "Removes \"\" or {} around string."
    (interactive)
    (save-excursion
      (bibtex-inside-field)
!     (let* ((case-fold-search t)
!          (bounds (bibtex-enclosing-field))
!          (stop (copy-marker (bibtex-end-of-text-in-field bounds))))
        (goto-char (bibtex-start-of-text-in-field bounds))
!       (let* ((boundaries (bibtex-search-forward-field-string stop)))
!       (while boundaries
!         (let ((text-end (copy-marker (cdr boundaries))))
!           (goto-char (car boundaries))
!           (delete-char 1)
!           (goto-char text-end)
!           (delete-backward-char 1)
!           (setq boundaries (bibtex-search-forward-field-string stop))))))))
  
  (defun bibtex-kill-field (&optional copy-only)
!   "Kills the entire enclosing BibTeX field.
! With prefix arg COPY-ONLY, copy the current field to `bibtex-field-kill-ring,'
  but do not actually kill it."
    (interactive "P")
!   (let* ((pnt (point))
!        (case-fold-search t))
      (bibtex-inside-field)
!     (let* ((bounds (bibtex-enclosing-field))
!          (the-end (bibtex-end-of-field bounds))
!          (the-beginning (bibtex-start-of-field bounds)))
!       (goto-char the-end)
        (skip-chars-forward " \t\n,")
!       (setq
!        bibtex-field-kill-ring
!        (cons
!         (list
!          'field
!          (buffer-substring-no-properties
!           (bibtex-start-of-name-in-field bounds)
!           (bibtex-end-of-name-in-field bounds))
!          (buffer-substring-no-properties
!           (bibtex-start-of-text-in-field bounds)
!           (bibtex-end-of-text-in-field bounds)))
!         bibtex-field-kill-ring))
        (if (> (length bibtex-field-kill-ring) bibtex-field-kill-ring-max)
!           (setcdr
!            (nthcdr (1- bibtex-field-kill-ring-max) bibtex-field-kill-ring)
!            nil))
        (setq bibtex-field-kill-ring-yank-pointer bibtex-field-kill-ring)
!       (if copy-only
!           (goto-char pnt)
!         (delete-region the-beginning the-end)
!         (let (bibtex-help-message)
!           (bibtex-find-text nil t t)))))
    (setq bibtex-last-kill-command 'field))
  
  (defun bibtex-copy-field-as-kill ()
--- 3292,3400 ----
        t)))
  
  (defun bibtex-next-field (arg)
!   "Find end of text of next BibTeX field; with ARG, to its beginning."
    (interactive "P")
    (bibtex-inside-field)
    (let ((start (point)))
      (condition-case ()
!         (let ((bounds (bibtex-enclosing-field)))
!           (goto-char (bibtex-end-of-field bounds))
!           (forward-char 2))
        (error
         (goto-char start)
         (end-of-line)
         (forward-char))))
    (bibtex-find-text arg t))
  
! (defun bibtex-find-text (arg &optional as-if-interactive no-error)
    "Go to end of text of current field; with ARG, go to beginning."
    (interactive "P")
    (bibtex-inside-field)
!   (let ((bounds (bibtex-enclosing-field (or (interactive-p)
!                                             as-if-interactive))))
      (if bounds
!         (progn (if arg
!                    (progn (goto-char (bibtex-start-of-text-in-field bounds))
!                           (if (looking-at "[{\"]")
!                               (forward-char)))
!                  (goto-char (bibtex-end-of-text-in-field bounds))
!                  (if (or (= (preceding-char) ?})
!                          (= (preceding-char) ?\"))
!                      (forward-char -1)))
!                (if bibtex-help-message
!                    (bibtex-print-help-message)))
        (beginning-of-line)
!       (cond ((setq bounds (bibtex-parse-string))
!              (goto-char (if arg
!                             (bibtex-start-of-text-in-string bounds)
!                           (bibtex-end-of-text-in-string bounds))))
!             ((looking-at bibtex-entry-maybe-empty-head)
!              (goto-char (if arg
!                             (match-beginning bibtex-key-in-head)
!                           (match-end 0))))
!             (t
!              (unless no-error
!                  (error "Not on BibTeX field")))))))
  
  (defun bibtex-remove-OPT-or-ALT ()
!   "Remove the string starting optional/alternative fields.
! Align text and go thereafter to end of text."
    (interactive)
    (bibtex-inside-field)
!   (let ((case-fold-search t)
!         (bounds (bibtex-enclosing-field)))
      (save-excursion
        (goto-char (bibtex-start-of-name-in-field bounds))
!       (when (looking-at "OPT\\|ALT")
!         (delete-region (match-beginning 0) (match-end 0))
!         ;; make field non-OPT
!         (search-forward "=")
!         (forward-char -1)
!         (delete-horizontal-space)
!         (if bibtex-align-at-equal-sign
!             (indent-to-column (- bibtex-text-indentation 2))
!           (insert " "))
!         (search-forward "=")
!         (delete-horizontal-space)
!         (if bibtex-align-at-equal-sign
!             (insert " ")
!           (indent-to-column bibtex-text-indentation))))
      (bibtex-inside-field)))
  
  (defun bibtex-remove-delimiters ()
!   "Remove \"\" or {} around string."
    (interactive)
    (save-excursion
      (bibtex-inside-field)
!     (let ((bounds (bibtex-enclosing-field)))
        (goto-char (bibtex-start-of-text-in-field bounds))
!       (delete-char 1)
!       (goto-char (1- (bibtex-end-of-text-in-field bounds)))
!       (delete-backward-char 1))))
  
  (defun bibtex-kill-field (&optional copy-only)
!   "Kill the entire enclosing BibTeX field.
! With prefix arg COPY-ONLY, copy the current field to `bibtex-field-kill-ring',
  but do not actually kill it."
    (interactive "P")
!   (save-excursion
      (bibtex-inside-field)
!     (let* ((case-fold-search t)
!            (bounds (bibtex-enclosing-field))
!            (end (bibtex-end-of-field bounds))
!            (beg (bibtex-start-of-field bounds)))
!       (goto-char end)
        (skip-chars-forward " \t\n,")
!       (push (list 'field (bibtex-name-in-field bounds)
!                   (bibtex-text-in-field-bounds bounds))
!             bibtex-field-kill-ring)
        (if (> (length bibtex-field-kill-ring) bibtex-field-kill-ring-max)
!           (setcdr (nthcdr (1- bibtex-field-kill-ring-max)
!                           bibtex-field-kill-ring)
!                   nil))
        (setq bibtex-field-kill-ring-yank-pointer bibtex-field-kill-ring)
!       (unless copy-only
!         (delete-region beg end))))
    (setq bibtex-last-kill-command 'field))
  
  (defun bibtex-copy-field-as-kill ()
***************
*** 3597,3625 ****
  With prefix arg COPY-ONLY the current entry to
  `bibtex-entry-kill-ring', but do not actually kill it."
    (interactive "P")
!   (let* ((pnt (point))
!        (case-fold-search t)
!        (beg (bibtex-beginning-of-entry))
!        (end
!         (progn
!           (bibtex-end-of-entry)
!           (if (re-search-forward
!                bibtex-entry-maybe-empty-head nil 'move)
!               (goto-char (match-beginning 0)))
!           (point))))
!     (setq
!      bibtex-entry-kill-ring
!      (cons
!       (list 'entry (buffer-substring-no-properties beg end))
!       bibtex-entry-kill-ring))
!     (if (> (length bibtex-entry-kill-ring) bibtex-entry-kill-ring-max)
!         (setcdr
!          (nthcdr (1- bibtex-entry-kill-ring-max) bibtex-entry-kill-ring)
!          nil))
      (setq bibtex-entry-kill-ring-yank-pointer bibtex-entry-kill-ring)
!     (if copy-only
!         (goto-char pnt)
!       (delete-region beg end)))
    (setq bibtex-last-kill-command 'entry))
  
  (defun bibtex-copy-entry-as-kill ()
--- 3406,3428 ----
  With prefix arg COPY-ONLY the current entry to
  `bibtex-entry-kill-ring', but do not actually kill it."
    (interactive "P")
!   (save-excursion
!     (let* ((case-fold-search t)
!            (beg (bibtex-beginning-of-entry))
!            (end (progn (bibtex-end-of-entry)
!                        (if (re-search-forward
!                             bibtex-entry-maybe-empty-head nil 'move)
!                            (goto-char (match-beginning 0)))
!                        (point))))
!       (push (list 'entry (buffer-substring-no-properties beg end))
!             bibtex-entry-kill-ring)
!       (if (> (length bibtex-entry-kill-ring) bibtex-entry-kill-ring-max)
!           (setcdr (nthcdr (1- bibtex-entry-kill-ring-max)
!                           bibtex-entry-kill-ring)
!                   nil))
      (setq bibtex-entry-kill-ring-yank-pointer bibtex-entry-kill-ring)
!     (unless copy-only
!       (delete-region beg end))))
    (setq bibtex-last-kill-command 'entry))
  
  (defun bibtex-copy-entry-as-kill ()
***************
*** 3665,3671 ****
      (goto-char (bibtex-start-of-text-in-field bounds))
      (delete-region (point) (bibtex-end-of-text-in-field bounds))
      (insert (concat (bibtex-field-left-delimiter)
!                   (bibtex-field-right-delimiter)) )
      (bibtex-find-text t)))
  
  (defun bibtex-pop-previous (arg)
--- 3468,3474 ----
      (goto-char (bibtex-start-of-text-in-field bounds))
      (delete-region (point) (bibtex-end-of-text-in-field bounds))
      (insert (concat (bibtex-field-left-delimiter)
!                     (bibtex-field-right-delimiter)) )
      (bibtex-find-text t)))
  
  (defun bibtex-pop-previous (arg)
***************
*** 3682,3796 ****
    (interactive "p")
    (bibtex-pop arg 'next))
  
! (defun bibtex-clean-entry (&optional new-reference-key called-by-reformat)
    "Finish editing the current BibTeX entry and clean it up.
! Checks that no required fields are empty and formats entry dependent
! on the value of bibtex-entry-format.
  If the reference key of the entry is empty or a prefix argument is given,
! calculate a new reference key (note: this only will work if fields in entry
! begin on separate lines prior to calling bibtex-clean-entry or if 'realign is
! contained in bibtex-entry-format).
! Don't call this on `string' or `preamble' entries.
  At end of the cleaning process, the functions in
! bibtex-clean-entry-hook are called with region narrowed to entry."
    (interactive "P")
!   (bibtex-format-entry)
!   (let* ((case-fold-search t)
!          (eob (bibtex-end-of-entry))
!          (key (progn
!                 (bibtex-beginning-of-entry)
!                 (if (re-search-forward
!                      bibtex-entry-head eob t)
!                     (buffer-substring-no-properties
!                      (match-beginning bibtex-key-in-head)
!                      (match-end bibtex-key-in-head))))))
!     (if (or
!          new-reference-key
!          (not key))
!         (progn
!           (let ((autokey
!                  (if bibtex-autokey-edit-before-use
!                      (read-from-minibuffer
!                       "Key to use: " (bibtex-generate-autokey) nil nil
!                       'bibtex-key-history)
!                    (bibtex-generate-autokey))))
!             (bibtex-beginning-of-entry)
!             (re-search-forward bibtex-entry-maybe-empty-head)
!             (if (match-beginning bibtex-key-in-head)
!                 (delete-region (match-beginning bibtex-key-in-head)
!                                (match-end bibtex-key-in-head)))
!             (insert autokey)
!             (let* ((start (bibtex-beginning-of-entry))
!                    (end (progn
!                           (bibtex-end-of-entry)
!                           (if (re-search-forward
!                                bibtex-entry-maybe-empty-head nil 'move)
!                               (goto-char (match-beginning 0)))
!                           (point)))
!                    (entry (buffer-substring start end)))
!               (delete-region start end)
!               (let ((success
!                      (or
!                       called-by-reformat
!                       (not bibtex-maintain-sorted-entries)
!                       (bibtex-find-entry-location autokey t))))
                  (insert entry)
                  (forward-char -1)
!                 (bibtex-beginning-of-entry)
!                 (re-search-forward bibtex-entry-head)
!                 (if (not success)
!                     (error
!                      "New inserted entry yields duplicate key"))))))))
!   (if (not called-by-reformat)
        (save-excursion
          (save-restriction
!           (narrow-to-region
!            (bibtex-beginning-of-entry) (bibtex-end-of-entry))
!           (bibtex-parse-keys t nil)
!           (run-hooks 'bibtex-clean-entry-hook)))))
  
  (defun bibtex-fill-entry ()
!   "Fill current entry.
! Realigns entry, so that every field starts on a separate line.  Field
  names appear in column `bibtex-field-indentation', field text starts in
  column `bibtex-text-indentation' and continuation lines start here, too.
! If `bibtex-align-at-equal-sign' is non-nil, align equal signs also."
    (interactive "*")
    (let ((pnt (copy-marker (point)))
!         (end (copy-marker (bibtex-end-of-entry))))
      (bibtex-beginning-of-entry)
      (bibtex-delete-whitespace)
      (indent-to-column bibtex-entry-offset)
!     (let ((bounds (bibtex-search-forward-field bibtex-field-name end)))
!       (while bounds
!       (let* ((begin-field (copy-marker (bibtex-start-of-field bounds)))
!              (end-field (copy-marker (bibtex-end-of-field bounds)))
!              (begin-name (copy-marker (bibtex-start-of-name-in-field bounds)))
!              (end-name (copy-marker (bibtex-end-of-name-in-field bounds))))
!         (goto-char begin-field)
!         (forward-char)
!         (bibtex-delete-whitespace)
!         (open-line 1)
!         (forward-char)
!         (indent-to-column
!          (+ bibtex-entry-offset bibtex-field-indentation))
!         (re-search-forward "[ \t\n]*=" end)
!         (replace-match "=")
!         (forward-char -1)
!         (if bibtex-align-at-equal-sign
!             (indent-to-column
!              (+ bibtex-entry-offset (- bibtex-text-indentation 2)))
!           (insert " "))
!         (forward-char)
!         (bibtex-delete-whitespace)
!         (if bibtex-align-at-equal-sign
!             (insert " ")
!           (indent-to-column bibtex-text-indentation))
!         (while (re-search-forward "[ \t\n]+" end-field 'move)
!           (replace-match " "))
!         (bibtex-do-auto-fill)
!         (goto-char end-field))
!       (setq bounds (bibtex-search-forward-field bibtex-field-name end))))
      (if (looking-at ",")
          (forward-char))
      (bibtex-delete-whitespace)
--- 3485,3619 ----
    (interactive "p")
    (bibtex-pop arg 'next))
  
! (defun bibtex-clean-entry (&optional new-key called-by-reformat)
    "Finish editing the current BibTeX entry and clean it up.
! Check that no required fields are empty and formats entry dependent
! on the value of `bibtex-entry-format'.
  If the reference key of the entry is empty or a prefix argument is given,
! calculate a new reference key. (Note: this will only work if fields in entry
! begin on separate lines prior to calling `bibtex-clean-entry' or if
! 'realign is contained in `bibtex-entry-format'.)
! Don't call `bibtex-clean-entry' on @Preamble entries.
  At end of the cleaning process, the functions in
! `bibtex-clean-entry-hook' are called with region narrowed to entry."
!   ;; Opt. arg called-by-reformat is t if bibtex-clean-entry
!   ;; is called by bibtex-reformat
    (interactive "P")
!   (let ((case-fold-search t)
!         entry-type key)
!     (bibtex-beginning-of-entry)
!     (save-excursion
!       (when (re-search-forward bibtex-entry-maybe-empty-head nil t)
!         (setq entry-type (downcase (bibtex-type-in-head)))
!         (setq key (bibtex-key-in-head))))
!     ;; formatting
!     (cond ((equal entry-type "preamble")
!            ;; (bibtex-format-preamble)
!            (error "No clean up of @Preamble entries"))
!           ((equal entry-type "string"))
!            ;; (bibtex-format-string)
!           (t (bibtex-format-entry)))
!     ;; set key
!     (when (or new-key (not key))
!       (setq key (bibtex-generate-autokey))
!       (if bibtex-autokey-edit-before-use
!           (setq key (bibtex-read-key "Key to use: " key)))
!       (re-search-forward bibtex-entry-maybe-empty-head)
!       (if (match-beginning bibtex-key-in-head)
!           (delete-region (match-beginning bibtex-key-in-head)
!                          (match-end bibtex-key-in-head)))
!       (insert key))
!     ;; sorting
!     (let* ((start (bibtex-beginning-of-entry))
!            (end (progn (bibtex-end-of-entry)
!                        (if (re-search-forward
!                             bibtex-entry-maybe-empty-head nil 'move)
!                            (goto-char (match-beginning 0)))
!                        (point)))
!            (entry (buffer-substring start end))
!            (index (progn (goto-char start)
!                          (bibtex-entry-index))))
!       (delete-region start end)
!       (unless (prog1 (or called-by-reformat
!                          (if (and bibtex-maintain-sorted-entries
!                                   (not (and bibtex-sort-ignore-string-entries
!                                             (equal entry-type "string"))))
!                              (bibtex-prepare-new-entry index)
!                            (not (bibtex-find-entry (car index)))))
                  (insert entry)
                  (forward-char -1)
!                 (bibtex-beginning-of-entry) ; moves backward
!                 (re-search-forward bibtex-entry-head))
!         (error "New inserted entry yields duplicate key")))
!     ;; final clean up
!     (unless called-by-reformat
        (save-excursion
          (save-restriction
!           (bibtex-narrow-to-entry)
!           ;; Only update the list of keys if it has been built already.
!           (cond ((equal entry-type "string")
!                  (if (listp bibtex-strings) (bibtex-parse-strings t)))
!                 ((listp bibtex-reference-keys) (bibtex-parse-keys t)))
!           (run-hooks 'bibtex-clean-entry-hook))))))
! 
! (defun bibtex-fill-field-bounds (bounds justify &optional move)
!   "Fill BibTeX field delimited by BOUNDS.
! If JUSTIFY is non-nil justify as well.
! If optional arg MOVE is non-nil move point to end of field."
!   (let ((end-field (copy-marker (bibtex-end-of-field bounds))))
!     (goto-char (bibtex-start-of-field bounds))
!     (if justify
!         (progn
!           (forward-char)
!           (bibtex-delete-whitespace)
!           (open-line 1)
!           (forward-char)
!           (indent-to-column (+ bibtex-entry-offset
!                                bibtex-field-indentation))
!           (re-search-forward "[ \t\n]*=" end-field)
!           (replace-match "=")
!           (forward-char -1)
!           (if bibtex-align-at-equal-sign
!               (indent-to-column
!                (+ bibtex-entry-offset (- bibtex-text-indentation 2)))
!             (insert " "))
!           (forward-char)
!           (bibtex-delete-whitespace)
!           (if bibtex-align-at-equal-sign
!               (insert " ")
!             (indent-to-column bibtex-text-indentation)))
!       (re-search-forward "[ \t\n]*=[ \t\n]*" end-field))
!     (while (re-search-forward "[ \t\n]+" end-field 'move)
!       (replace-match " "))
!     (do-auto-fill)
!     (if move (goto-char end-field))))
! 
! (defun bibtex-fill-field (&optional justify)
!   "Like \\[fill-paragraph], but fill current BibTeX field.
! Optional prefix arg JUSTIFY non-nil means justify as well.
! In BibTeX mode this function is bound to `fill-paragraph-function'."
!   (interactive "*P")
!   (let ((pnt (copy-marker (point)))
!         (bounds (bibtex-enclosing-field)))
!     (when bounds
!       (bibtex-fill-field-bounds bounds justify)
!       (goto-char pnt))))
  
  (defun bibtex-fill-entry ()
!   "Fill current BibTeX entry.
! Realign entry, so that every field starts on a separate line.  Field
  names appear in column `bibtex-field-indentation', field text starts in
  column `bibtex-text-indentation' and continuation lines start here, too.
! If `bibtex-align-at-equal-sign' is non-nil, align equal signs, too."
    (interactive "*")
    (let ((pnt (copy-marker (point)))
!         (end (copy-marker (bibtex-end-of-entry)))
!         bounds)
      (bibtex-beginning-of-entry)
      (bibtex-delete-whitespace)
      (indent-to-column bibtex-entry-offset)
!     (while (setq bounds (bibtex-search-forward-field bibtex-field-name end))
!       (bibtex-fill-field-bounds bounds t t))
      (if (looking-at ",")
          (forward-char))
      (bibtex-delete-whitespace)
***************
*** 3814,3914 ****
            (if additional-options
                (if use-previous-options
                    bibtex-reformat-previous-options
!                 (setq
!                  bibtex-reformat-previous-options
!                  (delq
!                   nil
!                   (list
!                    (if (or
!                         called-by-convert-alien
!                         (y-or-n-p
!                          "Realign entries (recommended for files not created 
by BibTeX mode)? "))
!                        'realign)
!                    (if (y-or-n-p
!                         "Remove empty optional and alternative fields? ")
!                        'opts-or-alts)
!                    (if (y-or-n-p
!                         "Remove delimiters around pure numerical fields? ")
!                        'numerical-fields)
!                    (if (y-or-n-p (concat
!                                   (if bibtex-comma-after-last-field
!                                       "Insert"
!                                     "Remove")
!                                   " comma at end of entry? "))
!                        'last-comma)
!                    (if (y-or-n-p
!                         "Replace double page dashes by single ones? ")
!                        'page-dashes)
!                    (if (y-or-n-p
!                         "Force delimiters? ")
!                        'delimiters)
!                    (if (y-or-n-p
!                         "Unify case of entry types and field names? ")
!                        'unify-case)))))
              '(realign)))
!          (reformat-reference-keys
!              (if additional-options
!                  (if use-previous-options
!                      bibtex-reformat-previous-reference-keys
!                    (setq
!                     bibtex-reformat-previous-reference-keys
!                     (y-or-n-p "Generate new reference keys automatically? 
")))))
           bibtex-autokey-edit-before-use
           (bibtex-sort-ignore-string-entries t)
!          (start-point
!           (if (bibtex-mark-active)
!               (region-beginning)
!             (progn
!               (bibtex-beginning-of-first-entry)
!               (bibtex-skip-to-valid-entry)
!               (point))))
!          (end-point
!           (if (bibtex-mark-active)
!               (region-end)
!             (point-max)))
!          (valid-bibtex-entry
!           (concat
!            "[ \t\n]+\\(@[ \t]*\\("
!            (mapconcat
!             (lambda (type)
!               (concat "\\(" (car type) "\\)"))
!             bibtex-entry-field-alist
!             "\\|")
!            "\\)\\)")))
      (save-restriction
        (narrow-to-region start-point end-point)
!       (if (memq 'realign bibtex-entry-format)
!           (progn
!             (goto-char (point-min))
!             (while (re-search-forward valid-bibtex-entry nil t)
!               (replace-match "\n\\1"))))
        (goto-char start-point)
        (bibtex-progress-message "Formatting" 1)
!       (bibtex-map-entries
!        (lambda (current)
!          (bibtex-progress-message)
!          (bibtex-clean-entry reformat-reference-keys reformat-reference-keys)
!          (if (memq 'realign bibtex-entry-format)
!              (progn
!                (bibtex-end-of-entry)
!                (bibtex-delete-whitespace)
!                (open-line 2)))))
        (bibtex-progress-message 'done))
!     (if (and
!          reformat-reference-keys
!          bibtex-maintain-sorted-entries
!          (not called-by-convert-alien))
!         (progn
!           (bibtex-sort-buffer)
!           (setq bibtex-reference-keys nil)
!           (bibtex-parse-keys nil t t)))
      (goto-char pnt)))
  
  (defun bibtex-convert-alien (&optional do-additional-reformatting)
!   "Converts an alien BibTeX buffer to be fully usable by BibTeX mode.
! If a file doesn't confirm with some standards used by BibTeX mode,
! some of the high-level features of BibTeX mode won't be available.
! This function tries to convert current buffer to confirm with these standards.
  With prefix argument DO-ADDITIONAL-REFORMATTING
  non-nil, read options for reformatting entries from minibuffer."
    (interactive "*P")
--- 3637,3704 ----
            (if additional-options
                (if use-previous-options
                    bibtex-reformat-previous-options
!                 (setq bibtex-reformat-previous-options
!                       (delq nil (list
!                                  (if (or called-by-convert-alien
!                                          (y-or-n-p "Realign entries 
(recommended)? "))
!                                      'realign)
!                                  (if (y-or-n-p "Remove empty optional and 
alternative fields? ")
!                                      'opts-or-alts)
!                                  (if (y-or-n-p "Remove delimiters around pure 
numerical fields? ")
!                                      'numerical-fields)
!                                  (if (y-or-n-p (concat (if 
bibtex-comma-after-last-field "Insert" "Remove")
!                                                        " comma at end of 
entry? "))
!                                      'last-comma)
!                                  (if (y-or-n-p "Replace double page dashes by 
single ones? ")
!                                      'page-dashes)
!                                  (if (y-or-n-p "Force delimiters? ")
!                                      'delimiters)
!                                  (if (y-or-n-p "Unify case of entry types and 
field names? ")
!                                      'unify-case)))))
              '(realign)))
!          (reformat-reference-keys (if additional-options
!                                       (if use-previous-options
!                                           
bibtex-reformat-previous-reference-keys
!                                         (setq 
bibtex-reformat-previous-reference-keys
!                                               (y-or-n-p "Generate new 
reference keys automatically? ")))))
           bibtex-autokey-edit-before-use
           (bibtex-sort-ignore-string-entries t)
!          (start-point (if (bibtex-mark-active)
!                           (region-beginning)
!                         (bibtex-beginning-of-first-entry)
!                         (bibtex-skip-to-valid-entry)
!                         (point)))
!          (end-point (if (bibtex-mark-active)
!                         (region-end)
!                       (point-max))))
      (save-restriction
        (narrow-to-region start-point end-point)
!       (when (memq 'realign bibtex-entry-format)
!         (goto-char (point-min))
!         (while (re-search-forward bibtex-valid-entry-whitespace-re nil t)
!           (replace-match "\n\\1")))
        (goto-char start-point)
        (bibtex-progress-message "Formatting" 1)
!       (bibtex-map-entries (lambda (key beg end)
!                             (bibtex-progress-message)
!                             (bibtex-clean-entry reformat-reference-keys t)
!                             (when (memq 'realign bibtex-entry-format)
!                               (goto-char end)
!                               (bibtex-delete-whitespace)
!                               (open-line 2))))
        (bibtex-progress-message 'done))
!     (when (and reformat-reference-keys
!                bibtex-maintain-sorted-entries
!                (not called-by-convert-alien))
!       (bibtex-sort-buffer)
!       (kill-local-variable 'bibtex-reference-keys))
      (goto-char pnt)))
  
  (defun bibtex-convert-alien (&optional do-additional-reformatting)
!   "Convert an alien BibTeX buffer to be fully usable by BibTeX mode.
! If a file does not conform with some standards used by BibTeX mode,
! some of the high-level features of BibTeX mode will not be available.
! This function tries to convert current buffer to conform with these standards.
  With prefix argument DO-ADDITIONAL-REFORMATTING
  non-nil, read options for reformatting entries from minibuffer."
    (interactive "*P")
***************
*** 3920,4074 ****
    (message
     "If errors occur, correct them and call `bibtex-convert-alien' again")
    (sit-for 5 nil t)
!   (if (let ((bibtex-mark-active)
!             bibtex-maintain-sorted-entries)
!         (bibtex-validate))
!       (progn
!         (message "Starting to reformat entries...")
!         (sit-for 2 nil t)
!         (bibtex-reformat do-additional-reformatting t)
!         (if bibtex-maintain-sorted-entries
!             (progn
!               (message "Starting to sort buffer...")
!               (bibtex-sort-buffer)))
!         (goto-char (point-max))
!         (message "Buffer is now parsable. Please save it."))))
! 
! (defun bibtex-complete-string ()
!   "Complete word fragment before point to longest prefix of a defined string.
! If point is not after the part of a word, all strings are listed.
! Remove surrounding delimiters if complete string could be expanded."
!   (interactive "*")
!   (bibtex-complete bibtex-strings t))
  
! (defun bibtex-complete-key ()
!   "Complete word fragment before point to longest prefix of a defined key.
! If point is not after the part of a word, all keys are listed.  This
! function is most useful in completing crossref entries."
!   (interactive "*")
!   (if (not bibtex-reference-keys)
!       (bibtex-parse-keys nil t))
!   (bibtex-complete bibtex-reference-keys))
  
  (defun bibtex-Article ()
    "Insert a new BibTeX @Article entry; see also `bibtex-entry'."
!   (interactive)
    (bibtex-entry "Article"))
  
  (defun bibtex-Book ()
    "Insert a new BibTeX @Book entry; see also `bibtex-entry'."
!   (interactive)
    (bibtex-entry "Book"))
  
  (defun bibtex-Booklet ()
    "Insert a new BibTeX @Booklet entry; see also `bibtex-entry'."
!   (interactive)
    (bibtex-entry "Booklet"))
  
  (defun bibtex-InBook ()
    "Insert a new BibTeX @InBook entry; see also `bibtex-entry'."
!   (interactive)
    (bibtex-entry "InBook"))
  
  (defun bibtex-InCollection ()
    "Insert a new BibTeX @InCollection entry; see also `bibtex-entry'."
!   (interactive)
    (bibtex-entry "InCollection"))
  
  (defun bibtex-InProceedings ()
    "Insert a new BibTeX @InProceedings entry; see also `bibtex-entry'."
!   (interactive)
    (bibtex-entry "InProceedings"))
  
  (defun bibtex-Manual ()
    "Insert a new BibTeX @Manual entry; see also `bibtex-entry'."
!   (interactive)
    (bibtex-entry "Manual"))
  
  (defun bibtex-MastersThesis ()
    "Insert a new BibTeX @MastersThesis entry; see also `bibtex-entry'."
!   (interactive)
    (bibtex-entry "MastersThesis"))
  
  (defun bibtex-Misc ()
    "Insert a new BibTeX @Misc entry; see also `bibtex-entry'."
!   (interactive)
    (bibtex-entry "Misc"))
  
  (defun bibtex-PhdThesis ()
    "Insert a new BibTeX @PhdThesis entry; see also `bibtex-entry'."
!   (interactive)
    (bibtex-entry "PhdThesis"))
  
  (defun bibtex-Proceedings ()
    "Insert a new BibTeX @Proceedings entry; see also `bibtex-entry'."
!   (interactive)
    (bibtex-entry "Proceedings"))
  
  (defun bibtex-TechReport ()
    "Insert a new BibTeX @TechReport entry; see also `bibtex-entry'."
!   (interactive)
    (bibtex-entry "TechReport"))
  
  (defun bibtex-Unpublished ()
    "Insert a new BibTeX @Unpublished entry; see also `bibtex-entry'."
!   (interactive)
    (bibtex-entry "Unpublished"))
  
! (defun bibtex-String ()
!   "Insert a new BibTeX @String entry."
!   (interactive)
!   (if (not bibtex-reference-keys)
!       (bibtex-parse-keys nil t))
!   (let ((key
!          (if (and
!               bibtex-maintain-sorted-entries
!               (not bibtex-sort-ignore-string-entries))
!              (completing-read
!               "String key: " bibtex-reference-keys nil nil nil 
'bibtex-key-history))))
!     (if (and
!          bibtex-maintain-sorted-entries
!          (not bibtex-sort-ignore-string-entries))
!       (bibtex-find-entry-location key)
!       (bibtex-move-outside-of-entry))
      (indent-to-column bibtex-entry-offset)
!     (insert
!      (concat
!       "@String"
!       (bibtex-entry-left-delimiter)
!       (if (and
!            bibtex-maintain-sorted-entries
!            (not bibtex-sort-ignore-string-entries))
!           key)
!       " = "
!       (bibtex-field-left-delimiter)
!       (bibtex-field-right-delimiter)
!       (bibtex-entry-right-delimiter)
!       "\n"))
!   (forward-line -1)
!   (forward-char
!    (if (and
!         bibtex-maintain-sorted-entries
!         (not bibtex-sort-ignore-string-entries))
!        (+ (length "@String{") (length key) (length " = {"))
!      (length "@String{")))))
  
  (defun bibtex-Preamble ()
    "Insert a new BibTeX @Preamble entry."
!   (interactive)
    (bibtex-move-outside-of-entry)
    (indent-to-column bibtex-entry-offset)
!   (insert
!    "@Preamble"
!    (bibtex-entry-left-delimiter)
!    (bibtex-entry-right-delimiter)
!    "\n")
!   (forward-line -1)
!   (forward-char 10))
  
  
  ;; Make BibTeX a Feature
  
  (provide 'bibtex)
  
  ;;; bibtex.el ends here
--- 3710,3895 ----
    (message
     "If errors occur, correct them and call `bibtex-convert-alien' again")
    (sit-for 5 nil t)
!   (deactivate-mark)  ; So bibtex-validate works on the whole buffer.
!   (when (let (bibtex-maintain-sorted-entries)
!           (bibtex-validate))
!     (message "Starting to reformat entries...")
!     (sit-for 2 nil t)
!     (bibtex-reformat do-additional-reformatting t)
!     (when bibtex-maintain-sorted-entries
!       (message "Starting to sort buffer...")
!       (bibtex-sort-buffer))
!     (goto-char (point-max))
!     (message "Buffer is now parsable. Please save it.")))
! 
! (defun bibtex-complete ()
!   "Complete word fragment before point according to context.
! If point is inside key or crossref field perform key completion based on
! `bibtex-reference-keys'. Inside any other field perform string
! completion based on `bibtex-strings'. An error is signaled if point
! is outside key or BibTeX field."
!   (interactive)
!   (let* ((pnt (point))
!          (case-fold-search t)
!          bounds compl)
!     (save-excursion
!       (if (and (setq bounds (bibtex-enclosing-field t))
!                (>= pnt (bibtex-start-of-text-in-field bounds))
!                (<= pnt (bibtex-end-of-text-in-field bounds)))
!           (progn
!             (goto-char (bibtex-start-of-name-in-field bounds))
!             (setq compl (if (string= "crossref"
!                                      (downcase
!                                       (buffer-substring-no-properties
!                                        (if (looking-at 
"\\(OPT\\)\\|\\(ALT\\)")
!                                            (match-end 0)
!                                          (point))
!                                        (bibtex-end-of-name-in-field bounds))))
!                             'key
!                           'str)))
!         (bibtex-beginning-of-entry)
!         (if (and (re-search-forward bibtex-entry-maybe-empty-head nil t)
!                  ;; point is inside a key
!                  (or (and (match-beginning bibtex-key-in-head)
!                           (>= pnt (match-beginning bibtex-key-in-head))
!                           (<= pnt (match-end bibtex-key-in-head)))
!                      ;; or point is on empty key
!                      (and (not (match-beginning bibtex-key-in-head))
!                           (= pnt (match-end 0)))))
!             (setq compl 'key))))
! 
!     (cond ((equal compl 'key)
!            ;; key completion
!            (setq choose-completion-string-functions
!                  (lambda (choice buffer mini-p base-size)
!                    (bibtex-choose-completion-string choice buffer mini-p 
base-size)
!                    (if bibtex-complete-key-cleanup
!                        (funcall bibtex-complete-key-cleanup choice))
!                    ;; return t (required by 
choose-completion-string-functions)
!                    t))
!            (let ((choice (bibtex-complete-internal bibtex-reference-keys)))
!              (if bibtex-complete-key-cleanup
!                  (funcall bibtex-complete-key-cleanup choice))))
! 
!           ((equal compl 'str)
!            ;; string completion
!            (setq choose-completion-string-functions
!                  (lambda (choice buffer mini-p base-size)
!                    (bibtex-choose-completion-string choice buffer mini-p 
base-size)
!                    (bibtex-complete-string-cleanup choice)
!                    ;; return t (required by 
choose-completion-string-functions)
!                    t))
!            (bibtex-complete-string-cleanup (bibtex-complete-internal 
bibtex-strings)))
  
!           (t (error "Point outside key or BibTeX field")))))
  
  (defun bibtex-Article ()
    "Insert a new BibTeX @Article entry; see also `bibtex-entry'."
!   (interactive "*")
    (bibtex-entry "Article"))
  
  (defun bibtex-Book ()
    "Insert a new BibTeX @Book entry; see also `bibtex-entry'."
!   (interactive "*")
    (bibtex-entry "Book"))
  
  (defun bibtex-Booklet ()
    "Insert a new BibTeX @Booklet entry; see also `bibtex-entry'."
!   (interactive "*")
    (bibtex-entry "Booklet"))
  
  (defun bibtex-InBook ()
    "Insert a new BibTeX @InBook entry; see also `bibtex-entry'."
!   (interactive "*")
    (bibtex-entry "InBook"))
  
  (defun bibtex-InCollection ()
    "Insert a new BibTeX @InCollection entry; see also `bibtex-entry'."
!   (interactive "*")
    (bibtex-entry "InCollection"))
  
  (defun bibtex-InProceedings ()
    "Insert a new BibTeX @InProceedings entry; see also `bibtex-entry'."
!   (interactive "*")
    (bibtex-entry "InProceedings"))
  
  (defun bibtex-Manual ()
    "Insert a new BibTeX @Manual entry; see also `bibtex-entry'."
!   (interactive "*")
    (bibtex-entry "Manual"))
  
  (defun bibtex-MastersThesis ()
    "Insert a new BibTeX @MastersThesis entry; see also `bibtex-entry'."
!   (interactive "*")
    (bibtex-entry "MastersThesis"))
  
  (defun bibtex-Misc ()
    "Insert a new BibTeX @Misc entry; see also `bibtex-entry'."
!   (interactive "*")
    (bibtex-entry "Misc"))
  
  (defun bibtex-PhdThesis ()
    "Insert a new BibTeX @PhdThesis entry; see also `bibtex-entry'."
!   (interactive "*")
    (bibtex-entry "PhdThesis"))
  
  (defun bibtex-Proceedings ()
    "Insert a new BibTeX @Proceedings entry; see also `bibtex-entry'."
!   (interactive "*")
    (bibtex-entry "Proceedings"))
  
  (defun bibtex-TechReport ()
    "Insert a new BibTeX @TechReport entry; see also `bibtex-entry'."
!   (interactive "*")
    (bibtex-entry "TechReport"))
  
  (defun bibtex-Unpublished ()
    "Insert a new BibTeX @Unpublished entry; see also `bibtex-entry'."
!   (interactive "*")
    (bibtex-entry "Unpublished"))
  
! (defun bibtex-String (&optional key)
!   "Insert a new BibTeX @String entry with key KEY."
!   (interactive (list (completing-read "String key: " bibtex-strings
!                                       nil nil nil 'bibtex-key-history)))
!   (let ((bibtex-maintain-sorted-entries
!          (if (not bibtex-sort-ignore-string-entries)
!              bibtex-maintain-sorted-entries))
!         endpos)
!     (unless (bibtex-prepare-new-entry (list key nil "String"))
!       (error "Entry with key `%s' already exists" key))
!     (if (zerop (length key)) (setq key nil))
      (indent-to-column bibtex-entry-offset)
!     (insert "@String"
!             (bibtex-entry-left-delimiter))
!     (if key
!         (insert key)
!       (setq endpos (point)))
!     (insert " = "
!             (bibtex-field-left-delimiter))
!     (if key
!         (setq endpos (point)))
!     (insert (bibtex-field-right-delimiter)
!             (bibtex-entry-right-delimiter)
!             "\n")
!     (goto-char endpos)))
  
  (defun bibtex-Preamble ()
    "Insert a new BibTeX @Preamble entry."
!   (interactive "*")
    (bibtex-move-outside-of-entry)
    (indent-to-column bibtex-entry-offset)
!   (insert "@Preamble"
!           (bibtex-entry-left-delimiter))
!   (let ((endpos (point)))
!     (insert (bibtex-entry-right-delimiter)
!             "\n")
!     (goto-char endpos)))
  
  
  ;; Make BibTeX a Feature
  
  (provide 'bibtex)
  
+ ;;; arch-tag: ee2be3af-caad-427f-b42a-d20fad630d04
  ;;; bibtex.el ends here




reply via email to

[Prev in Thread] Current Thread [Next in Thread]