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