S9
[llpp.git] / misc / llppac
blob1a464fc1644922962d90bcdbdbb24143ed5deb16
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 text() {
25 cat <<EOF
26 <pre style="font-size: ${1}pt;">
27 === $1 ===
28 Lorem ipsum dolor sit amet, consectetur...datat non proident, sunt in
29 culpa qui officia deserunt mollit anim id est laborum.
30 Posting Soccer Goals On Vine Is Illegal, Say England's Premier League
31 abcdefghizklmnopqrstwxyz
32 ABCDEFGHIZKLMNOPQRSTWXYZ
33 абвгдеёжзийклмнопрстуфхцчшщэюя
34 АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЭЮЯ
35 \`1234567890-=\\
36 ~!@#\$$%^&*()_+|
37 [];',./
38 {}:"&lt;&gt;?"
39 S in S9 59 S9 is like 5
40 3ЗЭэзээз3ЗqgO0o ijklI1| bgqpykvwlliliiijil1
41 Ре́ҙю̈мȩ̊́́́
42 01234567890 3ДС ЗДС
43 - - (~-) ~ ~ (-~)
44 curly vs plain braces {} () {}
46 echo \${@:5}
47 life [l i fe]
48 weird [we i rd]
49 Before [Bef ore, Be for e]
50 higher [gh]
51 multi [mu lti]
52 languge [an]
53 when [wh]
54 kerning [rn]
55 мне [мн е]
56 oiled [oi led]
57 mkfifo [mk f i fo, mk f i fo]
58 didn't [di dn't]
59 </pre>
60 EOF
63 maketext() {
64 # https://github.com/react-boilerplate/react-boilerplate/issues/1340
65 test -d "$cachedir/fonts" || mkdir "$cachedir/fonts"
66 cat >"$cachedir/fonts/text.html" <<EOF
67 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
68 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
69 <html>
70 <head>
71 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
72 <style type="text/css">
73 @font-face {
74 font-family: 'moo';
75 src: url('$1');
77 pre {
78 font-family: "moo";
80 </style>
81 <title>test</title>
82 </head>
84 <body>
85 EOF
86 for size in 6 8 10 12 4 2; do
87 text $size >>"$cachedir/fonts/text.html"
88 done;
89 cat >>"$cachedir/fonts/text.html" <<EOF
90 </body>
91 </html>
92 EOF
95 trap 'test -n "$casp" && rm -f "$casp"' 0
97 while getopts c:m:t:f opt; do
98 case $opt in
99 m) mime=$OPTARG;;
100 t) type=$OPTARG;;
101 f) force=true;;
102 c) css="-s $OPTARG";;
103 ?) die "usage: $0 [-c css] [-m mime/type] [-t filter] [-f] [path|url]";;
104 esac
105 done
106 shift $(($OPTIND - 1))
107 test -z "$1" && die "usage $0: path"
109 origin="$1"
110 if ${force-test ! -e "$1"} && expr >/dev/null "$1" : "\(ftp\|https\?\)://"; then
111 if executable_p wget; then
112 dl() {
113 wget -q $1 -O $2
115 elif executable_p curl; then
116 dl() {
117 curl $1 -o $2
119 else
120 die "no program to fetch remote urls found"
123 md5of="$cachedir/$(basename "$1")"
124 dl "$1" "$md5of" || test -e "$md5of"
125 shift
126 set -- "$md5of" "$@"
127 else
128 md5of="$1"
131 test -z "$type" && {
132 ft=$(file -L --mime-type -b "$1") || die "$ft"
135 case $ft in
136 application/x-gzip | application/x-compress) dc=zcat;;
137 application/x-xz) dc=xzcat;;
138 application/x-bzip2) dc=bzcat;;
139 *) unset dc || true;;
140 esac
142 filt='"${dc-cat}" "$1" |'
144 if test -z "$type"; then
145 test -z "$mime" && mime=$(file -L --mime-type -bz "$1" || die "$mime")
146 case $mime in
147 application/postscript) type=ps;;
148 application/pdf) type=pdf;;
149 image/vnd.djvu) type=djvu;;
150 text/html) type=html;;
151 text/plain) type=text;;
152 application/msword) type=word;;
153 application/vnd.openxmlformats-officedocument.* \
154 | application/vnd.ms-powerpoint \
155 | application/vnd.ms-excel \
156 | application/vnd.oasis.opendocument.*) type=uno;;
157 image/svg+xml) type=svg;;
158 image/png | image/jpeg) test -n "$dc" && type="image" || type="image2";;
159 image/*) type=image;;
160 application/x-dvi) type=dvi;;
161 application/x-font-ttf \
162 | application/vnd.ms-opentype \
163 | application/font-sfnt) type=font;;
164 *) die "unhandled file type: '$mime'";;
165 esac
168 caspsuf=".pdf"
169 case $type in
170 ps) conv='ps2pdf - "$casp"';;
171 image2|pdf) test -z "$dc" && exec llpp "$@" || conv='cat >"$casp"';;
172 texi) {
173 missing texi2html "texi2html(http://www.nongnu.org/texi2html/)"
174 missing prince "PrinceXML(http://www.princexml.com/)"
175 conv='texi2html - -o - | prince $css - -o "$casp"'
177 djvu) {
178 missing ddjvu "ddjvu(http://djvu.sourceforge.net/doc/man/ddjvu.html)"
179 conv='ddjvu -format=pdf - "$casp"'
181 html) {
182 missing prince "PrinceXML(http://www.princexml.com/)"
183 conv='prince $css - -o "$casp"'
185 html2epub) {
186 missing pandoc "pandoc(http://pandoc.org)"
187 caspsuf=".epub"
188 conv='pandoc -r html - -w epub -o "$casp"'
190 word) {
191 if executable_p unoconv && test -z "$dc"; then
192 unset filt
193 conv='unoconv -o "$casp" "$1"'
194 else
195 missing antiword "antiword or unoconv"
196 conv='antiword -m 8859-1.txt -a a4 - >"$casp"'
199 uno) {
200 test -n "$dc" && die "cannot convert compressed '$mime'"
201 unset filt
202 missing unoconv "unoconv(http://dag.wiee.rs/home-made/unoconv/)"
203 conv='unoconv -o "$casp" "$1"'
205 svg) {
206 if executable_p inkscape && test -z "$dc"; then
207 unset filt
208 conv='inkscape -z -A "$casp" "$1"'
209 else
210 missing rsvg-convert "rsvg-convert"
211 conv='rsvg-convert -f pdf -o "$casp"'
214 font) {
215 maketext "$1"
216 exec llpp "$cachedir/fonts/text.html"
218 image) {
219 missing convert "convert(http://www.imagemagick.org/script/convert.php)"
220 conv='convert - pdf:"$casp"'
222 dvi) {
223 test -n "$dc" && die "cannot convert compressed '$mime'"
224 unset filt
225 missing dvipdf "dvipdf(http://ghostscript.com/)"
226 conv='dvipdf "$1" "$casp"'
228 text) {
229 missing pandoc "pandoc(http://pandoc.org/)"
230 conv='pandoc -t epub - -o "$casp"'
231 caspsuf=.epub
233 *) die "unhandled filter type: '$type'";;
234 esac
236 hash=$(md5sum "$md5of") || die "$hash"
237 casp=$cachedir/${hash%% *}$caspsuf
239 { test -n "$force" || test ! -e "$casp"; } && eval "$filt" "$conv"
240 shift
242 exec llpp -origin $origin "$@" "$casp"