Marty Oehme
f96f9f2211
Scrapes a bibtex file for 'due' field, and outputs all found entries with their priority and sorted for date.
147 lines
4.1 KiB
Bash
Executable file
147 lines
4.1 KiB
Bash
Executable file
#!/usr/bin/env sh
|
|
# shows due entries of bibtex file passed in
|
|
# HACK: brittle! will break on various bibfile abnormities (even just on due date w/o priority)
|
|
# FIXME: reimplementation with real library needed
|
|
#
|
|
|
|
OPTIND=1 # Reset in case getopts has been used previously in the shell.
|
|
fields="due|priority|\bauthor\b|\btitle\b"
|
|
filterby="due"
|
|
file="${BIBFILE}"
|
|
until=""
|
|
|
|
show_help() {
|
|
printf "%s\n" \
|
|
"" \
|
|
" bib-due Show due readings from bibtex file." \
|
|
"" \
|
|
" Usage: bib-due [-hv] -i input.bib -r 'due|priority|\bauthor|\btitle' -l 'due' -u '2020-05-12'" \
|
|
"" \
|
|
" Options:" \
|
|
"" \
|
|
" -i [bibtex-file] Input bibtex file to scrape and get items from." \
|
|
"" \
|
|
" -r [fields] Field values to read in file." \
|
|
"" \
|
|
" -l [filter] Field to use as filter entity." \
|
|
" This field is required for the scraper to pick entries up." \
|
|
"" \
|
|
" help | -h | --help Print out this help." \
|
|
"" \
|
|
" Invoked without arguments, bib-due will scrape the file defined in BIBFILE environment variable, " \
|
|
" filtering entries with the 'due' field, and getting the values for 'due', 'priority', 'author', " \
|
|
" and 'title' fields. It will then print the entries to stdout." \
|
|
"" \
|
|
" Example output line:" \
|
|
"" \
|
|
' 2020-06-25 (1): Sergei Gerasymchuk -- “Ze” time in Ukraine (Gerasymchuk2019) ' \
|
|
""
|
|
}
|
|
|
|
filter_until() {
|
|
# filter for dates, with line numbers
|
|
filtered=$(echo "$entries" | grep -noE '[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}')
|
|
|
|
# redirect entries to fifo pipe
|
|
mkfifo filteredentries
|
|
finish() {
|
|
rm filteredentries
|
|
}
|
|
trap finish EXIT
|
|
echo "$filtered" >filteredentries &
|
|
|
|
# find first date past until filter
|
|
lastline=""
|
|
while IFS= read -r line; do
|
|
cond=$(printf '%s' "$line" | cut -d: -f2)
|
|
cond=$(date -d "$cond" +%s)
|
|
if [ "$cond" -gt "$until" ]; then
|
|
lastline=$(printf '%s' "$line" | cut -d: -f1)
|
|
break
|
|
fi
|
|
done <filteredentries
|
|
|
|
# special cases all in filter, or none in filter
|
|
if [ -z "$lastline" ]; then
|
|
return
|
|
elif [ "$lastline" -eq 1 ]; then
|
|
entries=""
|
|
# filter
|
|
else
|
|
# remove lines below found
|
|
lastprinted="$((lastline - 1))"
|
|
entries=$(echo "$entries" | sed -n "1,${lastprinted}p;${lastline}q")
|
|
fi
|
|
}
|
|
|
|
filter_priority() {
|
|
priority="$1"
|
|
# filter for dates, with line numbers
|
|
# filtered=$(echo "$entries" | grep -noE '[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}')
|
|
filtered=""
|
|
while [ "$priority" -gt 0 ]; do
|
|
current=$(echo "$entries" | grep -E "\($priority\)")
|
|
|
|
# append found to filtered entries
|
|
filtered=$(printf "%s\n%s" "$filtered" "$current")
|
|
|
|
# go to next 'higher' priority
|
|
priority="$((priority - 1))"
|
|
done
|
|
# sort them chronologically again, remove empty lines
|
|
entries="$(echo "$filtered" | sed -e '/^$/d' | sort)"
|
|
}
|
|
|
|
main() {
|
|
if [ -z "$file" ]; then
|
|
echo "Requires a bibtex file as argument."
|
|
exit 1
|
|
fi
|
|
|
|
# filter all entries for those containing filterby field (default: due)
|
|
# retain values of all fields mentioned in fields variable
|
|
entries=$(grep -E "^@|$fields" "$file" | awk 1 ORS=' ' | sed -E 's/@\w+\{/\n/g' | grep "$filterby" | tail -n +2 | sed -E 's/(,\s+(\w+)\s+=\s+|,\s*$)/\t/g' | awk -F'\t' '{ print $4 "\t" $5 "\t" $2 "\t" $3 "\t" $1 }')
|
|
|
|
# prettify and sort the entries for display (remove {}, order by date,prio,author,title)
|
|
entries=$(echo "$entries" | awk -F'\t' '{ gsub(/{/,""); gsub(/}/,""); gsub(/prio/,"",$2) } { print $1 " (" $2 "): " $3 " -- " $4 " (" $5 ")"}' | sort)
|
|
|
|
if [ -n "$until" ]; then
|
|
filter_until
|
|
fi
|
|
if [ -n "$priority" ]; then
|
|
filter_priority "$priority"
|
|
fi
|
|
|
|
echo "$entries"
|
|
}
|
|
|
|
while getopts "h?i:u:r:l:p:" opt; do
|
|
case "$opt" in
|
|
h | \?)
|
|
show_help
|
|
exit 0
|
|
;;
|
|
# v) verbose=1
|
|
# ;;
|
|
r)
|
|
fields="$OPTARG"
|
|
;;
|
|
l)
|
|
filterby="$OPTARG"
|
|
;;
|
|
i)
|
|
file="$OPTARG"
|
|
;;
|
|
u)
|
|
until="$(date -d "$OPTARG" +%s)"
|
|
;;
|
|
p)
|
|
priority="$OPTARG"
|
|
;;
|
|
esac
|
|
done
|
|
shift $((OPTIND - 1))
|
|
|
|
[ "${1:-}" = "--" ] && shift
|
|
|
|
main "$@"
|