@fuzdev/mdz 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +4 -0
  2. package/dist/MdzNodeView.svelte +30 -1
  3. package/dist/MdzNodeView.svelte.d.ts.map +1 -1
  4. package/dist/MdzStreamNodeView.svelte +31 -0
  5. package/dist/MdzStreamNodeView.svelte.d.ts.map +1 -1
  6. package/dist/context_helpers.d.ts +1 -1
  7. package/dist/mdz.d.ts +53 -2
  8. package/dist/mdz.d.ts.map +1 -1
  9. package/dist/mdz.js +29 -1
  10. package/dist/mdz_helpers.d.ts +35 -1
  11. package/dist/mdz_helpers.d.ts.map +1 -1
  12. package/dist/mdz_helpers.js +120 -0
  13. package/dist/mdz_lexer.d.ts +35 -1
  14. package/dist/mdz_lexer.d.ts.map +1 -1
  15. package/dist/mdz_lexer.js +211 -2
  16. package/dist/mdz_opcodes.d.ts +6 -1
  17. package/dist/mdz_opcodes.d.ts.map +1 -1
  18. package/dist/mdz_opcodes_to_nodes.d.ts.map +1 -1
  19. package/dist/mdz_opcodes_to_nodes.js +26 -0
  20. package/dist/mdz_stream_parser.d.ts.map +1 -1
  21. package/dist/mdz_stream_parser.js +20 -1
  22. package/dist/mdz_stream_parser_list.d.ts.map +1 -1
  23. package/dist/mdz_stream_parser_list.js +22 -1
  24. package/dist/mdz_stream_parser_state.d.ts +12 -0
  25. package/dist/mdz_stream_parser_state.d.ts.map +1 -1
  26. package/dist/mdz_stream_parser_state.js +1 -0
  27. package/dist/mdz_stream_parser_table.d.ts +72 -0
  28. package/dist/mdz_stream_parser_table.d.ts.map +1 -0
  29. package/dist/mdz_stream_parser_table.js +351 -0
  30. package/dist/mdz_stream_state.svelte.d.ts +5 -0
  31. package/dist/mdz_stream_state.svelte.d.ts.map +1 -1
  32. package/dist/mdz_stream_state.svelte.js +8 -0
  33. package/dist/mdz_to_svelte.d.ts.map +1 -1
  34. package/dist/mdz_to_svelte.js +37 -3
  35. package/dist/mdz_token_parser.d.ts +16 -0
  36. package/dist/mdz_token_parser.d.ts.map +1 -1
  37. package/dist/mdz_token_parser.js +101 -2
  38. package/dist/svelte_preprocess_mdz.js +2 -2
  39. package/package.json +8 -8
  40. package/src/lib/context_helpers.ts +1 -1
  41. package/src/lib/mdz.ts +70 -3
  42. package/src/lib/mdz_contexts.ts +1 -1
  43. package/src/lib/mdz_helpers.ts +125 -1
  44. package/src/lib/mdz_lexer.ts +262 -3
  45. package/src/lib/mdz_opcodes.ts +10 -1
  46. package/src/lib/mdz_opcodes_to_nodes.ts +37 -3
  47. package/src/lib/mdz_stream_parser.ts +26 -9
  48. package/src/lib/mdz_stream_parser_block.ts +2 -2
  49. package/src/lib/mdz_stream_parser_inline.ts +4 -4
  50. package/src/lib/mdz_stream_parser_link.ts +3 -3
  51. package/src/lib/mdz_stream_parser_list.ts +24 -2
  52. package/src/lib/mdz_stream_parser_state.ts +12 -2
  53. package/src/lib/mdz_stream_parser_table.ts +409 -0
  54. package/src/lib/mdz_stream_parser_text.ts +2 -2
  55. package/src/lib/mdz_stream_parser_url.ts +2 -2
  56. package/src/lib/mdz_stream_state.svelte.ts +8 -1
  57. package/src/lib/mdz_to_svelte.ts +39 -5
  58. package/src/lib/mdz_token_parser.ts +122 -5
  59. package/src/lib/svelte_preprocess_mdz.ts +4 -4
  60. package/src/lib/tsdoc_mdz.ts +1 -1
@@ -26,9 +26,12 @@ import type {
26
26
  MdzNodeHeading,
27
27
  MdzNodeCode,
28
28
  MdzNodeListItem,
29
- } from './mdz.js';
30
- import type {MdzOpcode, MdzNodeId} from './mdz_opcodes.js';
31
- import {mdz_extract_single_tag, mdz_heading_id, mdz_merge_adjacent_text} from './mdz_helpers.js';
29
+ MdzNodeTableRow,
30
+ MdzNodeTableCell,
31
+ MdzTableAlign,
32
+ } from './mdz.ts';
33
+ import type {MdzOpcode, MdzNodeId} from './mdz_opcodes.ts';
34
+ import {mdz_extract_single_tag, mdz_heading_id, mdz_merge_adjacent_text} from './mdz_helpers.ts';
32
35
 
33
36
  interface StackFrame {
34
37
  id: MdzNodeId;
@@ -43,6 +46,8 @@ interface StackFrame {
43
46
  ordered?: boolean;
44
47
  start_number?: number;
45
48
  number?: number;
49
+ align?: Array<MdzTableAlign>;
50
+ header?: boolean;
46
51
  // metadata from close opcode (deferred)
47
52
  end?: number;
48
53
  reference?: string;
@@ -76,6 +81,8 @@ export const mdz_opcodes_to_nodes = (opcodes: Array<MdzOpcode>): Array<MdzNode>
76
81
  ordered: op.ordered,
77
82
  start_number: op.start_number,
78
83
  number: op.number,
84
+ align: op.align,
85
+ header: op.header,
79
86
  });
80
87
  break;
81
88
  }
@@ -417,6 +424,33 @@ const build_node = (frame: StackFrame, frame_children: Array<MdzNode>): MdzNode
417
424
  return {type: 'Blockquote', children: frame_children, start: frame.start, end};
418
425
  }
419
426
 
427
+ case 'Table': {
428
+ // rows are the only children — `end` derives from the last, matching
429
+ // the sync token parser
430
+ const children = frame_children as Array<MdzNodeTableRow>;
431
+ const end = children.length > 0 ? children[children.length - 1]!.end : frame.end!;
432
+ return {type: 'Table', align: frame.align ?? [], children, start: frame.start, end};
433
+ }
434
+
435
+ case 'TableRow': {
436
+ const children = frame_children as Array<MdzNodeTableCell>;
437
+ return {
438
+ type: 'TableRow',
439
+ header: frame.header ?? false,
440
+ children,
441
+ start: frame.start,
442
+ end: frame.end!,
443
+ };
444
+ }
445
+
446
+ case 'TableCell':
447
+ return {
448
+ type: 'TableCell',
449
+ children: mdz_merge_adjacent_text(frame_children),
450
+ start: frame.start,
451
+ end: frame.end!,
452
+ };
453
+
420
454
  case 'Code': {
421
455
  // optimistic inline code container — concatenate children text into leaf MdzNodeCode
422
456
  let content = '';
@@ -35,7 +35,7 @@
35
35
  * @module
36
36
  */
37
37
 
38
- import type {MdzOpcode} from './mdz_opcodes.js';
38
+ import type {MdzOpcode} from './mdz_opcodes.ts';
39
39
  import {
40
40
  BACKTICK,
41
41
  ASTERISK,
@@ -44,6 +44,7 @@ import {
44
44
  NEWLINE,
45
45
  HYPHEN,
46
46
  HASH,
47
+ PIPE,
47
48
  LEFT_ANGLE,
48
49
  RIGHT_ANGLE,
49
50
  SLASH,
@@ -61,7 +62,7 @@ import {
61
62
  mdz_blockquote_line_has_content,
62
63
  mdz_blockquote_strip_width,
63
64
  mdz_remap_segments,
64
- } from './mdz_helpers.js';
65
+ } from './mdz_helpers.ts';
65
66
  import {
66
67
  type MdzStreamParserState,
67
68
  type TryResult,
@@ -80,7 +81,7 @@ import {
80
81
  pop_stack_entry,
81
82
  push_stack_entry,
82
83
  revert_failed_close,
83
- } from './mdz_stream_parser_state.js';
84
+ } from './mdz_stream_parser_state.ts';
84
85
  import {
85
86
  process_codeblock,
86
87
  process_codeblock_forced,
@@ -88,8 +89,9 @@ import {
88
89
  try_codeblock_open,
89
90
  try_heading,
90
91
  try_hr,
91
- } from './mdz_stream_parser_block.js';
92
- import {process_list_line, try_list_start} from './mdz_stream_parser_list.js';
92
+ } from './mdz_stream_parser_block.ts';
93
+ import {process_list_line, try_list_start} from './mdz_stream_parser_list.ts';
94
+ import {close_table, process_table_line, try_table_start} from './mdz_stream_parser_table.ts';
93
95
  import {
94
96
  check_close_word_boundary,
95
97
  close_delimiter,
@@ -97,13 +99,13 @@ import {
97
99
  try_code,
98
100
  try_double_delimiter,
99
101
  try_italic,
100
- } from './mdz_stream_parser_inline.js';
102
+ } from './mdz_stream_parser_inline.ts';
101
103
  import {
102
104
  try_close_tag,
103
105
  try_complete_link,
104
106
  try_link_open,
105
107
  try_tag_open,
106
- } from './mdz_stream_parser_link.js';
108
+ } from './mdz_stream_parser_link.ts';
107
109
  import {
108
110
  complete_pending_url,
109
111
  process_url_content,
@@ -111,8 +113,8 @@ import {
111
113
  try_auto_path_absolute,
112
114
  try_auto_path_relative,
113
115
  try_auto_url_forced,
114
- } from './mdz_stream_parser_url.js';
115
- import {consume_delimiter_as_text, consume_text_run} from './mdz_stream_parser_text.js';
116
+ } from './mdz_stream_parser_url.ts';
117
+ import {consume_delimiter_as_text, consume_text_run} from './mdz_stream_parser_text.ts';
116
118
 
117
119
  /**
118
120
  * Streaming opcode parser for mdz content.
@@ -224,6 +226,11 @@ const finish_state = (state: MdzStreamParserState): void => {
224
226
  if (state.buffer.length > 0) {
225
227
  process_loop(state, true);
226
228
  }
229
+ // close an open top-level table — forced processing ends it at the last
230
+ // row, but an already-drained buffer (everything consumed) needs this net
231
+ if (state.table) {
232
+ close_table(state);
233
+ }
227
234
  // close an open blockquote — finishes its nested inner document (an
228
235
  // unclosed fence inside ends at the quote's EOF, which is this) and
229
236
  // cascades recursively through deeper quotes
@@ -558,6 +565,12 @@ const process_loop = (state: MdzStreamParserState, forced: boolean): void => {
558
565
  continue;
559
566
  }
560
567
 
568
+ // open table — each line is a body row or ends the table
569
+ if (state.table) {
570
+ if (!process_table_line(state, forced)) return; // need more input
571
+ continue;
572
+ }
573
+
561
574
  const char_code = state.buffer.charCodeAt(state.pos);
562
575
 
563
576
  // newline handling
@@ -632,6 +645,10 @@ const process_loop = (state: MdzStreamParserState, forced: boolean): void => {
632
645
  const r = try_blockquote_start(state, forced);
633
646
  if (r === 'consumed') continue;
634
647
  if (!forced && r === 'need_more') return;
648
+ } else if (char_code === PIPE) {
649
+ const r = try_table_start(state, forced);
650
+ if (r === 'consumed') continue;
651
+ if (!forced && r === 'need_more') return;
635
652
  }
636
653
  }
637
654
 
@@ -17,7 +17,7 @@ import {
17
17
  NEWLINE,
18
18
  SPACE,
19
19
  is_line_whitespace,
20
- } from './mdz_helpers.js';
20
+ } from './mdz_helpers.ts';
21
21
  import {
22
22
  type CodeblockState,
23
23
  type MdzStreamParserState,
@@ -28,7 +28,7 @@ import {
28
28
  flush_text,
29
29
  offset,
30
30
  push_stack_entry,
31
- } from './mdz_stream_parser_state.js';
31
+ } from './mdz_stream_parser_state.ts';
32
32
 
33
33
  /**
34
34
  * Try to parse a heading at column 0.
@@ -14,7 +14,7 @@ import {
14
14
  is_word_char,
15
15
  mdz_blockquote_line_has_content,
16
16
  mdz_match_blockquote_prefix,
17
- } from './mdz_helpers.js';
17
+ } from './mdz_helpers.ts';
18
18
  import {
19
19
  type MdzStreamParserState,
20
20
  accumulate_text,
@@ -28,9 +28,9 @@ import {
28
28
  pop_stack_entry,
29
29
  push_stack_entry,
30
30
  revert_above,
31
- } from './mdz_stream_parser_state.js';
32
- import {match_fence_opener, match_list_marker} from './mdz_stream_parser_list.js';
33
- import {consume_delimiter_as_text} from './mdz_stream_parser_text.js';
31
+ } from './mdz_stream_parser_state.ts';
32
+ import {match_fence_opener, match_list_marker} from './mdz_stream_parser_list.ts';
33
+ import {consume_delimiter_as_text} from './mdz_stream_parser_text.ts';
34
34
 
35
35
  /**
36
36
  * Whether `buffer` contains a paragraph break — a newline followed (across
@@ -5,7 +5,7 @@
5
5
  * @module
6
6
  */
7
7
 
8
- import type {MdzNodeTypeContainer} from './mdz_opcodes.js';
8
+ import type {MdzNodeTypeContainer} from './mdz_opcodes.ts';
9
9
  import {
10
10
  A_UPPER,
11
11
  LEFT_BRACKET,
@@ -22,7 +22,7 @@ import {
22
22
  is_valid_path_char,
23
23
  mdz_is_safe_reference,
24
24
  mdz_is_url,
25
- } from './mdz_helpers.js';
25
+ } from './mdz_helpers.ts';
26
26
  import {
27
27
  type MdzStreamParserState,
28
28
  type TryResult,
@@ -36,7 +36,7 @@ import {
36
36
  pop_stack_entry,
37
37
  push_stack_entry,
38
38
  revert_above,
39
- } from './mdz_stream_parser_state.js';
39
+ } from './mdz_stream_parser_state.ts';
40
40
 
41
41
  // -- Links --
42
42
 
@@ -21,13 +21,15 @@ import {
21
21
  NEWLINE,
22
22
  NINE,
23
23
  PERIOD,
24
+ PIPE,
24
25
  RIGHT_ANGLE,
25
26
  SPACE,
26
27
  ZERO,
27
28
  is_line_whitespace,
28
29
  mdz_match_blockquote_prefix,
29
30
  mdz_blockquote_line_has_content,
30
- } from './mdz_helpers.js';
31
+ } from './mdz_helpers.ts';
32
+ import {match_table_in_item_head, open_table_in_item} from './mdz_stream_parser_table.ts';
31
33
  import {
32
34
  type MdzStreamParserState,
33
35
  type TryResult,
@@ -43,7 +45,7 @@ import {
43
45
  flush_text,
44
46
  offset,
45
47
  push_stack_entry,
46
- } from './mdz_stream_parser_state.js';
48
+ } from './mdz_stream_parser_state.ts';
47
49
 
48
50
  /**
49
51
  * A matched list marker: `- ` (unordered) or `N. ` (ordered, 1-9 digits).
@@ -495,6 +497,26 @@ export const process_list_line = (
495
497
  }
496
498
  }
497
499
 
500
+ // a deeper pipe-row line whose next line is a delimiter becomes a table
501
+ // child of the item it would otherwise continue (the fence/quote precedent,
502
+ // a two-line lookahead held until the delimiter line arrives)
503
+ if (indent > 0 && buffer.charCodeAt(j) === PIPE) {
504
+ const target_idx = list_continuation_target(state, indent);
505
+ if (target_idx !== -1) {
506
+ const marker_indent = state.list_levels[target_idx]!.indent;
507
+ const head = match_table_in_item_head(state, j, marker_indent, forced);
508
+ if (head === 'pending') return false;
509
+ if (head !== null) {
510
+ close_list_run(state);
511
+ while (state.list_levels.length - 1 > target_idx) {
512
+ close_list_level(state);
513
+ }
514
+ open_table_in_item(state, j, marker_indent, head);
515
+ return true;
516
+ }
517
+ }
518
+ }
519
+
498
520
  if (run_current && indent > deepest.indent) {
499
521
  // continuation line: soft break, structural indent stripped
500
522
  return continue_run(state, nl_pos, j);
@@ -8,8 +8,8 @@
8
8
  * @module
9
9
  */
10
10
 
11
- import type {MdzNodeTypeContainer, MdzNodeId, MdzOpcode} from './mdz_opcodes.js';
12
- import {NEWLINE, has_non_whitespace, mdz_heading_id_from_text} from './mdz_helpers.js';
11
+ import type {MdzNodeTypeContainer, MdzNodeId, MdzOpcode} from './mdz_opcodes.ts';
12
+ import {NEWLINE, has_non_whitespace, mdz_heading_id_from_text} from './mdz_helpers.ts';
13
13
 
14
14
  /**
15
15
  * Tri-state result for `try_*` parser handlers.
@@ -207,6 +207,15 @@ export interface MdzStreamParserState {
207
207
  * quote (prefix stripping + nested-parser feeding) — see `MdzBlockquoteState`.
208
208
  */
209
209
  blockquote: MdzBlockquoteState | null;
210
+ /**
211
+ * The open table, or null. While set, each line is consumed as a body row
212
+ * (or ends the table) by `process_table_line`. Holds the `Table` frame's id
213
+ * so the table can be closed when a non-row line or EOF ends it. `item_indent`
214
+ * is `null` for a top-level table (column-0 rows) or the enclosing list item's
215
+ * marker indent for a table nested as a block child (rows skip the indent and
216
+ * a dedent to that indent ends the table, returning control to the list).
217
+ */
218
+ table: {id: MdzNodeId; item_indent: number | null} | null;
210
219
  /**
211
220
  * Whether the innermost open ListItem's first inline run is current.
212
221
  * Content then flows directly into the ListItem frame — the sync AST
@@ -300,6 +309,7 @@ export const create_state = (): MdzStreamParserState => ({
300
309
  codeblock: null,
301
310
  list_levels: [],
302
311
  blockquote: null,
312
+ table: null,
303
313
  in_list_item_run: false,
304
314
  last_empty_item_end: 0,
305
315
  base_offset: 0,