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