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