Ligation avoidance
[llpp.git] / misc / llppac
blob2dcfeb0a9f8d215ca567f865eb8349068d3455de
1 #!/bin/sh
2 set -e
4 font=$HOME/x/fnt/LastResort.ttf
5 ! test -r $font || export LLPP_FALLBACK_FONT=$font
7 die() {
8 echo "$1" >&2
9 exit 1
12 cachedir="${XDG_CACHE_HOME:-$HOME/.cache}/llpp"
13 test -d "$cachedir" || die "cache directory '$cachedir' does not exist"
15 caspsuf=
16 type=
18 executable_p() { command -v "$1" >/dev/null 2>&1; }
20 missing() {
21 executable_p $1 || \
22 eval "$1() { die \"$2 is needed for \$type conversion\"; }"
25 text() {
26 cat <<EOF
27 <pre style="font-size: ${1}pt;">
28 $1 <hr>
29 EOF
30 test -n "$2" && cat $2 || cat <<EOF
31 S9 З3Ӡʒ I|l1 O0 0O o0 0o
33 ЁЖЗ
35 abcdefghijklmnopqrstuvwxyz
36 ABCDEFGHIJKLMNOPQRSTUVWXYZ
37 абвгдеёжзийклмнопрстуфхцчшщэюя
38 АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЭЮЯ
39 инпипнишпнипшнипнпншпнпинпипнпипщнпипипин
40 иннициатива шиорокошарикоподшипниковый взбзднуть гидроаэроионизация
41 телегаммааппарат фельдъегерь четырёхсотпятидесятисемимиллиметровое
42 превысокомногорассмотрительствующий вскользь забулдыжничество
43 цецецница
44 https://ru.wikipedia.org/wiki/Панграмма https://en.wikipedia.org/wiki/Pangram
45 Экс-граф? Плюш изъят. Бьём чуждый цен хвощ!
46 Waltz, bad nymph, for quick jigs vex
47 ',.ფyfგcრლაოეუიდჰთნსყჯქxბმwვზ
48 Σομε πσθδο γρεεκ
49 Il1| Il|1 I1l| I1|l I|1l I|l1 lI1| lI|1 l1I| l1|I l|1I l|I1
50 1lI| 1l|I 1Il| 1I|l 1|Il 1|lI |l1I |lI1 |1lI |1Il |I1l |Il1
51 \`1234567890-=\\
52 ~!@#\$$%^&*()_+|
53 ₹₽£$€
54 [];',.//|/\ &gt;- -&gt; ~~&lt; &lt;-- --&gt; == === ==&gt; &lt;==
55 {}:"&lt;&gt;?"
56 S in S9 59 S9 is like 5 also 8B B8 BB 88B8 88B8
57 final fjord flair ft fff
58 3ЗЭэзээз3ЗqgO0o ijklI1| bgqpykvwlliliiijil1 lLLl
59 01234567890 3ДС ЗДС ӠДС ʒДС
60 rnrmnnmrrrnmmr <i>Nürnberg</i> (rn -> m)
61 Apay Арау
62 örök für A̋ a̋ ő ű https://en.wikipedia.org/wiki/Diacritic
63 молодо́й
64 - - (~-) ~ ~ (-~) - ~ ~ - - ~ ~ ''"''""., 1.65Mb
65 curly vs plain braces {} () {} ({ {( }) )} →
66 Bjarne Stroustrup (/ˈbjɑːrnə ˈstraʊstrʊp/; Danish: [ˈbjɑːnə ˈsdʁʌwˀsdʁɔb]
67 ○●🅼
68 😁 😂 😃 😅 😆 😇 😈 😉 😊 😋 😌 😍 😎 😏 😐 😑
69 😒 😓 😕 😗 😘 😙 😚 😛 😜 😞 😠 😡 😢 😥 😧 😨
70 😩 😪 😫 😬 😭 😮 😯 😰 😱 😲 😳 😵 😶 😸 😹 😻
71 😼 😽 😾 😿 🙀 🙁 🙂 🙃 🙄 🙆 🙇 🙉 🙊 🙌 🙍 🙎
72 🙏 1F600 😀 1F621 😤 😦 😖 😄 😔 🙅 🙈 🙋 1F620
73 1F627 😟 😴 😷 😺 1F609 1F60C 😝 😣 ✉ 📧
75 kerning
76 echo \${@:5}
77 life [l i fe]
78 lambdabot [l a mb]
79 Commutative [Co mm utative]
80 weird [we i rd]
81 Before [Bef ore, Be for e]
82 higher [gh, h i gher, hi gher]
83 multi [mu lti]
84 till [ti ll]
85 language [an]
86 plan [la]
87 when [wh]
88 kerning [rn | ng]
89 мне [мн е]
90 oiled [oi led]
91 mkfifo [mk f i fo, mk f i fo]
92 didn't [di dn't]
93 argumnet (sic) []
94 more [mo re]
95 CmmCall [CmmC a l l]
96 -Wvla [-Wv la]
97 align [a l i gn]
98 Compiling [Co mp iling]
99 print [pr int]
100 fcmono [f cmono]
101 Mail [M ail]
102 xsrc [x src]
103 Pokorna
104 buildglyphs.js [buil dg lyphs]
105 Dollar [Do ll ar]
106 signed [s i gned]
107 Pine [Pi ne]
108 right [r i ght]
109 ugliness
110 Nigeria [Ni g eria]
111 Nothing [Nothi ng]
112 modify [mo dify]
113 mplus [mp lus]
114 Apostolic [A postolic]
115 коде [к о де]
116 Прокофьевну [Про ко фьевну]
117 Хэлп [X элп]
118 коснулся [ко снулся]
119 обьявляным [об ья вленым]
120 Queen [Qu een]
121 etymological [et ymological]
122 sigh [s i gh]
123 git [gi t]
124 некочевого [не ко чевого]
125 Розовое [Ро зо вое]
126 Trump [Tru mp]
127 покрытие [по кр ытие]
128 Singapore [Si ng apore]
129 Georgy [Ge orgy]
130 with [wi th]
131 Yokozuna [Y okozuna]
132 подтверждение [под тверждение]
133 Xwayland [X wayland]
134 callable [ca l l ab le]
135 Noah [N oa h]
136 Los [L os]
137 refused [ref used]
138 Julia [J ulia | Jul i a]
139 Joe Armstrong [J oe (rip :()]
140 James [J ames]
141 CAPTCHA [CA PTCHA]
142 KIZER [KI ZER]
143 Kavanugh [K avaunaugh]
145 almost kerning
146 hope doesn't
147 Illegal
148 automatically effective
149 Ilium is the Latin for Ilion.
150 jtanx
152 (from UTF8-demo.txt)
153 Box drawing alignment tests: █
155 ╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳
156 ║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳
157 ║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳
158 ╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳
159 ║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎
160 ║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏
161 ╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ ▗▄▖▛▀▜ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█
162 ▝▀▘▙▄▟
164 https://mirrors.zju.edu.cn/CTAN/fonts/gofonts/doc/gofonts.pdf (page 2)
166 DIN Legibility Standard
168 The recent German DIN 1450 legibility standard
169 recommends several features for font legibility, including
170 differentiation of letter shapes to reduce confusion. The Go fonts
171 conform to the 1450 standard by carefully differentiating zero from
172 capital O; numeral 1 from capital I (eye) and lowercase l (ell);
173 numeral 5 from capital S; and numeral 8 from capital B. The shapes of
174 bowls of b d p q follow the natural asymmetries of legible Renaissance
175 handwriting, aiding differentiation to reduce confusion. [5]
178 (https://en.wikipedia.org/wiki/Jabberwocky
179 Idea from the aforementioned gofonts paper)
181 Бе сгладне и честлинните комбурси Það leið að stekju, og slýgir greðlar
182 търляха се и сврецваха във плите; sig snældu og böluðu um slöffruna,
183 съвсем окласни бяха тук щурпите og angurvært sungu sópfiðrungar
184 и отма равапсатваха прасурси. við sífgelt týðmana svíræna.
186 (https://en.wikipedia.org/wiki/Typeface)
188 For the rational mind, type design can be a maddening game
189 of drawing things differently in order to make them appear the
190 same.
191 </pre>
195 maketext() {
196 # https://github.com/react-boilerplate/react-boilerplate/issues/1340
197 test -d "$cachedir/fonts" || mkdir "$cachedir/fonts"
198 filename="$(basename "$1")"
199 textfilename="$2"
200 cat >"$cachedir/fonts/text.html" <<EOF
201 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
202 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
203 <html>
204 <head>
205 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
206 <title>$filename</title>
207 <style type="text/css">
208 @font-face { font-family: moo; src: url('$1'); }
209 pre { font-family: moo; }
210 </style>
211 </head>
212 $filename
213 <body>
215 for size in 6 8 10 12 4 2; do
216 text $size $textfilename >>"$cachedir/fonts/text.html"
217 done
218 cat >>"$cachedir/fonts/text.html" <<EOF
219 <br/>
220 $(fc-scan -f '%{fullname} %{style} %{slant} %{file} %{fontversion} %{capability} %{lang}' "$1" || file "$1")
221 </body>
222 </html>
226 trap 'test -n "$casp" && rm -f "$casp"' 0
228 while getopts s:c:m:t:fu opt; do
229 case $opt in
230 m) mime=$OPTARG;;
231 t) type=$OPTARG;;
232 f) force=true;;
233 c) css="-s $OPTARG";;
234 s) textfilename="$OPTARG";;
235 ?) die "usage: $0 [-c css] [-m mime/type] [-t filter] [-f] [-s textfile] [path|url]";;
236 esac
237 done
238 shift $(($OPTIND - 1))
239 test -z "$1" && die "usage $0: path"
241 origin="$1"
242 if ${force-test ! -e "$1"} && expr >/dev/null "$1" : "\(ftp\|https\?\)://"; then
243 if executable_p wget; then
244 dl() { wget -q $1 -O $2; }
245 elif executable_p curl; then
246 dl() { curl -L $1 -o $2; }
247 else
248 die "no program to fetch remote urls found"
251 hashof="$cachedir/$(basename "$1")"
252 dl "$1" "$hashof" || test -e "$md5of"
253 shift
254 set -- "$hashof" "$@"
255 else
256 hashof="$1"
259 test -z "$type" && { ft=$(file -L --mime-type -b "$1") || die "$ft"; }
261 case $ft in
262 application/x-gzip | application/x-compress) dc=zcat;;
263 application/x-xz) dc=xzcat;;
264 application/x-bzip2) dc=bzcat;;
265 *) unset dc || true;;
266 esac
268 filt='"${dc-cat}" "$1" |'
270 typeofmime() {
271 case "$1" in
272 application/postscript) type=ps;;
273 application/pdf) type=pdf;;
274 image/vnd.djvu) type=djvu;;
275 text/html) type=html;;
276 text/plain) type=text;;
277 application/msword) type=word;;
278 application/vnd.openxmlformats-officedocument.* \
279 | application/vnd.ms-powerpoint \
280 | application/vnd.ms-excel \
281 | application/vnd.oasis.opendocument.*) type=uno;;
282 image/svg+xml) type=svg;;
283 image/png | image/jpeg) test -n "$dc" && type="image" || type="image2";;
284 image/*) type=image;;
285 application/x-dvi) type=dvi;;
286 application/x-font-ttf \
287 | application/vnd.ms-opentype \
288 | application/font-sfnt) type=font;;
289 *) return 1;;
290 esac
291 return 0
294 if test -z "$type"; then
295 test -z "$mime" && \
296 mime=$(file -L --mime-type -b "$1" || die "$mime") || \
297 $(file -L --mime-type -bz "$1" || die "$mime")
298 typeofmime "$mime" || die "unhandled file type: '$mime'"
301 caspsuf=".pdf"
302 case $type in
303 ps) conv='ps2pdf - "$casp"';;
304 image2|pdf) test -z "$dc" && exec llpp "$@" || conv='cat >"$casp"';;
305 texi) {
306 missing texi2html "texi2html(http://www.nongnu.org/texi2html/)"
307 missing prince "PrinceXML(http://www.princexml.com/)"
308 conv='texi2html - -o - | prince $css - -o "$casp"'
310 djvu) {
311 missing ddjvu "ddjvu(http://djvu.sourceforge.net/doc/man/ddjvu.html)"
312 conv='ddjvu -format=pdf - "$casp"'
314 html) {
315 missing prince "Prince(http://www.princexml.com/)"
316 conv='prince $css - -o "$casp"'
318 html2epub) {
319 missing pandoc "pandoc(http://pandoc.org)"
320 caspsuf=".epub"
321 conv='pandoc -r html - -w epub2 -o "$casp"'
323 word) {
324 if executable_p unoconv && test -z "$dc"; then
325 unset filt
326 conv='unoconv -o "$casp" "$1"'
327 else
328 missing antiword "antiword or unoconv"
329 conv='antiword -m 8859-1.txt -a a4 - >"$casp"'
332 uno) {
333 test -n "$dc" && die "cannot convert compressed '$mime'"
334 unset filt
335 missing unoconv "unoconv(http://dag.wiee.rs/home-made/unoconv/)"
336 conv='unoconv -o "$casp" "$1"'
338 svg) {
339 if executable_p inkscape && test -z "$dc"; then
340 unset filt
341 conv='inkscape -z -A "$casp" "$1"'
342 else
343 if executable_p rsvg-convert; then
344 conv='rsvg-convert -f pdf -o "$casp"'
345 else
346 test -n "$dc" && die "cannot convert compressed '$mime'"
347 unset filt
348 missing unoconv "unoconv(http://dag.wiee.rs/home-made/unoconv/)"
349 conv='unoconv -o "$casp" "$1"'
353 font) {
354 maketext "$1" "$textfilename"
355 exec llpp -origin $1 -layout-height 0 "$cachedir/fonts/text.html"
357 image) {
358 missing convert "convert(http://www.imagemagick.org/script/convert.php)"
359 conv='convert - pdf:"$casp"'
361 dvi) {
362 test -n "$dc" && die "cannot convert compressed '$mime'"
363 unset filt
364 missing dvipdf "dvipdf(http://ghostscript.com/)"
365 conv='dvipdf "$1" "$casp"'
367 text) {
368 missing pandoc "pandoc(http://pandoc.org/)"
369 conv='pandoc -t epub2 - -o "$casp"'
370 caspsuf=.epub
372 *) die "unhandled filter type: '$type'";;
373 esac
375 hash=$(cksum "$hashof") || die "$hash"
376 casp=$cachedir/${hash%% *}$caspsuf
378 { test -n "$force" || test ! -e "$casp"; } && eval "$filt" "$conv"
379 shift
381 exec llpp -origin $origin "$@" "$casp"