Order of S5 is not too important
[llpp.git] / misc / llppac
blob4f12a300a2bd145a2501f4506586133e1d1508dd
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 ',.ფyfგcრლაოეუიდჰთნსყჯქxბმwვზ
45 Σομε πσθδο γρεεκ
46 Il1| Il|1 I1l| I1|l I|1l I|l1 lI1| lI|1 l1I| l1|I l|1I l|I1
47 1lI| 1l|I 1Il| 1I|l 1|Il 1|lI |l1I |lI1 |1lI |1Il |I1l |Il1
48 \`1234567890-=\\
49 ~!@#\$$%^&*()_+|
50 [];',./ &gt;- -&gt; ~~&lt; &lt;-- --&gt; == === ==&gt; &lt;==
51 {}:"&lt;&gt;?"
52 S in S9 59 S9 is like 5
53 final fjord flair ft
54 3ЗЭэзээз3ЗqgO0o ijklI1| bgqpykvwlliliiijil1 lLLl
55 01234567890 3ДС ЗДС ӠДС ʒДС
56 rnrmnnmrrrnmmr <i>Nürnberg</i> (rn -> m)
57 Apay Арау
58 örök für A̋ a̋ ő ű https://en.wikipedia.org/wiki/Diacritic
59 молодо́й
60 - - (~-) ~ ~ (-~)
61 curly vs plain braces {} () {} ({ {( }) )} →
62 Bjarne Stroustrup (/ˈbjɑːrnə ˈstraʊstrʊp/; Danish: [ˈbjɑːnə ˈsdʁʌwˀsdʁɔb]
63 ○●🅼
65 kerning
66 echo \${@:5}
67 life [l i fe]
68 lambdabot [l a mb]
69 Commutative [Co mm utative]
70 weird [we i rd]
71 Before [Bef ore, Be for e]
72 higher [gh, h i gher, hi gher]
73 multi [mu lti]
74 till [ti ll]
75 language [an]
76 plan [la]
77 when [wh]
78 kerning [rn | ng]
79 мне [мн е]
80 oiled [oi led]
81 mkfifo [mk f i fo, mk f i fo]
82 didn't [di dn't]
83 argumnet (sic) []
84 more [mo re]
85 CmmCall [CmmC a l l]
86 -Wvla [-Wv la]
87 align [a l i gn]
88 Compiling [Co mp iling]
89 print [pr int]
90 fcmono [f cmono]
91 Mail [M ail]
92 xsrc [x src]
93 Pokorna
94 buildglyphs.js [buil dg lyphs]
95 Dollar [Do ll ar]
96 signed [s i gned]
97 Pine [Pi ne]
98 right [r i ght]
99 ugliness
100 Nigeria [Ni g eria]
101 Nothing [Nothi ng]
102 modify [mo dify]
103 mplus [mp lus]
104 Apostolic [A postolic]
105 коде [к о де]
106 Прокофьевну [Про ко фьевну]
107 Хэлп [X элп]
108 коснулся [ко снулся]
109 обьявляным [об ья вленым]
110 Queen [Qu een]
111 etymological [et ymologoical]
112 sigh [s i gh]
113 git [gi t]
114 некочевого [не ко чевого]
115 Розовое [Ро зо вое]
116 Trump [Tru mp]
117 покрытие [по кр ытие]
118 Julia [J ulia | Jul i a]
119 Singapore [Si ng apore]
120 Georgy [Ge orgy]
121 with [wi th]
122 Joe Armstrong [J oe (rip :()]
123 Yokozuna [Y okozuna]
124 подтверждение [под тверждение]
125 Xwayland [X wayland]
126 callable [ca l l ab le]
127 Noah [N oa h]
128 Los [L os]
129 refused [ref used]
130 James [J ames]
132 almost kerning
133 hope doesn't
134 Illegal
135 automatically effective
136 Ilium is the Latin for Ilion.
137 jtanx
139 (from UTF8-demo.txt)
140 Box drawing alignment tests: █
142 ╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳
143 ║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳
144 ║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳
145 ╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳
146 ║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎
147 ║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏
148 ╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ ▗▄▖▛▀▜ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█
149 ▝▀▘▙▄▟
151 https://mirrors.zju.edu.cn/CTAN/fonts/gofonts/doc/gofonts.pdf (page 2)
153 DIN Legibility Standard
155 The recent German DIN 1450 legibility standard
156 recommends several features for font legibility, including
157 differentiation of letter shapes to reduce confusion. The Go fonts
158 conform to the 1450 standard by carefully differentiating zero from
159 capital O; numeral 1 from capital I (eye) and lowercase l (ell);
160 numeral 5 from capital S; and numeral 8 from capital B. The shapes of
161 bowls of b d p q follow the natural asymmetries of legible Renaissance
162 handwriting, aiding differentiation to reduce confusion. [5]
165 (https://en.wikipedia.org/wiki/Jabberwocky
166 Idea from the aforementioned gofonts paper)
168 Бе сгладне и честлинните комбурси Það leið að stekju, og slýgir greðlar
169 търляха се и сврецваха във плите; sig snældu og böluðu um slöffruna,
170 съвсем окласни бяха тук щурпите og angurvært sungu sópfiðrungar
171 и отма равапсатваха прасурси. við sífgelt týðmana svíræna.
173 (https://en.wikipedia.org/wiki/Typeface)
175 For the rational mind, type design can be a maddening game
176 of drawing things differently in order to make them appear the
177 same.
178 </pre>
182 maketext() {
183 # https://github.com/react-boilerplate/react-boilerplate/issues/1340
184 test -d "$cachedir/fonts" || mkdir "$cachedir/fonts"
185 filename="$(basename "$1")"
186 textfilename="$2"
187 cat >"$cachedir/fonts/text.html" <<EOF
188 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
189 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
190 <html>
191 <head>
192 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
193 <title>$filename</title>
194 <style type="text/css">
195 @font-face { font-family: moo; src: url('$1'); }
196 pre { font-family: moo; }
197 </style>
198 </head>
199 $filename
200 <body>
202 for size in 6 8 10 12 4 2; do
203 text $size $textfilename >>"$cachedir/fonts/text.html"
204 done
205 cat >>"$cachedir/fonts/text.html" <<EOF
206 <br/>
207 $(fc-scan -f '%{fullname} %{style} %{slant} %{file} %{fontversion} %{capability} %{lang}' "$1" || file "$1")
208 </body>
209 </html>
213 trap 'test -n "$casp" && rm -f "$casp"' 0
215 while getopts s:c:m:t:fu opt; do
216 case $opt in
217 m) mime=$OPTARG;;
218 t) type=$OPTARG;;
219 f) force=true;;
220 c) css="-s $OPTARG";;
221 s) textfilename="$OPTARG";;
222 ?) die "usage: $0 [-c css] [-m mime/type] [-t filter] [-f] [-s textfile] [path|url]";;
223 esac
224 done
225 shift $(($OPTIND - 1))
226 test -z "$1" && die "usage $0: path"
228 origin="$1"
229 if ${force-test ! -e "$1"} && expr >/dev/null "$1" : "\(ftp\|https\?\)://"; then
230 if executable_p wget; then
231 dl() { wget -q $1 -O $2; }
232 elif executable_p curl; then
233 dl() { curl -L $1 -o $2; }
234 else
235 die "no program to fetch remote urls found"
238 hashof="$cachedir/$(basename "$1")"
239 dl "$1" "$hashof" || test -e "$md5of"
240 shift
241 set -- "$hashof" "$@"
242 else
243 hashof="$1"
246 test -z "$type" && { ft=$(file -L --mime-type -b "$1") || die "$ft"; }
248 case $ft in
249 application/x-gzip | application/x-compress) dc=zcat;;
250 application/x-xz) dc=xzcat;;
251 application/x-bzip2) dc=bzcat;;
252 *) unset dc || true;;
253 esac
255 filt='"${dc-cat}" "$1" |'
257 typeofmime() {
258 case "$1" in
259 application/postscript) type=ps;;
260 application/pdf) type=pdf;;
261 image/vnd.djvu) type=djvu;;
262 text/html) type=html;;
263 text/plain) type=text;;
264 application/msword) type=word;;
265 application/vnd.openxmlformats-officedocument.* \
266 | application/vnd.ms-powerpoint \
267 | application/vnd.ms-excel \
268 | application/vnd.oasis.opendocument.*) type=uno;;
269 image/svg+xml) type=svg;;
270 image/png | image/jpeg) test -n "$dc" && type="image" || type="image2";;
271 image/*) type=image;;
272 application/x-dvi) type=dvi;;
273 application/x-font-ttf \
274 | application/vnd.ms-opentype \
275 | application/font-sfnt) type=font;;
276 *) return 1;;
277 esac
278 return 0
281 if test -z "$type"; then
282 test -z "$mime" && \
283 mime=$(file -L --mime-type -b "$1" || die "$mime") || \
284 $(file -L --mime-type -bz "$1" || die "$mime")
285 typeofmime "$mime" || die "unhandled file type: '$mime'"
288 caspsuf=".pdf"
289 case $type in
290 ps) conv='ps2pdf - "$casp"';;
291 image2|pdf) test -z "$dc" && exec llpp "$@" || conv='cat >"$casp"';;
292 texi) {
293 missing texi2html "texi2html(http://www.nongnu.org/texi2html/)"
294 missing prince "PrinceXML(http://www.princexml.com/)"
295 conv='texi2html - -o - | prince $css - -o "$casp"'
297 djvu) {
298 missing ddjvu "ddjvu(http://djvu.sourceforge.net/doc/man/ddjvu.html)"
299 conv='ddjvu -format=pdf - "$casp"'
301 html) {
302 missing prince "Prince(http://www.princexml.com/)"
303 conv='prince $css - -o "$casp"'
305 html2epub) {
306 missing pandoc "pandoc(http://pandoc.org)"
307 caspsuf=".epub"
308 conv='pandoc -r html - -w epub2 -o "$casp"'
310 word) {
311 if executable_p unoconv && test -z "$dc"; then
312 unset filt
313 conv='unoconv -o "$casp" "$1"'
314 else
315 missing antiword "antiword or unoconv"
316 conv='antiword -m 8859-1.txt -a a4 - >"$casp"'
319 uno) {
320 test -n "$dc" && die "cannot convert compressed '$mime'"
321 unset filt
322 missing unoconv "unoconv(http://dag.wiee.rs/home-made/unoconv/)"
323 conv='unoconv -o "$casp" "$1"'
325 svg) {
326 if executable_p inkscape && test -z "$dc"; then
327 unset filt
328 conv='inkscape -z -A "$casp" "$1"'
329 else
330 if executable_p rsvg-convert; then
331 conv='rsvg-convert -f pdf -o "$casp"'
332 else
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"'
340 font) {
341 maketext "$1" "$textfilename"
342 exec llpp -origin $1 -layout-height 0 "$cachedir/fonts/text.html"
344 image) {
345 missing convert "convert(http://www.imagemagick.org/script/convert.php)"
346 conv='convert - pdf:"$casp"'
348 dvi) {
349 test -n "$dc" && die "cannot convert compressed '$mime'"
350 unset filt
351 missing dvipdf "dvipdf(http://ghostscript.com/)"
352 conv='dvipdf "$1" "$casp"'
354 text) {
355 missing pandoc "pandoc(http://pandoc.org/)"
356 conv='pandoc -t epub2 - -o "$casp"'
357 caspsuf=.epub
359 *) die "unhandled filter type: '$type'";;
360 esac
362 hash=$(cksum "$hashof") || die "$hash"
363 casp=$cachedir/${hash%% *}$caspsuf
365 { test -n "$force" || test ! -e "$casp"; } && eval "$filt" "$conv"
366 shift
368 exec llpp -origin $origin "$@" "$casp"