Safety nets
[llpp.git] / misc / llppac
blob8394eaf2730cc9c9fbd76cdbaaaab3717ee8b829
1 #!/bin/sh
2 set -e
4 die() {
5 echo "$1" >&2
6 exit 1
9 cachedir="${XDG_CACHE_HOME:-$HOME/.cache}/llpp"
10 test -d "$cachedir" || die "cache directory '$cachedir' does not exist"
12 caspsuf=
13 type=
15 executable_p() {
16 command -v "$1" >/dev/null 2>&1
19 missing() {
20 executable_p $1 || \
21 eval "$1() { die \"$1 is needed for \$type conversion\" ; }"
24 maketext() {
25 test -d "$cachedir/fonts" || mkdir "$cachedir/fonts"
26 cat >"$cachedir/fonts/text" <<EOF
27 Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
28 eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
29 minim veniam, quis nostrud exercitation ullamco laboris nisi ut
30 aliquip ex ea commodo consequat. Duis aute irure dolor in
31 reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
32 pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
33 culpa qui officia deserunt mollit anim id est laborum.
34 Posting Soccer Goals On Vine Is Illegal, Say England's Premier League
35 abcdefghizklmnopqrstwxyz
36 ABCDEFGHIZKLMNOPQRSTWXYZ
37 \`1234567890-=\\
38 ~!@#\$%^&*()_+|
39 [];',./
40 {}:"<>?
42 EOF
45 trap 'test -n "$casp" && rm -f "$casp"' 0
47 while getopts m:t:f opt; do
48 case $opt in
49 m) mime=$OPTARG;;
50 t) type=$OPTARG;;
51 f) force=1;;
52 ?) die "usage: $0 [-m mime/type] [-t filter] [-f] [path|url]";;
53 esac
54 done
55 shift $(($OPTIND - 1))
56 test -z "$1" && die "usage $0: path"
58 if test ! -e "$1" && expr >/dev/null "$1" : "\(ftp\|https\?\)://"; then
59 if executable_p wget; then
60 dl() {
61 wget -q -c -nc $1 -O $2
63 elif executable_p curl; then
64 dl() {
65 curl $1 -o $2
67 else
68 die "no program to fetch remote urls found"
71 md5of="$cachedir/$(basename "$1")"
72 dl "$1" "$md5of" || test -e "$md5of"
73 set -- "$md5of" ${2+"@"}
74 else
75 md5of="$1"
78 test -z "$type" && {
79 ft=$(file -L --mime-type -b "$1") || die "$ft"
82 case $ft in
83 application/x-gzip | application/x-compress) dc=zcat;;
84 application/x-xz) dc=xzcat;;
85 application/x-bzip2) dc=bzcat;;
86 *) unset dc || true;;
87 esac
89 filt='"${dc-cat}" "$1" |'
91 if test -z "$type"; then
92 test -z "$dc" || ft=$(file -L --mime-type -bz "$1") || die "$ft"
94 mime=${mime:-$ft}
95 case $mime in
96 application/postscript) type=ps;;
97 application/pdf) type=pdf;;
98 image/vnd.djvu) type=djvu;;
99 text/html) type=html;;
100 text/plain) type=text;;
101 application/msword) type=word;;
102 application/vnd.openxmlformats-officedocument.* \
103 | application/vnd.ms-powerpoint \
104 | application/vnd.ms-excel \
105 | application/vnd.oasis.opendocument.*) type=uno;;
106 image/svg+xml) type=svg;;
107 image/png | image/jpeg) test -n "$dc" && type="image" || type="image2";;
108 image/*) type=image;;
109 application/x-dvi) type=dvi;;
110 application/x-font-ttf | application/vnd.ms-opentype) type=font;;
111 *) die "unhandled file type: '$mime'";;
112 esac
115 case $type in
116 ps) conv='ps2pdf - "$casp"';;
117 image2|pdf) test -z "$dc" && exec llpp "$@" || conv='cat >"$casp"';;
118 djvu) conv='ddjvu -format=pdf - "$casp"';;
119 html) {
120 test -n "$dc" && die "cannot convert compressed '$mime'"
121 unset filt
122 missing prince "PrinceXML(http://www.princexml.com/)"
123 conv='prince "$1" -o "$casp"'
125 word) {
126 if executable_p unoconv && test -z "$dc"; then
127 unset filt
128 conv='unoconv -o "$casp" "$1"'
129 else
130 missing antiword "antiword or unoconv"
131 conv='antiword -m 8859-1.txt -a a4 - >"$casp"'
134 uno) {
135 test -n "$dc" && die "cannot convert compressed '$mime'"
136 unset filt
137 missing pandoc "unoconv(http://dag.wiee.rs/home-made/unoconv/)"
138 conv='unoconv -o "$casp" "$1"'
140 svg) {
141 missing rsvg-convert "rsvg-convert"
142 missing inkscape "inkscape(https://inkscape.org/en/)"
143 executable_p rsvg-convert \
144 && conv='rsvg-convert -f pdf -o "$casp"' \
145 || conv='inkscape -z -A "$casp" -'
147 font) {
148 if test -e "$2"; then
149 arg="$2"
150 else
151 arg="--waterfall $cachedir/fonts/text"
152 maketext
154 # https://mail.gnome.org/archives/gtk-i18n-list/2010-June/msg00000.html
155 eval $filt cat >$cachedir/fonts/font
156 cat >$cachedir/fonts/fonts.conf <<EOF
157 <?xml version="1.0"?>
158 <!DOCTYPE fontconfig SYSTEM "fonts.dtd">
159 <fontconfig>
160 <dir>$cachedir/fonts/</dir>
161 <cachedir>$cachedir/fonts/</cachedir>
162 <config></config>
163 </fontconfig>
165 unset filt
166 conv='FONTCONFIG_PATH=$cachedir/fonts/ pango-view -q $arg -o $casp'
167 caspsuf=.pdf
168 missing pango-view "pango-view(http://www.pango.org/)"
170 fcfont) {
171 if test -e "$2"; then
172 arg="$2"
173 else
174 arg="--waterfall $cachedir/fonts/text"
175 maketext
177 conv='pango-view --font="$1" -q $arg -o $casp'
178 caspsuf=.pdf
179 md5of=/dev/null
180 filt=
181 force=1
182 missing pango-view "pango-view(http://www.pango.org/)"
184 image) {
185 conv='convert - pdf:"$casp"'
186 missing convert "convert(http://www.imagemagick.org/script/convert.php)"
188 dvi) {
189 test -n "$dc" && die "cannot convert compressed '$mime'"
190 unset filt
191 conv='dvipdf "$1" "$casp"'
192 missing "dvipdf"
194 text) {
195 conv='pandoc -t epub - -o "$casp"'
196 caspsuf=.epub
197 missing "pandoc(http://pandoc.org/)"
199 *) die "unhandled filter type: '$type'";;
200 esac
202 hash=$(md5sum "$md5of") || die "$hash"
203 casp=$cachedir/${hash%% *}$caspsuf
204 (test -n "$force" -o ! -e "$casp") && eval "$filt" "$conv"
206 exec llpp -origin "$@" "$casp"