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