Skip to content

Instantly share code, notes, and snippets.

@hmenke

hmenke/tlclosure.sh

Last active Aug 14, 2020
Embed
What would you like to do?
Determine the transitive closure of dependencies of a TeX document
#!/usr/bin/env bash
set -eo pipefail
program="${0##*/}"
scheme="scheme-infraonly"
opts="$(getopt -o s: -l scheme: -n "$0" -- "$@")"
err="$?"
eval set -- "$opts"
while true; do case $1 in
-s|--scheme) scheme="$2"; shift 2 ;;
--) shift; break ;;
esac done
flsfile="$1"
if [ $err -ne 0 ] || [ $# -lt 1 ]; then
cat >&2 <<-EOF
Usage: $program [OPTIONS]... FILE.fls
OPTIONS
-s, --scheme=SET TeX Live scheme to base on (default: scheme-infraonly)
EXAMPLES
$ pdflatex -recorder test.tex
$ tlclosure -s scheme-basic test.fls
EOF
exit 1
fi
tmpdir=$(mktemp -d)
arch=$(tlmgr print-platform)
echo "Listing packages defined by $scheme"
cachedir="${XDG_CACHE_HOME:-$HOME/.cache}/tlclosure"
scheme_cache="$cachedir/$scheme.txt"
recurse() {
while read pkgs; do
[ -z "$pkgs" ] && break
echo "$pkgs" | tr ' ' '\n' | tee -a "$tmpdir/scheme.txt"
tlmgr info --data depends $pkgs | sed "s/ARCH/$arch/g" | tr ':' ' ' | tr '\n' ' ' | xargs | recurse
done
}
# TODO: expire cache
# compare mtime of $scheme_cache and tlpdb
if [ -f "$scheme_cache" ]; then
echo "=> Cache exists"
else
echo "$scheme" | recurse
mkdir -p "$cachedir"
sort "$tmpdir/scheme.txt" | uniq > "$scheme_cache"
fi
echo "Looking up the corresponding packages in TeX Live"
touch "$tmpdir/pkgs.txt"
grep '^INPUT ' "$flsfile" | xargs -i -P $(nproc) bash -c "
line=\"{}\"
file=\"\${line##INPUT }\"
[ -f \"./\$file\" ] && exit
pkg=\"\$(tlmgr search --file \"/\${file##*/}\\\$\" | head -n 1 | tr -d ':')\"
{
flock -x 9
if [ -n \"\$pkg\" ] &&
! grep -qFx \"\$pkg\" '$scheme_cache' &&
! grep -qFx \"\$pkg\" '$tmpdir/pkgs.txt'
then
echo \"\$pkg\" | tee -a '$tmpdir/pkgs.txt'
fi
} 9> '$tmpdir/pkgs.lock'
"
echo "$scheme" > "./pkgs.txt"
sort "$tmpdir/pkgs.txt" | uniq >> "./pkgs.txt"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment