Expand
[llpp.git] / misc / llppac
blobc2899bffe8391e8d0500a03b7a8b14bd3f34d7a1
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]
131 almost kerning
132 hope doesn't
133 Illegal
134 automatically effective
135 Ilium is the Latin for Ilion.
136 jtanx
138 (from UTF8-demo.txt)
139 Box drawing alignment tests: █
141 ╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳
142 ║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳
143 ║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳
144 ╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳
145 ║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎
146 ║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏
147 ╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ ▗▄▖▛▀▜ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█
148 ▝▀▘▙▄▟
150 https://mirrors.zju.edu.cn/CTAN/fonts/gofonts/doc/gofonts.pdf (page 2)
152 DIN Legibility Standard
154 The recent German DIN 1450 legibility standard
155 recommends several features for font legibility, including
156 differentiation of letter shapes to reduce confusion. The Go fonts
157 conform to the 1450 standard by carefully differentiating zero from
158 capital O; numeral 1 from capital I (eye) and lowercase l (ell);
159 numeral 5 from capital S; and numeral 8 from capital B. The shapes of
160 bowls of b d p q follow the natural asymmetries of legible Renaissance
161 handwriting, aiding differentiation to reduce confusion. [5]
164 Mistaking S for a 5 (at certain sizes) is more of a problem... but... Ze Germans
166 (https://en.wikipedia.org/wiki/Jabberwocky
167 Idea from the aforementioned gofonts paper)
169 Бе сгладне и честлинните комбурси Það leið að stekju, og slýgir greðlar
170 търляха се и сврецваха във плите; sig snældu og böluðu um slöffruna,
171 съвсем окласни бяха тук щурпите og angurvært sungu sópfiðrungar
172 и отма равапсатваха прасурси. við sífgelt týðmana svíræna.
174 (https://en.wikipedia.org/wiki/Typeface)
176 For the rational mind, type design can be a maddening game
177 of drawing things differently in order to make them appear the
178 same.
179 </pre>
183 maketext() {
184 # https://github.com/react-boilerplate/react-boilerplate/issues/1340
185 test -d "$cachedir/fonts" || mkdir "$cachedir/fonts"
186 filename="$(basename "$1")"
187 textfilename="$2"
188 cat >"$cachedir/fonts/text.html" <<EOF
189 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
190 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
191 <html>
192 <head>
193 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
194 <title>$filename</title>
195 <style type="text/css">
196 @font-face { font-family: moo; src: url('$1'); }
197 pre { font-family: moo; }
198 </style>
199 </head>
200 $filename
201 <body>
203 for size in 6 8 10 12 4 2; do
204 text $size $textfilename >>"$cachedir/fonts/text.html"
205 done
206 cat >>"$cachedir/fonts/text.html" <<EOF
207 <br/>
208 $(fc-scan -f '%{fullname} %{style} %{slant} %{file} %{fontversion} %{capability} %{lang}' "$1" || file "$1")
209 </body>
210 </html>
214 trap 'test -n "$casp" && rm -f "$casp"' 0
216 while getopts s:c:m:t:fu opt; do
217 case $opt in
218 m) mime=$OPTARG;;
219 t) type=$OPTARG;;
220 f) force=true;;
221 c) css="-s $OPTARG";;
222 s) textfilename="$OPTARG";;
223 ?) die "usage: $0 [-c css] [-m mime/type] [-t filter] [-f] [-s textfile] [path|url]";;
224 esac
225 done
226 shift $(($OPTIND - 1))
227 test -z "$1" && die "usage $0: path"
229 origin="$1"
230 if ${force-test ! -e "$1"} && expr >/dev/null "$1" : "\(ftp\|https\?\)://"; then
231 if executable_p wget; then
232 dl() { wget -q $1 -O $2; }
233 elif executable_p curl; then
234 dl() { curl -L $1 -o $2; }
235 else
236 die "no program to fetch remote urls found"
239 hashof="$cachedir/$(basename "$1")"
240 dl "$1" "$hashof" || test -e "$md5of"
241 shift
242 set -- "$hashof" "$@"
243 else
244 hashof="$1"
247 test -z "$type" && { ft=$(file -L --mime-type -b "$1") || die "$ft"; }
249 case $ft in
250 application/x-gzip | application/x-compress) dc=zcat;;
251 application/x-xz) dc=xzcat;;
252 application/x-bzip2) dc=bzcat;;
253 *) unset dc || true;;
254 esac
256 filt='"${dc-cat}" "$1" |'
258 typeofmime() {
259 case "$1" in
260 application/postscript) type=ps;;
261 application/pdf) type=pdf;;
262 image/vnd.djvu) type=djvu;;
263 text/html) type=html;;
264 text/plain) type=text;;
265 application/msword) type=word;;
266 application/vnd.openxmlformats-officedocument.* \
267 | application/vnd.ms-powerpoint \
268 | application/vnd.ms-excel \
269 | application/vnd.oasis.opendocument.*) type=uno;;
270 image/svg+xml) type=svg;;
271 image/png | image/jpeg) test -n "$dc" && type="image" || type="image2";;
272 image/*) type=image;;
273 application/x-dvi) type=dvi;;
274 application/x-font-ttf \
275 | application/vnd.ms-opentype \
276 | application/font-sfnt) type=font;;
277 *) return 1;;
278 esac
279 return 0
282 if test -z "$type"; then
283 test -z "$mime" && \
284 mime=$(file -L --mime-type -b "$1" || die "$mime") || \
285 $(file -L --mime-type -bz "$1" || die "$mime")
286 typeofmime "$mime" || die "unhandled file type: '$mime'"
289 caspsuf=".pdf"
290 case $type in
291 ps) conv='ps2pdf - "$casp"';;
292 image2|pdf) test -z "$dc" && exec llpp "$@" || conv='cat >"$casp"';;
293 texi) {
294 missing texi2html "texi2html(http://www.nongnu.org/texi2html/)"
295 missing prince "PrinceXML(http://www.princexml.com/)"
296 conv='texi2html - -o - | prince $css - -o "$casp"'
298 djvu) {
299 missing ddjvu "ddjvu(http://djvu.sourceforge.net/doc/man/ddjvu.html)"
300 conv='ddjvu -format=pdf - "$casp"'
302 html) {
303 missing prince "Prince(http://www.princexml.com/)"
304 conv='prince $css - -o "$casp"'
306 html2epub) {
307 missing pandoc "pandoc(http://pandoc.org)"
308 caspsuf=".epub"
309 conv='pandoc -r html - -w epub2 -o "$casp"'
311 word) {
312 if executable_p unoconv && test -z "$dc"; then
313 unset filt
314 conv='unoconv -o "$casp" "$1"'
315 else
316 missing antiword "antiword or unoconv"
317 conv='antiword -m 8859-1.txt -a a4 - >"$casp"'
320 uno) {
321 test -n "$dc" && die "cannot convert compressed '$mime'"
322 unset filt
323 missing unoconv "unoconv(http://dag.wiee.rs/home-made/unoconv/)"
324 conv='unoconv -o "$casp" "$1"'
326 svg) {
327 if executable_p inkscape && test -z "$dc"; then
328 unset filt
329 conv='inkscape -z -A "$casp" "$1"'
330 else
331 if executable_p rsvg-convert; then
332 conv='rsvg-convert -f pdf -o "$casp"'
333 else
334 test -n "$dc" && die "cannot convert compressed '$mime'"
335 unset filt
336 missing unoconv "unoconv(http://dag.wiee.rs/home-made/unoconv/)"
337 conv='unoconv -o "$casp" "$1"'
341 font) {
342 maketext "$1" "$textfilename"
343 exec llpp -origin $1 -layout-height 0 "$cachedir/fonts/text.html"
345 image) {
346 missing convert "convert(http://www.imagemagick.org/script/convert.php)"
347 conv='convert - pdf:"$casp"'
349 dvi) {
350 test -n "$dc" && die "cannot convert compressed '$mime'"
351 unset filt
352 missing dvipdf "dvipdf(http://ghostscript.com/)"
353 conv='dvipdf "$1" "$casp"'
355 text) {
356 missing pandoc "pandoc(http://pandoc.org/)"
357 conv='pandoc -t epub2 - -o "$casp"'
358 caspsuf=.epub
360 *) die "unhandled filter type: '$type'";;
361 esac
363 hash=$(cksum "$hashof") || die "$hash"
364 casp=$cachedir/${hash%% *}$caspsuf
366 { test -n "$force" || test ! -e "$casp"; } && eval "$filt" "$conv"
367 shift
369 exec llpp -origin $origin "$@" "$casp"