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