1;;; bibtex.el --- BibTeX mode for GNU Emacs -*- lexical-binding: t -*-
2
3;; Copyright (C) 1992, 1994-1999, 2001-2021 Free Software Foundation,
4;; Inc.
5
6;; Author: Stefan Schoef <schoef@offis.uni-oldenburg.de>
7;;      Bengt Martensson <bengt@mathematik.uni-Bremen.de>
8;;      Marc Shapiro <marc.shapiro@acm.org>
9;;      Mike Newton <newton@gumby.cs.caltech.edu>
10;;      Aaron Larson <alarson@src.honeywell.com>
11;;      Dirk Herrmann <D.Herrmann@tu-bs.de>
12;; Maintainer: Roland Winkler <winkler@gnu.org>
13;; Keywords: BibTeX, LaTeX, TeX
14
15;; This file is part of GNU Emacs.
16
17;; GNU Emacs is free software: you can redistribute it and/or modify
18;; it under the terms of the GNU General Public License as published by
19;; the Free Software Foundation, either version 3 of the License, or
20;; (at your option) any later version.
21
22;; GNU Emacs is distributed in the hope that it will be useful,
23;; but WITHOUT ANY WARRANTY; without even the implied warranty of
24;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25;; GNU General Public License for more details.
26
27;; You should have received a copy of the GNU General Public License
28;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
29
30;;; Commentary:
31
32;;  Major mode for editing and validating BibTeX files.
33
34;;  Usage:
35;;  See documentation for `bibtex-mode' or type "M-x describe-mode"
36;;  when you are in BibTeX mode.
37
38;;  Todo:
39;;  Distribute texinfo file.
40
41;;; Code:
42
43(require 'iso8601)
44
45
46;; User Options:
47
48(defgroup bibtex nil
49  "BibTeX mode."
50  :group 'tex
51  :prefix "bibtex-")
52
53(defgroup bibtex-autokey nil
54  "Generate automatically a key from the author/editor and the title field."
55  :group 'bibtex
56  :prefix "bibtex-autokey-")
57
58(defcustom bibtex-mode-hook nil
59  "List of functions to call on entry to BibTeX mode."
60  :group 'bibtex
61  :type 'hook)
62
63(defcustom bibtex-field-delimiters 'braces
64  "Type of field delimiters.  Allowed values are `braces' or `double-quotes'."
65  :group 'bibtex
66  :type '(choice (const braces)
67                 (const double-quotes)))
68
69(defcustom bibtex-entry-delimiters 'braces
70  "Type of entry delimiters.  Allowed values are `braces' or `parentheses'."
71  :group 'bibtex
72  :type '(choice (const braces)
73                 (const parentheses)))
74
75(defcustom bibtex-include-OPTcrossref '("InProceedings" "InCollection")
76  "List of BibTeX entries that get an OPTcrossref field."
77  :group 'bibtex
78  :type '(repeat string))
79
80(defcustom bibtex-include-OPTkey t
81  "If non-nil, all newly created entries get an OPTkey field.
82If this is a string, use it as the initial field text.
83If this is a function, call it to generate the initial field text."
84  :group 'bibtex
85  :type '(choice (const :tag "None" nil)
86                 (string :tag "Initial text")
87                 (function :tag "Initialize Function")
88                 (const :tag "Default" t))
89  :risky t)
90
91(defcustom bibtex-user-optional-fields
92  '(("annote" "Personal annotation (ignored)"))
93  "List of optional fields the user wants to have always present.
94Entries should be of the same form as the OPTIONAL list
95in `bibtex-BibTeX-entry-alist' (which see)."
96  :group 'bibtex
97  :type '(repeat (group (string :tag "Field")
98                        (string :tag "Comment")
99                        (option (choice :tag "Init"
100                                        (const nil) string function))))
101  :risky t)
102
103(defcustom bibtex-entry-format
104  '(opts-or-alts required-fields numerical-fields)
105  "Type of formatting performed by `bibtex-clean-entry'.
106It may be t, nil, or a list of symbols out of the following:
107opts-or-alts        Delete empty optional and alternative fields and
108                      remove OPT and ALT prefixes from used fields.
109required-fields     Signal an error if a required field is missing.
110numerical-fields    Delete delimiters around numeral fields.
111page-dashes         Change double dashes in page field to single dash
112                      (for scribe compatibility).
113whitespace          Delete whitespace at the beginning and end of fields.
114inherit-booktitle   If entry contains a crossref field and the booktitle
115                      field is empty, set the booktitle field to the content
116                      of the title field of the cross-referenced entry.
117realign             Realign entries, so that field texts and perhaps equal
118                      signs (depending on the value of
119                      `bibtex-align-at-equal-sign') begin in the same column.
120                      Also fill fields.
121last-comma          Add or delete comma on end of last field in entry,
122                      according to value of `bibtex-comma-after-last-field'.
123delimiters          Change delimiters according to variables
124                      `bibtex-field-delimiters' and `bibtex-entry-delimiters'.
125unify-case          Change case of entry and field names according to
126                      `bibtex-unify-case-function'.
127braces              Enclose parts of field entries by braces according to
128                      `bibtex-field-braces-alist'.
129strings             Replace parts of field entries by string constants
130                      according to `bibtex-field-strings-alist'.
131sort-fields         Sort fields to match the field order in
132                    `bibtex-BibTeX-entry-alist'.
133
134The value t means do all of the above formatting actions.
135The value nil means do no formatting at all."
136  :group 'bibtex
137  :type '(choice (const :tag "None" nil)
138                 (const :tag "All" t)
139                 (set :menu-tag "Some"
140                      (const opts-or-alts)
141                      (const required-fields)
142                      (const numerical-fields)
143                      (const page-dashes)
144                      (const whitespace)
145                      (const inherit-booktitle)
146                      (const realign)
147                      (const last-comma)
148                      (const delimiters)
149                      (const unify-case)
150                      (const braces)
151                      (const strings)
152                      (const sort-fields)))
153  :safe (lambda (x)
154          (or (eq x t)
155              (let ((ok t))
156                (while (consp x)
157                  (unless (memq (pop x)
158                                '( opts-or-alts required-fields numerical-fields
159                                   page-dashes whitespace inherit-booktitle
160                                   realign last-comma delimiters unify-case
161                                   braces strings sort-fields ))
162                    (setq ok nil)))
163                (unless x ok)))))
164
165(defcustom bibtex-field-braces-alist nil
166 "Alist of field regexps that \\[bibtex-clean-entry] encloses by braces.
167Each element has the form (FIELDS REGEXP), where FIELDS is a list
168of BibTeX field names and REGEXP is a regexp.
169Space characters in REGEXP will be replaced by \"[ \\t\\n]+\"."
170  :group 'bibtex
171  :type '(repeat (list (repeat (string :tag "field name"))
172                       (choice (regexp :tag "regexp")
173                               (sexp :tag "sexp")))))
174
175(defcustom bibtex-field-strings-alist nil
176 "Alist of regexps that \\[bibtex-clean-entry] replaces by string constants.
177Each element has the form (FIELDS REGEXP TO-STR), where FIELDS is a list
178of BibTeX field names.  In FIELDS search for REGEXP, which are replaced
179by the BibTeX string constant TO-STR.
180Space characters in REGEXP will be replaced by \"[ \\t\\n]+\"."
181  :group 'bibtex
182  :type '(repeat (list (repeat (string :tag "field name"))
183                       (regexp :tag "From regexp")
184                       (regexp :tag "To string constant"))))
185
186(defcustom bibtex-unify-case-function #'identity
187  "Function for unifying case of entry and field names.
188It is called with one argument, the entry or field name."
189  :version "28.1"
190  :type '(choice (const :tag "Same case as in `bibtex-field-alist'" identity)
191		 (const :tag "Downcase" downcase)
192		 (const :tag "Capitalize" capitalize)
193		 (const :tag "Upcase" upcase)
194                 (function :tag "Conversion function"))
195  :safe (lambda (x) (memq x '(upcase downcase capitalize identity))))
196
197(defcustom bibtex-clean-entry-hook nil
198  "List of functions to call when entry has been cleaned.
199Functions are called with point inside the cleaned entry, and the buffer
200narrowed to just the entry."
201  :group 'bibtex
202  :type 'hook)
203
204(defcustom bibtex-maintain-sorted-entries nil
205  "If non-nil, BibTeX mode maintains all entries in sorted order.
206Allowed non-nil values are:
207plain or t   Sort entries alphabetically by keys.
208crossref     Sort entries alphabetically by keys unless an entry has a
209             crossref field.  These crossrefed entries are placed in
210             alphabetical order immediately preceding the main entry.
211entry-class  The entries are divided into classes according to their
212             entry type, see `bibtex-sort-entry-class'.  Within each class
213             sort entries alphabetically by keys.
214(INDEX-FUN PREDICATE)
215(INDEX-FUN PREDICATE INIT-FUN)  Sort entries using INDEX-FUN and PREDICATE.
216             Function INDEX-FUN is called for each entry with point at the
217             end of the head of the entry.  Its return values are used to
218             sort the entries using PREDICATE.  Function PREDICATE takes two
219             arguments INDEX1 and INDEX2 as returned by INDEX-FUN.
220             It should return non-nil if INDEX1 should sort before INDEX2.
221             If INIT-FUN is non-nil, it should be a function that is called
222             with no arguments to initialize the sorting.
223See also `bibtex-sort-ignore-string-entries'."
224  :group 'bibtex
225  :version "28.1"
226  :type '(choice (const nil)
227                 (const t)
228                 (const plain)
229                 (const crossref)
230                 (const entry-class)
231                 (group :tag "Custom scheme"
232                        (function :tag "Index-Fun")
233                        (function :tag "Predicate")
234                        (option (function :tag "Init-Fun"))))
235  :safe (lambda (a) (memq a '(nil t plain crossref entry-class))))
236
237(defcustom bibtex-sort-entry-class
238  '(("String")
239    (catch-all)
240    ("Book" "Proceedings"))
241  "List of classes of BibTeX entry types, used for sorting entries.
242If value of `bibtex-maintain-sorted-entries' is `entry-class'
243entries are ordered according to the classes they belong to.  Each
244class contains a list of entry types.  An entry `catch-all' applies
245to all entries not explicitly mentioned."
246  :group 'bibtex
247  :type '(repeat (choice :tag "Class"
248                         (const :tag "catch-all" (catch-all))
249                         (repeat :tag "Entry type" string)))
250  :safe (lambda (x)
251          (let ((ok t))
252            (while (consp x)
253              (let ((y (pop x)))
254                (while (consp y)
255                  (let ((z (pop y)))
256                    (unless (or (stringp z) (eq z 'catch-all))
257                      (setq ok nil))))
258                (when y (setq ok nil))))
259            (unless x ok))))
260
261(defcustom bibtex-sort-ignore-string-entries t
262  "If non-nil, BibTeX @String entries are not sort-significant.
263That means they are ignored when determining ordering of the buffer
264\(e.g., sorting, locating alphabetical position for new entries, etc.)."
265  :group 'bibtex
266  :type 'boolean)
267
268(defcustom bibtex-field-kill-ring-max 20
269  "Max length of `bibtex-field-kill-ring' before discarding oldest elements."
270  :group 'bibtex
271  :type 'integer)
272
273(defcustom bibtex-entry-kill-ring-max 20
274  "Max length of `bibtex-entry-kill-ring' before discarding oldest elements."
275  :group 'bibtex
276  :type 'integer)
277
278(defcustom bibtex-parse-keys-timeout 60
279  "Time interval in seconds for parsing BibTeX buffers during idle time.
280Parsing initializes `bibtex-reference-keys' and `bibtex-strings'."
281  :group 'bibtex
282  :type 'integer)
283
284(defcustom bibtex-parse-keys-fast t
285  "If non-nil, use fast but simplified algorithm for parsing BibTeX keys.
286If parsing fails, try to set this variable to nil."
287  :group 'bibtex
288  :type 'boolean)
289
290(define-widget 'bibtex-entry-alist 'lazy
291  "Format of `bibtex-BibTeX-entry-alist' and friends."
292  :type '(repeat (group (string :tag "Entry type")
293                        (string :tag "Documentation")
294                        (repeat :tag "Required fields"
295                                (group (string :tag "Field")
296                                       (option (choice :tag "Comment" :value nil
297                                                       (const nil) string))
298                                       (option (choice :tag "Init" :value nil
299                                                       (const nil) string function))
300                                       (option (choice :tag "Alternative" :value nil
301                                                       (const nil) integer))))
302                        (repeat :tag "Crossref fields"
303                                (group (string :tag "Field")
304                                       (option (choice :tag "Comment" :value nil
305                                                       (const nil) string))
306                                       (option (choice :tag "Init" :value nil
307                                                       (const nil) string function))
308                                       (option (choice :tag "Alternative" :value nil
309                                                       (const nil) integer))))
310                        (repeat :tag "Optional fields"
311                                (group (string :tag "Field")
312                                       (option (choice :tag "Comment" :value nil
313                                                       (const nil) string))
314                                       (option (choice :tag "Init" :value nil
315                                                       (const nil) string function))
316                                       (option (choice :tag "Alternative" :value nil
317                                                       (const nil) integer)))))))
318
319(define-obsolete-variable-alias 'bibtex-entry-field-alist
320  'bibtex-BibTeX-entry-alist "24.1")
321(defcustom bibtex-BibTeX-entry-alist
322  '(("Article" "Article in Journal"
323     (("author")
324      ("title" "Title of the article (BibTeX converts it to lowercase)"))
325     (("journal") ("year"))
326     (("volume" "Volume of the journal")
327      ("number" "Number of the journal (only allowed if entry contains volume)")
328      ("pages" "Pages in the journal")
329      ("month") ("note")))
330    ("InProceedings" "Article in Conference Proceedings"
331     (("author")
332      ("title" "Title of the article in proceedings (BibTeX converts it to lowercase)"))
333     (("booktitle" "Name of the conference proceedings")
334      ("year"))
335     (("editor")
336      ("volume" "Volume of the conference proceedings in the series")
337      ("number" "Number of the conference proceedings in a small series (overwritten by volume)")
338      ("series" "Series in which the conference proceedings appeared")
339      ("pages" "Pages in the conference proceedings")
340      ("month") ("address")
341      ("organization" "Sponsoring organization of the conference")
342      ("publisher" "Publishing company, its location")
343      ("note")))
344    ("Conference" "Article in Conference Proceedings" ; same as InProceedings
345     (("author")
346      ("title" "Title of the article in proceedings (BibTeX converts it to lowercase)"))
347     (("booktitle" "Name of the conference proceedings")
348      ("year"))
349     (("editor")
350      ("volume" "Volume of the conference proceedings in the series")
351      ("number" "Number of the conference proceedings in a small series (overwritten by volume)")
352      ("series" "Series in which the conference proceedings appeared")
353      ("pages" "Pages in the conference proceedings")
354      ("month") ("address")
355      ("organization" "Sponsoring organization of the conference")
356      ("publisher" "Publishing company, its location")
357      ("note")))
358    ("InCollection" "Article in a Collection"
359     (("author")
360      ("title" "Title of the article in book (BibTeX converts it to lowercase)")
361      ("booktitle" "Name of the book"))
362     (("publisher") ("year"))
363     (("editor")
364      ("volume" "Volume of the book in the series")
365      ("number" "Number of the book in a small series (overwritten by volume)")
366      ("series" "Series in which the book appeared")
367      ("type" "Word to use instead of \"chapter\"")
368      ("chapter" "Chapter in the book")
369      ("pages" "Pages in the book")
370      ("edition" "Edition of the book as a capitalized English word")
371      ("month") ("address") ("note")))
372    ("InBook" "Chapter or Pages in a Book"
373     (("author" nil nil 0)
374      ("editor" nil nil 0)
375      ("title" "Title of the book")
376      ("chapter" "Chapter in the book"))
377     (("publisher") ("year"))
378     (("volume" "Volume of the book in the series")
379      ("number" "Number of the book in a small series (overwritten by volume)")
380      ("series" "Series in which the book appeared")
381      ("type" "Word to use instead of \"chapter\"")
382      ("address")
383      ("edition" "Edition of the book as a capitalized English word")
384      ("month")
385      ("pages" "Pages in the book")
386      ("note")))
387    ("Proceedings" "Conference Proceedings"
388     (("title" "Title of the conference proceedings")
389      ("year"))
390     nil
391     (("booktitle" "Title of the proceedings for cross references")
392      ("editor")
393      ("volume" "Volume of the conference proceedings in the series")
394      ("number" "Number of the conference proceedings in a small series (overwritten by volume)")
395      ("series" "Series in which the conference proceedings appeared")
396      ("address")
397      ("month")
398      ("organization" "Sponsoring organization of the conference")
399      ("publisher" "Publishing company, its location")
400      ("note")))
401    ("Book" "Book"
402     (("author" nil nil 0)
403      ("editor" nil nil 0)
404      ("title" "Title of the book"))
405     (("publisher") ("year"))
406     (("volume" "Volume of the book in the series")
407      ("number" "Number of the book in a small series (overwritten by volume)")
408      ("series" "Series in which the book appeared")
409      ("address")
410      ("edition" "Edition of the book as a capitalized English word")
411      ("month") ("note")))
412    ("Booklet" "Booklet (Bound, but no Publisher)"
413     (("title" "Title of the booklet (BibTeX converts it to lowercase)"))
414     nil
415     (("author")
416      ("howpublished" "The way in which the booklet was published")
417      ("address") ("month") ("year") ("note")))
418    ("PhdThesis" "PhD Thesis"
419     (("author")
420      ("title" "Title of the PhD thesis")
421      ("school" "School where the PhD thesis was written")
422      ("year"))
423     nil
424     (("type" "Type of the PhD thesis")
425      ("address" "Address of the school (if not part of field \"school\") or country")
426      ("month") ("note")))
427    ("MastersThesis" "Master's Thesis"
428     (("author")
429      ("title" "Title of the master's thesis (BibTeX converts it to lowercase)")
430      ("school" "School where the master's thesis was written")
431      ("year"))
432     nil
433     (("type" "Type of the master's thesis (if other than \"Master's thesis\")")
434      ("address" "Address of the school (if not part of field \"school\") or country")
435      ("month") ("note")))
436    ("TechReport" "Technical Report"
437     (("author")
438      ("title" "Title of the technical report (BibTeX converts it to lowercase)")
439      ("institution" "Sponsoring institution of the report")
440      ("year"))
441     nil
442     (("type" "Type of the report (if other than \"technical report\")")
443      ("number" "Number of the technical report")
444      ("address") ("month") ("note")))
445    ("Manual" "Technical Manual"
446     (("title" "Title of the manual"))
447     nil
448     (("author")
449      ("organization" "Publishing organization of the manual")
450      ("address")
451      ("edition" "Edition of the manual as a capitalized English word")
452      ("month") ("year") ("note")))
453    ("Unpublished" "Unpublished"
454     (("author")
455      ("title" "Title of the unpublished work (BibTeX converts it to lowercase)")
456      ("note"))
457     nil
458     (("month") ("year")))
459    ("Misc" "Miscellaneous" nil nil
460     (("author")
461      ("title" "Title of the work (BibTeX converts it to lowercase)")
462      ("howpublished" "The way in which the work was published")
463      ("month") ("year") ("note"))))
464  "Alist of BibTeX entry types and their associated fields.
465Elements are lists (ENTRY-TYPE DOC REQUIRED CROSSREF OPTIONAL).
466ENTRY-TYPE is the type of a BibTeX entry.
467DOC is a brief doc string used for menus.  If nil ENTRY-TYPE is used.
468REQUIRED is a list of required fields.
469CROSSREF is a list of fields that are optional if a crossref field
470is present; but these fields are required otherwise.
471OPTIONAL is a list of optional fields.
472
473Each element of these lists is a list of the form
474  (FIELD COMMENT INIT ALTERNATIVE).
475COMMENT, INIT, and ALTERNATIVE are optional.
476
477FIELD is the name of the field.
478COMMENT is the comment string that appears in the echo area.
479If COMMENT is nil use `bibtex-BibTeX-field-alist' if possible.
480INIT is either the initial content of the field or a function,
481which is called to determine the initial content of the field.
482ALTERNATIVE if non-nil is an integer N that numbers sets of
483alternatives.  A negative integer -N indicates an alias for the
484field +N.  Such aliases are ignored by `bibtex-entry' in the template
485for a new entry."
486  :group 'bibtex
487  :version "28.1"                       ; extend alternatives
488  :type 'bibtex-entry-alist
489  :risky t)
490
491(defcustom bibtex-biblatex-entry-alist
492  ;; Compare in biblatex documentation:
493  ;; Sec. 2.1.1  Regular types (required and optional fields)
494  ;; Sec. 2.2.5  Field Aliases
495  ;; Appendix A  Default Crossref setup
496  '(("Article" "Article in Journal"
497     (("author") ("title")
498      ("journaltitle" nil nil 3) ("journal" nil nil -3)
499      ("date" nil nil 1) ("year" nil nil -1))
500     nil
501     (("translator") ("annotator") ("commentator") ("subtitle") ("titleaddon")
502      ("editor") ("editora") ("editorb") ("editorc") ("journalsubtitle")
503      ("journaltitleaddon") ("issuetitle") ("issuesubtitle") ("issuetitleaddon")
504      ("language") ("origlanguage") ("series") ("volume") ("number") ("eid")
505      ("issue") ("month") ("pages") ("version") ("note") ("issn")
506      ("addendum") ("pubstate") ("doi")
507      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
508      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
509      ("url") ("urldate")))
510    ("Book" "Single-Volume Book"
511     (("author") ("title")
512      ("date" nil nil 1) ("year" nil nil -1))
513     nil
514     (("editor") ("editora") ("editorb") ("editorc")
515      ("translator") ("annotator") ("commentator")
516      ("introduction") ("foreword") ("afterword") ("subtitle") ("titleaddon")
517      ("maintitle") ("mainsubtitle") ("maintitleaddon")
518      ("language") ("origlanguage") ("volume") ("part") ("edition") ("volumes")
519      ("series") ("number") ("note") ("publisher")
520      ("location" nil nil 2) ("address" nil nil -2) ("isbn") ("eid")
521      ("chapter") ("pages") ("pagetotal") ("addendum") ("pubstate") ("doi")
522      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
523      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
524      ("url") ("urldate")))
525    ("MVBook" "Multi-Volume Book"
526     (("author") ("title")
527      ("date" nil nil 1) ("year" nil nil -1))
528     nil
529     (("editor") ("editora") ("editorb") ("editorc")
530      ("translator") ("annotator") ("commentator")
531      ("introduction") ("foreword") ("afterword") ("subtitle")
532      ("titleaddon") ("language") ("origlanguage") ("edition") ("volumes")
533      ("series") ("number") ("note") ("publisher")
534      ("location" nil nil 2) ("address" nil nil -2)
535      ("isbn") ("pagetotal") ("addendum") ("pubstate") ("doi")
536      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
537      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
538      ("url") ("urldate")))
539    ("InBook" "Chapter or Pages in a Book"
540     (("title") ("date" nil nil 1) ("year" nil nil -1))
541     (("author") ("booktitle"))
542     (("bookauthor") ("editor") ("editora") ("editorb") ("editorc")
543      ("translator") ("annotator") ("commentator") ("introduction") ("foreword")
544      ("afterword") ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle")
545      ("maintitleaddon") ("booksubtitle") ("booktitleaddon")
546      ("language") ("origlanguage") ("volume") ("part") ("edition") ("volumes")
547      ("series") ("number") ("note") ("publisher")
548      ("location" nil nil 2) ("address" nil nil -2) ("isbn") ("eid")
549      ("chapter") ("pages") ("addendum") ("pubstate") ("doi")
550      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
551      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
552      ("url") ("urldate")))
553    ("BookInBook" "Book in Collection" ; same as @inbook
554     (("title") ("date" nil nil 1) ("year" nil nil -1))
555     (("author") ("booktitle"))
556     (("bookauthor") ("editor") ("editora") ("editorb") ("editorc")
557      ("translator") ("annotator") ("commentator") ("introduction") ("foreword")
558      ("afterword") ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle")
559      ("maintitleaddon") ("booksubtitle") ("booktitleaddon")
560      ("language") ("origlanguage") ("volume") ("part") ("edition") ("volumes")
561      ("series") ("number") ("note") ("publisher")
562      ("location" nil nil 2) ("address" nil nil -2) ("isbn") ("eid")
563      ("chapter") ("pages") ("addendum") ("pubstate") ("doi")
564      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
565      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
566      ("url") ("urldate")))
567    ("SuppBook" "Supplemental Material in a Book" ; same as @inbook
568     (("title") ("date" nil nil 1) ("year" nil nil -1))
569     (("author") ("booktitle"))
570     (("bookauthor") ("editor") ("editora") ("editorb") ("editorc")
571      ("translator") ("annotator") ("commentator") ("introduction") ("foreword")
572      ("afterword") ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle")
573      ("maintitleaddon") ("booksubtitle") ("booktitleaddon")
574      ("language") ("origlanguage") ("volume") ("part") ("edition") ("volumes")
575      ("series") ("number") ("note") ("publisher")
576      ("location" nil nil 2) ("address" nil nil -2) ("isbn") ("eid")
577      ("chapter") ("pages") ("addendum") ("pubstate") ("doi")
578      ("eprint")("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
579      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
580      ("url") ("urldate")))
581    ("Booklet" "Booklet (Bound, but no Publisher)"
582     (("author" nil nil 0) ("editor" nil nil 0) ("title")
583      ("date" nil nil 1) ("year" nil nil -1))
584     nil
585     (("subtitle") ("titleaddon") ("language") ("howpublished") ("type")
586      ("note") ("location" nil nil 2) ("address" nil nil -2)
587      ("eid") ("chapter") ("pages") ("pagetotal")
588      ("addendum") ("pubstate") ("doi")
589      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
590      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
591      ("url") ("urldate")))
592    ("Collection" "Single-Volume Collection"
593     (("editor") ("title")
594      ("date" nil nil 1) ("year" nil nil -1))
595     nil
596     (("editora") ("editorb") ("editorc") ("translator") ("annotator")
597      ("commentator") ("introduction") ("foreword") ("afterword")
598      ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle")
599      ("maintitleaddon") ("language") ("origlanguage") ("volume")
600      ("part") ("edition") ("volumes") ("series") ("number") ("note")
601      ("publisher") ("location" nil nil 2) ("address" nil nil -2)
602      ("isbn") ("eid") ("chapter") ("pages")
603      ("pagetotal") ("addendum") ("pubstate") ("doi")
604      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
605      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
606      ("url") ("urldate")))
607    ("MVCollection" "Multi-Volume Collection"
608     (("editor") ("title")
609      ("date" nil nil 1) ("year" nil nil -1))
610     nil
611     (("editora") ("editorb") ("editorc") ("translator") ("annotator")
612      ("commentator") ("introduction") ("foreword") ("afterword")
613      ("subtitle") ("titleaddon") ("language") ("origlanguage") ("edition")
614      ("volumes") ("series") ("number") ("note") ("publisher")
615      ("location" nil nil 2) ("address" nil nil -2)
616      ("isbn") ("pagetotal") ("addendum") ("pubstate") ("doi")
617      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
618      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
619      ("url") ("urldate")))
620    ("InCollection" "Article in a Collection"
621     (("author") ("title")
622      ("date" nil nil 1) ("year" nil nil -1))
623     (("booktitle"))
624     (("editor") ("editora") ("editorb") ("editorc") ("translator")
625      ("annotator") ("commentator") ("introduction") ("foreword") ("afterword")
626      ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle")
627      ("maintitleaddon") ("booksubtitle") ("booktitleaddon")
628      ("language") ("origlanguage") ("volume") ("part") ("edition")
629      ("volumes") ("series") ("number") ("note") ("publisher")
630      ("location" nil nil 2) ("address" nil nil -2)
631      ("isbn") ("eid") ("chapter") ("pages") ("addendum") ("pubstate") ("doi")
632      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
633      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
634      ("url") ("urldate")))
635    ("SuppCollection" "Supplemental Material in a Collection" ; same as @incollection
636     (("author") ("title")
637      ("date" nil nil 1) ("year" nil nil -1))
638     (("booktitle"))
639     (("editor") ("editora") ("editorb") ("editorc") ("translator")
640      ("annotator") ("commentator") ("introduction") ("foreword") ("afterword")
641      ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle")
642      ("maintitleaddon") ("booksubtitle") ("booktitleaddon")
643      ("language") ("origlanguage") ("volume") ("part") ("edition")
644      ("volumes") ("series") ("number") ("note") ("publisher")
645      ("location" nil nil 2) ("address" nil nil -2)
646      ("isbn") ("eid") ("chapter") ("pages") ("addendum") ("pubstate") ("doi")
647      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
648      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
649      ("url") ("urldate")))
650    ("Dataset" "Data Set"
651     (("author" nil nil 0) ("editor" nil nil 0) ("title")
652      ("date" nil nil 1) ("year" nil nil -1))
653     nil
654     (("subtitle") ("titleaddon") ("language") ("edition") ("type") ("series")
655      ("number") ("version") ("note") ("organization") ("publisher")
656      ("location" nil nil 2) ("address" nil nil -2)
657      ("addendum") ("pubstate") ("doi")
658      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
659      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
660      ("url") ("urldate")))
661    ("Manual" "Technical Manual"
662     (("author" nil nil 0) ("editor" nil nil 0) ("title")
663      ("date" nil nil 1) ("year" nil nil -1))
664     nil
665     (("subtitle") ("titleaddon") ("language") ("edition")
666      ("type") ("series") ("number") ("version") ("note")
667      ("organization") ("publisher")
668      ("location" nil nil 2) ("address" nil nil -2)
669      ("isbn") ("eid") ("chapter")
670      ("pages") ("pagetotal") ("addendum") ("pubstate") ("doi")
671      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
672      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
673      ("url") ("urldate")))
674    ("Misc" "Miscellaneous"
675     (("author" nil nil 0) ("editor" nil nil 0) ("title")
676      ("date" nil nil 1) ("year" nil nil -1))
677     nil
678     (("subtitle") ("titleaddon") ("language") ("howpublished") ("type")
679      ("version") ("note") ("organization")
680      ("location" nil nil 2) ("address" nil nil -2)
681      ("month") ("addendum") ("pubstate") ("doi")
682      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
683      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
684      ("url") ("urldate")))
685    ("Online" "Online Resource"
686     (("author" nil nil 0) ("editor" nil nil 0) ("title")
687      ("date" nil nil 1) ("year" nil nil -1)
688      ("doi" nil nil 2) ("eprint" nil nil 2) ("url" nil nil 2))
689     nil
690     (("subtitle") ("titleaddon") ("language") ("version") ("note")
691      ("organization") ("month") ("addendum")
692      ("pubstate") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
693      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) ("urldate")))
694    ("Patent" "Patent"
695     (("author") ("title") ("number")
696      ("date" nil nil 1) ("year" nil nil -1))
697     nil
698     (("holder") ("subtitle") ("titleaddon") ("type") ("version")
699      ("location" nil nil 2) ("address" nil nil -2)
700      ("note") ("month") ("addendum") ("pubstate") ("doi")
701      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
702      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
703      ("url") ("urldate")))
704    ("Periodical" "Complete Issue of a Periodical"
705     (("editor") ("title")
706      ("date" nil nil 1) ("year" nil nil -1))
707     nil
708     (("editora") ("editorb") ("editorc") ("subtitle") ("titleaddon")
709      ("issuetitle") ("issuesubtitle") ("issuetitleaddon") ("language")
710      ("series") ("volume") ("number") ("issue")
711      ("month") ("note") ("issn") ("addendum") ("pubstate") ("doi")
712      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
713      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
714      ("url") ("urldate")))
715    ("SuppPeriodical" "Supplemental Material in a Periodical" ; same as @article
716     (("author") ("title")
717      ("journaltitle" nil nil 3) ("journal" nil nil -3)
718      ("date" nil nil 1) ("year" nil nil -1))
719     nil
720     (("translator") ("annotator") ("commentator") ("subtitle") ("titleaddon")
721      ("editor") ("editora") ("editorb") ("editorc") ("journalsubtitle")
722      ("journaltitleaddon") ("issuetitle") ("issuesubtitle") ("issuetitleaddon")
723      ("language") ("origlanguage") ("series") ("volume") ("number") ("eid")
724      ("issue") ("month") ("pages") ("version") ("note") ("issn")
725      ("addendum") ("pubstate") ("doi")
726      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
727      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
728      ("url") ("urldate")))
729    ("Proceedings" "Single-Volume Conference Proceedings"
730     (("title") ("date" nil nil 1) ("year" nil nil -1))
731     nil
732     (("editor") ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle")
733      ("maintitleaddon") ("eventtitle") ("eventtitleaddon") ("eventdate")
734      ("venue") ("language") ("volume") ("part") ("volumes") ("series")
735      ("number") ("note") ("organization") ("publisher")
736      ("location" nil nil 2) ("address" nil nil -2) ("month")
737      ("isbn") ("eid") ("chapter") ("pages") ("pagetotal") ("addendum")
738      ("pubstate") ("doi")
739      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
740      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
741      ("url") ("urldate")))
742    ("MVProceedings" "Multi-Volume Conference Proceedings"
743     (("title") ("date" nil nil 1) ("year" nil nil -1))
744     nil
745     (("editor") ("subtitle") ("titleaddon") ("eventtitle") ("eventtitleaddon")
746      ("eventdate") ("venue") ("language") ("volumes") ("series") ("number")
747      ("note") ("organization") ("publisher")
748      ("location" nil nil 2) ("address" nil nil -2) ("month")
749      ("isbn") ("pagetotal") ("addendum") ("pubstate") ("doi")
750      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
751      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
752      ("url") ("urldate")))
753    ("InProceedings" "Article in Conference Proceedings"
754     (("author") ("title")
755      ("date" nil nil 1) ("year" nil nil -1))
756     (("booktitle"))
757     (("editor") ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle")
758      ("maintitleaddon") ("booksubtitle") ("booktitleaddon")
759      ("eventtitle") ("eventtitleaddon") ("eventdate") ("venue") ("language")
760      ("volume") ("part") ("volumes") ("series") ("number") ("note")
761      ("organization") ("publisher")
762      ("location" nil nil 2) ("address" nil nil -2) ("month") ("isbn") ("eid")
763      ("chapter") ("pages") ("addendum") ("pubstate") ("doi")
764      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
765      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
766      ("url") ("urldate")))
767    ("Reference" "Single-Volume Work of Reference" ; same as @collection
768     (("editor") ("title") ("date" nil nil 1) ("year" nil nil -1))
769     nil
770     (("editora") ("editorb") ("editorc") ("translator") ("annotator")
771      ("commentator") ("introduction") ("foreword") ("afterword")
772      ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle")
773      ("maintitleaddon") ("language") ("origlanguage") ("volume")
774      ("part") ("edition") ("volumes") ("series") ("number") ("note")
775      ("publisher") ("location" nil nil 2) ("address" nil nil -2)
776      ("isbn") ("eid") ("chapter") ("pages")
777      ("pagetotal") ("addendum") ("pubstate") ("doi")
778      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
779      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
780      ("url") ("urldate")))
781    ("MVReference" "Multi-Volume Work of Reference" ; same as @mvcollection
782     (("editor") ("title") ("date" nil nil 1) ("year" nil nil -1))
783     nil
784     (("editora") ("editorb") ("editorc") ("translator") ("annotator")
785      ("commentator") ("introduction") ("foreword") ("afterword")
786      ("subtitle") ("titleaddon") ("language") ("origlanguage") ("edition")
787      ("volumes") ("series") ("number") ("note") ("publisher")
788      ("location" nil nil 2) ("address" nil nil -2)
789      ("isbn") ("pagetotal") ("addendum") ("pubstate") ("doi")
790      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
791      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
792      ("url") ("urldate")))
793    ("InReference" "Article in a Work of Reference" ; same as @incollection
794     (("author") ("title") ("date" nil nil 1) ("year" nil nil -1))
795     (("booktitle"))
796     (("editor") ("editora") ("editorb") ("editorc") ("translator")
797      ("annotator") ("commentator") ("introduction") ("foreword") ("afterword")
798      ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle")
799      ("maintitleaddon") ("booksubtitle") ("booktitleaddon")
800      ("language") ("origlanguage") ("volume") ("part") ("edition")
801      ("volumes") ("series") ("number") ("note") ("publisher")
802      ("location" nil nil 2) ("address" nil nil -2)
803      ("isbn") ("eid") ("chapter") ("pages") ("addendum") ("pubstate") ("doi")
804      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
805      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
806      ("url") ("urldate")))
807    ("Report" "Technical or Research Report"
808     (("author") ("title") ("type")
809      ("institution" nil nil 6) ("school" nil nil -6)
810      ("date" nil nil 1) ("year" nil nil -1))
811     nil
812     (("subtitle") ("titleaddon") ("language") ("number") ("version") ("note")
813      ("location" nil nil 2) ("address" nil nil -2)
814      ("month") ("isrn") ("eid") ("chapter") ("pages")
815      ("pagetotal") ("addendum") ("pubstate") ("doi")
816      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
817      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
818      ("url") ("urldate")))
819    ("Software" "Computer Software" ; Same as @misc.
820     (("author" nil nil 0) ("editor" nil nil 0) ("title")
821      ("date" nil nil 1) ("year" nil nil -1))
822     nil
823     (("subtitle") ("titleaddon") ("language") ("howpublished") ("type")
824      ("version") ("note") ("organization")
825      ("location" nil nil 2) ("address" nil nil -2)
826      ("month") ("addendum") ("pubstate") ("doi")
827      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
828      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
829      ("url") ("urldate")))
830    ("Thesis" "PhD or Master's Thesis"
831     (("author") ("title") ("type")
832      ("institution" nil nil 6) ("school" nil nil -6)
833      ("date" nil nil 1) ("year" nil nil -1))
834     nil
835     (("subtitle") ("titleaddon") ("language") ("note")
836      ("location" nil nil 2) ("address" nil nil -2)
837      ("month") ("isbn") ("eid") ("chapter") ("pages") ("pagetotal")
838      ("addendum") ("pubstate") ("doi")
839      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
840      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
841      ("url") ("urldate")))
842    ("PhdThesis" "PhD Thesis"
843     (("author")
844      ("title" "Title of the PhD thesis")
845      ("school" "School where the PhD thesis was written")
846      ("year"))
847     nil
848     (("type" "Type of the PhD thesis")
849      ("address" "Address of the school (if not part of field \"school\") or country")
850      ("month") ("note")))
851    ("TechReport" "Technical Report"
852     (("author")
853      ("title" "Title of the technical report (BibTeX converts it to lowercase)")
854      ("institution" "Sponsoring institution of the report")
855      ("year"))
856     nil
857     (("type" "Type of the report (if other than \"technical report\")")
858      ("number" "Number of the technical report")
859      ("address") ("month") ("note")))
860    ("Unpublished" "Unpublished"
861     (("author") ("title") ("date" nil nil 1) ("year" nil nil -1))
862     nil
863     (("subtitle") ("titleaddon") ("type") ("eventtitle") ("eventtitleaddon")
864      ("eventdate") ("venue") ("language") ("howpublished") ("note")
865      ("location" nil nil 2) ("address" nil nil -2)
866      ("isbn") ("month") ("addendum") ("pubstate") ("doi")
867      ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
868      ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
869      ("url") ("urldate"))))
870  "Alist of biblatex entry types and their associated fields.
871It has the same format as `bibtex-BibTeX-entry-alist'."
872  :group 'bibtex
873  :version "28.1"
874  :type 'bibtex-entry-alist
875  :risky t)
876
877(define-widget 'bibtex-field-alist 'lazy
878  "Format of `bibtex-BibTeX-entry-alist' and friends."
879  :type '(repeat (group (string :tag "Field type")
880                        (string :tag "Comment"))))
881
882(defcustom bibtex-BibTeX-field-alist
883  '(("author" "Author1 [and Author2 ...] [and others]")
884    ("editor" "Editor1 [and Editor2 ...] [and others]")
885    ("journal" "Name of the journal (use string, remove braces)")
886    ("year" "Year of publication")
887    ("month" "Month of the publication as a string (remove braces)")
888    ("note" "Remarks to be put at the end of the \\bibitem")
889    ("publisher" "Publishing company")
890    ("address" "Address of the publisher"))
891    "Alist of BibTeX fields.
892Each element is a list (FIELD COMMENT).  COMMENT is used as a default
893if `bibtex-BibTeX-entry-alist' does not define a comment for FIELD."
894  :group 'bibtex
895  :version "24.1"
896  :type 'bibtex-field-alist)
897
898(defcustom bibtex-biblatex-field-alist
899  ;; See 2.2.2 Data Fields
900  '(("abstract" "Abstract of the work")
901    ("addendum" "Miscellaneous bibliographic data")
902    ("afterword" "Author(s) of an afterword to the work")
903    ("annotation" "Annotation")
904    ("annotator" "Author(s) of annotations to the work")
905    ("author" "Author(s) of the title")
906    ("bookauthor" "Author(s) of the booktitle.")
907    ("bookpagination" "Pagination scheme of the enclosing work")
908    ("booksubtitle" "Subtitle related to the booktitle")
909    ("booktitle" "Title of the book")
910    ("booktitleaddon" "Annex to the booktitle")
911    ("chapter" "Chapter, section, or any other unit of a work")
912    ("commentator" "Author(s) of a commentary to the work")
913    ("date" "Publication date")
914    ("doi" "Digital Object Identifier")
915    ("edition" "Edition of a printed publication")
916    ("editor" "Editor(s) of the title, booktitle, or maintitle")
917    ("editora" "Secondary editor")
918    ("editorb" "Secondary editor")
919    ("editorc" "Secondary editor")
920    ("editortype" "Type of editorial role performed by the editor")
921    ("editoratype" "Type of editorial role performed by editora")
922    ("editorbtype" "Type of editorial role performed by editorb")
923    ("editorctype" "Type of editorial role performed by editorc")
924    ("eid" "Electronic identifier of an article")
925    ("eprint" "Electronic identifier of an online publication")
926    ("eprintclass" "Additional information related to the eprinttype")
927    ("eprinttype" "Type of eprint identifier")
928    ("eventdate" "Date of a conference or some other event")
929    ("eventtitle" "Title of a conference or some other event")
930    ("eventtitleaddon" "Annex to the eventtitle (e.g., acronym of known event)")
931    ("file" "Local link to an electronic version of the work")
932    ("foreword" "Author(s) of a foreword to the work")
933    ("holder" "Holder(s) of a patent")
934    ("howpublished" "Publication notice for unusual publications")
935    ("indextitle" "Title to use for indexing instead of the regular title")
936    ("institution" "Name of a university or some other institution")
937    ("introduction" "Author(s) of an introduction to the work")
938    ("isan" "International Standard Audiovisual Number of an audiovisual work")
939    ("isbn" "International Standard Book Number of a book.")
940    ("ismn" "International Standard Music Number for printed music")
941    ("isrn" "International Standard Technical Report Number")
942    ("issn" "International Standard Serial Number of a periodical.")
943    ("issue" "Issue of a journal")
944    ("issuesubtitle" "Subtitle of a specific issue of a journal or other periodical.")
945    ("issuetitle" "Title of a specific issue of a journal or other periodical.")
946    ("issuetitleaddon" "Annex to the issuetitle")
947    ("iswc" "International Standard Work Code of a musical work")
948    ("journalsubtitle" "Subtitle of a journal, a newspaper, or some other periodical.")
949    ("journaltitle" "Name of a journal, a newspaper, or some other periodical.")
950    ("journaltitleaddon" "Annex to the journaltitle")
951    ("label" "Substitute for the regular label to be used by the citation style")
952    ("language" "Language(s) of the work")
953    ("library" "Library name and a call number")
954    ("location" "Place(s) of publication")
955    ("mainsubtitle" "Subtitle related to the maintitle")
956    ("maintitle" "Main title of a multi-volume book, such as Collected Works")
957    ("maintitleaddon" "Annex to the maintitle")
958    ("month" "Publication month")
959    ("nameaddon" "Addon to be printed immediately after the author name")
960    ("note" "Miscellaneous bibliographic data")
961    ("number" "Number of a journal or the volume/number of a book in a series")
962    ("organization" "Organization(s) that published a work")
963    ("origdate" "Publication date of the original edition")
964    ("origlanguage" "Original publication language of a translated edition")
965    ("origlocation" "Location of the original edition")
966    ("origpublisher" "Publisher of the original edition")
967    ("origtitle" "Title of the original work")
968    ("pages" "Page number(s) or page range(s)")
969    ("pagetotal" "Total number of pages of the work.")
970    ("pagination" "Pagination of the work")
971    ("part" "Number of a partial volume")
972    ("publisher" "Name(s) of the publisher(s)")
973    ("pubstate" "Publication state of the work, e. g.,'in press'")
974    ("reprinttitle" "Title of a reprint of the work")
975    ("series" "Name of a publication series")
976    ("shortauthor" "Author(s) of the work, given in an abbreviated form")
977    ("shorteditor" "Editor(s) of the work, given in an abbreviated form")
978    ("shorthand" "Special designation overriding the default label")
979    ("shorthandintro" "Phrase overriding the standard shorthand introduction")
980    ("shortjournal" "Short version or an acronym of the journal title")
981    ("shortseries" "Short version or an acronym of the series field")
982    ("shorttitle" "Title in an abridged form")
983    ("subtitle" "Subtitle of the work")
984    ("title" "Title of the work")
985    ("titleaddon" "Annex to the title")
986    ("translator" "Translator(s) of the work")
987    ("type" "Type of a manual, patent, report, or thesis")
988    ("url" " URL of an online publication.")
989    ("urldate" "Access date of the address specified in the url field")
990    ("venue" "Location of a conference, a symposium, or some other event")
991    ("version" "Revision number of a piece of software, a manual, etc.")
992    ("volume" "Volume of a multi-volume book or a periodical")
993    ("volumes" "Total number of volumes of a multi-volume work")
994    ("year" "Year of publication"))
995    "Alist of biblatex fields.
996It has the same format as `bibtex-BibTeX-entry-alist'."
997  :group 'bibtex
998  :version "28.1"
999  :type 'bibtex-field-alist)
1000
1001(defcustom bibtex-dialect-list '(BibTeX biblatex)
1002  "List of BibTeX dialects known to BibTeX mode.
1003For each DIALECT (a symbol) a variable bibtex-DIALECT-entry-alist defines
1004the allowed entries and bibtex-DIALECT-field-alist defines known field types.
1005Predefined dialects include BibTeX and biblatex."
1006  :group 'bibtex
1007  :version "24.1"
1008  :type '(repeat (symbol :tag "Dialect")))
1009
1010(defcustom bibtex-dialect 'BibTeX
1011  "Current BibTeX dialect.  For allowed values see `bibtex-dialect-list'.
1012To interactively change the dialect use the command `bibtex-set-dialect'."
1013  :group 'bibtex
1014  :version "24.1"
1015  :set (lambda (symbol value)
1016         (set-default symbol value)
1017         ;; `bibtex-set-dialect' is undefined during loading (no problem).
1018         (if (fboundp 'bibtex-set-dialect)
1019             (bibtex-set-dialect value)))
1020  :type '(choice (const BibTeX)
1021                 (const biblatex)
1022                 (symbol :tag "Custom"))
1023  :safe #'symbolp)
1024
1025(defcustom bibtex-no-opt-remove-re "\\`option"
1026  "If a field name matches this regexp, the prefix OPT is not removed.
1027If nil prefix OPT is always removed."
1028  :group 'bibtex
1029  :version "24.1"
1030  :type '(choice (regexp) (const nil)))
1031
1032(defcustom bibtex-comment-start "@Comment"
1033  "String starting a BibTeX comment."
1034  :group 'bibtex
1035  :type 'string
1036  :safe #'stringp)
1037
1038(defcustom bibtex-add-entry-hook nil
1039  "List of functions to call when BibTeX entry has been inserted."
1040  :group 'bibtex
1041  :type 'hook)
1042
1043(defcustom bibtex-predefined-month-strings
1044  '(("jan" . "January")
1045    ("feb" . "February")
1046    ("mar" . "March")
1047    ("apr" . "April")
1048    ("may" . "May")
1049    ("jun" . "June")
1050    ("jul" . "July")
1051    ("aug" . "August")
1052    ("sep" . "September")
1053    ("oct" . "October")
1054    ("nov" . "November")
1055    ("dec" . "December"))
1056  "Alist of month string definitions used in the BibTeX style files.
1057Each element is a pair of strings (ABBREVIATION . EXPANSION)."
1058  :group 'bibtex
1059  :type '(repeat (cons (string :tag "Month abbreviation")
1060                       (string :tag "Month expansion"))))
1061
1062(defcustom bibtex-predefined-strings
1063  (append
1064   bibtex-predefined-month-strings
1065   '(("acmcs"    . "ACM Computing Surveys")
1066     ("acta"     . "Acta Informatica")
1067     ("cacm"     . "Communications of the ACM")
1068     ("ibmjrd"   . "IBM Journal of Research and Development")
1069     ("ibmsj"    . "IBM Systems Journal")
1070     ("ieeese"   . "IEEE Transactions on Software Engineering")
1071     ("ieeetc"   . "IEEE Transactions on Computers")
1072     ("ieeetcad" . "IEEE Transactions on Computer-Aided Design of Integrated Circuits")
1073     ("ipl"      . "Information Processing Letters")
1074     ("jacm"     . "Journal of the ACM")
1075     ("jcss"     . "Journal of Computer and System Sciences")
1076     ("scp"      . "Science of Computer Programming")
1077     ("sicomp"   . "SIAM Journal on Computing")
1078     ("tcs"      . "Theoretical Computer Science")
1079     ("tocs"     . "ACM Transactions on Computer Systems")
1080     ("tods"     . "ACM Transactions on Database Systems")
1081     ("tog"      . "ACM Transactions on Graphics")
1082     ("toms"     . "ACM Transactions on Mathematical Software")
1083     ("toois"    . "ACM Transactions on Office Information Systems")
1084     ("toplas"   . "ACM Transactions on Programming Languages and Systems")))
1085  "Alist of string definitions used in the BibTeX style files.
1086Each element is a pair of strings (ABBREVIATION . EXPANSION)."
1087  :group 'bibtex
1088  :type '(repeat (cons (string :tag "String")
1089                       (string :tag "String expansion"))))
1090
1091(defcustom bibtex-string-files nil
1092  "List of BibTeX files containing string definitions.
1093List elements can be absolute file names or file names relative
1094to the directories specified in `bibtex-string-file-path'."
1095  :group 'bibtex
1096  :type '(repeat file))
1097
1098(defcustom bibtex-string-file-path (getenv "BIBINPUTS")
1099  "Colon-separated list of paths to search for `bibtex-string-files'.
1100Initialized from the BIBINPUTS environment variable."
1101  :group 'bibtex
1102  :version "27.1"
1103  :type '(choice string
1104                 (const :tag "Not Set" nil)))
1105
1106(defcustom bibtex-files nil
1107  "List of BibTeX files that are searched for entry keys.
1108List elements can be absolute file names or file names relative to the
1109directories specified in `bibtex-file-path'.  If an element is a directory,
1110check all BibTeX files in this directory.  If an element is the symbol
1111`bibtex-file-path', check all BibTeX files in `bibtex-file-path'.
1112See also `bibtex-search-entry-globally'."
1113  :group 'bibtex
1114  :type '(repeat (choice (const :tag "bibtex-file-path" bibtex-file-path)
1115                         directory file)))
1116
1117(defcustom bibtex-file-path (getenv "BIBINPUTS")
1118  "Colon separated list of paths to search for `bibtex-files'.
1119Initialized from the BIBINPUTS environment variable."
1120  :group 'bibtex
1121  :version "27.1"
1122  :type '(choice string
1123                 (const :tag "Not Set" nil)))
1124
1125(defcustom bibtex-search-entry-globally nil
1126  "If non-nil, interactive calls of `bibtex-search-entry' search globally.
1127A global search includes all files in `bibtex-files'."
1128  :group 'bibtex
1129  :version "24.1"
1130  :type 'boolean)
1131
1132(defcustom bibtex-help-message t
1133  "If non-nil print help messages in the echo area on entering a new field."
1134  :group 'bibtex
1135  :type 'boolean)
1136
1137(defcustom bibtex-autokey-prefix-string ""
1138  "String prefix for automatically generated reference keys.
1139See `bibtex-generate-autokey' for details."
1140  :group 'bibtex-autokey
1141  :type 'string)
1142
1143(defcustom bibtex-autokey-names 1
1144  "Number of names to use for the automatically generated reference key.
1145Possibly more names are used according to `bibtex-autokey-names-stretch'.
1146If this variable is nil, all names are used.
1147See `bibtex-generate-autokey' for details."
1148  :group 'bibtex-autokey
1149  :type '(choice (const :tag "All" infty)
1150                 integer))
1151
1152(defcustom bibtex-autokey-names-stretch 0
1153  "Number of names that can additionally be used for reference keys.
1154These names are used only, if all names are used then.
1155See `bibtex-generate-autokey' for details."
1156  :group 'bibtex-autokey
1157  :type 'integer)
1158
1159(defcustom bibtex-autokey-additional-names ""
1160  "String to append to the generated key if not all names could be used.
1161See `bibtex-generate-autokey' for details."
1162  :group 'bibtex-autokey
1163  :type 'string)
1164
1165(defcustom bibtex-autokey-expand-strings nil
1166  "If non-nil, expand strings when extracting the content of a BibTeX field.
1167See `bibtex-generate-autokey' for details."
1168  :group 'bibtex-autokey
1169  :type 'boolean)
1170
1171(defvar bibtex-autokey-transcriptions
1172  (nconc
1173   (mapcar (lambda (a) (cons (regexp-opt (car a)) (cdr a)))
1174           '(;; language specific characters
1175             (("\\aa") . "a")                      ; \aa           -> a
1176             (("\\AA") . "A")                      ; \AA           -> A
1177             (("\"a" "\\\"a" "\\ae") . "ae")       ; "a,\"a,\ae    -> ae
1178             (("\"A" "\\\"A" "\\AE") . "Ae")       ; "A,\"A,\AE    -> Ae
1179             (("\\i") . "i")                       ; \i            -> i
1180             (("\\j") . "j")                       ; \j            -> j
1181             (("\\l") . "l")                       ; \l            -> l
1182             (("\\L") . "L")                       ; \L            -> L
1183             (("\"o" "\\\"o" "\\o" "\\oe") . "oe") ; "o,\"o,\o,\oe -> oe
1184             (("\"O" "\\\"O" "\\O" "\\OE") . "Oe") ; "O,\"O,\O,\OE -> Oe
1185             (("\"s" "\\\"s" "\\3") . "ss")        ; "s,\"s,\3     -> ss
1186             (("\"u" "\\\"u") . "ue")              ; "u,\"u        -> ue
1187             (("\"U" "\\\"U") . "Ue")              ; "U,\"U        -> Ue
1188             ;; hyphen, accents
1189             (("\\-" "\\`" "\\'" "\\^" "\\~" "\\=" "\\." "\\u" "\\v"
1190               "\\H" "\\t" "\\c" "\\d" "\\b") . "")
1191             ;; space
1192             (("~") . " ")))
1193   ;; more spaces
1194   '(("[\s\t\n]*\\(?:\\\\\\)?[\s\t\n]+" . " ")
1195     ;; braces, quotes, concatenation.
1196     ("[`'\"{}#]" . "")))
1197  "Alist of (OLD-REGEXP . NEW-STRING) pairs.
1198Used as default values of `bibtex-autokey-name-change-strings' and
1199`bibtex-autokey-titleword-change-strings'.  Defaults to translating some
1200language specific characters to their ASCII transcriptions, and
1201removing any accent characters.")
1202
1203(defcustom bibtex-autokey-name-change-strings
1204  bibtex-autokey-transcriptions
1205  "Alist of (OLD-REGEXP . NEW-STRING) pairs.
1206Any part of a name matching OLD-REGEXP is replaced by NEW-STRING.
1207Case is significant in OLD-REGEXP.  All regexps are tried in the
1208order in which they appear in the list.
1209See `bibtex-generate-autokey' for details."
1210  :group 'bibtex-autokey
1211  :type '(repeat (cons (regexp :tag "Old")
1212                       (string :tag "New"))))
1213
1214(define-obsolete-variable-alias 'bibtex-autokey-name-case-convert
1215  'bibtex-autokey-name-case-convert-function "29.1")
1216
1217(defcustom bibtex-autokey-name-case-convert-function #'downcase
1218  "Function called for each name to perform case conversion.
1219See `bibtex-generate-autokey' for details."
1220  :group 'bibtex-autokey
1221  :type '(choice (const :tag "Preserve case" identity)
1222                 (const :tag "Downcase" downcase)
1223                 (const :tag "Capitalize" capitalize)
1224                 (const :tag "Upcase" upcase)
1225                 (function :tag "Conversion function" :value identity))
1226  :safe (lambda (x) (memq x '(upcase downcase capitalize identity))))
1227
1228(defcustom bibtex-autokey-name-length 'infty
1229  "Number of characters from name to incorporate into key.
1230If this is set to anything but a number, all characters are used.
1231See `bibtex-generate-autokey' for details."
1232  :group 'bibtex-autokey
1233  :type '(choice (const :tag "All" infty)
1234                 integer))
1235
1236(defcustom bibtex-autokey-name-separator ""
1237  "String that comes between any two names in the key.
1238See `bibtex-generate-autokey' for details."
1239  :group 'bibtex-autokey
1240  :type 'string)
1241
1242(defcustom bibtex-autokey-year-length 2
1243  "Number of rightmost digits from the year field to incorporate into key.
1244See `bibtex-generate-autokey' for details."
1245  :group 'bibtex-autokey
1246  :type 'integer)
1247
1248(defcustom bibtex-autokey-use-crossref t
1249  "If non-nil use fields from cross-referenced entry if necessary.
1250If this variable is non-nil and some field has no entry, but a
1251valid crossref entry, the field from the cross-referenced entry is used.
1252See `bibtex-generate-autokey' for details."
1253  :group 'bibtex-autokey
1254  :type 'boolean)
1255
1256(defcustom bibtex-autokey-titlewords 5
1257  "Number of title words to use for the automatically generated reference key.
1258If this is set to anything but a number, all title words are used.
1259Possibly more words from the title are used according to
1260`bibtex-autokey-titlewords-stretch'.
1261See `bibtex-generate-autokey' for details."
1262  :group 'bibtex-autokey
1263  :type '(choice (const :tag "All" infty)
1264                 integer))
1265
1266(defcustom bibtex-autokey-title-terminators "[.!?:;]\\|--"
1267  "Regexp defining the termination of the main part of the title.
1268Case of the regexps is ignored.  See `bibtex-generate-autokey' for details."
1269  :group 'bibtex-autokey
1270  :type 'regexp)
1271
1272(defcustom bibtex-autokey-titlewords-stretch 2
1273  "Number of words that can additionally be used from the title.
1274These words are used only, if a sentence from the title can be ended then.
1275See `bibtex-generate-autokey' for details."
1276  :group 'bibtex-autokey
1277  :type 'integer)
1278
1279(defcustom bibtex-autokey-titleword-ignore
1280  '("A" "An" "On" "The" "Eine?" "Der" "Die" "Das"
1281    "[^[:upper:]].*" ".*[^[:upper:][:lower:]0-9].*")
1282  "Determines words from the title that are not to be used in the key.
1283Each item of the list is a regexp.  If a word of the title matches a
1284regexp from that list, it is not included in the title part of the key.
1285Case is significant.  See `bibtex-generate-autokey' for details."
1286  :group 'bibtex-autokey
1287  :type '(repeat regexp))
1288
1289(define-obsolete-variable-alias 'bibtex-autokey-titleword-case-convert
1290  'bibtex-autokey-titleword-case-convert-function "29.1")
1291
1292(defcustom bibtex-autokey-titleword-case-convert-function #'downcase
1293  "Function called for each titleword to perform case conversion.
1294See `bibtex-generate-autokey' for details."
1295  :group 'bibtex-autokey
1296  :type '(choice (const :tag "Preserve case" identity)
1297                 (const :tag "Downcase" downcase)
1298                 (const :tag "Capitalize" capitalize)
1299                 (const :tag "Upcase" upcase)
1300                 (function :tag "Conversion function")))
1301
1302(defcustom bibtex-autokey-titleword-abbrevs nil
1303  "Determines exceptions to the usual abbreviation mechanism.
1304An alist of (OLD-REGEXP . NEW-STRING) pairs.  Case is ignored
1305in matching against OLD-REGEXP, and the first matching pair is used.
1306See `bibtex-generate-autokey' for details."
1307  :group 'bibtex-autokey
1308  :type '(repeat (cons (regexp :tag "Old")
1309                       (string :tag "New"))))
1310
1311(defcustom bibtex-autokey-titleword-change-strings
1312  bibtex-autokey-transcriptions
1313  "Alist of (OLD-REGEXP . NEW-STRING) pairs.
1314Any part of title word matching a OLD-REGEXP is replaced by NEW-STRING.
1315Case is significant in OLD-REGEXP.  All regexps are tried in the
1316order in which they appear in the list.
1317See `bibtex-generate-autokey' for details."
1318  :group 'bibtex-autokey
1319  :type '(repeat (cons (regexp :tag "Old")
1320                       (string :tag "New"))))
1321
1322(defcustom bibtex-autokey-titleword-length 5
1323  "Number of characters from title words to incorporate into key.
1324If this is set to anything but a number, all characters are used.
1325See `bibtex-generate-autokey' for details."
1326  :group 'bibtex-autokey
1327  :type '(choice (const :tag "All" infty)
1328                 integer))
1329
1330(defcustom bibtex-autokey-titleword-separator "_"
1331  "String to be put between the title words.
1332See `bibtex-generate-autokey' for details."
1333  :group 'bibtex-autokey
1334  :type 'string)
1335
1336(defcustom bibtex-autokey-name-year-separator ""
1337  "String to be put between name part and year part of key.
1338See `bibtex-generate-autokey' for details."
1339  :group 'bibtex-autokey
1340  :type 'string)
1341
1342(defcustom bibtex-autokey-year-title-separator ":_"
1343  "String to be put between year part and title part of key.
1344See `bibtex-generate-autokey' for details."
1345  :group 'bibtex-autokey
1346  :type 'string)
1347
1348(defcustom bibtex-autokey-edit-before-use t
1349  "If non-nil, user is allowed to edit the generated key before it is used."
1350  :group 'bibtex-autokey
1351  :type 'boolean)
1352
1353(defcustom bibtex-autokey-before-presentation-function #'identity
1354  "Function to call before generated key is presented.
1355The function must take one argument (the automatically generated key),
1356and must return a string (the key to use)."
1357  :group 'bibtex-autokey
1358  :version "28.1"
1359  :type 'function)
1360
1361(defcustom bibtex-entry-offset 0
1362  "Offset for BibTeX entries.
1363Added to the value of all other variables which determine columns."
1364  :group 'bibtex
1365  :type 'integer
1366  :safe #'integerp)
1367
1368(defcustom bibtex-field-indentation 2
1369  "Starting column for the name part in BibTeX fields."
1370  :group 'bibtex
1371  :type 'integer)
1372
1373(defcustom bibtex-text-indentation
1374  (+ bibtex-field-indentation
1375     (length "organization = "))
1376  "Starting column for the text part in BibTeX fields.
1377Should be equal to the space needed for the longest name part."
1378  :group 'bibtex
1379  :type 'integer
1380  :safe #'integerp)
1381
1382(defcustom bibtex-contline-indentation
1383  (+ bibtex-text-indentation 1)
1384  "Starting column for continuation lines of BibTeX fields."
1385  :group 'bibtex
1386  :type 'integer
1387  :safe #'integerp)
1388
1389(defcustom bibtex-align-at-equal-sign nil
1390  "If non-nil, align fields at equal sign instead of field text.
1391If non-nil, the column for the equal sign is the value of
1392`bibtex-text-indentation', minus 2."
1393  :group 'bibtex
1394  :type 'boolean)
1395
1396(defcustom bibtex-comma-after-last-field nil
1397  "If non-nil, a comma is put at end of last field in the entry template."
1398  :group 'bibtex
1399  :type 'boolean)
1400
1401(defcustom bibtex-autoadd-commas t
1402  "If non-nil automatically add missing commas at end of BibTeX fields."
1403  :group 'bibtex
1404  :type 'boolean)
1405
1406(defcustom bibtex-autofill-types '("Proceedings")
1407  "Automatically fill fields if possible for those BibTeX entry types."
1408  :group 'bibtex
1409  :type '(repeat string))
1410
1411(defcustom bibtex-summary-function #'bibtex-summary
1412  "Function to call for generating a summary of current BibTeX entry.
1413It takes no arguments.  Point must be at beginning of entry.
1414Used by `bibtex-complete-crossref-cleanup' and `bibtex-copy-summary-as-kill'."
1415  :group 'bibtex
1416  :type '(choice (const :tag "Default" bibtex-summary)
1417                 (function :tag "Personalized function")))
1418
1419(defcustom bibtex-generate-url-list
1420  '((("url" . ".*:.*"))
1421    (("doi" . "10\\.[0-9]+/.+")
1422     "https://doi.org/%s"
1423     ("doi" ".*" 0)))
1424  "List of schemes for generating the URL of a BibTeX entry.
1425These schemes are used by `bibtex-url'.
1426
1427Each scheme should have one of these forms:
1428
1429  ((FIELD . REGEXP))
1430  ((FIELD . REGEXP) STEP...)
1431  ((FIELD . REGEXP) STRING STEP...)
1432
1433FIELD is a field name as returned by `bibtex-parse-entry'.
1434REGEXP is matched against the text of FIELD.  If the match succeeds,
1435then this scheme is used.  If no STRING and STEPs are specified
1436the matched text is used as the URL, otherwise the URL is built
1437by evaluating STEPs.  If no STRING is specified the STEPs must result
1438in strings which are concatenated.  Otherwise the resulting objects
1439are passed through `format' using STRING as format control string.
1440
1441A STEP is a list (FIELD REGEXP REPLACE).  The text of FIELD
1442is matched against REGEXP, and is replaced with REPLACE.
1443REPLACE can be a string, or a number (which selects the corresponding
1444submatch), or a function called with the field's text as argument
1445and with the `match-data' properly set.
1446
1447Case is always ignored.  Always remove the field delimiters.
1448If `bibtex-expand-strings' is non-nil, BibTeX strings are expanded
1449for generating the URL.
1450Set this variable before loading BibTeX mode.
1451
1452The following is a complex example, see URL `https://link.aps.org/'.
1453
1454   (((\"journal\" . \"\\\\=<\\(PR[ABCDEL]?\\|RMP\\)\\\\=>\")
1455     \"http://link.aps.org/abstract/%s/v%s/p%s\"
1456     (\"journal\" \".*\" upcase)
1457     (\"volume\" \".*\" 0)
1458     (\"pages\" \"\\`[A-Z]?[0-9]+\" 0)))"
1459  :group 'bibtex
1460  :version "24.4"
1461  :type '(repeat
1462          (cons :tag "Scheme"
1463                (cons :tag "Matcher" :extra-offset 4
1464                      (string :tag "BibTeX field")
1465		      (regexp :tag "Regexp"))
1466                (choice
1467                 (const :tag "Take match as is" nil)
1468                 (cons :tag "Formatted"
1469                  (string :tag "Format control string")
1470                  (repeat :tag "Steps to generate URL"
1471                          (list (string :tag "BibTeX field")
1472                                (regexp :tag "Regexp")
1473                                (choice (string :tag "Replacement")
1474                                        (integer :tag "Sub-match")
1475                                        (function :tag "Filter")))))
1476                 (repeat :tag "Concatenated"
1477                         (list (string :tag "BibTeX field")
1478			       (regexp :tag "Regexp")
1479                               (choice (string :tag "Replacement")
1480				       (integer :tag "Sub-match")
1481                                       (function :tag "Filter")))))))
1482  :risky t)
1483
1484(defcustom bibtex-cite-matcher-alist
1485  '(("\\\\cite[ \t\n]*{\\([^}]+\\)}" . 1))
1486  "Alist of rules to identify cited keys in a BibTeX entry.
1487Each rule should be of the form (REGEXP . SUBEXP), where SUBEXP
1488specifies which parenthesized expression in REGEXP is a cited key.
1489Case is significant.
1490Used by `bibtex-search-crossref' and for font-locking.
1491Set this variable before loading BibTeX mode."
1492  :group 'bibtex
1493  :type '(repeat (cons (regexp :tag "Regexp")
1494                       (integer :tag "Number")))
1495  :version "23.1")
1496
1497(defcustom bibtex-expand-strings nil
1498  "If non-nil, expand strings when extracting the content of a BibTeX field."
1499  :group 'bibtex
1500  :type 'boolean)
1501
1502(defcustom bibtex-search-buffer "*BibTeX Search*"
1503  "Buffer for BibTeX search results."
1504  :group 'bibtex
1505  :version "24.1"
1506  :type 'string)
1507
1508;; `bibtex-font-lock-keywords' is a user option, too.  But since the
1509;; patterns used to define this variable are defined in a later
1510;; section of this file, it is defined later.
1511
1512
1513;; Syntax Table and Keybindings
1514(defvar bibtex-mode-syntax-table
1515  (let ((st (make-syntax-table)))
1516    (modify-syntax-entry ?\" "\"" st)
1517    (modify-syntax-entry ?$ "$$  " st)
1518    (modify-syntax-entry ?% "<   " st)
1519    (modify-syntax-entry ?' "w   " st)	;FIXME: Not allowed in @string keys.
1520    (modify-syntax-entry ?@ "w   " st)
1521    (modify-syntax-entry ?\\ "\\" st)
1522    (modify-syntax-entry ?\f ">   " st)
1523    (modify-syntax-entry ?\n ">   " st)
1524    ;; Keys cannot have = in them (wrong font-lock of @string{foo=bar}).
1525    (modify-syntax-entry ?= "." st)
1526    (modify-syntax-entry ?~ " " st)
1527    st)
1528  "Syntax table used in BibTeX mode buffers.")
1529
1530(defvar bibtex-mode-map
1531  (let ((km (make-sparse-keymap)))
1532    ;; The Key `C-c&' is reserved for reftex.el
1533    (define-key km "\t" 'bibtex-find-text)
1534    (define-key km "\n" 'bibtex-next-field)
1535    (define-key km [remap forward-paragraph] 'bibtex-next-entry)
1536    (define-key km [remap backward-paragraph] 'bibtex-previous-entry)
1537    (define-key km "\M-\t" 'completion-at-point)
1538    (define-key km "\C-c\"" 'bibtex-remove-delimiters)
1539    (define-key km "\C-c{" 'bibtex-remove-delimiters)
1540    (define-key km "\C-c}" 'bibtex-remove-delimiters)
1541    (define-key km "\C-c\C-c" 'bibtex-clean-entry)
1542    (define-key km "\C-c\C-q" 'bibtex-fill-entry)
1543    (define-key km "\C-c\C-s" 'bibtex-search-entry)
1544    (define-key km "\C-c\C-x" 'bibtex-search-crossref)
1545    (define-key km "\C-c\C-t" 'bibtex-copy-summary-as-kill)
1546    (define-key km "\C-c?" 'bibtex-print-help-message)
1547    (define-key km "\C-c\C-p" 'bibtex-pop-previous)
1548    (define-key km "\C-c\C-n" 'bibtex-pop-next)
1549    (define-key km "\C-c\C-k" 'bibtex-kill-field)
1550    (define-key km "\C-c\M-k" 'bibtex-copy-field-as-kill)
1551    (define-key km "\C-c\C-w" 'bibtex-kill-entry)
1552    (define-key km "\C-c\M-w" 'bibtex-copy-entry-as-kill)
1553    (define-key km "\C-c\C-y" 'bibtex-yank)
1554    (define-key km "\C-c\M-y" 'bibtex-yank-pop)
1555    (define-key km "\C-c\C-d" 'bibtex-empty-field)
1556    (define-key km "\C-c\C-f" 'bibtex-make-field)
1557    (define-key km "\C-c\C-u" 'bibtex-entry-update)
1558    (define-key km "\C-c$" 'bibtex-ispell-abstract)
1559    (define-key km "\M-\C-a" 'bibtex-beginning-of-entry)
1560    (define-key km "\M-\C-e" 'bibtex-end-of-entry)
1561    (define-key km "\C-\M-l" 'bibtex-reposition-window)
1562    (define-key km "\C-\M-h" 'bibtex-mark-entry)
1563    (define-key km "\C-c\C-b" 'bibtex-entry)
1564    (define-key km "\C-c\C-rn" 'bibtex-narrow-to-entry)
1565    (define-key km "\C-c\C-rw" 'widen)
1566    (define-key km "\C-c\C-l" 'bibtex-url)
1567    (define-key km "\C-c\C-a" 'bibtex-search-entries)
1568    (define-key km "\C-c\C-o" 'bibtex-remove-OPT-or-ALT)
1569    (define-key km "\C-c\C-e\C-i" 'bibtex-InProceedings)
1570    (define-key km "\C-c\C-ei" 'bibtex-InCollection)
1571    (define-key km "\C-c\C-eI" 'bibtex-InBook)
1572    (define-key km "\C-c\C-e\C-a" 'bibtex-Article)
1573    (define-key km "\C-c\C-e\C-b" 'bibtex-InBook)
1574    (define-key km "\C-c\C-eb" 'bibtex-Book)
1575    (define-key km "\C-c\C-eB" 'bibtex-Booklet)
1576    (define-key km "\C-c\C-e\C-c" 'bibtex-InCollection)
1577    (define-key km "\C-c\C-e\C-m" 'bibtex-Manual)
1578    (define-key km "\C-c\C-em" 'bibtex-MastersThesis)
1579    (define-key km "\C-c\C-eM" 'bibtex-Misc)
1580    (define-key km "\C-c\C-e\C-p" 'bibtex-InProceedings)
1581    (define-key km "\C-c\C-ep" 'bibtex-Proceedings)
1582    (define-key km "\C-c\C-eP" 'bibtex-PhdThesis)
1583    (define-key km "\C-c\C-e\M-p" 'bibtex-Preamble)
1584    (define-key km "\C-c\C-e\C-s" 'bibtex-String)
1585    (define-key km "\C-c\C-e\C-t" 'bibtex-TechReport)
1586    (define-key km "\C-c\C-e\C-u" 'bibtex-Unpublished)
1587    km)
1588  "Keymap used in BibTeX mode.")
1589
1590(easy-menu-define bibtex-edit-menu bibtex-mode-map
1591  "BibTeX-Edit Menu in BibTeX mode."
1592  '("BibTeX-Edit"
1593    ("Moving inside an Entry"
1594     ["End of Field" bibtex-find-text t]
1595     ["Next Field" bibtex-next-field t]
1596     ["Next entry" bibtex-next-entry t]
1597     ["Previous entry" bibtex-previous-entry t]
1598     ["Beginning of Entry" bibtex-beginning-of-entry t]
1599     ["End of Entry" bibtex-end-of-entry t]
1600    "--"
1601     ["Make Entry Visible" bibtex-reposition-window t])
1602    ("Moving in BibTeX Buffers"
1603     ["Search Entry" bibtex-search-entry t]
1604     ["Search Crossref Entry" bibtex-search-crossref t])
1605    "--"
1606    ("Operating on Current Field"
1607     ["Fill Field" fill-paragraph t]
1608     ["Remove Delimiters" bibtex-remove-delimiters t]
1609     ["Remove OPT or ALT Prefix" bibtex-remove-OPT-or-ALT t]
1610     ["Clear Field" bibtex-empty-field t]
1611     "--"
1612     ["Kill Field" bibtex-kill-field t]
1613     ["Copy Field to Kill Ring" bibtex-copy-field-as-kill t]
1614     ["Paste Most Recently Killed Field" bibtex-yank t]
1615     ["Paste Previously Killed Field" bibtex-yank-pop t]
1616     "--"
1617     ["Make New Field" bibtex-make-field t]
1618     "--"
1619     ["Snatch from Similar Following Field" bibtex-pop-next t]
1620     ["Snatch from Similar Preceding Field" bibtex-pop-previous t]
1621     "--"
1622     ["String or Key Complete" bibtex-complete t]
1623     "--"
1624     ["Help about Current Field" bibtex-print-help-message t])
1625    ("Operating on Current Entry"
1626     ["Fill Entry" bibtex-fill-entry t]
1627     ["Clean Entry" bibtex-clean-entry t]
1628     ["Update Entry" bibtex-entry-update t]
1629     "--"
1630     ["Kill Entry" bibtex-kill-entry t]
1631     ["Copy Entry to Kill Ring" bibtex-copy-entry-as-kill t]
1632     ["Paste Most Recently Killed Entry" bibtex-yank t]
1633     ["Paste Previously Killed Entry" bibtex-yank-pop t]
1634     "--"
1635     ["Copy Summary to Kill Ring" bibtex-copy-summary-as-kill t]
1636     ["Browse URL" bibtex-url t]
1637     "--"
1638     ["Ispell Entry" bibtex-ispell-entry t]
1639     ["Ispell Entry Abstract" bibtex-ispell-abstract t]
1640     "--"
1641     ["Narrow to Entry" bibtex-narrow-to-entry t]
1642     ["Mark Entry" bibtex-mark-entry t]
1643     "--"
1644     ["View Cite Locations (RefTeX)" reftex-view-crossref-from-bibtex
1645      (fboundp 'reftex-view-crossref-from-bibtex)])
1646    ("Operating on Buffer or Region"
1647     ["Search Entries" bibtex-search-entries t]
1648     "--"
1649     ["Validate Entries" bibtex-validate t]
1650     ["Sort Entries" bibtex-sort-buffer t]
1651     ["Reformat Entries" bibtex-reformat t]
1652     ["Count Entries" bibtex-count-entries t]
1653     "--"
1654     ["Convert Alien Buffer" bibtex-convert-alien t])
1655    ("Operating on Multiple Buffers"
1656     ["(Re)Initialize BibTeX Buffers" bibtex-initialize t]
1657     ["Validate Entries" bibtex-validate-globally t])))
1658
1659
1660;; Internal Variables
1661
1662(defvar bibtex-entry-alist nil
1663  "Alist of currently active entry types.
1664Initialized by `bibtex-set-dialect'.")
1665
1666(defvar bibtex-field-alist nil
1667  "Alist of currently active field types.
1668Initialized by `bibtex-set-dialect'.")
1669
1670(defvar bibtex-field-braces-opt nil
1671  "Optimized value of `bibtex-field-braces-alist'.
1672Created by `bibtex-field-re-init'.
1673It is an alist with elements (FIELD . REGEXP).")
1674
1675(defvar bibtex-field-strings-opt nil
1676  "Optimized value of `bibtex-field-strings-alist'.
1677Created by `bibtex-field-re-init'.
1678It is an alist with elements (FIELD RULE1 RULE2 ...),
1679where each RULE is (REGEXP . TO-STR).")
1680
1681(defvar bibtex-pop-previous-search-point nil
1682  "Next point where `bibtex-pop-previous' starts looking for a similar entry.")
1683
1684(defvar bibtex-pop-next-search-point nil
1685  "Next point where `bibtex-pop-next' starts looking for a similar entry.")
1686
1687(defvar bibtex-field-kill-ring nil
1688  "Ring of least recently killed fields.
1689At most `bibtex-field-kill-ring-max' items are kept here.")
1690
1691(defvar bibtex-field-kill-ring-yank-pointer nil
1692  "The tail of `bibtex-field-kill-ring' whose car is the last item yanked.")
1693
1694(defvar bibtex-entry-kill-ring nil
1695  "Ring of least recently killed entries.
1696At most `bibtex-entry-kill-ring-max' items are kept here.")
1697
1698(defvar bibtex-entry-kill-ring-yank-pointer nil
1699  "The tail of `bibtex-entry-kill-ring' whose car is the last item yanked.")
1700
1701(defvar bibtex-last-kill-command nil
1702  "Type of the last kill command (either `field' or `entry').")
1703
1704(defvar-local bibtex-strings
1705  (lazy-completion-table bibtex-strings
1706                         (lambda ()
1707                           (bibtex-parse-strings (bibtex-string-files-init))))
1708  "Completion table for BibTeX string keys.
1709Initialized from `bibtex-predefined-strings' and `bibtex-string-files'.")
1710(put 'bibtex-strings 'risky-local-variable t)
1711
1712(defvar-local bibtex-reference-keys
1713  (lazy-completion-table bibtex-reference-keys
1714                         (lambda () (bibtex-parse-keys nil t)))
1715  "Completion table for BibTeX reference keys.
1716The CDRs of the elements are t for header keys and nil for crossref keys.")
1717(put 'bibtex-reference-keys 'risky-local-variable t)
1718
1719(defvar bibtex-buffer-last-parsed-tick nil
1720  "Value of `buffer-modified-tick' last time buffer was parsed for keys.")
1721
1722(defvar bibtex-parse-idle-timer nil
1723  "Stores if timer is already installed.")
1724
1725(defvar bibtex-progress-lastperc nil
1726  "Last reported percentage for the progress message.")
1727
1728(defvar bibtex-progress-lastmes nil
1729  "Last reported progress message.")
1730
1731(defvar bibtex-progress-interval nil
1732  "Interval for progress messages.")
1733
1734(defvar bibtex-key-history nil
1735  "History list for reading keys.")
1736
1737(defvar bibtex-entry-type-history nil
1738  "History list for reading entry types.")
1739
1740(defvar bibtex-field-history nil
1741  "History list for reading field names.")
1742
1743(defvar bibtex-reformat-previous-options nil
1744  "Last reformat options given.")
1745
1746(defvar bibtex-reformat-previous-reference-keys nil
1747  "Last reformat reference keys option given.")
1748
1749(defconst bibtex-field-name "[^\"#%'(),={} \t\n0-9][^\"#%'(),={} \t\n]*"
1750  "Regexp matching the name of a BibTeX field.")
1751
1752(defconst bibtex-name-part
1753  (concat ",[ \t\n]*\\(" bibtex-field-name "\\)")
1754  "Regexp matching the name part of a BibTeX field.")
1755
1756(defconst bibtex-reference-key "[][[:alnum:].:;?!`'/*@+|()<>&_^$-]+"
1757  "Regexp matching the reference key part of a BibTeX entry.")
1758
1759(defconst bibtex-field-const "[][[:alnum:].:;?!`'/*@+=|<>&_^$-]+"
1760  "Regexp matching a BibTeX field constant.")
1761
1762(defvar bibtex-entry-type nil
1763  "Regexp matching the type of a BibTeX entry.
1764Initialized by `bibtex-set-dialect'.")
1765
1766(defvar bibtex-entry-head nil
1767  "Regexp matching the header line of a BibTeX entry (including key).
1768Initialized by `bibtex-set-dialect'.")
1769
1770(defvar bibtex-entry-maybe-empty-head nil
1771  "Regexp matching the header line of a BibTeX entry (possibly without key).
1772Initialized by `bibtex-set-dialect'.")
1773
1774(defconst bibtex-any-entry-maybe-empty-head
1775  (concat "^[ \t]*\\(@[ \t]*" bibtex-field-name "\\)[ \t]*[({][ \t\n]*\\("
1776          bibtex-reference-key "\\)?")
1777  "Regexp matching the header line of any BibTeX entry (possibly without key).")
1778
1779(defvar bibtex-any-valid-entry-type nil
1780  "Regexp matching any valid BibTeX entry (including String and Preamble).
1781Initialized by `bibtex-set-dialect'.")
1782
1783(defconst bibtex-type-in-head 1
1784  "Regexp subexpression number of the type part in `bibtex-entry-head'.")
1785
1786(defconst bibtex-key-in-head 2
1787  "Regexp subexpression number of the key part in `bibtex-entry-head'.")
1788
1789(defconst bibtex-string-type "^[ \t]*\\(@[ \t]*String\\)[ \t]*[({][ \t\n]*"
1790   "Regexp matching the name of a BibTeX String entry.")
1791
1792(defconst bibtex-string-maybe-empty-head
1793  (concat bibtex-string-type "\\(" bibtex-reference-key "\\)?")
1794  "Regexp matching the header line of a BibTeX String entry.")
1795
1796(defconst bibtex-preamble-prefix
1797  "[ \t]*\\(@[ \t]*Preamble\\)[ \t]*[({][ \t\n]*"
1798  "Regexp matching the prefix part of a BibTeX Preamble entry.")
1799
1800(defconst bibtex-font-lock-syntactic-keywords
1801  `((,(concat "^[ \t]*\\(" (substring bibtex-comment-start 0 1) "\\)"
1802              (substring bibtex-comment-start 1) "\\>")
1803     1 '(11))))
1804
1805(defvar bibtex-font-lock-keywords
1806  ;; entry type and reference key
1807  `((,bibtex-any-entry-maybe-empty-head
1808     (,bibtex-type-in-head font-lock-function-name-face)
1809     (,bibtex-key-in-head font-lock-constant-face nil t))
1810    ;; optional field names (treated as comments)
1811    (,(concat "^[ \t]*\\(OPT" bibtex-field-name "\\)[ \t]*=")
1812     1 font-lock-comment-face)
1813    ;; field names
1814    (,(concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=")
1815     1 font-lock-variable-name-face)
1816    ;; url
1817    (bibtex-font-lock-url) (bibtex-font-lock-crossref)
1818    ;; cite
1819    ,@(mapcar (lambda (matcher)
1820                `((lambda (bound) (bibtex-font-lock-cite ',matcher bound))))
1821              bibtex-cite-matcher-alist))
1822  "Default expressions to highlight in BibTeX mode.")
1823
1824(defvar bibtex-font-lock-url-regexp
1825  ;; Assume that field names begin at the beginning of a line.
1826  (concat "^[ \t]*"
1827          (regexp-opt (delete-dups (mapcar #'caar bibtex-generate-url-list)) t)
1828          "[ \t]*=[ \t]*")
1829  "Regexp for `bibtex-font-lock-url' derived from `bibtex-generate-url-list'.")
1830
1831(defvar bibtex-string-empty-key nil
1832  "If non-nil, `bibtex-parse-string' accepts empty key.")
1833
1834(defvar bibtex-sort-entry-class-alist nil
1835  "Alist mapping entry types to their sorting index.
1836Auto-generated from `bibtex-sort-entry-class'.
1837Used when `bibtex-maintain-sorted-entries' is `entry-class'.")
1838
1839
1840(defun bibtex-parse-association (parse-lhs parse-rhs)
1841  "Parse a string of the format <left-hand-side = right-hand-side>.
1842The functions PARSE-LHS and PARSE-RHS are used to parse the corresponding
1843substrings.  These functions are expected to return nil if parsing is not
1844successful.  If the returned values of both functions are non-nil,
1845return a cons pair of these values.  Do not move point."
1846  (save-match-data
1847    (save-excursion
1848      (let ((left (funcall parse-lhs))
1849            right)
1850        (if (and left
1851                 (looking-at "[ \t\n]*=[ \t\n]*")
1852                 (goto-char (match-end 0))
1853                 (setq right (funcall parse-rhs)))
1854            (cons left right))))))
1855
1856(defun bibtex-parse-field-name ()
1857  "Parse the name part of a BibTeX field.
1858If the field name is found, return a triple consisting of the position of the
1859very first character of the match, the actual starting position of the name
1860part and end position of the match.  Move point to end of field name.
1861If `bibtex-autoadd-commas' is non-nil add missing comma at end of preceding
1862BibTeX field as necessary."
1863  (cond ((looking-at bibtex-name-part)
1864         (goto-char (match-end 0))
1865         (list (match-beginning 0) (match-beginning 1) (match-end 0)))
1866        ;; Maybe add a missing comma.
1867        ((and bibtex-autoadd-commas
1868              (looking-at (concat "[ \t\n]*\\(?:" bibtex-field-name
1869                                  "\\)[ \t\n]*=")))
1870         (skip-chars-backward " \t\n")
1871         ;; It can be confusing if non-editing commands try to
1872         ;; modify the buffer.
1873         (if buffer-read-only
1874             (user-error "Comma missing at buffer position %s" (point)))
1875         (insert ",")
1876         (forward-char -1)
1877         ;; Now try again.
1878         (bibtex-parse-field-name))))
1879
1880(defconst bibtex-braced-string-syntax-table
1881  (let ((st (make-syntax-table)))
1882    (modify-syntax-entry ?\{ "(}" st)
1883    (modify-syntax-entry ?\} "){" st)
1884    (modify-syntax-entry ?\[ "." st)
1885    (modify-syntax-entry ?\] "." st)
1886    (modify-syntax-entry ?\( "." st)
1887    (modify-syntax-entry ?\) "." st)
1888    (modify-syntax-entry ?\\ "." st)
1889    (modify-syntax-entry ?\" "." st)
1890    st)
1891  "Syntax-table to parse matched braces.")
1892
1893(defconst bibtex-quoted-string-syntax-table
1894  (let ((st (make-syntax-table)))
1895    (modify-syntax-entry ?\\ "\\" st)
1896    (modify-syntax-entry ?\" "\"" st)
1897    st)
1898  "Syntax-table to parse matched quotes.")
1899
1900(defun bibtex-parse-field-string ()
1901  "Parse a BibTeX field string enclosed by braces or quotes.
1902If a syntactically correct string is found, a pair containing the start and
1903end position of the field string is returned, nil otherwise.
1904Do not move point."
1905  (let ((end-point
1906         (or (and (eq (following-char) ?\")
1907                  (save-excursion
1908                    (with-syntax-table bibtex-quoted-string-syntax-table
1909                      (forward-sexp 1))
1910                    (point)))
1911             (and (eq (following-char) ?\{)
1912                  (save-excursion
1913                    (with-syntax-table bibtex-braced-string-syntax-table
1914                      (forward-sexp 1))
1915                    (point))))))
1916    (if end-point
1917        (cons (point) end-point))))
1918
1919(defun bibtex-parse-field-text ()
1920  "Parse the text part of a BibTeX field.
1921The text part is either a string, or an empty string, or a constant followed
1922by one or more <# (string|constant)> pairs.  If a syntactically correct text
1923is found, a pair containing the start and end position of the text is
1924returned, nil otherwise.  Move point to end of field text."
1925  (let ((starting-point (point))
1926        end-point failure boundaries)
1927    (while (not (or end-point failure))
1928      (cond ((looking-at bibtex-field-const)
1929             (goto-char (match-end 0)))
1930            ((setq boundaries (bibtex-parse-field-string))
1931             (goto-char (cdr boundaries)))
1932            ((setq failure t)))
1933      (if (looking-at "[ \t\n]*#[ \t\n]*")
1934          (goto-char (match-end 0))
1935        (setq end-point (point))))
1936    (skip-chars-forward " \t\n")
1937    (if (and (not failure)
1938             end-point)
1939        (list starting-point end-point (point)))))
1940
1941(defun bibtex-parse-field ()
1942  "Parse the BibTeX field beginning at the position of point.
1943If a syntactically correct field is found, return a cons pair containing
1944the boundaries of the name and text parts of the field.  Do not move point."
1945  (bibtex-parse-association 'bibtex-parse-field-name
1946                            'bibtex-parse-field-text))
1947
1948(defsubst bibtex-start-of-field (bounds)
1949  (nth 0 (car bounds)))
1950(defsubst bibtex-start-of-name-in-field (bounds)
1951  (nth 1 (car bounds)))
1952(defsubst bibtex-end-of-name-in-field (bounds)
1953  (nth 2 (car bounds)))
1954(defsubst bibtex-start-of-text-in-field (bounds)
1955  (nth 1 bounds))
1956(defsubst bibtex-end-of-text-in-field (bounds)
1957  (nth 2 bounds))
1958(defsubst bibtex-end-of-field (bounds)
1959  (nth 3 bounds))
1960
1961(defun bibtex-search-forward-field (name &optional bound)
1962  "Search forward to find a BibTeX field of name NAME.
1963If a syntactically correct field is found, return a pair containing
1964the boundaries of the name and text parts of the field.  The search
1965is limited by optional arg BOUND.  If BOUND is t the search is limited
1966by the end of the current entry.  Do not move point."
1967  (save-match-data
1968    (save-excursion
1969      (if (eq bound t)
1970          (let ((regexp (concat bibtex-name-part "[ \t\n]*=\\|"
1971                                bibtex-any-entry-maybe-empty-head))
1972                (case-fold-search t) bounds)
1973            (catch 'done
1974              (if (looking-at "[ \t]*@") (goto-char (match-end 0)))
1975              (while (and (not bounds)
1976                          (re-search-forward regexp nil t))
1977                (if (match-beginning 2)
1978                    ;; We found a new entry
1979                    (throw 'done nil)
1980                  ;; We found a field
1981                  (goto-char (match-beginning 0))
1982                  (setq bounds (bibtex-parse-field))))
1983              ;; Step through all fields so that we cannot overshoot.
1984              (while bounds
1985                (goto-char (bibtex-start-of-name-in-field bounds))
1986                (if (looking-at name) (throw 'done bounds))
1987                (goto-char (bibtex-end-of-field bounds))
1988                (setq bounds (bibtex-parse-field)))))
1989        ;; Bounded search or bound is nil (i.e. we cannot overshoot).
1990        ;; Indeed, the search is bounded when `bibtex-search-forward-field'
1991        ;; is called many times.  So we optimize this part of this function.
1992        (let ((name-part (concat ",[ \t\n]*\\(" name "\\)[ \t\n]*=[ \t\n]*"))
1993              (case-fold-search t) left right)
1994          (while (and (not right)
1995                      (re-search-forward name-part bound t))
1996            (setq left (list (match-beginning 0) (match-beginning 1)
1997                             (match-end 1))
1998                  ;; Don't worry that the field text could be past bound.
1999                  right (bibtex-parse-field-text)))
2000          (if right (cons left right)))))))
2001
2002(defun bibtex-search-backward-field (name &optional bound)
2003  "Search backward to find a BibTeX field of name NAME.
2004If a syntactically correct field is found, return a pair containing
2005the boundaries of the name and text parts of the field.  The search
2006is limited by the optional arg BOUND.  If BOUND is t the search is
2007limited by the beginning of the current entry.  Do not move point."
2008  (save-match-data
2009    (if (eq bound t)
2010        (setq bound (save-excursion (bibtex-beginning-of-entry))))
2011    (let ((name-part (concat ",[ \t\n]*\\(" name "\\)[ \t\n]*=[ \t\n]*"))
2012          (case-fold-search t) left right)
2013      (save-excursion
2014        ;; the parsing functions are not designed for parsing backwards :-(
2015        (when (search-backward "," bound t)
2016          (or (save-excursion
2017                (when (looking-at name-part)
2018                  (setq left (list (match-beginning 0) (match-beginning 1)
2019                                   (match-end 1)))
2020                  (goto-char (match-end 0))
2021                  (setq right (bibtex-parse-field-text))))
2022              (while (and (not right)
2023                          (re-search-backward name-part bound t))
2024                (setq left (list (match-beginning 0) (match-beginning 1)
2025                                 (match-end 1)))
2026                (save-excursion
2027                  (goto-char (match-end 0))
2028                  (setq right (bibtex-parse-field-text)))))
2029          (if right (cons left right)))))))
2030
2031(defun bibtex-name-in-field (bounds &optional remove-opt-alt)
2032  "Get content of name in BibTeX field defined via BOUNDS.
2033If optional arg REMOVE-OPT-ALT is non-nil remove \"OPT\" and \"ALT\"."
2034  (let ((name (buffer-substring-no-properties
2035               (bibtex-start-of-name-in-field bounds)
2036               (bibtex-end-of-name-in-field bounds))))
2037    (if (and remove-opt-alt
2038             (string-match "\\`\\(OPT\\|ALT\\)" name)
2039             (not (and bibtex-no-opt-remove-re
2040                       (string-match bibtex-no-opt-remove-re name))))
2041        (substring name 3)
2042      name)))
2043
2044(defun bibtex-text-in-field-bounds (bounds &optional content)
2045  "Get text in BibTeX field defined via BOUNDS.
2046If optional arg CONTENT is non-nil extract content of field
2047by removing field delimiters and concatenating the resulting string.
2048If `bibtex-expand-strings' is non-nil, also expand BibTeX strings."
2049  (if content
2050      (save-excursion
2051        (goto-char (bibtex-start-of-text-in-field bounds))
2052        (let ((epoint (bibtex-end-of-text-in-field bounds))
2053              content)
2054          (while (< (point) epoint)
2055            (if (looking-at bibtex-field-const)
2056                (let ((mtch (match-string-no-properties 0)))
2057                  (push (or (if bibtex-expand-strings
2058                                (cdr (assoc-string mtch (bibtex-strings) t)))
2059                            mtch)
2060                        content)
2061                  (goto-char (match-end 0)))
2062              (let ((bounds (bibtex-parse-field-string)))
2063                (push (buffer-substring-no-properties
2064                       (1+ (car bounds)) (1- (cdr bounds)))
2065                      content)
2066                (goto-char (cdr bounds))))
2067            (re-search-forward "\\=[ \t\n]*#[ \t\n]*" nil t))
2068          (apply #'concat (nreverse content))))
2069    (buffer-substring-no-properties (bibtex-start-of-text-in-field bounds)
2070                                    (bibtex-end-of-text-in-field bounds))))
2071
2072(defun bibtex-text-in-field (field &optional follow-crossref)
2073  "Return content of field FIELD of current BibTeX entry or nil if not found.
2074FIELD may also be a list of fields that are tried in order.
2075If optional arg FOLLOW-CROSSREF is non-nil, follow crossref."
2076  (save-excursion
2077    (let ((end (if (and (not follow-crossref) (stringp field))
2078                   t ; try to minimize parsing
2079                 (bibtex-end-of-entry)))
2080          bounds)
2081      (bibtex-beginning-of-entry) ; move point
2082      (let ((field (if (stringp field) (list field) field)))
2083        (while (and field (not bounds))
2084          (setq bounds (bibtex-search-forward-field (pop field) end))))
2085      (cond (bounds (bibtex-text-in-field-bounds bounds t))
2086            ((and follow-crossref
2087                  (setq bounds (bibtex-search-forward-field
2088                                "\\(OPT\\)?crossref" end)))
2089             (let ((crossref-field (bibtex-text-in-field-bounds bounds t)))
2090               (if (bibtex-search-crossref crossref-field)
2091                   ;; Do not pass FOLLOW-CROSSREF because we want
2092                   ;; to follow crossrefs only one level of recursion.
2093                   (bibtex-text-in-field field))))))))
2094
2095(defun bibtex-parse-string-prefix ()
2096  "Parse the prefix part of a BibTeX string entry, including reference key.
2097If the string prefix is found, return a triple consisting of the position of
2098the very first character of the match, the actual starting position of the
2099reference key and the end position of the match.
2100If `bibtex-string-empty-key' is non-nil accept empty string key."
2101  (let ((case-fold-search t))
2102    (if (looking-at bibtex-string-type)
2103        (let ((start (point)))
2104          (goto-char (match-end 0))
2105          (cond ((looking-at bibtex-reference-key)
2106                 (goto-char (match-end 0))
2107                 (list start
2108                       (match-beginning 0)
2109                       (match-end 0)))
2110                ((and bibtex-string-empty-key
2111                      (looking-at "="))
2112                 (skip-chars-backward " \t\n")
2113                 (list start (point) (point))))))))
2114
2115(defun bibtex-parse-string-postfix ()
2116  "Parse the postfix part of a BibTeX string entry, including the text.
2117If the string postfix is found, return a triple consisting of the position of
2118the actual starting and ending position of the text and the very last
2119character of the string entry.  Move point past BibTeX string entry."
2120  (let* ((case-fold-search t)
2121         (bounds (bibtex-parse-field-text)))
2122    (when bounds
2123      (goto-char (nth 1 bounds))
2124      (when (looking-at "[ \t\n]*[})]")
2125        (goto-char (match-end 0))
2126        (list (car bounds)
2127              (nth 1 bounds)
2128              (match-end 0))))))
2129
2130(defun bibtex-parse-string (&optional empty-key)
2131  "Parse a BibTeX string entry beginning at the position of point.
2132If a syntactically correct entry is found, return a cons pair containing
2133the boundaries of the reference key and text parts of the entry.
2134If EMPTY-KEY is non-nil, key may be empty.  Do not move point."
2135  (let ((bibtex-string-empty-key empty-key))
2136    (bibtex-parse-association 'bibtex-parse-string-prefix
2137                              'bibtex-parse-string-postfix)))
2138
2139(defun bibtex-search-forward-string (&optional empty-key)
2140  "Search forward to find a BibTeX string entry.
2141If a syntactically correct entry is found, a pair containing the boundaries of
2142the reference key and text parts of the string is returned.
2143If EMPTY-KEY is non-nil, key may be empty.  Do not move point."
2144  (save-excursion
2145    (save-match-data
2146      (let ((case-fold-search t) bounds)
2147        (while (and (not bounds)
2148                    (search-forward-regexp bibtex-string-type nil t))
2149          (save-excursion (goto-char (match-beginning 0))
2150                          (setq bounds (bibtex-parse-string empty-key))))
2151        bounds))))
2152
2153(defun bibtex-reference-key-in-string (bounds)
2154  "Return the key part of a BibTeX string defined via BOUNDS."
2155  (buffer-substring-no-properties (nth 1 (car bounds))
2156                                  (nth 2 (car bounds))))
2157
2158(defun bibtex-text-in-string (bounds &optional content)
2159  "Get text in BibTeX string field defined via BOUNDS.
2160If optional arg CONTENT is non-nil extract content
2161by removing field delimiters and concatenating the resulting string.
2162If `bibtex-expand-strings' is non-nil, also expand BibTeX strings."
2163  (bibtex-text-in-field-bounds bounds content))
2164
2165(defsubst bibtex-start-of-text-in-string (bounds)
2166  (nth 0 (cdr bounds)))
2167(defsubst bibtex-end-of-text-in-string (bounds)
2168  (nth 1 (cdr bounds)))
2169(defsubst bibtex-end-of-string (bounds)
2170  (nth 2 (cdr bounds)))
2171
2172(defsubst bibtex-type-in-head ()
2173  "Extract BibTeX type in head."
2174  ;;                              ignore @
2175  (buffer-substring-no-properties (1+ (match-beginning bibtex-type-in-head))
2176                                  (match-end bibtex-type-in-head)))
2177
2178(defsubst bibtex-key-in-head (&optional empty)
2179  "Extract BibTeX key in head.  Return optional arg EMPTY if key is empty."
2180  (or (match-string-no-properties bibtex-key-in-head)
2181      empty))
2182
2183(defun bibtex-parse-preamble ()
2184  "Parse BibTeX preamble.
2185Point must be at beginning of preamble.  Do not move point."
2186  (let ((case-fold-search t))
2187    (when (looking-at bibtex-preamble-prefix)
2188      (let ((start (match-beginning 0)) (pref-start (match-beginning 1))
2189            (bounds (save-excursion (goto-char (match-end 0))
2190                                    (bibtex-parse-string-postfix))))
2191        (if bounds (cons (list start pref-start) bounds))))))
2192
2193;; Helper Functions
2194
2195(defsubst bibtex-string= (str1 str2)
2196  "Return t if STR1 and STR2 are equal, ignoring case."
2197  (eq t (compare-strings str1 0 nil str2 0 nil t)))
2198
2199(defun bibtex-delete-whitespace ()
2200  "Delete all whitespace starting at point."
2201  (if (looking-at "[ \t\n]+")
2202      (delete-region (point) (match-end 0))))
2203
2204(defun bibtex-current-line ()
2205  "Compute line number of point regardless whether the buffer is narrowed."
2206  (+ (count-lines 1 (point))
2207     (if (bolp) 1 0)))
2208
2209(defun bibtex-valid-entry (&optional empty-key)
2210  "Parse a valid BibTeX entry (maybe without key if EMPTY-KEY is t).
2211A valid entry is a syntactical correct one with type contained in
2212`bibtex-BibTeX-entry-alist'.  Ignore @String and @Preamble entries.
2213Return a cons pair with buffer positions of beginning and end of entry
2214if a valid entry is found, nil otherwise.  Do not move point.
2215After a call to this function `match-data' corresponds to the header
2216of the entry, see regexp `bibtex-entry-head'."
2217  (let ((case-fold-search t) end)
2218    (if (looking-at (if empty-key bibtex-entry-maybe-empty-head
2219                    bibtex-entry-head))
2220        (save-excursion
2221          (save-match-data
2222            (goto-char (match-end 0))
2223            (let ((entry-closer
2224                   (if (save-excursion
2225                         (goto-char (match-end bibtex-type-in-head))
2226                         (looking-at "[ \t]*("))
2227                       ",?[ \t\n]*)" ; entry opened with `('
2228                     ",?[ \t\n]*}")) ; entry opened with `{'
2229                  bounds)
2230              (skip-chars-forward " \t\n")
2231              ;; loop over all BibTeX fields
2232              (while (setq bounds (bibtex-parse-field))
2233                (goto-char (bibtex-end-of-field bounds)))
2234              ;; This matches the infix* part.
2235              (if (looking-at entry-closer) (setq end (match-end 0)))))
2236          (if end (cons (match-beginning 0) end))))))
2237
2238(defun bibtex-skip-to-valid-entry (&optional backward)
2239  "Move point to beginning of the next valid BibTeX entry.
2240Do not move if we are already at beginning of a valid BibTeX entry.
2241With optional argument BACKWARD non-nil, move backward to
2242beginning of previous valid one.  A valid entry is a syntactical correct one
2243with type contained in `bibtex-BibTeX-entry-alist' or, if
2244`bibtex-sort-ignore-string-entries' is nil, a syntactical correct string
2245entry.  Return buffer position of beginning and end of entry if a valid
2246entry is found, nil otherwise."
2247  (interactive "P")
2248  (let ((case-fold-search t)
2249        found bounds)
2250    (beginning-of-line)
2251    ;; Loop till we look at a valid entry.
2252    (while (not (or found (if backward (bobp) (eobp))))
2253      (cond ((setq found (or (bibtex-valid-entry)
2254                             (and (not bibtex-sort-ignore-string-entries)
2255                                  (setq bounds (bibtex-parse-string))
2256                                  (cons (bibtex-start-of-field bounds)
2257                                        (bibtex-end-of-string bounds))))))
2258            (backward (re-search-backward "^[ \t]*@" nil 'move))
2259            (t (if (re-search-forward "\n\\([ \t]*@\\)" nil 'move)
2260                   (goto-char (match-beginning 1))))))
2261    found))
2262
2263(defun bibtex-map-entries (fun)
2264  "Call FUN for each BibTeX entry in buffer (possibly narrowed).
2265FUN is called with three arguments, the key of the entry and the buffer
2266positions of beginning and end of entry.  Also, point is at beginning of
2267entry and `match-data' corresponds to the header of the entry,
2268see regexp `bibtex-entry-head'.  If `bibtex-sort-ignore-string-entries'
2269is non-nil, FUN is not called for @String entries."
2270  (let ((case-fold-search t)
2271        (end-marker (make-marker))
2272        found)
2273    ;; Use marker to keep track of the buffer position of the end of
2274    ;; a BibTeX entry as this position may change during reformatting.
2275    (set-marker-insertion-type end-marker t)
2276    (save-excursion
2277      (goto-char (point-min))
2278      (while (setq found (bibtex-skip-to-valid-entry))
2279        (set-marker end-marker (cdr found))
2280        (looking-at bibtex-any-entry-maybe-empty-head)
2281        (funcall fun (bibtex-key-in-head "") (car found) end-marker)
2282        (goto-char end-marker)))))
2283
2284(defun bibtex-progress-message (&optional flag interval)
2285  "Echo a message about progress of current buffer.
2286If FLAG is a string, the message is initialized (in this case a
2287value for INTERVAL may be given as well (if not this is set to 5)).
2288If FLAG is `done', the message is deinitialized.
2289If FLAG is nil, a message is echoed if point was incremented at least
2290`bibtex-progress-interval' percent since last message was echoed."
2291  (cond ((stringp flag)
2292         (setq bibtex-progress-lastmes flag
2293               bibtex-progress-interval (or interval 5)
2294               bibtex-progress-lastperc 0))
2295        ((eq flag 'done)
2296         (message  "%s (done)" bibtex-progress-lastmes)
2297         (setq bibtex-progress-lastmes nil))
2298        (t
2299         (let* ((size (- (point-max) (point-min)))
2300                (perc (if (= size 0)
2301                          100
2302                        (floor (* 100.0 (- (point) (point-min))) size))))
2303           (when (>= perc (+ bibtex-progress-lastperc
2304                             bibtex-progress-interval))
2305             (setq bibtex-progress-lastperc perc)
2306             (message "%s (%d%%)" bibtex-progress-lastmes perc))))))
2307
2308(defun bibtex-field-left-delimiter ()
2309  "Return a string dependent on `bibtex-field-delimiters'."
2310  (if (eq bibtex-field-delimiters 'braces)
2311      "{"
2312    "\""))
2313
2314(defun bibtex-field-right-delimiter ()
2315  "Return a string dependent on `bibtex-field-delimiters'."
2316  (if (eq bibtex-field-delimiters 'braces)
2317      "}"
2318    "\""))
2319
2320(defun bibtex-entry-left-delimiter ()
2321  "Return a string dependent on `bibtex-entry-delimiters'."
2322  (if (eq bibtex-entry-delimiters 'braces)
2323      "{"
2324    "("))
2325
2326(defun bibtex-entry-right-delimiter ()
2327  "Return a string dependent on `bibtex-entry-delimiters'."
2328  (if (eq bibtex-entry-delimiters 'braces)
2329      "}"
2330    ")"))
2331
2332(defun bibtex-flash-head (prompt)
2333  "Flash at BibTeX entry head before point, if it exists."
2334  (let ((case-fold-search t)
2335        (pnt (point)))
2336    (save-excursion
2337      (bibtex-beginning-of-entry)
2338      (when (and (looking-at bibtex-any-entry-maybe-empty-head)
2339                 (< (point) pnt))
2340        (goto-char (match-beginning bibtex-type-in-head))
2341        (if (and (< 0 blink-matching-delay)
2342                 (pos-visible-in-window-p (point)))
2343            (sit-for blink-matching-delay)
2344          (message "%s%s" prompt (buffer-substring-no-properties
2345                                  (point) (match-end bibtex-key-in-head))))))))
2346
2347(defun bibtex-make-optional-field (field)
2348  "Make an optional field named FIELD in current BibTeX entry."
2349  (if (consp field)
2350      (bibtex-make-field (cons (concat "OPT" (car field)) (cdr field)))
2351    (bibtex-make-field (concat "OPT" field))))
2352
2353(defun bibtex-move-outside-of-entry ()
2354  "Make sure point is outside of a BibTeX entry."
2355  (let ((orig-point (point)))
2356    (bibtex-end-of-entry)
2357    (when (< (point) orig-point)
2358      ;; We moved backward, so we weren't inside an entry to begin with.
2359      ;; Leave point at the beginning of a line, and preferably
2360      ;; at the beginning of a paragraph.
2361      (goto-char orig-point)
2362      (beginning-of-line 1)
2363      (unless (= ?\n (char-before (1- (point))))
2364        (re-search-forward "^[ \t]*[@\n]" nil 'move)
2365        (backward-char 1)))
2366    (skip-chars-forward " \t\n")))
2367
2368(defun bibtex-beginning-of-first-entry ()
2369  "Go to beginning of line of first BibTeX entry in buffer.
2370If `bibtex-sort-ignore-string-entries' is non-nil, @String entries
2371are ignored.  Return point."
2372  (goto-char (point-min))
2373  (bibtex-skip-to-valid-entry)
2374  (point))
2375
2376(defun bibtex-enclosing-field (&optional comma noerr)
2377  "Search for BibTeX field enclosing point.
2378For `bibtex-mode''s internal algorithms, a field begins at the comma
2379following the preceding field.  Usually, this is not what the user expects.
2380Thus if COMMA is non-nil, the \"current field\" includes the terminating comma
2381as well as the entry delimiter if it appears on the same line.
2382Unless NOERR is non-nil, signal an error if no enclosing field is found.
2383On success return bounds, nil otherwise.  Do not move point."
2384  (save-excursion
2385    (when comma
2386      (end-of-line)
2387      (skip-chars-backward " \t")
2388      ;; Ignore entry delimiter and comma at end of line.
2389      (if (memq (preceding-char) '(?} ?\))) (forward-char -1))
2390      (if (= (preceding-char) ?,) (forward-char -1)))
2391
2392    (let ((bounds (bibtex-search-backward-field bibtex-field-name t)))
2393      (cond ((and bounds
2394                  (<= (bibtex-start-of-field bounds) (point))
2395                  (>= (bibtex-end-of-field bounds) (point)))
2396             bounds)
2397            ((not noerr)
2398             (user-error "Can't find enclosing BibTeX field"))))))
2399
2400(defun bibtex-beginning-first-field (&optional beg)
2401  "Move point to beginning of first field.
2402Optional arg BEG is beginning of entry."
2403  (if beg (goto-char beg) (bibtex-beginning-of-entry))
2404  (looking-at bibtex-any-entry-maybe-empty-head)
2405  (goto-char (match-end 0)))
2406
2407(defun bibtex-insert-kill (n &optional comma)
2408  "Reinsert the Nth stretch of killed BibTeX text (field or entry).
2409Optional arg COMMA is as in `bibtex-enclosing-field'."
2410  (unless bibtex-last-kill-command (user-error "BibTeX kill ring is empty"))
2411  (let ((fun (lambda (kryp kr) ; adapted from `current-kill'
2412               (car (set kryp (nthcdr (mod (- n (length (symbol-value kryp)))
2413                                           (length kr))
2414                                      kr))))))
2415    ;; We put the mark at the beginning of the inserted field or entry
2416    ;; and point at its end - a behavior similar to what `yank' does.
2417    ;; The mark is then used by `bibtex-yank-pop', which needs to know
2418    ;; what we have inserted.
2419    (if (eq bibtex-last-kill-command 'field)
2420        (progn
2421          ;; insert past the current field
2422          (goto-char (bibtex-end-of-field (bibtex-enclosing-field comma)))
2423          (push-mark)
2424          (bibtex-make-field (funcall fun 'bibtex-field-kill-ring-yank-pointer
2425                                      bibtex-field-kill-ring)
2426                             t nil t))
2427      ;; insert past the current entry
2428      (bibtex-skip-to-valid-entry)
2429      (push-mark)
2430      (insert (funcall fun 'bibtex-entry-kill-ring-yank-pointer
2431                       bibtex-entry-kill-ring))
2432      ;; If we copied an entry from a buffer containing only this one entry,
2433      ;; it can be missing the second "\n".
2434      (unless (looking-back "\n\n" (- (point) 2)) (insert "\n"))
2435      (unless (functionp bibtex-reference-keys)
2436        ;; update `bibtex-reference-keys'
2437        (save-excursion
2438          (goto-char (mark t))
2439          (looking-at bibtex-any-entry-maybe-empty-head)
2440          (let ((key (bibtex-key-in-head)))
2441            (if key (push (cons key t) bibtex-reference-keys))))))))
2442
2443(defsubst bibtex-vec-push (vec idx newelt)
2444  "Add NEWELT to the list stored in VEC at index IDX."
2445  (aset vec idx (cons newelt (aref vec idx))))
2446
2447(defun bibtex-format-entry ()
2448  "Helper function for `bibtex-clean-entry'.
2449Formats current entry according to variable `bibtex-entry-format'."
2450  ;; initialize `bibtex-field-braces-opt' if necessary
2451  (if (and bibtex-field-braces-alist (not bibtex-field-braces-opt))
2452      (setq bibtex-field-braces-opt
2453            (bibtex-field-re-init bibtex-field-braces-alist 'braces)))
2454  ;; initialize `bibtex-field-strings-opt' if necessary
2455  (if (and bibtex-field-strings-alist (not bibtex-field-strings-opt))
2456      (setq bibtex-field-strings-opt
2457            (bibtex-field-re-init bibtex-field-strings-alist 'strings)))
2458
2459  (let ((case-fold-search t)
2460        (format (if (eq bibtex-entry-format t)
2461                    '(realign opts-or-alts required-fields numerical-fields
2462                              page-dashes whitespace inherit-booktitle
2463                              last-comma delimiters unify-case braces
2464                              strings sort-fields)
2465                  bibtex-entry-format))
2466        (left-delim-re (regexp-quote (bibtex-field-left-delimiter)))
2467        bounds crossref-key req-field-list opt-field-list
2468        default-field-list field-list
2469        num-alt alt-fields idx error-field-name)
2470    (unwind-protect
2471        ;; formatting (undone if error occurs)
2472        (atomic-change-group
2473          (save-excursion
2474            (save-restriction
2475              (bibtex-narrow-to-entry)
2476
2477              ;; There are more elegant high-level functions for several tasks
2478              ;; done by `bibtex-format-entry'.  However, they contain some
2479              ;; redundancy compared with what we need to do anyway.
2480              ;; So for speed-up we avoid using them.
2481              ;; (`bibtex-format-entry' is called often by `bibtex-reformat'.)
2482
2483              ;; identify entry type
2484              (goto-char (point-min))
2485              (or (re-search-forward bibtex-entry-type nil t)
2486                  (user-error "Not inside a BibTeX entry"))
2487              (let* ((beg-type (1+ (match-beginning 0)))
2488                     (end-type (match-end 0))
2489                     (entry-list (assoc-string (buffer-substring-no-properties
2490                                                beg-type end-type)
2491                                               bibtex-entry-alist t)))
2492
2493                ;; unify case of entry type
2494                (when (memq 'unify-case format)
2495                  (delete-region beg-type end-type)
2496                  (insert (funcall bibtex-unify-case-function (car entry-list))))
2497
2498                ;; update left entry delimiter
2499                (when (memq 'delimiters format)
2500                  (goto-char end-type)
2501                  (skip-chars-forward " \t\n")
2502                  (delete-char 1)
2503                  (insert (bibtex-entry-left-delimiter)))
2504
2505                ;; Do we have a crossref key?
2506                (goto-char (point-min))
2507                (if (setq bounds (bibtex-search-forward-field
2508                                  "\\(OPT\\)?crossref"))
2509                    (let ((text (bibtex-text-in-field-bounds bounds t)))
2510                      (unless (equal "" text)
2511                        (setq crossref-key text))))
2512
2513                ;; list of required fields appropriate for an entry with
2514                ;; or without crossref key.
2515                (setq req-field-list (append (nth 2 entry-list)
2516                                             (unless crossref-key
2517                                               (nth 3 entry-list)))
2518                      opt-field-list (append (if crossref-key
2519                                               (nth 3 entry-list))
2520                                             (nth 4 entry-list)
2521                                             bibtex-user-optional-fields)
2522                      ;; default list of fields that may appear in this entry
2523                      default-field-list (append req-field-list opt-field-list)
2524                      ;; number of ALT fields we may find
2525                      num-alt (let ((n 0))
2526                                (mapc (lambda (x)
2527                                        (if (nth 3 x)
2528                                            (setq n (max n (abs (nth 3 x))))))
2529                                      default-field-list)
2530                                (1+ n))
2531                      ;; ALT fields of respective groups
2532                      alt-fields (make-vector num-alt nil))
2533
2534                (when (memq 'sort-fields format)
2535                  (goto-char (point-min))
2536                  (let ((beg-fields (save-excursion (bibtex-beginning-first-field)))
2537                        (fields-alist (bibtex-parse-entry
2538                                       nil (not (memq 'opts-or-alts format))))
2539                        bibtex-help-message elt)
2540                    (delete-region beg-fields (point))
2541                    (dolist (field default-field-list)
2542                      (when (setq elt (assoc-string (car field) fields-alist t))
2543                        (setq fields-alist (delete elt fields-alist))
2544                        (bibtex-make-field (list (car elt) nil (cdr elt)) nil nil t)))
2545                    (dolist (field fields-alist)
2546                      (unless (member (car field) '("=key=" "=type="))
2547                        (bibtex-make-field (list (car field) nil (cdr field)) nil nil t))))))
2548
2549              ;; process all fields
2550              (bibtex-beginning-first-field (point-min))
2551              (while (setq bounds (bibtex-parse-field))
2552                (let* ((beg-field (copy-marker (bibtex-start-of-field bounds)))
2553                       (end-field (copy-marker (bibtex-end-of-field bounds) t))
2554                       (beg-name  (copy-marker (bibtex-start-of-name-in-field bounds)))
2555                       (end-name  (copy-marker (bibtex-end-of-name-in-field bounds)))
2556                       (beg-text  (copy-marker (bibtex-start-of-text-in-field bounds)))
2557                       (end-text  (copy-marker (bibtex-end-of-text-in-field bounds) t))
2558                       (empty-field (equal "" (bibtex-text-in-field-bounds bounds t)))
2559                       (field-name (buffer-substring-no-properties beg-name end-name))
2560                       (opt-alt   (and (memq 'opts-or-alts format)
2561                                       (string-match "\\`\\(OPT\\|ALT\\)" field-name)
2562                                       (not (and bibtex-no-opt-remove-re
2563                                                 (string-match bibtex-no-opt-remove-re
2564                                                               field-name)))))
2565                       deleted)
2566                  (if opt-alt (setq field-name (substring field-name 3)))
2567
2568                  ;; keep track of alternatives
2569                  (if (and (not empty-field)
2570                           (setq idx (nth 3 (assoc-string field-name default-field-list t))))
2571                      (bibtex-vec-push alt-fields (abs idx) field-name))
2572
2573                  (if (memq 'opts-or-alts format)
2574                      ;; delete empty optional and alternative fields
2575                      ;; (but keep empty required fields)
2576                      (cond ((and empty-field
2577                                  (or opt-alt
2578                                      (let ((field (assoc-string
2579                                                    field-name req-field-list t)))
2580                                        (or (not field) ; OPT field
2581                                            (nth 3 field))))) ; ALT field
2582                             (delete-region beg-field end-field)
2583                             (setq deleted t))
2584                            ;; otherwise nonempty field: delete "OPT" or "ALT"
2585                            (opt-alt
2586                             (goto-char beg-name)
2587                             (delete-char 3))))
2588
2589                  (unless deleted
2590                    (push field-name field-list)
2591
2592                    ;; Remove whitespace at beginning and end of field.
2593                    ;; We do not look at individual parts of the field
2594                    ;; as {foo } # bar # { baz} is a fine field.
2595                    (when (memq 'whitespace format)
2596                      (goto-char beg-text)
2597                      (if (looking-at "\\([{\"]\\)[ \t\n]+")
2598                          (replace-match "\\1"))
2599                      (goto-char end-text)
2600                      (if (looking-back "[ \t\n]+\\([}\"]\\)" beg-text t)
2601                          (replace-match "\\1")))
2602
2603                    ;; remove delimiters from purely numerical fields
2604                    (when (and (memq 'numerical-fields format)
2605                               (progn (goto-char beg-text)
2606                                      (looking-at "\"[0-9]+\"\\|{[0-9]+}")))
2607                      (goto-char end-text)
2608                      (delete-char -1)
2609                      (goto-char beg-text)
2610                      (delete-char 1))
2611
2612                    ;; update delimiters
2613                    (when (memq 'delimiters format)
2614                      (goto-char beg-text)
2615                      ;; simplified from `bibtex-parse-field-text', as we
2616                      ;; already checked that the field format is correct
2617                      (while (< (point) end-text)
2618                        (if (looking-at bibtex-field-const)
2619                            (goto-char (match-end 0))
2620                          (let ((boundaries (bibtex-parse-field-string)))
2621                            (if (looking-at left-delim-re)
2622                                (goto-char (cdr boundaries))
2623                              (delete-char 1)
2624                              (insert (bibtex-field-left-delimiter))
2625                              (goto-char (1- (cdr boundaries)))
2626                              (delete-char 1)
2627                              (insert (bibtex-field-right-delimiter)))))
2628                        (if (looking-at "[ \t\n]*#[ \t\n]*")
2629                            (goto-char (match-end 0)))))
2630
2631                    ;; update page dashes
2632                    (if (and (memq 'page-dashes format)
2633                             (bibtex-string= field-name "pages")
2634                             (progn (goto-char beg-text)
2635                                    (looking-at
2636                                     "\\([\"{][0-9]+\\)[ \t\n]*--?[ \t\n]*\\([0-9]+[\"}]\\)")))
2637                        (replace-match "\\1-\\2"))
2638
2639                    ;; enclose field text by braces according to
2640                    ;; `bibtex-field-braces-alist'.
2641                    (let (case-fold-search temp) ; Case-sensitive search
2642                      (when (and (memq 'braces format)
2643                                 (setq temp (cdr (assoc-string field-name
2644                                                               bibtex-field-braces-opt t))))
2645                        (goto-char beg-text)
2646                        (while (re-search-forward temp end-text t)
2647                          (let ((beg (match-beginning 0))
2648                                (bounds (bibtex-find-text-internal nil t)))
2649                            (unless (or (nth 4 bounds) ; string constant
2650                                        ;; match already surrounded by braces
2651                                        ;; (braces are inside field delimiters)
2652                                        (and (< (point) (1- (nth 2 bounds)))
2653                                             (< (1+ (nth 1 bounds)) beg)
2654                                             (looking-at "}")
2655                                             (save-excursion (goto-char (1- beg))
2656                                                             (looking-at "{"))))
2657                              (insert "}")
2658                              (goto-char beg)
2659                              (insert "{")))))
2660
2661                      ;; replace field text by BibTeX string constants
2662                      ;; according to `bibtex-field-strings-alist'.
2663                      (when (and (memq 'strings format)
2664                                 (setq temp (cdr (assoc-string field-name
2665                                                               bibtex-field-strings-opt t))))
2666                        (goto-char beg-text)
2667                        (dolist (re temp)
2668                          (while (re-search-forward (car re) end-text t)
2669                            (let ((bounds (save-match-data
2670                                            (bibtex-find-text-internal nil t))))
2671                              (unless (nth 4 bounds)
2672                                ;; if match not at right subfield boundary...
2673                                (if (< (match-end 0) (1- (nth 2 bounds)))
2674                                    (insert " # " (bibtex-field-left-delimiter))
2675                                  (delete-char 1))
2676                                (replace-match (cdr re))
2677                                (goto-char (match-beginning 0))
2678                                ;; if match not at left subfield boundary...
2679                                (if (< (1+ (nth 1 bounds)) (match-beginning 0))
2680                                    (insert (bibtex-field-right-delimiter) " # ")
2681                                  (delete-char -1))))))))
2682
2683                    ;; use book title of crossref'd entry
2684                    (if (and (memq 'inherit-booktitle format)
2685                             empty-field
2686                             (bibtex-string= field-name "booktitle")
2687                             crossref-key)
2688                        (let ((title (save-excursion
2689                                       (save-restriction
2690                                         (widen)
2691                                         (if (bibtex-search-entry crossref-key t)
2692                                             (bibtex-text-in-field "title"))))))
2693                          (when title
2694                            (setq empty-field nil)
2695                            (goto-char (1+ beg-text))
2696                            (insert title))))
2697
2698                    ;; if empty field is a required field, complain
2699                    (when (and empty-field
2700                               (memq 'required-fields format)
2701                               (assoc-string field-name req-field-list t))
2702                      (setq error-field-name field-name)
2703                      (user-error "Mandatory field `%s' is empty" field-name))
2704
2705                    ;; unify case of field name
2706                    (when (memq 'unify-case format)
2707		      (let ((fname (car (assoc-string field-name
2708						      default-field-list t)))
2709			    (curname (buffer-substring beg-name end-name)))
2710			(delete-region beg-name end-name)
2711			(goto-char beg-name)
2712			(insert (funcall bibtex-unify-case-function
2713					 (or fname curname)))))
2714
2715                    ;; update point
2716                    (goto-char end-field))))
2717
2718              ;; check whether all required fields are present
2719              (when (memq 'required-fields format)
2720		(let ((alt-expect (make-vector num-alt nil)))
2721		  (dolist (fname req-field-list)
2722		    (cond ((nth 3 fname)
2723                           ;; t if required field has alternative flag
2724                           (setq idx (abs (nth 3 fname)))
2725			   (bibtex-vec-push alt-expect idx (car fname)))
2726			  ((not (member-ignore-case (car fname) field-list))
2727                           (setq error-field-name (car fname))
2728			   (user-error "Mandatory field `%s' is missing"
2729                                       (car fname)))))
2730		  (dotimes (idx num-alt)
2731		    (cond ((and (aref alt-expect idx)
2732                                (not (aref alt-fields idx)))
2733			   (setq error-field-name
2734                                 (car (last (aref alt-fields idx))))
2735			   (user-error "Alternative mandatory fields `%s' are missing"
2736                                       (mapconcat 'identity
2737                                                  (reverse
2738                                                   (aref alt-expect idx))
2739                                                  ", ")))
2740			  ((nth 1 (aref alt-fields idx))
2741			   (setq error-field-name
2742                                 (car (last (aref alt-fields idx))))
2743			   (user-error "Fields `%s' are alternatives"
2744                                       (mapconcat 'identity
2745                                                  (reverse
2746                                                   (aref alt-fields idx))
2747                                                  ", ")))))))
2748
2749              ;; update comma after last field
2750              (if (memq 'last-comma format)
2751                  (cond ((and bibtex-comma-after-last-field
2752                              (not (looking-at ",")))
2753                         (insert ","))
2754                        ((and (not bibtex-comma-after-last-field)
2755                              (looking-at ","))
2756                         (delete-char 1))))
2757
2758              ;; update right entry delimiter
2759              (if (looking-at ",")
2760                  (forward-char))
2761              (when (memq 'delimiters format)
2762                (skip-chars-forward " \t\n")
2763                (delete-char 1)
2764                (insert (bibtex-entry-right-delimiter)))
2765
2766              ;; realign and fill entry
2767              (if (memq 'realign format)
2768                  (bibtex-fill-entry)))))
2769
2770      ;; Unwindform: move point to location where error occurred if possible
2771      (if error-field-name
2772          (let (bounds)
2773            (when (save-excursion
2774                    (bibtex-beginning-of-entry)
2775                    (setq bounds
2776                          (bibtex-search-forward-field
2777                           ;; If we use the crossref field, a required field
2778                           ;; can have the OPT prefix
2779                           (concat "\\(OPT\\|ALT\\)?" error-field-name) t)))
2780              (goto-char (bibtex-start-of-text-in-field bounds))
2781              (bibtex-find-text)))))))
2782
2783(defun bibtex-field-re-init (regexp-alist type)
2784  "Calculate optimized value for bibtex-regexp-TYPE-opt.
2785This value is based on bibtex-regexp-TYPE-alist.  TYPE is `braces' or `strings'.
2786Return optimized value to be used by `bibtex-format-entry'."
2787  (setq regexp-alist
2788        (mapcar (lambda (e)
2789                  (list (car e)
2790                        (replace-regexp-in-string " +" "[ \t\n]+" (nth 1 e))
2791                        (nth 2 e))) ; nil for 'braces'.
2792                regexp-alist))
2793  (let (opt-list)
2794    ;; Loop over field names
2795    (dolist (field (delete-dups (apply #'append (mapcar #'car regexp-alist))))
2796      (let (rules)
2797        ;; Collect all matches we have for this field name
2798        (dolist (e regexp-alist)
2799          (if (assoc-string field (car e) t)
2800              (push (cons (nth 1 e) (nth 2 e)) rules)))
2801        (if (eq type 'braces)
2802            ;; concatenate all regexps to a single regexp
2803            (setq rules (concat "\\(?:" (mapconcat #'car rules "\\|") "\\)")))
2804        ;; create list of replacement rules.
2805        (push (cons field rules) opt-list)))
2806    opt-list))
2807
2808
2809(defun bibtex-autokey-abbrev (string len)
2810  "Return an abbreviation of STRING with at least LEN characters.
2811If LEN is positive the abbreviation is terminated only after a consonant
2812or at the word end.  If LEN is negative the abbreviation is strictly
2813enforced using abs (LEN) characters.  If LEN is not a number, STRING
2814is returned unchanged."
2815  (cond ((or (not (numberp len))
2816             (<= (length string) (abs len)))
2817         string)
2818        ((equal len 0)
2819         "")
2820        ((< len 0)
2821         (substring string 0 (abs len)))
2822        (t (let* ((case-fold-search t)
2823                  (abort-char (string-match "[^aeiou]" string (1- len))))
2824             (if abort-char
2825                 (substring string 0 (1+ abort-char))
2826               string)))))
2827
2828(defun bibtex-autokey-get-field (field &optional change-list)
2829  "Get content of BibTeX field FIELD.  Return empty string if not found.
2830FIELD may also be a list of fields that are tried in order.
2831Optional arg CHANGE-LIST is a list of substitution patterns that is
2832applied to the content of FIELD.  It is an alist with pairs
2833\(OLD-REGEXP . NEW-STRING)."
2834  (let* ((bibtex-expand-strings bibtex-autokey-expand-strings)
2835         (content (bibtex-text-in-field field bibtex-autokey-use-crossref))
2836        case-fold-search)
2837    (unless content (setq content ""))
2838    (dolist (pattern change-list)
2839      (setq content (replace-regexp-in-string (car pattern)
2840                                              (cdr pattern)
2841                                              content t)))
2842    content))
2843
2844(defun bibtex-autokey-get-names ()
2845  "Get contents of the name field of the current entry.
2846Do some modifications based on `bibtex-autokey-name-change-strings'.
2847Return the names as a concatenated string obeying `bibtex-autokey-names'
2848and `bibtex-autokey-names-stretch'."
2849  (let ((names (bibtex-autokey-get-field "author\\|editor"
2850                                         bibtex-autokey-name-change-strings)))
2851    ;; Some entries do not have a name field.
2852    (if (string= "" names)
2853        names
2854      (let* ((case-fold-search t)
2855             (name-list (mapcar #'bibtex-autokey-demangle-name
2856                                (split-string names "[ \t\n]+and[ \t\n]+")))
2857             additional-names)
2858        (unless (or (not (numberp bibtex-autokey-names))
2859                    (<= (length name-list)
2860                        (+ bibtex-autokey-names
2861                           bibtex-autokey-names-stretch)))
2862          ;; Take `bibtex-autokey-names' elements from beginning of name-list
2863          (setq name-list (nreverse (nthcdr (- (length name-list)
2864                                               bibtex-autokey-names)
2865                                            (nreverse name-list)))
2866                additional-names bibtex-autokey-additional-names))
2867        (concat (mapconcat #'identity name-list
2868                           bibtex-autokey-name-separator)
2869                additional-names)))))
2870
2871(defun bibtex-autokey-demangle-name (fullname)
2872  "Get the last part from a well-formed FULLNAME and perform abbreviations."
2873  (let* (case-fold-search
2874         (name (cond ((string-match "\\([[:upper:]][^, ]*\\)[^,]*," fullname)
2875                      ;; Name is of the form "von Last, First" or
2876                      ;; "von Last, Jr, First"
2877                      ;; --> Take the first capital part before the comma
2878                      (match-string 1 fullname))
2879                     ((string-match "\\([^, ]*\\)," fullname)
2880                      ;; Strange name: we have a comma, but nothing capital
2881                      ;; So we accept even lowercase names
2882                      (match-string 1 fullname))
2883                     ((string-match "\\(\\<[[:lower:]][^ ]* +\\)+\\([[:upper:]][^ ]*\\)"
2884                                    fullname)
2885                      ;; name is of the form "First von Last", "von Last",
2886                      ;; "First von von Last", or "d'Last"
2887                      ;; --> take the first capital part after the "von" parts
2888                      (match-string 2 fullname))
2889                     ((string-match "\\([^ ]+\\) *\\'" fullname)
2890                      ;; name is of the form "First Middle Last" or "Last"
2891                      ;; --> take the last token
2892                      (match-string 1 fullname))
2893                     (t (user-error "Name `%s' is incorrectly formed"
2894                                    fullname)))))
2895    (funcall bibtex-autokey-name-case-convert-function
2896             (bibtex-autokey-abbrev name bibtex-autokey-name-length))))
2897
2898(defun bibtex-autokey-get-year ()
2899  "Return year field contents as a string obeying `bibtex-autokey-year-length'."
2900  (let* ((str (bibtex-autokey-get-field '("date" "year"))) ; possibly ""
2901         (year (or (and (iso8601-valid-p str)
2902                        (let ((year (decoded-time-year (iso8601-parse str))))
2903                          (and year (number-to-string year))))
2904                   ;; BibTeX permits a year field "(about 1984)", where only
2905                   ;; the last four nonpunctuation characters must be numerals.
2906                   (and (string-match "\\([0-9][0-9][0-9][0-9]\\)[^[:alnum:]]*\\'" str)
2907                        (match-string 1 str))
2908                   (user-error "Year or date field `%s' invalid" str))))
2909    (substring year (max 0 (- (length year) bibtex-autokey-year-length)))))
2910
2911(defun bibtex-autokey-get-title ()
2912  "Get title field contents up to a terminator.
2913Return the result as a string."
2914  (let ((case-fold-search t)
2915        (titlestring
2916         (bibtex-autokey-get-field "title"
2917                                   bibtex-autokey-titleword-change-strings)))
2918    ;; ignore everything past a terminator
2919    (if (string-match bibtex-autokey-title-terminators titlestring)
2920        (setq titlestring (substring titlestring 0 (match-beginning 0))))
2921    ;; gather words from titlestring into a list.  Ignore
2922    ;; specific words and use only a specific amount of words.
2923    (let ((counter 0)
2924	  (ignore-re (concat "\\`\\(?:"
2925                             (mapconcat #'identity
2926                                        bibtex-autokey-titleword-ignore "\\|")
2927                             "\\)\\'"))
2928          titlewords titlewords-extra word)
2929      (while (and (or (not (numberp bibtex-autokey-titlewords))
2930                      (< counter (+ bibtex-autokey-titlewords
2931                                    bibtex-autokey-titlewords-stretch)))
2932                  (string-match "\\b\\w+" titlestring))
2933        (setq word (match-string 0 titlestring)
2934              titlestring (substring titlestring (match-end 0)))
2935        ;; Ignore words matched by one of the elements of
2936        ;; `bibtex-autokey-titleword-ignore'.  Case is significant.
2937        (unless (let (case-fold-search)
2938		  (string-match ignore-re word))
2939          (setq counter (1+ counter))
2940          (if (or (not (numberp bibtex-autokey-titlewords))
2941                  (<= counter bibtex-autokey-titlewords))
2942              (push word titlewords)
2943            (push word titlewords-extra))))
2944      ;; Obey `bibtex-autokey-titlewords-stretch':
2945      ;; If by now we have processed all words in titlestring, we include
2946      ;; titlewords-extra in titlewords.  Otherwise, we ignore titlewords-extra.
2947      (unless (string-match "\\b\\w+" titlestring)
2948        (setq titlewords (append titlewords-extra titlewords)))
2949      (mapconcat #'bibtex-autokey-demangle-title (nreverse titlewords)
2950                 bibtex-autokey-titleword-separator))))
2951
2952(defun bibtex-autokey-demangle-title (titleword)
2953  "Do some abbreviations on TITLEWORD.
2954The rules are defined in `bibtex-autokey-titleword-abbrevs'
2955and `bibtex-autokey-titleword-length'."
2956  (let ((case-fold-search t)
2957        (alist bibtex-autokey-titleword-abbrevs))
2958    (while (and alist
2959                (not (string-match (concat "\\`\\(?:" (caar alist) "\\)\\'")
2960                                   titleword)))
2961      (setq alist (cdr alist)))
2962    (if alist
2963        (cdar alist)
2964      (funcall bibtex-autokey-titleword-case-convert-function
2965               (bibtex-autokey-abbrev titleword bibtex-autokey-titleword-length)))))
2966
2967(defun bibtex-generate-autokey ()
2968  "Generate automatically a key for a BibTeX entry.
2969Use the author/editor, the year and the title field.
2970The algorithm works as follows.
2971
2972The name part:
2973 1. Use the author or editor field to generate the name part of the key.
2974    Expand BibTeX strings if `bibtex-autokey-expand-strings' is non-nil.
2975 2. Change the content of the name field according to
2976    `bibtex-autokey-name-change-strings' (see there for further detail).
2977 3. Use the first `bibtex-autokey-names' names in the name field.  If there
2978    are up to `bibtex-autokey-names' + `bibtex-autokey-names-stretch' names,
2979    use all names.
2980 4. Use only the last names to form the name part.  From these last names,
2981    take at least `bibtex-autokey-name-length' characters (truncate only
2982    after a consonant or at a word end).
2983 5. Convert all last names using the function
2984    `bibtex-autokey-name-case-convert-function'.
2985 6. Build the name part of the key by concatenating all abbreviated last
2986    names with the string `bibtex-autokey-name-separator' between any two.
2987    If there are more names in the name field than names used in the name
2988    part, append the string `bibtex-autokey-additional-names'.
2989
2990The year part:
2991 1. Build the year part of the key by truncating the content of the year
2992    component of the date or year field to the rightmost
2993    `bibtex-autokey-year-length' digits (useful values are 2 and 4).
2994 2. If both the year and date fields are absent, but the entry has a
2995    valid crossref field and `bibtex-autokey-use-crossref' is
2996    non-nil, use the date or year field of the cross-referenced entry
2997    instead.
2998
2999The title part
3000 1. Change the content of the title field according to
3001    `bibtex-autokey-titleword-change-strings' (see there for further detail).
3002 2. Truncate the title before the first match of
3003    `bibtex-autokey-title-terminators' and delete those words which appear
3004    in `bibtex-autokey-titleword-ignore'.  Build the title part using the
3005    first `bibtex-autokey-titlewords' words from this truncated title.
3006    If the truncated title ends after up to `bibtex-autokey-titlewords' +
3007    `bibtex-autokey-titlewords-stretch' words, use all words from the
3008    truncated title.
3009 3. For every title word that appears in `bibtex-autokey-titleword-abbrevs'
3010    use the corresponding abbreviation (see documentation of this variable
3011    for further detail).
3012 4. From every title word not generated by an abbreviation, take at least
3013    `bibtex-autokey-titleword-length' characters (truncate only after
3014    a consonant or at a word end).
3015 5. Convert all title words using the function
3016    `bibtex-autokey-titleword-case-convert-function'.
3017 6. Build the title part by concatenating all abbreviated title words with
3018    the string `bibtex-autokey-titleword-separator' between any two.
3019
3020Concatenate the key:
3021 1. Concatenate `bibtex-autokey-prefix-string', the name part, the year
3022    part and the title part.  If the name part and the year part are both
3023    non-empty insert `bibtex-autokey-name-year-separator' between the two.
3024    If the title part and the year (or name) part are non-empty, insert
3025    `bibtex-autokey-year-title-separator' between the two.
3026 2. `bibtex-autokey-before-presentation-function' must be
3027    a function taking one argument.  Call this function with the generated
3028    key as the argument.  Use the return value of this function (a string)
3029    as the key.
3030 3. If `bibtex-autokey-edit-before-use' is non-nil, present the key in the
3031    minibuffer to the user for editing.  Insert the key given by the user."
3032  (let* ((names (bibtex-autokey-get-names))
3033         (year (bibtex-autokey-get-year))
3034         (title (bibtex-autokey-get-title))
3035         (autokey (concat bibtex-autokey-prefix-string
3036                          names
3037                          (unless (or (equal names "")
3038                                      (equal year ""))
3039                            bibtex-autokey-name-year-separator)
3040                          year
3041                          (unless (or (and (equal names "")
3042                                           (equal year ""))
3043                                      (equal title ""))
3044                            bibtex-autokey-year-title-separator)
3045                          title)))
3046    (if bibtex-autokey-before-presentation-function
3047        (funcall bibtex-autokey-before-presentation-function autokey)
3048      autokey)))
3049
3050
3051(defun bibtex-global-key-alist ()
3052  "Return global key alist based on `bibtex-files'."
3053  (if bibtex-files
3054      (apply #'append
3055             (mapcar (lambda (buf)
3056                       (with-current-buffer buf bibtex-reference-keys))
3057                     ;; include current buffer only if it uses `bibtex-mode'
3058                     (bibtex-initialize (eq major-mode 'bibtex-mode))))
3059    (if (eq major-mode 'bibtex-mode)
3060        bibtex-reference-keys)))
3061
3062(defun bibtex-read-key (prompt &optional key global)
3063  "Read BibTeX key from minibuffer using PROMPT and default KEY.
3064If optional arg GLOBAL is non-nil, completion is based on the keys in
3065`bibtex-reference-keys' of `bibtex-files'."
3066  (let (completion-ignore-case)
3067    (completing-read prompt (if global (bibtex-global-key-alist)
3068                              bibtex-reference-keys)
3069                     nil nil key 'bibtex-key-history)))
3070
3071(defun bibtex-read-string-key (&optional key)
3072  "Read BibTeX string key from minibuffer using default KEY."
3073  (let ((completion-ignore-case t))
3074    (completing-read "String key: " bibtex-strings
3075                     nil nil key 'bibtex-key-history)))
3076
3077(defun bibtex-parse-keys (&optional abortable verbose)
3078  "Set `bibtex-reference-keys' to the keys used in the whole buffer.
3079Find both entry keys and crossref entries.  If ABORTABLE is non-nil abort
3080on user input.  If VERBOSE is non-nil give messages about progress.
3081Return alist of keys if parsing was completed, `aborted' otherwise.
3082If `bibtex-parse-keys-fast' is non-nil, use fast but simplified algorithm
3083for parsing BibTeX keys.  If parsing fails, try to set this variable to nil."
3084  (if (eq major-mode 'bibtex-mode)
3085      (let (ref-keys crossref-keys)
3086        (save-excursion
3087          (save-match-data
3088            (if verbose
3089                (bibtex-progress-message
3090                 (concat (buffer-name) ": parsing reference keys")))
3091            (catch 'userkey
3092              (goto-char (point-min))
3093              (if bibtex-parse-keys-fast
3094                  (let ((case-fold-search t)
3095                        (re (concat bibtex-entry-head "\\|"
3096                                    ",[ \t\n]*crossref[ \t\n]*=[ \t\n]*"
3097                                    "\\(\"[^\"]*\"\\|{[^}]*}\\)[ \t\n]*[,})]")))
3098                    (while (re-search-forward re nil t)
3099                      (if (and abortable (input-pending-p))
3100                          ;; user has aborted by typing a key: return `aborted'
3101                          (throw 'userkey 'aborted))
3102                      (cond ((match-end 3)
3103                             ;; This is a crossref.
3104                             (let ((key (buffer-substring-no-properties
3105                                         (1+ (match-beginning 3)) (1- (match-end 3)))))
3106                               (unless (assoc key crossref-keys)
3107                                 (push (list key) crossref-keys))))
3108                            ;; We probably have a non-bibtex file.
3109                            ((not (match-beginning bibtex-type-in-head))
3110                             (throw 'userkey nil))
3111                            ;; only keys of known entries
3112                            ((assoc-string (bibtex-type-in-head)
3113                                           bibtex-entry-alist t)
3114                             ;; This is an entry.
3115                             (let ((key (bibtex-key-in-head)))
3116                               (unless (assoc key ref-keys)
3117                                 (push (cons key t) ref-keys)))))))
3118
3119                (let (;; ignore @String entries because they are handled
3120                      ;; separately by `bibtex-parse-strings'
3121                      (bibtex-sort-ignore-string-entries t)
3122                      bounds)
3123                  (bibtex-map-entries
3124                   (lambda (key _beg end)
3125                     (if (and abortable
3126                              (input-pending-p))
3127                         ;; user has aborted by typing a key: return `aborted'
3128                         (throw 'userkey 'aborted))
3129                     (if verbose (bibtex-progress-message))
3130                     (unless (assoc key ref-keys)
3131                       (push (cons key t) ref-keys))
3132                     (if (and (setq bounds (bibtex-search-forward-field "crossref" end))
3133                              (setq key (bibtex-text-in-field-bounds bounds t))
3134                              (not (assoc key crossref-keys)))
3135                         (push (list key) crossref-keys))))))
3136
3137              (dolist (key crossref-keys)
3138                (unless (assoc (car key) ref-keys) (push key ref-keys)))
3139              (if verbose
3140                  (bibtex-progress-message 'done))
3141              ;; successful operation --> return `bibtex-reference-keys'
3142              (setq bibtex-reference-keys (nreverse ref-keys))))))))
3143
3144(defun bibtex-parse-strings (&optional add abortable)
3145  "Set `bibtex-strings' to the string definitions in the whole buffer.
3146If ADD is non-nil add the new strings to `bibtex-strings' instead of
3147simply resetting it.  If ADD is an alist of strings, also add ADD to
3148`bibtex-strings'.  If ABORTABLE is non-nil abort on user input.
3149Return alist of strings if parsing was completed, `aborted' otherwise."
3150  (save-excursion
3151    (save-match-data
3152      (goto-char (point-min))
3153      (let ((strings (if (and add (not (functionp bibtex-strings)))
3154                         bibtex-strings))
3155            bounds key)
3156        (if (listp add)
3157            (dolist (string add)
3158              (unless (assoc-string (car string) strings t)
3159                (push string strings))))
3160        (catch 'userkey
3161          (while (setq bounds (bibtex-search-forward-string))
3162            (if (and abortable
3163                     (input-pending-p))
3164                ;; user has aborted by typing a key --> return `aborted'
3165                (throw 'userkey 'aborted))
3166            (setq key (bibtex-reference-key-in-string bounds))
3167            (unless (assoc-string key strings t)
3168              (push (cons key (bibtex-text-in-string bounds t))
3169                    strings))
3170            (goto-char (bibtex-end-of-text-in-string bounds)))
3171          ;; successful operation --> return `bibtex-strings'
3172          (setq bibtex-strings strings))))))
3173
3174(defun bibtex-strings ()
3175  "Return `bibtex-strings'.  Initialize this variable if necessary."
3176  (if (functionp bibtex-strings)
3177      (bibtex-parse-strings (bibtex-string-files-init))
3178    bibtex-strings))
3179
3180(defun bibtex-string-files-init ()
3181  "Return initialization for `bibtex-strings'.
3182Use `bibtex-predefined-strings' and BibTeX files `bibtex-string-files'."
3183  (save-match-data
3184    (let ((dirlist (split-string (or bibtex-string-file-path default-directory)
3185                                 ":+"))
3186          (case-fold-search)
3187          string-files fullfilename compl bounds found)
3188      ;; collect absolute file names of valid string files
3189      (dolist (filename bibtex-string-files)
3190        (unless (string-match "\\.bib\\'" filename)
3191          (setq filename (concat filename ".bib")))
3192        ;; test filenames
3193        (if (file-name-absolute-p filename)
3194            (if (file-readable-p filename)
3195                (push filename string-files)
3196              (user-error "BibTeX strings file %s not found" filename))
3197          (dolist (dir dirlist)
3198            (when (file-readable-p
3199                   (setq fullfilename (expand-file-name filename dir)))
3200              (push fullfilename string-files)
3201              (setq found t)))
3202          (unless found
3203            (user-error "File %s not in paths defined via bibtex-string-file-path"
3204                        filename))))
3205      ;; parse string files
3206      (dolist (filename string-files)
3207        (with-temp-buffer
3208          (insert-file-contents filename)
3209          (goto-char (point-min))
3210          (while (setq bounds (bibtex-search-forward-string))
3211            (push (cons (bibtex-reference-key-in-string bounds)
3212                        (bibtex-text-in-string bounds t))
3213                  compl)
3214            (goto-char (bibtex-end-of-string bounds)))))
3215      (append bibtex-predefined-strings (nreverse compl)))))
3216
3217(defun bibtex-parse-buffers-stealthily ()
3218  "Parse buffer in the background during idle time.
3219Called by `run-with-idle-timer'.  Whenever Emacs has been idle
3220for `bibtex-parse-keys-timeout' seconds, parse all BibTeX buffers
3221which have been modified after last parsing.
3222Parsing initializes `bibtex-reference-keys' and `bibtex-strings'."
3223  (save-excursion
3224    (let ((buffers (buffer-list))
3225          (strings-init (bibtex-string-files-init)))
3226      (while (and buffers (not (input-pending-p)))
3227        (set-buffer (car buffers))
3228        (if (and (eq major-mode 'bibtex-mode)
3229                 (not (eq (buffer-modified-tick)
3230                          bibtex-buffer-last-parsed-tick)))
3231            (save-restriction
3232              (widen)
3233              ;; Output no progress messages in `bibtex-parse-keys'
3234              ;; because when in `y-or-n-p' that can hide the question.
3235              (if (and (listp (bibtex-parse-keys t))
3236                       ;; update `bibtex-strings'
3237                       (listp (bibtex-parse-strings strings-init t)))
3238
3239                  ;; remember that parsing was successful
3240                  (setq bibtex-buffer-last-parsed-tick (buffer-modified-tick)))))
3241        (setq buffers (cdr buffers))))))
3242
3243;;;###autoload
3244(defun bibtex-initialize (&optional current force select)
3245  "(Re)Initialize BibTeX buffers.
3246Visit the BibTeX files defined by `bibtex-files' and return a list
3247of corresponding buffers.
3248Initialize in these buffers `bibtex-reference-keys' if not yet set.
3249List of BibTeX buffers includes current buffer if CURRENT is non-nil
3250and the current buffer visits a file using `bibtex-mode'.
3251If FORCE is non-nil, (re)initialize `bibtex-reference-keys' even if
3252already set.  If SELECT is non-nil interactively select a BibTeX buffer.
3253
3254When called interactively, FORCE is t, CURRENT is t if current buffer
3255visits a file using `bibtex-mode', and SELECT is t if current buffer
3256does not use `bibtex-mode'."
3257  (interactive (list (eq major-mode 'bibtex-mode) t
3258                     (not (eq major-mode 'bibtex-mode))))
3259  (let ((file-path (split-string (or bibtex-file-path default-directory) ":+"))
3260        file-list dir-list buffer-list)
3261    ;; generate list of BibTeX files
3262    (dolist (file bibtex-files)
3263      (cond ((eq file 'bibtex-file-path)
3264             (setq dir-list (append dir-list file-path)))
3265            ((file-accessible-directory-p file)
3266             (push file dir-list))
3267            ((progn (unless (string-match "\\.bib\\'" file)
3268                      (setq file (concat file ".bib")))
3269                    (file-name-absolute-p file))
3270             (push file file-list))
3271            (t
3272             (let (expanded-file-name found)
3273               (dolist (dir file-path)
3274                 (when (file-readable-p
3275                        (setq expanded-file-name (expand-file-name file dir)))
3276                   (push expanded-file-name file-list)
3277                   (setq found t)))
3278               (unless found
3279                 (user-error "File `%s' not in paths defined via bibtex-file-path"
3280                             file))))))
3281    (dolist (file file-list)
3282      (unless (file-readable-p file)
3283        (user-error "BibTeX file `%s' not found" file)))
3284    ;; expand dir-list
3285    (dolist (dir dir-list)
3286      (setq file-list
3287            (append file-list (directory-files dir t "\\.bib\\'" t))))
3288    (delete-dups file-list)
3289    ;; visit files in FILE-LIST
3290    (dolist (file file-list)
3291      (if (file-readable-p file)
3292        (push (find-file-noselect file) buffer-list)))
3293    ;; Include current buffer iff we want it.
3294    ;; Exclude current buffer if it does not visit a file using `bibtex-mode'.
3295    ;; This way we exclude BibTeX buffers such as `bibtex-search-buffer'
3296    ;; that are not visiting a BibTeX file.  Also, calling `bibtex-initialize'
3297    ;; gives meaningful results for any current buffer.
3298    (unless (and current (eq major-mode 'bibtex-mode) buffer-file-name)
3299      (setq current nil))
3300    (cond ((and current (not (memq (current-buffer) buffer-list)))
3301           (push (current-buffer) buffer-list))
3302          ((and (not current) (memq (current-buffer) buffer-list))
3303           (setq buffer-list (delq (current-buffer) buffer-list))))
3304    ;; parse keys
3305    (let (string-init)
3306      (dolist (buffer buffer-list)
3307        (with-current-buffer buffer
3308          (if (or force (functionp bibtex-reference-keys))
3309              (bibtex-parse-keys))
3310          (when (or force (functionp bibtex-strings))
3311            (unless string-init (setq string-init (bibtex-string-files-init)))
3312            (bibtex-parse-strings string-init)))))
3313    ;; select BibTeX buffer
3314    (if select
3315        (if buffer-list
3316            (switch-to-buffer
3317             (completing-read "Switch to BibTeX buffer: "
3318                              (mapcar #'buffer-name buffer-list)
3319                              nil t
3320                              (if current (buffer-name (current-buffer)))))
3321          (message "No BibTeX buffers defined")))
3322    buffer-list))
3323
3324(defun bibtex-complete-string-cleanup (compl) (lambda (str status) ;Curried.
3325  "Cleanup after inserting string STR.
3326Remove enclosing field delimiters for STR.  Display message with
3327expansion of STR using expansion list COMPL."
3328  (when (memq status '(exact finished sole))
3329    (let ((abbr (cdr (assoc-string str compl t))))
3330      (when abbr
3331        (message "%s = abbreviation for `%s'" str abbr)))
3332    (when (eq status 'finished)
3333      (save-excursion (bibtex-remove-delimiters))))))
3334
3335(defun bibtex-complete-crossref-cleanup (buf) (lambda (key status) ;Curried.
3336  "Display summary message on entry KEY after completion of a crossref key.
3337Use `bibtex-summary-function' to generate summary."
3338  (when (memq status '(exact sole finished))
3339    (let ((summary
3340           (with-current-buffer buf
3341             (save-excursion
3342               (if (bibtex-search-entry key t)
3343                   (funcall bibtex-summary-function))))))
3344      (when summary
3345        (message "%s %s" key summary))))))
3346
3347(defun bibtex-copy-summary-as-kill (&optional arg)
3348  "Push summary of current BibTeX entry to kill ring.
3349Use `bibtex-summary-function' to generate summary.
3350If prefix ARG is non-nil push BibTeX entry's URL to kill ring
3351that is generated by calling `bibtex-url'."
3352  (interactive "P")
3353  (if arg (let ((url (bibtex-url nil t)))
3354            (if url (kill-new (message "%s" url))
3355              (message "No URL known")))
3356    (save-excursion
3357      (bibtex-beginning-of-entry)
3358      (if (looking-at bibtex-entry-maybe-empty-head)
3359          (kill-new (message "%s" (funcall bibtex-summary-function)))
3360        (user-error "No entry found")))))
3361
3362(defun bibtex-summary ()
3363  "Return summary of current BibTeX entry.
3364Used as default value of `bibtex-summary-function'."
3365  ;; It would be neat to make this function customizable.  How?
3366  (if (looking-at bibtex-entry-maybe-empty-head)
3367      (let* ((bibtex-autokey-name-case-convert-function #'identity)
3368             (bibtex-autokey-name-length 'infty)
3369             (bibtex-autokey-names 1)
3370             (bibtex-autokey-names-stretch 0)
3371             (bibtex-autokey-name-separator " ")
3372             (bibtex-autokey-additional-names " etal")
3373             (names (bibtex-autokey-get-names))
3374             (bibtex-autokey-year-length 4)
3375             (year (bibtex-autokey-get-year))
3376             (bibtex-autokey-titlewords 5)
3377             (bibtex-autokey-titlewords-stretch 2)
3378             (bibtex-autokey-titleword-case-convert-function #'identity)
3379             (bibtex-autokey-titleword-length 5)
3380             (bibtex-autokey-titleword-separator " ")
3381             (title (bibtex-autokey-get-title))
3382             (journal (bibtex-autokey-get-field
3383                       "journal" bibtex-autokey-transcriptions))
3384             (volume (bibtex-autokey-get-field "volume"))
3385             (pages (bibtex-autokey-get-field "pages" '(("-.*\\'" . "")))))
3386        (mapconcat (lambda (arg)
3387                     (if (not (string= "" (cdr arg)))
3388                         (concat (car arg) (cdr arg))))
3389                   `((" " . ,names) (" " . ,year) (": " . ,title)
3390                     (", " . ,journal) (" " . ,volume) (":" . ,pages))
3391                   ""))
3392    (user-error "Entry not found")))
3393
3394(defun bibtex-pop (arg direction)
3395  "Fill current field from the ARGth same field's text in DIRECTION.
3396Generic function used by `bibtex-pop-previous' and `bibtex-pop-next'."
3397  ;; parse current field
3398  (let* ((bounds (bibtex-enclosing-field t))
3399         (start-old-field (bibtex-start-of-field bounds))
3400         (start-old-text (bibtex-start-of-text-in-field bounds))
3401         (end-old-text (bibtex-end-of-text-in-field bounds))
3402         (field-name (bibtex-name-in-field bounds t))
3403         failure)
3404    (save-excursion
3405      ;; if executed several times in a row, start each search where
3406      ;; the last one was finished
3407      (cond ((eq last-command 'bibtex-pop)
3408             (goto-char (if (eq direction 'previous)
3409                            bibtex-pop-previous-search-point
3410                          bibtex-pop-next-search-point)))
3411            ((eq direction 'previous)
3412             (bibtex-beginning-of-entry))
3413            (t (bibtex-end-of-entry)))
3414      ;; Search for arg'th previous/next similar field
3415      (while (and (not failure)
3416                  (>= (setq arg (1- arg)) 0))
3417        ;; The search of BibTeX fields is not bounded by entry boundaries
3418        (if (eq direction 'previous)
3419            (if (setq bounds (bibtex-search-backward-field field-name))
3420                (goto-char (bibtex-start-of-field bounds))
3421              (setq failure t))
3422          (if (setq bounds (bibtex-search-forward-field field-name))
3423              (goto-char (bibtex-end-of-field bounds))
3424            (setq failure t))))
3425      (if failure
3426          (user-error "No %s matching BibTeX field"
3427                      (if (eq direction 'previous) "previous" "next"))
3428        ;; Found a matching field.  Remember boundaries.
3429        (let ((new-text (bibtex-text-in-field-bounds bounds))
3430              (nbeg (copy-marker (bibtex-start-of-field bounds)))
3431              (nend (copy-marker (bibtex-end-of-field bounds))))
3432          (bibtex-flash-head "From: ")
3433          ;; Go back to where we started, delete old text, and pop new.
3434          (goto-char end-old-text)
3435          (delete-region start-old-text end-old-text)
3436          (if (= nbeg start-old-field)
3437              (insert (bibtex-field-left-delimiter)
3438                      (bibtex-field-right-delimiter))
3439            (insert new-text))
3440          (setq bibtex-pop-previous-search-point (marker-position nbeg)
3441                bibtex-pop-next-search-point (marker-position nend))))))
3442  (bibtex-find-text nil nil nil t)
3443  (setq this-command 'bibtex-pop))
3444
3445(defun bibtex-beginning-of-field ()
3446  "Move point backward to beginning of field.
3447This function uses a simple, fast algorithm assuming that the field
3448begins at the beginning of a line.  We use this function for font-locking."
3449  (let ((field-reg (concat "^[ \t]*" bibtex-field-name "[ \t]*=")))
3450    (beginning-of-line)
3451    (unless (looking-at field-reg)
3452      (re-search-backward field-reg nil t))))
3453
3454(defun bibtex-font-lock-url (bound &optional no-button)
3455  "Font-lock for URLs.  BOUND limits the search.
3456If NO-BUTTON is non-nil do not generate buttons."
3457  (let ((case-fold-search t)
3458        (pnt (point))
3459        name bounds start end found)
3460    (bibtex-beginning-of-field)
3461    (while (and (not found)
3462                (<= (point) bound)
3463		(prog1 (re-search-forward bibtex-font-lock-url-regexp bound t)
3464		  (setq name (match-string-no-properties 1)))
3465		(setq bounds (bibtex-parse-field-text))
3466                (progn
3467                  (setq start (car bounds) end (nth 1 bounds))
3468                  ;; Always ignore field delimiters
3469                  (if (memq (char-before end) '(?\} ?\"))
3470                      (setq end (1- end)))
3471                  (if (memq (char-after start) '(?\{ ?\"))
3472                      (setq start (1+ start)))
3473                  (if (< start pnt) (setq start (min pnt end)))
3474                  (<= start bound)))
3475      (if (<= pnt start)
3476          (let ((lst bibtex-generate-url-list) url)
3477            (while (and (not found) (setq url (car (pop lst))))
3478              (goto-char start)
3479              (setq found (and (bibtex-string= name (car url))
3480                               (re-search-forward (cdr url) end t))))))
3481      (unless found (goto-char end)))
3482    (if (and found (not no-button))
3483        (bibtex-button (match-beginning 0) (match-end 0)
3484                       'bibtex-url (match-beginning 0)))
3485    found))
3486
3487(defun bibtex-font-lock-crossref (bound)
3488  "Font-lock for crossref fields.  BOUND limits the search."
3489  (let ((case-fold-search t)
3490        (pnt (point))
3491        (crossref-reg (concat "^[ \t]*crossref[ \t]*=[ \t\n]*"
3492                              "\\(\"[^\"]*\"\\|{[^}]*}\\)[ \t\n]*[,})]"))
3493	start end found)
3494    (bibtex-beginning-of-field)
3495    (while (and (not found)
3496		(re-search-forward crossref-reg bound t))
3497      (setq start (1+ (match-beginning 1))
3498            end (1- (match-end 1))
3499            found (>= start pnt)))
3500    (if found (bibtex-button start end 'bibtex-search-crossref
3501                             (buffer-substring-no-properties start end)
3502                             start t))
3503    found))
3504
3505(defun bibtex-font-lock-cite (matcher bound)
3506  "Font-lock for cited keys.
3507MATCHER identifies the cited key, see `bibtex-cite-matcher-alist'.
3508BOUND limits the search."
3509  (let (case-fold-search)
3510    (if (re-search-forward (car matcher) bound t)
3511        (let ((start (match-beginning (cdr matcher)))
3512              (end (match-end (cdr matcher))))
3513          (bibtex-button start end 'bibtex-search-crossref
3514                         (buffer-substring-no-properties start end)
3515                         start t t)
3516          t))))
3517
3518(defun bibtex-button-action (button)
3519  "Call BUTTON's BibTeX function."
3520  (apply (button-get button 'bibtex-function)
3521         (button-get button 'bibtex-args)))
3522
3523(define-button-type 'bibtex-url
3524  'action 'bibtex-button-action
3525  'bibtex-function #'bibtex-url
3526  'help-echo (purecopy "mouse-2, RET: follow URL"))
3527
3528(define-button-type 'bibtex-search-crossref
3529  'action 'bibtex-button-action
3530  'bibtex-function #'bibtex-search-crossref
3531  'help-echo (purecopy "mouse-2, RET: follow crossref"))
3532
3533(defun bibtex-button (beg end type &rest args)
3534  "Make a BibTeX button from BEG to END of type TYPE in the current buffer."
3535  (make-text-button beg end 'type type 'bibtex-args args))
3536
3537
3538;; Interactive Functions:
3539
3540;;;###autoload
3541(define-derived-mode bibtex-mode nil "BibTeX"
3542  "Major mode for editing BibTeX files.
3543
3544General information on working with BibTeX mode:
3545
3546Use commands such as \\<bibtex-mode-map>\\[bibtex-Book] to get a template for a specific entry.
3547Then fill in all desired fields using \\[bibtex-next-field] to jump from field
3548to field.  After having filled in all desired fields in the entry, clean the
3549new entry with the command \\[bibtex-clean-entry].
3550
3551Some features of BibTeX mode are available only by setting the variable
3552`bibtex-maintain-sorted-entries' to non-nil.  However, then BibTeX mode
3553works only with buffers containing valid (syntactically correct) and sorted
3554entries.  This is usually the case, if you have created a buffer completely
3555with BibTeX mode and finished every new entry with \\[bibtex-clean-entry].
3556
3557For third party BibTeX files, call the command \\[bibtex-convert-alien]
3558to fully take advantage of all features of BibTeX mode.
3559
3560
3561Special information:
3562
3563A command such as \\[bibtex-Book] outlines the fields for a BibTeX book entry.
3564
3565The names of optional fields start with the string OPT, and are thus ignored
3566by BibTeX.  The names of alternative fields from which only one is required
3567start with the string ALT.  The OPT or ALT string may be removed from
3568the name of a field with \\[bibtex-remove-OPT-or-ALT].
3569\\[bibtex-make-field] inserts a new field after the current one.
3570\\[bibtex-kill-field] kills the current field entirely.
3571\\[bibtex-yank] yanks the last recently killed field after the current field.
3572\\[bibtex-remove-delimiters] removes the double-quotes or braces around the text of the current field.
3573\\[bibtex-empty-field] replaces the text of the current field with the default \"\" or {}.
3574\\[bibtex-find-text] moves point to the end of the current field.
3575\\[completion-at-point] completes word fragment before point according to context.
3576
3577The command \\[bibtex-clean-entry] cleans the current entry, i.e. it removes OPT/ALT
3578from the names of all non-empty optional or alternative fields, checks that
3579no required fields are empty, and does some formatting dependent on the value
3580of `bibtex-entry-format'.  Furthermore, it can automatically generate a key
3581for the BibTeX entry, see `bibtex-generate-autokey'.
3582Note: some functions in BibTeX mode depend on entries being in a special
3583format (all fields beginning on separate lines), so it is usually a bad
3584idea to remove `realign' from `bibtex-entry-format'.
3585
3586BibTeX mode supports Imenu and hideshow minor mode (`hs-minor-mode').
3587
3588----------------------------------------------------------
3589Entry to BibTeX mode calls the value of `bibtex-mode-hook'
3590if that value is non-nil.
3591
3592\\{bibtex-mode-map}"
3593  (add-hook 'completion-at-point-functions
3594            #'bibtex-completion-at-point-function nil 'local)
3595  (make-local-variable 'bibtex-buffer-last-parsed-tick)
3596  ;; Install stealthy parse function if not already installed
3597  (unless bibtex-parse-idle-timer
3598    (setq bibtex-parse-idle-timer (run-with-idle-timer
3599                                   bibtex-parse-keys-timeout t
3600                                   'bibtex-parse-buffers-stealthily)))
3601  (setq-local paragraph-start "[ \f\n\t]*$")
3602  (setq-local comment-column 0)
3603  (setq-local defun-prompt-regexp "^[ \t]*@[[:alnum:]]+[ \t]*")
3604  (setq-local outline-regexp "[ \t]*@")
3605  (setq-local fill-paragraph-function #'bibtex-fill-field)
3606  (setq-local font-lock-defaults
3607              '(bibtex-font-lock-keywords
3608                nil t ((?$ . "\"")
3609                       ;; Mathematical expressions should be fontified as strings
3610                       (?\" . ".")
3611                       ;; Quotes are field delimiters and quote-delimited
3612                       ;; entries should be fontified in the same way as
3613                       ;; brace-delimited ones
3614                       )
3615                nil
3616                (font-lock-extra-managed-props . (category))
3617                (font-lock-mark-block-function
3618                 . (lambda ()
3619                     (set-mark (bibtex-end-of-entry))
3620                     (bibtex-beginning-of-entry)))))
3621  (setq-local syntax-propertize-function
3622              (syntax-propertize-via-font-lock
3623               bibtex-font-lock-syntactic-keywords))
3624  (let ((fun (lambda ()
3625               (bibtex-set-dialect)
3626               (setq-local comment-start bibtex-comment-start)
3627               (setq-local comment-start-skip
3628                           (concat (regexp-quote bibtex-comment-start) "\\>[ \t]*"))
3629               (setq-local fill-prefix
3630                           (make-string (+ bibtex-entry-offset
3631                                           bibtex-contline-indentation)
3632                                        ?\s)))))
3633    (if (and buffer-file-name enable-local-variables)
3634        (add-hook 'hack-local-variables-hook fun nil t)
3635      (funcall fun))))
3636
3637(defun bibtex-entry-alist (dialect)
3638  "Return entry-alist for DIALECT."
3639  (let ((var (intern (format "bibtex-%s-entry-alist" dialect)))
3640        entry-alist)
3641    (if (boundp var)
3642        (setq entry-alist (symbol-value var))
3643      (user-error "BibTeX dialect `%s' undefined" dialect))
3644    (if (not (consp (nth 1 (car entry-alist))))
3645        ;; new format
3646        entry-alist
3647      ;; Convert old format of `bibtex-entry-field-alist'
3648      (unless (get var 'entry-list-format)
3649        (put var 'entry-list-format "pre-24")
3650        (message "Old format of `%s' (pre GNU Emacs 24).
3651Please convert to the new format."
3652                 (if (eq (indirect-variable 'bibtex-entry-field-alist) var)
3653                     'bibtex-entry-field-alist var))
3654        (sit-for 3))
3655      (let (lst)
3656        (dolist (entry entry-alist)
3657          (let ((fl (nth 1 entry)) req xref opt)
3658            (dolist (field (copy-tree (car fl)))
3659              (if (nth 3 field) (setcar (nthcdr 3 field) 0))
3660              (if (or (not (nth 2 entry))
3661                      (assoc-string (car field) (car (nth 2 entry)) t))
3662                  (push field req)
3663                (push field xref)))
3664            (dolist (field (nth 1 fl))
3665              (push field opt))
3666            (push (list (car entry) nil (nreverse req)
3667                        (nreverse xref) (nreverse opt))
3668                  lst)))
3669        (nreverse lst)))))
3670
3671(defun bibtex-set-dialect (&optional dialect local)
3672  "Select BibTeX DIALECT for editing BibTeX files.
3673This sets the user variable `bibtex-dialect' as well as the dialect-dependent
3674internal variables.  Allowed dialects are listed in `bibtex-dialect-list'.
3675If DIALECT is nil use current value of `bibtex-dialect'.
3676If LOCAL is non-nil make buffer-local bindings for these variables rather than
3677setting the global values.  The dialect-dependent internal variables
3678are also bound buffer-locally if `bibtex-dialect' is already buffer-local
3679in the current buffer (for example, as a file-local variable).
3680LOCAL is t for interactive calls."
3681  (interactive (list (intern (completing-read "Dialect: "
3682                                              (mapcar #'list bibtex-dialect-list)
3683                                              nil t))
3684                     t))
3685  (let ((setfun (if (or local (local-variable-p 'bibtex-dialect))
3686                    (lambda (var val) (set (make-local-variable var) val))
3687                  'set)))
3688    (if dialect (funcall setfun 'bibtex-dialect dialect))
3689
3690    ;; Set internal variables
3691    (funcall setfun 'bibtex-entry-alist (bibtex-entry-alist bibtex-dialect))
3692    (funcall setfun 'bibtex-field-alist
3693             (let ((var (intern (format "bibtex-%s-field-alist"
3694                                        bibtex-dialect))))
3695               (if (boundp var)
3696                   (symbol-value var)
3697                 (user-error "Field types for BibTeX dialect `%s' undefined"
3698                             bibtex-dialect))))
3699    (funcall setfun 'bibtex-entry-type
3700             (concat "@[ \t]*\\(?:"
3701                     (regexp-opt (mapcar #'car bibtex-entry-alist)) "\\)"))
3702    (funcall setfun 'bibtex-entry-head
3703             (concat "^[ \t]*\\(" bibtex-entry-type "\\)[ \t]*[({][ \t\n]*\\("
3704                     bibtex-reference-key "\\)"))
3705    (funcall setfun 'bibtex-entry-maybe-empty-head
3706             (concat bibtex-entry-head "?"))
3707    (funcall setfun 'bibtex-any-valid-entry-type
3708             (concat "^[ \t]*@[ \t]*\\(?:"
3709                     (regexp-opt
3710                      (append '("String" "Preamble")
3711                              (mapcar #'car bibtex-entry-alist))) "\\)"))
3712    (setq imenu-generic-expression
3713          (list (list nil bibtex-entry-head bibtex-key-in-head))
3714          imenu-case-fold-search t)))
3715
3716;; Entry commands and menus for BibTeX dialects
3717;; We do not use `easy-menu-define' here because this gets confused
3718;; if we want to have multiple versions of the "same" menu.
3719(let ((select-map (make-sparse-keymap)))
3720  ;; Submenu for selecting the dialect
3721  (dolist (dialect (reverse bibtex-dialect-list))
3722    (define-key select-map (vector dialect)
3723      `(menu-item ,(symbol-name dialect)
3724                  (lambda () (interactive) (bibtex-set-dialect ',dialect t))
3725                  :button (:radio . (eq bibtex-dialect ',dialect)))))
3726  ;; We define a menu for each dialect.
3727  ;; Then we select the menu we want via the :visible keyword
3728  (dolist (dialect bibtex-dialect-list)
3729    (let ((entry-alist (bibtex-entry-alist dialect))
3730          (menu-map (make-sparse-keymap)))
3731      (define-key menu-map [select]
3732        `(menu-item "BibTeX dialect" ,select-map))
3733      (define-key menu-map [nil-2] '(menu-item "--"))
3734      (define-key menu-map [bibtex-preamble]
3735        '(menu-item "Preamble" bibtex-Preamble))
3736      (define-key menu-map [bibtex-String]
3737        '(menu-item "String" bibtex-String))
3738      (define-key menu-map [nil-1] '(menu-item "--"))
3739      (dolist (elt (reverse entry-alist))
3740        ;; Entry commands
3741        (let* ((entry (car elt))
3742               (fname (intern (format "bibtex-%s" entry))))
3743          (unless (fboundp fname)
3744            (defalias fname
3745              (lambda ()
3746                (:documentation
3747                 (format "Insert a template for a @%s entry; see also `bibtex-entry'."
3748                         entry))
3749                (interactive "*")
3750                (bibtex-entry entry))))
3751          ;; Menu entries
3752          (define-key menu-map (vector fname)
3753            `(menu-item ,(or (nth 1 elt) (car elt)) ,fname))))
3754      (define-key bibtex-mode-map
3755        (vector 'menu-bar dialect)
3756        `(menu-item "Entry-Types" ,menu-map
3757                    :visible (eq bibtex-dialect ',dialect))))))
3758
3759(defun bibtex-field-list (entry-type)
3760  "Return list of allowed fields for entry ENTRY-TYPE.
3761More specifically, the return value is a cons pair (REQUIRED . OPTIONAL),
3762where REQUIRED and OPTIONAL are lists of the required and optional field
3763names for ENTRY-TYPE according to `bibtex-BibTeX-entry-alist' and friends,
3764`bibtex-include-OPTkey', `bibtex-include-OPTcrossref',
3765and `bibtex-user-optional-fields'."
3766  (let ((e-list (assoc-string entry-type bibtex-entry-alist t))
3767        required optional)
3768    (unless e-list
3769      (user-error "Fields for BibTeX entry type %s not defined" entry-type))
3770    (if (member-ignore-case entry-type bibtex-include-OPTcrossref)
3771        (setq required (nth 2 e-list)
3772              optional (append (nth 3 e-list) (nth 4 e-list)))
3773      (setq required  (append (nth 2 e-list) (nth 3 e-list))
3774            optional (nth 4 e-list)))
3775    (if bibtex-include-OPTkey
3776        (push (list "key" "Used as label with certain BibTeX styles"
3777                    (if (or (stringp bibtex-include-OPTkey)
3778                            (functionp bibtex-include-OPTkey))
3779                        bibtex-include-OPTkey))
3780              optional))
3781    (if (member-ignore-case entry-type bibtex-include-OPTcrossref)
3782        (push '("crossref" "Reference key of the cross-referenced entry")
3783              optional))
3784    (setq optional (append optional bibtex-user-optional-fields))
3785    (cons (bibtex--skip-field-aliases required)
3786          (bibtex--skip-field-aliases optional))))
3787
3788(defun bibtex--skip-field-aliases (list)
3789  "Skip fields in LIST that are aliases, return the shortened list.
3790Aliases are fields for which the element ALTERNATIVE is a negative number,
3791see `bibtex-BibTeX-entry-alist'.  The shortened field list is used
3792for the templates of `bibtex-entry', whereas entry validation performed by
3793`bibtex-format-entry' uses the full list of fields for an entry."
3794  ;; FIXME: `bibtex-entry' and `bibtex-format-entry' handle aliases
3795  ;; under the hood in a manner that is largely invisible to users.
3796  ;; If instead one wanted to display the aliases as alternatives
3797  ;; in the usual way, field names may get both the ALT and the OPT prefix.
3798  ;; That gets rather clumsy.  Also, the code currently assumes that
3799  ;; field names have either the ALT or the OPT prefix, but not both.
3800  ;; Are there scenarios when it would be useful to display both?
3801  (let (alt-list new-list)
3802    (dolist (elt list) ; identify alternatives
3803      (if (and (nth 3 elt)
3804               (<= 0 (nth 3 elt)))
3805          (push (nth 3 elt) alt-list)))
3806    (setq alt-list (sort alt-list '<))
3807    ;; Skip aliases.  If ELT is marked as "proper alternative", but all
3808    ;; alternatives for field ELT are aliases, we do not label ELT
3809    ;; as an alternative either.
3810    (dolist (elt list)
3811      (let ((alt (nth 3 elt)))
3812        (if alt
3813            (if (<= 0 alt)
3814                (push (if (eq alt (cadr (memq alt alt-list)))
3815                          elt ; ELT has proper alternatives
3816                        (butlast elt)) ; alternatives of ELT are alias
3817                      new-list))
3818          (push elt new-list))))
3819    (reverse new-list)))
3820
3821(defun bibtex-entry (entry-type)
3822  "Insert a template for a BibTeX entry of type ENTRY-TYPE.
3823After insertion call the value of `bibtex-add-entry-hook' if that value
3824is non-nil."
3825  (interactive
3826   (let ((completion-ignore-case t))
3827     (list (completing-read "Entry Type: " bibtex-entry-alist
3828                            nil t nil 'bibtex-entry-type-history))))
3829  (let ((key (if bibtex-maintain-sorted-entries
3830                 (bibtex-read-key (format "%s key: " entry-type))))
3831        (field-list (bibtex-field-list entry-type)))
3832    (unless (bibtex-prepare-new-entry (list key nil entry-type))
3833      (user-error "Entry with key `%s' already exists" key))
3834    (indent-to-column bibtex-entry-offset)
3835    (insert "@" entry-type (bibtex-entry-left-delimiter))
3836    (if key (insert key))
3837    (save-excursion
3838      (mapc #'bibtex-make-field (car field-list))
3839      (mapc #'bibtex-make-optional-field (cdr field-list))
3840      (if bibtex-comma-after-last-field
3841          (insert ","))
3842      (insert "\n")
3843      (indent-to-column bibtex-entry-offset)
3844      (insert (bibtex-entry-right-delimiter) "\n\n"))
3845    (bibtex-next-field t)
3846    (if (member-ignore-case entry-type bibtex-autofill-types)
3847	(bibtex-autofill-entry))
3848    (run-hooks 'bibtex-add-entry-hook)))
3849
3850(defun bibtex-entry-update (&optional entry-type)
3851  "Update an existing BibTeX entry.
3852In the BibTeX entry at point, make new fields for those items that may occur
3853according to `bibtex-field-list', but are not yet present.
3854Also, add field delimiters to numerical fields if they are not present.
3855If ENTRY-TYPE is non-nil, change first the entry type to ENTRY-TYPE.
3856When called interactively with a prefix arg, query for a value of ENTRY-TYPE."
3857  (interactive
3858   (list (if current-prefix-arg
3859             (let ((completion-ignore-case t))
3860               (completing-read "New entry type: " bibtex-entry-alist
3861                                nil t nil 'bibtex-entry-type-history)))))
3862  (save-excursion
3863    (bibtex-beginning-of-entry)
3864    (when (looking-at bibtex-entry-maybe-empty-head)
3865      (goto-char (match-end 0))
3866      (if entry-type
3867          (save-excursion
3868            (replace-match (concat "@" entry-type) nil nil nil 1))
3869        (setq entry-type (bibtex-type-in-head)))
3870      (let* ((field-list (bibtex-field-list entry-type))
3871             (required (copy-tree (car field-list)))
3872             (optional (copy-tree (cdr field-list)))
3873             bounds)
3874        (while (setq bounds (bibtex-parse-field))
3875          (let ((fname (bibtex-name-in-field bounds t))
3876                (end (copy-marker (bibtex-end-of-field bounds) t)))
3877            (setq required (delete (assoc-string fname required t) required)
3878                  optional (delete (assoc-string fname optional t) optional))
3879            (when (string-match "\\`[0-9]+\\'"
3880                                (bibtex-text-in-field-bounds bounds))
3881              (goto-char (bibtex-end-of-text-in-field bounds))
3882              (insert (bibtex-field-right-delimiter))
3883              (goto-char (bibtex-start-of-text-in-field bounds))
3884              (insert (bibtex-field-left-delimiter)))
3885            (goto-char end)))
3886        (skip-chars-backward " \t\n")
3887        (mapc #'bibtex-make-field required)
3888        (mapc #'bibtex-make-optional-field optional)))))
3889
3890(defun bibtex-parse-entry (&optional content keep-opt-alt)
3891  "Parse entry at point, return an alist.
3892The alist elements have the form (FIELD . TEXT), where FIELD can also be
3893the special strings \"=type=\" and \"=key=\".  For the FIELD \"=key=\"
3894TEXT may be nil.  Move point to the end of the last field.
3895If optional arg CONTENT is non-nil extract content of text fields.
3896Remove \"OPT\" and \"ALT\" from FIELD unless KEEP-OPT-ALT is non-nil."
3897  (let (alist bounds)
3898    (when (looking-at bibtex-entry-maybe-empty-head)
3899      (push (cons "=type=" (bibtex-type-in-head)) alist)
3900      (push (cons "=key=" (bibtex-key-in-head)) alist)
3901      (goto-char (match-end 0))
3902      (while (setq bounds (bibtex-parse-field))
3903	(push (cons (bibtex-name-in-field bounds (not keep-opt-alt))
3904		    (bibtex-text-in-field-bounds bounds content))
3905	      alist)
3906	(goto-char (bibtex-end-of-field bounds))))
3907    (nreverse alist)))
3908
3909(defun bibtex-autofill-entry ()
3910  "Try to fill fields of current BibTeX entry based on neighboring entries.
3911The current entry must have a key.  Determine the neighboring entry
3912\(previous or next) whose key is more similar to the key of the current
3913entry.  For all empty fields of the current entry insert the corresponding
3914field contents of the neighboring entry.  Finally try to update the text
3915based on the difference between the keys of the neighboring and the current
3916entry (for example, the year parts of the keys)."
3917  (interactive)
3918  (bibtex-beginning-of-entry)
3919  (when (looking-at bibtex-entry-head)
3920    (let ((type (bibtex-type-in-head))
3921	  (key (bibtex-key-in-head))
3922	  (key-end (match-end bibtex-key-in-head))
3923          (case-fold-search t)
3924          (bibtex-sort-ignore-string-entries t)
3925	  tmp other-key other bounds)
3926      ;; The fields we want to change start right after the key.
3927      (goto-char key-end)
3928      ;; First see whether to use the previous or the next entry
3929      ;; for "inspiration".
3930      (save-excursion
3931	(goto-char (1- (match-beginning 0)))
3932	(bibtex-beginning-of-entry)
3933	(if (and (looking-at bibtex-entry-head)
3934                 (bibtex-string= type (bibtex-type-in-head))
3935                 ;; In case we found ourselves :-(
3936                 (not (equal key (setq tmp (bibtex-key-in-head)))))
3937	  (setq other-key tmp
3938                other (point))))
3939      (save-excursion
3940	(bibtex-end-of-entry)
3941	(bibtex-skip-to-valid-entry)
3942	(if (and (looking-at bibtex-entry-head)
3943                 (bibtex-string= type (bibtex-type-in-head))
3944                 ;; In case we found ourselves :-(
3945                 (not (equal key (setq tmp (bibtex-key-in-head))))
3946                 (or (not other-key)
3947                     ;; Check which is the best match.
3948                     (< (length (try-completion "" (list key other-key)))
3949                        (length (try-completion "" (list key tmp))))))
3950            (setq other-key tmp
3951                  other (point))))
3952      ;; Then fill the new entry's fields with the chosen other entry.
3953      (when other
3954	(setq other (save-excursion (goto-char other) (bibtex-parse-entry)))
3955	(setq key-end (point))	    ;In case parse-entry changed the buffer.
3956	(while (setq bounds (bibtex-parse-field))
3957	  (let ((text (assoc-string (bibtex-name-in-field bounds t)
3958                                    other t)))
3959	    (if (not (and text
3960                          (equal "" (bibtex-text-in-field-bounds bounds t))))
3961		(goto-char (bibtex-end-of-field bounds))
3962              (goto-char (bibtex-start-of-text-in-field bounds))
3963	      (delete-region (point) (bibtex-end-of-text-in-field bounds))
3964	      (insert (cdr text)))))
3965	;; Finally try to update the text based on the difference between
3966	;; the two keys.
3967	(let* ((prefix (try-completion "" (list key other-key)))
3968	       ;; If the keys are foo91 and foo92, don't replace 1 for 2
3969	       ;; but 91 for 92 instead.
3970	       (_ (if (string-match "[0-9]+\\'" prefix)
3971		      (setq prefix (substring prefix 0 (match-beginning 0)))))
3972	       (suffix (substring key (length prefix)))
3973	       (other-suffix (substring other-key (length prefix))))
3974	  (while (re-search-backward (regexp-quote other-suffix) key-end 'move)
3975	    (replace-match suffix)))))))
3976
3977(defun bibtex-print-help-message (&optional field comma)
3978  "Print helpful information about current FIELD in current BibTeX entry.
3979Optional arg COMMA is as in `bibtex-enclosing-field'.  It is t for
3980interactive calls."
3981  (interactive (list nil t))
3982  (unless field (setq field (car (bibtex-find-text-internal nil nil comma))))
3983  (if (string-search "@" field)
3984      (cond ((bibtex-string= field "@string")
3985             (message "String definition"))
3986            ((bibtex-string= field "@preamble")
3987             (message "Preamble definition"))
3988            (t (message "Entry key")))
3989    (let* ((case-fold-search t)
3990           (type (save-excursion
3991                   (bibtex-beginning-of-entry)
3992                   (looking-at bibtex-entry-maybe-empty-head)
3993                   (bibtex-type-in-head)))
3994           (field-list (bibtex-field-list type))
3995           (comment (assoc-string field (append (car field-list)
3996                                                (cdr field-list)) t)))
3997      (message "%s" (cond ((nth 1 comment) (nth 1 comment))
3998                          ((setq comment (assoc-string field bibtex-field-alist t))
3999                           (nth 1 comment))
4000                          (t "No comment available"))))))
4001
4002(defun bibtex-make-field (field &optional move interactive nodelim)
4003  "Make a field named FIELD in current BibTeX entry.
4004FIELD is either a string or a list of the form
4005\(FIELD-NAME COMMENT-STRING INIT ALTERNATIVE-FLAG) as in
4006`bibtex-BibTeX-entry-alist' and friends.
4007If MOVE is non-nil, move point past the present field before making
4008the new field.  If INTERACTIVE is non-nil, move point to the end of
4009the new field.  Otherwise move point past the new field.
4010MOVE and INTERACTIVE are t when called interactively.
4011INIT is surrounded by field delimiters, unless NODELIM is non-nil."
4012  (interactive
4013   (list (let ((completion-ignore-case t)
4014               (field-list (bibtex-field-list
4015                            (save-excursion
4016                              (bibtex-beginning-of-entry)
4017                              (looking-at bibtex-any-entry-maybe-empty-head)
4018                              (bibtex-type-in-head)))))
4019           (completing-read "BibTeX field name: "
4020                            (append (car field-list) (cdr field-list))
4021                            nil nil nil bibtex-field-history))
4022         t t))
4023  (unless (consp field)
4024    (setq field (list field)))
4025  (when move
4026    (bibtex-find-text)
4027    (if (looking-at "[}\"]")
4028        (forward-char)))
4029  (insert ",\n")
4030  (indent-to-column (+ bibtex-entry-offset bibtex-field-indentation))
4031  ;; If there are multiple sets of alternatives, we could use
4032  ;; the numeric value of (nth 3 field) to number these sets.  Useful??
4033  (if (nth 3 field) (insert "ALT"))
4034  (insert (car field) " ")
4035  (if bibtex-align-at-equal-sign
4036      (indent-to-column (+ bibtex-entry-offset
4037                           (- bibtex-text-indentation 2))))
4038  (insert "= ")
4039  (unless bibtex-align-at-equal-sign
4040    (indent-to-column (+ bibtex-entry-offset
4041                         bibtex-text-indentation)))
4042  (let ((init (nth 2 field)))
4043    (if (not init) (setq init "")
4044      (if (functionp init) (setq init (funcall init)))
4045      (unless (stringp init) (user-error "`%s' is not a string" init)))
4046    ;; NODELIM is required by `bibtex-insert-kill'
4047    (if nodelim (insert init)
4048      (insert (bibtex-field-left-delimiter) init
4049              (bibtex-field-right-delimiter))))
4050  (when interactive
4051    ;; (bibtex-find-text nil nil bibtex-help-message)
4052    (if (memq (preceding-char) '(?} ?\")) (forward-char -1))
4053    (if bibtex-help-message (bibtex-print-help-message (car field)))))
4054
4055(defun bibtex-beginning-of-entry ()
4056  "Move to beginning of BibTeX entry (beginning of line).
4057If inside an entry, move to the beginning of it, otherwise move to the
4058beginning of the previous entry.  If point is ahead of all BibTeX entries
4059move point to the beginning of buffer.  Return the new location of point."
4060  (interactive)
4061  (skip-chars-forward " \t")
4062  (if (looking-at "@")
4063      (forward-char))
4064  (re-search-backward "^[ \t]*@" nil 'move)
4065  (point))
4066
4067(defun bibtex-end-of-entry ()
4068  "Move to end of BibTeX entry (past the closing brace).
4069If inside an entry, move to the end of it, otherwise move to the end
4070of the previous entry.  Do not move if ahead of first entry.
4071Return the new location of point."
4072  (interactive)
4073  (let ((case-fold-search t)
4074        (pnt (point))
4075        (_ (bibtex-beginning-of-entry))
4076        (bounds (bibtex-valid-entry t)))
4077    (cond (bounds (goto-char (cdr bounds))) ; regular entry
4078          ;; @String or @Preamble
4079          ((setq bounds (or (bibtex-parse-string t) (bibtex-parse-preamble)))
4080           (goto-char (bibtex-end-of-string bounds)))
4081          ((looking-at bibtex-any-valid-entry-type)
4082           ;; Parsing of entry failed
4083           (user-error "Syntactically incorrect BibTeX entry starts here"))
4084          (t (if (called-interactively-p 'interactive)
4085		 (message "Not on a known BibTeX entry."))
4086             (goto-char pnt)))
4087    (point)))
4088
4089(defun bibtex-goto-line (arg)
4090  "Goto line ARG, counting from beginning of (narrowed) buffer."
4091  ;; code adapted from `goto-line'
4092  (goto-char (point-min))
4093  (if (eq selective-display t)
4094      (re-search-forward "[\n\C-m]" nil 'end (1- arg))
4095    (forward-line (1- arg))))
4096
4097(defun bibtex-reposition-window (&optional pos)
4098  "Make the current BibTeX entry visible.
4099If entry is smaller than `window-body-height', entry is centered in window.
4100Otherwise display the beginning of entry.
4101Optional arg POS is the position of the BibTeX entry to use."
4102  (interactive)
4103  (if pos (goto-char pos))
4104  (let ((pnt (point))
4105        (beg (line-number-at-pos (bibtex-beginning-of-entry)))
4106        (end (line-number-at-pos (bibtex-end-of-entry))))
4107    (if (> (window-body-height) (- end beg))
4108        ;; entry fits in current window
4109        (progn
4110          (bibtex-goto-line (/ (+ 1 beg end) 2))
4111          (recenter)
4112          (goto-char pnt))
4113      ;; entry too large for current window
4114      (bibtex-goto-line beg)
4115      (recenter 0)
4116      (if (> (1+ (- (line-number-at-pos pnt) beg))
4117             (window-body-height))
4118          (bibtex-goto-line beg)
4119        (goto-char pnt)))))
4120
4121(defun bibtex-mark-entry ()
4122  "Put mark at beginning, point at end of current BibTeX entry.
4123Activate mark in Transient Mark mode."
4124  (interactive)
4125  (push-mark (bibtex-beginning-of-entry) t t)
4126  (bibtex-end-of-entry))
4127
4128(defun bibtex-count-entries (&optional count-string-entries)
4129  "Count number of entries in current buffer or region.
4130With prefix argument COUNT-STRING-ENTRIES count all entries,
4131otherwise count all entries except @String entries.
4132If mark is active count entries in region, if not in whole buffer."
4133  (interactive "P")
4134  (let ((number 0)
4135        (bibtex-sort-ignore-string-entries (not count-string-entries)))
4136    (save-restriction
4137      (if mark-active (narrow-to-region (region-beginning) (region-end)))
4138      (bibtex-map-entries (lambda (_key _beg _end) (setq number (1+ number)))))
4139    (message "%s contains %d entries."
4140             (if mark-active "Region" "Buffer")
4141             number)))
4142
4143(defun bibtex-ispell-entry ()
4144  "Check BibTeX entry for spelling errors."
4145  (interactive)
4146  (ispell-region (save-excursion (bibtex-beginning-of-entry))
4147                 (save-excursion (bibtex-end-of-entry))))
4148
4149(defun bibtex-ispell-abstract ()
4150  "Check abstract of BibTeX entry for spelling errors."
4151  (interactive)
4152  (let ((bounds (save-excursion
4153                  (bibtex-beginning-of-entry)
4154                  (bibtex-search-forward-field "abstract" t))))
4155    (if bounds
4156        (ispell-region (bibtex-start-of-text-in-field bounds)
4157                       (bibtex-end-of-text-in-field bounds))
4158      (user-error "No abstract in entry"))))
4159
4160(defun bibtex-narrow-to-entry ()
4161  "Narrow buffer to current BibTeX entry."
4162  (interactive)
4163  (save-excursion
4164    (widen)
4165    (narrow-to-region (bibtex-beginning-of-entry)
4166                      (bibtex-end-of-entry))))
4167
4168(define-obsolete-function-alias 'bibtex-init-sort-entry-class-alist
4169  #'bibtex-init-sort "28.1")
4170(defun bibtex-init-sort (&optional parse)
4171  "Initialize sorting of BibTeX entries.
4172If PARSE is non-nil, also parse BibTeX keys."
4173  (if (or parse
4174          (and (eq bibtex-maintain-sorted-entries 'crossref)
4175               (functionp bibtex-reference-keys)))
4176      (bibtex-parse-keys))
4177  (unless (local-variable-p 'bibtex-sort-entry-class-alist)
4178    (setq-local bibtex-sort-entry-class-alist
4179                (let ((i -1) alist)
4180                  (dolist (class bibtex-sort-entry-class)
4181                    (setq i (1+ i))
4182                    (dolist (entry class)
4183                      ;; All entry types should be downcase (for ease of comparison).
4184                      (push (cons (if (stringp entry) (downcase entry) entry) i)
4185                            alist)))
4186                  alist)))
4187  ;; Custom sorting scheme
4188  (if (and (consp bibtex-maintain-sorted-entries)
4189           (nth 2 bibtex-maintain-sorted-entries))
4190      (funcall (nth 2 bibtex-maintain-sorted-entries))))
4191
4192(defun bibtex-entry-index ()
4193  "Return index of BibTeX entry head at or past position of point.
4194The index is a list (KEY CROSSREF-KEY ENTRY-TYPE) that is used for sorting
4195the entries of the BibTeX buffer.  CROSSREF-KEY is nil unless the value of
4196`bibtex-maintain-sorted-entries' is `crossref'.
4197If `bibtex-maintain-sorted-entries' is (INDEX-FUN ...), the index is the return
4198value of INDEX-FUN.  Return nil if no entry found.
4199Move point to the end of the head of the entry found."
4200  (let ((case-fold-search t))
4201    (if (re-search-forward bibtex-entry-maybe-empty-head nil t)
4202        (if (consp bibtex-maintain-sorted-entries)
4203            ;; Custom sorting scheme
4204            (funcall (car bibtex-maintain-sorted-entries))
4205          (let ((key (bibtex-key-in-head))
4206                ;; ENTRY-TYPE should be downcase (for ease of comparison)
4207                (entry-type (downcase (bibtex-type-in-head)))
4208                bounds)
4209            (list key
4210                  ;; Don't search CROSSREF-KEY if we don't need it.
4211                  (and (eq bibtex-maintain-sorted-entries 'crossref)
4212                       (setq bounds (bibtex-search-forward-field
4213                                      "\\(OPT\\)?crossref" t))
4214                       (bibtex-text-in-field-bounds bounds t))
4215                  entry-type))))))
4216
4217(defun bibtex-lessp (index1 index2)
4218  "Predicate for sorting BibTeX entries with indices INDEX1 and INDEX2.
4219Each index is a list (KEY CROSSREF-KEY ENTRY-TYPE).
4220The predicate depends on the variable `bibtex-maintain-sorted-entries'.
4221If its value is nil use plain sorting."
4222  (cond ((not index1) (not index2)) ; indices can be nil
4223        ((not index2) nil)
4224        ((consp bibtex-maintain-sorted-entries)
4225         (funcall (cadr bibtex-maintain-sorted-entries) index1 index2))
4226        ((eq bibtex-maintain-sorted-entries 'crossref)
4227         ;; CROSSREF-KEY may be nil or it can point to an entry
4228         ;; in another BibTeX file.  In both cases we ignore CROSSREF-KEY.
4229         (if (and (nth 1 index1)
4230                  (cdr (assoc-string (nth 1 index1) bibtex-reference-keys)))
4231             (if (and (nth 1 index2)
4232                      (cdr (assoc-string (nth 1 index2) bibtex-reference-keys)))
4233                 (or (string-lessp (nth 1 index1) (nth 1 index2))
4234                     (and (string-equal (nth 1 index1) (nth 1 index2))
4235                          (string-lessp (nth 0 index1) (nth 0 index2))))
4236               (not (string-lessp (nth 0 index2) (nth 1 index1))))
4237           (if (and (nth 1 index2)
4238                    (cdr (assoc-string (nth 1 index2) bibtex-reference-keys)))
4239               (string-lessp (nth 0 index1) (nth 1 index2))
4240             (string-lessp (nth 0 index1) (nth 0 index2)))))
4241        ((eq bibtex-maintain-sorted-entries 'entry-class)
4242         (let ((n1 (cdr (or (assoc (nth 2 index1) bibtex-sort-entry-class-alist)
4243                            (assoc 'catch-all bibtex-sort-entry-class-alist)
4244                            '(nil . 1000))))  ; if there is nothing else
4245               (n2 (cdr (or (assoc (nth 2 index2) bibtex-sort-entry-class-alist)
4246                            (assoc 'catch-all bibtex-sort-entry-class-alist)
4247                            '(nil . 1000))))) ; if there is nothing else
4248           (or (< n1 n2)
4249               (and (= n1 n2)
4250                    (string-lessp (car index1) (car index2))))))
4251        (t ; (eq bibtex-maintain-sorted-entries 'plain)
4252         (string-lessp (car index1) (car index2)))))
4253
4254(defun bibtex-sort-buffer ()
4255  "Sort BibTeX buffer alphabetically by key.
4256The predicate for sorting is defined via `bibtex-maintain-sorted-entries'.
4257If its value is nil use plain sorting.  Text outside of BibTeX entries is not
4258affected.  If `bibtex-sort-ignore-string-entries' is non-nil, @String entries
4259are ignored."
4260  (interactive)
4261  (bibtex-beginning-of-first-entry)     ; Needed by `sort-subr'
4262  (bibtex-init-sort)                    ; Needed by `bibtex-lessp'.
4263  (sort-subr nil
4264             'bibtex-skip-to-valid-entry   ; NEXTREC function
4265             'bibtex-end-of-entry          ; ENDREC function
4266             'bibtex-entry-index           ; STARTKEY function
4267             nil                           ; ENDKEY function
4268             'bibtex-lessp))               ; PREDICATE
4269
4270(defun bibtex-search-crossref (crossref-key &optional pnt split noerror)
4271  "Move point to the beginning of BibTeX entry CROSSREF-KEY.
4272If `bibtex-files' is non-nil, search all these files.
4273Otherwise the search is limited to the current buffer.
4274Return position of entry if CROSSREF-KEY is found or nil otherwise.
4275If CROSSREF-KEY is in the same buffer like current entry but before it
4276an error is signaled.  If NOERROR is non-nil this error is suppressed.
4277Optional arg PNT is the position of the referencing entry.  It defaults
4278to position of point.  If optional arg SPLIT is non-nil, split window
4279so that both the referencing and the crossrefed entry are displayed.
4280
4281If called interactively, CROSSREF-KEY defaults to either the crossref key
4282of current entry or a key matched by `bibtex-cite-matcher-alist',
4283whatever is nearer to the position of point.  SPLIT is t.  NOERROR is nil
4284for a crossref key, t otherwise."
4285  (interactive
4286   (save-excursion
4287     (let* ((pnt (point))
4288            (_ (bibtex-beginning-of-entry))
4289            (end (cdr (bibtex-valid-entry t)))
4290            (_ (unless end (user-error "Not inside valid entry")))
4291            (beg (match-end 0)) ; set by `bibtex-valid-entry'
4292            (bounds (bibtex-search-forward-field "\\(OPT\\)?crossref" end))
4293            case-fold-search best temp crossref-key)
4294       (if bounds
4295           (setq crossref-key (bibtex-text-in-field-bounds bounds t)
4296                 best (cons (bibtex-dist pnt (bibtex-end-of-field bounds)
4297                                         (bibtex-start-of-field bounds))
4298                            crossref-key)))
4299       (dolist (matcher bibtex-cite-matcher-alist)
4300         (goto-char beg)
4301         (while (re-search-forward (car matcher) end t)
4302           (setq temp (bibtex-dist pnt (match-end (cdr matcher))
4303                                   (match-beginning (cdr matcher))))
4304           ;; Accept the key closest to the position of point.
4305           (if (or (not best) (< temp (car best)))
4306               (setq best (cons temp (match-string-no-properties
4307                                      (cdr matcher)))))))
4308       (goto-char pnt)
4309       (setq temp (bibtex-read-key "Find crossref key: " (cdr best) t))
4310       (list temp (point) t (not (and crossref-key
4311                                      (string= temp crossref-key)))))))
4312
4313  (let (buffer pos eqb)
4314    (save-excursion
4315      (setq pos (bibtex-search-entry crossref-key t)
4316            buffer (current-buffer)))
4317    (setq eqb (eq buffer (current-buffer)))
4318    (cond ((not pos)
4319           (if split (message "Crossref key `%s' not found" crossref-key)))
4320          (split ; called (quasi) interactively
4321           (unless pnt (setq pnt (point)))
4322           (goto-char pnt)
4323           (if (and eqb (= pos (save-excursion (bibtex-beginning-of-entry))))
4324               (message "Key `%s' is current entry" crossref-key)
4325             (if eqb (select-window (split-window))
4326               (pop-to-buffer buffer))
4327             (bibtex-reposition-window pos)
4328             (beginning-of-line)
4329             (if (and eqb (> pnt pos) (not noerror))
4330                 (user-error "The referencing entry must precede the crossrefed entry"))))
4331          ;; `bibtex-search-crossref' is called noninteractively during
4332          ;; clean-up of an entry.  Then it is not possible to check
4333          ;; whether the current entry and the crossrefed entry have
4334          ;; the correct sorting order.
4335          (eqb (goto-char pos))
4336          (t (set-buffer buffer) (goto-char pos)))
4337    pos))
4338
4339(defun bibtex-dist (pos beg end)
4340  "Return distance between POS and region delimited by BEG and END."
4341  (cond ((and (<= beg pos) (<= pos end)) 0)
4342        ((< pos beg) (- beg pos))
4343        (t (- pos end))))
4344
4345;;;###autoload
4346(defun bibtex-search-entry (key &optional global start display)
4347  "Move point to the beginning of BibTeX entry named KEY.
4348Return position of entry if KEY is found or nil if not found.
4349With GLOBAL non-nil, search KEY in `bibtex-files'.  Otherwise the search
4350is limited to the current buffer.  Optional arg START is buffer position
4351where the search starts.  If it is nil, start search at beginning of buffer.
4352If DISPLAY is non-nil, display the buffer containing KEY.
4353Otherwise, use `set-buffer'.
4354When called interactively, START is nil, DISPLAY is t.
4355Also, GLOBAL is t if the current mode is not `bibtex-mode'
4356or `bibtex-search-entry-globally' is non-nil.
4357A prefix arg negates the value of `bibtex-search-entry-globally'."
4358  (interactive
4359   (let ((global (or (not (eq major-mode 'bibtex-mode))
4360                     (if bibtex-search-entry-globally
4361                         (not current-prefix-arg)
4362                       current-prefix-arg))))
4363     (list (bibtex-read-key "Find key: " nil global) global nil t)))
4364  (if (and global bibtex-files)
4365      (let ((buffer-list (bibtex-initialize t))
4366            buffer found)
4367        (while (and (not found)
4368                    (setq buffer (pop buffer-list)))
4369          (with-current-buffer buffer
4370            (if (cdr (assoc-string key bibtex-reference-keys))
4371                (setq found (bibtex-search-entry key)))))
4372        (cond ((and found display)
4373               ;; If possible, reuse the window displaying BUFFER.
4374               (let ((window (get-buffer-window buffer t)))
4375                 (if window
4376                     (progn
4377                       (select-frame-set-input-focus (window-frame window))
4378                       (select-window window))
4379	           (switch-to-buffer buffer)))
4380	       (bibtex-reposition-window found))
4381              (found (set-buffer buffer))
4382              (display (message "Key `%s' not found" key)))
4383        found)
4384
4385    (let* ((case-fold-search t)
4386           (pnt (save-excursion
4387                  (goto-char (or start (point-min)))
4388                  (if (re-search-forward (concat "^[ \t]*\\("
4389                                                 bibtex-entry-type
4390                                                 "\\)[ \t]*[({][ \t\n]*\\("
4391                                                 (regexp-quote key)
4392                                                 "\\)[ \t\n]*[,=]")
4393                                         nil t)
4394                      (match-beginning 0)))))
4395      (cond (pnt
4396             (goto-char pnt)
4397             (if display (bibtex-reposition-window)))
4398            (display (message "Key `%s' not found" key)))
4399      pnt)))
4400
4401(defun bibtex-prepare-new-entry (index)
4402  "Prepare a new BibTeX entry with index INDEX.
4403INDEX is a list (KEY CROSSREF-KEY ENTRY-TYPE).
4404Move point where the entry KEY should be placed.
4405If `bibtex-maintain-sorted-entries' is non-nil, perform a binary
4406search to look for place for KEY.  This requires that buffer is sorted,
4407see `bibtex-validate'.
4408Return t if preparation was successful or nil if entry KEY already exists."
4409  (bibtex-init-sort)  ; Needed by `bibtex-lessp'.
4410  (let ((key (nth 0 index))
4411        key-exist)
4412    (cond ((or (null key)
4413               (and (stringp key)
4414                    (string-equal key ""))
4415               (and (not (setq key-exist (bibtex-search-entry key)))
4416                    (not bibtex-maintain-sorted-entries)))
4417           (bibtex-move-outside-of-entry))
4418          ;; if key-exist is non-nil due to the previous cond clause
4419          ;; then point will be at beginning of entry named key.
4420          (key-exist)
4421          (t             ; `bibtex-maintain-sorted-entries' is non-nil
4422           (let* ((case-fold-search t)
4423                  (left (save-excursion (bibtex-beginning-of-first-entry)))
4424                  (bounds (save-excursion (goto-char (point-max))
4425                                          (bibtex-skip-to-valid-entry t)))
4426                  (right (if bounds (cdr bounds) (point-min)))
4427                  (found (if (>= left right) left))
4428                  actual-index new)
4429             (save-excursion
4430               ;; Binary search
4431               (while (not found)
4432                 (goto-char (/ (+ left right) 2))
4433                 (bibtex-skip-to-valid-entry t)
4434                 (setq actual-index (bibtex-entry-index))
4435                 (cond ((bibtex-lessp index actual-index)
4436                        (setq new (bibtex-beginning-of-entry))
4437                        (if (equal right new)
4438                            (setq found right)
4439                          (setq right new)))
4440                       (t
4441                        (bibtex-end-of-entry)
4442                        (bibtex-skip-to-valid-entry)
4443                        (setq new (point))
4444                        (if (equal left new)
4445                            (setq found right)
4446                          (setq left new))))))
4447             (goto-char found)
4448             (bibtex-beginning-of-entry)
4449             (setq actual-index (save-excursion (bibtex-entry-index)))
4450             (when (or (not actual-index)
4451                       (bibtex-lessp actual-index index))
4452               ;; buffer contains no valid entries or
4453               ;; greater than last entry --> append
4454               (bibtex-end-of-entry)
4455               (unless (bobp) (newline (forward-line 2)))
4456               (beginning-of-line)))))
4457    (unless key-exist t)))
4458
4459(defun bibtex-validate (&optional test-thoroughly)
4460  "Validate if buffer or region is syntactically correct.
4461Check also for duplicate keys and correct sort order provided
4462`bibtex-maintain-sorted-entries' is non-nil.
4463With optional argument TEST-THOROUGHLY non-nil check also for
4464the absence of required fields and for questionable month fields.
4465If mark is active, validate current region, if not the whole buffer.
4466Only check known entry types, so you can put comments outside of entries.
4467Return t if test was successful, nil otherwise."
4468  (interactive "P")
4469  (let* ((case-fold-search t)
4470         error-list syntax-error)
4471    (save-excursion
4472      (save-restriction
4473        (if mark-active (narrow-to-region (region-beginning) (region-end)))
4474
4475        ;; Check syntactical structure of entries
4476        (goto-char (point-min))
4477        (bibtex-progress-message "Checking syntactical structure")
4478        (let (bounds end)
4479          (while (setq end (re-search-forward "^[ \t]*@" nil t))
4480            (bibtex-progress-message)
4481            (goto-char (match-beginning 0))
4482            (cond ((setq bounds (bibtex-valid-entry))
4483                   (goto-char (cdr bounds)))
4484                  ((setq bounds (or (bibtex-parse-string)
4485                                    (bibtex-parse-preamble)))
4486                   (goto-char (bibtex-end-of-string bounds)))
4487                  ((looking-at bibtex-any-valid-entry-type)
4488                   (push (cons (bibtex-current-line)
4489                               "Syntax error (check esp. commas, braces, and quotes)")
4490                         error-list)
4491                   (goto-char (match-end 0)))
4492                  (t (goto-char end)))))
4493        (bibtex-progress-message 'done)
4494
4495        (if error-list
4496            ;; Continue only if there were no syntax errors.
4497            (setq syntax-error t)
4498
4499          ;; Check for duplicate keys and correct sort order
4500          (bibtex-init-sort t) ; Needed by `bibtex-lessp' and global key check.
4501          (let (previous current key-list)
4502            (bibtex-progress-message "Checking for duplicate keys")
4503            (bibtex-map-entries
4504             (lambda (key _beg _end)
4505               (bibtex-progress-message)
4506               (setq current (bibtex-entry-index))
4507               (cond ((not previous))
4508                     ((member key key-list)
4509                      (push (cons (bibtex-current-line)
4510                                  (format-message "Duplicate key `%s'" key))
4511                            error-list))
4512                     ((and bibtex-maintain-sorted-entries
4513                           (not (bibtex-lessp previous current)))
4514                      (push (cons (bibtex-current-line)
4515                                  "Entries out of order")
4516                            error-list)))
4517               (push key key-list)
4518               (setq previous current)))
4519            (bibtex-progress-message 'done))
4520
4521          ;; Check for duplicate keys in `bibtex-files'.
4522          ;; `bibtex-validate' only compares keys in current buffer with keys
4523          ;; in `bibtex-files'. `bibtex-validate-globally' compares keys for
4524          ;; each file in `bibtex-files' with keys of all other files in
4525          ;; `bibtex-files'.
4526          ;; We don't want to be fooled by outdated `bibtex-reference-keys'.
4527          (dolist (buffer (bibtex-initialize nil t))
4528            (dolist (key (with-current-buffer buffer bibtex-reference-keys))
4529              (when (and (cdr key)
4530                         (cdr (assoc-string (car key) bibtex-reference-keys)))
4531                (bibtex-search-entry (car key))
4532                (push (cons (bibtex-current-line)
4533                            (format-message
4534			     "Duplicate key `%s' in %s" (car key)
4535			     (abbreviate-file-name (buffer-file-name buffer))))
4536                      error-list))))
4537
4538          (when test-thoroughly
4539            (bibtex-progress-message
4540             "Checking required fields and month fields")
4541            (let ((bibtex-sort-ignore-string-entries t))
4542              (bibtex-map-entries
4543               (lambda (_key beg end)
4544                 (bibtex-progress-message)
4545                 (bibtex-beginning-first-field beg)
4546                 (let* ((beg-line (save-excursion (goto-char beg)
4547                                                  (bibtex-current-line)))
4548                        (entry-list (assoc-string (bibtex-type-in-head)
4549                                                  bibtex-entry-alist t))
4550                        (crossref (bibtex-search-forward-field "crossref" end))
4551                        (req (append (nth 2 entry-list)
4552                                     (unless crossref
4553                                       (copy-sequence (nth 3 entry-list)))))
4554                        (opt (append (if crossref (nth 3 entry-list))
4555                                     (nth 4 entry-list)
4556                                     bibtex-user-optional-fields))
4557                        (default (append req opt))
4558                        (num-alt (let ((n 0))
4559                                   (mapc (lambda (x)
4560                                           (if (nth 3 x)
4561                                               (setq n (max n (abs (nth 3 x))))))
4562                                         default)
4563                                   (1+ n)))
4564                        (alt-fields (make-vector num-alt nil))
4565                        bounds field idx)
4566                   (while (setq bounds (bibtex-parse-field))
4567                     (let ((field-name (bibtex-name-in-field bounds)))
4568                       (if (and (bibtex-string= field-name "month")
4569                                ;; Check only abbreviated month fields.
4570                                (let ((month (bibtex-text-in-field-bounds bounds)))
4571                                  (not (or (string-match "\\`[\"{].+[\"}]\\'" month)
4572                                           (assoc-string
4573                                            month
4574                                            bibtex-predefined-month-strings t)))))
4575                           (push (cons (bibtex-current-line)
4576                                       "Questionable month field")
4577                                 error-list))
4578                       (setq field (assoc-string field-name default t)
4579                             req (delete field req))
4580                       (if (setq idx (nth 3 field))
4581                           (if (aref alt-fields idx)
4582                               (push (cons (bibtex-current-line)
4583                                           "More than one non-empty alternative")
4584                                     error-list)
4585                             (aset alt-fields idx t))))
4586                     (goto-char (bibtex-end-of-field bounds)))
4587                   (let ((alt-expect (make-vector num-alt nil)))
4588                     (dolist (field req) ; absent required fields
4589                       (if (setq idx (nth 3 field))
4590                           (bibtex-vec-push alt-expect idx (car field))
4591                         (push (cons beg-line
4592                                     (format-message
4593				      "Required field `%s' missing"
4594				      (car field)))
4595                               error-list)))
4596                     (dotimes (idx num-alt)
4597                       (if (and (aref alt-expect idx)
4598                                (not (aref alt-fields idx)))
4599                           (push (cons beg-line
4600                                       (format-message
4601                                        "Alternative fields `%s' missing"
4602                                        (aref alt-expect idx)))
4603                                 error-list))))))))
4604            (bibtex-progress-message 'done)))))
4605
4606    (if error-list
4607        (let ((file (file-name-nondirectory (buffer-file-name)))
4608              (dir default-directory)
4609              (err-buf "*BibTeX validation errors*"))
4610          (setq error-list (sort error-list 'car-less-than-car))
4611          (with-current-buffer (get-buffer-create err-buf)
4612            (setq default-directory dir)
4613            (unless (eq major-mode 'compilation-mode) (compilation-mode))
4614            (let ((inhibit-read-only t))
4615              (delete-region (point-min) (point-max))
4616              (insert (substitute-command-keys
4617		       "BibTeX mode command `bibtex-validate'\n")
4618                      (if syntax-error
4619                          "Maybe undetected errors due to syntax errors.  \
4620Correct and validate again.\n"
4621                        "\n"))
4622              (dolist (err error-list)
4623                (insert (format "%s:%d: %s\n" file (car err) (cdr err))))
4624              (set-buffer-modified-p nil))
4625            (goto-char (point-min))
4626            (forward-line 2)) ; first error message
4627          (display-buffer err-buf)
4628          nil) ; return nil (i.e., buffer is invalid)
4629      (message "%s is syntactically correct"
4630               (if mark-active "Region" "Buffer"))
4631      t))) ; return t (i.e., buffer is valid)
4632
4633(defun bibtex-validate-globally (&optional strings)
4634  "Check for duplicate keys in `bibtex-files'.
4635With optional prefix arg STRINGS, check for duplicate strings, too.
4636Return t if test was successful, nil otherwise."
4637  (interactive "P")
4638  (let ((buffer-list (bibtex-initialize t))
4639        buffer-key-list current-buf current-keys error-list)
4640    ;; Check for duplicate keys within BibTeX buffer
4641    (dolist (buffer buffer-list)
4642      (with-current-buffer buffer
4643        (save-excursion
4644          (let (entry-type key key-list)
4645            (goto-char (point-min))
4646            (while (re-search-forward bibtex-entry-head nil t)
4647              (setq entry-type (bibtex-type-in-head)
4648                    key (bibtex-key-in-head))
4649              (if (or (and strings (bibtex-string= entry-type "string"))
4650                      (assoc-string entry-type bibtex-entry-alist t))
4651                  (if (member key key-list)
4652                      (push (format-message
4653			     "%s:%d: Duplicate key `%s'\n"
4654			     (buffer-file-name)
4655			     (bibtex-current-line) key)
4656                            error-list)
4657                    (push key key-list))))
4658            (push (cons buffer key-list) buffer-key-list)))))
4659
4660    ;; Check for duplicate keys among BibTeX buffers
4661    (while (setq current-buf (pop buffer-list))
4662      (setq current-keys (cdr (assq current-buf buffer-key-list)))
4663      (with-current-buffer current-buf
4664        (dolist (buffer buffer-list)
4665          (dolist (key (cdr (assq buffer buffer-key-list)))
4666            (when (assoc-string key current-keys)
4667              (bibtex-search-entry key)
4668              (push (format-message
4669		     "%s:%d: Duplicate key `%s' in %s\n"
4670		     (buffer-file-name) (bibtex-current-line) key
4671		     (abbreviate-file-name (buffer-file-name buffer)))
4672                    error-list))))))
4673
4674    ;; Process error list
4675    (if error-list
4676        (let ((err-buf "*BibTeX validation errors*"))
4677          (with-current-buffer (get-buffer-create err-buf)
4678            (unless (eq major-mode 'compilation-mode) (compilation-mode))
4679            (let ((inhibit-read-only t))
4680              (delete-region (point-min) (point-max))
4681              (insert (substitute-command-keys
4682		       "BibTeX mode command `bibtex-validate-globally'\n\n"))
4683              (dolist (err (sort error-list 'string-lessp)) (insert err))
4684              (set-buffer-modified-p nil))
4685            (goto-char (point-min))
4686            (forward-line 2)) ; first error message
4687          (display-buffer err-buf)
4688          nil) ; return nil (i.e., buffer is invalid)
4689      (message "No duplicate keys.")
4690      t))) ; return t (i.e., buffer is valid)
4691
4692(defun bibtex-next-field (begin &optional comma)
4693  "Move point to end of text of next BibTeX field or entry head.
4694With prefix BEGIN non-nil, move point to its beginning.  Optional arg COMMA
4695is as in `bibtex-enclosing-field'.  It is t for interactive calls."
4696  (interactive (list current-prefix-arg t))
4697  (let ((bounds (bibtex-find-text-internal t nil comma))
4698        end-of-entry)
4699    (if (not bounds)
4700        (setq end-of-entry t)
4701      (goto-char (nth 3 bounds))
4702      (if (assoc-string (car bounds) '("@String" "@Preamble") t)
4703          (setq end-of-entry t)
4704        ;; BibTeX key or field
4705        (if (looking-at ",[ \t\n]*") (goto-char (match-end 0)))
4706        ;; end of entry
4707        (if (looking-at "[)}][ \t\n]*") (setq end-of-entry t))))
4708    (if (and end-of-entry
4709             (re-search-forward bibtex-any-entry-maybe-empty-head nil t))
4710      (goto-char (match-beginning 0)))
4711    (bibtex-find-text begin nil bibtex-help-message)))
4712
4713(defun bibtex-next-entry (&optional arg)
4714  "Move point ARG entries forward.
4715ARG defaults to one.  Called interactively, ARG is the prefix
4716argument."
4717  (interactive "p")
4718  (bibtex-end-of-entry)
4719  (when (re-search-forward bibtex-entry-maybe-empty-head nil t (or arg 1))
4720    (goto-char (match-beginning 0))))
4721
4722(defun bibtex-previous-entry (&optional arg)
4723  "Move point ARG entries backward.
4724ARG defaults to one.  Called interactively, ARG is the prefix
4725argument."
4726  (interactive "p")
4727  (bibtex-beginning-of-entry)
4728  (when (re-search-backward bibtex-entry-maybe-empty-head nil t (or arg 1))
4729    (goto-char (match-beginning 0))))
4730
4731(defun bibtex-find-text (&optional begin noerror help comma)
4732  "Move point to end of text of current BibTeX field or entry head.
4733With optional prefix BEGIN non-nil, move point to its beginning.
4734Unless NOERROR is non-nil, an error is signaled if point is not
4735on a BibTeX field.  If optional arg HELP is non-nil print help message.
4736When called interactively, the value of HELP is `bibtex-help-message'.
4737Optional arg COMMA is as in `bibtex-enclosing-field'.  It is t for
4738interactive calls."
4739  (interactive (list current-prefix-arg nil bibtex-help-message t))
4740  (let ((bounds (bibtex-find-text-internal t nil comma)))
4741    (cond (bounds
4742           (if begin
4743               (progn (goto-char (nth 1 bounds))
4744                      (if (looking-at "[{\"]")
4745                          (forward-char)))
4746             (goto-char (nth 2 bounds))
4747             (if (memq (preceding-char) '(?} ?\"))
4748                 (forward-char -1)))
4749           (if help (bibtex-print-help-message (car bounds))))
4750          ((not noerror) (user-error "Not on BibTeX field")))))
4751
4752(defun bibtex-find-text-internal (&optional noerror subfield comma)
4753  "Find text part of current BibTeX field or entry head.
4754Return list (NAME START-TEXT END-TEXT END STRING-CONST) with field name
4755or entry type, start and end of text, and end of field or entry head.
4756STRING-CONST is a flag which is non-nil if current subfield delimited by #
4757is a BibTeX string constant.  Return value is nil if field or entry head
4758are not found.
4759If optional arg NOERROR is non-nil, an error message is suppressed
4760if text is not found.  If optional arg SUBFIELD is non-nil START-TEXT
4761and END-TEXT correspond to the current subfield delimited by #.
4762Optional arg COMMA is as in `bibtex-enclosing-field'."
4763  (save-excursion
4764    (let ((pnt (point))
4765          (bounds (bibtex-enclosing-field comma t))
4766          (case-fold-search t)
4767          name start-text end-text end failure done no-sub string-const)
4768      (bibtex-beginning-of-entry)
4769      (cond (bounds
4770             (setq name (bibtex-name-in-field bounds t)
4771                   start-text (bibtex-start-of-text-in-field bounds)
4772                   end-text (bibtex-end-of-text-in-field bounds)
4773                   end (bibtex-end-of-field bounds)))
4774            ;; @String
4775            ((setq bounds (bibtex-parse-string t))
4776             (if (<= pnt (bibtex-end-of-string bounds))
4777                 (setq name "@String" ;; not a field name!
4778                       start-text (bibtex-start-of-text-in-string bounds)
4779                       end-text (bibtex-end-of-text-in-string bounds)
4780                       end (bibtex-end-of-string bounds))
4781               (setq failure t)))
4782            ;; @Preamble
4783            ((setq bounds (bibtex-parse-preamble))
4784             (if (<= pnt (bibtex-end-of-string bounds))
4785                 (setq name "@Preamble" ;; not a field name!
4786                       start-text (bibtex-start-of-text-in-string bounds)
4787                       end-text (bibtex-end-of-text-in-string bounds)
4788                       end (bibtex-end-of-string bounds))
4789               (setq failure t)))
4790            ;; BibTeX head
4791            ((looking-at bibtex-entry-maybe-empty-head)
4792             (goto-char (match-end 0))
4793             (if comma (save-match-data
4794                         (re-search-forward "\\=[ \t\n]*," nil t)))
4795             (if (<= pnt (point))
4796                 (setq name (match-string-no-properties bibtex-type-in-head)
4797                       start-text (or (match-beginning bibtex-key-in-head)
4798                                 (match-end 0))
4799                       end-text (or (match-end bibtex-key-in-head)
4800                               (match-end 0))
4801                       end end-text
4802                       no-sub t) ; subfields do not make sense
4803               (setq failure t)))
4804            (t (setq failure t)))
4805      (when (and subfield (not failure))
4806        (setq failure no-sub)
4807        (unless failure
4808          (goto-char start-text)
4809          (while (not done)
4810            (if (or (prog1 (looking-at bibtex-field-const)
4811                      (setq end-text (match-end 0)
4812                            string-const t))
4813                    (prog1 (setq bounds (bibtex-parse-field-string))
4814                      (setq end-text (cdr bounds)
4815                            string-const nil)))
4816                (progn
4817                  (if (and (<= start-text pnt) (<= pnt end-text))
4818                      (setq done t)
4819                    (goto-char end-text))
4820                  (if (looking-at "[ \t\n]*#[ \t\n]*")
4821                      (setq start-text (goto-char (match-end 0)))))
4822              (setq done t failure t)))))
4823      (cond ((not failure)
4824             (list name start-text end-text end string-const))
4825            ((and no-sub (not noerror))
4826             (user-error "Not on text part of BibTeX field"))
4827            ((not noerror) (user-error "Not on BibTeX field"))))))
4828
4829(defun bibtex-remove-OPT-or-ALT (&optional comma)
4830  "Remove the string starting optional/alternative fields.
4831Align text and go thereafter to end of text.  Optional arg COMMA
4832is as in `bibtex-enclosing-field'.  It is t for interactive calls."
4833  (interactive (list t))
4834  (let ((case-fold-search t)
4835        (bounds (bibtex-enclosing-field comma)))
4836    (save-excursion
4837      (goto-char (bibtex-start-of-name-in-field bounds))
4838      (when (and (looking-at "OPT\\|ALT")
4839                 (not (and bibtex-no-opt-remove-re
4840                           (string-match
4841                            bibtex-no-opt-remove-re
4842                            (buffer-substring-no-properties
4843                             (bibtex-start-of-name-in-field bounds)
4844                             (bibtex-end-of-name-in-field bounds))))))
4845        (delete-region (match-beginning 0) (match-end 0))
4846        ;; make field non-OPT
4847        (search-forward "=")
4848        (forward-char -1)
4849        (delete-horizontal-space)
4850        (if bibtex-align-at-equal-sign
4851            (indent-to-column (- bibtex-text-indentation 2))
4852          (insert " "))
4853        (search-forward "=")
4854        (delete-horizontal-space)
4855        (if bibtex-align-at-equal-sign
4856            (insert " ")
4857          (indent-to-column bibtex-text-indentation))))))
4858
4859(defun bibtex-remove-delimiters (&optional comma)
4860  "Remove \"\" or {} around current BibTeX field text.
4861Optional arg COMMA is as in `bibtex-enclosing-field'.  It is t for
4862interactive calls."
4863  (interactive (list t))
4864  (let ((bounds (bibtex-find-text-internal nil t comma)))
4865    (unless (nth 4 bounds)
4866      (delete-region (1- (nth 2 bounds)) (nth 2 bounds))
4867      (delete-region (nth 1 bounds) (1+ (nth 1 bounds))))))
4868
4869(defun bibtex-kill-field (&optional copy-only comma)
4870  "Kill the entire enclosing BibTeX field.
4871With prefix arg COPY-ONLY, copy the current field to `bibtex-field-kill-ring',
4872but do not actually kill it.  Optional arg COMMA is as in
4873`bibtex-enclosing-field'.  It is t for interactive calls."
4874  (interactive (list current-prefix-arg t))
4875  (save-excursion
4876    (let* ((case-fold-search t)
4877           (bounds (bibtex-enclosing-field comma))
4878           (end (bibtex-end-of-field bounds))
4879           (beg (bibtex-start-of-field bounds)))
4880      (goto-char end)
4881      ;; Preserve white space at end of BibTeX entry
4882      (if (looking-at "[ \t\n]*[)}]")
4883          (progn (skip-chars-backward " \t\n")
4884                 (setq end (point)))
4885        (skip-chars-forward ","))
4886      (push (list (bibtex-name-in-field bounds) nil
4887                  (bibtex-text-in-field-bounds bounds))
4888            bibtex-field-kill-ring)
4889      (if (> (length bibtex-field-kill-ring) bibtex-field-kill-ring-max)
4890          (setcdr (nthcdr (1- bibtex-field-kill-ring-max)
4891                          bibtex-field-kill-ring)
4892                  nil))
4893      (setq bibtex-field-kill-ring-yank-pointer bibtex-field-kill-ring)
4894      (unless copy-only
4895        (delete-region beg end))))
4896  (setq bibtex-last-kill-command 'field))
4897
4898(defun bibtex-copy-field-as-kill (&optional comma)
4899  "Copy the BibTeX field at point to `bibtex-field-kill-ring'.
4900Optional arg COMMA is as in `bibtex-enclosing-field'.  It is t for
4901interactive calls."
4902  (interactive (list t))
4903  (bibtex-kill-field t comma))
4904
4905(defun bibtex-kill-entry (&optional copy-only)
4906  "Kill the entire enclosing BibTeX entry.
4907With prefix arg COPY-ONLY, copy the current entry to `bibtex-entry-kill-ring',
4908but do not actually kill it."
4909  (interactive "P")
4910  (save-excursion
4911    (let* ((case-fold-search t)
4912           (beg (bibtex-beginning-of-entry))
4913           (key (progn (looking-at bibtex-any-entry-maybe-empty-head)
4914                       (bibtex-key-in-head)))
4915           (end (progn (bibtex-end-of-entry)
4916                       (if (re-search-forward
4917                            bibtex-any-entry-maybe-empty-head nil 'move)
4918                           (goto-char (match-beginning 0)))
4919                       (point))))
4920      (push (buffer-substring-no-properties beg end)
4921            bibtex-entry-kill-ring)
4922      (if (> (length bibtex-entry-kill-ring) bibtex-entry-kill-ring-max)
4923          (setcdr (nthcdr (1- bibtex-entry-kill-ring-max)
4924                          bibtex-entry-kill-ring)
4925                  nil))
4926      (setq bibtex-entry-kill-ring-yank-pointer bibtex-entry-kill-ring)
4927      (unless copy-only
4928        (delete-region beg end)
4929        ;; remove key from `bibtex-reference-keys'.
4930        (unless (functionp bibtex-reference-keys)
4931          (setq bibtex-reference-keys
4932                (delete (cons key t) bibtex-reference-keys))))))
4933  (setq bibtex-last-kill-command 'entry))
4934
4935(defun bibtex-copy-entry-as-kill ()
4936  "Copy the entire enclosing BibTeX entry to `bibtex-entry-kill-ring'."
4937  (interactive)
4938  (bibtex-kill-entry t))
4939
4940(defun bibtex-yank (&optional n)
4941  "Reinsert the last BibTeX item.
4942More precisely, reinsert the field or entry killed or yanked most recently.
4943With argument N, reinsert the Nth most recently killed BibTeX item.
4944See also the command \\[bibtex-yank-pop]."
4945  (interactive "*p")
4946  (unless n (setq n 1))
4947  (bibtex-insert-kill (1- n) t)
4948  (setq this-command 'bibtex-yank))
4949
4950(defun bibtex-yank-pop (n)
4951  "Replace just-yanked killed BibTeX item with a different item.
4952This command is allowed only immediately after a `bibtex-yank' or a
4953`bibtex-yank-pop'.  In this case, the region contains a reinserted
4954previously killed BibTeX item.  `bibtex-yank-pop' deletes that item
4955and inserts in its place a different killed BibTeX item.
4956
4957With no argument, the previous kill is inserted.
4958With argument N, insert the Nth previous kill.
4959If N is negative, this is a more recent kill.
4960
4961The sequence of kills wraps around, so that after the oldest one
4962comes the newest one."
4963  (interactive "*p")
4964  (unless (eq last-command 'bibtex-yank)
4965    (user-error "Previous command was not a BibTeX yank"))
4966  (setq this-command 'bibtex-yank)
4967  (let ((inhibit-read-only t) key)
4968    ;; point is at end of yanked entry
4969    (unless (functionp bibtex-reference-keys)
4970      ;; remove key of yanked entry from `bibtex-reference-keys'
4971      (save-excursion
4972        (goto-char (mark t))
4973        (if (and (looking-at bibtex-any-entry-maybe-empty-head)
4974                 (setq key (bibtex-key-in-head)))
4975            (setq bibtex-reference-keys
4976                  (delete (cons key t) bibtex-reference-keys)))))
4977    (delete-region (point) (mark t))
4978    (bibtex-insert-kill n t)))
4979
4980(defun bibtex-empty-field (&optional comma)
4981  "Delete the text part of the current field, replace with empty text.
4982Optional arg COMMA is as in `bibtex-enclosing-field'.  It is t for
4983interactive calls."
4984  (interactive (list t))
4985  (let ((bounds (bibtex-enclosing-field comma)))
4986    (goto-char (bibtex-start-of-text-in-field bounds))
4987    (delete-region (point) (bibtex-end-of-text-in-field bounds))
4988    (insert (bibtex-field-left-delimiter)
4989            (bibtex-field-right-delimiter))
4990    (bibtex-find-text t nil bibtex-help-message)))
4991
4992(defun bibtex-pop-previous (arg)
4993  "Replace text of current field with the similar field in previous entry.
4994With arg, goes up ARG entries.  Repeated, goes up so many times.  May be
4995intermixed with \\[bibtex-pop-next] (bibtex-pop-next)."
4996  (interactive "p")
4997  (bibtex-pop arg 'previous))
4998
4999(defun bibtex-pop-next (arg)
5000  "Replace text of current field with the text of similar field in next entry.
5001With arg, goes down ARG entries.  Repeated, goes down so many times.  May be
5002intermixed with \\[bibtex-pop-previous] (bibtex-pop-previous)."
5003  (interactive "p")
5004  (bibtex-pop arg 'next))
5005
5006(defun bibtex-clean-entry (&optional new-key called-by-reformat)
5007  "Finish editing the current BibTeX entry and clean it up.
5008Check that no required fields are empty and format entry dependent
5009on the value of `bibtex-entry-format'.
5010If the reference key of the entry is empty or a prefix argument is given,
5011calculate a new reference key.  (Note: this works only if fields in entry
5012begin on separate lines prior to calling `bibtex-clean-entry' or if
5013'realign is contained in `bibtex-entry-format'.)
5014Don't call `bibtex-clean-entry' on @Preamble entries.
5015At end of the cleaning process, the functions in
5016`bibtex-clean-entry-hook' are called with region narrowed to entry."
5017  ;; Opt. arg CALLED-BY-REFORMAT is t if `bibtex-clean-entry'
5018  ;; is called by `bibtex-reformat'
5019  (interactive "P")
5020  (let ((case-fold-search t)
5021        (start (bibtex-beginning-of-entry))
5022        (_ (or (looking-at bibtex-any-entry-maybe-empty-head)
5023	       (user-error "Not inside a BibTeX entry")))
5024        (entry-type (bibtex-type-in-head))
5025        (key (bibtex-key-in-head)))
5026    (cond ((bibtex-string= entry-type "preamble")
5027           ;; (bibtex-format-preamble)
5028           (user-error "No clean up of @Preamble entries"))
5029          ((bibtex-string= entry-type "string")
5030           (setq entry-type 'string))
5031          ;; (bibtex-format-string)
5032          (t (bibtex-format-entry)))
5033    ;; set key
5034    (if (or new-key (not key))
5035        (save-excursion
5036          ;; First delete the old key so that a customized algorithm
5037          ;; for generating the new key does not get confused by the
5038          ;; old key.
5039          (re-search-forward (if (eq entry-type 'string)
5040                                 bibtex-string-maybe-empty-head
5041                               bibtex-entry-maybe-empty-head))
5042          (if (match-beginning bibtex-key-in-head)
5043              (delete-region (match-beginning bibtex-key-in-head)
5044                             (match-end bibtex-key-in-head)))
5045          (setq key (bibtex-generate-autokey))
5046          ;; Sometimes `bibtex-generate-autokey' returns an empty string
5047          (if (or bibtex-autokey-edit-before-use (string= "" key))
5048              (setq key (if (eq entry-type 'string)
5049                            (bibtex-read-string-key key)
5050                          (bibtex-read-key "Key to use: " key))))
5051          (insert key)))
5052
5053    (unless called-by-reformat
5054      (let* ((end (save-excursion
5055                    (bibtex-end-of-entry)
5056                    (if (re-search-forward
5057                         bibtex-entry-maybe-empty-head nil 'move)
5058                        (goto-char (match-beginning 0)))
5059                    (point)))
5060             (entry (buffer-substring start end))
5061             ;; include the crossref key in index
5062             (index (let ((bibtex-maintain-sorted-entries 'crossref))
5063                      (bibtex-entry-index))) ; moves point to end of head
5064             error)
5065        ;; sorting
5066        (if (and bibtex-maintain-sorted-entries
5067                 (not (and bibtex-sort-ignore-string-entries
5068                           (eq entry-type 'string))))
5069            (progn
5070              (delete-region start end)
5071              (setq error (not (bibtex-prepare-new-entry index))
5072                    start (point)) ; update start
5073              (save-excursion (insert entry)))
5074          (bibtex-search-entry key)
5075          (setq error (or (/= (point) start)
5076                          (bibtex-search-entry key nil end))))
5077        (if error
5078            (user-error "New inserted entry yields duplicate key"))
5079        (dolist (buffer (bibtex-initialize))
5080          (with-current-buffer buffer
5081            (if (cdr (assoc-string key bibtex-reference-keys))
5082                (user-error "Duplicate key in %s" (buffer-file-name)))))
5083
5084        ;; Only update `bibtex-strings' and `bibtex-reference-keys'
5085        ;; if they have been built already.
5086        (cond ((eq entry-type 'string)
5087               ;; We have a @String entry.
5088               (unless (or (functionp bibtex-strings)
5089                           (assoc key bibtex-strings))
5090                 (push (cons key (bibtex-text-in-string
5091                                  (bibtex-parse-string) t))
5092                       bibtex-strings)))
5093              ;; We have a normal entry.
5094              ((not (functionp bibtex-reference-keys))
5095               (let ((found (assoc key bibtex-reference-keys)))
5096                 (cond ((not found)
5097                        (push (cons key t) bibtex-reference-keys))
5098                       ((not (cdr found))
5099                        ;; Turn a crossref key into a header key
5100                        (setq bibtex-reference-keys
5101                              (cons (cons key t)
5102                                    (delete (list key) bibtex-reference-keys))))))
5103               ;; If entry has a crossref key, it goes into the list
5104               ;; `bibtex-reference-keys', too.
5105               (if (and (nth 1 index)
5106                        (not (assoc (nth 1 index) bibtex-reference-keys)))
5107                   (push (list (nth 1 index)) bibtex-reference-keys)))))
5108
5109      ;; final clean up
5110      (if bibtex-clean-entry-hook
5111          (save-excursion
5112            (save-restriction
5113              (bibtex-narrow-to-entry)
5114              (run-hooks 'bibtex-clean-entry-hook)))))))
5115
5116(defun bibtex-fill-field-bounds (bounds justify &optional move)
5117  "Fill BibTeX field delimited by BOUNDS.
5118If JUSTIFY is non-nil justify as well.
5119If optional arg MOVE is non-nil move point to end of field."
5120  (let ((end-field (copy-marker (bibtex-end-of-field bounds))))
5121    (if (not justify)
5122        (goto-char (bibtex-start-of-text-in-field bounds))
5123      (goto-char (bibtex-start-of-field bounds))
5124      (forward-char) ; leading comma
5125      (bibtex-delete-whitespace)
5126      (insert "\n")
5127      (indent-to-column (+ bibtex-entry-offset
5128                           bibtex-field-indentation))
5129      (re-search-forward "[ \t\n]*=" end-field)
5130      (replace-match "=")
5131      (forward-char -1)
5132      (if bibtex-align-at-equal-sign
5133          (indent-to-column
5134           (+ bibtex-entry-offset (- bibtex-text-indentation 2)))
5135        (insert " "))
5136      (forward-char)
5137      (bibtex-delete-whitespace)
5138      (if bibtex-align-at-equal-sign
5139          (insert " ")
5140        (indent-to-column bibtex-text-indentation)))
5141    ;; Paragraphs within fields are not preserved.  Bother?
5142    (fill-region-as-paragraph (line-beginning-position) end-field
5143                              default-justification nil (point))
5144    (if move (goto-char end-field))))
5145
5146(defun bibtex-fill-field (&optional justify)
5147  "Like \\[fill-paragraph], but fill current BibTeX field.
5148If optional prefix JUSTIFY is non-nil justify as well.
5149In BibTeX mode this function is bound to `fill-paragraph-function'."
5150  (interactive "*P")
5151  (let ((pnt (point-marker))
5152        (bounds (bibtex-enclosing-field t)))
5153    (bibtex-fill-field-bounds bounds justify)
5154    (goto-char pnt)))
5155
5156(defun bibtex-fill-entry ()
5157  "Fill current BibTeX entry.
5158Realign entry, so that every field starts on a separate line.  Field
5159names appear in column `bibtex-field-indentation', field text starts in
5160column `bibtex-text-indentation' and continuation lines start here, too.
5161If `bibtex-align-at-equal-sign' is non-nil, align equal signs, too."
5162  (interactive "*")
5163  (let ((pnt (point-marker))
5164        (beg (bibtex-beginning-of-entry)) ; move point
5165        bounds)
5166    (bibtex-delete-whitespace)
5167    (indent-to-column bibtex-entry-offset)
5168    (bibtex-beginning-first-field beg)
5169    (while (setq bounds (bibtex-parse-field))
5170      (bibtex-fill-field-bounds bounds t t))
5171    (if (looking-at ",")
5172        (forward-char))
5173    (skip-chars-backward " \t\n")
5174    (bibtex-delete-whitespace)
5175    (insert "\n")
5176    (indent-to-column bibtex-entry-offset)
5177    (goto-char pnt)))
5178
5179(defun bibtex-realign ()
5180  "Realign BibTeX entries such that they are separated by one blank line."
5181  (goto-char (point-min))
5182  (let ((case-fold-search t)
5183        (entry-type (concat "[ \t\n]*\\(" bibtex-entry-type "\\)")))
5184    ;; No blank lines prior to the first entry if there no
5185    ;; non-white characters in front of it.
5186    (when (looking-at entry-type)
5187      (replace-match "\\1"))
5188    ;; Entries are separated by one blank line.
5189    (while (re-search-forward entry-type nil t)
5190      (replace-match "\n\n\\1"))
5191    ;; One blank line past the last entry if it is followed by
5192    ;; non-white characters, no blank line otherwise.
5193    (beginning-of-line)
5194    (when (re-search-forward bibtex-entry-type nil t)
5195      (bibtex-end-of-entry)
5196      (bibtex-delete-whitespace)
5197      (open-line (if (eobp) 1 2)))))
5198
5199(defun bibtex-reformat (&optional read-options)
5200  "Reformat all BibTeX entries in buffer or region.
5201Without prefix argument, reformatting is based on `bibtex-entry-format'.
5202With prefix argument, read options for reformatting from minibuffer.
5203With \\[universal-argument] \\[universal-argument] prefix argument, reuse previous answers (if any) again.
5204If mark is active reformat entries in region, if not in whole buffer."
5205  (interactive "*P")
5206  (let* ((pnt (point))
5207         (use-previous-options
5208          (and (equal (prefix-numeric-value read-options) 16)
5209               (or bibtex-reformat-previous-options
5210                   bibtex-reformat-previous-reference-keys)))
5211         (bibtex-entry-format
5212          (cond (read-options
5213                 (if use-previous-options
5214                     bibtex-reformat-previous-options
5215                   (let (answers)
5216                     (map-y-or-n-p
5217                      #'car
5218                      (lambda (option)
5219                        (push (cdr option) answers))
5220                      `(("Realign entries (recommended)? " . realign)
5221                        ("Remove empty optional and alternative fields? " . opts-or-alts)
5222                        ("Remove delimiters around pure numerical fields? " . numerical-fields)
5223                        (,(concat (if bibtex-comma-after-last-field "Insert" "Remove")
5224                                  " comma at end of entry? ")
5225                         . last-comma)
5226                        ("Replace double page dashes by single ones? " . page-dashes)
5227                        ("Delete whitespace at the beginning and end of fields? " . whitespace)
5228                        ("Inherit booktitle? " . inherit-booktitle)
5229                        ("Force delimiters? " . delimiters)
5230                        ("Unify case of entry types and field names? " . unify-case)
5231                        ("Enclose parts of field entries by braces? " . braces)
5232                        ("Replace parts of field entries by string constants? " . strings)
5233                        ("Sort fields? " . sort-fields))
5234                      '("formatting action" "formatting actions" "perform"))
5235                     (setq bibtex-reformat-previous-options (nreverse answers)))))
5236                ;; Do not include required-fields because `bibtex-reformat'
5237                ;; cannot handle the error messages of `bibtex-format-entry'.
5238                ;; Use `bibtex-validate' to check for required fields.
5239                ((eq t bibtex-entry-format)
5240                 '(realign opts-or-alts numerical-fields delimiters
5241                           last-comma page-dashes unify-case inherit-booktitle
5242                           whitespace braces strings sort-fields))
5243                (t
5244                 (cons 'realign (remove 'required-fields bibtex-entry-format)))))
5245         (reformat-reference-keys
5246          (if read-options
5247              (if use-previous-options
5248                  bibtex-reformat-previous-reference-keys
5249                (setq bibtex-reformat-previous-reference-keys
5250                      (y-or-n-p "Generate new reference keys automatically? ")))))
5251         (bibtex-sort-ignore-string-entries t)
5252         bibtex-autokey-edit-before-use)
5253
5254    (save-restriction
5255      (if mark-active (narrow-to-region (region-beginning) (region-end)))
5256      (if (memq 'realign bibtex-entry-format)
5257          (bibtex-realign))
5258      (bibtex-progress-message "Formatting" 1)
5259      (bibtex-map-entries (lambda (_key _beg _end)
5260                            (bibtex-progress-message)
5261                            (bibtex-clean-entry reformat-reference-keys t)))
5262      (bibtex-progress-message 'done))
5263    (when reformat-reference-keys
5264      (kill-local-variable 'bibtex-reference-keys)
5265      (when bibtex-maintain-sorted-entries
5266        (bibtex-progress-message "Sorting" 1)
5267        (bibtex-sort-buffer)
5268        (bibtex-progress-message 'done)))
5269    (goto-char pnt)))
5270
5271(defun bibtex-convert-alien (&optional read-options)
5272  "Make an alien BibTeX buffer fully usable by BibTeX mode.
5273If a file does not conform with all standards used by BibTeX mode,
5274some of the high-level features of BibTeX mode are not available.
5275This function tries to convert current buffer to conform with these standards.
5276With prefix argument READ-OPTIONS non-nil, read options for reformatting
5277entries from minibuffer."
5278  (interactive "*P")
5279  (message "Starting to validate buffer...")
5280  (sit-for 1)
5281  (bibtex-realign)
5282  (deactivate-mark)  ; So `bibtex-validate' works on the whole buffer.
5283  (if (not (let (bibtex-maintain-sorted-entries)
5284             (bibtex-validate)))
5285      (message "Correct errors and call `bibtex-convert-alien' again")
5286    (message "Starting to reformat entries...")
5287    (sit-for 2)
5288    (bibtex-reformat read-options)
5289    (goto-char (point-max))
5290    (message "Buffer is now parsable.  Please save it.")))
5291
5292(define-obsolete-function-alias 'bibtex-complete #'completion-at-point "24.1")
5293(defun bibtex-completion-at-point-function ()
5294  (let ((pnt (point))
5295        (case-fold-search t)
5296        (beg (save-excursion
5297               (re-search-backward "[ \t{\"]")
5298               (forward-char)
5299               (point)))
5300        (end (point))
5301        bounds name compl)
5302    (save-excursion
5303      (if (and (setq bounds (bibtex-enclosing-field nil t))
5304               (>= pnt (bibtex-start-of-text-in-field bounds))
5305               (<= pnt (bibtex-end-of-text-in-field bounds)))
5306          (setq name (bibtex-name-in-field bounds t)
5307                compl (cond ((bibtex-string= name "crossref")
5308                             ;; point is in crossref field
5309                             'crossref-key)
5310                            ((bibtex-string= name "month")
5311                             ;; point is in month field
5312                             bibtex-predefined-month-strings)
5313                            ;; point is in other field
5314                            (t (bibtex-strings))))
5315        (bibtex-beginning-of-entry)
5316        (cond ((setq bounds (bibtex-parse-string t))
5317               ;; point is inside a @String key
5318               (cond ((and (>= pnt (nth 1 (car bounds)))
5319                           (<= pnt (nth 2 (car bounds))))
5320                      (setq compl 'string))
5321                     ;; point is inside a @String field
5322                     ((and (>= pnt (bibtex-start-of-text-in-string bounds))
5323                           (<= pnt (bibtex-end-of-text-in-string bounds)))
5324                      (setq compl (bibtex-strings)))))
5325              ;; point is inside a @Preamble field
5326              ((setq bounds (bibtex-parse-preamble))
5327               (if (and (>= pnt (bibtex-start-of-text-in-string bounds))
5328                        (<= pnt (bibtex-end-of-text-in-string bounds)))
5329                   (setq compl (bibtex-strings))))
5330              ((and (looking-at bibtex-entry-maybe-empty-head)
5331                    ;; point is inside a key
5332                    (or (and (match-beginning bibtex-key-in-head)
5333                             (>= pnt (match-beginning bibtex-key-in-head))
5334                             (<= pnt (match-end bibtex-key-in-head)))
5335                        ;; or point is on empty key
5336                        (and (not (match-beginning bibtex-key-in-head))
5337                             (= pnt (match-end 0)))))
5338               (setq compl 'key)))))
5339
5340    (cond ((eq compl 'key)
5341           ;; Key completion: no cleanup needed.
5342           (list beg end
5343                 (lambda (s p a)
5344                   (let (completion-ignore-case)
5345                     (complete-with-action a (bibtex-global-key-alist) s p)))))
5346
5347          ((eq compl 'crossref-key)
5348           ;; Crossref key completion.
5349           (let* ((buf (current-buffer)))
5350             (list beg end
5351                   (lambda (s p a)
5352                     (cond
5353                      ((eq a 'metadata) '(metadata (category . bibtex-key)))
5354                      (t (let ((completion-ignore-case nil))
5355                           (complete-with-action
5356                            a (bibtex-global-key-alist) s p)))))
5357                   :exit-function (bibtex-complete-crossref-cleanup buf))))
5358
5359          ((eq compl 'string)
5360           ;; String key completion: no cleanup needed.
5361           (list beg end
5362                 (lambda (s p a)
5363                   (let ((completion-ignore-case t))
5364                     (complete-with-action a bibtex-strings s p)))))
5365
5366          (compl
5367           ;; String completion.
5368           (list beg end
5369                 (lambda (s p a)
5370                   (cond
5371                    ((eq a 'metadata) '(metadata (category . bibtex-string)))
5372                    (t (let ((completion-ignore-case t))
5373                         (complete-with-action a compl s p)))))
5374                 :exit-function (bibtex-complete-string-cleanup compl))))))
5375
5376(defun bibtex-String (&optional key)
5377  "Insert a new BibTeX @String entry with key KEY."
5378  (interactive (list (bibtex-read-string-key)))
5379  (let ((bibtex-maintain-sorted-entries
5380         (unless bibtex-sort-ignore-string-entries
5381           bibtex-maintain-sorted-entries))
5382        endpos)
5383    (unless (bibtex-prepare-new-entry (list key nil "String"))
5384      (user-error "Entry with key `%s' already exists" key))
5385    (if (zerop (length key)) (setq key nil))
5386    (indent-to-column bibtex-entry-offset)
5387    (insert "@String"
5388            (bibtex-entry-left-delimiter))
5389    (if key
5390        (insert key)
5391      (setq endpos (point)))
5392    (insert " = "
5393            (bibtex-field-left-delimiter))
5394    (if key
5395        (setq endpos (point)))
5396    (insert (bibtex-field-right-delimiter)
5397            (bibtex-entry-right-delimiter)
5398            "\n")
5399    (goto-char endpos)))
5400
5401(defun bibtex-Preamble ()
5402  "Insert a new BibTeX @Preamble entry."
5403  (interactive "*")
5404  (bibtex-move-outside-of-entry)
5405  (indent-to-column bibtex-entry-offset)
5406  (insert "@Preamble"
5407          (bibtex-entry-left-delimiter)
5408          (bibtex-field-left-delimiter))
5409  (let ((endpos (point)))
5410    (insert (bibtex-field-right-delimiter)
5411            (bibtex-entry-right-delimiter)
5412            "\n")
5413    (goto-char endpos)))
5414
5415(defun bibtex-url (&optional pos no-browse)
5416  "Browse a URL for the BibTeX entry at point.
5417Optional POS is the location of the BibTeX entry.
5418The URL is generated using the schemes defined in `bibtex-generate-url-list'
5419\(see there).  If multiple schemes match for this entry, or the same scheme
5420matches more than once, use the one for which the first step's match is the
5421closest to POS.  The URL is passed to `browse-url' unless NO-BROWSE is t.
5422Return the URL or nil if none can be generated."
5423  (interactive)
5424  (unless pos (setq pos (point)))
5425  (save-excursion
5426    (goto-char pos)
5427    (bibtex-beginning-of-entry)
5428    (let ((end (save-excursion (bibtex-end-of-entry)))
5429          (fields-alist (save-excursion (bibtex-parse-entry t)))
5430          ;; Always ignore case,
5431          (case-fold-search t)
5432          text url scheme obj fmt fl-match)
5433      ;; The return value of `bibtex-parse-entry' (i.e., FIELDS-ALIST)
5434      ;; is always used to generate the URL.  However, if the BibTeX
5435      ;; entry contains more than one URL, we have multiple matches
5436      ;; for the first step defining the generation of the URL.
5437      ;; Therefore, we try to initiate the generation of the URL
5438      ;; based on the match of `bibtex-font-lock-url' that is the
5439      ;; closest to POS.  If that fails (no match found) we try to
5440      ;; initiate the generation of the URL based on the properly
5441      ;; concatenated CONTENT of the field as returned by
5442      ;; `bibtex-text-in-field-bounds'.  The latter approach can
5443      ;; differ from the former because `bibtex-font-lock-url' uses
5444      ;; the buffer itself.
5445      (while (bibtex-font-lock-url end t)
5446        (push (list (bibtex-dist pos (match-beginning 0) (match-end 0))
5447                    (match-beginning 0)
5448                    (buffer-substring-no-properties
5449                     (match-beginning 0) (match-end 0)))
5450              fl-match)
5451        ;; `bibtex-font-lock-url' moves point to end of match.
5452        (forward-char))
5453      (when fl-match
5454        (setq fl-match (car (sort fl-match (lambda (x y) (< (car x) (car y))))))
5455        (goto-char (nth 1 fl-match))
5456        (bibtex-beginning-of-field) (re-search-backward ",")
5457        (let* ((bounds (bibtex-parse-field))
5458               (name (bibtex-name-in-field bounds))
5459               (content (bibtex-text-in-field-bounds bounds t))
5460               (lst bibtex-generate-url-list))
5461          ;; This match can fail when CONTENT differs from text in buffer.
5462          (when (string-match (regexp-quote (nth 2 fl-match)) content)
5463            ;; TEXT is the part of CONTENT that starts with the match
5464            ;; of `bibtex-font-lock-url' we are looking for.
5465            (setq text (substring content (match-beginning 0)))
5466            (while (and (not url) (setq scheme (pop lst)))
5467              ;; Verify the match of `bibtex-font-lock-url' by
5468              ;; comparing with TEXT.
5469              (when (and (bibtex-string= (caar scheme) name)
5470                         (string-match (cdar scheme) text))
5471                (setq url t scheme (cdr scheme)))))))
5472
5473      ;; If the match of `bibtex-font-lock-url' was not approved
5474      ;; parse FIELDS-ALIST, i.e., the output of `bibtex-parse-entry'.
5475      (unless url
5476        (let ((lst bibtex-generate-url-list))
5477          (while (and (not url) (setq scheme (pop lst)))
5478            (when (and (setq text (cdr (assoc-string (caar scheme)
5479                                                      fields-alist t)))
5480                       (string-match (cdar scheme) text))
5481              (setq url t scheme (cdr scheme))))))
5482
5483      (when url
5484        (setq url (if (null scheme) (match-string 0 text)
5485                    (if (stringp (car scheme))
5486                        (setq fmt (pop scheme)))
5487                    (dolist (step scheme)
5488                      ;; In the first STEP, if the field contains multiple
5489                      ;; matches, we want the match the closest to point.
5490                      ;; (if (eq step (car scheme))
5491                      (setq text (cdr (assoc-string (car step) fields-alist t)))
5492                      (if (string-match (nth 1 step) text)
5493                          (push (cond ((functionp (nth 2 step))
5494                                       (funcall (nth 2 step) text))
5495                                      ((numberp (nth 2 step))
5496                                       (match-string (nth 2 step) text))
5497                                      (t
5498                                       (replace-match (nth 2 step) t nil text)))
5499                                obj)
5500                        ;; If SCHEME is set up correctly,
5501                        ;; we should never reach this point
5502                        (error "Match failed: %s" text)))
5503                    (if fmt (apply #'format fmt (nreverse obj))
5504                      (apply #'concat (nreverse obj)))))
5505        (if (called-interactively-p 'interactive) (message "%s" url))
5506        (unless no-browse (browse-url url)))
5507      (if (and (not url) (called-interactively-p 'interactive))
5508	  (message "No URL known."))
5509      url)))
5510
5511;; We could combine multiple search results with set operations
5512;; AND, OR, MINUS, and NOT.  Would this be useful?
5513;; How complicated are searches in real life?
5514;; We could also have other searches such as "publication year newer than...".
5515(defun bibtex-search-entries (field regexp &optional global display)
5516  "Search BibTeX entries for FIELD matching REGEXP.
5517REGEXP may be a regexp to search for.
5518If REGEXP is a function, it is called for each entry with two args,
5519the buffer positions of beginning and end of entry.  Then an entry
5520is accepted if this function returns non-nil.
5521If FIELD is an empty string perform search for REGEXP in whole entry.
5522With GLOBAL non-nil, search in `bibtex-files'.  Otherwise the search
5523is limited to the current buffer.
5524If DISPLAY is non-nil, display search results in `bibtex-search-buffer'.
5525When called interactively, DISPLAY is t.
5526Also, GLOBAL is t if `bibtex-search-entry-globally' is non-nil.
5527A prefix arg negates the value of `bibtex-search-entry-globally'.
5528Return alist with elements (KEY FILE ENTRY),
5529where FILE is the BibTeX file of ENTRY."
5530  (interactive
5531   (list (completing-read
5532          "Field: "
5533          (delete-dups
5534           (apply #'append
5535                  bibtex-user-optional-fields
5536                  (mapcar (lambda (x) (mapcar #'car (apply #'append (nthcdr 2 x))))
5537                          bibtex-entry-alist)))
5538          nil t)
5539         (read-string "Regexp: ")
5540         (if bibtex-search-entry-globally
5541             (not current-prefix-arg)
5542           current-prefix-arg)
5543         t))
5544  (let ((funp (functionp regexp))
5545        entries text file)
5546    ;; If REGEXP is a function, the value of FIELD is ignored anyway.
5547    ;; Yet to ensure the code below does not fail, we make FIELD
5548    ;; a non-empty string.
5549    (if (and funp (string= "" field)) (setq field "unrestricted"))
5550    (dolist (buffer (if (and global bibtex-files)
5551                        (bibtex-initialize t)
5552                      (list (current-buffer))))
5553      (with-current-buffer buffer
5554        (setq file (if buffer-file-name
5555                       (file-name-nondirectory buffer-file-name)
5556                     (buffer-name buffer)))
5557        (save-excursion
5558          (goto-char (point-min))
5559          (if (string= "" field)
5560              ;; Unrestricted search.
5561              (while (re-search-forward regexp nil t)
5562                (save-excursion
5563                  (let ((mbeg (match-beginning 0))
5564                        (mend (match-end 0))
5565                        (beg (bibtex-beginning-of-entry))
5566                        (end (bibtex-end-of-entry))
5567                        key)
5568                    (if (and (<= beg mbeg)
5569                             (<= mend end)
5570                             (progn
5571                               (goto-char beg)
5572                               (looking-at bibtex-entry-head))
5573                             (setq key (bibtex-key-in-head))
5574                             (not (assoc key entries)))
5575                        (push (list key file
5576                                    (buffer-substring-no-properties beg end))
5577                              entries)))))
5578            ;; The following is slow.  But it works reliably even in more
5579            ;; complicated cases with BibTeX string constants and crossrefed
5580            ;; entries.  If you prefer speed over reliability, perform an
5581            ;; unrestricted search.
5582            (bibtex-map-entries
5583             (lambda (key beg end)
5584               (if (and (cond (funp (funcall regexp beg end))
5585                              ((and (setq text (bibtex-text-in-field field t))
5586                                    (string-match regexp text))))
5587                        (not (assoc key entries)))
5588                   (push (list key file
5589                               (buffer-substring-no-properties beg end))
5590                         entries))))))))
5591    (if display
5592        (if entries
5593            (bibtex-display-entries entries)
5594          (message "No BibTeX entries %smatching `%s'"
5595                   (if (string= "" field) ""
5596                     (format-message "with field `%s' " field))
5597                   regexp)))
5598    entries))
5599
5600(defun bibtex-display-entries (entries &optional append)
5601  "Display BibTeX ENTRIES in `bibtex-search-buffer'.
5602ENTRIES is an alist with elements (KEY FILE ENTRY),
5603where FILE is the BibTeX file of ENTRY.
5604If APPEND is non-nil, append ENTRIES to those already displayed."
5605  (pop-to-buffer (get-buffer-create bibtex-search-buffer))
5606  ;; It would be nice if this buffer was editable, though editing
5607  ;; can be meaningful only for individual existing entries
5608  ;; (unlike reordering or creating new entries).
5609  ;; Fancy workaround: Editing commands in the virtual buffer could
5610  ;; jump to the real entry in the real buffer.
5611  (let (buffer-read-only)
5612    (if append (goto-char (point-max)) (erase-buffer))
5613    (dolist (entry (sort entries (lambda (x y) (string< (car x) (car y)))))
5614      (insert "% " (nth 1 entry) "\n" (nth 2 entry) "\n\n")))
5615    ;; `bibtex-sort-buffer' fails with the file names associated with
5616    ;; each entry.  Prior to sorting we could make the file name
5617    ;; a BibTeX field of each entry (using `bibtex-make-field').
5618    ;; Or we could make it a text property that we unfold afterwards.
5619    ;; (bibtex-sort-buffer)
5620  (bibtex-mode)
5621  (set-buffer-modified-p nil)
5622  (setq buffer-read-only t)
5623  (goto-char (point-min)))
5624
5625(define-obsolete-function-alias 'bibtex-find-crossref #'bibtex-search-crossref "29.1")
5626(define-obsolete-function-alias 'bibtex-find-entry #'bibtex-search-entry "29.1")
5627
5628(provide 'bibtex)
5629;;; bibtex.el ends here
5630