d8d0d53f27af92d45cf6aa4821b8156ed2e8e036
[sheet.git] / writing-latn.inc.pl
1 use 5.014;
2 use utf8;
3 use List::Util qw( pairs pairmap sum );
4
5 my %C = qw(red #EC1C24  blue #3953A3  yellow #F9EC31  black #231F20);
6 my $U = 0;  # optional unicode alternatives
7
8 my @wrapstyle = (
9         'td { white-space: normal; word-spacing: 5em }', # force line break between words
10         '.sample { word-spacing: 0 }',
11         '.sample span { margin-right: 1ex; white-space: nowrap }', # larger space between letters
12 );
13 my $spacestyle = '.sample span { margin-right: 0.5ex }';  # separate multiple letters
14 my @tapstyle = (
15         @wrapstyle,
16         '{ line-height: 1ex }',
17         '.sample { font-size: 80% }',
18 );
19
20 sub disptap {
21         my $code = shift;
22         my ($prefix, @dots) = $code =~ m/\A(-?)(\d)(\d)/ or return $code;
23         if ($U) {
24                 # unicode glyph alternative as DOMINO TILE HORIZONTAL-0a-0b
25                 return $prefix . chr(0x1F031 + ($dots[0] * 7) + $dots[1]);
26         }
27         return $prefix . join(' ', map { '·' x $_ } @dots);
28 }
29
30 sub dispbar {
31         my $code = shift or return '';
32
33         return join '', pairmap {
34                 ($a =~ tr/123/❘❙❚/r) . ($b =~ tr/321/  /dr)
35         } split //, $code if $U;
36
37         my @cols = split //, $code;  # bar and space widths
38         my $width = sum(@cols);
39         return sprintf(
40                 '<svg width="%d" height="%d" viewBox="-.5 0 %d %d"><path d="%s"/></svg>',
41                 $width * 2, 14, $width, 7, join(' ',
42                         'M0,0',
43                         map {
44                                 join('m1,-7', ('v7') x $_->[0]),  # line per bar width
45                                 (map { sprintf 'm%d,-7', $_ + 1 } $_->[1] || ()),  # space forward
46                         }
47                         pairs @cols
48                 )
49         );
50 }
51
52 (
53 uppercase => {
54         list => [qw{ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z }],
55 },
56 lowercase => {
57         list => [qw{ a b c d e f g h i j k l m n o p q r s t u v w x y z }],
58 },
59 suetterlin => {
60         title => 'Sütterlin',
61         style => [
62                 '@font-face {
63                         font-family: Suetterlin; /* R. G. Arens */
64                         src: url("/suetterlin.ttf");
65                 }',
66                 'td { font-family: Suetterlin }',
67         ],
68         list => [qw{ a b c d e f g h i j k l m n o p q r ſ s t u v w x y z }],
69 },
70 roman => {
71         title => 'Old Roman Cursive',
72         style => [
73                 'svg path { stroke-linecap: round; stroke-linejoin: round }',
74                 '.sample span { margin-right: -10px }',
75         ],
76         list => [
77                 map {
78                         !m/^(-?)(\w.+)/ ? $_ :
79                         $1.'<svg width="20" height="20" viewBox="0 0 12 20"><path d="'.$2.'"/></svg>'
80                 }
81                 "m2,4 c1,2 8,9 8,9 M2,15 6,9",
82                 "m2,4 c0,0 3,-2 4,1 1,2 0,9 3,9 1,-0 2,-1 2,-1 m-6,-2 c-5,4 -0,6 1,3",
83                 "m4,7 4,-2 m-4,4 c0,0 -2,7 3,6",
84                 "m3,2 c0,0 7,10 7,12 m-2,-4 c-5,2 -4,9 1,3",
85                 "m3,10 4,0 m2,-7 c0,0 -7,1 -5,16",
86                 "m4,11 5,-2 m-3,-4 7,-4 M0,18 c0,0 4,3 5,-3 2,-6 2,-10 2,-10",
87                 "m3,6 7,-2 m-7,4 c-2,5 4,9 6,6 l1,3",
88                 "m7,9 4,-0 m-8,0 c4,0 6,-1 5,6 M1,3 c2,-0 2,12 2,12",
89                 '>', # i = j
90                 "m6,8 -0,7",
91                 "-m9,5 -5,4 4,4 m-4,-10 -1,13",
92                 "m3,2 c0,0 -1,9 1,10 5,2 6,2 6,2",
93                 "m0,16 3,-10 4,6 2,-5 5,4",
94                 "m2,16 1,-9 5,8 2,-9",
95                 "m5,8 c-2,0 -2,6 1,5 4,-2 1,-5 1,-5",
96                 "m5,8 c0,0 -1,8 2,6 m-3,-7 5,3",
97                 "m3,6 9,12 m-9,-11 c-4,1 -3,4 -3,4 0,0 2,2 6,-1",
98                 "m0,6 c3,-1 3,-1 6,0 2,1 3,3 6,1 m-7,-1 -2,11",
99                 "m13,3 c0,0 -5,2 -8,4 -2,3 -1,5 -2,9 -1,1 -4,2 -4,2",
100                 "m2,7 8,0 m-4,1 c0,0 -1,8 3,5",
101                 '>', # u = v
102                 "m2,5 c0,0 3,5 6,3 3,-2 2,-3 2,-3",
103                 '-',
104                 "m3,19 c-1,-6 6,-17 6,-17 M1,8 c0,0 10,1 10,1",
105                 "-m0,7 c2,-3 5,-2 5,1 l0,11 c0,0 -0,-4 -0,-10 -0,-4 4,-4 6,-3",
106                 "-m3,6 c4,-1 3,3 3,3 -1,3 -2,5 -1,5 1,1 3,0 3,0",
107         ],
108 },
109 sutton => {
110         title => 'Sutton <abbr title="American Sign Lanugage">ASL</abbr>',
111         style => $spacestyle,
112         list => [
113                 # American manual alphabet in Sutton (U+1D800+) notation
114                 map { !!$_ && pack 'W*', map { hex "1D$_" } unpack '(A3)*', $_ } qw{
115                 8F7a9c    847a9c    86Da9c    801a9c    84Aa9c
116                 8CEa9c    8F0       815aa2    892a9c    892a9c9A2aac
117                 840a9c    8DCa9c    88Da9c
118                 819a9c    876a9c    840a9caA1 8F0a9caA1 81Aa9c
119                 903a9c    8FBa9c    815a9c    80Ea9c    887a9c
120                 806a9c    89Aa9c    800a9c945aaa
121                 0         965aa6
122         }],
123 },
124 unistrokes => {
125         title => 'Unistrokes',
126         style => 'svg path { stroke-linecap: round; stroke-linejoin: round }',
127         list => [
128                 map { '<svg width="14" height="16" viewBox="-1 -1 8 10">'.$_.'</svg>' }
129                 map {
130                         sprintf('<circle cx="%s" cy="%s" r="1"/>', m/\AM(\d+),(\d+)(.?)/) . # start point
131                         (!!$3 && qq(<path d="$_"/>))
132                 }
133                 'M3,8 V0',
134                 'M0,0 6,4 0,8',
135                 'M6,0 0,4 6,8',
136                 'M6,0 0,4 6,8',
137                 'M6,4 H0',
138                 'M6,0 0,0 0,8',
139                 'M0,8 6,8 6,0',
140                 'M0,0 6,0 6,8',
141                 'M3,0 V8',
142                 'M6,0 6,8 0,8',
143                 'M0,8 6,0',
144                 'M0,0 0,8 6,8',
145                 'M6,8 3,0 0,8',
146                 'M0,8 3,0 6,8',
147                 'M6,0 Q0,6 3,8 6,6 0,0',
148                 'M0,0 Q4,8 6,4 4,0 0,8',
149                 'M6,0 Q2,8 0,4 2,0 6,8',
150                 'M0,0 6,8',
151                 'M6,0 0,0 6,8 0,8',
152                 'M0,4 H6',
153                 'M6,0 3,8 0,0',
154                 'M0,0 3,8 6,0',
155                 'M0,0 0,8 6,0 6,8',
156                 'M0,0 Q6,6 3,8 0,6 6,0',
157                 'M6,0 0,8',
158                 'M0,0 6,0 0,8 6,8',
159                 'M3,4',
160         ],
161 },
162 #graffiti => {
163 #       title => 'Palm Graffiti',
164 #},
165 ita2 => {
166         title => '<abbr title="International Telegraph Alphabet">ITA</abbr>2',
167         style => [@wrapstyle, 'td { font-size: 50% }'],
168         list => [map { tr/01/○●/r =~ s/..\K/ /r } qw(
169                 11000 10011 01110 10010 10000 10110 01011 00101 01100 11010 11110 01001 00111
170                 00110 00011 01101 11101 01010 10100 00001 11100 01111 11001 10111 10101 10001
171                 00100
172         )],
173 },
174 braille => {
175         list => [qw{ ⠁ ⠃ ⠉ ⠙ ⠑ ⠋ ⠛ ⠓ ⠊ ⠚ ⠅ ⠇ ⠍ ⠝ ⠕ ⠏ ⠟ ⠗ ⠎ ⠞ ⠥ ⠧ ⠺ ⠭ ⠽ ⠵ }],
176 },
177 tactile => {
178         title => '5-point Tactile',
179         list => [
180                 map { '<svg width="9" height="12" viewBox="0 0 18 24">'.$_.'</svg>' }
181                 map {
182                         join '', map { sprintf '<circle cx="%d" cy="%d" r="4"/>',
183                                 !$_ ?  9 : $_ & 1 ? 4 : 14,
184                                 !$_ ? 12 : $_ < 3 ? 4 : 20,
185                         } split //
186                 }
187                 qw{
188                         4 234 012 14 0 014 023 12
189                         02 024 0134 23 013 03 01 123
190                         0124 13 04 1 34 0123 134 0234
191                         034 124
192                 }
193         ],
194 },
195 morse => {
196         style => $spacestyle,
197         list => [map {tr/.-/‧‑/r} qw{
198                 .- -... -.-. -.. . ..-. --. .... .. .--- -.- .-.. --
199                 -. --- .--. --.- .-. ... - ..- ...- .-- -..- -.-- --..
200         }],
201 },
202 tap => {
203         title => 'Tap code',
204         style => \@tapstyle,
205         list => [map { disptap($_) } qw{
206                 11 12 13 14 15 21 22 23  > 24 25 31 32
207                 33 34 35 41 42 43 44 45 51 52 53 54 55
208         }],
209 },
210 shorttap => {
211         title => 'Short Tap',
212         style => \@tapstyle,
213         list => [map { disptap($_) } qw{
214                 11 12 13 14 21 22 23 20 > 31 -13 32 33
215                 30 41 42 -13 43 40 10 51 52 53 50 -31 -40
216         }],
217 },
218 cards => {
219         style => 'td { font-family: Symbola, "DejaVu Sans", serif, sans }',
220         list => [(
221                 map { chr(0x1F0A0 + $_), sprintf('<b>%s</b>', chr(0x1F0B0 + $_)) }  # spades, hearts
222                 1 .. 11, 13, 14  # A 2-10 J Q K
223         ), '', chr(0x1F0CF), chr(0x1F0DF) ],
224 },
225 maritime => {
226         title => 'Maritime flags',
227         style => $spacestyle,
228         list => [
229                 # International Code of Signals, SVG fills
230                 map { !!$_ && '<svg width="20" height="20" viewBox="0 0 30 30">'.s/\n?\t+//gr.'</svg>' }
231                 split /\n\n/, qq{
232                         <path fill="$C{blue}" d="M0,0 h30 l-7.5,15 7.5,15 h-30 z"/>
233                         <path fill="white" d="M0,0 h15 v30 h-15"/>
234
235                         <path fill="$C{red}" d="M0,0 h30 l-7.5,15 7.5,15 h-30 z"/>
236
237                         <path fill="$C{blue}" d="M0,0 h30v30 h-30z"/>
238                         <path fill="white" d="M0,6  h30 v18 h-30" />
239                         <path fill="$C{red}" d="M0,12 h30 v6  h-30" />
240
241                         <path fill="$C{yellow}" d="M0,0 h30v30 h-30z"/>
242                         <path fill="$C{blue}" d="M0,6 h30 v18 h-30"/>
243
244                         <path fill="$C{red}" d="M0,0 h30v30 h-30z"/>
245                         <path fill="$C{blue}" d="M0,0 h30 v15 h-30"/>
246
247                         <path fill="white" d="M0,0 h30v30 h-30z"/>
248                         <path fill="$C{red}" d="M15,0 l15,15 -15,15 -15,-15"/>
249
250                         <path fill="$C{blue}" d="M0,0 h30v30 h-30z"/>
251                         <path fill="$C{yellow}" d="M 0,0 h5 v30 h-5"/>
252                         <path fill="$C{yellow}" d="M10,0 h5 v30 h-5"/>
253                         <path fill="$C{yellow}" d="M20,0 h5 v30 h-5"/>
254
255                         <path fill="$C{red}" d="M0,0 h30v30 h-30z"/>
256                         <path fill="white" d="M0,0 h15 v30 h-15"/>
257
258                         <path fill="$C{yellow}" d="M0,0 h30v30 h-30z"/>
259                         <circle fill="$C{black}" r="7.5" cx="15" cy="15"/>
260
261                         <path fill="$C{blue}" d="M0,0 h30v30 h-30z"/>
262                         <path fill="white" d="M0,10 h30 v10 h-30"/>
263
264                         <path fill="$C{blue}" d="M0,0 h30v30 h-30z"/>
265                         <path fill="$C{yellow}" d="M0,0 h15 v30 h-15"/>
266
267                         <path fill="$C{black}" d="M0,0 h30v30 h-30z"/>
268                         <path fill="$C{yellow}" d="M0,0 h15 v15 h-15 M15,15 h15 v15 h-15"/>
269
270                         <path fill="white" d="M0,0 h30v30 h-30z"/>
271                         <path fill="$C{blue}" d="M4,0h22l-11,11 M4,30h22l-11,-11 M0,4v22l11,-11 M30,4v22l-11,-11"/>
272
273                         <path fill="white" d="M0,0 h30v30 h-30z"/>
274                         <path fill="$C{blue}" d="
275                                 M0,0     h7.5v7.5h-7.5 m0,7.5h7.5v7.5h-7.5
276                                 m7.5,-15 h7.5v7.5h-7.5 m0,7.5h7.5v7.5h-7.5
277                                 m7.5,-30 h7.5v7.5h-7.5 m0,7.5h7.5v7.5h-7.5
278                                 m7.5,-15 h7.5v7.5h-7.5 m0,7.5h7.5v7.5h-7.5
279                         "/>
280
281                         <path fill="$C{yellow}" d="M0,0 h30v30 h-30z"/>
282                         <path fill="$C{red}" d="M0,0 h30 v30"/>
283
284                         <path fill="$C{blue}" d="M0,0 h30v30 h-30z"/>
285                         <path fill="white" d="M10,10 h10 v10 h-10"/>
286
287                         <path fill="$C{yellow}" d="M0,0 h30v30 h-30z"/>
288
289                         <path fill="$C{red}" d="M0,0 h30v30 h-30z"/>
290                         <path fill="$C{yellow}" d="M12.5,0 v30 h5 v-30"/>
291                         <path fill="$C{yellow}" d="M0,12.5 h30 v5 h-30"/>
292
293                         <path fill="white" d="M0,0 h30v30 h-30z"/>
294                         <path fill="$C{blue}" d="M10,10 h10 v10 h-10"/>
295
296                         <path fill="white" d="M0,0 h30v30 h-30z"/>
297                         <path fill="$C{red}" d="M0,0 h10 v30 h-10"/>
298                         <path fill="$C{blue}" d="M20,0 h10 v30 h-10"/>
299
300                         <path fill="white" d="M0,0 h30v30 h-30z"/>
301                         <path fill="$C{red}" d="M0,0 h15 v15 h-15 M15,15 h15 v15 h-15"/>
302
303                         <path fill="$C{red}" d="M0,0 h30v30 h-30z"/>
304                         <path fill="white" d="M4,0h22l-11,11 M4,30h22l-11,-11 M0,4v22l11,-11 M30,4v22l-11,-11"/>
305
306                         <path fill="$C{blue}" d="M0,0 h30v30 h-30z"/>
307                         <path fill="white" d="M5,5 h20 v20 h-20"/>
308                         <path fill="$C{red}" d="M10,10 h10 v10 h-10"/>
309
310                         <path fill="white" d="M0,0 h30v30 h-30z"/>
311                         <path fill="$C{blue}" d="M12.5,0 v30 h5 v-30"/>
312                         <path fill="$C{blue}" d="M0,12.5 h30 v5 h-30"/>
313
314                         <path fill="$C{red}" d="M0,0 h30v30 h-30z"/>
315                         <path fill="$C{yellow}" d="M0,0h6l-6,6 M12,0h6l-18,18v-6 M24,0h6l-30,30v-6
316                                 M30,6v6l-18,18h-6 M30,18v6l-6,6h-6"/>
317
318                         <path fill="$C{black}" d="M0,0 h30v30 h-30z"/>
319                         <path fill="$C{blue}" d="M30,0 v31 l-15,-15"/>
320                         <path fill="$C{yellow}" d="M0,0  h31 l-15,15"/>
321                         <path fill="$C{red}" d="M0,30 h31 l-15,-15"/>
322
323
324
325                         <path fill="$C{blue}" d="M0,5 30,15 0,25"/>
326                         <path fill="$C{yellow}" d="M0,9 20,15 0,21"/>
327
328                         <path fill="$C{blue}" d="M0,5 30,15 0,25"/>
329                         <path fill="white" d="M15,10 30,15 15,20"/>
330                 },
331         ],
332 },
333 flag => {
334         title => 'Flag semaphore',
335         list => [
336                 map {
337                         local $_ = $_;
338                         s/[1-4]\K(?=[4-9])/ /; # prevent unwanted vertical crossing
339                         tr/1-9/↙←↖↑↗→↘↓/;
340                         s{(\S)(?=.)}{<span style="position:absolute">$1</span>};
341                         $_
342                 }
343                 qw(
344                         1 2 3 4 5  6 7 21 31 46  14 51 16 17 23
345                         24 25 26 27 34  35 47 56 57 36  67
346                 )
347         ],
348 },
349 chappe => {
350         title => 'Chappe semaphore',
351         list => [
352                 map {
353                         my ($r, $pr, $pl) = split //, $_;
354                         /^\D$/ ? $_ : sprintf(
355                                 join('',
356                                         '<svg width="16" height="20" viewBox="0 0 10 15">',
357                                         '<path d="M5,6 v7"/>',
358                                         '<path d="M0,%s h10 %s" transform="rotate(%d 5 6)"/>',
359                                         '</svg>',
360                                 ),
361                                 ['6', '3v3', '9v-3']->[$pl],
362                                 [ '',  'v3',  'v-3']->[$pr],
363                                 $r * 45,
364                         );
365                 }
366                 # 360° rotation (0-7) and position state (0-2) of left and right bars
367                 qw(
368                   021 121 221 321 421 521 621 721
369                   > 022 122 222 322 011 111 211 311
370                   001 101 201 301 401 501 601 701 020
371                 )
372         ],
373 },
374 prussian => {
375         title => 'Prussian semaphore',
376         list => [
377                 map { /^\D+$/ ? $_ : sprintf
378                         join('',
379                                 '<svg width="10" height="20" viewBox="0 0 8 18">',
380                                 '<path d="M4,1 v18"/>',
381                                 (map {(
382                                         qq(<path d="M0 $_ h4" transform="rotate(%d 4 $_)"/>),
383                                         qq(<path d="M4 $_ h4" transform="rotate(-%d 4 $_)"/>),
384                                 )} 3, 7, 14),
385                                 '</svg>',
386                         ),
387                         map { ($_ - 2) * 45 % 360 } split //, $_
388                 }
389                 # rotation state (0-3) for left and right bar of 3 rows
390                 qw(
391                         003000 000200 203300 000030 033030 000130 000330 032330 > 031330
392                         022020 130120 001320 233010 030210 022310 203001 233001
393                         131001 231301 000202 023302 230003 032003 201003 101003
394                 )
395         ],
396 },
397 code39 => {
398         title => 'Code 39',
399         list => [map { dispbar($_) } qw(
400                 2111121121 1121121121 2121121111 1111221121 2111221111 1121221111
401                 1111122121 2111122111 1121122111 1111222111 2111111221 1121111221
402                 2121111211 1111211221 2111211211 1121211211 1111112221 2111112211
403                 1121112211 1111212211 2211111121 1221111121 2221111111 1211211121
404                 2211211111 1221211111            1221112111 0 1211212111
405         )], # ISO/IEC 16388
406 },
407 code93 => {
408         title => 'Code 93',
409         list => [map { dispbar($_) } qw(
410                 211113 211212 211311 221112 221211 231111 112113 112212 112311 122112
411                 132111 111123 111222 111321 121122 131121 212112 212211 211122 211221
412                 221121 222111 112122 112221 122121 123111        311211 0 111141
413         )],
414 },
415 code128 => {
416         title => 'Code 128',
417         list => [map { dispbar($_) } qw(
418                 111323 131123 131321 112313 132113 132311 211313 231113 231311 112133
419                 112331 132131 113123 113321 133121 313121 211331 231131 213113 213311
420                 213131 311123 311321 331121 312113 312311        212222 0 211412 2331112
421         )],
422 },
423 rm4scc => {
424         title => '<abbr title="Royal Mail 4-State Customer Code">RM4SCC</abbr>',
425         list => [
426                 map {
427                         my $len = length $_;
428                         !$len ? '' : sprintf(
429                                 '<svg width="%d" height="20" viewBox="0 0 %d 6">'
430                                 . '<path d="M1%s"/></svg>',
431                                 $len * 5, $len * 2,
432                                 join ' m2',
433                                 map { sprintf ',%dv%dm0,-%d',
434                                         ($_ & 1 ? 0 : 2),  2 + ($_ & 2) + ($_ & 1) * 2,
435                                         ($_ & 1 ? 0 : 2) + 2 + ($_ & 2) + ($_ & 1) * 2,
436                                 }
437                                 split //
438                         );
439                 }
440                 qw(
441                                                                 2121 2301
442                         0132 0312 0330 2112 2130 2310
443                         1023 1203 1221 3003 3021 3201
444                         1032 1212 1230 3012 3030 3210
445                         1122 1302 1320 3102 3120 3300
446                         0033
447                 ), # 0 for space
448                 '', 1, 3  # start/end
449         ],
450 },
451 dni => {
452         title => "D'ni",
453         list => [
454                 map {
455                         state $window = 'M-.5,-.5H8.5V8.5H-.5Z';
456                         state $v = [
457                                 '',
458                                 'M0,4 8,4',
459                                 'M0,8 Q4,4 8,8',
460                                 'M0,4 4,8 8,4',
461                                 'M2,0 2,4 8,4',
462                                 'M0,0 8,8 M0,8 8,0', # cross
463                                 'M3.5,4 h1', # dot
464                         ];
465                         state $h = [
466                                 '',
467                                 'M4,0 4,8',
468                                 'M0,0 Q4,4 0,8',
469                                 'M4,-.5 0,4 4,8.5',
470                                 'M4,8 4,2 8,2',
471                         ];
472                         sprintf '<svg width="16" height="16" viewBox="-.5 -.5 9 9"><path d="%s"/></svg>',
473                                 $window . ($h->[$_ % 5] . $v->[$_ / 5] || $v->[6]);
474                 } 0 .. 5*5
475         ],
476 },
477 pigpen => {
478         style => [
479                 'svg path { stroke-linecap: square }',
480                 '.sample svg { margin-right: 0.1em }',
481         ],
482         list => [
483                 map {
484                         qq(<svg width="12" height="12" viewBox="-.5 -.5 7 7">$_</svg>)
485                 }
486                 map {
487                         local $_ = $_;
488                         s/^H/mX,0/ or s/^V/m0,X/ or s/^/m0,0/;
489                         s/[hv]\K|X/6/g;
490                         s/(?:v|,[^0]).*?v\K/-/;
491                         s/(?:h|m[^0]).*?h\K/-/;
492                         m/h/ or s/v/l3,/g;
493                         m/v/ or s/h([^h]*)/l$1,3/g;
494                         my $dot = s/\.// && qq(<circle cx="3" cy="3" r="1"/>);
495                         qq(<path d="$_"/>$dot)
496                 }
497                 qw(
498                         Hvh  vhv  vh  hvh  vhvh  Hhvh  hv  Vvhv  Hhv
499                         Hvh. vhv. vh. hvh. vhvh. Hhvh. hv. Vvhv. Hhv.
500                         vv  hh  Hhh  Vvv
501                         vv. hh. Hhh. Vvv.
502                 ),
503         ],
504 },
505 nyctographs => {
506         style => [
507                 'svg path { stroke-linecap: round; stroke-linejoin: round }',
508                 '.sample svg {
509                         background: rgba(0,0,0, .1);
510                         padding: 0.1em;
511                         margin-right: 0.2em;
512                 }',
513         ],
514         list => [
515                 map { s/M[\d,\hM]+(?=[M"])//gr }  # clean up superfluous moves
516                 map { sprintf
517                         '<svg width="14" height="14" viewBox="-.5 -.5 5 5">'
518                         . '<path d="M0,0%s %s4,0 %s4,4 %s0,4 %s0,0"/></svg>',
519                         'h.5v.5h-.5v-.5',  # start anchor
520                         map { ['M', 'h0M', 'L']->[$_] }
521                         split //
522                 }
523                 # draw style (0=empty, 1=dot, 2=line connect) to right, down, left, up
524                 qw(
525                         0010 0112 2022 2220 2000 2012 0122 0202 0020 0220 0012 0022 2202
526                         0222 2222 0102 0200 2201 2002 2200 0100 0110 0120 2001 2010 2020 0
527                 ),
528         ],
529 },
530 chromacons => {
531         list => [
532                 # Colour Alphabet by Paul Green-Armytage (2010)
533                 map {
534                         sprintf('<span%s>%s</span>',
535                                 !!$_ && sprintf(' style="background:#%s" title="%s"', split /:/),
536                                 chr(8195), # em space
537                         );
538                 }
539                 qw{
540                         F0A3FF:Amethyst 0075DC:Blue      993F00:Caramel  4C005C:Damson   191919:Ebony
541                         005C31:Forest   2BCE48:Green     FFCC99:Honeydew 808080:Iron     94FFB5:Jade
542                         8F7C00:Khaki    9DCC00:Lime      C20088:Mallow
543                         003380:Navy     FFA405:Orpiment  FFA8BB:Pink     426600:Quagmire FF0010:Red
544                         5EF1F2:Sky      00998F:Turquoise E0FF66:Uranium  740AFF:Violet   990000:Wine
545                         FFFF80:Xanthin  FFFF00:Yellow    FF5005:Zinnia   0
546                 }
547         ],
548 },
549 );