aboutsummaryrefslogtreecommitdiffstats
path: root/bib-add
diff options
context:
space:
mode:
Diffstat (limited to 'bib-add')
-rwxr-xr-xbib-add67
1 files changed, 67 insertions, 0 deletions
diff --git a/bib-add b/bib-add
new file mode 100755
index 0000000..28ebf82
--- /dev/null
+++ b/bib-add
@@ -0,0 +1,67 @@
+#!/bin/sh
+# bib-add - insert bibtex entries from stdin into a database file
+#
+# usage: bib-add [-f] db.bib < entry
+# -f replace existing entries with the same key
+
+usage() {
+ printf 'usage: bib-add [-f] db.bib < entry\n' >&2
+ exit 2
+}
+
+if [ -n "$BIBUTILS_LIB" ]; then
+ LIB=$BIBUTILS_LIB
+elif [ -d "$(dirname "$0")/lib" ]; then
+ LIB=$(dirname "$0")/lib
+else
+ LIB=/usr/local/share/bibutils
+fi
+
+force=0
+while getopts f opt; do
+ case $opt in
+ f) force=1 ;;
+ *) usage ;;
+ esac
+done
+shift $((OPTIND - 1))
+[ $# -eq 1 ] || usage
+db=$1
+
+tmp=$(mktemp) && tmpkeys=$(mktemp) && tmpdb=$(mktemp) || exit 1
+trap 'rm -f "$tmp" "$tmpkeys" "$tmpdb"' EXIT INT TERM
+
+# canonicalize the incoming entries
+awk -f "$LIB/bib-parse.awk" -f "$LIB/bib-canon.awk" -f "$LIB/bib-select.awk" \
+ -v keys= -v invert=1 > "$tmp"
+
+if [ ! -s "$tmp" ]; then
+ printf 'bib-add: no entries on stdin\n' >&2
+ exit 1
+fi
+
+awk -f "$LIB/bib-parse.awk" -f "$LIB/bib-lskeys.awk" "$tmp" > "$tmpkeys"
+
+if [ -f "$db" ]; then
+ dups=$(awk -f "$LIB/bib-parse.awk" -f "$LIB/bib-lskeys.awk" "$db" \
+ | grep -Fxf "$tmpkeys") || dups=
+ if [ -n "$dups" ]; then
+ if [ "$force" -eq 1 ]; then
+ # rewrite the database without the entries being replaced
+ keys=$(printf '%s\n' "$dups" | paste -sd, -)
+ awk -f "$LIB/bib-parse.awk" -f "$LIB/bib-canon.awk" \
+ -f "$LIB/bib-select.awk" -v keys="$keys" -v invert=1 \
+ "$db" > "$tmpdb" || exit 1
+ cp "$tmpdb" "$db"
+ else
+ printf 'bib-add: duplicate keys in %s:\n' "$db" >&2
+ printf '%s\n' "$dups" >&2
+ exit 1
+ fi
+ fi
+fi
+
+{
+ [ -s "$db" ] && echo ""
+ cat "$tmp"
+} >> "$db"