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