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