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