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