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