Do not trust unicorn optimizers
[llpp.git] / misc / llppac
blob5d05c497b07610c2540547aeaede72372e79f2c4
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() { command -v "$1" >/dev/null 2>&1; }
17 missing() {
18 executable_p $1 || \
19 eval "$1() { die \"$2 is needed for \$type conversion\"; }"
22 text() {
23 cat <<EOF
24 <pre style="font-size: ${1}pt;">
25 === $1 ===
26 EOF
27 test -n "$2" && cat $2 || cat <<EOF
28 S9 З3Ӡʒ Il1
30 ЁЖЗ
32 abcdefghijklmnopqrstwxyz
33 ABCDEFGHIJKLMNOPQRSTWXYZ
34 абвгдеёжзийклмнопрстуфхцчшщэюя
35 АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЭЮЯ
36 инпипнишпнипшнипнпншпнпинпипнпипщнпипипин
37 иннициатива шиорокошарикоподшипниковый взбзднуть гидроаэроионизация
38 телегаммааппарат фельдъегерь четырёхсотпятидесятисемимиллиметровое
39 превысокомногорассмотрительствующий вскользь забулдыжничество
40 цецецница
41 Σομε πσθδο γρεεκ
42 \`1234567890-=\\
43 ~!@#\$$%^&*()_+|
44 [];',./
45 {}:"&lt;&gt;?"
46 S in S9 59 S9 is like 5
47 final fjord flair ft
48 3ЗЭэзээз3ЗqgO0o ijklI1| bgqpykvwlliliiijil1 lLLl
49 01234567890 3ДС ЗДС ӠДС ʒДС
50 rnrmnnmrrrnmmr
51 Apay Арау
52 örök für
53 - - (~-) ~ ~ (-~)
54 curly vs plain braces {} () {} →
56 kerning
57 echo \${@:5}
58 life [l i fe]
59 lambdabot [l a mb]
60 Commutative [Co mm utative]
61 weird [we i rd]
62 Before [Bef ore, Be for e]
63 higher [gh, h i gher, hi gher]
64 multi [mu lti]
65 till [ti ll]
66 language [an]
67 plan [la]
68 when [wh]
69 kerning [rn | ng]
70 мне [мн е]
71 oiled [oi led]
72 mkfifo [mk f i fo, mk f i fo]
73 didn't [di dn't]
74 argumnet (sic) []
75 more [mo re]
76 CmmCall [CmmC a l l]
77 -Wvla [-Wv la]
78 align [a l i gn]
79 Compiling [Co mp iling]
80 print [pr int]
81 fcmono [f cmono]
82 Mail [M ail]
83 xsrc [x src]
84 Pokorna
85 buildglyphs.js [buil dg lyphs]
86 Dollar [Do ll ar]
87 signed [s i gned]
88 Pine [Pi ne]
89 right [r i ght]
90 ugliness
91 Nigeria [Ni g eria]
92 Nothing [Nothi ng]
93 modify [mo dify]
94 mplus [mp lus]
95 Apostolic [A postolic]
96 коде [к о де]
97 Прокофьевну [Пра ко фьевну]
98 Хэлп [X элп]
99 коснулся [ко снулся]
100 обьявляным [об ья вленым]
101 Queen [Qu een]
102 etymological [et ymologoical]
103 sigh [s i gh]
104 git [gi t]
105 некочевого [не ко чевого]
107 almost kerning
108 hope doesn't
109 Illegal
110 automatically effective
111 Ilium is the Latin for Ilion.
113 (from UTF8-demo.txt)
114 Box drawing alignment tests: █
116 ╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳
117 ║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳
118 ║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳
119 ╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳
120 ║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎
121 ║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏
122 ╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ ▗▄▖▛▀▜ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█
123 ▝▀▘▙▄▟
125 https://mirrors.zju.edu.cn/CTAN/fonts/gofonts/doc/gofonts.pdf (page 2)
127 DIN Legibility Standard
129 The recent German DIN 1450 legibility standard
130 recommends several features for font legibility, including
131 differentiation of letter shapes to reduce confusion. The Go fonts
132 conform to the 1450 standard by carefully differentiating zero from
133 capital O; numeral 1 from capital I (eye) and lowercase l (ell);
134 numeral 5 from capital S; and numeral 8 from capital B. The shapes of
135 bowls of b d p q follow the natural asymmetries of legible Renaissance
136 handwriting, aiding differentiation to reduce confusion. [5]
139 Mistaking S for a 5 (at certain sizes) is more of a problem... but... Ze Germans
141 (https://en.wikipedia.org/wiki/Jabberwocky
142 Idea from the aforementioned gofonts paper)
144 Бе сгладне и честлинните комбурси Það leið að stekju, og slýgir greðlar
145 търляха се и сврецваха във плите; sig snældu og böluðu um slöffruna,
146 съвсем окласни бяха тук щурпите og angurvært sungu sópfiðrungar
147 и отма равапсатваха прасурси. við sífgelt týðmana svíræna.
149 (https://en.wikipedia.org/wiki/Typeface)
151 For the rational mind, type design can be a maddening game
152 of drawing things differently in order to make them appear the
153 same.
154 </pre>
158 maketext() {
159 # https://github.com/react-boilerplate/react-boilerplate/issues/1340
160 test -d "$cachedir/fonts" || mkdir "$cachedir/fonts"
161 filename="$(basename "$1")"
162 textfilename="$2"
163 cat >"$cachedir/fonts/text.html" <<EOF
164 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
165 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
166 <html>
167 <head>
168 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
169 <title>$filename</title>
170 <style type="text/css">
171 @font-face { font-family: moo; src: url('$1'); }
172 pre { font-family: moo; }
173 </style>
174 </head>
175 $filename
176 <body>
178 for size in 6 8 10 12 4 2; do
179 text $size $textfilename >>"$cachedir/fonts/text.html"
180 done
181 cat >>"$cachedir/fonts/text.html" <<EOF
182 <br/>
183 $(fc-scan -f '%{fullname} %{style} %{slant} %{file} %{fontversion} %{capability} %{lang}' "$1" || file "$1")
184 </body>
185 </html>
189 trap 'test -n "$casp" && rm -f "$casp"' 0
191 while getopts s:c:m:t:fu opt; do
192 case $opt in
193 m) mime=$OPTARG;;
194 t) type=$OPTARG;;
195 f) force=true;;
196 c) css="-s $OPTARG";;
197 s) textfilename="$OPTARG";;
198 ?) die "usage: $0 [-c css] [-m mime/type] [-t filter] [-f] [-s textfile] [path|url]";;
199 esac
200 done
201 shift $(($OPTIND - 1))
202 test -z "$1" && die "usage $0: path"
204 origin="$1"
205 if ${force-test ! -e "$1"} && expr >/dev/null "$1" : "\(ftp\|https\?\)://"; then
206 if executable_p wget; then
207 dl() { wget -q $1 -O $2; }
208 elif executable_p curl; then
209 dl() { curl -L $1 -o $2; }
210 else
211 die "no program to fetch remote urls found"
214 hashof="$cachedir/$(basename "$1")"
215 dl "$1" "$hashof" || test -e "$md5of"
216 shift
217 set -- "$hashof" "$@"
218 else
219 hashof="$1"
222 test -z "$type" && { ft=$(file -L --mime-type -b "$1") || die "$ft"; }
224 case $ft in
225 application/x-gzip | application/x-compress) dc=zcat;;
226 application/x-xz) dc=xzcat;;
227 application/x-bzip2) dc=bzcat;;
228 *) unset dc || true;;
229 esac
231 filt='"${dc-cat}" "$1" |'
233 typeofmime() {
234 case "$1" in
235 application/postscript) type=ps;;
236 application/pdf) type=pdf;;
237 image/vnd.djvu) type=djvu;;
238 text/html) type=html;;
239 text/plain) type=text;;
240 application/msword) type=word;;
241 application/vnd.openxmlformats-officedocument.* \
242 | application/vnd.ms-powerpoint \
243 | application/vnd.ms-excel \
244 | application/vnd.oasis.opendocument.*) type=uno;;
245 image/svg+xml) type=svg;;
246 image/png | image/jpeg) test -n "$dc" && type="image" || type="image2";;
247 image/*) type=image;;
248 application/x-dvi) type=dvi;;
249 application/x-font-ttf \
250 | application/vnd.ms-opentype \
251 | application/font-sfnt) type=font;;
252 *) return 1;;
253 esac
254 return 0
257 if test -z "$type"; then
258 test -z "$mime" && \
259 mime=$(file -L --mime-type -b "$1" || die "$mime") || \
260 $(file -L --mime-type -bz "$1" || die "$mime")
261 typeofmime "$mime" || die "unhandled file type: '$mime'"
264 caspsuf=".pdf"
265 case $type in
266 ps) conv='ps2pdf - "$casp"';;
267 image2|pdf) test -z "$dc" && exec llpp "$@" || conv='cat >"$casp"';;
268 texi) {
269 missing texi2html "texi2html(http://www.nongnu.org/texi2html/)"
270 missing prince "PrinceXML(http://www.princexml.com/)"
271 conv='texi2html - -o - | prince $css - -o "$casp"'
273 djvu) {
274 missing ddjvu "ddjvu(http://djvu.sourceforge.net/doc/man/ddjvu.html)"
275 conv='ddjvu -format=pdf - "$casp"'
277 html) {
278 missing prince "Prince(http://www.princexml.com/)"
279 conv='prince $css - -o "$casp"'
281 html2epub) {
282 missing pandoc "pandoc(http://pandoc.org)"
283 caspsuf=".epub"
284 conv='pandoc -r html - -w epub2 -o "$casp"'
286 word) {
287 if executable_p unoconv && test -z "$dc"; then
288 unset filt
289 conv='unoconv -o "$casp" "$1"'
290 else
291 missing antiword "antiword or unoconv"
292 conv='antiword -m 8859-1.txt -a a4 - >"$casp"'
295 uno) {
296 test -n "$dc" && die "cannot convert compressed '$mime'"
297 unset filt
298 missing unoconv "unoconv(http://dag.wiee.rs/home-made/unoconv/)"
299 conv='unoconv -o "$casp" "$1"'
301 svg) {
302 if executable_p inkscape && test -z "$dc"; then
303 unset filt
304 conv='inkscape -z -A "$casp" "$1"'
305 else
306 missing rsvg-convert "rsvg-convert"
307 conv='rsvg-convert -f pdf -o "$casp"'
310 font) {
311 maketext "$1" "$textfilename"
312 exec llpp -origin $1 -layout-height 0 "$cachedir/fonts/text.html"
314 image) {
315 missing convert "convert(http://www.imagemagick.org/script/convert.php)"
316 conv='convert - pdf:"$casp"'
318 dvi) {
319 test -n "$dc" && die "cannot convert compressed '$mime'"
320 unset filt
321 missing dvipdf "dvipdf(http://ghostscript.com/)"
322 conv='dvipdf "$1" "$casp"'
324 text) {
325 missing pandoc "pandoc(http://pandoc.org/)"
326 conv='pandoc -t epub2 - -o "$casp"'
327 caspsuf=.epub
329 *) die "unhandled filter type: '$type'";;
330 esac
332 hash=$(cksum "$hashof") || die "$hash"
333 casp=$cachedir/${hash%% *}$caspsuf
335 { test -n "$force" || test ! -e "$casp"; } && eval "$filt" "$conv"
336 shift
338 exec llpp -origin $origin "$@" "$casp"