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