Fix corner case
[llpp.git] / misc / llppac
blobcc844500d243e5925afa26d148afa240a9c0f183
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 \"$2 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 абвгдеёжзийклмнопрстуфхцчшщэюя
38 АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЭЮЯ
39 \`1234567890-=\\
40 ~!@#\$%^&*()_+|
41 [];',./
42 {}:"<>?"
44 EOF
47 trap 'test -n "$casp" && rm -f "$casp"' 0
49 while getopts m:t:f opt; do
50 case $opt in
51 m) mime=$OPTARG;;
52 t) type=$OPTARG;;
53 f) force=1;;
54 c) css="-s $OPTARG";;
55 ?) die "usage: $0 [-m mime/type] [-t filter] [-f] [path|url]";;
56 esac
57 done
58 shift $(($OPTIND - 1))
59 test -z "$1" && die "usage $0: path"
61 origin="$1"
62 if test ! -e "$1" && expr >/dev/null "$1" : "\(ftp\|https\?\)://"; then
63 if executable_p wget; then
64 dl() {
65 wget -q -c -nc $1 -O $2
67 elif executable_p curl; then
68 dl() {
69 curl $1 -o $2
71 else
72 die "no program to fetch remote urls found"
75 md5of="$cachedir/$(basename "$1")"
76 dl "$1" "$md5of" || test -e "$md5of"
77 shift
78 set -- "$md5of" "$@"
79 else
80 md5of="$1"
83 test -z "$type" && {
84 ft=$(file -L --mime-type -b "$1") || die "$ft"
87 case $ft in
88 application/x-gzip | application/x-compress) dc=zcat;;
89 application/x-xz) dc=xzcat;;
90 application/x-bzip2) dc=bzcat;;
91 *) unset dc || true;;
92 esac
94 filt='"${dc-cat}" "$1" |'
96 if test -z "$type"; then
97 test -z "$mime" && mime=$(file -L --mime-type -bz "$1" || die "$mime")
98 case $mime in
99 application/postscript) type=ps;;
100 application/pdf) type=pdf;;
101 image/vnd.djvu) type=djvu;;
102 text/html) type=html;;
103 text/plain) type=text;;
104 application/msword) type=word;;
105 application/vnd.openxmlformats-officedocument.* \
106 | application/vnd.ms-powerpoint \
107 | application/vnd.ms-excel \
108 | application/vnd.oasis.opendocument.*) type=uno;;
109 image/svg+xml) type=svg;;
110 image/png | image/jpeg) test -n "$dc" && type="image" || type="image2";;
111 image/*) type=image;;
112 application/x-dvi) type=dvi;;
113 application/x-font-ttf | application/vnd.ms-opentype) type=font;;
114 *) die "unhandled file type: '$mime'";;
115 esac
118 caspsuf=".pdf"
119 case $type in
120 ps) conv='ps2pdf - "$casp"';;
121 image2|pdf) test -z "$dc" && exec llpp "$@" || conv='cat >"$casp"';;
122 djvu) conv='ddjvu -format=pdf - "$casp"';;
123 html) {
124 missing prince "PrinceXML(http://www.princexml.com/)"
125 conv='prince $css - -o "$casp"'
127 html2epub) {
128 missing pandoc "pandoc(http://pandoc.org)"
129 caspsuf=".epub"
130 conv='pandoc -r html - -w epub -o "$casp"'
132 word) {
133 if executable_p unoconv && test -z "$dc"; then
134 unset filt
135 conv='unoconv -o "$casp" "$1"'
136 else
137 missing antiword "antiword or unoconv"
138 conv='antiword -m 8859-1.txt -a a4 - >"$casp"'
141 uno) {
142 test -n "$dc" && die "cannot convert compressed '$mime'"
143 unset filt
144 missing unoconv "unoconv(http://dag.wiee.rs/home-made/unoconv/)"
145 conv='unoconv -o "$casp" "$1"'
147 svg) {
148 if executable_p inkscape && test -z "$dc"; then
149 unset filt
150 conv='inkscape -z -A "$casp" "$1"'
151 else
152 missing rsvg-convert "rsvg-convert"
153 conv='rsvg-convert -f pdf -o "$casp"'
156 font) {
157 if test -e "$2"; then
158 arg="$2"
159 else
160 arg="--waterfall $cachedir/fonts/text"
161 maketext
163 # https://mail.gnome.org/archives/gtk-i18n-list/2010-June/msg00000.html
164 eval $filt cat >$cachedir/fonts/font
165 cat >$cachedir/fonts/fonts.conf <<EOF
166 <?xml version="1.0"?>
167 <!DOCTYPE fontconfig SYSTEM "fonts.dtd">
168 <fontconfig>
169 <dir>$cachedir/fonts/</dir>
170 <cachedir>$cachedir/fonts/</cachedir>
171 <config></config>
172 </fontconfig>
174 unset filt
175 missing pango-view "pango-view(http://www.pango.org/)"
176 conv='FONTCONFIG_PATH=$cachedir/fonts/ pango-view -q $arg -o $casp'
178 fcfont) {
179 if test -e "$2"; then
180 arg="$2"
181 else
182 arg="--waterfall $cachedir/fonts/text"
183 maketext
185 unset filt
186 missing pango-view "pango-view(http://www.pango.org/)"
187 conv='pango-view --font="$1" -q $arg -o $casp'
188 md5of=/dev/null
189 force=1
191 image) {
192 missing convert "convert(http://www.imagemagick.org/script/convert.php)"
193 conv='convert - pdf:"$casp"'
195 dvi) {
196 test -n "$dc" && die "cannot convert compressed '$mime'"
197 unset filt
198 missing dvipdf "dvipdf(http://ghostscript.com/)"
199 conv='dvipdf "$1" "$casp"'
201 text) {
202 missing pandoc "pandoc(http://pandoc.org/)"
203 conv='pandoc -t epub - -o "$casp"'
204 caspsuf=.epub
206 *) die "unhandled filter type: '$type'";;
207 esac
209 hash=$(md5sum "$md5of") || die "$hash"
210 casp=$cachedir/${hash%% *}$caspsuf
211 (test -n "$force" -o ! -e "$casp") && eval "$filt" "$conv"
212 shift
214 exec llpp -origin $origin "$@" "$casp"