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