Commit | Line | Data |
---|---|---|
c0274f38 ER |
1 | ;;; bibtex.el --- BibTeX mode for GNU Emacs |
2 | ||
31bc4210 | 3 | ;; Copyright (C) 1992, 1994, 1995, 1996 Free Software Foundation, Inc. |
9750e079 | 4 | |
31bc4210 | 5 | ;; Author: Stefan Schoef <schoef@offis.uni-oldenburg.de> |
2f056143 | 6 | ;; Bengt Martensson <bengt@mathematik.uni-Bremen.de> |
f961a17c ER |
7 | ;; Mark Shapiro <shapiro@corto.inria.fr> |
8 | ;; Mike Newton <newton@gumby.cs.caltech.edu> | |
9 | ;; Aaron Larson <alarson@src.honeywell.com> | |
31bc4210 | 10 | ;; Maintainer: Stefan Schoef <schoef@offis.uni-oldenburg.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 RS |
35 | ;; See documentation for function bibtex-mode (or type "\M-x describe-mode" |
36 | ;; when you are in bibtex-mode). | |
e5167999 | 37 | |
5c69dbfc RS |
38 | ;; Todo: |
39 | ;; Distribute texinfo file. | |
9ae11a89 | 40 | |
5c69dbfc | 41 | ;; Known Bugs: |
cb4ad359 RS |
42 | ;; 1. using regular expressions to match the entire BibTeX entry dies |
43 | ;; on long entries (e.g. those containing abstracts) since | |
44 | ;; the length of regular expression matches is fairly limited. | |
45 | ;; 2. Calling bibtex-find-text in a string entry results in the | |
46 | ;; error message "Can't find enclosing Bibtex field" instead of | |
47 | ;; moving to the empty string. [reported by gernot@cs.unsw.oz.au] | |
e5167999 | 48 | |
31bc4210 | 49 | ;; (current keeper: schoef@offis.uni-oldenburg.de |
5c69dbfc RS |
50 | ;; previous: alarson@src.honeywell.com) |
51 | ||
52 | ;;; Code: | |
b578f267 | 53 | |
5c69dbfc | 54 | ;; User Options: |
e5167999 | 55 | |
cb4ad359 | 56 | (defvar bibtex-field-left-delimiter "{" |
a9cb9b80 RS |
57 | "*Set this to { or \" according to your personal preferences. |
58 | This variable is buffer local.") | |
59 | (make-variable-buffer-local 'bibtex-field-left-delimiter) | |
745bc783 | 60 | |
cb4ad359 | 61 | (defvar bibtex-field-right-delimiter "}" |
a9cb9b80 RS |
62 | "*Set this to } or \" according to your personal preferences. |
63 | This variable is buffer local.") | |
64 | (make-variable-buffer-local 'bibtex-field-right-delimiter) | |
cb4ad359 RS |
65 | |
66 | (defvar bibtex-include-OPTcrossref '("InProceedings" "InCollection") | |
67 | "*All entries listed here will have an OPTcrossref field.") | |
e5167999 | 68 | |
745bc783 | 69 | (defvar bibtex-include-OPTkey t |
d30bfc76 | 70 | "*If non-nil, all entries will have an OPTkey field.") |
cb4ad359 | 71 | |
745bc783 | 72 | (defvar bibtex-include-OPTannote t |
d30bfc76 | 73 | "*If non-nil, all entries will have an OPTannote field.") |
745bc783 | 74 | |
cb4ad359 RS |
75 | (defvar bibtex-mode-user-optional-fields nil |
76 | "*List of optional fields the user wants to have always present. | |
77 | Entries should be lists of strings with two elements (first element = | |
78 | name of the field, second element = comment to appear in the echo area).") | |
79 | ||
80 | (defvar bibtex-clean-entry-zap-empty-opts t | |
81 | "*If non-nil, bibtex-clean-entry will delete all empty optional fields.") | |
82 | ||
83 | (defvar bibtex-sort-ignore-string-entries t | |
0640d7bf | 84 | "*If non-nil, BibTeX @STRING entries are not sort-significant. |
cb4ad359 | 85 | That means they are ignored when determining ordering of the buffer |
0640d7bf KH |
86 | (e.g. sorting, locating alphabetical position for new entries, etc.). |
87 | This variable is buffer local.") | |
88 | (make-variable-buffer-local 'bibtex-sort-ignore-string-entries) | |
e5167999 | 89 | |
d5fbc7c7 | 90 | (defvar bibtex-maintain-sorted-entries nil |
0640d7bf | 91 | "*If non-nil, bibtex-mode maintains all BibTeX entries in sorted order. |
cb4ad359 | 92 | Setting this variable to nil will strip off some comfort (e.g. TAB |
0640d7bf KH |
93 | completion for reference keys in minibuffer, automatic detection of |
94 | duplicates) from bibtex-mode. See also bibtex-sort-ignore-string-entries. | |
95 | This variable is buffer local.") | |
96 | (make-variable-buffer-local 'bibtex-maintain-sorted-entries) | |
9ae11a89 | 97 | |
af6fb89d KH |
98 | (defvar bibtex-parse-keys-timeout auto-save-timeout |
99 | "*Specifies interval for parsing buffer for keys. | |
100 | The buffer is checked every bibtex-parse-keys-timeout seconds if it is | |
101 | modified since last parsing and is parsed if necessary. This is needed | |
102 | only if buffer is maintained sorted (bibtex-maintain-sorted-entries | |
103 | non-nil).") | |
104 | ||
cb4ad359 RS |
105 | (defvar bibtex-entry-field-alist |
106 | '( | |
107 | ("Article" . (((("author" "Author1 [and Author2 ...] [and others]") | |
0640d7bf | 108 | ("title" "Title of the article (BibTeX converts it to lowercase)") |
cb4ad359 RS |
109 | ("journal" "Name of the journal (use string, remove braces)") |
110 | ("year" "Year of publication")) | |
111 | (("volume" "Volume of the journal") | |
112 | ("number" "Number of the journal") | |
113 | ("month" "Month of the publication as a string (remove braces)") | |
114 | ("pages" "Pages in the journal") | |
115 | ("note" "Remarks to be put at the end of the \\bibitem"))) | |
116 | ((("author" "Author1 [and Author2 ...] [and others]") | |
0640d7bf | 117 | ("title" "Title of the article (BibTeX converts it to lowercase)")) |
cb4ad359 RS |
118 | (("journal" "Name of the journal (use string, remove braces)") |
119 | ("year" "Year of publication") | |
120 | ("volume" "Volume of the journal") | |
121 | ("number" "Number of the journal") | |
122 | ("month" "Month of the publication as a string (remove braces)") | |
123 | ("pages" "Pages in the journal") | |
124 | ("note" "Remarks to be put at the end of the \\bibitem"))))) | |
125 | ("Book" . (((("author" "Author1 [and Author2 ...] [and others]") | |
126 | ("title" "Title of the book") | |
127 | ("publisher" "Publishing company") | |
128 | ("year" "Year of publication")) | |
129 | (("editor" "Editor1 [and Editor2 ...] [and others]") | |
130 | ("volume" "Volume of the book in the series") | |
131 | ("number" "Number of the book in a small series (overwritten by volume)") | |
132 | ("series" "Series in which the book appeared") | |
133 | ("address" "Address of the publisher") | |
134 | ("edition" "Edition of the book as a capitalized English word") | |
135 | ("month" "Month of the publication as a string (remove braces)") | |
136 | ("note" "Remarks to be put at the end of the \\bibitem"))))) | |
0640d7bf | 137 | ("Booklet" . (((("title" "Title of the booklet (BibTeX converts it to lowercase)")) |
cb4ad359 RS |
138 | (("author" "Author1 [and Author2 ...] [and others]") |
139 | ("howpublished" "The way in which the booklet was published") | |
140 | ("address" "Address of the publisher") | |
141 | ("year" "Year of publication") | |
142 | ("month" "Month of the publication as a string (remove braces)") | |
143 | ("note" "Remarks to be put at the end of the \\bibitem"))))) | |
144 | ("InBook" . (((("author" "Author1 [and Author2 ...] [and others]") | |
145 | ("title" "Title of the book") | |
146 | ("chapter" "Chapter in the book") | |
147 | ("publisher" "Publishing company") | |
148 | ("year" "Year of publication")) | |
149 | (("editor" "Editor1 [and Editor2 ...] [and others]") | |
150 | ("volume" "Volume of the book in the series") | |
151 | ("number" "Number of the book in a small series (overwritten by volume)") | |
152 | ("series" "Series in which the book appeared") | |
153 | ("address" "Address of the publisher") | |
154 | ("edition" "Edition of the book as a capitalized English word") | |
155 | ("month" "Month of the publication as a string (remove braces)") | |
156 | ("pages" "Pages in the book") | |
157 | ("type" "Word to use instead of \"chapter\"") | |
158 | ("note" "Remarks to be put at the end of the \\bibitem"))) | |
159 | ((("author" "Author1 [and Author2 ...] [and others]") | |
160 | ("title" "Title of the book") | |
161 | ("chapter" "Chapter in the book")) | |
162 | (("publisher" "Publishing company") | |
163 | ("year" "Year of publication") | |
164 | ("editor" "Editor1 [and Editor2 ...] [and others]") | |
165 | ("volume" "Volume of the book in the series") | |
166 | ("number" "Number of the book in a small series (overwritten by volume)") | |
167 | ("series" "Series in which the book appeared") | |
168 | ("address" "Address of the publisher") | |
169 | ("edition" "Edition of the book as a capitalized English word") | |
170 | ("month" "Month of the publication as a string (remove braces)") | |
171 | ("pages" "Pages in the book") | |
172 | ("type" "Word to use instead of \"chapter\"") | |
173 | ("note" "Remarks to be put at the end of the \\bibitem"))))) | |
174 | ("InCollection" . (((("author" "Author1 [and Author2 ...] [and others]") | |
0640d7bf | 175 | ("title" "Title of the article in book (BibTeX converts it to lowercase)") |
cb4ad359 RS |
176 | ("booktitle" "Name of the book") |
177 | ("publisher" "Publishing company") | |
178 | ("year" "Year of publication")) | |
179 | (("editor" "Editor1 [and Editor2 ...] [and others]") | |
180 | ("volume" "Volume of the book in the series") | |
181 | ("number" "Number of the book in a small series (overwritten by volume)") | |
182 | ("series" "Series in which the book appeared") | |
183 | ("chapter" "Chapter in the book") | |
184 | ("type" "Word to use instead of \"chapter\"") | |
185 | ("address" "Address of the publisher") | |
186 | ("edition" "Edition of the book as a capitalized English word") | |
187 | ("month" "Month of the publication as a string (remove braces)") | |
188 | ("pages" "Pages in the book") | |
189 | ("note" "Remarks to be put at the end of the \\bibitem"))) | |
190 | ((("author" "Author1 [and Author2 ...] [and others]") | |
0640d7bf | 191 | ("title" "Title of the article in book (BibTeX converts it to lowercase)") |
cb4ad359 RS |
192 | ("booktitle" "Name of the book")) |
193 | (("publisher" "Publishing company") | |
194 | ("year" "Year of publication") | |
195 | ("editor" "Editor1 [and Editor2 ...] [and others]") | |
196 | ("volume" "Volume of the book in the series") | |
197 | ("number" "Number of the book in a small series (overwritten by volume)") | |
198 | ("series" "Series in which the book appeared") | |
199 | ("chapter" "Chapter in the book") | |
200 | ("type" "Word to use instead of \"chapter\"") | |
201 | ("address" "Address of the publisher") | |
202 | ("edition" "Edition of the book as a capitalized English word") | |
203 | ("month" "Month of the publication as a string (remove braces)") | |
204 | ("pages" "Pages in the book") | |
205 | ("note" "Remarks to be put at the end of the \\bibitem"))))) | |
206 | ("InProceedings" . (((("author" "Author1 [and Author2 ...] [and others]") | |
0640d7bf | 207 | ("title" "Title of the article in proceedings (BibTeX converts it to lowercase)") |
cb4ad359 RS |
208 | ("booktitle" "Name of the conference proceedings") |
209 | ("year" "Year of publication")) | |
210 | (("editor" "Editor1 [and Editor2 ...] [and others]") | |
211 | ("volume" "Volume of the conference proceedings in the series") | |
212 | ("number" "Number of the conference proceedings in a small series (overwritten by volume)") | |
213 | ("series" "Series in which the conference proceedings appeared") | |
214 | ("organization" "Sponsoring organization of the conference") | |
215 | ("publisher" "Publishing company, its location") | |
216 | ("address" "Location of the Proceedings") | |
217 | ("month" "Month of the publication as a string (remove braces)") | |
218 | ("pages" "Pages in the conference proceedings") | |
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 in proceedings (BibTeX converts it to lowercase)") |
cb4ad359 RS |
222 | ("booktitle" "Name of the conference proceedings")) |
223 | (("editor" "Editor1 [and Editor2 ...] [and others]") | |
224 | ("volume" "Volume of the conference proceedings in the series") | |
225 | ("number" "Number of the conference proceedings in a small series (overwritten by volume)") | |
226 | ("series" "Series in which the conference proceedings appeared") | |
227 | ("year" "Year of publication") | |
228 | ("organization" "Sponsoring organization of the conference") | |
229 | ("publisher" "Publishing company, its location") | |
230 | ("address" "Location of the Proceedings") | |
231 | ("month" "Month of the publication as a string (remove braces)") | |
232 | ("pages" "Pages in the conference proceedings") | |
233 | ("note" "Remarks to be put at the end of the \\bibitem"))))) | |
234 | ("Manual" . (((("title" "Title of the manual")) | |
235 | (("author" "Author1 [and Author2 ...] [and others]") | |
236 | ("organization" "Publishing organization of the manual") | |
237 | ("address" "Address of the organization") | |
238 | ("edition" "Edition of the manual as a capitalized English word") | |
239 | ("year" "Year of publication") | |
240 | ("month" "Month of the publication as a string (remove braces)") | |
241 | ("note" "Remarks to be put at the end of the \\bibitem"))))) | |
242 | ||
243 | ("MastersThesis" . (((("author" "Author1 [and Author2 ...] [and others]") | |
0640d7bf | 244 | ("title" "Title of the master\'s thesis (BibTeX converts it to lowercase)") |
cb4ad359 RS |
245 | ("school" "School where the master\'s thesis was written") |
246 | ("year" "Year of publication")) | |
247 | (("address" "Address of the school (if not part of field \"school\") or country") | |
248 | ("type" "Type of the master\'s thesis") | |
249 | ("month" "Month of the publication as a string (remove braces)") | |
250 | ("note" "Remarks to be put at the end of the \\bibitem"))))) | |
251 | ("Misc" . ((() | |
252 | (("author" "Author1 [and Author2 ...] [and others]") | |
0640d7bf | 253 | ("title" "Title of the reference (BibTeX converts it to lowercase)") |
cb4ad359 RS |
254 | ("howpublished" "The way in which the reference was published") |
255 | ("year" "Year of publication") | |
256 | ("month" "Month of the publication as a string (remove braces)") | |
257 | ("note" "Remarks to be put at the end of the \\bibitem"))))) | |
258 | ("PhdThesis" . (((("author" "Author1 [and Author2 ...] [and others]") | |
259 | ("title" "Title of the PhD. thesis") | |
260 | ("school" "School where the PhD. thesis was written") | |
261 | ("year" "Year of publication")) | |
262 | (("address" "Address of the school (if not part of field \"school\") or country") | |
263 | ("type" "Type of the PhD. thesis") | |
264 | ("month" "Month of the publication as a string (remove braces)") | |
265 | ("note" "Remarks to be put at the end of the \\bibitem"))))) | |
266 | ("Proceedings" . (((("title" "Title of the conference proceedings") | |
267 | ("year" "Year of publication")) | |
268 | (("editor" "Editor1 [and Editor2 ...] [and others]") | |
269 | ("volume" "Volume of the conference proceedings in the series") | |
270 | ("number" "Number of the conference proceedings in a small series (overwritten by volume)") | |
271 | ("series" "Series in which the conference proceedings appeared") | |
272 | ("publisher" "Publishing company, its location") | |
273 | ("organization" "Sponsoring organization of the conference") | |
274 | ("address" "Location of the Proceedings") | |
275 | ("month" "Month of the publication as a string (remove braces)") | |
276 | ("note" "Remarks to be put at the end of the \\bibitem"))))) | |
277 | ("TechReport" . (((("author" "Author1 [and Author2 ...] [and others]") | |
0640d7bf | 278 | ("title" "Title of the technical report (BibTeX converts it to lowercase)") |
cb4ad359 RS |
279 | ("institution" "Sponsoring institution of the report") |
280 | ("year" "Year of publication")) | |
281 | (("type" "Type of the report (if other than \"technical report\")") | |
282 | ("number" "Number of the technical report") | |
283 | ("address" "Address of the institution (if not part of field \"institution\") or country") | |
284 | ("month" "Month of the publication as a string (remove braces)") | |
285 | ("note" "Remarks to be put at the end of the \\bibitem"))))) | |
286 | ("Unpublished" . (((("author" "Author1 [and Author2 ...] [and others]") | |
0640d7bf | 287 | ("title" "Title of the unpublished reference (BibTeX converts it to lowercase)") |
cb4ad359 RS |
288 | ("note" "Remarks to be put at the end of the \\bibitem")) |
289 | (("year" "Year of publication") | |
290 | ("month" "Month of the publication as a string (remove braces)"))))) | |
291 | ) | |
292 | ||
293 | "Defines reference types and their associated fields. | |
294 | List of | |
295 | (entry-name (required optional) (crossref-required crossref-optional)) | |
296 | triples. | |
297 | If the third element is nil, the first pair is always to be used. | |
298 | If not, the second pair is to be used in the case of presence of a | |
299 | crossref field and the third in the case of absence. | |
300 | Required , optional, crossref-required and crossref-optional are lists. | |
301 | Each element of these lists is a list of strings with two elements | |
302 | (first element = name of the field, | |
303 | second element = comment to appear in the echo area).") | |
304 | ||
305 | (defvar bibtex-predefined-strings | |
306 | '( | |
307 | ("jan") ("feb") ("mar") ("apr") ("may") ("jun") ("jul") ("aug") | |
308 | ("sep") ("oct") ("nov") ("dec") | |
309 | ("acmcs") ("acta") ("cacm") ("ibmjrd") ("ibmsj") ("ieeese") | |
310 | ("ieeetc") ("ieeetcad") ("ipl") ("jacm") ("jcss") ("scp") | |
311 | ("sicomp") ("tcs") ("tocs") ("tods") ("tog") ("toms") ("toois") | |
312 | ("toplas") | |
313 | ) | |
314 | "Alist of string definitions. | |
315 | Should contain the strings defined in the BibTeX style files. Each | |
316 | element is a list with just one element: the string.") | |
317 | ||
318 | (defvar bibtex-string-files nil | |
319 | "*List of BibTeX files containing string definitions. | |
320 | Those files must be specified using pathnames relative to the | |
321 | directories specified in $BIBINPUTS. This variable is only evaluated | |
322 | when bibtex-mode is entered (i. e. when loading the BibTeX file).") | |
323 | ||
324 | (defvar bibtex-help-message t | |
325 | "*If not nil print help messages in the echo area on entering a new field.") | |
326 | ||
327 | (defvar bibtex-autokey-names 1 | |
328 | "*Number of names to use for the automatically generated reference key. | |
329 | If this is set to anything but a number, all names are used. | |
330 | See the documentation of function bibtex-generate-autokey for further detail.") | |
331 | ||
332 | (defvar bibtex-autokey-name-change-strings | |
333 | '(("\\\\\\\"a" "ae") ("\\\\\\\"o" "oe") ("\\\\\\\"u" "ue") | |
334 | ("\\\\\\\"s" "ss") | |
335 | ("\\\\\\\"A" "Ae") ("\\\\\\\"O" "Oe") ("\\\\\\\"U" "Ue") | |
af6fb89d KH |
336 | ("\\\"a" "ae") ("\\\"o" "oe") ("\\\"u" "ue") ("\\\"s" "ss") |
337 | ("\\\"A" "Ae") ("\\\"O" "Oe") ("\\\"U" "Ue") | |
cb4ad359 RS |
338 | ("{" "") ("}" "")) |
339 | "Alist of (old-regexp new-string) pairs. | |
340 | Any part of name matching a old-regexp is replaced by new-string. | |
341 | Case of the old-regexp is significant. All regexps are tried in the | |
342 | order in which they appear in the list, so be sure to avoid recursion here. | |
343 | See the documentation of function bibtex-generate-autokey for further detail.") | |
344 | ||
345 | (defvar bibtex-autokey-name-length 'infty | |
346 | "*Number of characters from name to incorporate into key. | |
347 | If this is set to anything but a number, all characters are used. | |
348 | See the documentation of function bibtex-generate-autokey for further detail.") | |
349 | ||
350 | (defvar bibtex-autokey-name-separator "" | |
351 | "*String that comes between any two names in the key. | |
352 | See the documentation of function bibtex-generate-autokey for further detail.") | |
353 | ||
354 | (defvar bibtex-autokey-year-length 2 | |
355 | "*Number of rightmost digits from the year field yo incorporate into key. | |
356 | See the documentation of function bibtex-generate-autokey for further detail.") | |
357 | ||
358 | (defvar bibtex-autokey-titlewords 5 | |
359 | "*Number of title words to use for the automatically generated reference key. | |
360 | If this is set to anything but a number, all title words are used. | |
361 | See the documentation of function bibtex-generate-autokey for further detail.") | |
362 | ||
363 | (defvar bibtex-autokey-title-terminators | |
364 | '("\\." "!" "\\?" ":" ";" "---") | |
365 | "*Regexp list defining the termination of the main part of the title. | |
366 | Case of the regexps is ignored. | |
367 | See the documentation of function bibtex-generate-autokey for further detail.") | |
368 | ||
369 | (defvar bibtex-autokey-titlewords-stretch 2 | |
370 | "*Number of words that can additionally be used from the title. | |
371 | These words are used only, if a sentence from the title can be ended then. | |
372 | See the documentation of function bibtex-generate-autokey for further detail.") | |
373 | ||
374 | (defvar bibtex-autokey-titleword-first-ignore | |
375 | '("a" "an" "on" "the" "eine?" "der" "die" "das") | |
376 | "*Determines words that may begin a title but are not to be used in the key. | |
377 | Each item of the list is a regexp. If the first word of the title matchs a | |
378 | regexp from that list, it is not included in the title, even if it is | |
379 | capitalized. Regexps in the list must be entered using lowercase letters.") | |
380 | ||
381 | (defvar bibtex-autokey-titleword-abbrevs nil | |
382 | "*Determines exceptions to the usual abbreviation mechanism. | |
383 | A list of (old-regexp new-string) pairs. | |
384 | Use all lowercase letters for old-regexp. | |
385 | See the documentation of function bibtex-generate-autokey for further detail.") | |
386 | ||
387 | (defvar bibtex-autokey-titleword-change-strings | |
388 | '(("\\\\\\\"a" "ae") ("\\\\\\\"o" "oe") ("\\\\\\\"u" "ue") | |
389 | ("\\\\\\\"s" "ss") | |
390 | ("\\\\\\\"A" "Ae") ("\\\\\\\"O" "Oe") ("\\\\\\\"U" "Ue") | |
af6fb89d KH |
391 | ("\\\"a" "ae") ("\\\"o" "oe") ("\\\"u" "ue") ("\\\"s" "ss") |
392 | ("\\\"A" "Ae") ("\\\"O" "Oe") ("\\\"U" "Ue") | |
cb4ad359 RS |
393 | ("{" "") ("}" "")) |
394 | "Alist of (old-regexp new-string) pairs. | |
395 | Any part of title word matching a old-regexp is replaced by new-string. | |
396 | Case of the old-regexp is significant. | |
397 | See the documentation of function bibtex-generate-autokey for further detail.") | |
398 | ||
399 | (defvar bibtex-autokey-titleword-length 5 | |
400 | "*Number of characters from title words to incorporate into key. | |
401 | If this is set to anything but a number, all characters are used. | |
402 | See the documentation of function bibtex-generate-autokey for further detail.") | |
403 | ||
404 | (defvar bibtex-autokey-titleword-separator "_" | |
405 | "*String to be put between the title words. | |
406 | See the documentation of function bibtex-generate-autokey for further detail.") | |
407 | ||
408 | (defvar bibtex-autokey-name-year-separator "" | |
409 | "*String to be put between name part and year part of key. | |
410 | See the documentation of function bibtex-generate-autokey for further detail.") | |
411 | ||
412 | (defvar bibtex-autokey-year-title-separator ":_" | |
413 | "*String to be put between name part and year part of key. | |
414 | See the documentation of function bibtex-generate-autokey for further detail.") | |
415 | ||
416 | (defvar bibtex-autokey-edit-before-use t | |
417 | "*If non-nil, user is allowed to edit the generated key before it is used.") | |
418 | ||
31bc4210 RS |
419 | ;; bibtex-font-lock-keywords is a user option as well, but since the |
420 | ;; patterns used to define this variable are defined in a later | |
421 | ;; section of this file, its definition comes later. | |
422 | ||
cb4ad359 | 423 | \f |
5c69dbfc | 424 | ;; Syntax Table, Keybindings and BibTeX Entry List |
9ae11a89 ER |
425 | (defvar bibtex-mode-syntax-table |
426 | (let ((st (make-syntax-table))) | |
af6fb89d KH |
427 | (modify-syntax-entry ?\" "w" st) |
428 | ;; this was formerly "\"". Does this cause any problems? | |
9ae11a89 ER |
429 | (modify-syntax-entry ?$ "$$ " st) |
430 | (modify-syntax-entry ?% "< " st) | |
431 | (modify-syntax-entry ?' "w " st) | |
432 | (modify-syntax-entry ?@ "w " st) | |
433 | (modify-syntax-entry ?\\ "\\" st) | |
434 | (modify-syntax-entry ?\f "> " st) | |
435 | (modify-syntax-entry ?\n "> " st) | |
436 | (modify-syntax-entry ?~ " " st) | |
437 | st)) | |
438 | ||
9ae11a89 ER |
439 | (defvar bibtex-mode-map |
440 | (let ((km (make-sparse-keymap))) | |
441 | ||
442 | (define-key km "\t" 'bibtex-find-text) | |
443 | (define-key km "\n" 'bibtex-next-field) | |
cb4ad359 RS |
444 | (define-key km "\M-\t" 'bibtex-complete-string) |
445 | (define-key km "\C-c\"" 'bibtex-remove-double-quotes-or-braces) | |
446 | (define-key km "\C-c{" 'bibtex-remove-double-quotes-or-braces) | |
447 | (define-key km "\C-c}" 'bibtex-remove-double-quotes-or-braces) | |
9ae11a89 | 448 | (define-key km "\C-c\C-c" 'bibtex-clean-entry) |
cb4ad359 | 449 | (define-key km "\C-c?" 'bibtex-print-help-message) |
9ae11a89 ER |
450 | (define-key km "\C-c\C-p" 'bibtex-pop-previous) |
451 | (define-key km "\C-c\C-n" 'bibtex-pop-next) | |
452 | (define-key km "\C-c\C-k" 'bibtex-kill-optional-field) | |
453 | (define-key km "\C-c\C-d" 'bibtex-empty-field) | |
cb4ad359 RS |
454 | (define-key km "\C-c$" 'bibtex-ispell-entry) |
455 | (define-key km "\M-\C-a" 'bibtex-beginning-of-entry) | |
456 | (define-key km "\M-\C-e" 'bibtex-end-of-entry) | |
1d7158ce | 457 | (define-key km "\C-c\C-b" 'bibtex-entry) |
cb4ad359 | 458 | (define-key km "\C-c\C-q" 'bibtex-hide-entry-bodies) |
cb4ad359 RS |
459 | (define-key km "\C-c\C-rn" 'bibtex-narrow-to-entry) |
460 | (define-key km "\C-c\C-rw" 'widen) | |
461 | (define-key km "\C-c\C-o" 'bibtex-remove-OPT) | |
9ae11a89 | 462 | |
cb4ad359 | 463 | (define-key km "\C-c\C-e\C-i" 'bibtex-InProceedings) |
9ae11a89 | 464 | (define-key km "\C-c\C-ei" 'bibtex-InCollection) |
cb4ad359 RS |
465 | (define-key km "\C-c\C-eI" 'bibtex-InBook) |
466 | (define-key km "\C-c\C-e\C-a" 'bibtex-Article) | |
467 | (define-key km "\C-c\C-e\C-b" 'bibtex-InBook) | |
468 | (define-key km "\C-c\C-eb" 'bibtex-Book) | |
469 | (define-key km "\C-c\C-eB" 'bibtex-Booklet) | |
470 | (define-key km "\C-c\C-e\C-c" 'bibtex-InCollection) | |
9ae11a89 ER |
471 | (define-key km "\C-c\C-e\C-m" 'bibtex-Manual) |
472 | (define-key km "\C-c\C-em" 'bibtex-MastersThesis) | |
473 | (define-key km "\C-c\C-eM" 'bibtex-Misc) | |
cb4ad359 | 474 | (define-key km "\C-c\C-e\C-p" 'bibtex-InProceedings) |
9ae11a89 | 475 | (define-key km "\C-c\C-ep" 'bibtex-Proceedings) |
cb4ad359 RS |
476 | (define-key km "\C-c\C-eP" 'bibtex-PhdThesis) |
477 | (define-key km "\C-c\C-e\M-p" 'bibtex-preamble) | |
9ae11a89 | 478 | (define-key km "\C-c\C-e\C-s" 'bibtex-string) |
cb4ad359 | 479 | (define-key km "\C-c\C-e\C-t" 'bibtex-TechReport) |
9ae11a89 ER |
480 | (define-key km "\C-c\C-e\C-u" 'bibtex-Unpublished) |
481 | km)) | |
482 | ||
0640d7bf | 483 | (define-key bibtex-mode-map [menu-bar bibtex-edit] |
cb4ad359 | 484 | (cons "BibTeX-Edit" (make-sparse-keymap "BibTeX-Edit"))) |
0640d7bf | 485 | (define-key bibtex-mode-map [menu-bar bibtex-edit bibtex-print-help-message] |
1def9aec | 486 | '("Help about Current Field" . bibtex-print-help-message)) |
0640d7bf | 487 | (define-key bibtex-mode-map [menu-bar bibtex-edit bibtex-complete-string] |
cb4ad359 | 488 | '("String Complete" . bibtex-complete-string)) |
0640d7bf | 489 | (define-key bibtex-mode-map [menu-bar bibtex-edit bibtex-next-field] |
cb4ad359 | 490 | '("Next Field" . bibtex-next-field)) |
0640d7bf | 491 | (define-key bibtex-mode-map [menu-bar bibtex-edit bibtex-find-text] |
cb4ad359 | 492 | '("End of Field" . bibtex-find-text)) |
0640d7bf | 493 | (define-key bibtex-mode-map [menu-bar bibtex-edit bibtex-pop-previous] |
cb4ad359 | 494 | '("Snatch from Similar Preceding Field" . bibtex-pop-previous)) |
0640d7bf | 495 | (define-key bibtex-mode-map [menu-bar bibtex-edit bibtex-pop-next] |
cb4ad359 | 496 | '("Snatch from Similar Following Field" . bibtex-pop-next)) |
0640d7bf | 497 | (define-key bibtex-mode-map [menu-bar bibtex-edit bibtex-remove-OPT] |
cb4ad359 | 498 | '("Remove OPT" . bibtex-remove-OPT)) |
0640d7bf | 499 | (define-key bibtex-mode-map [menu-bar bibtex-edit bibtex-remove-double-quotes-or-braces] |
cb4ad359 | 500 | '("Remove Quotes or Braces" . bibtex-remove-double-quotes-or-braces)) |
0640d7bf | 501 | (define-key bibtex-mode-map [menu-bar bibtex-edit bibtex-clean-entry] |
1def9aec | 502 | '("Clean Up Entry" . bibtex-clean-entry)) |
0640d7bf | 503 | (define-key bibtex-mode-map [menu-bar bibtex-edit bibtex-sort-entries] |
cb4ad359 | 504 | '("Sort Entries" . bibtex-sort-entries)) |
31bc4210 RS |
505 | (define-key bibtex-mode-map |
506 | [menu-bar bibtex-edit bibtex-validate-buffer-from-point] | |
507 | '("Validate Entries Starting at Point" . | |
508 | (lambda () | |
509 | (interactive) | |
510 | (bibtex-validate-buffer t)))) | |
0640d7bf | 511 | (define-key bibtex-mode-map [menu-bar bibtex-edit bibtex-validate-buffer] |
cb4ad359 | 512 | '("Validate Entries" . bibtex-validate-buffer)) |
9ae11a89 | 513 | |
cb4ad359 RS |
514 | (define-key bibtex-mode-map [menu-bar entry-types] |
515 | (cons "Entry-Types" (make-sparse-keymap "Entry-Types"))) | |
516 | (define-key bibtex-mode-map [menu-bar entry-types bibtex-preamble] | |
517 | '("Preamble" . bibtex-preamble)) | |
518 | (define-key bibtex-mode-map [menu-bar entry-types bibtex-string] | |
519 | '("String" . bibtex-string)) | |
520 | (define-key bibtex-mode-map [menu-bar entry-types bibtex-Misc] | |
521 | '("Miscellaneous" . bibtex-Misc)) | |
522 | (define-key bibtex-mode-map [menu-bar entry-types bibtex-Unpublished] | |
523 | '("Unpublished" . bibtex-Unpublished)) | |
524 | (define-key bibtex-mode-map [menu-bar entry-types bibtex-Manual] | |
525 | '("Technical Manual" . bibtex-Manual)) | |
526 | (define-key bibtex-mode-map [menu-bar entry-types bibtex-TechReport] | |
527 | '("Technical Report" . bibtex-TechReport)) | |
528 | (define-key bibtex-mode-map [menu-bar entry-types bibtex-MastersThesis] | |
529 | '("Master's Thesis" . bibtex-MastersThesis)) | |
530 | (define-key bibtex-mode-map [menu-bar entry-types bibtex-PhdThesis] | |
531 | '("PhD. Thesis" . bibtex-PhdThesis)) | |
532 | (define-key bibtex-mode-map [menu-bar entry-types bibtex-Booklet] | |
533 | '("Booklet (Bound, but no Publisher/Institution)" . bibtex-Booklet)) | |
534 | (define-key bibtex-mode-map [menu-bar entry-types bibtex-Book] | |
535 | '("Book" . bibtex-Book)) | |
536 | (define-key bibtex-mode-map [menu-bar entry-types bibtex-Proceedings] | |
537 | '("Conference Proceedings" . bibtex-Proceedings)) | |
538 | (define-key bibtex-mode-map [menu-bar entry-types bibtex-InBook] | |
539 | '("Chapter or Pages in a Book" . bibtex-InBook)) | |
540 | (define-key bibtex-mode-map [menu-bar entry-types bibtex-InCollection] | |
541 | '("Article in a Collection" . bibtex-InCollection)) | |
542 | (define-key bibtex-mode-map [menu-bar entry-types bibtex-InProceedings] | |
543 | '("Article in Conference Proceedings" . bibtex-InProceedings)) | |
544 | (define-key bibtex-mode-map [menu-bar entry-types bibtex-Article] | |
545 | '("Article in Journal" . bibtex-Article)) | |
9ae11a89 | 546 | |
31bc4210 RS |
547 | \f |
548 | ;; Bug Reporting | |
549 | ||
550 | (defconst | |
551 | bibtex-maintainer-address "Stefan Schoef <schoef@offis.uni-oldenburg.de>") | |
552 | ;; current maintainer | |
9ae11a89 | 553 | |
cb4ad359 | 554 | \f |
5c69dbfc | 555 | ;; Internal Variables |
9ae11a89 | 556 | |
cb4ad359 RS |
557 | (defvar bibtex-pop-previous-search-point nil) |
558 | ;; Next point where bibtex-pop-previous starts looking for a similar | |
559 | ;; entry. | |
9ae11a89 | 560 | |
cb4ad359 RS |
561 | (defvar bibtex-pop-next-search-point nil) |
562 | ;; Next point where bibtex-pop-next starts looking for a similar entry. | |
745bc783 | 563 | |
cb4ad359 RS |
564 | (defvar bibtex-completion-candidates nil) |
565 | ;; Candidates for bibtex-complete-string. Initialized from | |
566 | ;; bibtex-predefined-strings and bibtex-string-files. This variable is | |
567 | ;; buffer-local. | |
568 | (make-variable-buffer-local 'bibtex-completion-candidates) | |
745bc783 | 569 | |
0640d7bf KH |
570 | (defvar bibtex-keys nil) |
571 | ;; Candidates for TAB completion when entering a reference key using | |
572 | ;; the minibuffer. Initialized in bibtex-mode and updated for each | |
573 | ;; new entry. This variable is buffer-local. | |
574 | (make-variable-buffer-local 'bibtex-keys) | |
575 | ||
576 | (defvar bibtex-buffer-last-parsed-for-keys-tick nil) | |
577 | ;; Remembers the value returned by buffer-modified-tick when buffer | |
578 | ;; was parsed for keys the last time. | |
579 | (make-variable-buffer-local 'bibtex-keys) | |
580 | ||
cb4ad359 | 581 | \f |
5c69dbfc | 582 | ;; Functions to Parse the BibTeX Entries |
745bc783 | 583 | |
745bc783 | 584 | (defun bibtex-cfield (name text) |
cb4ad359 | 585 | ;; Create a regexp for a BibTeX field of name NAME and text TEXT. |
745bc783 JB |
586 | (concat ",[ \t\n]*\\(" |
587 | name | |
588 | "\\)[ \t\n]*=[ \t\n]*\\(" | |
589 | text | |
590 | "\\)")) | |
cb4ad359 RS |
591 | (defconst bibtex-name-in-cfield 1) |
592 | ;; The regexp subexpression number of the name part in bibtex-cfield. | |
593 | ||
594 | (defconst bibtex-text-in-cfield 2) | |
595 | ;; The regexp subexpression number of the text part in bibtex-cfield. | |
596 | ||
31bc4210 | 597 | (defconst bibtex-field-name "[^\"#%'(),={} \t\n0-9][^\"#%'(),={} \t\n]*") |
cb4ad359 RS |
598 | ;; Regexp defining the name part of a BibTeX field. |
599 | ||
31bc4210 RS |
600 | (defconst bibtex-field-const "[][A-Za-z0-9.:;?!`'()/*@_+=|<>-]+") |
601 | ;; Format of a bibtex field constant (same as bibtex-reference-key (see below)) | |
d30bfc76 | 602 | |
31bc4210 RS |
603 | (defconst bibtex-field-string-part-not-braced |
604 | "[^{}]") | |
605 | ;; Match field string part without braces | |
606 | ||
607 | (defconst bibtex-field-string-part-no-inner-braces | |
608 | (concat | |
609 | "{" | |
610 | "\\(" bibtex-field-string-part-not-braced "\\)*" | |
611 | "}")) | |
612 | ;; Match field string part with no inner braces | |
613 | ||
614 | (defconst bibtex-field-string-part-1-inner-brace | |
745bc783 | 615 | (concat |
31bc4210 | 616 | "{" |
cb4ad359 | 617 | "\\(" |
31bc4210 RS |
618 | "\\(" bibtex-field-string-part-not-braced "\\)" |
619 | "\\|" | |
620 | "\\(" bibtex-field-string-part-no-inner-braces "\\)" | |
621 | "\\)*" | |
622 | "}")) | |
623 | ;; Match field string part with at most 1 inner brace | |
624 | ||
625 | (defconst bibtex-field-string-part-2-inner-braces | |
626 | (concat | |
627 | "{" | |
628 | "\\(" | |
629 | "\\(" bibtex-field-string-part-not-braced "\\)" | |
630 | "\\|" | |
631 | "\\(" bibtex-field-string-part-no-inner-braces "\\)" | |
632 | "\\|" | |
633 | "\\(" bibtex-field-string-part-1-inner-brace "\\)" | |
634 | "\\)*" | |
635 | "}")) | |
636 | ;; Match field string part with at most 2 inner braces | |
637 | ||
638 | (defconst bibtex-field-string-part-3-inner-braces | |
639 | (concat | |
640 | "{" | |
641 | "\\(" | |
642 | "\\(" bibtex-field-string-part-not-braced "\\)" | |
643 | "\\|" | |
644 | "\\(" bibtex-field-string-part-no-inner-braces "\\)" | |
645 | "\\|" | |
646 | "\\(" bibtex-field-string-part-1-inner-brace "\\)" | |
647 | "\\|" | |
648 | "\\(" bibtex-field-string-part-2-inner-braces "\\)" | |
649 | "\\)*" | |
650 | "}")) | |
651 | ;; Match field string part with at most 3 inner braces | |
652 | ||
653 | (defconst bibtex-field-string-braced | |
654 | bibtex-field-string-part-3-inner-braces) | |
655 | ;; Match braced field string with inner nesting level of braces at most 3 | |
656 | ||
657 | (defconst bibtex-field-string-quoted | |
658 | (concat | |
659 | "\"" | |
660 | "\\(" | |
661 | "\\(" "[^\"\\]" "\\)" ;; every character except quote or backslash | |
662 | "\\|" | |
af6fb89d KH |
663 | ;; "\\(" "\"[A-Za-z-]" "\\)" ;; a quote followed by a letter or dash |
664 | ;; "\\|" | |
665 | ;; last two lines commented out until lines like | |
666 | ;; author = "Stefan Sch"of" | |
667 | ;; are supported by BibTeX | |
31bc4210 RS |
668 | "\\(" "\\\\.\\|\n" "\\)" ;; a backslash followed by any character |
669 | "\\)*" | |
670 | "\"")) | |
671 | ;; Match quoted field string | |
672 | ||
673 | (defconst bibtex-field-string | |
674 | (concat | |
675 | "\\(" bibtex-field-string-braced "\\)" | |
676 | "\\|" | |
677 | "\\(" bibtex-field-string-quoted "\\)")) | |
678 | ;; Match a braced or quoted string | |
e5167999 | 679 | |
745bc783 | 680 | (defconst bibtex-field-string-or-const |
cb4ad359 RS |
681 | (concat bibtex-field-const "\\|" bibtex-field-string)) |
682 | ;; Match either bibtex-field-string or bibtex-field-const. | |
745bc783 | 683 | |
745bc783 JB |
684 | (defconst bibtex-field-text |
685 | (concat | |
686 | "\\(" bibtex-field-string-or-const "\\)" | |
31bc4210 | 687 | "\\([ \t\n]+#[ \t\n]+\\(" bibtex-field-string-or-const "\\)\\)*")) |
cb4ad359 RS |
688 | ;; Regexp defining the text part of a BibTeX field: either a string, |
689 | ;; or an empty string, or a constant followed by one or more # / | |
0640d7bf | 690 | ;; constant pairs. |
745bc783 JB |
691 | |
692 | (defconst bibtex-field | |
cb4ad359 RS |
693 | (bibtex-cfield bibtex-field-name bibtex-field-text)) |
694 | ;; Regexp defining the format of a BibTeX field. | |
695 | ||
696 | (defconst bibtex-name-in-field bibtex-name-in-cfield) | |
697 | ;; The regexp subexpression number of the name part in BibTeX-field. | |
745bc783 | 698 | |
cb4ad359 RS |
699 | (defconst bibtex-text-in-field bibtex-text-in-cfield) |
700 | ;; The regexp subexpression number of the text part in BibTeX-field. | |
745bc783 | 701 | |
0640d7bf | 702 | (defconst bibtex-reference-type "@[A-Za-z]+") |
cb4ad359 RS |
703 | ;; Regexp defining the type part of a BibTeX reference entry. |
704 | ||
31bc4210 RS |
705 | (defconst bibtex-reference-key "[][A-Za-z0-9.:;?!`'()/*@_+=|<>-]+") |
706 | ;; Regexp defining the label part of a BibTeX reference entry (same as | |
707 | ;; bibtex-field-const (see above)) | |
0640d7bf | 708 | |
745bc783 | 709 | (defconst bibtex-reference-head |
af6fb89d | 710 | (concat "^[ \t]*\\(" |
745bc783 | 711 | bibtex-reference-type |
87988794 | 712 | "\\)[ \t]*[({][ \t]*\\(" |
0640d7bf | 713 | bibtex-reference-key |
cb4ad359 RS |
714 | "\\)")) |
715 | ;; Regexp defining format of the header line of a BibTeX reference | |
716 | ;; entry. | |
717 | ||
0640d7bf KH |
718 | (defconst bibtex-reference-maybe-empty-head |
719 | (concat bibtex-reference-head "?")) | |
720 | ;; Regexp defining format of the header line of a maybe empty | |
721 | ;; BibTeX reference entry (without reference key). | |
722 | ||
af6fb89d | 723 | (defconst bibtex-type-in-head 1) |
cb4ad359 RS |
724 | ;; The regexp subexpression number of the type part in |
725 | ;; bibtex-reference-head. | |
726 | ||
af6fb89d | 727 | (defconst bibtex-key-in-head 2) |
cb4ad359 RS |
728 | ;; The regexp subexpression number of the key part in |
729 | ;; bibtex-reference-head. | |
745bc783 JB |
730 | |
731 | (defconst bibtex-reference | |
cb4ad359 RS |
732 | (concat bibtex-reference-head |
733 | "\\([ \t\n]*" bibtex-field "\\)*" | |
0640d7bf | 734 | "[ \t\n]*,?[ \t\n]*[})]")) |
cb4ad359 RS |
735 | ;; Regexp defining the format of a BibTeX reference entry. |
736 | ||
737 | (defconst bibtex-type-in-reference bibtex-type-in-head) | |
738 | ;; The regexp subexpression number of the type part in | |
739 | ;; bibtex-reference. | |
740 | ||
741 | (defconst bibtex-key-in-reference bibtex-key-in-head) | |
742 | ;; The regexp subexpression number of the key part in | |
743 | ;; bibtex-reference. | |
744 | ||
745bc783 JB |
745 | (defconst bibtex-string |
746 | (concat "^[ \t]*@[sS][tT][rR][iI][nN][gG][ \t\n]*[({][ \t\n]*\\(" | |
0640d7bf | 747 | bibtex-reference-key |
745bc783 JB |
748 | "\\)[ \t\n]*=[ \t\n]*\\(" |
749 | bibtex-field-text | |
cb4ad359 RS |
750 | "\\)[ \t\n]*[})]")) |
751 | ;; Regexp defining the format of a BibTeX string entry. | |
745bc783 | 752 | |
0640d7bf | 753 | (defconst bibtex-key-in-string 1) |
cb4ad359 | 754 | ;; The regexp subexpression of the name part in bibtex-string. |
745bc783 | 755 | |
cb4ad359 RS |
756 | (defconst bibtex-text-in-string 2) |
757 | ;; The regexp subexpression of the text part in bibtex-string. | |
745bc783 | 758 | |
31bc4210 RS |
759 | (defvar bibtex-font-lock-keywords |
760 | (list | |
761 | (list bibtex-reference-maybe-empty-head | |
762 | (list bibtex-type-in-head 'font-lock-function-name-face) | |
763 | (list bibtex-key-in-head 'font-lock-reference-face nil t)) | |
764 | ;; reference type and reference label | |
765 | (list (concat "^[ \t]*\\(OPT" bibtex-field-name "\\)[ \t]*=") | |
766 | 1 'font-lock-comment-face) | |
767 | ;; optional field names (treated as comments) | |
768 | (list (concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=") | |
769 | 1 'font-lock-variable-name-face) | |
770 | ;; field names | |
771 | "*Default expressions to highlight in BibTeX mode.")) | |
772 | ;; now all needed patterns are defined | |
773 | ||
cb4ad359 RS |
774 | (defconst bibtex-name-alignment 2) |
775 | ;; Alignment for the name part in BibTeX fields. Chosen on aesthetic | |
776 | ;; grounds only. | |
9ae11a89 | 777 | |
cb4ad359 RS |
778 | (defconst bibtex-text-alignment (length " organization = ")) |
779 | ;; Alignment for the text part in BibTeX fields. Equal to the space | |
780 | ;; needed for the longest name part. | |
745bc783 | 781 | |
cb4ad359 | 782 | \f |
5c69dbfc | 783 | ;; Helper Functions |
e5167999 | 784 | |
cb4ad359 RS |
785 | (defun assoc-ignore-case (string alist) |
786 | ;; Return non-nil if STRING is `equal' to the car of an element of | |
787 | ;; LIST. Comparison is done with case ignored. The value is actually | |
788 | ;; the element of LIST whose car is `equal' to STRING. | |
789 | (or (assoc string alist) | |
790 | (while (and alist | |
791 | (not (string-equal | |
792 | (downcase string) | |
793 | (downcase (car (car alist)))))) | |
794 | (setq alist (cdr alist))) | |
795 | (car alist))) | |
e5167999 | 796 | |
cb4ad359 RS |
797 | (defun member-of-regexp (string list) |
798 | ;; Return non-nil if STRING is exactly matched by an element of | |
799 | ;; LIST. This function is influenced by the actual value of | |
800 | ;; `case-fold-search'. The value is actually the tail of LIST whose | |
801 | ;; car matches STRING. | |
802 | (while | |
803 | (and | |
804 | list | |
805 | (not | |
806 | (string-match | |
807 | (concat "^" (car list) "$") | |
808 | string))) | |
809 | (setq list (cdr list))) | |
810 | list) | |
811 | ||
812 | (defun assoc-of-regexp (string alist) | |
813 | ;; Return non-nil if STRING is exactly matched by the car of an | |
814 | ;; element of LIST. This function is influenced by the actual value | |
815 | ;; of `case-fold-search'. The value is actually the element of LIST | |
816 | ;; whose car matches STRING. | |
817 | (while | |
818 | (and | |
819 | alist | |
820 | (not | |
821 | (string-match | |
822 | (concat "^" (car (car alist)) "$") | |
823 | string))) | |
824 | (setq alist (cdr alist))) | |
825 | (car alist)) | |
e5167999 | 826 | |
9ae11a89 | 827 | (defun skip-whitespace-and-comments () |
9ae11a89 ER |
828 | (let ((md (match-data))) |
829 | (unwind-protect | |
830 | (while (cond ((looking-at "\\s>+\\|\\s +") | |
831 | ;; was whitespace | |
832 | ;; NOTE: also checked end-comment. In latex and | |
833 | ;; lisp modes, newline is an end comment, but it | |
834 | ;; should also be a whitespace char. | |
835 | (goto-char (match-end 0))) | |
836 | ;; If looking at beginning of comment, skip to end. | |
837 | ((looking-at "\\s<") | |
838 | (re-search-forward "\\s>")))) | |
839 | (store-match-data md)))) | |
840 | ||
cb4ad359 RS |
841 | (defun map-bibtex-entries (fun) |
842 | ;; Call FUN for each BibTeX entry starting with the current. Do this | |
843 | ;; to the end of the file. FUN is called with one argument, the key | |
844 | ;; of the entry, and with point inside the entry. If | |
0640d7bf | 845 | ;; bibtex-sort-ignore-string-entries is non-nil, FUN will not be called |
cb4ad359 RS |
846 | ;; for @string entries. |
847 | (bibtex-beginning-of-entry) | |
0640d7bf | 848 | (while (re-search-forward bibtex-reference-head nil t) |
cb4ad359 | 849 | (if (and bibtex-sort-ignore-string-entries |
0640d7bf | 850 | (string-equal "@string" |
5c69dbfc | 851 | (downcase (buffer-substring-no-properties |
0640d7bf KH |
852 | (match-beginning bibtex-type-in-head) |
853 | (match-end bibtex-type-in-head))))) | |
cb4ad359 | 854 | nil |
5c69dbfc | 855 | (funcall fun (buffer-substring-no-properties |
0640d7bf KH |
856 | (match-beginning bibtex-key-in-head) |
857 | (match-end bibtex-key-in-head)))))) | |
e5167999 | 858 | |
cb4ad359 RS |
859 | (defun bibtex-flash-head () |
860 | ;; Flash at BibTeX reference head before point, if exists. | |
861 | (let ((flash)) | |
862 | (cond ((re-search-backward bibtex-reference-head (point-min) t) | |
863 | (goto-char (match-beginning bibtex-type-in-head)) | |
864 | (setq flash (match-end bibtex-key-in-reference))) | |
865 | (t | |
866 | (end-of-line) | |
867 | (skip-chars-backward " \t") | |
868 | (setq flash (point)) | |
869 | (beginning-of-line) | |
870 | (skip-chars-forward " \t"))) | |
871 | (if (pos-visible-in-window-p (point)) | |
872 | (sit-for 1) | |
873 | (message "From: %s" | |
874 | (buffer-substring (point) flash))))) | |
e5167999 | 875 | |
cb4ad359 RS |
876 | (defun bibtex-move-outside-of-entry () |
877 | ;; Make sure we are outside of a BibTeX entry. | |
878 | (cond ((or | |
879 | (= (point) (point-max)) | |
880 | (= (point) (point-min)) | |
881 | (looking-at "[ \n]*@") | |
882 | ) | |
883 | t) | |
884 | (t | |
885 | (backward-paragraph) | |
886 | (forward-paragraph))) | |
887 | (re-search-forward "[ \t\n]*" (point-max) t)) | |
e5167999 ER |
888 | |
889 | (defun beginning-of-first-bibtex-entry () | |
cb4ad359 | 890 | ;; Go to the beginning of the first BibTeX entry in buffer. |
e5167999 | 891 | (goto-char (point-min)) |
0640d7bf KH |
892 | (cond |
893 | ((re-search-forward "^@" nil 'move) | |
894 | (beginning-of-line)) | |
895 | ((and (bobp) (eobp)) | |
896 | nil) | |
897 | (t | |
898 | (message "Warning: No BibTeX entries found!")))) | |
e5167999 | 899 | |
cb4ad359 RS |
900 | (defun bibtex-inside-field () |
901 | ;; Try to avoid point being at end of a BibTeX field. | |
902 | (end-of-line) | |
0640d7bf | 903 | (skip-chars-backward " \t") |
cb4ad359 | 904 | (cond ((= (preceding-char) ?,) |
0640d7bf KH |
905 | (forward-char -2))) |
906 | (cond ((or | |
907 | (= (preceding-char) ?}) | |
908 | (= (preceding-char) ?\")) | |
909 | (forward-char -1)))) | |
9ae11a89 | 910 | |
cb4ad359 RS |
911 | (defun bibtex-enclosing-field () |
912 | ;; Search for BibTeX field enclosing point. Point moves to end of | |
913 | ;; field; also, use match-beginning and match-end to parse the field. | |
914 | ;; sct@dcs.edinburgh.ac.uk | |
915 | (let ((old-point (point))) | |
916 | (condition-case errname | |
917 | (bibtex-enclosing-regexp bibtex-field) | |
918 | (search-failed | |
919 | (goto-char old-point) | |
920 | (error "Can't find enclosing BibTeX field."))))) | |
e5167999 | 921 | |
cb4ad359 | 922 | (defun bibtex-enclosing-reference () |
0640d7bf KH |
923 | ;; Search for BibTeX reference enclosing point. Point moves to |
924 | ;; beginning of reference. Beginning/end of reference is given by | |
925 | ;; (match-beginning/match-end 0). | |
926 | (let ((old-point (point))) | |
927 | (if (not | |
928 | (re-search-backward bibtex-reference-head (point-min) t)) | |
929 | (progn | |
930 | (error "Can't find enclosing BibTeX reference.") | |
931 | (goto-char old-point))) | |
932 | (goto-char (match-beginning bibtex-type-in-head)) | |
933 | (let ((pnt (point))) | |
934 | (if (not | |
935 | (re-search-forward bibtex-reference (point-max) t)) | |
936 | (progn | |
937 | (error "Can't find enclosing BibTeX reference.") | |
938 | (goto-char old-point)) | |
939 | (goto-char pnt))))) | |
940 | ||
941 | (defun bibtex-enclosing-reference-maybe-empty-head () | |
942 | ;; Search for BibTeX reference enclosing point. Point moves to | |
943 | ;; beginning of reference. Beginning/end of reference is given by | |
944 | ;; (match-beginning/match-end 0). | |
cb4ad359 RS |
945 | (let ((old-point (point))) |
946 | (if (not | |
947 | (re-search-backward | |
0640d7bf | 948 | bibtex-reference-maybe-empty-head (point-min) t)) |
cb4ad359 RS |
949 | (progn |
950 | (error "Can't find enclosing BibTeX reference.") | |
951 | (goto-char old-point))) | |
0640d7bf | 952 | (goto-char (match-beginning bibtex-type-in-head)) |
cb4ad359 RS |
953 | (let ((pnt (point))) |
954 | (if (not | |
0640d7bf KH |
955 | (re-search-forward |
956 | (concat | |
957 | bibtex-reference-maybe-empty-head | |
958 | "\\([ \t\n]*" bibtex-field "\\)*" | |
959 | "[ \t\n]*,?[ \t\n]*[})]") | |
960 | (point-max) t)) | |
cb4ad359 RS |
961 | (progn |
962 | (error "Can't find enclosing BibTeX reference.") | |
963 | (goto-char old-point)) | |
964 | (goto-char pnt))))) | |
9ae11a89 | 965 | |
cb4ad359 RS |
966 | (defun bibtex-enclosing-regexp (regexp) |
967 | ;; Search for REGEXP enclosing point. Point moves to end of | |
968 | ;; REGEXP. See also match-beginning and match-end. If an enclosing | |
969 | ;; REGEXP is not found, signals search-failed; point is left in an | |
970 | ;; undefined location. | |
971 | ;; Doesn't something like this exist already? | |
31bc4210 | 972 | ;; compute reasonable limits for the loop |
cb4ad359 RS |
973 | (let* ((initial (point)) |
974 | (right (if (re-search-forward regexp (point-max) t) | |
975 | (match-end 0) | |
976 | (point-max))) | |
977 | (left | |
978 | (progn | |
979 | (goto-char initial) | |
980 | (if (re-search-backward regexp (point-min) t) | |
981 | (match-beginning 0) | |
982 | (point-min))))) | |
983 | ; within the prescribed limits, loop until a match is found | |
984 | (goto-char left) | |
985 | (re-search-forward regexp right nil 1) | |
986 | (if (> (match-beginning 0) initial) | |
987 | (signal 'search-failed (list regexp))) | |
988 | (while (<= (match-end 0) initial) | |
989 | (re-search-forward regexp right nil 1) | |
990 | (if (> (match-beginning 0) initial) | |
991 | (signal 'search-failed (list regexp)))) | |
992 | )) | |
e5167999 | 993 | |
cb4ad359 RS |
994 | (defun bibtex-autokey-change (string change-list) |
995 | ;; Returns a string where some regexps are changed according to | |
996 | ;; change-list. Every item of change-list is an (old-regexp | |
997 | ;; new-string) pair. | |
998 | (let ((return-string string) | |
999 | case-fold-search | |
1000 | (index 0) | |
1001 | (len (length change-list)) | |
1002 | change-item) | |
1003 | (while (< index len) | |
1004 | (setq change-item (elt change-list index)) | |
1005 | (while (string-match (car change-item) return-string) | |
1006 | (setq | |
1007 | return-string | |
1008 | (concat (substring return-string 0 (match-beginning 0)) | |
1009 | (elt change-item 1) | |
1010 | (substring return-string (match-end 0))))) | |
1011 | (setq index (1+ index))) | |
1012 | return-string)) | |
1013 | ||
1014 | (defun bibtex-autokey-abbrev (string len) | |
1015 | ;; Returns an abbreviation of string with at least len | |
1016 | ;; characters. String is aborted only after a consonant or at the | |
1017 | ;; word end. If len is not a number, string is returned unchanged. | |
1018 | (let* ((string-length (length string)) | |
1019 | (len (if (numberp len) | |
1020 | (min len string-length) | |
1021 | len)) | |
1022 | (return-string (if (numberp len) | |
1023 | (substring string 0 len))) | |
1024 | (index len) | |
1025 | (vowels '(?a ?e ?i ?o ?u ?A ?E ?I ?O ?U))) | |
1026 | (if (numberp len) | |
1027 | (progn | |
1028 | (while (and | |
1029 | (< index string-length) | |
1030 | (member (elt return-string | |
1031 | (1- (length return-string))) | |
1032 | vowels)) | |
1033 | (setq return-string (concat return-string | |
1034 | (substring | |
1035 | string index (1+ index))) | |
1036 | index (1+ index))) | |
1037 | return-string) | |
1038 | string))) | |
1039 | ||
1040 | (defun bibtex-generate-autokey () | |
1041 | "Generates automatically a key from the author/editor and the title field. | |
1042 | The generation algorithm works as follows: | |
1043 | 1. If there is a non-empty author (preferred) or editor field, | |
1044 | use it for the name part of the key. | |
1045 | 2. Change any substring found in `bibtex-autokey-name-change-strings' | |
1046 | to the corresponding new one (see documentation of this variable | |
1047 | for further detail). | |
1048 | 3. For every of the first `bibtex-autokey-names' names in the | |
1049 | \"name\" field, determine the last name. | |
1050 | 4. From every last name, take at least `bibtex-autokey-name-length' | |
1051 | characters (abort only after a consonant or at a word end). | |
1052 | 5. Build the name part of the key by concatenating all abbreviated last | |
1053 | names with the string `bibtex-autokey-name-separator' between | |
1054 | any two. | |
1055 | 6. Build the year part of the key by truncating the contents of the | |
1056 | \"year\" field to the rightmost `bibtex-autokey-year-length' | |
1057 | digits (useful values are 2 and 4). | |
1058 | 7. For the title part of the key change the contents of the \"title\" | |
1059 | field of the reference according to | |
1060 | `bibtex-autokey-titleword-change-strings' to the corresponding | |
1061 | new one (see documentation of this variable for further detail). | |
1062 | 8. Abbreviate the result to the string up to (but not including) the | |
2e282f92 | 1063 | first occurrence of a regexp matched by the items of |
cb4ad359 RS |
1064 | `bibtex-autokey-title-terminators' and delete the first |
1065 | word if it appears in `bibtex-autokey-titleword-first-ignore'. | |
1066 | Build the title part of the key by using at least the first | |
1067 | `bibtex-autokey-titlewords' capitalized words from this | |
1068 | abbreviated title. If the abbreviated title ends after maximal | |
1069 | `bibtex-autokey-titlewords' + `bibtex-autokey-titlewords-stretch' | |
1070 | capitalized words, all capitalized words from the abbreviated title | |
1071 | are used. | |
1072 | 9. For every used title word that appears in | |
1073 | `bibtex-autokey-titleword-abbrevs' use the corresponding abbreviation | |
1074 | (see documentation of this variable for further detail). | |
1075 | 10. From every title word not generated by an abbreviation, take at | |
1076 | least `bibtex-autokey-titleword-length' characters (abort only after | |
1077 | a consonant or at a word end). | |
1078 | 11. Build the title part of the key by concatenating all abbreviated | |
1079 | title words with the string `bibtex-autokey-titleword-separator' | |
1080 | between any two. | |
1081 | 12. At least, to get the key, concatenate the name part, the year part | |
1082 | and the title part with `bibtex-autokey-name-year-separator' | |
1083 | between the name and the year if both are non-empty and | |
1084 | `bibtex-autokey-year-title-separator' between the year and | |
1085 | the title if both are non-empty." | |
1086 | ||
1087 | (let* ((pnt (point)) | |
1088 | (min | |
1089 | (progn | |
1090 | (bibtex-beginning-of-entry) | |
1091 | (point))) | |
1092 | (max | |
1093 | (progn | |
1094 | (bibtex-end-of-entry) | |
1095 | (point))) | |
1096 | (namefield | |
1097 | (progn | |
1098 | (goto-char min) | |
1099 | (if (or | |
0640d7bf KH |
1100 | (re-search-forward "^[ \t]*author[ \t]*=" max t) |
1101 | (re-search-forward "^[ \t]*editor[ \t]*=" max t)) | |
cb4ad359 RS |
1102 | (let* (bibtex-help-message |
1103 | (start (progn | |
1104 | (bibtex-find-text t) | |
1105 | (point))) | |
1106 | (end (progn | |
1107 | (bibtex-find-text nil) | |
1108 | (point)))) | |
1109 | (bibtex-autokey-change | |
5c69dbfc | 1110 | (buffer-substring-no-properties start end) |
cb4ad359 RS |
1111 | bibtex-autokey-name-change-strings)) |
1112 | ""))) | |
1113 | (namelist | |
1114 | (mapcar | |
1115 | (function | |
1116 | (lambda (fullname) | |
1117 | (bibtex-autokey-abbrev | |
1118 | (if (string-match "," fullname) | |
1119 | (substring fullname 0 (match-beginning 0)) | |
1120 | (progn | |
1121 | (if (string-match " [^ ]*$" fullname) | |
1122 | (substring | |
1123 | fullname (1+ (match-beginning 0))) | |
1124 | fullname))) | |
1125 | bibtex-autokey-name-length))) | |
1126 | ;; Gather all names into a list | |
1127 | (let (names | |
1128 | (counter 0)) | |
1129 | (while (and | |
1130 | (not (equal namefield "")) | |
1131 | (or | |
1132 | (not (numberp bibtex-autokey-names)) | |
1133 | (< counter bibtex-autokey-names))) | |
1134 | (if (string-match " and " namefield) | |
1135 | (progn | |
1136 | (setq | |
1137 | names | |
1138 | (append names | |
1139 | (list | |
1140 | (downcase | |
1141 | (substring | |
1142 | namefield 0 (match-beginning 0))))) | |
1143 | namefield | |
1144 | (substring namefield (match-end 0)))) | |
1145 | (setq names | |
1146 | (append names (list (downcase namefield))) | |
1147 | namefield "")) | |
1148 | (setq counter (1+ counter))) | |
1149 | names))) | |
1150 | (namepart (mapconcat (function (lambda (name) name)) | |
1151 | namelist | |
1152 | bibtex-autokey-name-separator)) | |
1153 | (yearfield | |
1154 | (progn | |
1155 | (goto-char min) | |
0640d7bf | 1156 | (if (re-search-forward |
cb4ad359 | 1157 | "^[ \t]*year[ \t]*=[ \t]*\\([0-9]*\\)" max t) |
5c69dbfc RS |
1158 | (buffer-substring-no-properties |
1159 | (match-beginning 1) (match-end 1)) | |
cb4ad359 RS |
1160 | ""))) |
1161 | (yearpart | |
1162 | (if (equal yearfield "") | |
1163 | "" | |
1164 | (substring yearfield | |
1165 | (- (length yearfield) | |
1166 | bibtex-autokey-year-length)))) | |
1167 | (titlestring | |
1168 | (let ((case-fold-search t) | |
1169 | (titlefield | |
1170 | (progn | |
1171 | (goto-char min) | |
0640d7bf | 1172 | (if (re-search-forward |
cb4ad359 RS |
1173 | "^[ \t]*title[ \t]*=" max t) |
1174 | (let* (bibtex-help-message | |
1175 | (start (progn | |
1176 | (bibtex-find-text t) | |
1177 | (point))) | |
1178 | (end (progn | |
1179 | (bibtex-find-text nil) | |
1180 | (point)))) | |
1181 | (bibtex-autokey-change | |
5c69dbfc | 1182 | (buffer-substring-no-properties start end) |
cb4ad359 RS |
1183 | bibtex-autokey-titleword-change-strings)) |
1184 | ""))) | |
1185 | case-fold-search | |
1186 | (index 0) | |
1187 | (numberofitems | |
1188 | (length bibtex-autokey-title-terminators))) | |
1189 | (while (< index numberofitems) | |
1190 | (if (string-match | |
1191 | (elt bibtex-autokey-title-terminators index) | |
1192 | titlefield) | |
1193 | (setq titlefield | |
1194 | (substring titlefield 0 (match-beginning 0)))) | |
1195 | (setq index (1+ index))) | |
1196 | titlefield)) | |
1197 | (titlelist | |
1198 | (mapcar | |
1199 | (function | |
1200 | (lambda (titleword) | |
1201 | (let ((abbrev | |
1202 | (assoc-of-regexp | |
1203 | titleword bibtex-autokey-titleword-abbrevs))) | |
1204 | (if abbrev | |
1205 | (elt abbrev 1) | |
1206 | (bibtex-autokey-abbrev | |
1207 | titleword | |
1208 | bibtex-autokey-titleword-length))))) | |
1209 | ;; Gather all titlewords into a list | |
1210 | (let (titlewords | |
1211 | titlewords-extra | |
1212 | case-fold-search | |
1213 | (counter 0) | |
1214 | (first t)) | |
1215 | (while (and | |
1216 | (not (equal titlestring "")) | |
1217 | (or | |
1218 | (not (numberp bibtex-autokey-titlewords)) | |
1219 | (< counter (+ | |
1220 | bibtex-autokey-titlewords | |
1221 | bibtex-autokey-titlewords-stretch)))) | |
1222 | (if (string-match "\\b[A-Z][A-Za-z0-9]*" titlestring) | |
1223 | (let* ((end-match (match-end 0)) | |
1224 | (titleword | |
1225 | (downcase (substring titlestring | |
1226 | (match-beginning 0) | |
1227 | end-match)))) | |
1228 | (if (or | |
1229 | (not (numberp bibtex-autokey-titlewords)) | |
1230 | (< counter bibtex-autokey-titlewords)) | |
1231 | (if (and | |
1232 | first | |
1233 | (member-of-regexp | |
1234 | titleword | |
1235 | bibtex-autokey-titleword-first-ignore)) | |
1236 | (setq counter -1) | |
1237 | (setq titlewords | |
1238 | (append titlewords (list titleword)))) | |
1239 | (setq | |
1240 | titlewords-extra | |
1241 | (append titlewords-extra (list titleword)))) | |
1242 | (setq titlestring | |
1243 | (substring titlestring end-match))) | |
1244 | (setq titlestring "")) | |
1245 | (setq first nil | |
1246 | counter (1+ counter))) | |
1247 | (if (string-match "\\b[A-Z][^ ]*\\b" titlestring) | |
1248 | titlewords | |
1249 | (append titlewords titlewords-extra))))) | |
1250 | (titlepart (mapconcat (function (lambda (name) name)) | |
1251 | titlelist | |
1252 | bibtex-autokey-titleword-separator)) | |
1253 | (autokey | |
1254 | (concat | |
1255 | namepart | |
1256 | (if (not | |
1257 | (or | |
1258 | (equal namepart "") | |
1259 | (equal yearpart ""))) | |
1260 | bibtex-autokey-name-year-separator) | |
1261 | yearpart | |
1262 | (if (not | |
1263 | (or | |
1264 | (and | |
1265 | (equal namepart "") | |
1266 | (equal yearpart "")) | |
1267 | (equal titlepart ""))) | |
1268 | bibtex-autokey-year-title-separator) | |
1269 | titlepart))) | |
1270 | (goto-char pnt) | |
1271 | autokey)) | |
e5167999 | 1272 | |
0640d7bf KH |
1273 | (defun bibtex-parse-keys (add &optional abortable) |
1274 | ;; Sets bibtex-keys to the keys used in the whole (possibly | |
1275 | ;; restricted) buffer (either as entry keys or as crossref entries). | |
1276 | ;; If ADD is non-nil adds the new keys to bibtex-keys instead of | |
1277 | ;; simply resetting it. If ABORTABLE is non-nil abort on user input. | |
1278 | (if bibtex-maintain-sorted-entries | |
1279 | (let ((labels (if add | |
1280 | bibtex-keys)) | |
1281 | label | |
1282 | (case-fold-search t)) | |
1283 | (save-excursion | |
1284 | (goto-char (point-min)) | |
1285 | (if (not add) | |
1286 | (message "Parsing reference keys...")) | |
1287 | ||
1288 | (if (not | |
1289 | (catch 'userkey | |
1290 | (while | |
1291 | (re-search-forward | |
1292 | (concat | |
31bc4210 RS |
1293 | "\\(" bibtex-reference-head "\\)" |
1294 | "\\|" | |
0640d7bf | 1295 | "\\(" |
31bc4210 RS |
1296 | "^[ \t]*crossref[ \t\n]*=[ \t\n]*" |
1297 | "\\(" | |
1298 | "\\({" | |
1299 | bibtex-reference-key | |
1300 | ;; every valid crossref entry must have the | |
1301 | ;; form of a reference key, so we need no | |
1302 | ;; nesting of brace etc. here | |
1303 | "}\\)" | |
1304 | "\\|" | |
1305 | "\\(\"" | |
1306 | bibtex-reference-key | |
1307 | "\"\\)" | |
1308 | "\\)" | |
1309 | ",?$" | |
0640d7bf KH |
1310 | "\\)") |
1311 | nil t) | |
1312 | (if (and | |
1313 | abortable | |
1314 | (input-pending-p)) | |
1315 | (throw 'userkey t)) | |
1316 | (if (match-beginning (1+ bibtex-key-in-head)) | |
1317 | (setq | |
1318 | label | |
1319 | (buffer-substring-no-properties | |
1320 | (match-beginning (1+ bibtex-key-in-head)) | |
1321 | (match-end (1+ bibtex-key-in-head)))) | |
1322 | (setq | |
1323 | label | |
1324 | (buffer-substring-no-properties | |
31bc4210 RS |
1325 | (1+ (match-beginning (+ 3 bibtex-key-in-head))) |
1326 | (1- (match-end (+ 3 bibtex-key-in-head)))))) | |
0640d7bf KH |
1327 | (if (not (assoc label labels)) |
1328 | (setq labels | |
1329 | (cons (list label) labels)))))) | |
1330 | (progn | |
1331 | (setq | |
1332 | bibtex-buffer-last-parsed-for-keys-tick | |
1333 | (buffer-modified-tick)) | |
1334 | (if (not add) | |
1335 | (message "Parsing reference keys... done")) | |
1336 | (setq bibtex-keys labels))))))) | |
1337 | ||
1338 | (defun bibtex-auto-fill-function () | |
1339 | (let ((fill-prefix (make-string (+ bibtex-text-alignment 1) ? ))) | |
1340 | (do-auto-fill))) | |
1341 | ||
cb4ad359 | 1342 | \f |
5c69dbfc | 1343 | ;; Interactive Functions: |
cb4ad359 RS |
1344 | |
1345 | ;;;###autoload | |
1346 | (defun bibtex-mode () | |
1347 | "Major mode for editing BibTeX files. | |
31bc4210 RS |
1348 | To submit a problem report, enter `\\[bibtex-submit-bug-report]' from a |
1349 | bibtex-mode buffer. This automatically sets up a mail buffer with | |
1350 | version information already added. You just need to add a description | |
1351 | of the problem, including a reproducable test case and send the | |
1352 | message. | |
cb4ad359 RS |
1353 | |
1354 | \\{bibtex-mode-map} | |
1355 | ||
1356 | A command such as \\[bibtex-Book] will outline the fields for a BibTeX book entry. | |
1357 | ||
1358 | The optional fields start with the string OPT, and thus ignored by BibTeX. | |
1359 | The OPT string may be removed from a field with \\[bibtex-remove-OPT]. | |
1360 | \\[bibtex-kill-optional-field] kills the current optional field entirely. | |
1361 | \\[bibtex-remove-double-quotes-or-braces] removes the double-quotes or | |
1362 | braces around the text of the current field. \\[bibtex-empty-field] | |
1363 | replaces the text of the current field with the default \"\" or {}. | |
1364 | ||
1365 | The command \\[bibtex-clean-entry] cleans the current entry, i.e. (i) removes | |
1366 | double-quotes or braces from entirely numerical fields, (ii) removes | |
1367 | OPT from all non-empty optional fields, (iii) removes all empty | |
1368 | optional fields, and (iv) checks that no non-optional fields are empty. | |
1369 | ||
1370 | Use \\[bibtex-find-text] to position the cursor at the end of the current field. | |
1371 | Use \\[bibtex-next-field] to move to end of the next field. | |
1372 | ||
1373 | The following may be of interest as well: | |
9ae11a89 | 1374 | |
cb4ad359 RS |
1375 | Functions: |
1376 | bibtex-entry | |
1377 | bibtex-print-help-message | |
1378 | bibtex-beginning-of-entry | |
1379 | bibtex-end-of-entry | |
1380 | bibtex-ispell-abstract | |
1381 | bibtex-narrow-to-entry | |
1382 | bibtex-hide-entry-bodies | |
1383 | bibtex-sort-entries | |
1384 | bibtex-validate-buffer | |
1385 | bibtex-pop-previous | |
1386 | bibtex-pop-next | |
1387 | bibtex-complete-string | |
1388 | ||
1389 | Variables: | |
1390 | bibtex-field-left-delimiter | |
1391 | bibtex-field-right-delimiter | |
1392 | bibtex-include-OPTcrossref | |
1393 | bibtex-include-OPTkey | |
1394 | bibtex-include-OPTannote | |
1395 | bibtex-mode-user-optional-fields | |
1396 | bibtex-clean-entry-zap-empty-opts | |
1397 | bibtex-sort-ignore-string-entries | |
1398 | bibtex-maintain-sorted-entries | |
1399 | bibtex-entry-field-alist | |
1400 | bibtex-predefined-strings | |
1401 | bibtex-string-files | |
1402 | ||
1403 | --------------------------------------------------------- | |
1404 | Entry to this mode calls the value of bibtex-mode-hook if that value is | |
1405 | non-nil." | |
1406 | (interactive) | |
1407 | (kill-all-local-variables) | |
1408 | (use-local-map bibtex-mode-map) | |
1409 | (setq major-mode 'bibtex-mode) | |
1410 | (setq mode-name "BibTeX") | |
1411 | (set-syntax-table bibtex-mode-syntax-table) | |
1412 | (setq bibtex-completion-candidates bibtex-predefined-strings) | |
1413 | (mapcar | |
1414 | (function | |
1415 | (lambda (filename) | |
1416 | ;; collect pathnames | |
1417 | (let* ((bib (getenv "BIBINPUTS")) | |
1418 | (path (if bib | |
1419 | bib | |
1420 | ".")) | |
1421 | (dirs | |
1422 | (mapcar | |
1423 | (function | |
1424 | (lambda (dirname) ;; strips off trailing slashes | |
1425 | (let ((len (length dirname))) | |
1426 | (if (equal (elt dirname (1- len)) "/") | |
1427 | (substring dirname 0 (1- (1- len))) | |
1428 | dirname)))) | |
1429 | (let (actdirs) | |
1430 | (while (string-match ":" path) | |
1431 | (setq actdirs | |
1432 | (append actdirs | |
1433 | (list (substring | |
1434 | path 0 | |
1435 | (1- (match-end 0))))) | |
1436 | path (substring path (match-end 0)))) | |
1437 | (append actdirs (list path))))) | |
1438 | (filename (if (string-match "\.bib$" filename) | |
1439 | filename | |
1440 | (concat filename ".bib"))) | |
1441 | fullfilename | |
1442 | (item 0) | |
1443 | (size (length dirs))) | |
1444 | ;; test filenames | |
1445 | (while (and | |
1446 | (< item size) | |
1447 | (not (file-readable-p | |
1448 | (setq fullfilename | |
1449 | (concat (elt dirs item) "/" filename))))) | |
1450 | (setq item (1+ item))) | |
1451 | (if (< item size) | |
1452 | ;; file was found | |
1453 | (let ((curbuf (current-buffer)) | |
1454 | (bufname (make-temp-name "")) | |
1455 | (compl bibtex-completion-candidates)) | |
1456 | (create-file-buffer bufname) | |
1457 | (set-buffer bufname) | |
1458 | (insert-file-contents fullfilename) | |
1459 | (goto-char (point-min)) | |
0640d7bf | 1460 | (while (re-search-forward bibtex-string nil t) |
cb4ad359 RS |
1461 | (setq |
1462 | compl | |
1463 | (append | |
1464 | compl | |
1465 | (list | |
5c69dbfc | 1466 | (list (buffer-substring-no-properties |
0640d7bf KH |
1467 | (match-beginning bibtex-key-in-string) |
1468 | (match-end bibtex-key-in-string))))))) | |
cb4ad359 RS |
1469 | (kill-buffer bufname) |
1470 | (set-buffer curbuf) | |
1471 | (setq bibtex-completion-candidates compl)) | |
1472 | (error "File %s not in $BIBINPUTS paths" filename))))) | |
1473 | bibtex-string-files) | |
af6fb89d KH |
1474 | (run-with-idle-timer |
1475 | bibtex-parse-keys-timeout bibtex-parse-keys-timeout | |
0640d7bf KH |
1476 | (function |
1477 | (lambda () | |
1478 | (if (and | |
1479 | bibtex-maintain-sorted-entries | |
1480 | (eq major-mode 'bibtex-mode) | |
1481 | (not | |
1482 | (eq (buffer-modified-tick) | |
1483 | bibtex-buffer-last-parsed-for-keys-tick))) | |
1484 | (bibtex-parse-keys nil t))))) | |
1485 | (bibtex-parse-keys nil) | |
cb4ad359 | 1486 | (make-local-variable 'paragraph-start) |
ac0e96eb | 1487 | (setq paragraph-start "[ \f\n\t]*$") |
cb4ad359 RS |
1488 | (make-local-variable 'comment-start) |
1489 | (setq comment-start "%") | |
1b97fc6e RS |
1490 | (make-local-variable 'normal-auto-fill-function) |
1491 | (setq normal-auto-fill-function 'bibtex-auto-fill-function) | |
0640d7bf | 1492 | (set (make-local-variable 'font-lock-defaults) |
27abea5a | 1493 | '(bibtex-font-lock-keywords |
31bc4210 RS |
1494 | nil t ((?$ . "\"") |
1495 | ;; Mathematical expressions should be fontified as strings | |
1496 | (?\" . ".") | |
1497 | ;; Quotes are field delimiters and quote-delimited | |
1498 | ;; entries should be fontified in the same way as | |
1499 | ;; brace-delimited ones | |
1500 | ))) | |
cb4ad359 | 1501 | (run-hooks 'bibtex-mode-hook)) |
9ae11a89 | 1502 | |
31bc4210 RS |
1503 | (defun bibtex-submit-bug-report () |
1504 | "Submit via mail a bug report on bibtex.el." | |
1505 | (interactive) | |
1506 | (if (y-or-n-p "Do you want to submit a bug report on BibTeX mode? ") | |
1507 | (progn | |
1508 | (require 'reporter) | |
1509 | (let ((reporter-prompt-for-summary-p t)) | |
1510 | (reporter-submit-bug-report | |
1511 | bibtex-maintainer-address | |
1512 | "bibtex.el" | |
1513 | (list | |
1514 | 'system-configuration | |
1515 | 'system-configuration-options | |
1516 | 'bibtex-sort-ignore-string-entries | |
1517 | 'bibtex-maintain-sorted-entries | |
1518 | 'bibtex-field-left-delimiter | |
1519 | 'bibtex-field-right-delimiter | |
1520 | ;; Possible sorting and parsing bugs | |
1521 | 'bibtex-mode-user-optional-fields | |
1522 | ;; Possible format error | |
1523 | 'bibtex-predefined-strings | |
1524 | 'bibtex-string-files | |
1525 | ;; Possible format error | |
1526 | 'bibtex-font-lock-keywords | |
1527 | ;; Possible bugs regarding fontlocking | |
1528 | 'bibtex-autokey-names | |
1529 | 'bibtex-autokey-name-change-strings | |
1530 | 'bibtex-autokey-name-length | |
1531 | 'bibtex-autokey-name-separator | |
1532 | 'bibtex-autokey-year-length | |
1533 | 'bibtex-autokey-titlewords | |
1534 | 'bibtex-autokey-title-terminators | |
1535 | 'bibtex-autokey-titlewords-stretch | |
1536 | 'bibtex-autokey-titleword-first-ignore | |
1537 | 'bibtex-autokey-titleword-abbrevs | |
1538 | 'bibtex-autokey-titleword-change-strings | |
1539 | 'bibtex-autokey-titleword-length | |
1540 | 'bibtex-autokey-titleword-separator | |
1541 | 'bibtex-autokey-name-year-separator | |
1542 | 'bibtex-autokey-year-title-separator | |
1543 | 'bibtex-autokey-edit-before-use | |
1544 | ;; Possible bugs regarding automatic labels | |
1545 | 'bibtex-entry-field-alist | |
1546 | ;; Possible format error | |
1547 | 'bibtex-help-message | |
1548 | 'bibtex-include-OPTcrossref | |
1549 | 'bibtex-include-OPTkey | |
1550 | 'bibtex-include-OPTannote | |
1551 | 'bibtex-clean-entry-zap-empty-opts | |
1552 | ;; User variables which shouldn't cause any errors | |
1553 | ) | |
1554 | nil nil | |
1555 | (concat "Hi Stefan, | |
1556 | ||
1557 | I want to report a bug on Emacs BibTeX mode. | |
1558 | I've read the `Bugs' section in the `Emacs' info page, so I know how | |
1559 | to make a clear and unambiguous report. I have started a fresh Emacs | |
1560 | via `"invocation-name " --no-init-file --no-site-file', thereafter (in | |
1561 | case I'm reporting on a version of `bibtex.el' which is not part of | |
1562 | the standard emacs distribution) I loaded the questionable version | |
1563 | of `bibtex.el' with `M-x load-file', and then, to produce the buggy | |
1564 | behaviour, I did the following:"))) | |
1565 | (message nil)))) | |
1566 | ||
9ae11a89 | 1567 | (defun bibtex-entry (entry-type &optional required optional) |
0640d7bf KH |
1568 | "Inserts a new BibTeX entry. |
1569 | Calls the value of bibtex-add-entry-hook if that value is non-nil." | |
9ae11a89 | 1570 | (interactive (let* ((completion-ignore-case t) |
cb4ad359 RS |
1571 | (e-t (completing-read |
1572 | "Entry Type: " | |
1573 | bibtex-entry-field-alist | |
1574 | nil t))) | |
9ae11a89 ER |
1575 | (list e-t))) |
1576 | (if (and (null required) (null optional)) | |
cb4ad359 | 1577 | (let* ((e (assoc-ignore-case entry-type bibtex-entry-field-alist)) |
9ae11a89 ER |
1578 | (r-n-o (elt e 1)) |
1579 | (c-ref (elt e 2))) | |
1580 | (if (null e) | |
cb4ad359 RS |
1581 | (error "Bibtex entry type %s not defined!" entry-type)) |
1582 | (if (and | |
1583 | (member entry-type bibtex-include-OPTcrossref) | |
1584 | c-ref) | |
9ae11a89 ER |
1585 | (setq required (elt c-ref 0) |
1586 | optional (elt c-ref 1)) | |
1587 | (setq required (elt r-n-o 0) | |
1588 | optional (elt r-n-o 1))))) | |
0640d7bf KH |
1589 | (let ((key |
1590 | (if bibtex-maintain-sorted-entries | |
1591 | (completing-read | |
1592 | (format "%s key: " entry-type) | |
1593 | bibtex-keys)))) | |
1594 | (if bibtex-maintain-sorted-entries | |
1595 | (bibtex-find-entry-location key) | |
1596 | (bibtex-move-outside-of-entry)) | |
e5167999 | 1597 | (insert "@" entry-type "{") |
e5167999 | 1598 | (if key |
9ae11a89 ER |
1599 | (insert key)) |
1600 | (save-excursion | |
1601 | (mapcar 'bibtex-make-field required) | |
cb4ad359 RS |
1602 | (if (member entry-type bibtex-include-OPTcrossref) |
1603 | (bibtex-make-optional-field '("crossref"))) | |
9ae11a89 | 1604 | (if bibtex-include-OPTkey |
cb4ad359 | 1605 | (bibtex-make-optional-field '("key"))) |
9ae11a89 ER |
1606 | (mapcar 'bibtex-make-optional-field optional) |
1607 | (mapcar 'bibtex-make-optional-field | |
1608 | bibtex-mode-user-optional-fields) | |
1609 | (if bibtex-include-OPTannote | |
cb4ad359 | 1610 | (bibtex-make-optional-field '("annote"))) |
9ae11a89 | 1611 | (insert "\n}\n\n")) |
0640d7bf | 1612 | (bibtex-next-field t) |
9ae11a89 | 1613 | (run-hooks 'bibtex-add-entry-hook))) |
e5167999 | 1614 | |
cb4ad359 RS |
1615 | (defun bibtex-print-help-message () |
1616 | "Prints helpful information about current field in current BibTeX entry." | |
1617 | (interactive) | |
1618 | (let* ((pnt (point)) | |
1619 | (field-name | |
1620 | (progn | |
1621 | (beginning-of-line) | |
1622 | (condition-case errname | |
1623 | (bibtex-enclosing-regexp bibtex-field) | |
1624 | (search-failed | |
1625 | (goto-char pnt) | |
1626 | (error "Not on BibTeX field"))) | |
0640d7bf KH |
1627 | (let ((mb (match-beginning bibtex-name-in-field)) |
1628 | (me (match-end bibtex-name-in-field))) | |
1629 | (goto-char mb) | |
5c69dbfc | 1630 | (buffer-substring-no-properties |
0640d7bf | 1631 | (if (looking-at "OPT") |
cb4ad359 RS |
1632 | (+ 3 mb) |
1633 | mb) | |
1634 | me)))) | |
1635 | (reference-type | |
1636 | (progn | |
1637 | (re-search-backward | |
0640d7bf | 1638 | bibtex-reference-maybe-empty-head nil t) |
5c69dbfc | 1639 | (buffer-substring-no-properties |
0640d7bf KH |
1640 | (1+ (match-beginning bibtex-type-in-head)) |
1641 | (match-end bibtex-type-in-head)))) | |
cb4ad359 RS |
1642 | (entry-list |
1643 | (assoc-ignore-case reference-type | |
1644 | bibtex-entry-field-alist)) | |
1645 | (c-r-list (elt entry-list 2)) | |
1646 | (req-opt-list | |
1647 | (if (and | |
1648 | (member reference-type bibtex-include-OPTcrossref) | |
1649 | c-r-list) | |
1650 | c-r-list | |
1651 | (elt entry-list 1))) | |
1652 | (list-of-entries (append | |
1653 | (elt req-opt-list 0) | |
1654 | (elt req-opt-list 1) | |
1655 | bibtex-mode-user-optional-fields | |
1656 | (if (member | |
1657 | reference-type | |
1658 | bibtex-include-OPTcrossref) | |
1659 | '(("crossref" | |
1660 | "Label of the crossreferenced entry"))) | |
1661 | (if bibtex-include-OPTannote | |
1662 | '(("annote" | |
1663 | "Personal annotation (ignored)"))) | |
1664 | (if bibtex-include-OPTkey | |
1665 | '(("key" | |
1666 | "Key used for label creation if author and editor fields are missing")))))) | |
1667 | (goto-char pnt) | |
31bc4210 RS |
1668 | (let ((comment (assoc-ignore-case field-name list-of-entries))) |
1669 | (if comment | |
1670 | (message (elt comment 1)) | |
1671 | (message "NO COMMENT AVAILABLE"))))) | |
d30bfc76 | 1672 | |
9ae11a89 | 1673 | (defun bibtex-make-field (e-t) |
cb4ad359 | 1674 | "Makes a field named E-T in current BibTeX entry." |
0640d7bf | 1675 | (interactive "sBibTeX field name: ") |
5c69dbfc RS |
1676 | (let ((name (if (consp e-t) |
1677 | (elt e-t 0) | |
1678 | e-t))) | |
0640d7bf KH |
1679 | (if (interactive-p) |
1680 | (progn | |
1681 | (bibtex-find-text nil) | |
1682 | (if (looking-at "[}\"]") | |
1683 | (forward-char 1)))) | |
9ae11a89 | 1684 | (insert ",\n") |
93d35499 | 1685 | (indent-to-column bibtex-name-alignment) |
9ae11a89 ER |
1686 | (insert name " = ") |
1687 | (indent-to-column bibtex-text-alignment) | |
0640d7bf KH |
1688 | (insert bibtex-field-left-delimiter bibtex-field-right-delimiter) |
1689 | (if (interactive-p) | |
1690 | (forward-char -1)))) | |
9ae11a89 ER |
1691 | |
1692 | (defun bibtex-make-optional-field (e-t) | |
cb4ad359 | 1693 | "Makes an optional field named E-T in current BibTeX entry." |
9ae11a89 ER |
1694 | (if (consp e-t) |
1695 | (setq e-t (cons (concat "OPT" (car e-t)) (cdr e-t))) | |
1696 | (setq e-t (concat "OPT" e-t))) | |
1697 | (bibtex-make-field e-t)) | |
745bc783 | 1698 | |
cb4ad359 RS |
1699 | (defun bibtex-beginning-of-entry () |
1700 | "Move to beginning of BibTeX entry. | |
1701 | If inside an entry, move to the beginning of it, otherwise move to the | |
1702 | beginning of the previous entry." | |
745bc783 | 1703 | (interactive) |
a9cb9b80 RS |
1704 | (if (looking-at "^@") |
1705 | (forward-char)) | |
cb4ad359 | 1706 | (re-search-backward "^@" nil 'move)) |
e5167999 | 1707 | |
cb4ad359 RS |
1708 | (defun bibtex-end-of-entry () |
1709 | "Move to end of BibTeX entry. | |
1710 | If inside an entry, move to the end of it, otherwise move to the end | |
a9cb9b80 | 1711 | of the previous entry." |
745bc783 | 1712 | (interactive) |
cb4ad359 RS |
1713 | (bibtex-beginning-of-entry) |
1714 | (let ((parse-sexp-ignore-comments t)) | |
a9cb9b80 | 1715 | (forward-sexp 2) ;; skip entry type and body |
cb4ad359 RS |
1716 | )) |
1717 | ||
1718 | (defun bibtex-ispell-entry () | |
1719 | "Spell whole BibTeX entry." | |
745bc783 | 1720 | (interactive) |
cb4ad359 RS |
1721 | (ispell-region (progn (bibtex-beginning-of-entry) (point)) |
1722 | (progn (bibtex-end-of-entry) (point)))) | |
745bc783 | 1723 | |
cb4ad359 RS |
1724 | (defun bibtex-ispell-abstract () |
1725 | "Spell abstract of BibTeX entry." | |
745bc783 | 1726 | (interactive) |
cb4ad359 RS |
1727 | (let ((pnt (bibtex-end-of-entry))) |
1728 | (bibtex-beginning-of-entry) | |
1729 | (if (null | |
1730 | (re-search-forward "^[ \t]*[OPT]*abstract[ \t]*=" pnt)) | |
1731 | (error "No abstract in entry."))) | |
1732 | (ispell-region (point) | |
1733 | (save-excursion (forward-sexp) (point)))) | |
745bc783 | 1734 | |
cb4ad359 RS |
1735 | (defun bibtex-narrow-to-entry () |
1736 | "Narrow buffer to current BibTeX entry." | |
745bc783 | 1737 | (interactive) |
cb4ad359 RS |
1738 | (save-excursion |
1739 | (narrow-to-region (progn (bibtex-beginning-of-entry) (point)) | |
1740 | (progn (bibtex-end-of-entry) (point))))) | |
745bc783 | 1741 | |
cb4ad359 RS |
1742 | (defun bibtex-hide-entry-bodies (&optional arg) |
1743 | "Hide all lines between first and last BibTeX entries not beginning with @. | |
1744 | With argument, show all text." | |
1745 | (interactive "P") | |
1746 | (save-excursion | |
1747 | (beginning-of-first-bibtex-entry) | |
1748 | ;; subst-char-in-region modifies the buffer, despite what the | |
1749 | ;; documentation says... | |
1750 | (let ((modifiedp (buffer-modified-p)) | |
1751 | (buffer-read-only nil)) | |
1752 | (if arg | |
1753 | (subst-char-in-region (point) (point-max) ?\r ?\n t) | |
1754 | (while (save-excursion (re-search-forward "\n[^@]" (point-max) t)) | |
1755 | ;; (save-excursion (replace-regexp "\n\\([^@]\\)" "\r\\1")) | |
1756 | (save-excursion | |
1757 | (while (re-search-forward "\n\\([^@]\\)" nil t) | |
1758 | (replace-match "\r\\1" nil nil))))) | |
1759 | (setq selective-display (not arg)) | |
1760 | (set-buffer-modified-p modifiedp)))) | |
745bc783 | 1761 | |
cb4ad359 RS |
1762 | (defun bibtex-sort-entries () |
1763 | "Sort BibTeX entries alphabetically by key. | |
0640d7bf KH |
1764 | Text outside of BibTeX entries is not affected. If |
1765 | bibtex-sort-ignore-string-entries is non-nil, @string entries will be | |
1766 | ignored." | |
745bc783 | 1767 | (interactive) |
cb4ad359 RS |
1768 | (save-restriction |
1769 | (beginning-of-first-bibtex-entry) | |
1770 | (narrow-to-region | |
1771 | (point) | |
1772 | (save-excursion | |
1773 | (goto-char (point-max)) | |
cb4ad359 RS |
1774 | (bibtex-end-of-entry) |
1775 | (point))) | |
0640d7bf KH |
1776 | (if bibtex-sort-ignore-string-entries |
1777 | (if (re-search-forward bibtex-reference nil 'move) | |
1778 | (goto-char (match-beginning 0)))) | |
cb4ad359 RS |
1779 | (sort-subr |
1780 | nil | |
1781 | ;; NEXTREC function | |
cb4ad359 RS |
1782 | (function |
1783 | (lambda () | |
0640d7bf KH |
1784 | (if bibtex-sort-ignore-string-entries |
1785 | (if (re-search-forward bibtex-reference nil 'move) | |
1786 | (goto-char (match-beginning 0))) | |
1787 | (if (re-search-forward bibtex-reference-head nil 'move) | |
1788 | (goto-char (match-beginning 0)))))) | |
1789 | ;; ENDREC function | |
1790 | 'bibtex-end-of-entry | |
cb4ad359 | 1791 | ;; STARTKEY function |
cb4ad359 RS |
1792 | (function |
1793 | (lambda () | |
0640d7bf KH |
1794 | (if bibtex-sort-ignore-string-entries |
1795 | (progn | |
1796 | (re-search-forward bibtex-reference) | |
1797 | (buffer-substring-no-properties | |
1798 | (match-beginning bibtex-key-in-reference) | |
1799 | (match-end bibtex-key-in-reference))) | |
1800 | (re-search-forward bibtex-reference-head) | |
1801 | (buffer-substring-no-properties | |
1802 | (match-beginning bibtex-key-in-head) | |
1803 | (match-end bibtex-key-in-head))))) | |
1804 | ;; ENDKEY function | |
1805 | nil))) | |
cb4ad359 | 1806 | |
0640d7bf | 1807 | (defun bibtex-find-entry-location (entry-name &optional ignore-dups) |
cb4ad359 | 1808 | "Looking for place to put the BibTeX entry named ENTRY-NAME. |
0640d7bf KH |
1809 | Performs a binary search (therefore, buffer is assumed to be in sorted |
1810 | order, without duplicates (see \\[bibtex-validate-buffer]), if it is | |
1811 | not, bibtex-find-entry-location will fail). If entry-name is already | |
2e282f92 | 1812 | used as a reference key, an error is signaled. However, if optional |
0640d7bf | 1813 | variable IGNORE-DUPS is non-nil, no error messages about duplicate |
2e282f92 | 1814 | entries are signaled, but the error handling is assumed to be made in |
0640d7bf | 1815 | the calling function. Nil is returned, if an duplicate entry error |
2e282f92 | 1816 | occurred, and t in all other cases." |
0640d7bf KH |
1817 | (let* ((left |
1818 | (progn | |
1819 | (beginning-of-first-bibtex-entry) | |
1820 | (if bibtex-sort-ignore-string-entries | |
1821 | (re-search-forward bibtex-reference nil `move) | |
1822 | (bibtex-end-of-entry)) | |
1823 | (point))) | |
1824 | (right | |
1825 | (progn | |
1826 | (goto-char (point-max)) | |
1827 | (if bibtex-sort-ignore-string-entries | |
1828 | (re-search-backward bibtex-reference nil `move) | |
1829 | (bibtex-beginning-of-entry)) | |
1830 | (point))) | |
1831 | actual-point | |
1832 | actual-key | |
1833 | (done (>= left right)) | |
1834 | new | |
1835 | dup) | |
1836 | (while (not done) | |
1837 | (setq actual-point (/ (+ left right) 2)) | |
1838 | (goto-char actual-point) | |
1839 | (bibtex-beginning-of-entry) | |
1840 | (setq actual-key | |
1841 | (if bibtex-sort-ignore-string-entries | |
1842 | (progn | |
1843 | (re-search-forward bibtex-reference) | |
1844 | (buffer-substring-no-properties | |
1845 | (match-beginning bibtex-key-in-reference) | |
1846 | (match-end bibtex-key-in-reference))) | |
1847 | (re-search-forward bibtex-reference-head) | |
1848 | (buffer-substring-no-properties | |
1849 | (match-beginning bibtex-key-in-head) | |
1850 | (match-end bibtex-key-in-head)))) | |
1851 | (cond | |
1852 | ((string-lessp entry-name actual-key) | |
1853 | (setq new (match-beginning 0)) | |
1854 | (if (equal right new) | |
1855 | (setq done t) | |
1856 | (setq right new))) | |
1857 | ((string-lessp actual-key entry-name) | |
1858 | (setq new (match-end 0)) | |
1859 | (if (equal left new) | |
1860 | (setq done t) | |
1861 | (setq left new))) | |
1862 | ((string-equal actual-key entry-name) | |
1863 | (setq dup t | |
1864 | done t) | |
1865 | (if (not ignore-dups) | |
1866 | (error "Entry with key `%s' already exists!" entry-name))))) | |
1867 | (if dup | |
1868 | nil | |
1869 | (goto-char right) | |
1870 | (if (re-search-forward bibtex-reference nil t) | |
1871 | (progn | |
1872 | (setq actual-key | |
1873 | (buffer-substring-no-properties | |
1874 | (match-beginning bibtex-key-in-reference) | |
1875 | (match-end bibtex-key-in-reference))) | |
1876 | (if (string-lessp actual-key entry-name) | |
1877 | ;; even greater than last entry --> we must append | |
1878 | (progn | |
1879 | (goto-char (match-end 0)) | |
1880 | (newline (forward-line 2)) | |
1881 | (beginning-of-line)) | |
1882 | (goto-char right)))) | |
1883 | t))) | |
cb4ad359 | 1884 | |
31bc4210 | 1885 | (defun bibtex-validate-buffer (&optional from-point) |
cb4ad359 RS |
1886 | "Validate if the current BibTeX buffer is syntactically correct. |
1887 | Any garbage (e.g. comments) before the first \"@\" is not tested (so | |
31bc4210 RS |
1888 | you can put comments here). |
1889 | With non-nil FROM-POINT it starts with entry enclosing point." | |
1890 | (interactive "P") | |
cb4ad359 | 1891 | (let ((pnt (point)) |
31bc4210 RS |
1892 | (starting-point |
1893 | (progn | |
1894 | (if from-point | |
1895 | (bibtex-beginning-of-entry) | |
1896 | (beginning-of-first-bibtex-entry)) | |
1897 | (point)))) | |
0640d7bf | 1898 | ;; looking if entries fit syntactical structure |
31bc4210 RS |
1899 | (goto-char starting-point) |
1900 | (while (re-search-forward "^@" nil t) | |
cb4ad359 RS |
1901 | (forward-char -1) |
1902 | (let ((p (point))) | |
0640d7bf KH |
1903 | (if (or |
1904 | (looking-at "@string") | |
1905 | (looking-at "@preamble")) | |
cb4ad359 RS |
1906 | (forward-char) |
1907 | (if (not (and | |
1908 | (re-search-forward bibtex-reference nil t) | |
1909 | (equal p (match-beginning 0)))) | |
1910 | (progn | |
1911 | (goto-char p) | |
1912 | (error "Bad entry begins here")))))) | |
0640d7bf KH |
1913 | ;; looking if entries are balanced (a single non-escaped quote |
1914 | ;; inside braces is not detected by the former check, but | |
1915 | ;; bibtex-sort-entries stumbles about it | |
31bc4210 | 1916 | (goto-char starting-point) |
0640d7bf KH |
1917 | (map-bibtex-entries |
1918 | (function | |
1919 | (lambda (current) | |
1920 | (bibtex-beginning-of-entry) | |
1921 | (forward-sexp 2)))) | |
1922 | ;; looking for correct sort order and duplicates | |
1923 | (if bibtex-maintain-sorted-entries | |
31bc4210 | 1924 | (let (previous |
0640d7bf | 1925 | point) |
31bc4210 | 1926 | (goto-char starting-point) |
0640d7bf KH |
1927 | (map-bibtex-entries |
1928 | (function | |
1929 | (lambda (current) | |
1930 | (cond ((or (null previous) | |
1931 | (string< previous current)) | |
1932 | (setq previous current | |
1933 | point (point))) | |
1934 | ((string-equal previous current) | |
1935 | (error "Duplicate here with previous!")) | |
1936 | (t | |
1937 | (error "Entries out of order here!")))))))) | |
cb4ad359 | 1938 | (goto-char pnt) |
31bc4210 RS |
1939 | (if from-point |
1940 | (message "Part of BibTeX buffer starting at point is syntactically correct") | |
1941 | (message "BibTeX buffer is syntactically correct")))) | |
745bc783 | 1942 | |
745bc783 | 1943 | (defun bibtex-next-field (arg) |
cb4ad359 | 1944 | "Finds end of text of next BibTeX field; with arg, to its beginning." |
745bc783 JB |
1945 | (interactive "P") |
1946 | (bibtex-inside-field) | |
1947 | (let ((start (point))) | |
1948 | (condition-case () | |
1949 | (progn | |
1950 | (bibtex-enclosing-field) | |
1951 | (goto-char (match-end 0)) | |
1952 | (forward-char 2)) | |
1953 | (error | |
1954 | (goto-char start) | |
1955 | (end-of-line) | |
1956 | (forward-char 1)))) | |
1957 | (bibtex-find-text arg)) | |
1958 | ||
1959 | (defun bibtex-find-text (arg) | |
1960 | "Go to end of text of current field; with arg, go to beginning." | |
1961 | (interactive "P") | |
1962 | (bibtex-inside-field) | |
1963 | (bibtex-enclosing-field) | |
1964 | (if arg | |
1965 | (progn | |
1966 | (goto-char (match-beginning bibtex-text-in-field)) | |
a9cb9b80 | 1967 | (if (looking-at "[{\"]") |
745bc783 JB |
1968 | (forward-char 1))) |
1969 | (goto-char (match-end bibtex-text-in-field)) | |
a9cb9b80 RS |
1970 | (if (or |
1971 | (= (preceding-char) ?}) | |
1972 | (= (preceding-char) ?\")) | |
cb4ad359 RS |
1973 | (forward-char -1))) |
1974 | (if bibtex-help-message | |
1975 | (bibtex-print-help-message))) | |
e5167999 | 1976 | |
745bc783 | 1977 | (defun bibtex-remove-OPT () |
cb4ad359 | 1978 | "Removes the 'OPT' starting optional arguments and goes to end of text." |
745bc783 JB |
1979 | (interactive) |
1980 | (bibtex-inside-field) | |
1981 | (bibtex-enclosing-field) | |
1982 | (save-excursion | |
1983 | (goto-char (match-beginning bibtex-name-in-field)) | |
1984 | (if (looking-at "OPT") | |
9ae11a89 ER |
1985 | ;; sct@dcs.edinburgh.ac.uk |
1986 | (progn | |
1987 | (delete-char (length "OPT")) | |
1988 | (search-forward "=") | |
1989 | (delete-horizontal-space) | |
1990 | (indent-to-column bibtex-text-alignment)))) | |
745bc783 JB |
1991 | (bibtex-inside-field)) |
1992 | ||
cb4ad359 RS |
1993 | (defun bibtex-remove-double-quotes-or-braces () |
1994 | "Removes \"\" or {} around string." | |
745bc783 JB |
1995 | (interactive) |
1996 | (save-excursion | |
1997 | (bibtex-inside-field) | |
1998 | (bibtex-enclosing-field) | |
1999 | (let ((start (match-beginning bibtex-text-in-field)) | |
31bc4210 | 2000 | (stop (match-end bibtex-text-in-field))) |
745bc783 | 2001 | (goto-char start) |
31bc4210 RS |
2002 | (while (re-search-forward bibtex-field-string stop t) |
2003 | (let ((beg (match-beginning 0)) | |
2004 | (end (match-end 0))) | |
2005 | (goto-char end) | |
2006 | (forward-char -1) | |
2007 | (if (looking-at "[}\"]") | |
2008 | (delete-char 1)) | |
2009 | (goto-char beg) | |
2010 | (if (looking-at "[{\"]") | |
2011 | (delete-char 1))))))) | |
745bc783 JB |
2012 | |
2013 | (defun bibtex-kill-optional-field () | |
cb4ad359 | 2014 | "Kill the entire enclosing optional BibTeX field." |
745bc783 JB |
2015 | (interactive) |
2016 | (bibtex-inside-field) | |
2017 | (bibtex-enclosing-field) | |
2018 | (goto-char (match-beginning bibtex-name-in-field)) | |
2019 | (let ((the-end (match-end 0)) | |
2020 | (the-beginning (match-beginning 0))) | |
2021 | (if (looking-at "OPT") | |
2022 | (progn | |
2023 | (goto-char the-end) | |
2024 | (skip-chars-forward " \t\n,") | |
2025 | (kill-region the-beginning the-end)) | |
2026 | (error "Mandatory fields can't be killed")))) | |
2027 | ||
2028 | (defun bibtex-empty-field () | |
cb4ad359 | 2029 | "Delete the text part of the current field, replace with empty text." |
745bc783 JB |
2030 | (interactive) |
2031 | (bibtex-inside-field) | |
2032 | (bibtex-enclosing-field) | |
2033 | (goto-char (match-beginning bibtex-text-in-field)) | |
2034 | (kill-region (point) (match-end bibtex-text-in-field)) | |
cb4ad359 RS |
2035 | (insert (concat bibtex-field-left-delimiter |
2036 | bibtex-field-right-delimiter)) | |
745bc783 JB |
2037 | (bibtex-find-text t)) |
2038 | ||
31bc4210 RS |
2039 | (defun bibtex-pop (arg direction) |
2040 | ;; generic function to be used by bibtex-pop-previous and bibtex-pop-next | |
2041 | (let (bibtex-help-message) | |
2042 | (bibtex-find-text nil)) | |
745bc783 | 2043 | (save-excursion |
31bc4210 RS |
2044 | ;; parse current field |
2045 | (bibtex-inside-field) | |
745bc783 JB |
2046 | (bibtex-enclosing-field) |
2047 | (let ((start-old-text (match-beginning bibtex-text-in-field)) | |
2048 | (stop-old-text (match-end bibtex-text-in-field)) | |
2049 | (start-name (match-beginning bibtex-name-in-field)) | |
2050 | (stop-name (match-end bibtex-name-in-field)) | |
2051 | (new-text)) | |
2052 | (goto-char start-name) | |
31bc4210 RS |
2053 | ;; construct regexp for field with same name as this one, |
2054 | ;; ignoring possible OPT's | |
745bc783 JB |
2055 | (let ((matching-entry |
2056 | (bibtex-cfield | |
5c69dbfc RS |
2057 | (buffer-substring-no-properties (if (looking-at "OPT") |
2058 | (+ (point) (length "OPT")) | |
2059 | (point)) | |
2060 | stop-name) | |
745bc783 | 2061 | bibtex-field-text))) |
31bc4210 RS |
2062 | ;; if executed several times in a row, start each search where |
2063 | ;; the last one was finished | |
2064 | (cond ((eq last-command 'bibtex-pop) | |
2065 | t | |
2066 | ) | |
745bc783 | 2067 | (t |
0640d7bf | 2068 | (bibtex-enclosing-reference-maybe-empty-head) |
cb4ad359 | 2069 | (setq bibtex-pop-previous-search-point (point)) |
745bc783 | 2070 | (setq bibtex-pop-next-search-point (match-end 0)))) |
31bc4210 RS |
2071 | (if (eq direction 'previous) |
2072 | (goto-char bibtex-pop-previous-search-point) | |
2073 | (goto-char bibtex-pop-next-search-point)) | |
2074 | ;; Now search for arg'th previous/next similar field | |
745bc783 | 2075 | (cond |
31bc4210 RS |
2076 | ((if (eq direction 'previous) |
2077 | (re-search-backward matching-entry (point-min) t arg) | |
2078 | (re-search-forward matching-entry (point-max) t arg)) | |
2079 | ;; Found a matching field. Remember boundaries. | |
2080 | (setq bibtex-pop-previous-search-point (match-beginning 0)) | |
2081 | (setq bibtex-pop-next-search-point (match-end 0)) | |
2082 | (setq new-text | |
5c69dbfc | 2083 | (buffer-substring-no-properties |
31bc4210 RS |
2084 | (match-beginning bibtex-text-in-field) |
2085 | (match-end bibtex-text-in-field))) | |
cb4ad359 | 2086 | ;; change delimiters, if any changes needed |
31bc4210 RS |
2087 | (let ((start 0) |
2088 | old-open | |
2089 | new-open | |
2090 | old-close | |
2091 | new-close) | |
2092 | (if (equal bibtex-field-left-delimiter "{") | |
2093 | (setq old-open ?\" | |
2094 | new-open ?\{ | |
2095 | old-close ?\" | |
2096 | new-close ?\}) | |
2097 | (setq old-open ?\{ | |
2098 | new-open ?\" | |
2099 | old-close ?\} | |
2100 | new-close ?\")) | |
2101 | (while (string-match bibtex-field-string new-text start) | |
2102 | (let ((beg (match-beginning 0)) | |
2103 | (end (1- (match-end 0)))) | |
2104 | (if (and | |
2105 | (eq (aref new-text beg) old-open) | |
2106 | (eq (aref new-text end) old-close)) | |
2107 | (progn | |
2108 | (aset new-text beg new-open) | |
2109 | (aset new-text end new-close)))) | |
2110 | (setq start (match-end 0)))) | |
745bc783 | 2111 | (bibtex-flash-head) |
31bc4210 | 2112 | ;; Go back to where we started, delete old text, and pop new. |
745bc783 JB |
2113 | (goto-char stop-old-text) |
2114 | (delete-region start-old-text stop-old-text) | |
2115 | (insert new-text)) | |
31bc4210 RS |
2116 | (t |
2117 | ;; search failed | |
2118 | (error (concat "No " | |
2119 | (if (eq direction 'previous) | |
2120 | "previous" | |
2121 | "next") | |
2122 | " matching BibTeX field."))))))) | |
2123 | (let (bibtex-help-message) | |
2124 | (bibtex-find-text nil)) | |
2125 | (setq this-command 'bibtex-pop)) | |
2126 | ||
2127 | (defun bibtex-pop-previous (arg) | |
2128 | "Replace text of current field with the text of similar field in previous entry. | |
2129 | With arg, goes up ARG entries. Repeated, goes up so many times. May be | |
2130 | intermixed with \\[bibtex-pop-next] (bibtex-pop-next)." | |
2131 | (interactive "p") | |
2132 | (bibtex-pop arg 'previous)) | |
745bc783 JB |
2133 | |
2134 | (defun bibtex-pop-next (arg) | |
2135 | "Replace text of current field with the text of similar field in next entry. | |
31bc4210 | 2136 | With arg, goes down ARG entries. Repeated, goes down so many times. May be |
745bc783 JB |
2137 | intermixed with \\[bibtex-pop-previous] (bibtex-pop-previous)." |
2138 | (interactive "p") | |
31bc4210 | 2139 | (bibtex-pop arg 'next)) |
745bc783 | 2140 | |
cb4ad359 RS |
2141 | (defun bibtex-clean-entry (&optional arg) |
2142 | "Finish editing the current BibTeX entry and clean it up. | |
2143 | For all optional fields of current BibTeX entry: if empty, kill the | |
2144 | whole field; otherwise, remove the \"OPT\" string in the name; if text | |
2145 | numerical, remove double-quotes. For all mandatory fields: if empty, | |
2146 | signal error. If label of entry is empty or a prefix argument was | |
2147 | given, calculate a new entry label." | |
2148 | (interactive "P") | |
2149 | (bibtex-beginning-of-entry) | |
2150 | (let ((start (point)) | |
2151 | crossref-there) | |
745bc783 | 2152 | (save-restriction |
cb4ad359 RS |
2153 | (narrow-to-region start (save-excursion (bibtex-end-of-entry) (point))) |
2154 | (while (and | |
2155 | (re-search-forward bibtex-field (point-max) t 1) | |
2156 | (not crossref-there)) | |
2157 | ;; determine if reference has crossref entry | |
2158 | (let ((begin-name (match-beginning bibtex-name-in-field)) | |
2159 | (begin-text (match-beginning bibtex-text-in-field))) | |
745bc783 | 2160 | (goto-char begin-name) |
cb4ad359 RS |
2161 | (if (looking-at "\\(OPTcrossref\\)\\|\\(crossref\\)") |
2162 | (progn | |
2163 | (goto-char begin-text) | |
31bc4210 | 2164 | (if (not (looking-at "\\(\"\"\\)\\|\\({}\\)")) |
cb4ad359 | 2165 | (setq crossref-there t)))))) |
0640d7bf | 2166 | (bibtex-enclosing-reference-maybe-empty-head) |
cb4ad359 RS |
2167 | (re-search-forward bibtex-reference-type) |
2168 | (let ((begin-type (1+ (match-beginning 0))) | |
2169 | (end-type (match-end 0))) | |
2170 | (goto-char start) | |
2171 | (while (re-search-forward bibtex-field (point-max) t 1) | |
2172 | (let ((begin-field (match-beginning 0)) | |
2173 | (end-field (match-end 0)) | |
2174 | (begin-name (match-beginning bibtex-name-in-field)) | |
2175 | (end-name (match-end bibtex-name-in-field)) | |
2176 | (begin-text (match-beginning bibtex-text-in-field)) | |
2177 | (end-text (match-end bibtex-text-in-field)) | |
2178 | ) | |
2179 | (goto-char begin-name) | |
2180 | (cond ((and | |
2181 | (looking-at "OPT") | |
2182 | bibtex-clean-entry-zap-empty-opts) | |
2183 | (goto-char begin-text) | |
31bc4210 | 2184 | (if (looking-at "\\(\"\"\\)\\|\\({}\\)") |
cb4ad359 RS |
2185 | ;; empty: delete whole field if really optional |
2186 | ;; (missing crossref handled) or complain | |
2187 | (if (and | |
2188 | (not crossref-there) | |
2189 | (assoc | |
2190 | (downcase | |
5c69dbfc | 2191 | (buffer-substring-no-properties |
cb4ad359 RS |
2192 | (+ (length "OPT") begin-name) end-name)) |
2193 | (car (car (cdr | |
2194 | (assoc-ignore-case | |
5c69dbfc RS |
2195 | (buffer-substring-no-properties |
2196 | begin-type end-type) | |
cb4ad359 RS |
2197 | bibtex-entry-field-alist)))))) |
2198 | ;; field is not really optional | |
2199 | (progn | |
2200 | (goto-char begin-name) | |
2201 | (delete-char (length "OPT")) | |
2202 | ;; make field non-OPT | |
2203 | (search-forward "=") | |
2204 | (delete-horizontal-space) | |
2205 | (indent-to-column bibtex-text-alignment) | |
2206 | (forward-char) | |
2207 | ;; and loop to go through next test | |
2208 | (error "Mandatory field ``%s'' is empty" | |
5c69dbfc RS |
2209 | (buffer-substring-no-properties |
2210 | begin-name | |
2211 | end-name))) | |
cb4ad359 RS |
2212 | ;; field is optional |
2213 | (delete-region begin-field end-field)) | |
2214 | ;; otherwise: not empty, delete "OPT" | |
2215 | (goto-char begin-name) | |
2216 | (delete-char (length "OPT")) | |
2217 | (progn | |
2218 | ;; fixup alignment. [alarson:19920309.2047CST] | |
2219 | (search-forward "=") | |
2220 | (delete-horizontal-space) | |
2221 | (indent-to-column bibtex-text-alignment)) | |
31bc4210 RS |
2222 | (goto-char begin-field) |
2223 | ;; and loop to go through next test | |
cb4ad359 RS |
2224 | )) |
2225 | (t | |
2226 | (goto-char begin-text) | |
31bc4210 | 2227 | (cond ((looking-at "\\(\"[0-9]+\"\\)\\|\\({[0-9]+}\\)") |
cb4ad359 RS |
2228 | ;; if numerical, |
2229 | (goto-char end-text) | |
31bc4210 | 2230 | (delete-char -1) |
cb4ad359 RS |
2231 | (goto-char begin-text) |
2232 | (delete-char 1) | |
31bc4210 RS |
2233 | ;; delete enclosing delimiters |
2234 | (goto-char end-field) | |
2235 | ;; go to end for next search | |
2236 | (forward-char -2) | |
2237 | ;; to compensate for the 2 delimiters deleted | |
cb4ad359 | 2238 | ) |
31bc4210 RS |
2239 | ((looking-at "\\(\"\"\\)\\|\\({}\\)") |
2240 | ;; if empty field, complain | |
cb4ad359 | 2241 | (forward-char 1) |
5c69dbfc | 2242 | (if (not (or (equal (buffer-substring-no-properties |
cb4ad359 RS |
2243 | begin-name |
2244 | (+ begin-name 3)) | |
2245 | "OPT") | |
5c69dbfc | 2246 | (equal (buffer-substring-no-properties |
cb4ad359 RS |
2247 | begin-name |
2248 | (+ begin-name 3)) | |
2249 | "opt"))) | |
2250 | (error "Mandatory field ``%s'' is empty" | |
5c69dbfc RS |
2251 | (buffer-substring-no-properties |
2252 | begin-name end-name)))) | |
cb4ad359 RS |
2253 | (t |
2254 | (goto-char end-field))))))))) | |
745bc783 | 2255 | (goto-char start) |
0640d7bf | 2256 | (bibtex-end-of-entry)) |
cb4ad359 | 2257 | (let* ((eob (progn |
cb4ad359 RS |
2258 | (bibtex-end-of-entry) |
2259 | (point))) | |
2260 | (key (progn | |
2261 | (bibtex-beginning-of-entry) | |
0640d7bf | 2262 | (if (re-search-forward |
cb4ad359 | 2263 | bibtex-reference-head eob t) |
5c69dbfc | 2264 | (buffer-substring-no-properties |
cb4ad359 RS |
2265 | (match-beginning bibtex-key-in-head) |
2266 | (match-end bibtex-key-in-head)))))) | |
2267 | (if (or | |
2268 | arg | |
2269 | (not key)) | |
2270 | (progn | |
2271 | (let ((autokey | |
2272 | (if bibtex-autokey-edit-before-use | |
2273 | (read-from-minibuffer "Key to use: " | |
2274 | (bibtex-generate-autokey)) | |
2275 | (bibtex-generate-autokey)))) | |
2276 | (bibtex-beginning-of-entry) | |
0640d7bf KH |
2277 | (re-search-forward bibtex-reference-maybe-empty-head) |
2278 | (if (match-beginning bibtex-key-in-head) | |
2279 | (delete-region (match-beginning bibtex-key-in-head) | |
2280 | (match-end bibtex-key-in-head))) | |
cb4ad359 RS |
2281 | (insert autokey) |
2282 | (let ((start (progn | |
2283 | (bibtex-beginning-of-entry) | |
2284 | (point))) | |
2285 | (end (progn | |
2286 | (bibtex-end-of-entry) | |
0640d7bf | 2287 | (re-search-forward "^@" nil 'move) |
cb4ad359 | 2288 | (beginning-of-line) |
fa59ceb3 RS |
2289 | (point))) |
2290 | last-command) | |
cb4ad359 | 2291 | (kill-region start end) |
0640d7bf KH |
2292 | (let ((success |
2293 | (or | |
2294 | (not bibtex-maintain-sorted-entries) | |
2295 | (bibtex-find-entry-location autokey t)))) | |
cb4ad359 | 2296 | (yank) |
cb4ad359 | 2297 | (setq kill-ring (cdr kill-ring)) |
0640d7bf KH |
2298 | (forward-char -1) |
2299 | (bibtex-beginning-of-entry) | |
2300 | (re-search-forward bibtex-reference-head) | |
cb4ad359 RS |
2301 | (if (not success) |
2302 | (error | |
0640d7bf KH |
2303 | "New inserted reference may be a duplicate.")))))))) |
2304 | (save-excursion | |
2305 | (let ((start (progn (bibtex-beginning-of-entry) (point))) | |
2306 | (end (progn (bibtex-end-of-entry) (point)))) | |
2307 | (save-restriction | |
2308 | (narrow-to-region start end) | |
2309 | (bibtex-parse-keys t))))) | |
cb4ad359 RS |
2310 | |
2311 | (defun bibtex-complete-string () | |
2312 | "Complete word fragment before point to longest prefix of a defined string. | |
2313 | If point is not after the part of a word, all strings are listed." | |
2314 | (interactive "*") | |
2315 | (let* ((end (point)) | |
2316 | (beg (save-excursion | |
2317 | (re-search-backward "[ \t{\"]") | |
2318 | (forward-char 1) | |
2319 | (point))) | |
5c69dbfc | 2320 | (part-of-word (buffer-substring-no-properties beg end)) |
cb4ad359 RS |
2321 | (string-list (copy-sequence bibtex-completion-candidates)) |
2322 | (case-fold-search t) | |
2323 | (completion (save-excursion | |
31bc4210 RS |
2324 | (while (re-search-backward |
2325 | bibtex-string (point-min) t) | |
cb4ad359 | 2326 | (setq string-list |
31bc4210 RS |
2327 | (cons |
2328 | (list | |
2329 | (buffer-substring-no-properties | |
2330 | (match-beginning bibtex-key-in-string) | |
2331 | (match-end bibtex-key-in-string))) | |
2332 | string-list))) | |
2333 | (setq string-list | |
2334 | (sort string-list | |
2335 | (lambda(x y) | |
2336 | (string-lessp | |
2337 | (car x) | |
2338 | (car y))))) | |
2339 | (try-completion part-of-word string-list)))) | |
cb4ad359 | 2340 | (cond ((eq completion t) |
31bc4210 RS |
2341 | ;; remove double-quotes or braces if field is no concatenation |
2342 | (save-excursion | |
2343 | (bibtex-inside-field) | |
2344 | (bibtex-enclosing-field) | |
2345 | (let ((end (match-end bibtex-text-in-field))) | |
2346 | (goto-char (match-beginning bibtex-text-in-field)) | |
2347 | (if (and | |
2348 | (looking-at bibtex-field-string) | |
2349 | (equal (match-end 0) end)) | |
2350 | (bibtex-remove-double-quotes-or-braces))))) | |
cb4ad359 RS |
2351 | ((null completion) |
2352 | (error "Can't find completion for \"%s\"" part-of-word)) | |
2353 | ((not (string= part-of-word completion)) | |
2354 | (delete-region beg end) | |
2355 | (insert completion) | |
2356 | (if (assoc completion string-list) | |
31bc4210 RS |
2357 | ;; remove double-quotes or braces if field is no concatenation |
2358 | (save-excursion | |
2359 | (bibtex-inside-field) | |
2360 | (bibtex-enclosing-field) | |
2361 | (let ((end (match-end bibtex-text-in-field))) | |
2362 | (goto-char (match-beginning bibtex-text-in-field)) | |
2363 | (if (and | |
2364 | (looking-at bibtex-field-string) | |
2365 | (equal (match-end 0) end)) | |
2366 | (bibtex-remove-double-quotes-or-braces)))))) | |
cb4ad359 RS |
2367 | (t |
2368 | (message "Making completion list...") | |
2369 | (let ((list (all-completions part-of-word string-list))) | |
2370 | (with-output-to-temp-buffer "*Completions*" | |
2371 | (display-completion-list list))) | |
2372 | (message "Making completion list...done"))))) | |
745bc783 | 2373 | |
cb4ad359 RS |
2374 | (defun bibtex-Article () |
2375 | (interactive) | |
2376 | (bibtex-entry "Article")) | |
2798dfd6 | 2377 | |
cb4ad359 RS |
2378 | (defun bibtex-Book () |
2379 | (interactive) | |
2380 | (bibtex-entry "Book")) | |
2798dfd6 | 2381 | |
cb4ad359 RS |
2382 | (defun bibtex-Booklet () |
2383 | (interactive) | |
2384 | (bibtex-entry "Booklet")) | |
2385 | ||
2386 | (defun bibtex-InBook () | |
2387 | (interactive) | |
2388 | (bibtex-entry "InBook")) | |
2389 | ||
2390 | (defun bibtex-InCollection () | |
2391 | (interactive) | |
2392 | (bibtex-entry "InCollection")) | |
2393 | ||
2394 | (defun bibtex-InProceedings () | |
2395 | (interactive) | |
2396 | (bibtex-entry "InProceedings")) | |
2397 | ||
2398 | (defun bibtex-Manual () | |
2399 | (interactive) | |
2400 | (bibtex-entry "Manual")) | |
2401 | ||
2402 | (defun bibtex-MastersThesis () | |
2403 | (interactive) | |
2404 | (bibtex-entry "MastersThesis")) | |
2405 | ||
2406 | (defun bibtex-Misc () | |
2407 | (interactive) | |
2408 | (bibtex-entry "Misc")) | |
2409 | ||
2410 | (defun bibtex-PhdThesis () | |
2411 | (interactive) | |
2412 | (bibtex-entry "PhdThesis")) | |
2413 | ||
2414 | (defun bibtex-Proceedings () | |
2415 | (interactive) | |
2416 | (bibtex-entry "Proceedings")) | |
2417 | ||
2418 | (defun bibtex-TechReport () | |
2419 | (interactive) | |
2420 | (bibtex-entry "TechReport")) | |
2421 | ||
2422 | (defun bibtex-Unpublished () | |
2423 | (interactive) | |
2424 | (bibtex-entry "Unpublished")) | |
2425 | ||
2426 | (defun bibtex-string () | |
2427 | (interactive) | |
2428 | (bibtex-move-outside-of-entry) | |
2429 | (insert | |
2430 | (concat | |
2431 | "@string{ = " | |
2432 | bibtex-field-left-delimiter | |
2433 | bibtex-field-right-delimiter | |
2434 | "}\n")) | |
2435 | (forward-line -1) | |
2436 | (forward-char 8)) | |
2437 | ||
2438 | (defun bibtex-preamble () | |
2439 | (interactive) | |
2440 | (bibtex-move-outside-of-entry) | |
2441 | (insert "@Preamble{}\n") | |
2442 | (forward-line -1) | |
2443 | (forward-char 10)) | |
2798dfd6 | 2444 | |
745bc783 | 2445 | \f |
5c69dbfc | 2446 | ;; Make BibTeX a Feature |
cb4ad359 RS |
2447 | |
2448 | (provide 'bibtex) | |
745bc783 | 2449 | |
9ae11a89 | 2450 | ;;; bibtex.el ends here |