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