Montserrat Alternates
[llpp.git] / misc / llppac
blob8f8b016c1c590c8dc2c83778078d59b72e9461c9
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 \`1234567890-=\\
40 ~!@#\$$%^&*()_+|
41 [];',./
42 {}:"&lt;&gt;?"
43 S in S9 59 S9 is like 5
44 final fjord flair ft
45 3ЗЭэзээз3ЗqgO0o ijklI1| bgqpykvwlliliiijil1 lLLl
46 01234567890 3ДС ЗДС ӠДС ʒДС
47 rnrmnnmrrrnmmr
48 Apay Арау
49 örök
50 - - (~-) ~ ~ (-~)
51 curly vs plain braces {} () {} →
53 kerning
54 echo \${@:5}
55 life [l i fe]
56 lambdabot [l a mb]
57 Commutative [Co mm utative]
58 weird [we i rd]
59 Before [Bef ore, Be for e]
60 higher [gh, h i gher, hi gher]
61 multi [mu lti]
62 till [ti ll]
63 language [an]
64 plan [la]
65 when [wh]
66 kerning [rn | ng]
67 мне [мн е]
68 oiled [oi led]
69 mkfifo [mk f i fo, mk f i fo]
70 didn't [di dn't]
71 argumnet (sic) []
72 more [mo re]
73 CmmCall [CmmC a l l]
74 -Wvla [-Wv la]
75 align [a l i gn]
76 Compiling [Co mp iling]
77 print [pr int]
78 fcmono [f cmono]
79 Mail [M ail]
80 xsrc [x src]
81 Pokorna
82 buildglyphs.js [buil dg lyphs]
83 Dollar [Do ll ar]
84 signed [s i gned]
85 Pine [Pi ne]
86 right [r i ght]
87 ugliness
88 Nigeria [Ni g eria]
89 Nothing [Nothi ng]
90 modify [mo dify]
91 mplus [mp lus]
92 Apostolic [A postolic]
93 коде [к о де]
94 Прокофьевну [Пра ко фьевну]
95 Хэлп [X элп]
96 коснулся [ко снулся]
97 обьявляным [об ья вленым]
99 almost kerning
100 hope doesn't
101 Illegal
102 automatically effective
103 Ilium is the Latin for Ilion.
105 (from UTF8-demo.txt)
106 Box drawing alignment tests: █
108 ╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳
109 ║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳
110 ║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳
111 ╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳
112 ║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎
113 ║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏
114 ╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ ▗▄▖▛▀▜ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█
115 ▝▀▘▙▄▟
117 https://mirrors.zju.edu.cn/CTAN/fonts/gofonts/doc/gofonts.pdf (page 2)
119 DIN Legibility Standard
121 The recent German DIN 1450 legibility standard
122 recommends several features for font legibility, including
123 differentiation of letter shapes to reduce confusion. The Go fonts
124 conform to the 1450 standard by carefully differentiating zero from
125 capital O; numeral 1 from capital I (eye) and lowercase l (ell);
126 numeral 5 from capital S; and numeral 8 from capital B. The shapes of
127 bowls of b d p q follow the natural asymmetries of legible Renaissance
128 handwriting, aiding differentiation to reduce confusion. [5]
131 Mistaking S for a 5 (at certain sizes) is more of a problem... but... Ze Germans
133 (https://en.wikipedia.org/wiki/Jabberwocky
134 Idea from the aforementioned gofonts paper)
136 Бе сгладне и честлинните комбурси Það leið að stekju, og slýgir greðlar
137 търляха се и сврецваха във плите; sig snældu og böluðu um slöffruna,
138 съвсем окласни бяха тук щурпите og angurvært sungu sópfiðrungar
139 и отма равапсатваха прасурси. við sífgelt týðmana svíræna.
141 (https://en.wikipedia.org/wiki/Typeface)
143 For the rational mind, type design can be a maddening game
144 of drawing things differently in order to make them appear the
145 same.
146 </pre>
150 maketext() {
151 # https://github.com/react-boilerplate/react-boilerplate/issues/1340
152 test -d "$cachedir/fonts" || mkdir "$cachedir/fonts"
153 filename="$(basename "$1")"
154 textfilename="$2"
155 cat >"$cachedir/fonts/text.html" <<EOF
156 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
157 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
158 <html>
159 <head>
160 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
161 <title>$filename</title>
162 <style type="text/css">
163 @font-face { font-family: moo; src: url('$1'); }
164 pre { font-family: moo; }
165 </style>
166 </head>
167 $filename
168 <body>
170 for size in 6 8 10 12 4 2; do
171 text $size $textfilename >>"$cachedir/fonts/text.html"
172 done
173 cat >>"$cachedir/fonts/text.html" <<EOF
174 <br/>
175 $(fc-scan -f '%{fullname} %{style} %{slant} %{file} %{fontversion} %{capability} %{lang}' "$1" || file "$1")
176 </body>
177 </html>
181 trap 'test -n "$casp" && rm -f "$casp"' 0
183 while getopts s:c:m:t:fu opt; do
184 case $opt in
185 m) mime=$OPTARG;;
186 t) type=$OPTARG;;
187 f) force=true;;
188 c) css="-s $OPTARG";;
189 s) textfilename="$OPTARG";;
190 ?) die "usage: $0 [-c css] [-m mime/type] [-t filter] [-f] [-s textfile] [path|url]";;
191 esac
192 done
193 shift $(($OPTIND - 1))
194 test -z "$1" && die "usage $0: path"
196 origin="$1"
197 if ${force-test ! -e "$1"} && expr >/dev/null "$1" : "\(ftp\|https\?\)://"; then
198 if executable_p wget; then
199 dl() { wget -q $1 -O $2; }
200 elif executable_p curl; then
201 dl() { curl -L $1 -o $2; }
202 else
203 die "no program to fetch remote urls found"
206 hashof="$cachedir/$(basename "$1")"
207 dl "$1" "$hashof" || test -e "$md5of"
208 shift
209 set -- "$hashof" "$@"
210 else
211 hashof="$1"
214 test -z "$type" && { ft=$(file -L --mime-type -b "$1") || die "$ft"; }
216 case $ft in
217 application/x-gzip | application/x-compress) dc=zcat;;
218 application/x-xz) dc=xzcat;;
219 application/x-bzip2) dc=bzcat;;
220 *) unset dc || true;;
221 esac
223 filt='"${dc-cat}" "$1" |'
225 typeofmime() {
226 case "$1" in
227 application/postscript) type=ps;;
228 application/pdf) type=pdf;;
229 image/vnd.djvu) type=djvu;;
230 text/html) type=html;;
231 text/plain) type=text;;
232 application/msword) type=word;;
233 application/vnd.openxmlformats-officedocument.* \
234 | application/vnd.ms-powerpoint \
235 | application/vnd.ms-excel \
236 | application/vnd.oasis.opendocument.*) type=uno;;
237 image/svg+xml) type=svg;;
238 image/png | image/jpeg) test -n "$dc" && type="image" || type="image2";;
239 image/*) type=image;;
240 application/x-dvi) type=dvi;;
241 application/x-font-ttf \
242 | application/vnd.ms-opentype \
243 | application/font-sfnt) type=font;;
244 *) return 1;;
245 esac
246 return 0
249 if test -z "$type"; then
250 test -z "$mime" && \
251 mime=$(file -L --mime-type -b "$1" || die "$mime") || \
252 $(file -L --mime-type -bz "$1" || die "$mime")
253 typeofmime "$mime" || die "unhandled file type: '$mime'"
256 caspsuf=".pdf"
257 case $type in
258 ps) conv='ps2pdf - "$casp"';;
259 image2|pdf) test -z "$dc" && exec llpp "$@" || conv='cat >"$casp"';;
260 texi) {
261 missing texi2html "texi2html(http://www.nongnu.org/texi2html/)"
262 missing prince "PrinceXML(http://www.princexml.com/)"
263 conv='texi2html - -o - | prince $css - -o "$casp"'
265 djvu) {
266 missing ddjvu "ddjvu(http://djvu.sourceforge.net/doc/man/ddjvu.html)"
267 conv='ddjvu -format=pdf - "$casp"'
269 html) {
270 missing prince "Prince(http://www.princexml.com/)"
271 conv='prince $css - -o "$casp"'
273 html2epub) {
274 missing pandoc "pandoc(http://pandoc.org)"
275 caspsuf=".epub"
276 conv='pandoc -r html - -w epub2 -o "$casp"'
278 word) {
279 if executable_p unoconv && test -z "$dc"; then
280 unset filt
281 conv='unoconv -o "$casp" "$1"'
282 else
283 missing antiword "antiword or unoconv"
284 conv='antiword -m 8859-1.txt -a a4 - >"$casp"'
287 uno) {
288 test -n "$dc" && die "cannot convert compressed '$mime'"
289 unset filt
290 missing unoconv "unoconv(http://dag.wiee.rs/home-made/unoconv/)"
291 conv='unoconv -o "$casp" "$1"'
293 svg) {
294 if executable_p inkscape && test -z "$dc"; then
295 unset filt
296 conv='inkscape -z -A "$casp" "$1"'
297 else
298 missing rsvg-convert "rsvg-convert"
299 conv='rsvg-convert -f pdf -o "$casp"'
302 font) {
303 maketext "$1" "$textfilename"
304 exec llpp -origin $1 -layout-height 0 "$cachedir/fonts/text.html"
306 image) {
307 missing convert "convert(http://www.imagemagick.org/script/convert.php)"
308 conv='convert - pdf:"$casp"'
310 dvi) {
311 test -n "$dc" && die "cannot convert compressed '$mime'"
312 unset filt
313 missing dvipdf "dvipdf(http://ghostscript.com/)"
314 conv='dvipdf "$1" "$casp"'
316 text) {
317 missing pandoc "pandoc(http://pandoc.org/)"
318 conv='pandoc -t epub2 - -o "$casp"'
319 caspsuf=.epub
321 *) die "unhandled filter type: '$type'";;
322 esac
324 hash=$(cksum "$hashof") || die "$hash"
325 casp=$cachedir/${hash%% *}$caspsuf
327 { test -n "$force" || test ! -e "$casp"; } && eval "$filt" "$conv"
328 shift
330 exec llpp -origin $origin "$@" "$casp"