aboutsummaryrefslogtreecommitdiffstats
path: root/bib-gen
blob: 0fdd63a7dd872968bc371c42c92805506e2cdafb (plain)
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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"