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