23a7af2bf85f010fe39bae7dffc3d8c02e21eec3
[bpt/emacs.git] / lisp / textmodes / refbib.el
1 ;;; refbib.el --- convert refer-style references to ones usable by Latex bib
2
3 ;; Copyright (C) 1989, 2001, 2002, 2003, 2004, 2005,
4 ;; 2006, 2007 Free Software Foundation, Inc.
5
6 ;; Author: Henry Kautz <kautz@research.att.com>
7 ;; Maintainer: FSF
8 ;; Keywords: bib, tex
9
10 ;; This file is part of GNU Emacs.
11
12 ;; GNU Emacs is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; any later version.
16
17 ;; GNU Emacs is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the
24 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02110-1301, USA.
26
27 ;;; Commentary:
28
29 ;; Use: from a buffer containing the refer-style bibliography,
30 ;; M-x r2b-convert-buffer
31 ;; Program will prompt for an output buffer name, and will log
32 ;; warnings during the conversion process in the buffer *Log*.
33
34 ;;; Change Log:
35
36 ;; HISTORY
37 ;; 9/88, created H.Kautz
38 ;; modified 1/19/89, allow books with editor but no author;
39 ;; added %O ordering field;
40 ;; appended invalid multiple fields, instead of
41 ;; discarding;
42 ;; added rule, a tech report whose %R number
43 ;; contains "ISBN" is really a book
44 ;; added rule, anything with an editor is a book
45 ;; or a proceedings
46 ;; added 'manual type, for items with institution
47 ;; but no author or editor
48 ;; fixed bug so trailing blanks are trimmed
49 ;; added 'proceedings type
50 ;; used "organization" field for proceedings
51 ;; modified 2/16/89, updated help messages
52 ;; modified 2/23/89, include capitalize stop words in r2b stop words,
53 ;; fixed problems with contractions (e.g. it's),
54 ;; caught multiple stop words in a row
55 ;; modified 3/1/89, fixed capitalize-title for first words all caps
56 ;; modified 3/15/89, allow use of " to delimit fields
57 ;; modified 4/18/89, properly "quote" special characters on output
58
59 ;;; Code:
60
61 ;**********************************************************
62 ; User Parameters
63
64 (defgroup refbib nil
65 "Convert refer-style references to ones usable by Latex bib."
66 :prefix "r2b-"
67 :group 'wp)
68
69 (defcustom r2b-trace-on nil
70 "*Non-nil means trace conversion."
71 :type 'boolean
72 :group 'refbib)
73
74 (defcustom r2b-journal-abbrevs
75 '(
76 )
77 "Abbreviation list for journal names.
78 If the car of an element matches a journal name exactly, it is replaced by
79 the cadr when output. Braces must be included if replacement is a
80 {string}, but not if replacement is a bibtex abbreviation. The cadr
81 may be eliminated if is exactly the same as the car.
82 Because titles are capitalized before matching, the abbreviation
83 for the journal name should be listed as beginning with a capital
84 letter, even if it really doesn't.
85 For example, a value of '((\"Aij\" \"{Artificial Intelligence}\")
86 \(\"Ijcai81\" \"ijcai7\")) would expand Aij to the text string
87 \"Artificial Intelligence\", but would replace Ijcai81 with the
88 BibTeX macro \"ijcai7\"."
89 :type '(repeat (list string string))
90 :group 'refbib)
91
92 (defcustom r2b-booktitle-abbrevs
93 '(
94 )
95 "Abbreviation list for book and proceedings names.
96 If the car of an element matches a title or booktitle exactly, it is
97 replaced by the cadr when output. Braces must be included if
98 replacement is a {string}, but not if replacement is a bibtex
99 abbreviation. The cadr may be eliminated if is exactly the same as
100 the car.
101 Because titles are capitalized before matching, the abbreviated title
102 should be listed as beginning with a capital letter, even if it doesn't.
103 For example, a value of '((\"Aij\" \"{Artificial Intelligence}\")
104 \(\"Ijcai81\" \"ijcai7\")) would expand Aij to the text string
105 \"Artificial Intelligence\", but would replace Ijcai81 with the
106 BibTeX macro \"ijcai7\"."
107 :type '(repeat (list string string))
108 :group 'refbib)
109
110 (defcustom r2b-proceedings-list
111 '()
112 "Assoc list of books or journals which are really conference proceedings,
113 but whose name and whose abbrev expansion (as defined in `r2b-journal-abbrevs'
114 and `r2b-booktitle-abbrevs') does not contain the words \"conference\" or
115 \"proceedings\". (Those cases are handled automatically.)
116 The entry must match the given data exactly.
117 Because titles are capitalized before matching, the items in this list
118 should begin with a capital letter.
119 For example, suppose the title \"Ijcai81\" is used for the proceedings of
120 a conference, and its expansion is the BibTeX macro \"ijcai7\". Then
121 `r2b-proceedings-list' should be '((\"Ijcai81\") ...). If instead its
122 expansion were \"Proceedings of the Seventh International Conference
123 on Artificial Intelligence\", then you would NOT need to include Ijcai81
124 in `r2b-proceedings-list' (although it wouldn't cause an error)."
125 :type '(repeat (list string string))
126 :group 'refbib)
127
128 (defvar r2b-additional-stop-words
129 "Some\\|What"
130 "Words not to be used to build the citation key.
131 This is in addition to the `r2b-capitalize-title-stop-words'.")
132
133 (defcustom r2b-delimit-with-quote t
134 "*If true, then use \" to delimit fields, otherwise use braces."
135 :type 'boolean
136 :group 'refbib)
137
138 ;**********************************************************
139 ; Utility Functions
140
141 (defvar r2b-capitalize-title-stop-words
142 (concat
143 "the\\|and\\|of\\|is\\|a\\|an\\|of\\|for\\|in\\|to\\|in\\|on\\|at\\|"
144 "by\\|with\\|that\\|its")
145 "Words not to be capitalized in a title (unless the first word).")
146
147 (defvar r2b-capitalize-title-stop-regexp
148 (concat "\\(" r2b-capitalize-title-stop-words "\\)\\(\\b\\|'\\)"))
149
150 (defun r2b-capitalize-title-region (begin end)
151 "Like `capitalize-region', but don't capitalize stop words, except the first."
152 (interactive "r")
153 (let ((case-fold-search nil) (orig-syntax-table (syntax-table)))
154 (unwind-protect
155 (save-restriction
156 (set-syntax-table text-mode-syntax-table)
157 (narrow-to-region begin end)
158 (goto-char (point-min))
159 (if (looking-at "[A-Z][a-z]*[A-Z]")
160 (forward-word 1)
161 (capitalize-word 1))
162 (while (re-search-forward "\\<" nil t)
163 (if (looking-at "[A-Z][a-z]*[A-Z]")
164 (forward-word 1)
165 (if (let ((case-fold-search t))
166 (looking-at r2b-capitalize-title-stop-regexp))
167 (downcase-word 1)
168 (capitalize-word 1)))
169 ))
170 (set-syntax-table orig-syntax-table))))
171
172
173 (defun r2b-capitalize-title (s)
174 "Like `capitalize', but don't capitalize stop words, except the first."
175 (save-excursion
176 (set-buffer (get-buffer-create "$$$Scratch$$$"))
177 (erase-buffer)
178 (insert s)
179 (r2b-capitalize-title-region (point-min) (point-max))
180 (buffer-string)))
181
182 ;*********************************************************
183 (defun r2b-reset ()
184 "Unbind defvars, for debugging."
185 (interactive)
186 (makunbound 'r2b-journal-abbrevs)
187 (makunbound 'r2b-booktitle-abbrevs)
188 (makunbound 'r2b-proceedings-list)
189 (makunbound 'r2b-capitalize-title-stop-words)
190 (makunbound 'r2b-capitalize-title-stop-regexp)
191 (makunbound 'r2b-additional-stop-words)
192 (makunbound 'r2b-stop-regexp))
193
194 (defvar r2b-stop-regexp
195 (concat "\\`\\(\\("
196 r2b-additional-stop-words "\\|" r2b-capitalize-title-stop-words
197 "\\)\\('\\w*\\)?\\W+\\)*\\([A-Z0-9]+\\)"))
198
199
200 (defun r2b-trace (&rest args)
201 (if r2b-trace-on
202 (progn
203 (apply (function message) args)
204 (sit-for 0))))
205
206 (defun r2b-match (exp)
207 "Returns string matched in current buffer."
208 (buffer-substring (match-beginning exp) (match-end exp)))
209
210 (defcustom r2b-out-buf-name "*Out*"
211 "*Name of buffer for output from refer-to-bibtex."
212 :type 'string
213 :group 'refbib)
214
215 (defcustom r2b-log-name "*Log*"
216 "*Name of buffer for logs errors from refer-to-bibtex."
217 :type 'string
218 :group 'refbib)
219
220 (defvar r2b-in-buf nil)
221 (defvar r2b-out-buf nil)
222 (defvar r2b-log nil)
223
224 (defvar r2b-error-found nil)
225
226 (eval-when-compile
227 (defvar r2b-variables) (defvar r2bv-address) (defvar r2bv-annote)
228 (defvar r2bv-author) (defvar r2bv-booktitle) (defvar r2bv-date)
229 (defvar r2bv-decade) (defvar r2bv-editor) (defvar r2bv-entry-kind)
230 (defvar r2bv-institution) (defvar r2bv-journal) (defvar r2bv-keywords)
231 (defvar r2bv-kn) (defvar r2bv-month) (defvar r2bv-note)
232 (defvar r2bv-number) (defvar r2bv-ordering) (defvar r2bv-organization)
233 (defvar r2bv-pages) (defvar r2bv-primary-author) (defvar r2bv-publisher)
234 (defvar r2bv-school) (defvar r2bv-title) (defvar r2bv-title-first-word)
235 (defvar r2bv-tr) (defvar r2bv-type) (defvar r2bv-volume)
236 (defvar r2bv-where) (defvar r2bv-year))
237
238 (setq r2b-variables '(
239 r2b-error-found
240 r2bv-author
241 r2bv-primary-author
242 r2bv-date
243 r2bv-year
244 r2bv-decade
245 r2bv-month
246 r2bv-title
247 r2bv-title-first-word
248 r2bv-editor
249 r2bv-annote
250 r2bv-tr
251 r2bv-address
252 r2bv-institution
253 r2bv-keywords
254 r2bv-booktitle
255 r2bv-journal
256 r2bv-volume
257 r2bv-number
258 r2bv-pages
259 r2bv-booktitle
260 r2bv-kn
261 r2bv-publisher
262 r2bv-organization
263 r2bv-school
264 r2bv-type
265 r2bv-where
266 r2bv-note
267 r2bv-ordering
268 ))
269
270 (defun r2b-clear-variables ()
271 "Set all global vars used by r2b to nil."
272 (let ((vars r2b-variables))
273 (while vars
274 (set (car vars) nil)
275 (setq vars (cdr vars)))))
276
277 (defun r2b-warning (&rest args)
278 (setq r2b-error-found t)
279 (princ (apply (function format) args) r2b-log)
280 (princ "\n" r2b-log)
281 (princ "\n" r2b-out-buf)
282 (princ "% " r2b-out-buf)
283 (princ (apply (function format) args) r2b-out-buf))
284
285 (defun r2b-get-field (var field &optional unique required capitalize)
286 "Set VAR to string value of FIELD, if any. If none, VAR is set to
287 nil. If multiple fields appear, then separate values with the
288 '\\nand\\t\\t', unless UNIQUE is non-nil, in which case log a warning
289 and just concatenate the values. Trim off leading blanks and tabs on
290 first line, and trailing blanks and tabs of every line. Log a warning
291 and set VAR to the empty string if REQUIRED is true. Capitalize as a
292 title if CAPITALIZE is true. Returns value of VAR."
293 (let (item val (not-past-end t))
294 (r2b-trace "snarfing %s" field)
295 (goto-char (point-min))
296 (while (and not-past-end
297 (re-search-forward
298 (concat "^" field "\\b[ \t]*\\(.*[^ \t\n]\\)[ \t]*") nil t))
299 (setq item (r2b-match 1))
300 (while (and (setq not-past-end (zerop (forward-line 1)))
301 (not (looking-at "[ \t]*$\\|%")))
302 (looking-at "\\(.*[^ \t\n]\\)[ \t]*$")
303 (setq item (concat item "\n" (r2b-match 1)))
304 )
305 (if (null val)
306 (setq val item)
307 (if unique
308 (progn
309 (r2b-warning "*Invalid multiple field %s %s" field item)
310 (setq val (concat val "\n" item))
311 )
312 (setq val (concat val "\n\t\tand " item))
313 )
314 )
315 )
316 (if (and val capitalize)
317 (setq val (r2b-capitalize-title val)))
318 (set var val)
319 (if (and (null val) required)
320 (r2b-require var))
321 ))
322
323 (defun r2b-set-match (var n regexp string )
324 "Set VAR to the Nth subpattern in REGEXP matched by STRING, or nil if none."
325 (set var
326 (if (and (stringp string) (string-match regexp string))
327 (substring string (match-beginning n) (match-end n))
328 nil)
329 )
330 )
331
332 (defvar r2b-month-abbrevs
333 '(("jan") ("feb") ("mar") ("apr") ("may") ("jun") ("jul") ("aug")
334 ("sep") ("oct") ("nov") ("dec")))
335
336 (defun r2b-convert-month ()
337 "Try to convert `r2bv-month' to a standard 3 letter name."
338 (if r2bv-month
339 (let ((months r2b-month-abbrevs))
340 (if (string-match "[^0-9]" r2bv-month)
341 (progn
342 (while (and months (not (string-match (car (car months))
343 r2bv-month)))
344 (setq months (cdr months)))
345 (if months
346 (setq r2bv-month (car (car months)))))
347 (progn
348 (setq months (car (read-from-string r2bv-month)))
349 (if (and (numberp months)
350 (> months 0)
351 (< months 13))
352 (setq r2bv-month (car (nth months r2b-month-abbrevs)))
353 (progn
354 (r2b-warning "* Ridiculous month")
355 (setq r2bv-month nil))
356 ))
357 ))
358 )
359 )
360
361 (defun r2b-snarf-input ()
362 "Parse buffer into global variables."
363 (let ((case-fold-search t))
364 (r2b-trace "snarfing...")
365 (sit-for 0)
366 (set-buffer r2b-in-buf)
367 (goto-char (point-min))
368 (princ " " r2b-log)
369 (princ (buffer-substring (point) (progn (end-of-line) (point))) r2b-log)
370 (terpri r2b-log)
371
372 (r2b-get-field 'r2bv-author "%A")
373 (r2b-get-field 'r2bv-editor "%E")
374 (cond
375 (r2bv-author
376 (r2b-set-match 'r2bv-primary-author 1
377 "\\b\\(\\w+\\)[ \t]*\\($\\|,\\)" r2bv-author)
378 )
379 (r2bv-editor
380 (r2b-set-match 'r2bv-primary-author 1
381 "\\b\\(\\w+\\)[ \t]*\\($\\|,\\)" r2bv-editor)
382 )
383 (t
384 (setq r2bv-primary-author "")
385 )
386 )
387
388 (r2b-get-field 'r2bv-date "%D" t t)
389 (r2b-set-match 'r2bv-year 0 "[12][0-9][0-9][0-9]" r2bv-date)
390 (and (null r2bv-year)
391 (r2b-set-match 'r2bv-year 1 "[^0-9]\\([0-9][0-9]\\)$" r2bv-date)
392 (setq r2bv-year (concat "19" r2bv-year)))
393 (r2b-set-match 'r2bv-decade 1 "..\\(..\\)" r2bv-year)
394 (r2b-set-match 'r2bv-month 0
395 "[0-9]+/\\|[a-zA-Z]+" r2bv-date)
396 (if (and (stringp r2bv-month) (string-match "\\(.*\\)/$" r2bv-month))
397 (setq r2bv-month (substring r2bv-month 0 (match-end 1))))
398 (r2b-convert-month)
399
400 (r2b-get-field 'r2bv-title "%T" t t t)
401 (r2b-set-match 'r2bv-title-first-word 4
402 r2b-stop-regexp
403 r2bv-title)
404
405 (r2b-get-field 'r2bv-annote "%X" t )
406 (r2b-get-field 'r2bv-tr "%R" t)
407 (r2b-get-field 'r2bv-address "%C" t)
408 (r2b-get-field 'r2bv-institution "%I" t)
409 (r2b-get-field 'r2bv-keywords "%K")
410 (r2b-get-field 'r2bv-booktitle "%B" t nil t)
411 (r2b-get-field 'r2bv-journal "%J" t nil t)
412 (r2b-get-field 'r2bv-volume "%V" t)
413 (r2b-get-field 'r2bv-number "%N" t)
414 (r2b-get-field 'r2bv-pages "%P" t)
415 (r2b-get-field 'r2bv-where "%W" t)
416 (r2b-get-field 'r2bv-ordering "%O" t)
417 )
418 )
419
420
421 (defun r2b-put-field (field data &optional abbrevs)
422 "Print bibtex FIELD = {DATA} if DATA not null; precede
423 with a comma and newline; if ABBREVS list is given, then
424 try to replace the {DATA} with an abbreviation."
425 (if data
426 (let (match nodelim multi-line index)
427 (cond
428 ((and abbrevs (setq match (assoc data abbrevs)))
429 (if (null (cdr match))
430 (setq data (car match))
431 (setq data (car (cdr match))))
432 (setq nodelim t))
433 ((and (not (equal data ""))
434 (not (string-match "[^0-9]" data)))
435 (setq nodelim t))
436 (t
437 (setq index 0)
438 (while (string-match "[\\~^]" data index)
439 (setq data (concat (substring data 0 (match-beginning 0))
440 "\\verb+"
441 (substring data (match-beginning 0) (match-end 0))
442 "+"
443 (substring data (match-end 0))))
444 (setq index (+ (match-end 0) 7)))
445 (setq index 0)
446 (while (string-match "[$&%#_{}]" data index)
447 (setq data (concat (substring data 0 (match-beginning 0))
448 "\\"
449 (substring data (match-beginning 0))))
450 (setq index (+ (match-end 0) 1)))
451 (setq index 0)
452 (if r2b-delimit-with-quote
453 (while (string-match "\"" data index)
454 (setq data (concat (substring data 0 (match-beginning 0))
455 "{\"}"
456 (substring data (match-end 0))))
457 (setq index (+ (match-end 0) 2))))
458 ))
459 (princ ", \n ")
460 (princ field)
461 (princ " =\t")
462 (if (not nodelim)
463 (if r2b-delimit-with-quote
464 (princ "\"")
465 (princ "{")))
466 (string-match ".*" data)
467 (if (> (match-end 0) 59)
468 (princ "\n"))
469 (princ data)
470 (if (not nodelim)
471 (if r2b-delimit-with-quote
472 (princ "\"")
473 (princ "}")))
474 )
475 ))
476
477
478 (defun r2b-require (vars)
479 "If any of VARS is null, set to empty string and log error."
480 (cond
481 ((null vars))
482 ((listp vars) (r2b-require (car vars)) (r2b-require (cdr vars)))
483 (t
484 (if (null (symbol-value vars))
485 (progn
486 (r2b-warning "*Missing value for field %s" vars)
487 (set vars "")
488 )))
489 )
490 )
491
492
493 (defmacro r2b-moveq (new old)
494 "Set NEW to OLD and set OLD to nil."
495 (list 'progn (list 'setq new old) (list 'setq old 'nil)))
496
497 (defun r2b-isa-proceedings (name)
498 "Return t if NAME is the name of proceedings."
499 (and
500 name
501 (or
502 (string-match "proceedings\\|conference" name)
503 (assoc name r2b-proceedings-list)
504 (let ((match (assoc name r2b-booktitle-abbrevs)))
505 (and match
506 (string-match "proceedings\\|conference" (car (cdr match)))))
507 )))
508
509 (defun r2b-isa-university (name)
510 "Return t if NAME is a university or similar organization,
511 but not a publisher."
512 (and
513 name
514 (string-match "university" name)
515 (not (string-match "press" name))
516
517 ))
518
519 (defun r2b-barf-output ()
520 "Generate bibtex based on global variables."
521 (let ((standard-output r2b-out-buf) (case-fold-search t) match)
522
523 (r2b-trace "...barfing")
524 (sit-for 0)
525 (set-buffer r2b-out-buf)
526
527 (setq r2bv-kn (concat r2bv-primary-author r2bv-decade
528 r2bv-title-first-word))
529
530 (setq r2bv-entry-kind
531 (cond
532 ((r2b-isa-proceedings r2bv-journal)
533 (r2b-moveq r2bv-booktitle r2bv-journal)
534 (if (r2b-isa-university r2bv-institution)
535 (r2b-moveq r2bv-organization r2bv-institution)
536 (r2b-moveq r2bv-publisher r2bv-institution))
537 (r2b-moveq r2bv-note r2bv-tr)
538 (r2b-require 'r2bv-author)
539 'inproceedings)
540 ((r2b-isa-proceedings r2bv-booktitle)
541 (if (r2b-isa-university r2bv-institution)
542 (r2b-moveq r2bv-organization r2bv-institution)
543 (r2b-moveq r2bv-publisher r2bv-institution))
544 (r2b-moveq r2bv-note r2bv-tr)
545 (r2b-require 'r2bv-author)
546 'inproceedings)
547 ((and r2bv-tr (string-match "phd" r2bv-tr))
548 (r2b-moveq r2bv-school r2bv-institution)
549 (r2b-require 'r2bv-school )
550 (r2b-require 'r2bv-author)
551 'phdthesis)
552 ((and r2bv-tr (string-match "master" r2bv-tr))
553 (r2b-moveq r2bv-school r2bv-institution)
554 (r2b-require 'r2bv-school )
555 (r2b-require 'r2bv-author)
556 'mastersthesis)
557 ((and r2bv-tr (string-match "draft\\|unpublish" r2bv-tr))
558 (r2b-moveq r2bv-note r2bv-institution)
559 (r2b-require 'r2bv-author)
560 'unpublished)
561 (r2bv-journal
562 (r2b-require 'r2bv-author)
563 'article)
564 (r2bv-booktitle
565 (r2b-moveq r2bv-publisher r2bv-institution)
566 (r2b-moveq r2bv-note r2bv-tr)
567 (r2b-require 'r2bv-publisher)
568 (r2b-require 'r2bv-author)
569 'incollection)
570 ((and r2bv-author
571 (null r2bv-editor)
572 (string-match "\\`personal communication\\'" r2bv-title))
573 'misc)
574 ((r2b-isa-proceedings r2bv-title)
575 (if (r2b-isa-university r2bv-institution)
576 (r2b-moveq r2bv-organization r2bv-institution)
577 (r2b-moveq r2bv-publisher r2bv-institution))
578 (r2b-moveq r2bv-note r2bv-tr)
579 'proceedings)
580 ((or r2bv-editor
581 (and r2bv-author
582 (or
583 (null r2bv-tr)
584 (string-match "\\bisbn\\b" r2bv-tr))))
585 (r2b-moveq r2bv-publisher r2bv-institution)
586 (r2b-moveq r2bv-note r2bv-tr)
587 (r2b-require 'r2bv-publisher)
588 (if (null r2bv-editor)
589 (r2b-require 'r2bv-author))
590 'book)
591 (r2bv-tr
592 (r2b-require 'r2bv-institution)
593 (if (string-match
594 "\\`\\(\\(.\\|\n\\)+\\)[ \t\n]+\\([^ \t\n]\\)+\\'"
595 r2bv-tr)
596 (progn
597 (setq r2bv-type (substring r2bv-tr 0 (match-end 1)))
598 (setq r2bv-number (substring r2bv-tr
599 (match-beginning 3)))
600 (setq r2bv-tr nil))
601 (r2b-moveq r2bv-number r2bv-tr))
602 (r2b-require 'r2bv-author)
603 'techreport)
604 (r2bv-institution
605 (r2b-moveq r2bv-organization r2bv-institution)
606 'manual)
607 (t
608 'misc)
609 ))
610
611 (r2b-require '( r2bv-year))
612
613 (if r2b-error-found
614 (princ "\n% Warning -- Errors During Conversion Next Entry\n"))
615
616 (princ "\n@")
617 (princ r2bv-entry-kind)
618 (princ "( ")
619 (princ r2bv-kn)
620
621 (r2b-put-field "author" r2bv-author )
622 (r2b-put-field "title" r2bv-title r2b-booktitle-abbrevs)
623 (r2b-put-field "year" r2bv-year )
624
625 (r2b-put-field "month" r2bv-month r2b-month-abbrevs)
626 (r2b-put-field "journal" r2bv-journal r2b-journal-abbrevs)
627 (r2b-put-field "volume" r2bv-volume)
628 (r2b-put-field "type" r2bv-type)
629 (r2b-put-field "number" r2bv-number)
630 (r2b-put-field "booktitle" r2bv-booktitle r2b-booktitle-abbrevs)
631 (r2b-put-field "editor" r2bv-editor)
632 (r2b-put-field "publisher" r2bv-publisher)
633 (r2b-put-field "institution" r2bv-institution)
634 (r2b-put-field "organization" r2bv-organization)
635 (r2b-put-field "school" r2bv-school)
636 (r2b-put-field "pages" r2bv-pages)
637 (r2b-put-field "address" r2bv-address)
638 (r2b-put-field "note" r2bv-note)
639 (r2b-put-field "keywords" r2bv-keywords)
640 (r2b-put-field "where" r2bv-where)
641 (r2b-put-field "ordering" r2bv-ordering)
642 (r2b-put-field "annote" r2bv-annote)
643
644 (princ " )\n")
645 )
646 )
647
648
649 (defun r2b-convert-record (output)
650 "Transform current bib entry and append to buffer OUTPUT.
651 Do `\\[r2b-help]' for more info."
652 (interactive
653 (list (read-string "Output to buffer: " r2b-out-buf-name)))
654 (let (rec-end rec-begin not-done)
655 (setq r2b-out-buf-name output)
656 (setq r2b-out-buf (get-buffer-create output))
657 (setq r2b-in-buf (current-buffer))
658 (set-buffer r2b-out-buf)
659 (goto-char (point-max))
660 (setq r2b-log (get-buffer-create r2b-log-name))
661 (set-buffer r2b-log)
662 (goto-char (point-max))
663 (set-buffer r2b-in-buf)
664 (setq not-done (re-search-forward "[^ \t\n]" nil t))
665 (if not-done
666 (progn
667 (re-search-backward "^[ \t]*$" nil 2)
668 (re-search-forward "^%")
669 (beginning-of-line nil)
670 (setq rec-begin (point))
671 (re-search-forward "^[ \t]*$" nil 2)
672 (setq rec-end (point))
673 (narrow-to-region rec-begin rec-end)
674 (r2b-clear-variables)
675 (r2b-snarf-input)
676 (r2b-barf-output)
677 (set-buffer r2b-in-buf)
678 (widen)
679 (goto-char rec-end)
680 t)
681 nil
682 )
683 ))
684
685
686 (defun r2b-convert-buffer (output)
687 "Transform current buffer and append to buffer OUTPUT.
688 Do `\\[r2b-help]' for more info."
689 (interactive
690 (list (read-string "Output to buffer: " r2b-out-buf-name)))
691 (save-excursion
692 (setq r2b-log (get-buffer-create r2b-log-name))
693 (set-buffer r2b-log)
694 (erase-buffer))
695 (widen)
696 (goto-char (point-min))
697 (message "Working, please be patient...")
698 (sit-for 0)
699 (while (r2b-convert-record output) t)
700 (message "Done, results in %s, errors in %s"
701 r2b-out-buf-name r2b-log-name)
702 )
703
704 (defvar r2b-help-message
705 " Refer to Bibtex Bibliography Conversion
706
707 A refer-style database is of the form:
708
709 %A Joe Blow
710 %T Great Thoughts I've Thought
711 %D 1977
712 etc.
713
714 This utility converts these kind of databases to bibtex form, for
715 users of TeX and LaTex. Instructions:
716 1. Visit the file containing the refer-style database.
717 2. The command
718 M-x r2b-convert-buffer
719 converts the entire buffer, appending its output by default in a
720 buffer named *Out*, and logging progress and errors in a buffer
721 named *Log*. The original file is never modified.
722 Note that results are appended to *Out*, so if that buffer
723 buffer already exists and contains material you don't want to
724 save, you should kill it first.
725 3. Switch to the buffer *Out* and save it as a named file.
726 4. To convert a single refer-style entry, simply position the cursor
727 at the entry and enter
728 M-x r2b-convert-record
729 Again output is appended to *Out* and errors are logged in *Log*.
730
731 This utility is very robust and pretty smart about determining the
732 type of the entry. It includes facilities for expanding refer macros
733 to text, or substituting bibtex macros. Do M-x describe-variable on
734 r2b-journal-abbrevs
735 r2b-booktitle-abbrevs
736 r2b-proceedings-list
737 for information on these features.
738
739 Please send bug reports and suggestions to
740 Henry Kautz
741 kautz@research.att.com
742 allegra!kautz")
743
744
745 (defun r2b-help ()
746 "Print help describing the `refbib' package."
747 (interactive)
748 (with-output-to-temp-buffer "*Help*"
749 (princ r2b-help-message)
750 (save-excursion
751 (set-buffer standard-output)
752 (help-mode))))
753
754 (provide 'refbib)
755 (provide 'refer-to-bibtex)
756
757 ;;; arch-tag: 664afee2-6e76-4408-ba56-981d8a179586
758 ;;; refbib.el ends here