f Ligatures
[llpp.git] / misc / llppac
blob2617fcc5e061840adfcdc8b04d6516d8608c86b0
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 final fjord flair ft
57 3ЗЭэзээз3ЗqgO0o ijklI1| bgqpykvwlliliiijil1 lLLl
58 01234567890 3ДС ЗДС
59 rnrmnnmrrrnmmr
60 Apay Арау
61 - - (~-) ~ ~ (-~)
62 curly vs plain braces {} () {}
64 kerning
65 echo \${@:5}
66 life [l i fe]
67 weird [we i rd]
68 Before [Bef ore, Be for e]
69 higher [gh, h i gher, hi gher]
70 multi [mu lti]
71 language [an]
72 plan [la]
73 when [wh]
74 kerning [rn | ng]
75 мне [мн е]
76 oiled [oi led]
77 mkfifo [mk f i fo, mk f i fo]
78 didn't [di dn't]
79 argumnet (sic) []
80 more [mo re]
81 CmmCall [CmmC a l l]
82 -Wvla [-Wv la]
83 align [a l i gn]
84 Compiling [Co mp iling]
85 print [pr int]
86 fcmono [f cmono]
87 Mail [M ail]
88 xsrc [x src]
89 Pokorna
90 buildglyphs.js [buil dg lyphs]
91 Dollar [Do ll ar]
92 signed [s i gned]
94 almost kerning
95 hope doesn't
96 Illegal
97 automatically effective
98 Ilium is the Latin for Ilion.
100 (from UTF8-demo.txt)
101 Box drawing alignment tests: █
103 ╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳
104 ║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳
105 ║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳
106 ╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳
107 ║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎
108 ║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏
109 ╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ ▗▄▖▛▀▜ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█
110 ▝▀▘▙▄▟
111 </pre>
115 maketext() {
116 # https://github.com/react-boilerplate/react-boilerplate/issues/1340
117 test -d "$cachedir/fonts" || mkdir "$cachedir/fonts"
118 filename="$(basename "$1")"
119 cat >"$cachedir/fonts/text.html" <<EOF
120 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
121 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
122 <html>
123 <head>
124 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
125 <title>$filename</title>
126 <style type="text/css">
127 @font-face {
128 font-family: moo;
129 src: url('$1');
131 pre {
132 font-family: moo;
134 </style>
135 </head>
136 $filename
137 <body>
139 #for size in 8; do
140 for size in 6 8 10 12 4 2; do
141 text $size >>"$cachedir/fonts/text.html"
142 done;
143 cat >>"$cachedir/fonts/text.html" <<EOF
144 <br/>
145 $(fc-scan -f '%{fullname} %{style} %{slant} %{file} %{fontversion} %{capability} %{lang}' "$1" || file "$1")
146 </body>
147 </html>
151 trap 'test -n "$casp" && rm -f "$casp"' 0
153 while getopts c:m:t:fu opt; do
154 case $opt in
155 m) mime=$OPTARG;;
156 t) type=$OPTARG;;
157 f) force=true;;
158 c) css="-s $OPTARG";;
159 u) usemupdf=true;;
160 ?) die "usage: $0 [-c css] [-m mime/type] [-t filter] [-f] [path|url]";;
161 esac
162 done
163 shift $(($OPTIND - 1))
164 test -z "$1" && die "usage $0: path"
166 origin="$1"
167 if ${force-test ! -e "$1"} && expr >/dev/null "$1" : "\(ftp\|https\?\)://"; then
168 if executable_p wget; then
169 dl() {
170 wget -q $1 -O $2
172 elif executable_p curl; then
173 dl() {
174 curl $1 -o $2
176 else
177 die "no program to fetch remote urls found"
180 md5of="$cachedir/$(basename "$1")"
181 dl "$1" "$md5of" || test -e "$md5of"
182 shift
183 set -- "$md5of" "$@"
184 else
185 md5of="$1"
188 test -z "$type" && {
189 ft=$(file -L --mime-type -b "$1") || die "$ft"
192 case $ft in
193 application/x-gzip | application/x-compress) dc=zcat;;
194 application/x-xz) dc=xzcat;;
195 application/x-bzip2) dc=bzcat;;
196 *) unset dc || true;;
197 esac
199 filt='"${dc-cat}" "$1" |'
201 if test -z "$type"; then
202 test -z "$mime" && mime=$(file -L --mime-type -bz "$1" || die "$mime")
203 case $mime in
204 application/postscript) type=ps;;
205 application/pdf) type=pdf;;
206 image/vnd.djvu) type=djvu;;
207 text/html) type=html;;
208 text/plain) type=text;;
209 application/msword) type=word;;
210 application/vnd.openxmlformats-officedocument.* \
211 | application/vnd.ms-powerpoint \
212 | application/vnd.ms-excel \
213 | application/vnd.oasis.opendocument.*) type=uno;;
214 image/svg+xml) type=svg;;
215 image/png | image/jpeg) test -n "$dc" && type="image" || type="image2";;
216 image/*) type=image;;
217 application/x-dvi) type=dvi;;
218 application/x-font-ttf \
219 | application/vnd.ms-opentype \
220 | application/font-sfnt) type=font;;
221 *) die "unhandled file type: '$mime'";;
222 esac
225 caspsuf=".pdf"
226 case $type in
227 ps) conv='ps2pdf - "$casp"';;
228 image2|pdf) test -z "$dc" && exec llpp "$@" || conv='cat >"$casp"';;
229 texi) {
230 missing texi2html "texi2html(http://www.nongnu.org/texi2html/)"
231 missing prince "PrinceXML(http://www.princexml.com/)"
232 conv='texi2html - -o - | prince $css - -o "$casp"'
234 djvu) {
235 missing ddjvu "ddjvu(http://djvu.sourceforge.net/doc/man/ddjvu.html)"
236 conv='ddjvu -format=pdf - "$casp"'
238 html) {
239 missing prince "PrinceXML(http://www.princexml.com/)"
240 conv='prince $css - -o "$casp"'
242 html2epub) {
243 missing pandoc "pandoc(http://pandoc.org)"
244 caspsuf=".epub"
245 conv='pandoc -r html - -w epub -o "$casp"'
247 word) {
248 if executable_p unoconv && test -z "$dc"; then
249 unset filt
250 conv='unoconv -o "$casp" "$1"'
251 else
252 missing antiword "antiword or unoconv"
253 conv='antiword -m 8859-1.txt -a a4 - >"$casp"'
256 uno) {
257 test -n "$dc" && die "cannot convert compressed '$mime'"
258 unset filt
259 missing unoconv "unoconv(http://dag.wiee.rs/home-made/unoconv/)"
260 conv='unoconv -o "$casp" "$1"'
262 svg) {
263 if executable_p inkscape && test -z "$dc"; then
264 unset filt
265 conv='inkscape -z -A "$casp" "$1"'
266 else
267 missing rsvg-convert "rsvg-convert"
268 conv='rsvg-convert -f pdf -o "$casp"'
271 font) {
272 if test -z $usemupdf; then
273 v="llpp -origin $1"
274 else
275 mupdf=$HOME/x/rcs/git/mupdf/build/native/mupdf-gl
276 executable_p $mupdf || v=mupdf-gl && v=$mupdf
278 maketext "$1"
279 exec $v "$cachedir/fonts/text.html"
281 image) {
282 missing convert "convert(http://www.imagemagick.org/script/convert.php)"
283 conv='convert - pdf:"$casp"'
285 dvi) {
286 test -n "$dc" && die "cannot convert compressed '$mime'"
287 unset filt
288 missing dvipdf "dvipdf(http://ghostscript.com/)"
289 conv='dvipdf "$1" "$casp"'
291 text) {
292 missing pandoc "pandoc(http://pandoc.org/)"
293 conv='pandoc -t epub - -o "$casp"'
294 caspsuf=.epub
296 *) die "unhandled filter type: '$type'";;
297 esac
299 hash=$(md5sum "$md5of") || die "$hash"
300 casp=$cachedir/${hash%% *}$caspsuf
302 { test -n "$force" || test ! -e "$casp"; } && eval "$filt" "$conv"
303 shift
305 exec llpp -origin $origin "$@" "$casp"