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