aboutsummaryrefslogtreecommitdiffstats
path: root/bib-gen
diff options
context:
space:
mode:
authorDouglas B. Rumbaugh <doug@douglasrumbaugh.com>2026-06-06 12:02:41 -0400
committerDouglas B. Rumbaugh <doug@douglasrumbaugh.com>2026-06-06 12:02:41 -0400
commiteabf1f6d74dac497ce31e3e2f441cfa25e9f74f2 (patch)
tree626d64c3574cfbc7cc38eae6d142ef22b21cf59b /bib-gen
parent8351a1da3f56cde9939b934bc5533a95aff1c95e (diff)
downloadbibutils-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 'bib-gen')
-rwxr-xr-xbib-gen95
1 files changed, 95 insertions, 0 deletions
diff --git a/bib-gen b/bib-gen
new file mode 100755
index 0000000..0fdd63a
--- /dev/null
+++ b/bib-gen
@@ -0,0 +1,95 @@
+#!/bin/sh
+# bib-gen - generate a bibtex entry
+#
+# usage: bib-gen [-t type] [field=value ...]
+# bib-gen [-t type] -F field,field,... (tab-separated stdin)
+#
+# With field=value arguments, one entry is built from them. With -F,
+# one entry is built per tab-separated line of stdin, columns matching
+# the listed fields. Otherwise the user is prompted interactively.
+# Entries are emitted on stdout with generated keys.
+
+usage() {
+ printf 'usage: bib-gen [-t type] [field=value ...]\n' >&2
+ printf ' bib-gen [-t type] -F field,field,... < data\n' >&2
+ exit 2
+}
+
+type=article
+fmt=
+while getopts t:F: opt; do
+ case $opt in
+ t) type=$OPTARG ;;
+ F) fmt=$OPTARG ;;
+ *) usage ;;
+ esac
+done
+shift $((OPTIND - 1))
+
+bibkey=$(dirname "$0")/bib-key
+[ -x "$bibkey" ] || bibkey=bib-key
+
+# fields prompted for in interactive mode, per entry type
+fields_for() {
+ case $1 in
+ article) echo "author title journal year volume number pages month doi" ;;
+ book) echo "author title publisher year volume series address edition" ;;
+ inproceedings|conference)
+ echo "author title booktitle year editor pages publisher doi" ;;
+ incollection) echo "author title booktitle publisher year editor pages chapter" ;;
+ techreport) echo "author title institution year number address month" ;;
+ phdthesis|mastersthesis)
+ echo "author title school year address month" ;;
+ *) echo "author title year howpublished note url" ;;
+ esac
+}
+
+if [ -n "$fmt" ]; then
+ # batch mode: tab-separated values on stdin
+ awk -F '\t' -v fmt="$fmt" -v type="$type" '
+ BEGIN { nf = split(fmt, F, ",") }
+ NF {
+ printf "@%s{FIXME,\n", type
+ for (i = 1; i <= nf && i <= NF; i++)
+ if ($i != "")
+ printf " %s = {%s},\n", F[i], $i
+ print "}"
+ }' | "$bibkey"
+ exit $?
+fi
+
+tmp=$(mktemp) || exit 1
+trap 'rm -f "$tmp"' EXIT INT TERM
+
+if [ $# -gt 0 ]; then
+ # argument mode: field=value pairs
+ for arg in "$@"; do
+ case $arg in
+ *=*) printf '%s\t%s\n' "${arg%%=*}" "${arg#*=}" >> "$tmp" ;;
+ *) usage ;;
+ esac
+ done
+else
+ # interactive mode
+ printf 'entry type [%s]: ' "$type" >&2
+ read -r ans || exit 1
+ [ -n "$ans" ] && type=$ans
+ for f in $(fields_for "$type"); do
+ printf '%s: ' "$f" >&2
+ read -r ans || break
+ [ -n "$ans" ] && printf '%s\t%s\n' "$f" "$ans" >> "$tmp"
+ done
+fi
+
+if [ ! -s "$tmp" ]; then
+ printf 'bib-gen: no fields given\n' >&2
+ exit 1
+fi
+
+{
+ printf '@%s{FIXME,\n' "$type"
+ while IFS=' ' read -r name value; do
+ printf ' %s = {%s},\n' "$name" "$value"
+ done < "$tmp"
+ printf '}\n'
+} | "$bibkey"