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