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