diff options
Diffstat (limited to 'bib-extract')
| -rwxr-xr-x | bib-extract | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/bib-extract b/bib-extract new file mode 100755 index 0000000..52aa85b --- /dev/null +++ b/bib-extract @@ -0,0 +1,60 @@ +#!/bin/sh +# bib-extract - emit only the database entries cited in an aux file +# +# usage: bib-extract file.aux [db.bib] (db on stdin if omitted) +# +# roff/refer citation sources are planned but not yet supported. + +usage() { + printf 'usage: bib-extract file.aux [db.bib]\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 + +[ $# -ge 1 ] && [ $# -le 2 ] || usage +aux=$1 +shift +[ -r "$aux" ] || { printf 'bib-extract: cannot read %s\n' "$aux" >&2; exit 1; } + +keys=$(awk ' + # classic bibtex: \citation{key,key,...} + { + line = $0 + while (match(line, /\\citation\{[^}]*\}/)) { + n = split(substr(line, RSTART + 10, RLENGTH - 11), a, ",") + for (i = 1; i <= n; i++) + if (a[i] != "") + print a[i] + line = substr(line, RSTART + RLENGTH) + } + } + # biblatex/biber: \abx@aux@cite{segment}{key} (older: one argument) + { + line = $0 + while (match(line, /\\abx@aux@cite(\{[0-9]*\})?\{[^}]*\}/)) { + s = substr(line, RSTART, RLENGTH) + sub(/\}$/, "", s) + sub(/^.*\{/, "", s) + if (s != "") + print s + line = substr(line, RSTART + RLENGTH) + } + }' "$aux" | sort -u | paste -sd, -) + +[ -n "$keys" ] || exit 0 + +# \nocite{*} cites everything: emit the whole database +case ",$keys," in + *,\*,*) keys= invert=1 ;; + *) invert=0 ;; +esac + +exec awk -f "$LIB/bib-parse.awk" -f "$LIB/bib-canon.awk" \ + -f "$LIB/bib-select.awk" -v keys="$keys" -v invert="$invert" "$@" |