lL
[llpp.git] / misc / llppac
blob99fa25e81f7c22ca5cb1141fa527e00183cf5ffe
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 # ibm plex mono = ~ S9 З3 align
26 # droid sans mono = ~ S9 З3
27 # input mono = S9 З3 -Wvla didn't
28 # fira mono = S9
29 # pt mono = ~ plan
30 # anonymous pro = life З3
31 # camingo code = S9
32 # roboto mono
33 # | anonymous pro = ЁЖЗ
34 # source code pro = S9
35 # tex gyre cursor = ~
36 # ubuntu mono = ~ S9 З3
37 # go mono = З3 align plan
38 # everson mono = З3 life 0 ~
39 # open sans = Ilium is the Latin for Ilion.
40 cat <<EOF
41 <pre style="font-size: ${1}pt;">
42 === $1 ===
43 S9 З3 align
45 ЁЖЗ
47 abcdefghizklmnopqrstwxyz
48 ABCDEFGHIZKLMNOPQRSTWXYZ
49 абвгдеёжзийклмнопрстуфхцчшщэюя
50 АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЭЮЯ
51 \`1234567890-=\\
52 ~!@#\$$%^&*()_+|
53 [];',./
54 {}:"&lt;&gt;?"
55 S in S9 59 S9 is like 5
56 3ЗЭэзээз3ЗqgO0o ijklI1| bgqpykvwlliliiijil1 lLLl
57 01234567890 3ДС ЗДС
58 rnrmnnmrrrnmmr
59 Apay Арау
60 - - (~-) ~ ~ (-~)
61 curly vs plain braces {} () {}
63 kerning
64 echo \${@:5}
65 life [l i fe]
66 weird [we i rd]
67 Before [Bef ore, Be for e]
68 higher [gh, h i gher, hi gher]
69 multi [mu lti]
70 language [an]
71 plan [la]
72 when [wh]
73 kerning [rn | ng]
74 мне [мн е]
75 oiled [oi led]
76 mkfifo [mk f i fo, mk f i fo]
77 didn't [di dn't]
78 argumnet (sic) []
79 more [mo re]
80 CmmCall [CmmC a l l]
81 -Wvla [-Wv la]
82 align [a l i gn]
83 Compiling [Co mp iling]
84 print [pr int]
85 fcmono [f cmono]
86 Mail [M ail]
87 xsrc [x src]
88 Pokorna
89 buildglyphs.js [buil dg lyphs]
90 Dollar [Do ll ar]
91 signed [s i gned]
93 almost kerning
94 hope doesn't
95 Illegal
96 automatically effective
97 Ilium is the Latin for Ilion.
99 (from UTF8-demo.txt)
100 Box drawing alignment tests: █
102 ╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳
103 ║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳
104 ║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳
105 ╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳
106 ║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎
107 ║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏
108 ╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ ▗▄▖▛▀▜ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█
109 ▝▀▘▙▄▟
110 </pre>
114 maketext() {
115 # https://github.com/react-boilerplate/react-boilerplate/issues/1340
116 test -d "$cachedir/fonts" || mkdir "$cachedir/fonts"
117 filename="$(basename "$1")"
118 cat >"$cachedir/fonts/text.html" <<EOF
119 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
120 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
121 <html>
122 <head>
123 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
124 <title>$filename</title>
125 <style type="text/css">
126 @font-face {
127 font-family: moo;
128 src: url('$1');
130 pre {
131 font-family: moo;
133 </style>
134 </head>
135 $filename
136 <body>
138 #for size in 8; do
139 for size in 6 8 10 12 4 2; do
140 text $size >>"$cachedir/fonts/text.html"
141 done;
142 cat >>"$cachedir/fonts/text.html" <<EOF
143 <br/>
144 $(fc-scan -f '%{fullname} %{style} %{slant} %{file} %{fontversion} %{capability} %{lang}' "$1" || file "$1")
145 </body>
146 </html>
150 trap 'test -n "$casp" && rm -f "$casp"' 0
152 while getopts c:m:t:fu opt; do
153 case $opt in
154 m) mime=$OPTARG;;
155 t) type=$OPTARG;;
156 f) force=true;;
157 c) css="-s $OPTARG";;
158 u) usemupdf=true;;
159 ?) die "usage: $0 [-c css] [-m mime/type] [-t filter] [-f] [path|url]";;
160 esac
161 done
162 shift $(($OPTIND - 1))
163 test -z "$1" && die "usage $0: path"
165 origin="$1"
166 if ${force-test ! -e "$1"} && expr >/dev/null "$1" : "\(ftp\|https\?\)://"; then
167 if executable_p wget; then
168 dl() {
169 wget -q $1 -O $2
171 elif executable_p curl; then
172 dl() {
173 curl $1 -o $2
175 else
176 die "no program to fetch remote urls found"
179 md5of="$cachedir/$(basename "$1")"
180 dl "$1" "$md5of" || test -e "$md5of"
181 shift
182 set -- "$md5of" "$@"
183 else
184 md5of="$1"
187 test -z "$type" && {
188 ft=$(file -L --mime-type -b "$1") || die "$ft"
191 case $ft in
192 application/x-gzip | application/x-compress) dc=zcat;;
193 application/x-xz) dc=xzcat;;
194 application/x-bzip2) dc=bzcat;;
195 *) unset dc || true;;
196 esac
198 filt='"${dc-cat}" "$1" |'
200 if test -z "$type"; then
201 test -z "$mime" && mime=$(file -L --mime-type -bz "$1" || die "$mime")
202 case $mime in
203 application/postscript) type=ps;;
204 application/pdf) type=pdf;;
205 image/vnd.djvu) type=djvu;;
206 text/html) type=html;;
207 text/plain) type=text;;
208 application/msword) type=word;;
209 application/vnd.openxmlformats-officedocument.* \
210 | application/vnd.ms-powerpoint \
211 | application/vnd.ms-excel \
212 | application/vnd.oasis.opendocument.*) type=uno;;
213 image/svg+xml) type=svg;;
214 image/png | image/jpeg) test -n "$dc" && type="image" || type="image2";;
215 image/*) type=image;;
216 application/x-dvi) type=dvi;;
217 application/x-font-ttf \
218 | application/vnd.ms-opentype \
219 | application/font-sfnt) type=font;;
220 *) die "unhandled file type: '$mime'";;
221 esac
224 caspsuf=".pdf"
225 case $type in
226 ps) conv='ps2pdf - "$casp"';;
227 image2|pdf) test -z "$dc" && exec llpp "$@" || conv='cat >"$casp"';;
228 texi) {
229 missing texi2html "texi2html(http://www.nongnu.org/texi2html/)"
230 missing prince "PrinceXML(http://www.princexml.com/)"
231 conv='texi2html - -o - | prince $css - -o "$casp"'
233 djvu) {
234 missing ddjvu "ddjvu(http://djvu.sourceforge.net/doc/man/ddjvu.html)"
235 conv='ddjvu -format=pdf - "$casp"'
237 html) {
238 missing prince "PrinceXML(http://www.princexml.com/)"
239 conv='prince $css - -o "$casp"'
241 html2epub) {
242 missing pandoc "pandoc(http://pandoc.org)"
243 caspsuf=".epub"
244 conv='pandoc -r html - -w epub -o "$casp"'
246 word) {
247 if executable_p unoconv && test -z "$dc"; then
248 unset filt
249 conv='unoconv -o "$casp" "$1"'
250 else
251 missing antiword "antiword or unoconv"
252 conv='antiword -m 8859-1.txt -a a4 - >"$casp"'
255 uno) {
256 test -n "$dc" && die "cannot convert compressed '$mime'"
257 unset filt
258 missing unoconv "unoconv(http://dag.wiee.rs/home-made/unoconv/)"
259 conv='unoconv -o "$casp" "$1"'
261 svg) {
262 if executable_p inkscape && test -z "$dc"; then
263 unset filt
264 conv='inkscape -z -A "$casp" "$1"'
265 else
266 missing rsvg-convert "rsvg-convert"
267 conv='rsvg-convert -f pdf -o "$casp"'
270 font) {
271 if test -z $usemupdf; then
272 v="llpp -origin $1"
273 else
274 mupdf=$HOME/x/rcs/git/mupdf/build/native/mupdf-gl
275 executable_p $mupdf || v=mupdf-gl && v=$mupdf
277 maketext "$1"
278 exec $v "$cachedir/fonts/text.html"
280 image) {
281 missing convert "convert(http://www.imagemagick.org/script/convert.php)"
282 conv='convert - pdf:"$casp"'
284 dvi) {
285 test -n "$dc" && die "cannot convert compressed '$mime'"
286 unset filt
287 missing dvipdf "dvipdf(http://ghostscript.com/)"
288 conv='dvipdf "$1" "$casp"'
290 text) {
291 missing pandoc "pandoc(http://pandoc.org/)"
292 conv='pandoc -t epub - -o "$casp"'
293 caspsuf=.epub
295 *) die "unhandled filter type: '$type'";;
296 esac
298 hash=$(md5sum "$md5of") || die "$hash"
299 casp=$cachedir/${hash%% *}$caspsuf
301 { test -n "$force" || test ! -e "$casp"; } && eval "$filt" "$conv"
302 shift
304 exec llpp -origin $origin "$@" "$casp"