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