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