Mercurial > hg > xemacs-beta
comparison lisp/modes/bibtex.el @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | ac2d302a0011 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
1 ;;; bibtex.el --- BibTeX mode for GNU Emacs | |
2 | |
3 ;; Copyright (C) 1992 Free Software Foundation, Inc. | |
4 | |
5 ;; Author: Bengt Martensson <ubrinf!mond!bengt> | |
6 ;; Mark Shapiro <shapiro@corto.inria.fr> | |
7 ;; Mike Newton <newton@gumby.cs.caltech.edu> | |
8 ;; Aaron Larson <alarson@src.honeywell.com> | |
9 ;; Version: 1.3.1 | |
10 ;; Maintainer:Aaron Larson <alarson@src.honeywell.com> | |
11 ;; Adapted-By: ESR | |
12 ;; Keywords: tex, bib | |
13 | |
14 ;; This file is part of XEmacs. | |
15 | |
16 ;; XEmacs is free software; you can redistribute it and/or modify it | |
17 ;; under the terms of the GNU General Public License as published by | |
18 ;; the Free Software Foundation; either version 2, or (at your option) | |
19 ;; any later version. | |
20 | |
21 ;; XEmacs is distributed in the hope that it will be useful, but | |
22 ;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
23 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
24 ;; General Public License for more details. | |
25 | |
26 ;; You should have received a copy of the GNU General Public License | |
27 ;; along with XEmacs; see the file COPYING. If not, write to the Free | |
28 ;; Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | |
29 | |
30 ;;; TODO distribute texinfo file. | |
31 | |
32 ;;; LCD Archive Entry: | |
33 ;;; bibtex-mode|Bengt Martensson, Marc Shapiro, Aaron Larson| | |
34 ;;; alarson@src.honeywell.com| | |
35 ;;; Support for maintaining BibTeX format bibliography databases| | |
36 ;;; 93-03-29|version 1.3|~/modes/bibtex-mode.el.Z| | |
37 | |
38 ;;; Commentary: | |
39 | |
40 ;;; BUGS: | |
41 ;;; 1. using regular expressions to match the entire bibtex entry dies | |
42 ;;; on long bibtex entires (e.g. those containing abstracts) since | |
43 ;;; the length of regular expression matches is fairly limited. | |
44 ;;; 2. When inserting a string (with \C-C\C-E\s) hitting a TAB results | |
45 ;;; in the error message "Can't find enclosing Bibtex field" instead | |
46 ;;; of moving to the empty string. [reported by gernot@cs.unsw.oz.au] | |
47 ;;; 3. Function string-equalp should be in a library file, not in this | |
48 ;;; file. | |
49 | |
50 ;;; (current keeper: alarson@src.honeywell.com | |
51 ;;; previous: shapiro@corto.inria.fr) | |
52 | |
53 ;;; Change Log: | |
54 | |
55 ;; Mon Mar 29 14:06:06 1993 Aaron Larson (alarson at gendibal) | |
56 ;; | |
57 ;; * bibtex.el: V1.3 released Mar 30, 1993 | |
58 ;; (bibtex-field-name): Fix to match definition if latex manual, | |
59 ;; specifically letters, digits, and punctuation other than comma. | |
60 ;; Underscore is retained for historical reasons. | |
61 ;; (bibtex-make-field): Fix to work around bug in Lucid prin1-to-string | |
62 ;; function as reported by Martin Sjolin <marsj@ida.liu.se>. | |
63 ;; (bibtex-entry): minor code cleanup. | |
64 ;; (bibtex-mode-map): Remove key binding (C-c n) for | |
65 ;; narrow-to-bibtex-entry, previous binding violated emacs policy of | |
66 ;; reserving C-c followed by a letter for user customization. | |
67 ;; revise modification history to better conform to FSF changelog | |
68 ;; standards. | |
69 ;; (bibtex-refile-entry): Removed. Would need disclaimer papers to | |
70 ;; incorporate it into official sources, and unable to contact author. | |
71 ;; Fix minor "syntax" errors in documentation strings and such found | |
72 ;; by new byte compiler. Funs bibtex-mode, bibtex-remove-double-quotes | |
73 ;; | |
74 ;; | |
75 ;; Fri Jan 15 14:06:06 1993 Aaron Larson (alarson at gendibal) | |
76 ;; | |
77 ;; * bibtex.el: V1.2 released Feb 15 1993 | |
78 ;; (find-bibtex-entry-location bibtex-make-field): Fixed placement of | |
79 ;; "interactive specification". [Bug report from | |
80 ;; mernst@theory.lcs.mit.edu] | |
81 ;; Fixed problem where bibtex-entry would fail if user typed entry | |
82 ;; name in wrong case. | |
83 ;; (bibtex-inside-field) Position the cursor _before_ the last comma | |
84 ;; on a line (the comma is not necessarily "inside" the field); this | |
85 ;; does not seem to break any existing code. ref sct@dcs.edinburgh.ac.uk | |
86 ;; (bibtex-enclosing-field, bibtex-enclosing-reference): leave | |
87 ;; point unmoved if no enclosing field/reference is found. As a | |
88 ;; result of changes (3) and (4) bibtex-next-field works properly, | |
89 ;; even when called from the entry key position. | |
90 ;; (bibtex-remove-OPT): realign the '=' after removing the 'opt'. | |
91 ;; (bibtex-clean-entry): always remove any trailing comma from the | |
92 ;; end of a bibtex entry (these commas get stripped automatically when | |
93 ;; optional fields are killed by bibtex-kill-optional-field, but can be | |
94 ;; left if optional fields are removed by other means). | |
95 ;; (bibtex-x-help) Replace tab with spaces in X menu as noted by | |
96 ;; khera@cs.duke.edu | |
97 ;; (bibtex-refile-entry): Added (from brannon@jove.cs.caltech.edu) | |
98 ;; (bibtex-sort-ignore-string-entries sort-bibtex-entries, | |
99 ;; map-bibtex-entries): Added variable as requested by | |
100 ;; gernot@cs.unsw.oz.au, required changes to funs. | |
101 ;; (bibtex-current-entry-label): Added at request of | |
102 ;; yasuro@maekawa.is.uec.ac.jp | |
103 ;; (bibtex-DEAthesis:) Deleted along with corresponding entry from | |
104 ;; bibtex-x-help per shapiro@corto.inria.fr | |
105 ;; Moved narrow-to-bibtex-entry from C-c C-n to C-c n (the previous | |
106 ;; binding was in conflict with the binding for bibtex-pop-next. | |
107 ;; bug report from [shapiro@corto.inria.fr] | |
108 ;; | |
109 | |
110 ;;; | |
111 ;;; alarson@src.honeywell.com 92-Feb-13 | |
112 ;;; 1. Made bibtex-entry user callable, now prompts for entry type (e.g. | |
113 ;;; Article), with completion, and bound it to a key. This is now my | |
114 ;;; preferred way to add most entries. | |
115 ;;; 2. Made fields of a bibtex entry derived from the alist bibtex-entry- | |
116 ;;; field-alist. | |
117 ;;; 3. Fixed handling of escaped double quotes, e.g. "Schr{\"o}dinger". | |
118 ;;; 4. Fixed bug where unhiding bibtex entries moved point. | |
119 ;;; 5. Made "field name" specs permit (name . value) for defaulting. E.g. | |
120 ;;; (setq bibtex-mode-user-optional-fields '(("library" . "alarson"))) | |
121 ;;; will generate the field: | |
122 ;;; library = "alarson", | |
123 ;;; 6. Added binding for narrow-to-bibtex-entry | |
124 ;;; 7. Adding a bibtex entry now runs hook: bibtex-add-entry-hook | |
125 ;;; 8. Made bibtex-clean-entry fixup text alignment, and eliminated the | |
126 ;;; dependency on bibtex-enclosing-reference which has a problem with | |
127 ;;; long entries (e.g. those containing abstracts). | |
128 ;;; | |
129 ;;; alarson@src.honeywell.com 92-Jan-31 | |
130 ;;; Added support for: ispell, beginning/end of entry movement, a simple | |
131 ;;; outline like mode (hide the bodies of bibtex entries), support for | |
132 ;;; sorting bibtex entries, and maintaining them in sorted order, and | |
133 ;;; simple buffer validation. | |
134 ;;; User visible functions added: | |
135 ;;; ispell-{abstract,bibtex-entry}, {beginning,end}-of-bibtex-entry | |
136 ;;; hide-bibtex-entry-bodies, sort-bibtex-entries, validate-bibtex- | |
137 ;;; buffer, find-bibtex-duplicates | |
138 ;;; user visible variables added: | |
139 ;;; bibtex-maintain-sorted-entries | |
140 ;;; new local keybindings: | |
141 ;;; " tex-insert-quote | |
142 ;;; C-c$ ispell-bibtex-entry | |
143 ;;; M-C-a beginning-of-bibtex-entry | |
144 ;;; M-C-e end-of-bibtex-entry | |
145 ;;; Mike Newton (newton@gumby.cs.caltech.edu) 90.11.17 | |
146 ;;; * Handle items like | |
147 ;;; title = poft # "Fifth Tri-quarterly" # random-conf, | |
148 ;;; and title = {This title is inside curlies} | |
149 ;;; * added user settable, always present, optional fields | |
150 ;;; * fixed 'bibtex-find-it's doc string's location | |
151 ;;; * bibtex-field-text made more general (it wouldn't handle the # construct) | |
152 ;;; and it now handles a small subset of the {} cases | |
153 | |
154 ;;; Bengt Martensson, March 6 | |
155 ;;; Adapted to Bibtex 0.99 by updating the optional fields according | |
156 ;;; to the document BibTeXing, Oren Patashnik, dated January 31, 1988. | |
157 ;;; Updated documentation strings accordingly. Added (provide 'bibtex). | |
158 ;;; If bibtex-include-OPT-crossref is non-nil, every entry will have | |
159 ;;; an OPTcrossref field, analogously for bibtex-include-OPTkey and | |
160 ;;; bibtex-include-OPTannote. Added bibtex-preamble, bound to ^C^EP, | |
161 ;;; and also found in X- and sun-menus. Cleaned up the sun-menu | |
162 ;;; stuff, and made it more uniform with the X-menu stuff. Marc: I | |
163 ;;; strongly suspect that I broke your parsing... (Or, more | |
164 ;;; correctly, BibTeX 0.99 broke it.) | |
165 ;;; Added bibtex-clean-entry-zap-empty-opts, defvar'd to t. If it | |
166 ;;; is nil, bibtex-clean-entry will leave empty optional fields alone. | |
167 | |
168 ;;; Marc Shapiro 1-feb-89: integrated changes by Bengt Martensson 88-05-06: | |
169 ;;; Added Sun menu support. Locally bound to right mouse button in | |
170 ;;; bibtex-mode. Emacs 18.49 allows local mouse bindings!! | |
171 ;;; Commented out DEAthesis. | |
172 | |
173 ;;; Marc Shapiro 6-oct-88 | |
174 ;;; * skip-whitespace replaced by skip-chars-forward | |
175 ;;; * use indent-to-column instead of inserting tabs (changes to | |
176 ;;; bibtex-entry, bibtex-make-entry, bibtex-make-OPT-entry, renamed to | |
177 ;;; bibtex-make-optional-entry) | |
178 ;;; * C-c C-k deletes the current OPT entry entirely | |
179 ;;; * C-c C-d replaces text of field with "" | |
180 ;;; * renamed bibtex-find-it to bibtex-find-text. With arg, now goes to | |
181 ;;; start of text. Fixed bugs in it. | |
182 | |
183 ;;; Marc Shapiro 23-sep-88 | |
184 ;;; * bibtex-clean-entry moves past end of entry. | |
185 ;;; * bibtex-clean-entry signals mandatory fields left empty. | |
186 | |
187 ;;; Marc Shapiro 18-jul-88 | |
188 ;;; * Fixed bug in bibtex-flash-entry | |
189 ;;; * Moved all the entry type keystrokes to "C-c C-e something" (instead of | |
190 ;;; "C-c something" previously) to make room for more. C-c C-e is | |
191 ;;; supposed to stand for "entry" [idea taken from mail-mode]. Moved | |
192 ;;; bibtex-pop-previous to C-c C-p and bibtex-pop-next to C-c C-n. | |
193 ;;; * removed binding for "\e[25~" | |
194 ;;; * replaced bibtex-clean-optionals by bibtex-clean-entry, bound to | |
195 ;;; C-c C-c | |
196 | |
197 ;;; Marc Shapiro 13-jul-88 [based on ideas by Sacha Krakowiak of IMAG] | |
198 ;;; * bibtex-pop-previous replaces current field with value of | |
199 ;;; similar field in previous entry. May be called n times in a row | |
200 ;;; (or with arg n) to pop similar field of n'th previous entry. | |
201 ;;; There is also a bibtex-pop-next to get similar field of next | |
202 ;;; entry. | |
203 ;;; * C-c C-k now kills all empty optional fields of current entry, and | |
204 ;;; removes "OPT" for those optional fields which have text. | |
205 | |
206 ;;; Marc Shapiro 14-dec-87 | |
207 ;;; Cosmetic fixes. Fixed small bug in bibtex-move-outside-of-entry. | |
208 ;;; Skip Montanaro <steinmetz!sprite!montanaro> 7-dec-87, Shapiro 10-dec-87 | |
209 ;;; before inserting an entry, make sure we are outside of a bib entry | |
210 ;;; Marc Shapiro 3-nov-87 | |
211 ;;; addition for France: DEAthesis | |
212 ;;; Marc Shapiro 19-oct-1987 | |
213 ;;; add X window menu option; bug fixes. TAB, LFD, C-c " and C-c C-o now | |
214 ;;; behave consistently; deletion never occurs blindly. | |
215 ;;; Marc Shapiro <shapiro@inria.inria.fr> 15-oct-1986 | |
216 ;;; align long lines nicely; C-c C-o checks for the "OPT" string; | |
217 ;;; TAB goes to the end of the string; use lower case; use | |
218 ;;; run-hooks | |
219 | |
220 ;;; Bengt Martensson <ubrinf!mond!bengt> 87-06-28 | |
221 ;;; Bengt Martensson <bengt@mathematik.uni-Bremen.de> 87-06-28 | |
222 ;;; Original version | |
223 | |
224 ;;; Code: | |
225 | |
226 ;;; NOTE by Marc Shapiro, 14-dec-87: | |
227 ;;; (bibtex-x-environment) binds an X menu for bibtex mode to x-button-c-right. | |
228 ;;; Trouble is, in Emacs 18.44 you can't have a mode-specific mouse binding, | |
229 ;;; so it will remain active in all windows. Yuck! | |
230 | |
231 (provide 'bibtex) | |
232 | |
233 ;;; these guys typically don't have autoloads...[alarson:19920131.1548CST] | |
234 ;;; Check for fboundp first so that if user autoloads them from non standard | |
235 ;;; places, the users bindings will take precedence. | |
236 (if (not (fboundp 'tex-insert-quote)) | |
237 (autoload 'tex-insert-quote "tex-mode")) | |
238 (if (not (fboundp 'sort-subr)) | |
239 (autoload 'sort-subr "sort")) | |
240 | |
241 ;;; These should be in a more generally accessible location. | |
242 | |
243 (defun string-equalp (s1 s2) | |
244 "Like string= except differences in case are ignored." | |
245 (let ((ss1 (if (symbolp s1) (symbol-name s1) s1)) | |
246 (ss2 (if (symbolp s2) (symbol-name s2) s2))) | |
247 (and (= (length ss1) (length ss2)) | |
248 (string-equal (upcase ss1) (upcase ss2))))) | |
249 | |
250 ;;; This should be moved into simple.el, and the functions there modified | |
251 ;;; to call it rather than doing it themselves. | |
252 (defun put-string-on-kill-ring (string) | |
253 "Make STRING be the first element of the kill ring." | |
254 (setq kill-ring (cons string kill-ring)) | |
255 (if (> (length kill-ring) kill-ring-max) | |
256 (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)) | |
257 (setq kill-ring-yank-pointer kill-ring)) | |
258 | |
259 | |
260 | |
261 | |
262 (defvar bibtex-clean-entry-zap-empty-opts t | |
263 "*If non-nil, bibtex-clean-entry will delete all empty optional fields.") | |
264 | |
265 (defvar bibtex-include-OPTcrossref t | |
266 "*If non-nil, all entries will have an OPTcrossref field.") | |
267 (defvar bibtex-include-OPTkey t | |
268 "*If non-nil, all entries will have an OPTkey field.") | |
269 (defvar bibtex-include-OPTannote t | |
270 "*If non-nil, all entries will have an OPTannote field.") | |
271 | |
272 ;; note: the user should be allowed to have their own list of always | |
273 ;; available optional fields. exs: "keywords" "categories" | |
274 | |
275 (defvar bibtex-mode-user-optional-fields nil ;no default value | |
276 "*List of optional fields that user want to have as always present | |
277 when making a bibtex entry. One possibility is for ``keywords''. | |
278 Entries can be either strings or conses, in which case the car should be | |
279 string and the cdr the value to be inserted.") | |
280 | |
281 (defvar bibtex-mode-syntax-table | |
282 (let ((st (make-syntax-table))) | |
283 ;; [alarson:19920214.1004CST] make double quote a string quote | |
284 (modify-syntax-entry ?\" "\"" st) | |
285 (modify-syntax-entry ?$ "$$ " st) | |
286 (modify-syntax-entry ?% "< " st) | |
287 (modify-syntax-entry ?' "w " st) | |
288 (modify-syntax-entry ?@ "w " st) | |
289 (modify-syntax-entry ?\\ "\\" st) | |
290 (modify-syntax-entry ?\f "> " st) | |
291 (modify-syntax-entry ?\n "> " st) | |
292 (modify-syntax-entry ?~ " " st) | |
293 st)) | |
294 | |
295 (defvar bibtex-mode-abbrev-table nil "") | |
296 (define-abbrev-table 'bibtex-mode-abbrev-table ()) | |
297 (defvar bibtex-mode-map | |
298 (let ((km (make-sparse-keymap))) | |
299 | |
300 (define-key km "\t" 'bibtex-find-text) | |
301 (define-key km "\n" 'bibtex-next-field) | |
302 (define-key km "\C-c\"" 'bibtex-remove-double-quotes) | |
303 (define-key km "\C-c\C-c" 'bibtex-clean-entry) | |
304 (define-key km "\C-c?" 'describe-mode) | |
305 (define-key km "\C-c\C-p" 'bibtex-pop-previous) | |
306 (define-key km "\C-c\C-n" 'bibtex-pop-next) | |
307 (define-key km "\C-c\C-k" 'bibtex-kill-optional-field) | |
308 (define-key km "\C-c\C-d" 'bibtex-empty-field) | |
309 | |
310 ;; [alarson:19920131.1543CST] | |
311 (define-key km "\"" 'tex-insert-quote) | |
312 (define-key km "\C-c$" 'ispell-bibtex-entry) | |
313 (define-key km "\M-\C-a" 'beginning-of-bibtex-entry) | |
314 (define-key km "\M-\C-e" 'end-of-bibtex-entry) | |
315 (define-key km "\C-c\C-b" 'bibtex-entry) | |
316 ; (define-key km "\C-cn" 'narrow-to-bibtex-entry) | |
317 | |
318 (define-key km "\C-c\C-e\C-a" 'bibtex-Article) | |
319 (define-key km "\C-c\C-e\C-b" 'bibtex-Book) | |
320 ; (define-key km "\C-c\C-e\C-d" 'bibtex-DEAthesis) | |
321 (define-key km "\C-c\C-e\C-c" 'bibtex-InProceedings) | |
322 (define-key km "\C-c\C-e\C-i" 'bibtex-InBook) | |
323 (define-key km "\C-c\C-ei" 'bibtex-InCollection) | |
324 (define-key km "\C-c\C-eI" 'bibtex-InProceedings) | |
325 (define-key km "\C-c\C-e\C-m" 'bibtex-Manual) | |
326 (define-key km "\C-c\C-em" 'bibtex-MastersThesis) | |
327 (define-key km "\C-c\C-eM" 'bibtex-Misc) | |
328 (define-key km "\C-c\C-o" 'bibtex-remove-OPT) | |
329 (define-key km "\C-c\C-e\C-p" 'bibtex-PhdThesis) | |
330 (define-key km "\C-c\C-ep" 'bibtex-Proceedings) | |
331 (define-key km "\C-c\C-eP" 'bibtex-preamble) | |
332 (define-key km "\C-c\C-e\C-t" 'bibtex-TechReport) | |
333 (define-key km "\C-c\C-e\C-s" 'bibtex-string) | |
334 (define-key km "\C-c\C-e\C-u" 'bibtex-Unpublished) | |
335 | |
336 (define-key km 'button3 'bibtex-menu) | |
337 km)) | |
338 | |
339 (defvar bibtex-pop-previous-search-point nil | |
340 "Next point where bibtex-pop-previous should start looking for a similar | |
341 entry.") | |
342 | |
343 (defvar bibtex-pop-next-search-point nil | |
344 "Next point where bibtex-pop-next should start looking for a similar | |
345 entry.") | |
346 | |
347 (defvar bibtex-entry-field-alist | |
348 '( | |
349 ("Article" . ((("author" "title" "journal" "year") | |
350 ("volume" "number" "pages" "month" "note")) | |
351 (("author" "title") | |
352 ("journal" "year" "volume" "number" "pages" | |
353 "month" "note")))) | |
354 ("Book" . ((("author" "title" "publisher" "year") | |
355 ("editor" "volume" "number" "series" "address" | |
356 "edition" "month" "note")))) | |
357 ("Booklet" . ((("title") | |
358 ("author" "howpublished" "address" "month" "year" "note")))) | |
359 | |
360 ;; France: Dipl\^{o}me d'Etudes Approfondies (similar to Master's) | |
361 ; ("DEAthesis" . ((("author" "title" "school" "year") | |
362 ; ("address" "month" "note")))) | |
363 | |
364 ("InBook" . ((("author" "title" "chapter" "publisher" "year") | |
365 ("editor" "pages" "volume" "number" "series" "address" | |
366 "edition" "month" "type" "note")) | |
367 (("author" "title" "chapter") | |
368 ("publisher" "year" "editor" "pages" "volume" "number" | |
369 "series" "address" "edition" "month" "type" "note")))) | |
370 | |
371 | |
372 ("InCollection" . ((("author" "title" | |
373 "booktitle" "publisher" "year") | |
374 ("editor" "volume" "number" "series" "type" "chapter" | |
375 "pages" "address" "edition" "month" "note")) | |
376 (("author" "title") | |
377 ("booktitle" "publisher" "year" | |
378 "editor" "volume" "number" "series" "type" "chapter" | |
379 "pages" "address" "edition" "month" "note")))) | |
380 | |
381 | |
382 ("InProceedings" . ((("author" "title" "booktitle" "year") | |
383 ("editor" "volume" "number" "series" "pages" | |
384 "organization" "publisher" "address" "month" "note")) | |
385 (("author" "title") | |
386 ("editor" "volume" "number" "series" "pages" | |
387 "booktitle" "year" | |
388 "organization" "publisher" "address" "month" "note")))) | |
389 | |
390 | |
391 ("Manual" . ((("title") | |
392 ("author" "organization" "address" "edition" "year" | |
393 "month" "note")))) | |
394 | |
395 ("MastersThesis" . ((("author" "title" "school" "year") | |
396 ("address" "month" "note" "type")))) | |
397 | |
398 ("Misc" . ((() | |
399 ("author" "title" "howpublished" "year" "month" "note")))) | |
400 | |
401 ("PhdThesis" . ((("author" "title" "school" "year") | |
402 ("address" "month" "type" "note")))) | |
403 | |
404 ("Proceedings" . ((("title" "year") | |
405 ("editor" "volume" "number" "series" "publisher" | |
406 "organization" "address" "month" "note")))) | |
407 | |
408 ("TechReport" . ((("author" "title" "institution" "year") | |
409 ("type" "number" "address" "month" "note")))) | |
410 | |
411 ("Unpublished" . ((("author" "title" "note") | |
412 ("year" "month")))) | |
413 ) | |
414 | |
415 "List of (entry-name (required optional) (crossref-required crossref-optional)) | |
416 tripples. If the third element is nil, then the first pair can be used. Required | |
417 and optional are lists of strings. All entry creation functions use this variable | |
418 to generate entries, and bibtex-entry ensures the entry type is valid. This | |
419 variable can be used for example to make bibtex manipulate a different set of entry | |
420 types, e.g. a crossreference document of organization types.") | |
421 | |
422 | |
423 ;;; A bibtex file is a sequence of entries, either string definitions | |
424 ;;; or reference entries. A reference entry has a type part, a | |
425 ;;; key part, and a comma-separated sequence of fields. A string | |
426 ;;; entry has a single field. A field has a left and right part, | |
427 ;;; separated by a '='. The left part is the name, the right part is | |
428 ;;; the text. Here come the definitions allowing to create and/or parse | |
429 ;;; entries and fields: | |
430 | |
431 ;;; fields | |
432 (defun bibtex-cfield (name text) | |
433 "Create a regexp for a bibtex field of name NAME and text TEXT" | |
434 (concat ",[ \t\n]*\\(" | |
435 name | |
436 "\\)[ \t\n]*=[ \t\n]*\\(" | |
437 text | |
438 "\\)")) | |
439 (defconst bibtex-name-in-cfield 1 | |
440 "The regexp subexpression number of the name part in bibtex-cfield.") | |
441 (defconst bibtex-text-in-cfield 2 | |
442 "The regexp subexpression number of the text part in bibtex-cfield.") | |
443 | |
444 ;;; KAWATA Yasuro <yasuro@qqqq.maekawa.is.uec.ac.jp> reported bug that "/" | |
445 ;;; was not premitted in field names. The old value of this var was: | |
446 ;;; "[A-Za-z][---A-Za-z0-9:_+]*" | |
447 ;;; According to the LaTeX manual, page 71, the legal values are letters, | |
448 ;;; digits, and punctuation other than comma. Section 2.1 defines | |
449 ;;; punctuation as: | |
450 ;;; .:;,?!`'()[]-/*@ | |
451 ;;; and says that += can be used in normal text. Specifically #$%&~_^\{} | |
452 ;;; are called out as special chars. Some experimentation with LaTeX | |
453 ;;; indicates that # and ~ definitely don't work, but that the following | |
454 ;;; citation does! \cite{a0.:;?!`'()[]-/*@_&$^+=|<>}. I chose here to | |
455 ;;; permit _ since it was previously allowed, but otherwise to only handle | |
456 ;;; punc and += | |
457 ;;; Amendment: I couldn't get a regexp with both "[]"'s and hyphen to | |
458 ;;; work. It looks like you need them both to be the first entries in a | |
459 ;;; regexp pattern. [alarson:19930315.0900CST] | |
460 | |
461 (defconst bibtex-field-name "[A-Za-z][---A-Za-z0-9.:;?!`'()/*@_+=]*" | |
462 "Regexp defining the name part of a bibtex field.") | |
463 | |
464 ;; bibtex-field-text must be able to handle | |
465 ;; title = "Proc. Fifteenth Annual" # STOC, | |
466 ;; month = "10~" # jan, | |
467 ;; year = "{\noopsort{1973c}}1981", | |
468 ;; month = apr # "-" # may, | |
469 ;; key = {Volume-2}, | |
470 ;; note = "Volume~2 is listed under Knuth \cite{book-full}" | |
471 ;; i have added a few of these, but not all! -- MON | |
472 | |
473 (defconst bibtex-field-const | |
474 "[0-9A-Za-z][---A-Za-z0-9:_+]*" | |
475 "Format of a bibtex field constant.") | |
476 | |
477 (defconst bibtex-field-string | |
478 (concat | |
479 "\"[^\"]*[^\\\\]\"\\|\"\"") | |
480 "Match either a string or an empty string.") | |
481 | |
482 (defconst bibtex-field-string-or-const | |
483 (concat bibtex-field-const "\\|" bibtex-field-string) | |
484 "Match either bibtex-field-string or bibtex-field-const.") | |
485 | |
486 (defconst bibtex-field-text | |
487 (concat | |
488 "\\(" bibtex-field-string-or-const "\\)" | |
489 "\\([ \t\n]+#[ \t\n]+\\(" bibtex-field-string-or-const "\\)\\)*\\|" | |
490 "{[^{}]*[^\\\\]}") | |
491 "Regexp defining the text part of a bibtex field: either a string, or | |
492 an empty string, or a constant followed by one or more # / constant pairs. | |
493 Also matches simple {...} patterns.") | |
494 | |
495 ;(defconst bibtex-field-text | |
496 ; "\"[^\"]*[^\\\\]\"\\|\"\"\\|[0-9A-Za-z][---A-Za-z0-9:_+]*" | |
497 ; "Regexp defining the text part of a bibtex field: either a string, or an empty string, or a constant.") | |
498 | |
499 (defconst bibtex-field | |
500 (bibtex-cfield bibtex-field-name bibtex-field-text) | |
501 "Regexp defining the format of a bibtex field") | |
502 | |
503 (defconst bibtex-name-in-field bibtex-name-in-cfield | |
504 "The regexp subexpression number of the name part in bibtex-field") | |
505 (defconst bibtex-text-in-field bibtex-text-in-cfield | |
506 "The regexp subexpression number of the text part in bibtex-field") | |
507 | |
508 ;;; references | |
509 (defconst bibtex-reference-type | |
510 "@[A-Za-z]+" | |
511 "Regexp defining the type part of a bibtex reference entry") | |
512 (defconst bibtex-reference-head | |
513 (concat "^[ \t]*\\(" | |
514 bibtex-reference-type | |
515 "\\)[ \t]*[({]\\(" | |
516 bibtex-field-name | |
517 "\\)") | |
518 "Regexp defining format of the header line of a bibtex reference entry") | |
519 (defconst bibtex-type-in-head 1 | |
520 "The regexp subexpression number of the type part in bibtex-reference-head") | |
521 (defconst bibtex-key-in-head 2 | |
522 "The regexp subexpression number of the key part in | |
523 bibtex-reference-head") | |
524 | |
525 (defconst bibtex-reference | |
526 (concat bibtex-reference-head | |
527 "\\([ \t\n]*" bibtex-field "\\)*" | |
528 "[ \t\n]*[})]") | |
529 "Regexp defining the format of a bibtex reference entry") | |
530 (defconst bibtex-type-in-reference bibtex-type-in-head | |
531 "The regexp subexpression number of the type part in bibtex-reference") | |
532 (defconst bibtex-key-in-reference bibtex-key-in-head | |
533 "The regexp subexpression number of the key part in | |
534 bibtex-reference") | |
535 | |
536 ;;; strings | |
537 (defconst bibtex-string | |
538 (concat "^[ \t]*@[sS][tT][rR][iI][nN][gG][ \t\n]*[({][ \t\n]*\\(" | |
539 bibtex-field-name | |
540 "\\)[ \t\n]*=[ \t\n]*\\(" | |
541 bibtex-field-text | |
542 "\\)[ \t\n]*[})]") | |
543 "Regexp defining the format of a bibtex string entry") | |
544 (defconst bibtex-name-in-string 1 | |
545 "The regexp subexpression of the name part in bibtex-string") | |
546 (defconst bibtex-text-in-string 2 | |
547 "The regexp subexpression of the text part in bibtex-string") | |
548 | |
549 (defconst bibtex-name-alignment 2 | |
550 "Alignment for the name part in BibTeX fields. | |
551 Chosen on aesthetic grounds only.") | |
552 | |
553 (defconst bibtex-text-alignment (length " organization = ") | |
554 "Alignment for the text part in BibTeX fields. | |
555 Equal to the space needed for the longest name part.") | |
556 | |
557 (defun bibtex-current-entry-label (&optional include-cite kill) | |
558 "Return the label of the bibtex entry containing, or preceding point. | |
559 Optional argument INCLUDE-CITE, if true means put a '\\cite{}' around the | |
560 returned value. Second optional argument KILL, if true, means place the | |
561 returned value in the kill buffer. Interactively; providing prefix | |
562 argument makes INCLUDE-CITE true, and kill is true by default. | |
563 | |
564 Rationale: | |
565 The intention is that someone will write a function that can be bound to | |
566 a mouse key so that people entering TeX can just mouse on the bibtex entry | |
567 and have the citation key inserted at the current point (which will almost | |
568 certainly be in some other buffer). In the interim this function is | |
569 marginally useful for keyboard binding and is not bound by default. | |
570 Suggested binding is ^C-k." | |
571 (interactive (list current-prefix-arg t)) | |
572 (save-excursion | |
573 (beginning-of-bibtex-entry) | |
574 (re-search-forward bibtex-reference-head (save-excursion (end-of-bibtex-entry) (point))) | |
575 (let* ((key (buffer-substring (match-beginning bibtex-key-in-head) | |
576 (match-end bibtex-key-in-head))) | |
577 (val (if include-cite | |
578 (format "\\cite{%s}" key) | |
579 key))) | |
580 (if kill | |
581 (put-string-on-kill-ring val)) | |
582 val))) | |
583 | |
584 ;;; bibtex mode: | |
585 | |
586 ;;;###autoload | |
587 (defun bibtex-mode () | |
588 "Major mode for editing bibtex files. | |
589 | |
590 \\{bibtex-mode-map} | |
591 | |
592 A command such as \\[bibtex-Book] will outline the fields for a BibTeX book entry. | |
593 | |
594 The optional fields start with the string OPT, and thus ignored by BibTeX. | |
595 The OPT string may be removed from a field with \\[bibtex-remove-OPT]. | |
596 \\[bibtex-kill-optional-field] kills the current optional field entirely. | |
597 \\[bibtex-remove-double-quotes] removes the double-quotes around the text of | |
598 the current field. \\[bibtex-empty-field] replaces the text of the current | |
599 field with the default \"\". | |
600 | |
601 The command \\[bibtex-clean-entry] cleans the current entry, i.e. (i) removes | |
602 double-quotes from entirely numerical fields, (ii) removes OPT from all | |
603 non-empty optional fields, (iii) removes all empty optional fields, and (iv) | |
604 checks that no non-optional fields are empty. | |
605 | |
606 Use \\[bibtex-find-text] to position the dot at the end of the current field. | |
607 Use \\[bibtex-next-field] to move to end of the next field. | |
608 | |
609 The following may be of interest as well: | |
610 | |
611 Functions: | |
612 find-bibtex-duplicates | |
613 find-bibtex-entry-location | |
614 hide-bibtex-entry-bodies | |
615 sort-bibtex-entries | |
616 validate-bibtex-buffer | |
617 | |
618 Variables: | |
619 bibtex-clean-entry-zap-empty-opts | |
620 bibtex-entry-field-alist | |
621 bibtex-include-OPTannote | |
622 bibtex-include-OPTcrossref | |
623 bibtex-include-OPTkey | |
624 bibtex-maintain-sorted-entries | |
625 bibtex-mode-user-optional-fields | |
626 | |
627 Fields: | |
628 address | |
629 Publisher's address | |
630 annote | |
631 Long annotation used for annotated bibliographies (begins sentence) | |
632 author | |
633 Name(s) of author(s), in BibTeX name format | |
634 booktitle | |
635 Book title when the thing being referenced isn't the whole book. | |
636 For book entries, the title field should be used instead. | |
637 chapter | |
638 Chapter number | |
639 crossref | |
640 The database key of the entry being cross referenced. | |
641 edition | |
642 Edition of a book (e.g., \"second\") | |
643 editor | |
644 Name(s) of editor(s), in BibTeX name format. | |
645 If there is also an author field, then the editor field should be | |
646 for the book or collection that the work appears in | |
647 howpublished | |
648 How something strange has been published (begins sentence) | |
649 institution | |
650 Sponsoring institution | |
651 journal | |
652 Journal name (macros are provided for many) | |
653 key | |
654 Alphabetizing and labeling key (needed when no author or editor) | |
655 month | |
656 Month (macros are provided) | |
657 note | |
658 To help the reader find a reference (begins sentence) | |
659 number | |
660 Number of a journal or technical report | |
661 organization | |
662 Organization (sponsoring a conference) | |
663 pages | |
664 Page number or numbers (use `--' to separate a range) | |
665 publisher | |
666 Publisher name | |
667 school | |
668 School name (for theses) | |
669 series | |
670 The name of a series or set of books. | |
671 An individual book will will also have it's own title | |
672 title | |
673 The title of the thing being referenced | |
674 type | |
675 Type of a technical report (e.g., \"Research Note\") to be used | |
676 instead of the default \"Technical Report\" | |
677 volume | |
678 Volume of a journal or multivolume work | |
679 year | |
680 Year---should contain only numerals | |
681 --------------------------------------------------------- | |
682 Entry to this mode calls the value of bibtex-mode-hook if that value is | |
683 non-nil." | |
684 (interactive) | |
685 (kill-all-local-variables) | |
686 (set-syntax-table bibtex-mode-syntax-table) | |
687 (use-local-map bibtex-mode-map) | |
688 (setq major-mode 'bibtex-mode) | |
689 (setq mode-name "BibTeX") | |
690 (set-syntax-table bibtex-mode-syntax-table) | |
691 (setq local-abbrev-table bibtex-mode-abbrev-table) | |
692 (make-local-variable 'paragraph-start) | |
693 (setq paragraph-start "^[ \f\n\t]*$") | |
694 (auto-fill-mode 1) ; nice alignments | |
695 (setq left-margin (+ bibtex-text-alignment 1)) | |
696 | |
697 (run-hooks 'bibtex-mode-hook)) | |
698 | |
699 (defun bibtex-move-outside-of-entry () | |
700 "Make sure we are outside of a bib entry" | |
701 (cond ((or | |
702 (= (point) (point-max)) | |
703 (= (point) (point-min)) | |
704 (looking-at "[ \n]*@") | |
705 ) | |
706 t) | |
707 (t | |
708 (backward-paragraph) | |
709 (forward-paragraph))) | |
710 (re-search-forward "[ \t\n]*" (point-max) t)) | |
711 | |
712 (defun ispell-abstract () | |
713 (interactive) | |
714 (beginning-of-bibtex-entry) | |
715 (re-search-forward "^[ \t]*[OPT]*abstract[ \t]*=") | |
716 (ispell-region (point) | |
717 (save-excursion (forward-sexp) (point)))) | |
718 | |
719 (defun beginning-of-bibtex-entry () | |
720 (interactive) | |
721 (re-search-backward "^@" nil 'move)) | |
722 | |
723 (defun skip-whitespace-and-comments () | |
724 ;; It might be a good idea to have forward-sexp with argument 0 do what | |
725 ;; this function tries to do, namely skip whitespace and comments. | |
726 ;; Maybe a better name for this would be skip-to-next-sexp. | |
727 ;; alternative implementation: | |
728 ;; (let ((parse-sexp-ignore-comments t)) | |
729 ;; (forward-sexp 1) | |
730 ;; (forward-sexp -1)) | |
731 ;; but I've had problems with this not getting the parse of comments | |
732 ;; right going backward if they contain unbalanced expressions or string | |
733 ;; quotes. [alarson:19920217.1021CST] | |
734 (let ((md (match-data))) | |
735 (unwind-protect | |
736 (while (cond ((looking-at "\\s>+\\|\\s +") | |
737 ;; was whitespace | |
738 ;; NOTE: also checked end-comment. In latex and | |
739 ;; lisp modes, newline is an end comment, but it | |
740 ;; should also be a whitespace char. | |
741 (goto-char (match-end 0))) | |
742 ;; If looking at beginning of comment, skip to end. | |
743 ((looking-at "\\s<") | |
744 (re-search-forward "\\s>")))) | |
745 (store-match-data md)))) | |
746 | |
747 ;;; [alarson:19920214.1007CST] | |
748 (defun end-of-bibtex-entry () | |
749 "If inside an entry, move to the end of it, otherwise move to the end | |
750 of the next entry." | |
751 (interactive) | |
752 ;; if point was previously at the end of an entry, this puts us | |
753 ;; inside the next entry, otherwise we remain in the current one. | |
754 (progn | |
755 (skip-whitespace-and-comments) | |
756 ;;; (skip-chars-forward " \t\n") | |
757 (end-of-line)) | |
758 (beginning-of-bibtex-entry) | |
759 (let ((parse-sexp-ignore-comments t)) | |
760 (forward-sexp) ; skip entry type | |
761 (forward-sexp) ; skip entry body | |
762 )) | |
763 ;(defun end-of-bibtex-entry () | |
764 ; (interactive) | |
765 ; (re-search-forward "}$" nil 'move)) | |
766 | |
767 (defun ispell-bibtex-entry () | |
768 (interactive) | |
769 (ispell-region (progn (beginning-of-bibtex-entry) (point)) | |
770 (progn (end-of-bibtex-entry) (point)))) | |
771 | |
772 (defun narrow-to-bibtex-entry () | |
773 (interactive) | |
774 (save-excursion | |
775 (narrow-to-region (progn (beginning-of-bibtex-entry) (point)) | |
776 (progn (end-of-bibtex-entry) (point))))) | |
777 | |
778 | |
779 (defun beginning-of-first-bibtex-entry () | |
780 (goto-char (point-min)) | |
781 (cond | |
782 ((re-search-forward "^@" nil 'move) | |
783 (beginning-of-line)) | |
784 ((and (bobp) (eobp)) | |
785 nil) | |
786 (t | |
787 (message "Warning: No bibtex entries found!")))) | |
788 | |
789 (defun hide-bibtex-entry-bodies (&optional arg) | |
790 "Hide all lines between first and last bibtex entries not beginning with @. | |
791 With argument, show all text." | |
792 (interactive "P") | |
793 (save-excursion | |
794 (beginning-of-first-bibtex-entry) | |
795 ;; subst-char-in-region modifies the buffer, despite what the | |
796 ;; documentation says... | |
797 (let ((modifiedp (buffer-modified-p)) | |
798 (buffer-read-only nil)) | |
799 (if arg | |
800 (subst-char-in-region (point) (point-max) ?\r ?\n t) | |
801 (while (save-excursion (re-search-forward "\n[^@]" (point-max) t)) | |
802 (save-excursion (replace-regexp "\n\\([^@]\\)" "\r\\1")))) | |
803 (setq selective-display (not arg)) | |
804 (set-buffer-modified-p modifiedp)))) | |
805 | |
806 (defvar bibtex-sort-ignore-string-entries nil | |
807 "*If true, bibtex @STRING entries are ignored when determining ordering | |
808 of the buffer (e.g. sorting, locating alphabetical position for new entries, | |
809 etc.)") | |
810 | |
811 (defun sort-bibtex-entries () | |
812 "Sort bibtex entries alphabetically by key. | |
813 Text before the first bibtex entry, and following the last is not affected. | |
814 If bibtex-sort-ignore-string-entries is true, @string entries will be ignored. | |
815 | |
816 Bugs: | |
817 1. Text between the closing brace ending one bibtex entry, and the @ starting | |
818 the next, is considered part of the PRECEDING entry. Perhaps it should be | |
819 part of the following entry." | |
820 (interactive) | |
821 (save-restriction | |
822 (beginning-of-first-bibtex-entry) | |
823 (narrow-to-region (point) | |
824 (save-excursion | |
825 (goto-char (point-max)) | |
826 (beginning-of-bibtex-entry) | |
827 (end-of-bibtex-entry) | |
828 (point))) | |
829 (sort-subr nil ; reversep | |
830 ;; beginning of record function | |
831 'forward-line | |
832 ;; end of record function | |
833 (function (lambda () (and (re-search-forward "}\\s-*\n[\n \t]*@" nil 'move) | |
834 (forward-char -2)))) | |
835 ;; start of key function | |
836 (if bibtex-sort-ignore-string-entries | |
837 (function (lambda () | |
838 (while (and (re-search-forward "^\\s-*\\([@a-zA-Z]*\\)\\s-*{\\s-*") | |
839 (string-equalp "@string" | |
840 (buffer-substring (match-beginning 1) | |
841 (match-end 1))))) | |
842 nil)) | |
843 (function (lambda () (re-search-forward "{\\s-*") nil))) | |
844 ;; end of key function | |
845 (function (lambda () (search-forward ","))) | |
846 ))) | |
847 | |
848 (defun map-bibtex-entries (fun) | |
849 "Call FUN for each bibtex entry starting with the current, to the end of the file. | |
850 FUN is called with one argument, the key of the entry, and with point inside the entry. | |
851 If bibtex-sort-ignore-string-entries is true, FUN will not be called for @string entries." | |
852 (beginning-of-bibtex-entry) | |
853 (while (re-search-forward "^@[^{]*{[ \t]*\\([^, ]*\\)" nil t) | |
854 (if (and bibtex-sort-ignore-string-entries | |
855 (string-equalp "@string{" | |
856 (buffer-substring (match-beginning 0) | |
857 (match-beginning 1)))) | |
858 nil ; ignore the @string entry. | |
859 (funcall fun (buffer-substring (match-beginning 1) (match-end 1)))))) | |
860 | |
861 (defun find-bibtex-entry-location (entry-name) | |
862 "Searches from beginning of current buffer looking for place to put the | |
863 bibtex entry named ENTRY-NAME. Buffer is assumed to be in sorted order, | |
864 without duplicates (see \\[sort-bibtex-entries]), if it is not, an error will | |
865 be signalled." | |
866 (interactive "sBibtex entry key: ") | |
867 (let ((previous nil) | |
868 point) | |
869 (beginning-of-first-bibtex-entry) | |
870 (or (catch 'done | |
871 (map-bibtex-entries (function (lambda (current) | |
872 (cond | |
873 ((string-equal entry-name current) | |
874 (error "Entry duplicates existing!")) | |
875 ((or (null previous) | |
876 (string< previous current)) | |
877 (setq previous current | |
878 point (point)) | |
879 (if (string< entry-name current) | |
880 (progn | |
881 (beginning-of-bibtex-entry) | |
882 ;; Many schemes append strings to | |
883 ;; existing entries to resolve them, | |
884 ;; so initial substring matches may | |
885 ;; indicate a duplicate entry. | |
886 (let ((idx (string-match (regexp-quote entry-name) current))) | |
887 (if (and (integerp idx) | |
888 (zerop idx)) | |
889 (progn | |
890 (message "Warning: Entry %s may be a duplicate of %s!" | |
891 entry-name current) | |
892 (ding t)))) | |
893 (throw 'done t)))) | |
894 ((string-equal previous current) | |
895 (error "Duplicate here with previous!")) | |
896 (t (error "Entries out of order here!"))))))) | |
897 (end-of-bibtex-entry)))) | |
898 | |
899 (defun validate-bibtex-buffer () | |
900 "Find some typical errors in bibtex files. | |
901 1. At signs (@) not as first char of a line. | |
902 2. Double quotes (\") inside strings. | |
903 3. Closing braces (}) not the last character of a line." | |
904 (interactive) | |
905 (let ((point (point))) | |
906 (while (re-search-forward ".@" nil t) | |
907 (let* ((foo (parse-partial-sexp (save-excursion (beginning-of-bibtex-entry) | |
908 (point)) | |
909 (point))) | |
910 (in-a-string (nth 3 foo))) | |
911 (if (not in-a-string) | |
912 (error "At sign (@) out of place!")))) | |
913 (goto-char point) | |
914 (while (search-forward "\"" nil t) | |
915 (or (looking-at "[,}][ \t]*$") | |
916 (char-equal (preceding-char) ?\") | |
917 ;; some versions put closing brace on separate line. | |
918 (looking-at "[ \t]*\n}") | |
919 (save-excursion | |
920 (save-restriction | |
921 (narrow-to-region (point) | |
922 (progn (beginning-of-line) (point))) | |
923 (looking-at "^[ \t]*[a-zA-Z]+[ \t]*=[ \t]*\"$"))) | |
924 (error "Quote out of place, or missing \",\" or \"}\"!"))) | |
925 (goto-char point) | |
926 ;; This is only approximate, should actually search for close braces, | |
927 ;; then see if they are inside a string, or at the end of a line. | |
928 ;; This just gets the typical case of whitespace after a closing brace. | |
929 (while (search-forward "}[ \t]+$" nil t) | |
930 (error "Brace not last char of line!")) | |
931 (goto-char point) | |
932 (message "Bibtex buffer appears o.k."))) | |
933 | |
934 (defun find-bibtex-duplicates () | |
935 "Searches forward in current buffer looking for duplicate bibtex entries. | |
936 Buffer is assumed to be sorted, see \\[sort-bibtex-entries]" | |
937 (interactive) | |
938 (let ((point (point))) | |
939 ;; errors if things are not right... | |
940 (find-bibtex-entry-location (make-string 10 255)) | |
941 (goto-char point) | |
942 (message "No duplicates found!"))) | |
943 | |
944 | |
945 ;;; assoc doesn't ignore case, so we need an assoc that does... | |
946 (defun assoc-string-equalp (thing alist) | |
947 (or (assoc thing alist) | |
948 (while (and alist | |
949 (not (string-equalp thing (car (car alist))))) | |
950 (setq alist (cdr alist))) | |
951 (car alist))) | |
952 | |
953 (defvar bibtex-maintain-sorted-entries nil | |
954 "*If true, bibtex-mode will attempt to maintain all bibtex entries in | |
955 sorted order. | |
956 | |
957 Note that this is more a property of a file than a personal preference and | |
958 as such should normally be set via a file local variable entry.") | |
959 | |
960 (defun bibtex-entry (entry-type &optional required optional) | |
961 (interactive (let* ((completion-ignore-case t) | |
962 (e-t (completing-read "Entry Type: " bibtex-entry-field-alist | |
963 nil t))) | |
964 (list e-t))) | |
965 (if (and (null required) (null optional)) | |
966 (let* ((e (assoc-string-equalp entry-type bibtex-entry-field-alist)) | |
967 (r-n-o (elt e 1)) | |
968 (c-ref (elt e 2))) | |
969 (if (null e) | |
970 (error "Bibtex entry type %s not defined!")) | |
971 (if (and bibtex-include-OPTcrossref c-ref) | |
972 (setq required (elt c-ref 0) | |
973 optional (elt c-ref 1)) | |
974 (setq required (elt r-n-o 0) | |
975 optional (elt r-n-o 1))))) | |
976 (let ((key (if bibtex-maintain-sorted-entries | |
977 (read-string (format "%s key: " entry-type))))) | |
978 (if key | |
979 (find-bibtex-entry-location key)) | |
980 (bibtex-move-outside-of-entry) | |
981 (insert "@" entry-type "{") | |
982 (if key | |
983 (insert key)) | |
984 (save-excursion | |
985 (mapcar 'bibtex-make-field required) | |
986 (if bibtex-include-OPTcrossref | |
987 (bibtex-make-optional-field "crossref")) | |
988 (if bibtex-include-OPTkey | |
989 (bibtex-make-optional-field "key")) | |
990 (mapcar 'bibtex-make-optional-field optional) | |
991 (mapcar 'bibtex-make-optional-field | |
992 bibtex-mode-user-optional-fields) | |
993 (if bibtex-include-OPTannote | |
994 (bibtex-make-optional-field "annote")) | |
995 (insert "\n}\n\n")) | |
996 (if key | |
997 (bibtex-next-field t)) | |
998 (run-hooks 'bibtex-add-entry-hook))) | |
999 | |
1000 ;; (defun bibtex-entry (entry-type required optional) | |
1001 ;; (bibtex-move-outside-of-entry) | |
1002 ;; (insert (concat "@" entry-type "{,\n\n}\n\n")) | |
1003 ;; (previous-line 3) | |
1004 ;; (insert (mapconcat 'bibtex-make-entry required ",\n")) | |
1005 ;; (if required | |
1006 ;; (if optional | |
1007 ;; (insert ",\n"))) | |
1008 ;; (insert (mapconcat 'bibtex-make-OPT-entry optional ",\n")) | |
1009 ;; (if bibtex-mode-user-optional-fields ;MON... | |
1010 ;; (progn | |
1011 ;; (if optional | |
1012 ;; (insert ",\n")) | |
1013 ;; (insert (mapconcat 'bibtex-make-OPT-entry | |
1014 ;; bibtex-mode-user-optional-fields | |
1015 ;; ",\n")))) ;MON | |
1016 ;; (up-list -1) | |
1017 ;; (forward-char 1)) | |
1018 | |
1019 | |
1020 (defun bibtex-make-field (e-t) | |
1021 (interactive "sBibTeX entry type: ") | |
1022 (let ((name (if (consp e-t) (car e-t) e-t)) | |
1023 (value (if (consp e-t) (cdr e-t) ""))) | |
1024 (insert ",\n") | |
1025 (indent-to-column bibtex-name-alignment) | |
1026 (insert name " = ") | |
1027 (indent-to-column bibtex-text-alignment) | |
1028 ;; lucid emacs prin1-to-string breaks the undo chain. When they fix | |
1029 ;; that, the hack can be removed. [alarson:19930316.0805CST] | |
1030 ; (insert (prin1-to-string value)) | |
1031 ;; begin hack | |
1032 (insert (format (if (stringp value) "\"%s\"" "%s") | |
1033 value)) | |
1034 ;; end hack | |
1035 nil)) | |
1036 | |
1037 (defun bibtex-make-optional-field (e-t) | |
1038 (interactive "sOptional BibTeX entry type: ") | |
1039 (if (consp e-t) | |
1040 (setq e-t (cons (concat "OPT" (car e-t)) (cdr e-t))) | |
1041 (setq e-t (concat "OPT" e-t))) | |
1042 (bibtex-make-field e-t)) | |
1043 | |
1044 ;; What to do about crossref? if present, journal and year are | |
1045 ;; both optional. Due to this, i move all of them into optional. -- MON | |
1046 | |
1047 (defun bibtex-Article () | |
1048 (interactive) | |
1049 (bibtex-entry "Article")) | |
1050 | |
1051 (defun bibtex-Book () | |
1052 (interactive) | |
1053 (bibtex-entry "Book")) | |
1054 | |
1055 (defun bibtex-Booklet () | |
1056 (interactive) | |
1057 (bibtex-entry "Booklet")) | |
1058 | |
1059 ;(defun bibtex-DEAthesis () | |
1060 ; (interactive) | |
1061 ; (bibtex-entry "DEAthesis")) | |
1062 | |
1063 (defun bibtex-InBook () | |
1064 (interactive) | |
1065 (bibtex-entry "InBook")) | |
1066 | |
1067 (defun bibtex-InCollection () | |
1068 (interactive) | |
1069 (bibtex-entry "InCollection")) | |
1070 | |
1071 (defun bibtex-InProceedings () | |
1072 (interactive) | |
1073 (bibtex-entry "InProceedings")) | |
1074 | |
1075 (defun bibtex-Manual () | |
1076 (interactive) | |
1077 (bibtex-entry "Manual")) | |
1078 | |
1079 (defun bibtex-MastersThesis () | |
1080 (interactive) | |
1081 (bibtex-entry "MastersThesis")) | |
1082 | |
1083 (defun bibtex-Misc () | |
1084 (interactive) | |
1085 (bibtex-entry "Misc")) | |
1086 | |
1087 (defun bibtex-PhdThesis () | |
1088 (interactive) | |
1089 (bibtex-entry "PhdThesis")) | |
1090 | |
1091 (defun bibtex-Proceedings () | |
1092 (interactive) | |
1093 (bibtex-entry "Proceedings")) | |
1094 | |
1095 (defun bibtex-TechReport () | |
1096 (interactive) | |
1097 (bibtex-entry "TechReport")) | |
1098 | |
1099 (defun bibtex-Unpublished () | |
1100 (interactive) | |
1101 (bibtex-entry "Unpublished")) | |
1102 | |
1103 (defun bibtex-string () | |
1104 (interactive) | |
1105 (bibtex-move-outside-of-entry) | |
1106 (insert "@string{ = \"\"}\n") | |
1107 (previous-line 1) | |
1108 (forward-char 8)) | |
1109 | |
1110 (defun bibtex-preamble () | |
1111 (interactive) | |
1112 (bibtex-move-outside-of-entry) | |
1113 (insert "@Preamble{}\n") | |
1114 (previous-line 1) | |
1115 (forward-char 10)) | |
1116 | |
1117 (defun bibtex-next-field (arg) | |
1118 "Finds end of text of next BibTeX field; with arg, to its beginning" | |
1119 (interactive "P") | |
1120 (bibtex-inside-field) | |
1121 (let ((start (point))) | |
1122 (condition-case () | |
1123 (progn | |
1124 (bibtex-enclosing-field) | |
1125 (goto-char (match-end 0)) | |
1126 (forward-char 2)) | |
1127 (error | |
1128 (goto-char start) | |
1129 (end-of-line) | |
1130 (forward-char 1)))) | |
1131 (bibtex-find-text arg)) | |
1132 | |
1133 ;; (defun bibtex-next-field () | |
1134 ;; "Finds end of text of next field." | |
1135 ;; (interactive) | |
1136 ;; (condition-case () | |
1137 ;; (progn | |
1138 ;; (bibtex-inside-field) | |
1139 ;; (re-search-forward ",[ \t\n]*" (point-max) 1) | |
1140 ;; (bibtex-enclosing-field) | |
1141 ;; (bibtex-inside-field)) | |
1142 ;; (error nil))) | |
1143 | |
1144 (defun bibtex-find-text (arg) | |
1145 "Go to end of text of current field; with arg, go to beginning." | |
1146 (interactive "P") | |
1147 (bibtex-inside-field) | |
1148 (bibtex-enclosing-field) | |
1149 (if arg | |
1150 (progn | |
1151 (goto-char (match-beginning bibtex-text-in-field)) | |
1152 (if (looking-at "\"") | |
1153 (forward-char 1))) | |
1154 (goto-char (match-end bibtex-text-in-field)) | |
1155 (if (= (preceding-char) ?\") | |
1156 (forward-char -1)))) | |
1157 | |
1158 ;; (defun bibtex-find-text () | |
1159 ;; "Go to end of text of current field." | |
1160 ;; (interactive) | |
1161 ;; (condition-case () | |
1162 ;; (progn | |
1163 ;; (bibtex-inside-field) | |
1164 ;; (bibtex-enclosing-field) | |
1165 ;; (goto-char (match-end bibtex-text-in-field)) | |
1166 ;; (bibtex-inside-field)) | |
1167 ;; (error nil))) | |
1168 | |
1169 (defun bibtex-remove-OPT () | |
1170 "Removes the 'OPT' starting optional arguments and goes to end of text" | |
1171 (interactive) | |
1172 (bibtex-inside-field) | |
1173 (bibtex-enclosing-field) | |
1174 (save-excursion | |
1175 (goto-char (match-beginning bibtex-name-in-field)) | |
1176 (if (looking-at "OPT") | |
1177 ;; sct@dcs.edinburgh.ac.uk | |
1178 (progn | |
1179 (delete-char (length "OPT")) | |
1180 (search-forward "=") | |
1181 (delete-horizontal-space) | |
1182 (indent-to-column bibtex-text-alignment)))) | |
1183 (bibtex-inside-field)) | |
1184 | |
1185 (defun bibtex-inside-field () | |
1186 "Try to avoid point being at end of a bibtex field." | |
1187 (interactive) | |
1188 (end-of-line) | |
1189 (skip-chars-backward " \t") ;MON - maybe delete these chars? | |
1190 (cond ((= (preceding-char) ?,) | |
1191 (forward-char -2))) ; -1 --> -2 sct@dcs.edinburgh.ac.uk | |
1192 (cond ((= (preceding-char) ?\") | |
1193 (forward-char -1)))) ;MON - only go back if quote | |
1194 | |
1195 (defun bibtex-remove-double-quotes () | |
1196 "Removes \"\" around string." | |
1197 (interactive) | |
1198 (save-excursion | |
1199 (bibtex-inside-field) | |
1200 (bibtex-enclosing-field) | |
1201 (let ((start (match-beginning bibtex-text-in-field)) | |
1202 (stop (match-end bibtex-text-in-field))) | |
1203 (goto-char stop) | |
1204 (forward-char -1) | |
1205 (if (looking-at "\"") | |
1206 (delete-char 1)) | |
1207 (goto-char start) | |
1208 (if (looking-at "\"") | |
1209 (delete-char 1))))) | |
1210 | |
1211 (defun bibtex-kill-optional-field () | |
1212 "Kill the entire enclosing optional BibTeX field" | |
1213 (interactive) | |
1214 (bibtex-inside-field) | |
1215 (bibtex-enclosing-field) | |
1216 (goto-char (match-beginning bibtex-name-in-field)) | |
1217 (let ((the-end (match-end 0)) | |
1218 (the-beginning (match-beginning 0))) | |
1219 (if (looking-at "OPT") | |
1220 (progn | |
1221 (goto-char the-end) | |
1222 (skip-chars-forward " \t\n,") | |
1223 (kill-region the-beginning the-end)) | |
1224 (error "Mandatory fields can't be killed")))) | |
1225 | |
1226 (defun bibtex-empty-field () | |
1227 "Delete the text part of the current field, replace with empty text" | |
1228 (interactive) | |
1229 (bibtex-inside-field) | |
1230 (bibtex-enclosing-field) | |
1231 (goto-char (match-beginning bibtex-text-in-field)) | |
1232 (kill-region (point) (match-end bibtex-text-in-field)) | |
1233 (insert "\"\"") | |
1234 (bibtex-find-text t)) | |
1235 | |
1236 | |
1237 (defun bibtex-pop-previous (arg) | |
1238 "Replace text of current field with the text of similar field in previous entry. | |
1239 With arg, go up ARG entries. Repeated, goes up so many times. May be | |
1240 intermixed with \\[bibtex-pop-next] (bibtex-pop-next)." | |
1241 (interactive "p") | |
1242 (bibtex-inside-field) | |
1243 (save-excursion | |
1244 ; parse current field | |
1245 (bibtex-enclosing-field) | |
1246 (let ((start-old-text (match-beginning bibtex-text-in-field)) | |
1247 (stop-old-text (match-end bibtex-text-in-field)) | |
1248 (start-name (match-beginning bibtex-name-in-field)) | |
1249 (stop-name (match-end bibtex-name-in-field)) | |
1250 (new-text)) | |
1251 (goto-char start-name) | |
1252 ; construct regexp for previous field with same name as this one | |
1253 (let ((matching-entry | |
1254 (bibtex-cfield | |
1255 (buffer-substring (if (looking-at "OPT") | |
1256 (+ (point) (length "OPT")) | |
1257 (point)) | |
1258 stop-name) | |
1259 bibtex-field-text))) | |
1260 | |
1261 ; if executed several times in a row, start each search where the | |
1262 ; last one finished | |
1263 (cond ((or (eq last-command 'bibtex-pop-previous) | |
1264 (eq last-command 'bibtex-pop-next)) | |
1265 t | |
1266 ) | |
1267 (t | |
1268 (bibtex-enclosing-reference) | |
1269 (setq bibtex-pop-previous-search-point (match-beginning 0)) | |
1270 (setq bibtex-pop-next-search-point (match-end 0)))) | |
1271 (goto-char bibtex-pop-previous-search-point) | |
1272 | |
1273 ; Now search for arg'th previous similar field | |
1274 (cond | |
1275 ((re-search-backward matching-entry (point-min) t arg) | |
1276 (setq new-text | |
1277 (buffer-substring (match-beginning bibtex-text-in-cfield) | |
1278 (match-end bibtex-text-in-cfield))) | |
1279 ; Found a matching field. Remember boundaries. | |
1280 (setq bibtex-pop-next-search-point (match-end 0)) | |
1281 (setq bibtex-pop-previous-search-point (match-beginning 0)) | |
1282 (bibtex-flash-head) | |
1283 ; Go back to where we started, delete old text, and pop new. | |
1284 (goto-char stop-old-text) | |
1285 (delete-region start-old-text stop-old-text) | |
1286 (insert new-text)) | |
1287 (t ; search failed | |
1288 (error "No previous matching BibTeX field.")))))) | |
1289 (setq this-command 'bibtex-pop-previous)) | |
1290 | |
1291 (defun bibtex-pop-next (arg) | |
1292 "Replace text of current field with the text of similar field in next entry. | |
1293 With arg, go up ARG entries. Repeated, goes up so many times. May be | |
1294 intermixed with \\[bibtex-pop-previous] (bibtex-pop-previous)." | |
1295 (interactive "p") | |
1296 (bibtex-inside-field) | |
1297 (save-excursion | |
1298 ; parse current field | |
1299 (bibtex-enclosing-field) | |
1300 (let ((start-old-text (match-beginning bibtex-text-in-field)) | |
1301 (stop-old-text (match-end bibtex-text-in-field)) | |
1302 (start-name (match-beginning bibtex-name-in-field)) | |
1303 (stop-name (match-end bibtex-name-in-field)) | |
1304 (new-text)) | |
1305 (goto-char start-name) | |
1306 ; construct regexp for next field with same name as this one, | |
1307 ; ignoring possible OPT's | |
1308 (let ((matching-entry | |
1309 (bibtex-cfield | |
1310 (buffer-substring (if (looking-at "OPT") | |
1311 (+ (point) (length "OPT")) | |
1312 (point)) | |
1313 stop-name) | |
1314 bibtex-field-text))) | |
1315 | |
1316 ; if executed several times in a row, start each search where the | |
1317 ; last one finished | |
1318 (cond ((or (eq last-command 'bibtex-pop-next) | |
1319 (eq last-command 'bibtex-pop-previous)) | |
1320 t | |
1321 ) | |
1322 (t | |
1323 (bibtex-enclosing-reference) | |
1324 (setq bibtex-pop-previous-search-point (match-beginning 0)) | |
1325 (setq bibtex-pop-next-search-point (match-end 0)))) | |
1326 (goto-char bibtex-pop-next-search-point) | |
1327 | |
1328 ; Now search for arg'th next similar field | |
1329 (cond | |
1330 ((re-search-forward matching-entry (point-max) t arg) | |
1331 (setq new-text | |
1332 (buffer-substring (match-beginning bibtex-text-in-cfield) | |
1333 (match-end bibtex-text-in-cfield))) | |
1334 ; Found a matching field. Remember boundaries. | |
1335 (setq bibtex-pop-next-search-point (match-end 0)) | |
1336 (setq bibtex-pop-previous-search-point (match-beginning 0)) | |
1337 (bibtex-flash-head) | |
1338 ; Go back to where we started, delete old text, and pop new. | |
1339 (goto-char stop-old-text) | |
1340 (delete-region start-old-text stop-old-text) | |
1341 (insert new-text)) | |
1342 (t ; search failed | |
1343 (error "No next matching BibTeX field.")))))) | |
1344 (setq this-command 'bibtex-pop-next)) | |
1345 | |
1346 (defun bibtex-flash-head () | |
1347 "Flash at BibTeX reference head before point, if exists. (Moves point)." | |
1348 (let ((flash)) | |
1349 (cond ((re-search-backward bibtex-reference-head (point-min) t) | |
1350 (goto-char (match-beginning bibtex-type-in-head)) | |
1351 (setq flash (match-end bibtex-key-in-reference))) | |
1352 (t | |
1353 (end-of-line) | |
1354 (skip-chars-backward " \t") | |
1355 (setq flash (point)) | |
1356 (beginning-of-line) | |
1357 (skip-chars-forward " \t"))) | |
1358 (if (pos-visible-in-window-p (point)) | |
1359 (sit-for 1) | |
1360 (message "From: %s" | |
1361 (buffer-substring (point) flash))))) | |
1362 | |
1363 | |
1364 | |
1365 (defun bibtex-enclosing-field () | |
1366 "Search for BibTeX field enclosing point. | |
1367 Point moves to end of field; also, use match-beginning and match-end | |
1368 to parse the field." | |
1369 ;; sct@dcs.edinburgh.ac.uk | |
1370 (let ((old-point (point))) | |
1371 (condition-case errname | |
1372 (bibtex-enclosing-regexp bibtex-field) | |
1373 (search-failed | |
1374 (goto-char old-point) | |
1375 (error "Can't find enclosing BibTeX field."))))) | |
1376 | |
1377 (defun bibtex-enclosing-reference () | |
1378 "Search for BibTeX reference enclosing point. | |
1379 Point moves to end of reference; also, use match-beginning and match-end | |
1380 to parse the reference." | |
1381 ;; sct@dcs.edinburgh.ac.uk | |
1382 (let ((old-point (point))) | |
1383 (condition-case errname | |
1384 (bibtex-enclosing-regexp bibtex-reference) | |
1385 (search-failed | |
1386 (goto-char old-point) | |
1387 (error "Can't find enclosing BibTeX reference."))))) | |
1388 | |
1389 (defun bibtex-enclosing-regexp (regexp) | |
1390 "Search for REGEXP enclosing point. | |
1391 Point moves to end of REGEXP. See also match-beginning and match-end. | |
1392 If an enclosing REGEXP is not found, signals search-failed; point is left in | |
1393 an undefined location. | |
1394 | |
1395 [Doesn't something like this exist already?]" | |
1396 | |
1397 (interactive "sRegexp: ") | |
1398 ; compute reasonable limits for the loop | |
1399 (let* ((initial (point)) | |
1400 (right (if (re-search-forward regexp (point-max) t) | |
1401 (match-end 0) | |
1402 (point-max))) | |
1403 (left | |
1404 (progn | |
1405 (goto-char initial) | |
1406 (if (re-search-backward regexp (point-min) t) | |
1407 (match-beginning 0) | |
1408 (point-min))))) | |
1409 ; within the prescribed limits, loop until a match is found | |
1410 (goto-char left) | |
1411 (re-search-forward regexp right nil 1) | |
1412 (if (> (match-beginning 0) initial) | |
1413 (signal 'search-failed (list regexp))) | |
1414 (while (<= (match-end 0) initial) | |
1415 (re-search-forward regexp right nil 1) | |
1416 (if (> (match-beginning 0) initial) | |
1417 (signal 'search-failed (list regexp)))) | |
1418 )) | |
1419 | |
1420 (defun bibtex-clean-entry () | |
1421 "For all optional fields of current BibTeX entry: if empty, kill the whole field; otherwise, remove the \"OPT\" string in the name; if text numerical, remove double-quotes. For all mandatory fields: if empty, signal error." | |
1422 (interactive) | |
1423 (beginning-of-bibtex-entry) | |
1424 (let ((start (point))) | |
1425 (save-restriction | |
1426 (narrow-to-region start (save-excursion (end-of-bibtex-entry) (point))) | |
1427 (while (re-search-forward bibtex-field (point-max) t 1) | |
1428 (let ((begin-field (match-beginning 0)) | |
1429 (end-field (match-end 0)) | |
1430 (begin-name (match-beginning bibtex-name-in-field)) | |
1431 (end-name (match-end bibtex-name-in-field)) | |
1432 (begin-text (match-beginning bibtex-text-in-field)) | |
1433 (end-text (match-end bibtex-text-in-field)) | |
1434 ) | |
1435 (goto-char begin-name) | |
1436 (cond ((and | |
1437 (looking-at "OPT") | |
1438 bibtex-clean-entry-zap-empty-opts) | |
1439 (goto-char begin-text) | |
1440 (if (looking-at "\"\"") ; empty: delete whole field | |
1441 (delete-region begin-field end-field) | |
1442 ; otherwise: not empty, delete "OPT" | |
1443 (goto-char begin-name) | |
1444 (delete-char (length "OPT")) | |
1445 (progn | |
1446 ;; fixup alignment. [alarson:19920309.2047CST] | |
1447 (search-forward "=") | |
1448 (delete-horizontal-space) | |
1449 (indent-to-column bibtex-text-alignment)) | |
1450 (goto-char begin-field) ; and loop to go through next test | |
1451 )) | |
1452 (t | |
1453 (goto-char begin-text) | |
1454 (cond ((looking-at "\"[0-9]+\"") ; if numerical, | |
1455 (goto-char end-text) | |
1456 (delete-char -1) ; delete enclosing double-quotes | |
1457 (goto-char begin-text) | |
1458 (delete-char 1) | |
1459 (goto-char end-field) ; go to end for next search | |
1460 (forward-char -2) ; to compensate for the 2 quotes deleted | |
1461 ) | |
1462 ((looking-at "\"\"") ; if empty quotes, complain | |
1463 (forward-char 1) | |
1464 (if (not (or (equal (buffer-substring | |
1465 begin-name | |
1466 (+ begin-name 3)) | |
1467 "OPT") | |
1468 (equal (buffer-substring | |
1469 begin-name | |
1470 (+ begin-name 3)) | |
1471 "opt"))) | |
1472 (error "Mandatory field ``%s'' is empty" | |
1473 (buffer-substring begin-name end-name)))) | |
1474 (t | |
1475 (goto-char end-field)))))))) | |
1476 (goto-char start) | |
1477 (end-of-bibtex-entry) | |
1478 ;; sct@dcs.edinburgh.ac.uk | |
1479 (save-excursion | |
1480 (previous-line 1) | |
1481 (end-of-line) | |
1482 (if (eq (preceding-char) ?,) | |
1483 (backward-delete-char 1))) | |
1484 (skip-whitespace-and-comments))) | |
1485 | |
1486 | |
1487 ;;; Menus for bibtex mode | |
1488 | |
1489 (defconst bibtex-menu | |
1490 '("BibTeX Commands" | |
1491 "Entry Types" | |
1492 "---" | |
1493 ["Article in Conference Proceedings" bibtex-InProceedings t] | |
1494 ["Article in Journal" bibtex-Article t] | |
1495 ["Book" bibtex-Book t] | |
1496 ["Booklet" bibtex-Booklet t] | |
1497 ["Conference" bibtex-InProceedings t] | |
1498 ["Master's Thesis" bibtex-MastersThesis t] | |
1499 ["DEA Thesis" bibtex-DEAthesis t] | |
1500 ["Phd. Thesis" bibtex-PhdThesis t] | |
1501 ["Technical Report" bibtex-TechReport t] | |
1502 ["Technical Manual" bibtex-Manual t] | |
1503 ["Conference Proceedings" bibtex-Proceedings t] | |
1504 ["A Chapter in a Book" bibtex-InBook t] | |
1505 ["An Article in a Collection" bibtex-InCollection t] | |
1506 ["Miscellaneous" bibtex-Misc t] | |
1507 ["Unpublished" bibtex-Unpublished t] | |
1508 ["String" bibtex-string t] | |
1509 ["Preamble" bibtex-preamble t] | |
1510 "---" | |
1511 "Bibtex Edit" | |
1512 "---" | |
1513 ["Next Field" bibtex-next-field t] | |
1514 ["To End of Field" bibtex-find-text t] | |
1515 ["Snatch From Similar Preceding Field" bibtex-pop-previous t] | |
1516 ["Snatch From Similar Following Field" bibtex-pop-next t] | |
1517 ["Remove OPT" bibtex-remove-OPT t] | |
1518 ["Remove Quotes" bibtex-remove-double-quotes t] | |
1519 ["Clean Up Entry" bibtex-clean-entry t] | |
1520 ["Find Duplicates" find-bibtex-duplicates t] | |
1521 ["Sort Entries" sort-bibtex-entries t] | |
1522 ["Validate Entries" validate-bibtex-buffer t] | |
1523 )) | |
1524 | |
1525 (defun bibtex-menu () | |
1526 (interactive) | |
1527 (let ((popup-menu-titles nil)) | |
1528 (popup-menu bibtex-menu))) | |
1529 | |
1530 ;;; bibtex.el ends here |