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