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