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