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