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