#!/bin/sh set -eu die() { echo "$1" >&2 exit 1 } cachedir="$HOME/.cache/llpp" test -d "$cachedir" || die "cache directory '$cachedir' does not exist" caspsuf= type= executable_p() { command -v "$1" >/dev/null 2>&1; } missing() { executable_p $1 || \ eval "$1() { die \"$2 is needed for \$type conversion\"; }" } trap 'test -n "${casp-}" && rm -f "$casp"' 0 while getopts s:c:m:t:fu opt; do case $opt in m) mime=$OPTARG;; t) type=$OPTARG;; f) force=true;; c) css="-s $OPTARG";; ?) die "usage: $0 [-c css] [-m mime/type] [-t filter] [-f] [path|url]";; esac done shift $(($OPTIND - 1)) test -z "$1" && die "usage $0: path" origin="$1" if ${force-test ! -e "$1"} && expr >/dev/null "$1" : "\(ftp\|https\?\)://"; then if executable_p wget; then dl() { wget -q $1 -O $2; } elif executable_p curl; then dl() { curl -L $1 -o $2; } else die "no program to fetch remote urls found" fi hashof="$cachedir/$(basename "$1")" dl "$1" "$hashof" || test -e "$md5of" shift set -- "$hashof" "$@" else hashof="$1" fi test -z "$type" && { ft=$(file -L --mime-type -b "$1") || die "$ft"; case $ft in application/x-gzip | application/x-compress) dc=zcat;; application/x-xz) dc=xzcat;; application/x-bzip2) dc=bzcat;; *) unset dc || true;; esac } filt='"${dc-cat}" "$1" |' typeofmime() { case "$1" in application/postscript) type=ps;; application/pdf) type=pdf;; image/vnd.djvu) type=djvu;; text/html) type=html;; text/plain) type=text;; application/msword) type=word;; application/vnd.openxmlformats-officedocument.* \ | application/vnd.ms-powerpoint \ | application/vnd.ms-excel \ | application/vnd.oasis.opendocument.*) type=uno;; image/svg+xml) type=svg;; image/png | image/jpeg) test -n "${dc-}" && type="image" || type="image2";; image/*) type=image;; application/x-dvi) type=dvi;; *) return 1;; esac return 0 } if test -z "$type"; then test -z "${mime-}" && \ mime=$(file -L --mime-type -b "$1" || die "$mime") || \ $(file -L --mime-type -bz "$1" || die "$mime") typeofmime "$mime" || die "unhandled file type: '$mime'" fi caspsuf=".pdf" case $type in ps) missing ps2pdf "ps2df(https://ghostscript.com/)" conv='ps2pdf - "$casp"' ;; image2|pdf) test -z "${dc-}" && exec llpp "$@" || conv='cat >"$casp"';; texi) missing texi2html "texi2html(http://www.nongnu.org/texi2html/)" conv='texi2html - -o $casp' caspsuf=.html ;; djvu) missing ddjvu "ddjvu(http://djvu.sourceforge.net/doc/man/ddjvu.html)" conv='ddjvu -format=pdf - "$casp"' ;; html) missing prince "Prince(http://www.princexml.com/)" conv='prince $css - -o "$casp"' ;; html2epub) missing pandoc "pandoc(http://pandoc.org)" caspsuf=".epub" conv='pandoc -r html - -w epub2 -o "$casp"' ;; word) missing unoconv "unoconv" filt= conv='unoconv -o "$casp" "$1"' ;; uno) test -n "$dc" && die "cannot convert compressed '$mime'" unset filt missing unoconv "unoconv(http://dag.wiee.rs/home-made/unoconv/)" conv='unoconv -o "$casp" "$1"' ;; svg) if executable_p inkscape && test -z "$dc"; then unset filt conv='inkscape -z -A "$casp" "$1"' else if executable_p rsvg-convert; then conv='rsvg-convert -f pdf -o "$casp"' else test -n "$dc" && die "cannot convert compressed '$mime'" unset filt missing unoconv "unoconv(http://dag.wiee.rs/home-made/unoconv/)" conv='unoconv -o "$casp" "$1"' fi fi ;; image) missing convert "convert(http://www.imagemagick.org/script/convert.php)" conv='convert - pdf:"$casp"' ;; dvi) test -n "$dc" && die "cannot convert compressed '$mime'" unset filt missing dvipdf "dvipdf(http://ghostscript.com/)" conv='dvipdf "$1" "$casp"' ;; text) missing pandoc "pandoc(http://pandoc.org/)" conv='pandoc -t epub2 - -o "$casp"' caspsuf=.epub ;; *) die "unhandled filter type: '$type'";; esac hash=$(cksum "$hashof") || die "$hash" casp=$cachedir/${hash%% *}$caspsuf { test -n "${force-}" || test ! -e "$casp"; } && eval "$filt" "$conv" shift exec llpp -origin $origin "$@" "$casp"