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