diff options
| author | Douglas B. Rumbaugh <doug@douglasrumbaugh.com> | 2026-06-06 12:02:41 -0400 |
|---|---|---|
| committer | Douglas B. Rumbaugh <doug@douglasrumbaugh.com> | 2026-06-06 12:02:41 -0400 |
| commit | eabf1f6d74dac497ce31e3e2f441cfa25e9f74f2 (patch) | |
| tree | 626d64c3574cfbc7cc38eae6d142ef22b21cf59b /lib/ref2bib.awk | |
| parent | 8351a1da3f56cde9939b934bc5533a95aff1c95e (diff) | |
| download | bibutils-eabf1f6d74dac497ce31e3e2f441cfa25e9f74f2.tar.gz | |
Initial implementation (only a few years later!)
This is pure Claude. I'd written out the plan for
this suite of scripts eons ago, but never found the
time to actual do it. Remembered it this morning,
pointed Claude at the README, and had something
that appears to work in minutes.
caveat emptor: the design is mine, but the code is
purely LLM generated at this point.
Diffstat (limited to 'lib/ref2bib.awk')
| -rw-r--r-- | lib/ref2bib.awk | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/lib/ref2bib.awk b/lib/ref2bib.awk new file mode 100644 index 0000000..422fdd7 --- /dev/null +++ b/lib/ref2bib.awk @@ -0,0 +1,107 @@ +# ref2bib.awk - convert refer records to bibtex entries +# +# Standalone (does not use bib-parse.awk). Records are separated by +# blank lines. Output keys are FIXME; pipe through bib-key. + +BEGIN { + RS = "" + FS = "\n" +} + +function r_trim(t) { + sub(/^[ \t\r]+/, "", t) + sub(/[ \t\r]+$/, "", t) + return t +} + +function r_emit(name, v) { + if (v != "") + printf " %s = {%s},\n", name, v +} + +{ + split("", val) + na = 0 + ne = 0 + split("", A) + split("", E) + lasttag = "" + for (i = 1; i <= NF; i++) { + line = $i + if (substr(line, 1, 1) == "%") { + tag = substr(line, 2, 1) + v = r_trim(substr(line, 3)) + if (tag == "A") + A[++na] = v + else if (tag == "E") + E[++ne] = v + else + val[tag] = v + lasttag = tag + } else if (lasttag == "A") + A[na] = A[na] " " r_trim(line) + else if (lasttag == "E") + E[ne] = E[ne] " " r_trim(line) + else if (lasttag != "") + val[lasttag] = val[lasttag] " " r_trim(line) + } + if (na == 0 && ne == 0 && !("T" in val)) + next + + # guess an entry type from the fields present + if ("J" in val) + type = "article" + else if ("B" in val) + type = (val["B"] ~ /[Pp]roceedings|[Cc]onference|[Ss]ymposium|[Ww]orkshop/) \ + ? "inproceedings" : "incollection" + else if ("R" in val) + type = "techreport" + else if ("I" in val) + type = "book" + else + type = "misc" + + if (out_n++) + print "" + printf "@%s{FIXME,\n", type + + authors = "" + for (i = 1; i <= na; i++) + authors = (i == 1) ? A[i] : authors " and " A[i] + r_emit("author", authors) + editors = "" + for (i = 1; i <= ne; i++) + editors = (i == 1) ? E[i] : editors " and " E[i] + r_emit("editor", editors) + + r_emit("title", val["T"]) + r_emit("journal", val["J"]) + r_emit("booktitle", val["B"]) + + d = val["D"] + if (match(d, /[0-9][0-9][0-9][0-9]/)) { + r_emit("year", substr(d, RSTART, 4)) + m = r_trim(substr(d, 1, RSTART - 1) substr(d, RSTART + 4)) + if (m != "") + r_emit("month", m) + } else + r_emit("year", d) + + r_emit("volume", val["V"]) + r_emit("number", val["N"]) + p = val["P"] + gsub(/-+/, "--", p) + r_emit("pages", p) + r_emit(type == "techreport" ? "institution" : "publisher", val["I"]) + r_emit("address", val["C"]) + if ("R" in val) { + if ("N" in val) + r_emit("note", val["R"]) + else + r_emit("number", val["R"]) + } + r_emit("keywords", val["K"]) + r_emit("abstract", val["X"]) + r_emit("note", val["O"]) + print "}" +} |