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