svgbob/map/ascii_map.rs
1#![allow(clippy::type_complexity)]
2use crate::{
3 buffer::{
4 fragment::PolygonTag::{
5 ArrowBottom, ArrowBottomLeft, ArrowBottomRight, ArrowLeft,
6 ArrowRight, ArrowTop, ArrowTopLeft, ArrowTopRight, DiamondBullet,
7 },
8 Cell, CellGrid,
9 },
10 fragment::{arc, broken_line, circle, line, polygon, rect},
11 Fragment, Property,
12 Signal::{self, Medium, Strong, Weak},
13};
14use once_cell::sync::Lazy;
15use std::{collections::BTreeMap, sync::Arc};
16
17/// The figure below is a Cell that can contain 1 character, divided into 32 equal small rectangles called CellGrid.
18/// ```ignore
19/// 0 1 2 3 4 B C D
20/// 0┌─┬─┬─┬─┐ A┌─┬─┬─┬─┐E
21/// 1├─┼─┼─┼─┤ │ │ │ │ │
22/// 2├─┼─┼─┼─┤ F├─G─H─I─┤J
23/// 3├─┼─┼─┼─┤ │ │ │ │ │
24/// 4├─┼─┼─┼─┤ K├─L─M─N─┤O
25/// 5├─┼─┼─┼─┤ │ │ │ │ │
26/// 6├─┼─┼─┼─┤ P├─Q─R─S─┤T
27/// 7├─┼─┼─┼─┤ │ │ │ │ │
28/// 8└─┴─┴─┴─┘ U└─┴─┴─┴─┘Y
29/// ``` V W X
30
31pub static ASCII_PROPERTIES: Lazy<BTreeMap<char, Property>> = Lazy::new(|| {
32 let cell = Cell::new(0, 0);
33
34 let a = CellGrid::a();
35 let b = CellGrid::b();
36 let c = CellGrid::c();
37 let d = CellGrid::d();
38 let e = CellGrid::e();
39 let f = CellGrid::f();
40 let g = CellGrid::g();
41 let h = CellGrid::h();
42 let i = CellGrid::i();
43 let j = CellGrid::j();
44 let k = CellGrid::k();
45 let l = CellGrid::l();
46 let m = CellGrid::m();
47 let n = CellGrid::n();
48 let o = CellGrid::o();
49 let p = CellGrid::p();
50 let q = CellGrid::q();
51 let r = CellGrid::r();
52 let s = CellGrid::s();
53 let t = CellGrid::t();
54 let u = CellGrid::u();
55 let v = CellGrid::v();
56 let w = CellGrid::w();
57 let x = CellGrid::x();
58 let y = CellGrid::y();
59
60 /// cellgrids that have no names
61 /// just name them with coordinate locations
62 let _01 = CellGrid::point(0, 1);
63 let _11 = CellGrid::point(1, 1);
64 let _21 = CellGrid::point(2, 1);
65 let _31 = CellGrid::point(3, 1);
66 let _41 = CellGrid::point(4, 1);
67 let _03 = CellGrid::point(0, 3);
68 let _13 = CellGrid::point(1, 3);
69 let _23 = CellGrid::point(2, 3);
70 let _33 = CellGrid::point(3, 3);
71 let _43 = CellGrid::point(4, 3);
72 let _05 = CellGrid::point(0, 5);
73 let _15 = CellGrid::point(1, 5);
74 let _25 = CellGrid::point(2, 5);
75 let _35 = CellGrid::point(3, 5);
76 let _45 = CellGrid::point(4, 5);
77 let _07 = CellGrid::point(0, 7);
78 let _17 = CellGrid::point(1, 7);
79 let _27 = CellGrid::point(2, 7);
80 let _37 = CellGrid::point(3, 7);
81 let _47 = CellGrid::point(4, 7);
82
83 let unit1 = Cell::unit(1); // 0.25
84 let unit1_5 = Cell::unit(1) * 1.5; // 0.375
85 let unit2 = Cell::unit(2); // 0.5
86 let unit3 = Cell::unit(3); // 0.75
87 let unit4 = Cell::unit(4); // 1.0
88 let unit5 = Cell::unit(5); // 1.25
89 let unit6 = Cell::unit(6); // 1.5
90 let unit7 = Cell::unit(7); // 1.75
91 let unit8 = Cell::unit(8); // 2.0
92
93 // in between 1 and 2
94 let between1_2 = (unit1 + unit2) / 2.0; // 0.375
95
96 /// char, default static fragments, conditional fragments
97 let map: Vec<(
98 char,
99 Vec<(Signal, Vec<Fragment>)>,
100 Arc<
101 dyn Fn(
102 &Property,
103 &Property,
104 &Property,
105 &Property,
106 &Property,
107 &Property,
108 &Property,
109 &Property,
110 ) -> Vec<(bool, Vec<Fragment>)>
111 + Sync
112 + Send,
113 >,
114 )> = vec![
115 ///////////////
116 // dash -
117 ///////////////
118 (
119 '-',
120 vec![(Strong, vec![line(k, o)])],
121 Arc::new(
122 move |top_left,
123 top,
124 top_right,
125 left,
126 right,
127 bottom_left,
128 bottom,
129 bottom_right| {
130 vec![(true, vec![line(k, o)])]
131 },
132 ),
133 ),
134 ///////////////
135 // tilde ~
136 ///////////////
137 (
138 '~',
139 vec![(Strong, vec![broken_line(k, o)])],
140 Arc::new(
141 move |top_left,
142 top,
143 top_right,
144 left,
145 right,
146 bottom_left,
147 bottom,
148 bottom_right| {
149 vec![(true, vec![broken_line(k, o)])]
150 },
151 ),
152 ),
153 ////////////////////
154 // vertical line |
155 ////////////////////
156 (
157 '|',
158 vec![(Strong, vec![line(c, w)])],
159 Arc::new(
160 move |top_left,
161 top,
162 top_right,
163 left,
164 right,
165 bottom_left,
166 bottom,
167 bottom_right| {
168 vec![
169 (
170 !bottom_left.is('/')
171 && !bottom_right.is('\\')
172 && !top_left.is('\\')
173 && !top_right.is('/'),
174 vec![line(c, w)],
175 ),
176 // _
177 // |
178 (top_right.line_overlap(u, v), vec![line(c, e)]),
179 // _
180 // |
181 (top_left.line_overlap(x, y), vec![line(a, c)]),
182 // |_
183 (right.line_overlap(u, v), vec![line(w, y)]),
184 // _|
185 (left.line_overlap(x, y), vec![line(u, w)]),
186 // |-
187 (right.line_strongly_overlap(k, l), vec![line(m, o)]),
188 // -|
189 (left.line_strongly_overlap(n, o), vec![line(k, m)]),
190 // TODO: restrict lef, right, bottom, top_right, is not connecting to
191 // here
192 // |
193 // /
194 (
195 bottom_left.line_overlap(e, u),
196 vec![line(c, m), line(m, u)],
197 ),
198 // TODO: restrict left, right, bottom, top_left, top_right
199 // |
200 // \
201 (
202 bottom_right.line_overlap(a, y),
203 vec![line(c, m), line(m, y)],
204 ),
205 // TODO: restrict left, right, top, bottom_left, bottom_right
206 // \ /
207 // |
208 (
209 top_left.line_overlap(a, y)
210 && top_right.line_overlap(e, u),
211 vec![line(a, m), line(m, w), line(m, e)],
212 ),
213 ]
214 },
215 ),
216 ),
217 ////////////////////
218 // exclamation bang !
219 ////////////////////
220 (
221 '!',
222 vec![(Strong, vec![broken_line(c, w)])],
223 Arc::new(
224 move |top_left,
225 top,
226 top_right,
227 left,
228 right,
229 bottom_left,
230 bottom,
231 bottom_right| {
232 vec![(
233 top.line_strongly_overlap(r, w)
234 || bottom.line_strongly_overlap(c, h),
235 vec![broken_line(c, w)],
236 )]
237 },
238 ),
239 ),
240 ////////////////////
241 // colon :
242 ////////////////////
243 (
244 ':',
245 vec![(Strong, vec![broken_line(c, w)])],
246 Arc::new(
247 move |top_left,
248 top,
249 top_right,
250 left,
251 right,
252 bottom_left,
253 bottom,
254 bottom_right| {
255 vec![(
256 top.line_strongly_overlap(r, w)
257 || bottom.line_strongly_overlap(c, h),
258 vec![broken_line(c, w)],
259 )]
260 },
261 ),
262 ),
263 /////////////////////////
264 // plus cross +
265 /////////////////////////
266 (
267 '+',
268 vec![
269 (Medium, vec![line(c, w), line(k, o)]),
270 (Weak, vec![line(a, y), line(u, e)]),
271 ],
272 Arc::new(
273 move |top_left,
274 top,
275 top_right,
276 left,
277 right,
278 bottom_left,
279 bottom,
280 bottom_right| {
281 vec![
282 // |
283 // +
284 (top.line_overlap(r, w), vec![line(c, m)]),
285 // +
286 // |
287 (bottom.line_overlap(c, h), vec![line(m, w)]),
288 // -+
289 (left.line_overlap(n, o), vec![line(k, m)]),
290 // +-
291 (right.line_overlap(k, l), vec![line(m, o)]),
292 // .+
293 (left.line_weakly_overlap(n, o), vec![line(k, m)]),
294 // +.
295 (right.line_weakly_overlap(k, l), vec![line(m, o)]),
296 // \
297 // +
298 (top_left.line_overlap(s, y), vec![line(a, m)]),
299 // +
300 // \
301 (bottom_right.line_overlap(a, g), vec![line(m, y)]),
302 // /
303 // +
304 (top_right.line_overlap(q, u), vec![line(m, e)]),
305 // +
306 // /
307 (bottom_left.line_overlap(e, i), vec![line(m, u)]),
308 ]
309 },
310 ),
311 ),
312 /////////////////////////
313 // letter X
314 /////////////////////////
315 (
316 'X',
317 vec![(Strong, vec![line(a, y), line(u, e)])],
318 Arc::new(
319 move |top_left,
320 top,
321 top_right,
322 left,
323 right,
324 bottom_left,
325 bottom,
326 bottom_right| {
327 vec![
328 /*
329 // \ X
330 // X \
331 (top_left.line_overlap(s,y) || bottom_right.line_overlap(a,g), vec![line(a, y)]),
332 // / X
333 // X /
334 (top_right.line_overlap(q,u) || bottom_left.line_overlap(e,i), vec![line(e, u)]),
335 */
336 // -x
337 (left.line_strongly_overlap(m, o), vec![line(m, k)]),
338 // x-
339 (right.line_strongly_overlap(k, l), vec![line(m, o)]),
340 // |
341 // x
342 (top.line_strongly_overlap(r, w), vec![line(m, c)]),
343 // x
344 // |
345 (bottom.line_strongly_overlap(c, h), vec![line(m, w)]),
346 // \
347 // x
348 (
349 top_left.line_strongly_overlap(s, y),
350 vec![line(m, a)],
351 ),
352 // /
353 // x
354 (
355 top_right.line_strongly_overlap(u, q),
356 vec![line(m, e)],
357 ),
358 // x
359 // /
360 (
361 bottom_left.line_strongly_overlap(e, i),
362 vec![line(m, u)],
363 ),
364 // x
365 // \
366 (
367 bottom_right.line_strongly_overlap(a, g),
368 vec![line(m, y)],
369 ),
370 ]
371 },
372 ),
373 ),
374 /////////////////////////
375 // asterisk *
376 /////////////////////////
377 (
378 '*',
379 vec![
380 (Strong, vec![circle(m, unit1_5, true)]),
381 (Medium, vec![line(c, w), line(k, o)]),
382 (Weak, vec![line(a, y), line(u, e)]),
383 ],
384 Arc::new(
385 move |top_left,
386 top,
387 top_right,
388 left,
389 right,
390 bottom_left,
391 bottom,
392 bottom_right| {
393 vec![
394 // must have at least one connection
395 // \|/
396 // -*-
397 // /|\
398 (
399 top.line_strongly_overlap(r, w)
400 || bottom.line_strongly_overlap(c, h)
401 || left.line_strongly_overlap(n, o)
402 || right.line_strongly_overlap(k, l)
403 || top_left.line_strongly_overlap(s, y)
404 || bottom_right.line_strongly_overlap(a, g)
405 || bottom_left.line_strongly_overlap(u, q)
406 || top_right.line_strongly_overlap(e, i),
407 vec![circle(m, unit1_5, true)],
408 ),
409 // |
410 // *
411 (top.line_strongly_overlap(r, w), vec![line(c, h)]),
412 // *
413 // |
414 (bottom.line_strongly_overlap(c, h), vec![line(w, r)]),
415 // -*
416 (left.line_overlap(n, o), vec![line(k, m)]),
417 // *-
418 (right.line_overlap(k, l), vec![line(m, o)]),
419 // \
420 // *
421 (
422 top_left.line_strongly_overlap(s, y),
423 vec![line(a, g)],
424 ),
425 // /
426 // *
427 (
428 top_right.line_strongly_overlap(u, q),
429 vec![line(e, i)],
430 ),
431 // *
432 // /
433 (
434 bottom_left.line_strongly_overlap(e, i),
435 vec![line(u, q)],
436 ),
437 // *
438 // \
439 (
440 bottom_right.line_strongly_overlap(a, g),
441 vec![line(s, y)],
442 ),
443 ]
444 },
445 ),
446 ),
447 /////////////////////////
448 // hash pound #
449 /////////////////////////
450 (
451 '#',
452 vec![
453 (Strong, vec![rect(f, t, true, false)]),
454 (Medium, vec![line(c, w), line(k, o)]),
455 (Weak, vec![line(a, y), line(u, e)]),
456 ],
457 Arc::new(
458 move |top_left,
459 top,
460 top_right,
461 left,
462 right,
463 bottom_left,
464 bottom,
465 bottom_right| {
466 vec![
467 //
468 // |
469 // --#--
470 // |
471 (
472 top.line_overlap(r, w)
473 || bottom.line_overlap(c, h)
474 || left.line_overlap(n, o)
475 || right.line_overlap(k, l),
476 vec![rect(f, t, true, false)],
477 ),
478 //
479 // \ # / #
480 // # \ # /
481 //
482 (
483 top_left.line_overlap(s, y)
484 || bottom_right.line_overlap(a, g)
485 || bottom_left.line_overlap(u, q)
486 || top_right.line_overlap(e, i),
487 vec![polygon(
488 vec![
489 m.adjust(1.4, 2.0),
490 m.adjust(1.4, -2.0),
491 m.adjust(-1.4, -2.0),
492 m.adjust(-1.4, 2.0),
493 ],
494 true,
495 vec![DiamondBullet],
496 )],
497 ),
498 //
499 // |
500 // #
501 //
502 (top.line_overlap(r, w), vec![line(c, h)]),
503 //
504 // #
505 // |
506 //
507 (bottom.line_overlap(c, h), vec![line(r, w)]),
508 // \
509 // #
510 (
511 top_left.line_strongly_overlap(s, y),
512 vec![line(a, g)],
513 ),
514 // /
515 // #
516 (
517 top_right.line_strongly_overlap(u, q),
518 vec![line(e, i)],
519 ),
520 // #
521 // /
522 (
523 bottom_left.line_strongly_overlap(e, i),
524 vec![line(u, q)],
525 ),
526 // #
527 // \
528 (
529 bottom_right.line_strongly_overlap(a, g),
530 vec![line(s, y)],
531 ),
532 ]
533 },
534 ),
535 ),
536 /////////////////////////
537 // small letter o
538 /////////////////////////
539 (
540 'o',
541 vec![
542 (Medium, vec![circle(m, unit1_5, false)]),
543 (Medium, vec![line(k, o)]),
544 (Weak, vec![line(c, w)]),
545 (Weak, vec![line(a, y), line(u, e)]),
546 ],
547 Arc::new(
548 move |top_left,
549 top,
550 top_right,
551 left,
552 right,
553 bottom_left,
554 bottom,
555 bottom_right| {
556 vec![
557 // must have at least one connection
558 // \|/
559 // -o-
560 // /|\
561 (
562 top.line_strongly_overlap(r, w)
563 || bottom.line_strongly_overlap(c, h)
564 || left.line_strongly_overlap(n, o)
565 || right.line_strongly_overlap(k, l)
566 || top_left.line_strongly_overlap(s, y)
567 || bottom_right.line_strongly_overlap(a, g)
568 || bottom_left.line_strongly_overlap(u, q)
569 || top_right.line_strongly_overlap(e, i),
570 vec![circle(m, unit1_5, false)],
571 ),
572 // |
573 // o
574 (top.line_strongly_overlap(r, w), vec![line(c, h)]),
575 // o
576 // |
577 (bottom.line_strongly_overlap(c, h), vec![line(w, r)]),
578 // \
579 // o
580 (
581 top_left.line_strongly_overlap(s, y),
582 vec![line(a, g)],
583 ),
584 // /
585 // o
586 (
587 top_right.line_strongly_overlap(u, q),
588 vec![line(e, i)],
589 ),
590 // o
591 // /
592 (
593 bottom_left.line_strongly_overlap(e, i),
594 vec![line(u, q)],
595 ),
596 // o
597 // \
598 (
599 bottom_right.line_strongly_overlap(a, g),
600 vec![line(s, y)],
601 ),
602 ]
603 },
604 ),
605 ),
606 /////////////////////////
607 // big letter O
608 /////////////////////////
609 (
610 'O',
611 vec![
612 (Medium, vec![circle(m, unit2, false)]),
613 (Medium, vec![line(k, o)]),
614 (Weak, vec![line(c, w)]),
615 (Weak, vec![line(a, y), line(u, e)]),
616 ],
617 Arc::new(
618 move |top_left,
619 top,
620 top_right,
621 left,
622 right,
623 bottom_left,
624 bottom,
625 bottom_right| {
626 vec![
627 // must have at least one connection
628 // \|/
629 // -O-
630 // /|\
631 (
632 top.line_strongly_overlap(r, w)
633 || bottom.line_strongly_overlap(c, h)
634 || left.line_strongly_overlap(n, o)
635 || right.line_strongly_overlap(k, l)
636 || top_left.line_strongly_overlap(s, y)
637 || bottom_right.line_strongly_overlap(a, g)
638 || bottom_left.line_strongly_overlap(u, q)
639 || top_right.line_strongly_overlap(e, i),
640 vec![circle(m, unit2, false)],
641 ),
642 // |
643 // O
644 (top.line_strongly_overlap(r, w), vec![line(c, h)]),
645 // O
646 // |
647 (bottom.line_strongly_overlap(c, h), vec![line(w, r)]),
648 // \
649 // O
650 (
651 top_left.line_strongly_overlap(s, y),
652 vec![line(a, g)],
653 ),
654 // /
655 // O
656 (
657 top_right.line_strongly_overlap(u, q),
658 vec![line(e, i)],
659 ),
660 // O
661 // /
662 (
663 bottom_left.line_strongly_overlap(e, i),
664 vec![line(u, q)],
665 ),
666 // O
667 // \
668 (
669 bottom_right.line_strongly_overlap(a, g),
670 vec![line(s, y)],
671 ),
672 ]
673 },
674 ),
675 ),
676 ////////////////////
677 // underscore _
678 ////////////////////
679 (
680 '_',
681 vec![(Strong, vec![line(u, y)])],
682 Arc::new(
683 move |top_left,
684 top,
685 top_right,
686 left,
687 right,
688 bottom_left,
689 bottom,
690 bottom_right| {
691 vec![
692 (true, vec![line(u, y)]),
693 // /_
694 (
695 left.line_strongly_overlap(e, u),
696 vec![line(u, cell.left().u())],
697 ),
698 // _\
699 (
700 right.line_strongly_overlap(a, y),
701 vec![line(y, cell.right().y())],
702 ),
703 ]
704 },
705 ),
706 ),
707 //////////////////////
708 // dot period .
709 //////////////////////
710 (
711 '.',
712 vec![
713 (Medium, vec![line(m, w)]), // connects down
714 (Weak, vec![line(m, k)]), // connects left
715 (Weak, vec![line(m, o)]), // connects right
716 ],
717 Arc::new(
718 move |top_left,
719 top,
720 top_right,
721 left,
722 right,
723 bottom_left,
724 bottom,
725 bottom_right| {
726 vec![
727 // .
728 // |
729 (bottom.line_strongly_overlap(c, h), vec![line(r, w)]),
730 // .
731 // / \
732 (
733 bottom_left.line_strongly_overlap(e, i)
734 && bottom_right.line_strongly_overlap(a, g),
735 vec![line(m, u), line(m, y)],
736 ),
737 // .-
738 // |
739 (
740 right.line_overlap(k, l)
741 && bottom.line_overlap(c, h),
742 vec![arc(o, r, unit2), line(r, w)],
743 ),
744 // .-
745 // |
746 (
747 right.line_overlap(k, l)
748 && bottom_left.line_overlap(c, h),
749 vec![
750 arc(m, cell.bottom_left().c(), unit4),
751 line(m, o),
752 ],
753 ),
754 // -.
755 // |
756 (
757 left.line_overlap(n, o)
758 && bottom.line_overlap(c, h),
759 vec![arc(r, k, unit2), line(r, w)],
760 ),
761 // -.
762 // |
763 // exemption that bottom right is not a backquote
764 (
765 !bottom_right.is('`')
766 && left.line_overlap(n, o)
767 && bottom_right.line_overlap(c, h),
768 vec![
769 arc(cell.bottom_right().c(), m, unit4),
770 line(k, m),
771 ],
772 ),
773 // .-
774 // /
775 (
776 right.line_overlap(k, l)
777 && bottom_left.line_overlap(e, i),
778 vec![arc(o, q, unit4), line(q, u)],
779 ),
780 // .-
781 // \
782 (
783 right.line_overlap(k, l)
784 && bottom_right.line_overlap(a, g),
785 vec![arc(o, s, between1_2), line(s, y)],
786 ),
787 // -.
788 // \
789 (
790 left.line_overlap(n, o)
791 && bottom_right.line_overlap(a, g),
792 vec![arc(s, k, unit4), line(s, y)],
793 ),
794 // -.
795 // /
796 (
797 left.line_overlap(n, o)
798 && bottom_left.line_overlap(e, i),
799 vec![arc(q, k, between1_2), line(u, q)],
800 ),
801 // .
802 // (
803 (
804 bottom_left.arcs_to(e, y),
805 vec![arc(o, q, unit4), line(q, u)],
806 ),
807 // .
808 // )
809 (
810 bottom_right.arcs_to(u, a),
811 vec![arc(s, k, unit4), line(s, y)],
812 ),
813 // _.-
814 (
815 left.line_overlap(u, y) && right.line_overlap(k, o),
816 vec![line(u, o)],
817 ),
818 // -._
819 (
820 left.line_overlap(k, o) && right.line_overlap(u, y),
821 vec![line(k, y)],
822 ),
823 // `.
824 // `
825 (
826 left.is('`') && bottom_right.is('`'),
827 vec![broken_line(
828 cell.left().c(),
829 cell.bottom_right().c(),
830 )],
831 ),
832 // .'
833 // '
834 (
835 right.is('\'') && bottom_left.is('\''),
836 vec![broken_line(
837 cell.right().c(),
838 cell.bottom_left().c(),
839 )],
840 ),
841 // '. `.
842 // \ \
843 (
844 (left.is('\'') || left.is('`'))
845 && bottom_right.line_overlap(a, m),
846 vec![arc(y, cell.left().a(), unit8 * 2.0)],
847 ),
848 // .'
849 // /
850 (
851 right.is('\'') && bottom_left.line_overlap(e, m),
852 vec![arc(cell.right().e(), u, unit8 * 2.0)],
853 ),
854 // TODO: restrict left, right, bottom, top_right, is not connecting to here
855 // |
856 // .
857 // /
858 (
859 top.line_overlap(m, w)
860 && bottom_left.line_overlap(e, m),
861 vec![arc(q, h, unit8), line(c, h), line(q, u)],
862 ),
863 // TODO: restrict left, right, bottom,top, is not connecting to here
864 // /
865 // .
866 // /
867 (
868 top_right.line_overlap(m, u)
869 && bottom_left.line_overlap(e, m),
870 vec![line(u, e)],
871 ),
872 // TODO: restrict left, right, bottom, top_left, does not connect to
873 // here
874 // |
875 // .
876 // \
877 (
878 top.line_overlap(m, w)
879 && bottom_right.line_overlap(a, m),
880 vec![line(c, h), arc(h, s, unit8), line(s, y)],
881 ),
882 ]
883 },
884 ),
885 ),
886 //////////////////////
887 // comma ,
888 //////////////////////
889 (
890 ',',
891 vec![
892 (Medium, vec![line(m, r)]),
893 (Weak, vec![line(m, k)]), // connects left
894 (Weak, vec![line(m, o)]), // connects right
895 ],
896 Arc::new(
897 move |top_left,
898 top,
899 top_right,
900 left,
901 right,
902 bottom_left,
903 bottom,
904 bottom_right| {
905 vec![
906 // ,-
907 // |
908 (
909 right.line_overlap(k, l)
910 && bottom.line_overlap(c, h),
911 vec![arc(o, r, unit2), line(r, w)],
912 ),
913 // ,-
914 // /
915 (
916 right.line_overlap(k, l)
917 && bottom_left.line_overlap(e, i),
918 vec![arc(o, q, unit4), line(q, u)],
919 ),
920 // ,
921 // (
922 (
923 bottom_left.arcs_to(e, y),
924 vec![arc(o, q, unit4), line(q, u)],
925 ),
926 ]
927 },
928 ),
929 ),
930 //////////////////////
931 // single quote '
932 //////////////////////
933 (
934 '\'',
935 vec![
936 (Medium, vec![line(c, h)]), //connects top
937 (Weak, vec![line(m, k)]), // connects left
938 (Weak, vec![line(m, o)]), // connects right
939 ],
940 Arc::new(
941 move |top_left,
942 top,
943 top_right,
944 left,
945 right,
946 bottom_left,
947 bottom,
948 bottom_right| {
949 vec![
950 // |
951 // '
952 (top.line_strongly_overlap(m, w), vec![line(c, h)]),
953 // |
954 // '-
955 (
956 right.line_overlap(k, l) && top.line_overlap(r, w),
957 vec![arc(h, o, unit2), line(c, h)],
958 ),
959 // |
960 // '-
961 (
962 right.line_overlap(k, l)
963 && top_left.line_overlap(r, w),
964 vec![
965 arc(cell.top_left().w(), m, unit4),
966 line(m, o),
967 ],
968 ),
969 // |
970 // -'
971 (
972 left.line_overlap(n, o) && top.line_overlap(r, w),
973 vec![arc(k, h, unit2), line(c, h)],
974 ),
975 // |
976 // -'
977 (
978 left.line_overlap(n, o)
979 && top_right.line_overlap(r, w),
980 vec![
981 arc(m, cell.top_right().w(), unit4),
982 line(k, m),
983 ],
984 ),
985 // \
986 // '-
987 (
988 top_left.line_overlap(s, y)
989 && right.line_overlap(k, l),
990 vec![line(a, g), arc(g, o, unit4)],
991 ),
992 // /
993 // '-
994 (
995 top_right.line_overlap(u, q)
996 && right.line_overlap(k, l),
997 vec![line(e, i), arc(i, o, between1_2)],
998 ),
999 // /
1000 // -'
1001 (
1002 top_right.line_overlap(u, q)
1003 && left.line_overlap(n, o),
1004 vec![arc(k, i, unit4), line(i, e)],
1005 ),
1006 // \
1007 // -'
1008 (
1009 top_left.line_overlap(s, y)
1010 && left.line_overlap(n, o),
1011 vec![arc(k, g, between1_2), line(g, a)],
1012 ),
1013 // \ /
1014 // '
1015 (
1016 top_left.line_overlap(s, y)
1017 && top_right.line_overlap(u, q),
1018 vec![line(a, m), line(m, e)],
1019 ),
1020 // (
1021 // '
1022 (
1023 top_left.arcs_to(e, y),
1024 vec![line(a, g), arc(g, o, unit4)],
1025 ),
1026 // )
1027 // '
1028 (
1029 top_right.arcs_to(u, a),
1030 vec![arc(k, i, unit4), line(i, e)],
1031 ),
1032 // _
1033 // -'
1034 (
1035 left.line_overlap(k, o)
1036 && top_right.line_overlap(u, y),
1037 vec![line(k, e)],
1038 ),
1039 // _
1040 // '-
1041 (
1042 top_left.line_overlap(u, y)
1043 && right.line_overlap(k, o),
1044 vec![line(a, o)],
1045 ),
1046 // .
1047 // .'
1048 (
1049 left.is('.') && top_right.is('.'),
1050 vec![broken_line(
1051 cell.left().m(),
1052 cell.top_right().m(),
1053 )],
1054 ),
1055 // .
1056 // '.
1057 (
1058 right.is('.') && top_left.is('.'),
1059 vec![broken_line(
1060 cell.top_left().m(),
1061 cell.right().m(),
1062 )],
1063 ),
1064 // /
1065 // .'
1066 (
1067 left.is('.') && top_right.is('/'),
1068 vec![arc(cell.left().u(), e, unit8 * 2.0)],
1069 ),
1070 ]
1071 },
1072 ),
1073 ),
1074 //////////////////////
1075 // other single quote ’
1076 //////////////////////
1077 (
1078 '’',
1079 vec![
1080 (Medium, vec![line(c, h)]), //connects top
1081 (Weak, vec![line(m, k)]), // connects left
1082 (Weak, vec![line(m, o)]), // connects right
1083 ],
1084 Arc::new(
1085 move |top_left,
1086 top,
1087 top_right,
1088 left,
1089 right,
1090 bottom_left,
1091 bottom,
1092 bottom_right| {
1093 vec![
1094 // |
1095 // ’-
1096 (
1097 right.line_overlap(k, l) && top.line_overlap(r, w),
1098 vec![arc(h, o, unit2), line(c, h)],
1099 ),
1100 // |
1101 // -’
1102 (
1103 left.line_overlap(n, o) && top.line_overlap(r, w),
1104 vec![arc(k, h, unit2), line(c, h)],
1105 ),
1106 // \
1107 // ’-
1108 (
1109 top_left.line_overlap(s, y)
1110 && right.line_overlap(k, l),
1111 vec![line(a, g), arc(g, o, unit4)],
1112 ),
1113 // /
1114 // ’-
1115 (
1116 top_right.line_overlap(u, q)
1117 && right.line_overlap(k, l),
1118 vec![line(e, i), arc(i, o, between1_2)],
1119 ),
1120 // /
1121 // -’
1122 (
1123 top_right.line_overlap(u, q)
1124 && left.line_overlap(n, o),
1125 vec![arc(k, i, unit4), line(i, e)],
1126 ),
1127 // \
1128 // -’
1129 (
1130 top_left.line_overlap(s, y)
1131 && left.line_overlap(n, o),
1132 vec![arc(k, g, between1_2), line(g, a)],
1133 ),
1134 // \ /
1135 // ’
1136 (
1137 top_left.line_overlap(s, y)
1138 && top_right.line_overlap(u, q),
1139 vec![line(a, m), line(m, e)],
1140 ),
1141 // (
1142 // ’
1143 (
1144 top_left.arcs_to(e, y),
1145 vec![line(a, g), arc(g, o, unit4)],
1146 ),
1147 // )
1148 // ’
1149 (
1150 top_right.arcs_to(u, a),
1151 vec![arc(k, i, unit4), line(i, e)],
1152 ),
1153 // _
1154 // -’
1155 (
1156 left.line_overlap(k, o)
1157 && top_right.line_overlap(u, y),
1158 vec![line(k, e)],
1159 ),
1160 // _
1161 // ’-
1162 (
1163 top_left.line_overlap(u, y)
1164 && right.line_overlap(k, o),
1165 vec![line(a, o)],
1166 ),
1167 // .
1168 // .’
1169 (
1170 left.is('.') && top_right.is('.'),
1171 vec![broken_line(
1172 cell.left().m(),
1173 cell.top_right().m(),
1174 )],
1175 ),
1176 // .
1177 // ’.
1178 (
1179 right.is('.') && top_left.is('.'),
1180 vec![broken_line(
1181 cell.top_left().m(),
1182 cell.right().m(),
1183 )],
1184 ),
1185 ]
1186 },
1187 ),
1188 ),
1189 //////////////////////
1190 // backtick / backquote `
1191 //////////////////////
1192 (
1193 '`',
1194 vec![
1195 (Medium, vec![line(c, m)]),
1196 (Weak, vec![line(m, k)]), // connects left
1197 (Weak, vec![line(m, o)]), // connects right
1198 ],
1199 Arc::new(
1200 move |top_left,
1201 top,
1202 top_right,
1203 left,
1204 right,
1205 bottom_left,
1206 bottom,
1207 bottom_right| {
1208 vec![
1209 // |
1210 // `-
1211 (
1212 right.line_overlap(k, l) && top.line_overlap(r, w),
1213 vec![arc(h, o, unit2), line(c, h)],
1214 ),
1215 // \
1216 // `-
1217 (
1218 top_left.line_overlap(s, y)
1219 && right.line_overlap(k, l),
1220 vec![line(a, g), arc(g, o, unit4)],
1221 ),
1222 // (
1223 // `
1224 (
1225 top_left.arcs_to(e, y),
1226 vec![line(a, g), arc(g, o, unit4)],
1227 ),
1228 // _
1229 // `-
1230 (
1231 top_left.line_overlap(u, y)
1232 && right.line_overlap(k, o),
1233 vec![line(a, o)],
1234 ),
1235 // .
1236 // `.
1237 (
1238 top_left.is('.') && right.is('.'),
1239 vec![broken_line(
1240 cell.top_left().m(),
1241 cell.right().m(),
1242 )],
1243 ),
1244 // \
1245 // `.
1246 (
1247 top_left.is('\\') && right.is('.'),
1248 vec![arc(a, cell.right().y(), unit8 * 2.0)],
1249 ),
1250 // ,
1251 // `-
1252 (
1253 top.is(',') && right.line_overlap(k, l),
1254 vec![arc(h, o, unit2), line(c, h)],
1255 ),
1256 ]
1257 },
1258 ),
1259 ),
1260 //////////////////////
1261 // forward slash / slant line
1262 //////////////////////
1263 (
1264 '/',
1265 vec![(Strong, vec![line(u, e)])],
1266 Arc::new(
1267 move |top_left,
1268 top,
1269 top_right,
1270 left,
1271 right,
1272 bottom_left,
1273 bottom,
1274 bottom_right| {
1275 vec![
1276 (!bottom.line_strongly_overlap(c, h), vec![line(u, e)]),
1277 // /-
1278 (right.line_strongly_overlap(k, l), vec![line(m, o)]),
1279 // -/
1280 (left.line_strongly_overlap(n, o), vec![line(m, k)]),
1281 // /
1282 // |
1283 (
1284 bottom.line_strongly_overlap(c, h),
1285 vec![line(e, m), line(m, w)],
1286 ),
1287 ]
1288 },
1289 ),
1290 ),
1291 //////////////////////
1292 // backward slash \
1293 //////////////////////
1294 (
1295 '\\',
1296 vec![(Strong, vec![line(a, y)])],
1297 Arc::new(
1298 move |top_left,
1299 top,
1300 top_right,
1301 left,
1302 right,
1303 bottom_left,
1304 bottom,
1305 bottom_right| {
1306 vec![
1307 (!bottom.is('|'), vec![line(a, y)]),
1308 // \
1309 // |
1310 (
1311 bottom.line_overlap(c, m),
1312 vec![line(a, m), line(m, w)],
1313 ),
1314 // \-
1315 (right.line_strongly_overlap(k, l), vec![line(m, o)]),
1316 // -\
1317 (left.line_strongly_overlap(n, o), vec![line(m, k)]),
1318 ]
1319 },
1320 ),
1321 ),
1322 ////////////////////////
1323 // open parenthesis (
1324 ////////////////////////
1325 (
1326 '(',
1327 vec![(Medium, vec![arc(e, y, unit8)])],
1328 Arc::new(
1329 move |top_left,
1330 top,
1331 top_right,
1332 left,
1333 right,
1334 bottom_left,
1335 bottom,
1336 bottom_right| {
1337 vec![
1338 (
1339 !top.line_overlap(r, w)
1340 && !bottom.line_overlap(c, h),
1341 vec![arc(e, y, unit8)],
1342 ),
1343 // |
1344 // (
1345 // |
1346 (bottom.line_overlap(c, h), vec![arc(c, w, unit6)]),
1347 // -(-
1348 (
1349 left.line_overlap(m, o) && right.line_overlap(k, l),
1350 vec![line(k, o)],
1351 ),
1352 ]
1353 },
1354 ),
1355 ),
1356 ////////////////////////
1357 // close parenthesis )
1358 ////////////////////////
1359 (
1360 ')',
1361 vec![(Medium, vec![arc(u, a, unit8)])],
1362 Arc::new(
1363 move |top_left,
1364 top,
1365 top_right,
1366 left,
1367 right,
1368 bottom_left,
1369 bottom,
1370 bottom_right| {
1371 vec![
1372 (
1373 !top.line_overlap(r, w)
1374 && !bottom.line_overlap(c, h),
1375 vec![arc(u, a, unit8)],
1376 ),
1377 // |
1378 // )
1379 // |
1380 (
1381 top.line_overlap(r, w) && bottom.line_overlap(c, h),
1382 vec![arc(w, c, unit6)],
1383 ),
1384 // -)-
1385 (
1386 left.line_overlap(m, o) && right.line_overlap(k, l),
1387 vec![line(k, o)],
1388 ),
1389 ]
1390 },
1391 ),
1392 ),
1393 ////////////////////////
1394 // big letter V
1395 ////////////////////////
1396 (
1397 'V',
1398 vec![
1399 (
1400 Medium,
1401 vec![polygon(vec![f, j, w], true, vec![ArrowBottom])],
1402 ),
1403 (Weak, vec![line(m, w)]),
1404 ],
1405 Arc::new(
1406 move |top_left,
1407 top,
1408 top_right,
1409 left,
1410 right,
1411 bottom_left,
1412 bottom,
1413 bottom_right| {
1414 vec![
1415 // |
1416 // V
1417 (
1418 top.line_overlap(r, w),
1419 vec![
1420 polygon(vec![f, j, w], true, vec![ArrowBottom]),
1421 line(c, h),
1422 ],
1423 ),
1424 // \
1425 // V
1426 // TODO: use arrow function which alias to a polygon
1427 (
1428 top_left.line_overlap(s, y),
1429 vec![
1430 polygon(
1431 vec![f.adjust_x(-0.5), s, d.adjust_y(0.5)],
1432 true,
1433 vec![ArrowBottomRight],
1434 ),
1435 line(a, g),
1436 ],
1437 ),
1438 // /
1439 // V
1440 (
1441 top_right.line_overlap(u, q),
1442 vec![
1443 polygon(
1444 vec![j.adjust_x(0.5), q, b.adjust_y(0.5)],
1445 true,
1446 vec![ArrowBottomLeft],
1447 ),
1448 line(e, i),
1449 ],
1450 ),
1451 // `.
1452 // V
1453 (
1454 top_left.is('.'),
1455 vec![polygon(
1456 vec![f, o, c],
1457 true,
1458 vec![ArrowBottomRight],
1459 )],
1460 ),
1461 // .'
1462 // V
1463 (
1464 top_right.is('.'),
1465 vec![polygon(
1466 vec![j, k, c],
1467 true,
1468 vec![ArrowBottomLeft],
1469 )],
1470 ),
1471 // V
1472 // |
1473 (
1474 bottom.line_overlap(c, h),
1475 vec![line(a, w), line(w, e)],
1476 ),
1477 ]
1478 },
1479 ),
1480 ),
1481 ////////////////////////
1482 // letter v
1483 ////////////////////////
1484 (
1485 'v',
1486 vec![(
1487 Medium,
1488 vec![polygon(
1489 vec![f, j, w],
1490 true,
1491 vec![ArrowBottom, ArrowBottomLeft, ArrowBottomRight],
1492 )],
1493 )],
1494 Arc::new(
1495 move |top_left,
1496 top,
1497 top_right,
1498 left,
1499 right,
1500 bottom_left,
1501 bottom,
1502 bottom_right| {
1503 vec![
1504 // |
1505 // v
1506 (
1507 top.line_overlap(r, w),
1508 vec![
1509 polygon(vec![f, j, w], true, vec![ArrowBottom]),
1510 line(c, h),
1511 ],
1512 ),
1513 // \
1514 // v
1515 (
1516 top_left.line_overlap(s, y),
1517 vec![
1518 polygon(
1519 vec![f.adjust_x(-0.5), s, d.adjust_y(0.5)],
1520 true,
1521 vec![ArrowBottomRight],
1522 ),
1523 line(a, g),
1524 ],
1525 ),
1526 // /
1527 // v
1528 (
1529 top_right.line_overlap(u, q),
1530 vec![
1531 polygon(
1532 vec![j.adjust_x(0.5), q, b.adjust_y(0.5)],
1533 true,
1534 vec![ArrowBottomLeft],
1535 ),
1536 line(e, i),
1537 ],
1538 ),
1539 // `.
1540 // v
1541 (
1542 top_left.is('.'),
1543 vec![polygon(
1544 vec![f, o, c],
1545 true,
1546 vec![ArrowBottomRight],
1547 )],
1548 ),
1549 // .'
1550 // v
1551 (
1552 top_right.is('.'),
1553 vec![polygon(
1554 vec![j, k, c],
1555 true,
1556 vec![ArrowBottomLeft],
1557 )],
1558 ),
1559 // v
1560 // |
1561 (
1562 bottom.line_overlap(c, h)
1563 && !top.line_overlap(r, w),
1564 vec![line(a, w), line(w, e)],
1565 ),
1566 ]
1567 },
1568 ),
1569 ),
1570 ////////////////////////
1571 // caret ^
1572 ////////////////////////
1573 (
1574 '^',
1575 vec![(
1576 Medium,
1577 vec![polygon(
1578 vec![p, c, t],
1579 true,
1580 vec![ArrowTop, ArrowTopLeft, ArrowTopRight],
1581 )],
1582 )],
1583 Arc::new(
1584 move |top_left,
1585 top,
1586 top_right,
1587 left,
1588 right,
1589 bottom_left,
1590 bottom,
1591 bottom_right| {
1592 vec![
1593 // ^
1594 // |
1595 (
1596 bottom.line_overlap(c, h),
1597 vec![
1598 polygon(vec![p, c, t], true, vec![ArrowTop]),
1599 line(r, w),
1600 ],
1601 ),
1602 // ^
1603 // \
1604 (
1605 bottom_right.line_overlap(a, g)
1606 && !bottom_left.is('/'),
1607 vec![
1608 polygon(
1609 vec![t.adjust_x(0.5), g, v.adjust_y(-0.5)],
1610 true,
1611 vec![ArrowTopLeft],
1612 ),
1613 line(s, y),
1614 ],
1615 ),
1616 // ^
1617 // /
1618 (
1619 bottom_left.line_overlap(e, i)
1620 && !bottom_right.is('\\'),
1621 vec![
1622 polygon(
1623 vec![p.adjust_x(-0.5), i, x.adjust_y(-0.5)],
1624 true,
1625 vec![ArrowTopRight],
1626 ),
1627 line(u, q),
1628 ],
1629 ),
1630 // |
1631 // ^
1632 (
1633 top.line_overlap(r, w)
1634 && !bottom.line_overlap(c, h),
1635 vec![line(c, u), line(c, y)],
1636 ),
1637 // ^
1638 // / \
1639 (
1640 bottom_left.is('/') && bottom_right.is('\\'),
1641 vec![line(c, u), line(c, y)],
1642 ),
1643 ]
1644 },
1645 ),
1646 ),
1647 ////////////////////////
1648 // greater than >
1649 ////////////////////////
1650 (
1651 '>',
1652 vec![(
1653 Medium,
1654 vec![polygon(vec![f, o, p], true, vec![ArrowRight])],
1655 )],
1656 Arc::new(
1657 move |top_left,
1658 top,
1659 top_right,
1660 left,
1661 right,
1662 bottom_left,
1663 bottom,
1664 bottom_right| {
1665 vec![
1666 // --->
1667 (
1668 left.line_overlap(n, o),
1669 vec![polygon(
1670 vec![f, o, p],
1671 true,
1672 vec![ArrowRight],
1673 )],
1674 ),
1675 // >----
1676 (
1677 right.line_overlap(k, l)
1678 && !left.line_overlap(n, o),
1679 vec![line(f, o), line(o, p)],
1680 ),
1681 // `>
1682 (
1683 left.is('`'),
1684 vec![polygon(
1685 vec![f, o, p],
1686 true,
1687 vec![ArrowRight],
1688 )],
1689 ),
1690 // .>
1691 (
1692 left.is('.'),
1693 vec![polygon(
1694 vec![f, o, p],
1695 true,
1696 vec![ArrowRight],
1697 )],
1698 ),
1699 // >> (double arrow)
1700 (
1701 left.is('>'),
1702 vec![polygon(
1703 vec![f, o, p],
1704 true,
1705 vec![ArrowRight],
1706 )],
1707 ),
1708 ]
1709 },
1710 ),
1711 ),
1712 ////////////////////////
1713 // less than <
1714 ////////////////////////
1715 (
1716 '<',
1717 vec![(Medium, vec![polygon(vec![j, k, t], true, vec![ArrowLeft])])],
1718 Arc::new(
1719 move |top_left,
1720 top,
1721 top_right,
1722 left,
1723 right,
1724 bottom_left,
1725 bottom,
1726 bottom_right| {
1727 vec![
1728 // <--
1729 (
1730 right.line_overlap(k, l),
1731 vec![polygon(vec![j, k, t], true, vec![ArrowLeft])],
1732 ),
1733 // --<
1734 (
1735 left.line_overlap(m, o)
1736 && !right.line_overlap(k, l),
1737 vec![line(j, k), line(k, t)],
1738 ),
1739 // <.
1740 (
1741 right.is('.'),
1742 vec![polygon(vec![j, k, t], true, vec![ArrowLeft])],
1743 ),
1744 // <'
1745 (
1746 right.is('\''),
1747 vec![polygon(vec![j, k, t], true, vec![ArrowLeft])],
1748 ),
1749 // <<
1750 (
1751 right.is('<'),
1752 vec![polygon(vec![j, k, t], true, vec![ArrowLeft])],
1753 ),
1754 ]
1755 },
1756 ),
1757 ),
1758 //////////////////////
1759 // equal sign =
1760 //////////////////////
1761 (
1762 '=',
1763 vec![(Medium, vec![line(_03, _43), line(_05, _45)])],
1764 Arc::new(
1765 move |top_left,
1766 top,
1767 top_right,
1768 left,
1769 right,
1770 bottom_left,
1771 bottom,
1772 bottom_right| {
1773 vec![(true, vec![line(_03, _43), line(_05, _45)])]
1774 },
1775 ),
1776 ),
1777 ];
1778
1779 let mut btree = BTreeMap::new();
1780 for (ch, fragments, closure) in map {
1781 btree.insert(ch, Property::new(ch, fragments, closure));
1782 }
1783 btree
1784});