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