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