eleven / ocho Public

Clone
git clone https://amadan.net/eleven/ocho

Plain git — no account needed to clone.

Download

Download this file

1{
2 "description": "Composer serialization contract (issue #890): composer doc shape (the markdown.json tree vocabulary) -> exact wire bytes. The web serializer (composer-md.js serializeDoc) is the authority; the native twin (ComposerSerialize.swift) must emit identical bytes. `reparse` documents the accepted serialize-then-parse non-identities (expelled whitespace, code padding, typed double breaks becoming paragraphs); absent means parseMessage(md) returns the input tree. Scope notes: no nested blocks, no links from typing, no breaks inside list items — unreachable from composer typing on both platforms (web binds neither sinkListItem nor Tab; native has literal edit-load and plain paste). When a twin disagrees, fix the implementation, never the vector.",
3 "vectors": [
4 {
5 "name": "plain_single",
6 "tree": [
7 {
8 "t": "p",
9 "children": [
10 {
11 "t": "text",
12 "text": "hello"
13 }
14 ]
15 }
16 ],
17 "md": "hello"
18 },
19 {
20 "name": "plain_multiline",
21 "tree": [
22 {
23 "t": "p",
24 "children": [
25 {
26 "t": "text",
27 "text": "a"
28 },
29 {
30 "t": "br"
31 },
32 {
33 "t": "text",
34 "text": "b"
35 }
36 ]
37 }
38 ],
39 "md": "a\nb",
40 "note": "hard_break is a plain \\n on the wire"
41 },
42 {
43 "name": "double_break",
44 "tree": [
45 {
46 "t": "p",
47 "children": [
48 {
49 "t": "text",
50 "text": "a"
51 },
52 {
53 "t": "br"
54 },
55 {
56 "t": "br"
57 },
58 {
59 "t": "text",
60 "text": "b"
61 }
62 ]
63 }
64 ],
65 "md": "a\n\nb",
66 "reparse": [
67 {
68 "t": "p",
69 "children": [
70 {
71 "t": "text",
72 "text": "a"
73 }
74 ]
75 },
76 {
77 "t": "p",
78 "children": [
79 {
80 "t": "text",
81 "text": "b"
82 }
83 ]
84 }
85 ],
86 "note": "two typed breaks read back as two paragraphs"
87 },
88 {
89 "name": "bold",
90 "tree": [
91 {
92 "t": "p",
93 "children": [
94 {
95 "t": "strong",
96 "children": [
97 {
98 "t": "text",
99 "text": "b"
100 }
101 ]
102 }
103 ]
104 }
105 ],
106 "md": "**b**"
107 },
108 {
109 "name": "italic",
110 "tree": [
111 {
112 "t": "p",
113 "children": [
114 {
115 "t": "em",
116 "children": [
117 {
118 "t": "text",
119 "text": "i"
120 }
121 ]
122 }
123 ]
124 }
125 ],
126 "md": "*i*"
127 },
128 {
129 "name": "strike_single_tilde",
130 "tree": [
131 {
132 "t": "p",
133 "children": [
134 {
135 "t": "strike",
136 "children": [
137 {
138 "t": "text",
139 "text": "s"
140 }
141 ]
142 }
143 ]
144 }
145 ],
146 "md": "~s~",
147 "note": "single tilde — old clients render it perfectly"
148 },
149 {
150 "name": "inline_code",
151 "tree": [
152 {
153 "t": "p",
154 "children": [
155 {
156 "t": "code",
157 "text": "c"
158 }
159 ]
160 }
161 ],
162 "md": "`c`"
163 },
164 {
165 "name": "bold_italic",
166 "tree": [
167 {
168 "t": "p",
169 "children": [
170 {
171 "t": "em",
172 "children": [
173 {
174 "t": "strong",
175 "children": [
176 {
177 "t": "text",
178 "text": "bi"
179 }
180 ]
181 }
182 ]
183 }
184 ]
185 }
186 ],
187 "md": "***bi***",
188 "note": "mark rank: em outermost"
189 },
190 {
191 "name": "strong_strike",
192 "tree": [
193 {
194 "t": "p",
195 "children": [
196 {
197 "t": "strong",
198 "children": [
199 {
200 "t": "strike",
201 "children": [
202 {
203 "t": "text",
204 "text": "x"
205 }
206 ]
207 }
208 ]
209 }
210 ]
211 }
212 ],
213 "md": "**~x~**"
214 },
215 {
216 "name": "em_strike",
217 "tree": [
218 {
219 "t": "p",
220 "children": [
221 {
222 "t": "em",
223 "children": [
224 {
225 "t": "strike",
226 "children": [
227 {
228 "t": "text",
229 "text": "x"
230 }
231 ]
232 }
233 ]
234 }
235 ]
236 }
237 ],
238 "md": "*~x~*"
239 },
240 {
241 "name": "em_strong_strike",
242 "tree": [
243 {
244 "t": "p",
245 "children": [
246 {
247 "t": "em",
248 "children": [
249 {
250 "t": "strong",
251 "children": [
252 {
253 "t": "strike",
254 "children": [
255 {
256 "t": "text",
257 "text": "x"
258 }
259 ]
260 }
261 ]
262 }
263 ]
264 }
265 ]
266 }
267 ],
268 "md": "***~x~***"
269 },
270 {
271 "name": "mixable_continuation",
272 "tree": [
273 {
274 "t": "p",
275 "children": [
276 {
277 "t": "strong",
278 "children": [
279 {
280 "t": "text",
281 "text": "bold "
282 }
283 ]
284 },
285 {
286 "t": "em",
287 "children": [
288 {
289 "t": "strong",
290 "children": [
291 {
292 "t": "text",
293 "text": "inner"
294 }
295 ]
296 }
297 ]
298 },
299 {
300 "t": "strong",
301 "children": [
302 {
303 "t": "text",
304 "text": " bold"
305 }
306 ]
307 }
308 ]
309 }
310 ],
311 "md": "**bold *inner* bold**",
312 "reparse": [
313 {
314 "t": "p",
315 "children": [
316 {
317 "t": "strong",
318 "children": [
319 {
320 "t": "text",
321 "text": "bold "
322 },
323 {
324 "t": "em",
325 "children": [
326 {
327 "t": "text",
328 "text": "inner"
329 }
330 ]
331 },
332 {
333 "t": "text",
334 "text": " bold"
335 }
336 ]
337 }
338 ]
339 }
340 ],
341 "note": "the already-open strong stays outside"
342 },
343 {
344 "name": "escape_star_in_strong",
345 "tree": [
346 {
347 "t": "p",
348 "children": [
349 {
350 "t": "strong",
351 "children": [
352 {
353 "t": "text",
354 "text": "a*b"
355 }
356 ]
357 }
358 ]
359 }
360 ],
361 "md": "**a\\*b**",
362 "note": "in-mark escapes only"
363 },
364 {
365 "name": "escape_star_in_em",
366 "tree": [
367 {
368 "t": "p",
369 "children": [
370 {
371 "t": "em",
372 "children": [
373 {
374 "t": "text",
375 "text": "2*3"
376 }
377 ]
378 }
379 ]
380 }
381 ],
382 "md": "*2\\*3*"
383 },
384 {
385 "name": "escape_tilde_in_strike",
386 "tree": [
387 {
388 "t": "p",
389 "children": [
390 {
391 "t": "strike",
392 "children": [
393 {
394 "t": "text",
395 "text": "a~b"
396 }
397 ]
398 }
399 ]
400 }
401 ],
402 "md": "~a\\~b~"
403 },
404 {
405 "name": "zero_escape_plain",
406 "tree": [
407 {
408 "t": "p",
409 "children": [
410 {
411 "t": "text",
412 "text": "2*3 and ~x~ stay"
413 }
414 ]
415 }
416 ],
417 "md": "2*3 and ~x~ stay",
418 "reparse": [
419 {
420 "t": "p",
421 "children": [
422 {
423 "t": "text",
424 "text": "2*3 and "
425 },
426 {
427 "t": "strike",
428 "children": [
429 {
430 "t": "text",
431 "text": "x"
432 }
433 ]
434 },
435 {
436 "t": "text",
437 "text": " stay"
438 }
439 ]
440 }
441 ],
442 "note": "plain text serializes verbatim, never a backslash"
443 },
444 {
445 "name": "code_tick_sizing",
446 "tree": [
447 {
448 "t": "p",
449 "children": [
450 {
451 "t": "code",
452 "text": "a`b"
453 }
454 ]
455 }
456 ],
457 "md": "`` a`b ``",
458 "note": "delimiters sized past inner backticks, space-padded"
459 },
460 {
461 "name": "code_double_tick",
462 "tree": [
463 {
464 "t": "p",
465 "children": [
466 {
467 "t": "code",
468 "text": "a``b"
469 }
470 ]
471 }
472 ],
473 "md": "``` a``b ```"
474 },
475 {
476 "name": "code_space_padding",
477 "tree": [
478 {
479 "t": "p",
480 "children": [
481 {
482 "t": "code",
483 "text": " x "
484 }
485 ]
486 }
487 ],
488 "md": "` x `",
489 "reparse": [
490 {
491 "t": "p",
492 "children": [
493 {
494 "t": "code",
495 "text": "x"
496 }
497 ]
498 }
499 ]
500 },
501 {
502 "name": "code_beside_marks",
503 "tree": [
504 {
505 "t": "p",
506 "children": [
507 {
508 "t": "strong",
509 "children": [
510 {
511 "t": "text",
512 "text": "b"
513 }
514 ]
515 },
516 {
517 "t": "text",
518 "text": " "
519 },
520 {
521 "t": "code",
522 "text": "c"
523 }
524 ]
525 }
526 ],
527 "md": "**b** `c`"
528 },
529 {
530 "name": "expel_trailing_ws",
531 "tree": [
532 {
533 "t": "p",
534 "children": [
535 {
536 "t": "strong",
537 "children": [
538 {
539 "t": "text",
540 "text": "a "
541 }
542 ]
543 },
544 {
545 "t": "text",
546 "text": "b"
547 }
548 ]
549 }
550 ],
551 "md": "**a** b",
552 "reparse": [
553 {
554 "t": "p",
555 "children": [
556 {
557 "t": "strong",
558 "children": [
559 {
560 "t": "text",
561 "text": "a"
562 }
563 ]
564 },
565 {
566 "t": "text",
567 "text": " b"
568 }
569 ]
570 }
571 ],
572 "note": "expelEnclosingWhitespace"
573 },
574 {
575 "name": "expel_leading_ws",
576 "tree": [
577 {
578 "t": "p",
579 "children": [
580 {
581 "t": "text",
582 "text": "a"
583 },
584 {
585 "t": "strong",
586 "children": [
587 {
588 "t": "text",
589 "text": " b"
590 }
591 ]
592 }
593 ]
594 }
595 ],
596 "md": "a **b**",
597 "reparse": [
598 {
599 "t": "p",
600 "children": [
601 {
602 "t": "text",
603 "text": "a "
604 },
605 {
606 "t": "strong",
607 "children": [
608 {
609 "t": "text",
610 "text": "b"
611 }
612 ]
613 }
614 ]
615 }
616 ]
617 },
618 {
619 "name": "ws_only_styled",
620 "tree": [
621 {
622 "t": "p",
623 "children": [
624 {
625 "t": "text",
626 "text": "a"
627 },
628 {
629 "t": "strong",
630 "children": [
631 {
632 "t": "text",
633 "text": " "
634 }
635 ]
636 },
637 {
638 "t": "text",
639 "text": "b"
640 }
641 ]
642 }
643 ],
644 "md": "a b",
645 "reparse": [
646 {
647 "t": "p",
648 "children": [
649 {
650 "t": "text",
651 "text": "a b"
652 }
653 ]
654 }
655 ],
656 "note": "whitespace-only styled run collapses to bare whitespace"
657 },
658 {
659 "name": "marked_break_spans",
660 "tree": [
661 {
662 "t": "p",
663 "children": [
664 {
665 "t": "strong",
666 "children": [
667 {
668 "t": "text",
669 "text": "a"
670 },
671 {
672 "t": "br"
673 },
674 {
675 "t": "text",
676 "text": "b"
677 }
678 ]
679 }
680 ]
681 }
682 ],
683 "md": "**a\nb**",
684 "note": "select-across-lines ⌘B: the break carries the mark"
685 },
686 {
687 "name": "unmarked_break_closes",
688 "tree": [
689 {
690 "t": "p",
691 "children": [
692 {
693 "t": "strong",
694 "children": [
695 {
696 "t": "text",
697 "text": "a"
698 }
699 ]
700 },
701 {
702 "t": "br"
703 },
704 {
705 "t": "strong",
706 "children": [
707 {
708 "t": "text",
709 "text": "b"
710 }
711 ]
712 }
713 ]
714 }
715 ],
716 "md": "**a**\n**b**",
717 "note": "typed Shift+Enter: plain break closes and reopens the mark"
718 },
719 {
720 "name": "break_mark_not_continuing",
721 "tree": [
722 {
723 "t": "p",
724 "children": [
725 {
726 "t": "strong",
727 "children": [
728 {
729 "t": "text",
730 "text": "a"
731 },
732 {
733 "t": "br"
734 }
735 ]
736 },
737 {
738 "t": "text",
739 "text": "b"
740 }
741 ]
742 }
743 ],
744 "md": "**a**\nb",
745 "reparse": [
746 {
747 "t": "p",
748 "children": [
749 {
750 "t": "strong",
751 "children": [
752 {
753 "t": "text",
754 "text": "a"
755 }
756 ]
757 },
758 {
759 "t": "br"
760 },
761 {
762 "t": "text",
763 "text": "b"
764 }
765 ]
766 }
767 ],
768 "note": "a break's mark drops when the mark doesn't continue"
769 },
770 {
771 "name": "unicode_styled",
772 "tree": [
773 {
774 "t": "p",
775 "children": [
776 {
777 "t": "strong",
778 "children": [
779 {
780 "t": "text",
781 "text": "líne ✨ emoji"
782 }
783 ]
784 }
785 ]
786 }
787 ],
788 "md": "**líne ✨ emoji**"
789 },
790 {
791 "name": "bullet_list",
792 "tree": [
793 {
794 "t": "ul",
795 "items": [
796 [
797 {
798 "t": "p",
799 "children": [
800 {
801 "t": "text",
802 "text": "a"
803 }
804 ]
805 }
806 ],
807 [
808 {
809 "t": "p",
810 "children": [
811 {
812 "t": "text",
813 "text": "b"
814 }
815 ]
816 }
817 ]
818 ]
819 }
820 ],
821 "md": "- a\n- b"
822 },
823 {
824 "name": "bullet_styled_item",
825 "tree": [
826 {
827 "t": "ul",
828 "items": [
829 [
830 {
831 "t": "p",
832 "children": [
833 {
834 "t": "strong",
835 "children": [
836 {
837 "t": "text",
838 "text": "b"
839 }
840 ]
841 },
842 {
843 "t": "text",
844 "text": " x"
845 }
846 ]
847 }
848 ]
849 ]
850 }
851 ],
852 "md": "- **b** x"
853 },
854 {
855 "name": "ordered_basic",
856 "tree": [
857 {
858 "t": "ol",
859 "start": 1,
860 "items": [
861 [
862 {
863 "t": "p",
864 "children": [
865 {
866 "t": "text",
867 "text": "a"
868 }
869 ]
870 }
871 ],
872 [
873 {
874 "t": "p",
875 "children": [
876 {
877 "t": "text",
878 "text": "b"
879 }
880 ]
881 }
882 ]
883 ]
884 }
885 ],
886 "md": "1. a\n2. b"
887 },
888 {
889 "name": "ordered_start3",
890 "tree": [
891 {
892 "t": "ol",
893 "start": 3,
894 "items": [
895 [
896 {
897 "t": "p",
898 "children": [
899 {
900 "t": "text",
901 "text": "a"
902 }
903 ]
904 }
905 ],
906 [
907 {
908 "t": "p",
909 "children": [
910 {
911 "t": "text",
912 "text": "b"
913 }
914 ]
915 }
916 ]
917 ]
918 }
919 ],
920 "md": "3. a\n4. b"
921 },
922 {
923 "name": "ordered_width_start9",
924 "tree": [
925 {
926 "t": "ol",
927 "start": 9,
928 "items": [
929 [
930 {
931 "t": "p",
932 "children": [
933 {
934 "t": "text",
935 "text": "a"
936 }
937 ]
938 }
939 ],
940 [
941 {
942 "t": "p",
943 "children": [
944 {
945 "t": "text",
946 "text": "b"
947 }
948 ]
949 }
950 ]
951 ]
952 }
953 ],
954 "md": " 9. a\n10. b",
955 "note": "width from digits(start+count-1): ' 9. a' aligns under '10. b'"
956 },
957 {
958 "name": "ordered_ten_items",
959 "tree": [
960 {
961 "t": "ol",
962 "start": 1,
963 "items": [
964 [
965 {
966 "t": "p",
967 "children": [
968 {
969 "t": "text",
970 "text": "item1"
971 }
972 ]
973 }
974 ],
975 [
976 {
977 "t": "p",
978 "children": [
979 {
980 "t": "text",
981 "text": "item2"
982 }
983 ]
984 }
985 ],
986 [
987 {
988 "t": "p",
989 "children": [
990 {
991 "t": "text",
992 "text": "item3"
993 }
994 ]
995 }
996 ],
997 [
998 {
999 "t": "p",
1000 "children": [
1001 {
1002 "t": "text",
1003 "text": "item4"
1004 }
1005 ]
1006 }
1007 ],
1008 [
1009 {
1010 "t": "p",
1011 "children": [
1012 {
1013 "t": "text",
1014 "text": "item5"
1015 }
1016 ]
1017 }
1018 ],
1019 [
1020 {
1021 "t": "p",
1022 "children": [
1023 {
1024 "t": "text",
1025 "text": "item6"
1026 }
1027 ]
1028 }
1029 ],
1030 [
1031 {
1032 "t": "p",
1033 "children": [
1034 {
1035 "t": "text",
1036 "text": "item7"
1037 }
1038 ]
1039 }
1040 ],
1041 [
1042 {
1043 "t": "p",
1044 "children": [
1045 {
1046 "t": "text",
1047 "text": "item8"
1048 }
1049 ]
1050 }
1051 ],
1052 [
1053 {
1054 "t": "p",
1055 "children": [
1056 {
1057 "t": "text",
1058 "text": "item9"
1059 }
1060 ]
1061 }
1062 ],
1063 [
1064 {
1065 "t": "p",
1066 "children": [
1067 {
1068 "t": "text",
1069 "text": "item10"
1070 }
1071 ]
1072 }
1073 ]
1074 ]
1075 }
1076 ],
1077 "md": " 1. item1\n 2. item2\n 3. item3\n 4. item4\n 5. item5\n 6. item6\n 7. item7\n 8. item8\n 9. item9\n10. item10"
1078 },
1079 {
1080 "name": "quote_single",
1081 "tree": [
1082 {
1083 "t": "quote",
1084 "children": [
1085 {
1086 "t": "p",
1087 "children": [
1088 {
1089 "t": "text",
1090 "text": "q"
1091 }
1092 ]
1093 }
1094 ]
1095 }
1096 ],
1097 "md": "> q"
1098 },
1099 {
1100 "name": "quote_styled",
1101 "tree": [
1102 {
1103 "t": "quote",
1104 "children": [
1105 {
1106 "t": "p",
1107 "children": [
1108 {
1109 "t": "strong",
1110 "children": [
1111 {
1112 "t": "text",
1113 "text": "b"
1114 }
1115 ]
1116 },
1117 {
1118 "t": "text",
1119 "text": " i"
1120 }
1121 ]
1122 }
1123 ]
1124 }
1125 ],
1126 "md": "> **b** i"
1127 },
1128 {
1129 "name": "quote_multiline",
1130 "tree": [
1131 {
1132 "t": "quote",
1133 "children": [
1134 {
1135 "t": "p",
1136 "children": [
1137 {
1138 "t": "text",
1139 "text": "a"
1140 },
1141 {
1142 "t": "br"
1143 },
1144 {
1145 "t": "text",
1146 "text": "b"
1147 }
1148 ]
1149 }
1150 ]
1151 }
1152 ],
1153 "md": "> a\n> b"
1154 },
1155 {
1156 "name": "quote_double_break",
1157 "tree": [
1158 {
1159 "t": "quote",
1160 "children": [
1161 {
1162 "t": "p",
1163 "children": [
1164 {
1165 "t": "text",
1166 "text": "a"
1167 },
1168 {
1169 "t": "br"
1170 },
1171 {
1172 "t": "br"
1173 },
1174 {
1175 "t": "text",
1176 "text": "b"
1177 }
1178 ]
1179 }
1180 ]
1181 }
1182 ],
1183 "md": "> a\n> \n> b",
1184 "reparse": [
1185 {
1186 "t": "quote",
1187 "children": [
1188 {
1189 "t": "p",
1190 "children": [
1191 {
1192 "t": "text",
1193 "text": "a"
1194 }
1195 ]
1196 },
1197 {
1198 "t": "p",
1199 "children": [
1200 {
1201 "t": "text",
1202 "text": "b"
1203 }
1204 ]
1205 }
1206 ]
1207 }
1208 ],
1209 "note": "the blank quoted line carries a trailing space"
1210 },
1211 {
1212 "name": "fence_plain",
1213 "tree": [
1214 {
1215 "t": "codeblock",
1216 "text": "code",
1217 "lang": ""
1218 }
1219 ],
1220 "md": "```\ncode\n```"
1221 },
1222 {
1223 "name": "fence_lang",
1224 "tree": [
1225 {
1226 "t": "codeblock",
1227 "text": "code **here**",
1228 "lang": "js"
1229 }
1230 ],
1231 "md": "```js\ncode **here**\n```"
1232 },
1233 {
1234 "name": "fence_inner_backticks",
1235 "tree": [
1236 {
1237 "t": "codeblock",
1238 "text": "x = ```\ny",
1239 "lang": ""
1240 }
1241 ],
1242 "md": "````\nx = ```\ny\n````"
1243 },
1244 {
1245 "name": "fence_empty",
1246 "tree": [
1247 {
1248 "t": "codeblock",
1249 "text": "",
1250 "lang": ""
1251 }
1252 ],
1253 "md": "```\n```"
1254 },
1255 {
1256 "name": "fence_tildes_stay",
1257 "tree": [
1258 {
1259 "t": "codeblock",
1260 "text": "~~~",
1261 "lang": ""
1262 }
1263 ],
1264 "md": "```\n~~~\n```",
1265 "note": "tildes never grow a backtick fence"
1266 },
1267 {
1268 "name": "mixed_blocks",
1269 "tree": [
1270 {
1271 "t": "p",
1272 "children": [
1273 {
1274 "t": "text",
1275 "text": "intro"
1276 }
1277 ]
1278 },
1279 {
1280 "t": "ul",
1281 "items": [
1282 [
1283 {
1284 "t": "p",
1285 "children": [
1286 {
1287 "t": "text",
1288 "text": "one"
1289 }
1290 ]
1291 }
1292 ],
1293 [
1294 {
1295 "t": "p",
1296 "children": [
1297 {
1298 "t": "text",
1299 "text": "two"
1300 }
1301 ]
1302 }
1303 ]
1304 ]
1305 },
1306 {
1307 "t": "quote",
1308 "children": [
1309 {
1310 "t": "p",
1311 "children": [
1312 {
1313 "t": "text",
1314 "text": "bye"
1315 }
1316 ]
1317 }
1318 ]
1319 }
1320 ],
1321 "md": "intro\n\n- one\n- two\n\n> bye"
1322 },
1323 {
1324 "name": "para_then_list",
1325 "tree": [
1326 {
1327 "t": "p",
1328 "children": [
1329 {
1330 "t": "text",
1331 "text": "a"
1332 },
1333 {
1334 "t": "br"
1335 },
1336 {
1337 "t": "text",
1338 "text": "b"
1339 }
1340 ]
1341 },
1342 {
1343 "t": "ul",
1344 "items": [
1345 [
1346 {
1347 "t": "p",
1348 "children": [
1349 {
1350 "t": "text",
1351 "text": "x"
1352 }
1353 ]
1354 }
1355 ]
1356 ]
1357 }
1358 ],
1359 "md": "a\nb\n\n- x"
1360 }
1361 ]
1362}
1363