@fuzdev/mdz 0.2.0 → 0.4.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 (83) hide show
  1. package/README.md +4 -0
  2. package/dist/Mdz.svelte +18 -9
  3. package/dist/Mdz.svelte.d.ts +9 -2
  4. package/dist/Mdz.svelte.d.ts.map +1 -1
  5. package/dist/MdzNodeView.svelte +129 -115
  6. package/dist/MdzNodeView.svelte.d.ts +4 -1
  7. package/dist/MdzNodeView.svelte.d.ts.map +1 -1
  8. package/dist/MdzPrecompiled.svelte +3 -3
  9. package/dist/MdzPrecompiled.svelte.d.ts.map +1 -1
  10. package/dist/MdzRoot.svelte +3 -3
  11. package/dist/MdzRoot.svelte.d.ts.map +1 -1
  12. package/dist/MdzStream.svelte +6 -6
  13. package/dist/MdzStream.svelte.d.ts.map +1 -1
  14. package/dist/MdzStreamNodeView.svelte +129 -118
  15. package/dist/MdzStreamNodeView.svelte.d.ts +4 -1
  16. package/dist/MdzStreamNodeView.svelte.d.ts.map +1 -1
  17. package/dist/context_helpers.js +1 -1
  18. package/dist/mdz.d.ts +6 -0
  19. package/dist/mdz.d.ts.map +1 -1
  20. package/dist/mdz.js +8 -0
  21. package/dist/mdz_contexts.d.ts.map +1 -1
  22. package/dist/mdz_debug_work.d.ts +38 -0
  23. package/dist/mdz_debug_work.d.ts.map +1 -0
  24. package/dist/mdz_debug_work.js +37 -0
  25. package/dist/mdz_helpers.d.ts +61 -0
  26. package/dist/mdz_helpers.d.ts.map +1 -1
  27. package/dist/mdz_helpers.js +74 -2
  28. package/dist/mdz_lexer.d.ts +12 -0
  29. package/dist/mdz_lexer.d.ts.map +1 -1
  30. package/dist/mdz_lexer.js +190 -40
  31. package/dist/mdz_opcodes.d.ts.map +1 -1
  32. package/dist/mdz_opcodes_to_nodes.d.ts.map +1 -1
  33. package/dist/mdz_opcodes_to_nodes.js +22 -17
  34. package/dist/mdz_stream_parser.d.ts.map +1 -1
  35. package/dist/mdz_stream_parser.js +8 -8
  36. package/dist/mdz_stream_parser_block.js +5 -5
  37. package/dist/mdz_stream_parser_inline.d.ts.map +1 -1
  38. package/dist/mdz_stream_parser_inline.js +22 -20
  39. package/dist/mdz_stream_parser_link.d.ts.map +1 -1
  40. package/dist/mdz_stream_parser_link.js +88 -56
  41. package/dist/mdz_stream_parser_list.d.ts.map +1 -1
  42. package/dist/mdz_stream_parser_list.js +23 -9
  43. package/dist/mdz_stream_parser_state.d.ts +29 -0
  44. package/dist/mdz_stream_parser_state.d.ts.map +1 -1
  45. package/dist/mdz_stream_parser_state.js +59 -10
  46. package/dist/mdz_stream_parser_table.d.ts +3 -2
  47. package/dist/mdz_stream_parser_table.d.ts.map +1 -1
  48. package/dist/mdz_stream_parser_table.js +24 -13
  49. package/dist/mdz_stream_parser_text.d.ts.map +1 -1
  50. package/dist/mdz_stream_parser_text.js +36 -25
  51. package/dist/mdz_stream_parser_url.js +7 -7
  52. package/dist/mdz_stream_state.svelte.d.ts.map +1 -1
  53. package/dist/mdz_to_svelte.d.ts +1 -1
  54. package/dist/mdz_to_svelte.d.ts.map +1 -1
  55. package/dist/mdz_to_svelte.js +28 -31
  56. package/dist/mdz_token_parser.d.ts.map +1 -1
  57. package/dist/mdz_token_parser.js +24 -25
  58. package/dist/svelte_preprocess_mdz.d.ts +2 -2
  59. package/dist/svelte_preprocess_mdz.d.ts.map +1 -1
  60. package/dist/svelte_preprocess_mdz.js +41 -47
  61. package/package.json +28 -40
  62. package/src/lib/context_helpers.ts +2 -2
  63. package/src/lib/mdz.ts +11 -2
  64. package/src/lib/mdz_contexts.ts +5 -5
  65. package/src/lib/mdz_debug_work.ts +38 -0
  66. package/src/lib/mdz_helpers.ts +126 -23
  67. package/src/lib/mdz_lexer.ts +243 -93
  68. package/src/lib/mdz_opcodes.ts +1 -1
  69. package/src/lib/mdz_opcodes_to_nodes.ts +35 -30
  70. package/src/lib/mdz_stream_parser.ts +17 -17
  71. package/src/lib/mdz_stream_parser_block.ts +14 -14
  72. package/src/lib/mdz_stream_parser_inline.ts +38 -34
  73. package/src/lib/mdz_stream_parser_link.ts +99 -66
  74. package/src/lib/mdz_stream_parser_list.ts +41 -29
  75. package/src/lib/mdz_stream_parser_state.ts +100 -28
  76. package/src/lib/mdz_stream_parser_table.ts +47 -36
  77. package/src/lib/mdz_stream_parser_text.ts +40 -39
  78. package/src/lib/mdz_stream_parser_url.ts +11 -11
  79. package/src/lib/mdz_stream_state.svelte.ts +8 -8
  80. package/src/lib/mdz_to_svelte.ts +38 -46
  81. package/src/lib/mdz_token_parser.ts +55 -58
  82. package/src/lib/svelte_preprocess_mdz.ts +92 -89
  83. package/src/lib/tsdoc_mdz.ts +1 -1
@@ -44,7 +44,7 @@ export const mdz_opcodes_to_nodes = (opcodes) => {
44
44
  start_number: op.start_number,
45
45
  number: op.number,
46
46
  align: op.align,
47
- header: op.header,
47
+ header: op.header
48
48
  });
49
49
  break;
50
50
  }
@@ -180,7 +180,7 @@ export const mdz_opcodes_to_nodes = (opcodes) => {
180
180
  type: 'Text',
181
181
  content: trimmed_content,
182
182
  start: text_node.end,
183
- end: text_node.end + trimmed_content.length,
183
+ end: text_node.end + trimmed_content.length
184
184
  };
185
185
  text_nodes.set(op.trim_id, trimmed_node);
186
186
  }
@@ -191,7 +191,7 @@ export const mdz_opcodes_to_nodes = (opcodes) => {
191
191
  children: [text_node],
192
192
  link_type: op.link_type,
193
193
  start: op.start,
194
- end: op.end,
194
+ end: op.end
195
195
  };
196
196
  // replace text node with [Link, trimmed?] in the buffer
197
197
  if (trimmed_node) {
@@ -250,7 +250,12 @@ const insert_replacement = (children, stack, reverted_idx, at, op) => {
250
250
  }
251
251
  }
252
252
  // 3. standalone Text node
253
- const node = { type: 'Text', content: text, start: op.start, end: op.start + text.length };
253
+ const node = {
254
+ type: 'Text',
255
+ content: text,
256
+ start: op.start,
257
+ end: op.start + text.length
258
+ };
254
259
  if (at >= children.length) {
255
260
  children.push(node);
256
261
  }
@@ -284,7 +289,7 @@ const build_node = (frame, frame_children) => {
284
289
  type: 'Paragraph',
285
290
  children,
286
291
  start: children[0].start,
287
- end: children[children.length - 1].end,
292
+ end: children[children.length - 1].end
288
293
  };
289
294
  }
290
295
  case 'Heading': {
@@ -296,7 +301,7 @@ const build_node = (frame, frame_children) => {
296
301
  id,
297
302
  children,
298
303
  start: frame.start,
299
- end: frame.end,
304
+ end: frame.end
300
305
  };
301
306
  }
302
307
  case 'Bold':
@@ -304,21 +309,21 @@ const build_node = (frame, frame_children) => {
304
309
  type: 'Bold',
305
310
  children: mdz_merge_adjacent_text(frame_children),
306
311
  start: frame.start,
307
- end: frame.end,
312
+ end: frame.end
308
313
  };
309
314
  case 'Italic':
310
315
  return {
311
316
  type: 'Italic',
312
317
  children: mdz_merge_adjacent_text(frame_children),
313
318
  start: frame.start,
314
- end: frame.end,
319
+ end: frame.end
315
320
  };
316
321
  case 'Strikethrough':
317
322
  return {
318
323
  type: 'Strikethrough',
319
324
  children: mdz_merge_adjacent_text(frame_children),
320
325
  start: frame.start,
321
- end: frame.end,
326
+ end: frame.end
322
327
  };
323
328
  case 'Link':
324
329
  return {
@@ -327,7 +332,7 @@ const build_node = (frame, frame_children) => {
327
332
  children: mdz_merge_adjacent_text(frame_children),
328
333
  link_type: frame.link_type ?? 'internal',
329
334
  start: frame.start,
330
- end: frame.end,
335
+ end: frame.end
331
336
  };
332
337
  case 'List': {
333
338
  // items are the only possible children; `end` derives from the last
@@ -341,7 +346,7 @@ const build_node = (frame, frame_children) => {
341
346
  start_number: frame.start_number ?? 1,
342
347
  children,
343
348
  start: frame.start,
344
- end,
349
+ end
345
350
  };
346
351
  }
347
352
  return { type: 'List', ordered: false, children, start: frame.start, end };
@@ -375,7 +380,7 @@ const build_node = (frame, frame_children) => {
375
380
  header: frame.header ?? false,
376
381
  children,
377
382
  start: frame.start,
378
- end: frame.end,
383
+ end: frame.end
379
384
  };
380
385
  }
381
386
  case 'TableCell':
@@ -383,7 +388,7 @@ const build_node = (frame, frame_children) => {
383
388
  type: 'TableCell',
384
389
  children: mdz_merge_adjacent_text(frame_children),
385
390
  start: frame.start,
386
- end: frame.end,
391
+ end: frame.end
387
392
  };
388
393
  case 'Code': {
389
394
  // optimistic inline code container — concatenate children text into leaf MdzNodeCode
@@ -396,7 +401,7 @@ const build_node = (frame, frame_children) => {
396
401
  type: 'Code',
397
402
  content,
398
403
  start: frame.start,
399
- end: frame.end,
404
+ end: frame.end
400
405
  };
401
406
  }
402
407
  case 'Codeblock': {
@@ -411,7 +416,7 @@ const build_node = (frame, frame_children) => {
411
416
  lang: frame.lang ?? null,
412
417
  content,
413
418
  start: frame.start,
414
- end: frame.end,
419
+ end: frame.end
415
420
  };
416
421
  }
417
422
  case 'Element':
@@ -420,7 +425,7 @@ const build_node = (frame, frame_children) => {
420
425
  name: frame.name ?? '',
421
426
  children: mdz_merge_adjacent_text(frame_children),
422
427
  start: frame.start,
423
- end: frame.end,
428
+ end: frame.end
424
429
  };
425
430
  case 'Component':
426
431
  return {
@@ -428,7 +433,7 @@ const build_node = (frame, frame_children) => {
428
433
  name: frame.name ?? '',
429
434
  children: mdz_merge_adjacent_text(frame_children),
430
435
  start: frame.start,
431
- end: frame.end,
436
+ end: frame.end
432
437
  };
433
438
  default:
434
439
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"mdz_stream_parser.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/mdz_stream_parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,kBAAkB,CAAC;AAiFhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,qBAAa,eAAe;;IAG3B;;;OAGG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIzB;;;;;;;;;;;;;;;OAeG;IACH,MAAM,IAAI,IAAI;IAId;;;OAGG;IACH,YAAY,IAAI,KAAK,CAAC,SAAS,CAAC;CAKhC"}
1
+ {"version":3,"file":"mdz_stream_parser.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/mdz_stream_parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAiFlD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,qBAAa,eAAe;;IAG3B;;;OAGG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIzB;;;;;;;;;;;;;;;OAeG;IACH,MAAM,IAAI,IAAI;IAId;;;OAGG;IACH,YAAY,IAAI,KAAK,CAAC,SAAS,CAAC;CAKhC"}
@@ -34,14 +34,14 @@
34
34
  *
35
35
  * @module
36
36
  */
37
- import { BACKTICK, ASTERISK, UNDERSCORE, TILDE, NEWLINE, HYPHEN, HASH, PIPE, LEFT_ANGLE, RIGHT_ANGLE, SLASH, LEFT_BRACKET, RIGHT_BRACKET, H_LOWER, H_UPPER, PERIOD, SPACE, ZERO, NINE, is_word_char, is_line_whitespace, mdz_match_blockquote_prefix, mdz_blockquote_line_has_content, mdz_blockquote_strip_width, mdz_remap_segments, } from './mdz_helpers.js';
38
- import { accumulate_text, alloc_id, close_all_list_levels, close_codeblock_at_eof, close_heading, close_paragraph, create_state, emit, find_open, flush_text, handle_paragraph_break, offset, pop_stack_entry, push_stack_entry, revert_failed_close, } from './mdz_stream_parser_state.js';
39
- import { process_codeblock, process_codeblock_forced, process_codeblock_in_item, try_codeblock_open, try_heading, try_hr, } from './mdz_stream_parser_block.js';
37
+ import { BACKTICK, ASTERISK, UNDERSCORE, TILDE, NEWLINE, HYPHEN, HASH, PIPE, LEFT_ANGLE, RIGHT_ANGLE, SLASH, LEFT_BRACKET, RIGHT_BRACKET, H_LOWER, H_UPPER, PERIOD, SPACE, ZERO, NINE, is_word_char, is_line_whitespace, mdz_match_blockquote_prefix, mdz_blockquote_line_has_content, mdz_blockquote_strip_width, mdz_remap_segments } from './mdz_helpers.js';
38
+ import { accumulate_text, alloc_id, close_all_list_levels, close_codeblock_at_eof, close_heading, close_paragraph, create_state, emit, find_open, flush_text, handle_paragraph_break, offset, pop_stack_entry, push_stack_entry, revert_failed_close } from './mdz_stream_parser_state.js';
39
+ import { process_codeblock, process_codeblock_forced, process_codeblock_in_item, try_codeblock_open, try_heading, try_hr } from './mdz_stream_parser_block.js';
40
40
  import { process_list_line, try_list_start } from './mdz_stream_parser_list.js';
41
41
  import { close_table, process_table_line, try_table_start } from './mdz_stream_parser_table.js';
42
- import { check_close_word_boundary, close_delimiter, process_code_content, try_code, try_double_delimiter, try_italic, } from './mdz_stream_parser_inline.js';
43
- import { try_close_tag, try_complete_link, try_link_open, try_tag_open, } from './mdz_stream_parser_link.js';
44
- import { complete_pending_url, process_url_content, start_speculative_url, try_auto_path_absolute, try_auto_path_relative, try_auto_url_forced, } from './mdz_stream_parser_url.js';
42
+ import { check_close_word_boundary, close_delimiter, process_code_content, try_code, try_double_delimiter, try_italic } from './mdz_stream_parser_inline.js';
43
+ import { try_close_tag, try_complete_link, try_link_open, try_tag_open } from './mdz_stream_parser_link.js';
44
+ import { complete_pending_url, process_url_content, start_speculative_url, try_auto_path_absolute, try_auto_path_relative, try_auto_url_forced } from './mdz_stream_parser_url.js';
45
45
  import { consume_delimiter_as_text, consume_text_run } from './mdz_stream_parser_text.js';
46
46
  /**
47
47
  * Streaming opcode parser for mdz content.
@@ -207,7 +207,7 @@ const open_blockquote = (state, item_indent) => {
207
207
  segments: [{ inner_start: 0, source_start: offset(state, strip) }],
208
208
  inner_len: 0,
209
209
  text_inner_ends: new Map(),
210
- item_indent,
210
+ item_indent
211
211
  };
212
212
  state.pos = strip;
213
213
  state.prev_char = SPACE;
@@ -361,7 +361,7 @@ const process_blockquote = (state, forced) => {
361
361
  const strip = first + mdz_blockquote_strip_width(buffer, first);
362
362
  blockquote.segments.push({
363
363
  inner_start: blockquote.inner_len,
364
- source_start: offset(state, strip),
364
+ source_start: offset(state, strip)
365
365
  });
366
366
  state.pos = strip;
367
367
  state.column = strip - line_start;
@@ -6,8 +6,8 @@
6
6
  *
7
7
  * @module
8
8
  */
9
- import { BACKTICK, HASH, HR_HYPHEN_COUNT, HYPHEN, MAX_HEADING_LEVEL, MIN_CODEBLOCK_BACKTICKS, NEWLINE, SPACE, is_line_whitespace, } from './mdz_helpers.js';
10
- import { alloc_id, close_paragraph, emit, flush_text, offset, push_stack_entry, } from './mdz_stream_parser_state.js';
9
+ import { BACKTICK, HASH, HR_HYPHEN_COUNT, HYPHEN, MAX_HEADING_LEVEL, MIN_CODEBLOCK_BACKTICKS, NEWLINE, SPACE, is_line_whitespace } from './mdz_helpers.js';
10
+ import { alloc_id, close_paragraph, emit, flush_text, offset, push_stack_entry } from './mdz_stream_parser_state.js';
11
11
  /**
12
12
  * Try to parse a heading at column 0.
13
13
  *
@@ -55,7 +55,7 @@ export const try_heading = (state) => {
55
55
  id,
56
56
  node_type: 'Heading',
57
57
  start: heading_start,
58
- level: hash_count,
58
+ level: hash_count
59
59
  });
60
60
  push_stack_entry(state, id, 'Heading', heading_start);
61
61
  state.in_heading = true;
@@ -103,7 +103,7 @@ export const try_hr = (state, forced = false) => {
103
103
  id,
104
104
  node_type: 'Hr',
105
105
  start: offset(state, start),
106
- end: offset(state, i),
106
+ end: offset(state, i)
107
107
  });
108
108
  // `i` sits at the line's newline, or at the buffer end — in forced mode
109
109
  // always the buffer end (a newline would have resolved this line during
@@ -193,7 +193,7 @@ export const emit_codeblock_text = (state, cb, content, content_start) => {
193
193
  content,
194
194
  text_type: 'Text',
195
195
  start: text_start,
196
- end: text_start + content.length,
196
+ end: text_start + content.length
197
197
  });
198
198
  cb.text_id = id;
199
199
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mdz_stream_parser_inline.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/mdz_stream_parser_inline.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,EACN,KAAK,oBAAoB,EAYzB,MAAM,8BAA8B,CAAC;AA6GtC;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAChC,OAAO,oBAAoB,EAC3B,WAAW,IAAI,GAAG,IAAI,EACtB,WAAW,MAAM,GAAG,eAAe,EACnC,gBAAc,KACZ,OA2BF,CAAC;AAIF;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,oBAAoB,EAAE,gBAAc,KAAG,OAyCxE,CAAC;AAIF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,yBAAyB,GAAI,OAAO,oBAAoB,KAAG,OAOvE,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,oBAAoB,EAAE,WAAW,MAAM,KAAG,OAuBhF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,oBAAoB,GAChC,OAAO,oBAAoB,EAC3B,gBAAc,KACZ,WAAW,GAAG,UAAU,GAAG,SAmB7B,CAAC;AAIF,cAAc;AACd,eAAO,MAAM,QAAQ,GAAI,OAAO,oBAAoB,EAAE,gBAAc,KAAG,OAoFtE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,oBAAoB,EAAE,MAAM,MAAM,KAAG,MAyB7E,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,GAAI,OAAO,oBAAoB,KAAG,OAO5E,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,oBAAoB,KAAG,IA2ClE,CAAC"}
1
+ {"version":3,"file":"mdz_stream_parser_inline.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/mdz_stream_parser_inline.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,EACN,KAAK,oBAAoB,EAYzB,MAAM,8BAA8B,CAAC;AA6GtC;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAChC,OAAO,oBAAoB,EAC3B,WAAW,IAAI,GAAG,IAAI,EACtB,WAAW,MAAM,GAAG,eAAe,EACnC,gBAAc,KACZ,OA2BF,CAAC;AAIF;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,oBAAoB,EAAE,gBAAc,KAAG,OAyCxE,CAAC;AAIF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,yBAAyB,GAAI,OAAO,oBAAoB,KAAG,OAOvE,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,oBAAoB,EAAE,WAAW,MAAM,KAAG,OAuBhF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,oBAAoB,GAChC,OAAO,oBAAoB,EAC3B,gBAAc,KACZ,WAAW,GAAG,UAAU,GAAG,SAmB7B,CAAC;AAIF,cAAc;AACd,eAAO,MAAM,QAAQ,GAAI,OAAO,oBAAoB,EAAE,gBAAc,KAAG,OAwFtE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,oBAAoB,EAAE,MAAM,MAAM,KAAG,MAyB7E,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,GAAI,OAAO,oBAAoB,KAAG,OAO5E,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,oBAAoB,KAAG,IA2ClE,CAAC"}
@@ -4,8 +4,8 @@
4
4
  *
5
5
  * @module
6
6
  */
7
- import { BACKTICK, NEWLINE, RIGHT_ANGLE, UNDERSCORE, is_line_whitespace, is_word_char, mdz_blockquote_line_has_content, mdz_match_blockquote_prefix, } from './mdz_helpers.js';
8
- import { accumulate_text, alloc_id, buffer_index_of, emit, ensure_paragraph, flush_text, is_run_boundary, offset, pop_stack_entry, push_stack_entry, revert_above, } from './mdz_stream_parser_state.js';
7
+ import { BACKTICK, NEWLINE, RIGHT_ANGLE, UNDERSCORE, is_line_whitespace, is_word_char, mdz_blockquote_line_has_content, mdz_match_blockquote_prefix } from './mdz_helpers.js';
8
+ import { accumulate_text, alloc_id, buffer_index_of, emit, ensure_paragraph, flush_text, is_run_boundary, offset, pop_stack_entry, push_stack_entry, revert_above } from './mdz_stream_parser_state.js';
9
9
  import { match_fence_opener, match_list_marker } from './mdz_stream_parser_list.js';
10
10
  import { consume_delimiter_as_text } from './mdz_stream_parser_text.js';
11
11
  /**
@@ -236,7 +236,7 @@ export const close_delimiter = (state, stack_idx) => {
236
236
  type: 'revert',
237
237
  id: entry.id,
238
238
  replacement_text: delimiter,
239
- start: entry.start,
239
+ start: entry.start
240
240
  });
241
241
  accumulate_text(state, delimiter, offset(state));
242
242
  }
@@ -297,15 +297,20 @@ export const scan_closer_boundary = (state, forced = false) => {
297
297
  /** @nodocs */
298
298
  export const try_code = (state, forced = false) => {
299
299
  const start = state.pos;
300
- let i = start + 1; // past opening backtick
300
+ const search_start = start + 1; // past opening backtick
301
301
  // compute search boundary: don't scan past open formatting delimiters
302
- const search_limit = code_search_limit(state, start + 1);
303
- // scan for closing backtick (must be before newline and search boundary)
304
- while (i < state.buffer.length && i < search_limit) {
305
- const c = state.buffer.charCodeAt(i);
306
- if (c === BACKTICK) {
302
+ const search_limit = code_search_limit(state, search_start);
303
+ // find the first closing backtick or newline (memoized — a candidate that
304
+ // holds under open formatting re-enters here on every feed, and a raw scan
305
+ // would re-cover the same growing region each time, going quadratic on a
306
+ // single long line)
307
+ const close_pos = buffer_index_of(state, '`', search_start);
308
+ const newline_pos = buffer_index_of(state, '\n', search_start);
309
+ const terminator = close_pos !== -1 && (newline_pos === -1 || close_pos < newline_pos) ? close_pos : newline_pos;
310
+ if (terminator !== -1 && terminator < search_limit) {
311
+ if (terminator === close_pos) {
307
312
  // found close
308
- const content = state.buffer.slice(start + 1, i);
313
+ const content = state.buffer.slice(search_start, terminator);
309
314
  if (content.length === 0) {
310
315
  // empty code — treat as text
311
316
  consume_delimiter_as_text(state, '``');
@@ -320,20 +325,17 @@ export const try_code = (state, forced = false) => {
320
325
  content,
321
326
  text_type: 'Code',
322
327
  start: offset(state, start),
323
- end: offset(state, i + 1),
328
+ end: offset(state, terminator + 1)
324
329
  });
325
330
  state.active_text_id = null;
326
- state.pos = i + 1;
327
- state.column += i + 1 - start;
331
+ state.pos = terminator + 1;
332
+ state.column += terminator + 1 - start;
328
333
  state.prev_char = BACKTICK;
329
334
  return true;
330
335
  }
331
- if (c === NEWLINE) {
332
- // inline code can't span lines — treat opening backtick as text
333
- consume_delimiter_as_text(state, '`');
334
- return true;
335
- }
336
- i++;
336
+ // newline before any close — inline code can't span lines
337
+ consume_delimiter_as_text(state, '`');
338
+ return true;
337
339
  }
338
340
  // hit search limit (open formatting delimiter boundary) — treat backtick as
339
341
  // text. This is the documented backtick-adjacent divergence point: when the
@@ -341,7 +343,7 @@ export const try_code = (state, forced = false) => {
341
343
  // processed), the one-shot parse rejects that italic and scans unbounded —
342
344
  // see the `MdzStreamParser` TSDoc and the parity suite's expected-divergence
343
345
  // battery
344
- if (i < state.buffer.length && i >= search_limit) {
346
+ if (search_limit < state.buffer.length) {
345
347
  consume_delimiter_as_text(state, '`');
346
348
  return true;
347
349
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mdz_stream_parser_link.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/mdz_stream_parser_link.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoBH,OAAO,EACN,KAAK,oBAAoB,EACzB,KAAK,SAAS,EAWd,MAAM,8BAA8B,CAAC;AAItC,cAAc;AACd,eAAO,MAAM,aAAa,GAAI,OAAO,oBAAoB,KAAG,OAa3D,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAC9B,OAAO,oBAAoB,EAC3B,gBAAgB,MAAM,EACtB,aAAa,MAAM,KACjB,IAUF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,oBAAoB,EAAE,gBAAgB,MAAM,KAAG,OAwEvF,CAAC;AAIF,cAAc;AACd,eAAO,MAAM,YAAY,GAAI,OAAO,oBAAoB,KAAG,SAyE1D,CAAC;AAEF,cAAc;AACd,eAAO,MAAM,aAAa,GAAI,OAAO,oBAAoB,KAAG,SA0C3D,CAAC"}
1
+ {"version":3,"file":"mdz_stream_parser_link.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/mdz_stream_parser_link.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoBH,OAAO,EACN,KAAK,oBAAoB,EACzB,KAAK,SAAS,EAYd,MAAM,8BAA8B,CAAC;AAMtC,cAAc;AACd,eAAO,MAAM,aAAa,GAAI,OAAO,oBAAoB,KAAG,OAoB3D,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAC9B,OAAO,oBAAoB,EAC3B,gBAAgB,MAAM,EACtB,aAAa,MAAM,KACjB,IAUF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,oBAAoB,EAAE,gBAAgB,MAAM,KAAG,OA4EvF,CAAC;AAIF,cAAc;AACd,eAAO,MAAM,YAAY,GAAI,OAAO,oBAAoB,KAAG,SAqF1D,CAAC;AAEF,cAAc;AACd,eAAO,MAAM,aAAa,GAAI,OAAO,oBAAoB,KAAG,SAiD3D,CAAC"}
@@ -4,11 +4,20 @@
4
4
  *
5
5
  * @module
6
6
  */
7
- import { A_UPPER, LEFT_BRACKET, LEFT_PAREN, NEWLINE, RIGHT_ANGLE, RIGHT_BRACKET, RIGHT_PAREN, SLASH, SPACE, Z_UPPER, is_letter, is_tag_name_char, is_valid_path_char, mdz_is_safe_reference, mdz_is_url, } from './mdz_helpers.js';
8
- import { accumulate_text, alloc_id, emit, ensure_paragraph, flush_text, is_run_boundary, offset, pop_stack_entry, push_stack_entry, revert_above, } from './mdz_stream_parser_state.js';
7
+ import { A_UPPER, LEFT_BRACKET, LEFT_PAREN, MAX_INLINE_NESTING_DEPTH, RIGHT_ANGLE, RIGHT_BRACKET, RIGHT_PAREN, SLASH, SPACE, Z_UPPER, is_letter, is_tag_name_char, is_valid_path_char, mdz_is_safe_reference, mdz_is_url } from './mdz_helpers.js';
8
+ import { accumulate_text, alloc_id, buffer_index_of, emit, ensure_paragraph, flush_text, is_run_boundary, offset, pop_stack_entry, push_stack_entry, revert_above } from './mdz_stream_parser_state.js';
9
+ import { consume_delimiter_as_text } from './mdz_stream_parser_text.js';
10
+ import { mdz_debug_work } from './mdz_debug_work.js';
9
11
  // -- Links --
10
12
  /** @nodocs */
11
13
  export const try_link_open = (state) => {
14
+ // nesting-depth cap: too deep to open — render `[` literal, matching the
15
+ // sync lexer's `#tokenize_markdown_link` cap (keeps the two parsers agreeing
16
+ // on where deep `[` stops nesting)
17
+ if (state.open_link_tag_depth >= MAX_INLINE_NESTING_DEPTH) {
18
+ consume_delimiter_as_text(state, '[');
19
+ return true;
20
+ }
12
21
  flush_text(state);
13
22
  ensure_paragraph(state);
14
23
  const id = alloc_id(state);
@@ -55,63 +64,67 @@ export const try_complete_link = (state, link_stack_idx) => {
55
64
  abort_link_to_text(state, link_stack_idx, bracket_pos);
56
65
  return true;
57
66
  }
58
- // found ]( — scan for )
59
- let i = bracket_pos + 2; // past ](
60
- while (i < state.buffer.length) {
61
- const c = state.buffer.charCodeAt(i);
62
- if (c === RIGHT_PAREN) {
63
- const reference = state.buffer.slice(bracket_pos + 2, i);
64
- // validate reference: non-empty and only valid path chars
65
- if (!reference.trim()) {
66
- abort_link_to_text(state, link_stack_idx, bracket_pos);
67
- return true;
68
- }
69
- let valid = true;
70
- for (let j = 0; j < reference.length; j++) {
71
- if (!is_valid_path_char(reference.charCodeAt(j))) {
72
- valid = false;
73
- break;
74
- }
75
- }
76
- if (!valid) {
77
- abort_link_to_text(state, link_stack_idx, bracket_pos);
78
- return true;
79
- }
80
- // Reject unsafe protocols (javascript:, data:, etc.) at parse time.
81
- // `is_valid_path_char` permits `:` so we have to filter explicitly.
82
- if (!mdz_is_safe_reference(reference)) {
83
- abort_link_to_text(state, link_stack_idx, bracket_pos);
84
- return true;
85
- }
86
- // success — close the link with reference
87
- flush_text(state);
88
- revert_above(state, link_stack_idx);
89
- const entry = pop_stack_entry(state);
90
- const link_type = mdz_is_url(reference) ? 'external' : 'internal';
91
- emit(state, {
92
- type: 'close',
93
- id: entry.id,
94
- end: offset(state, i + 1),
95
- reference,
96
- link_type,
97
- });
98
- state.active_text_id = null;
99
- state.pos = i + 1;
100
- state.column += i + 1 - bracket_pos;
101
- state.prev_char = RIGHT_PAREN;
67
+ // found ]( — find the reference's terminator: `)` completes, a space or
68
+ // newline aborts. Memoized searches (see `buffer_index_of`) — a link whose
69
+ // URL arrives incrementally re-enters here on every feed with `pos` still
70
+ // at the `]`, and a raw scan would re-cover the growing reference each
71
+ // time, going quadratic on long streamed URLs.
72
+ const ref_start = bracket_pos + 2;
73
+ const close_pos = buffer_index_of(state, ')', ref_start);
74
+ const space_pos = buffer_index_of(state, ' ', ref_start);
75
+ const newline_pos = buffer_index_of(state, '\n', ref_start);
76
+ let invalid_pos = space_pos;
77
+ if (newline_pos !== -1 && (invalid_pos === -1 || newline_pos < invalid_pos)) {
78
+ invalid_pos = newline_pos;
79
+ }
80
+ if (close_pos === -1) {
81
+ // didn't find ) — need more input or invalid
82
+ if (invalid_pos === -1)
83
+ return false; // need more input
84
+ // found invalid char before any ) — revert
85
+ abort_link_to_text(state, link_stack_idx, bracket_pos);
86
+ return true;
87
+ }
88
+ if (invalid_pos !== -1 && invalid_pos < close_pos) {
89
+ // invalid character in URL (simplified check)
90
+ abort_link_to_text(state, link_stack_idx, bracket_pos);
91
+ return true;
92
+ }
93
+ const i = close_pos;
94
+ const reference = state.buffer.slice(ref_start, i);
95
+ // validate reference: non-empty and only valid path chars
96
+ if (!reference.trim()) {
97
+ abort_link_to_text(state, link_stack_idx, bracket_pos);
98
+ return true;
99
+ }
100
+ for (let j = 0; j < reference.length; j++) {
101
+ if (!is_valid_path_char(reference.charCodeAt(j))) {
102
+ abort_link_to_text(state, link_stack_idx, bracket_pos);
102
103
  return true;
103
104
  }
104
- if (c === NEWLINE || c === SPACE) {
105
- // invalid character in URL (simplified check)
106
- break;
107
- }
108
- i++;
109
105
  }
110
- // didn't find ) — need more input or invalid
111
- if (i >= state.buffer.length)
112
- return false; // need more input
113
- // found invalid char before ) — revert
114
- abort_link_to_text(state, link_stack_idx, bracket_pos);
106
+ // Reject unsafe protocols (javascript:, data:, etc.) at parse time.
107
+ // `is_valid_path_char` permits `:` so we have to filter explicitly.
108
+ if (!mdz_is_safe_reference(reference)) {
109
+ abort_link_to_text(state, link_stack_idx, bracket_pos);
110
+ return true;
111
+ }
112
+ // success — close the link with reference
113
+ flush_text(state);
114
+ revert_above(state, link_stack_idx);
115
+ const entry = pop_stack_entry(state);
116
+ const link_type = mdz_is_url(reference) ? 'external' : 'internal';
117
+ emit(state, {
118
+ type: 'close',
119
+ id: entry.id,
120
+ end: offset(state, i + 1),
121
+ reference,
122
+ link_type
123
+ });
124
+ state.active_text_id = null;
125
+ state.pos = i + 1;
126
+ state.column += i + 1 - bracket_pos;
127
+ state.prev_char = RIGHT_PAREN;
115
128
  return true;
116
129
  };
117
130
  // -- Tags --
@@ -129,7 +142,18 @@ export const try_tag_open = (state) => {
129
142
  if (!is_letter(state.buffer.charCodeAt(i))) {
130
143
  return 'not_match';
131
144
  }
145
+ // nesting-depth cap: `<letter…` is a tag open, but we're too deep to nest —
146
+ // render `<` literal, matching the sync lexer's `#tokenize_tag` cap. Checked
147
+ // after the closer/hold cases above (a `</…>` closer still closes; a `<` at
148
+ // the buffer end still holds), so only genuine opens are suppressed.
149
+ if (state.open_link_tag_depth >= MAX_INLINE_NESTING_DEPTH) {
150
+ consume_delimiter_as_text(state, '<');
151
+ return 'consumed';
152
+ }
132
153
  // collect tag name
154
+ // TODO the name/whitespace scans rescan from `start` on every held retry
155
+ // of an unclosed tag's open tail — needs a hold watermark; a length cap would
156
+ // diverge from the sync parser on pathological multi-KB "tag names"
133
157
  const name_start = i;
134
158
  while (i < state.buffer.length && is_tag_name_char(state.buffer.charCodeAt(i))) {
135
159
  i++;
@@ -201,9 +225,17 @@ export const try_close_tag = (state) => {
201
225
  return 'not_match';
202
226
  const name = state.buffer.slice(name_start, i);
203
227
  i++; // past >
228
+ // O(1) bail when no tag of this name is open — without it, every `</name>`
229
+ // candidate walks the whole inline stack, which grows one frame per leaked
230
+ // unclosed `<Tag>` and goes quadratic on tag-dense input (the same shape
231
+ // `open_counts` guards for the delimiter inlines)
232
+ if (!state.open_tag_counts?.get(name))
233
+ return 'not_match';
204
234
  // find matching open tag on stack
205
235
  let found_idx = -1;
206
236
  for (let j = state.stack.length - 1; j >= 0; j--) {
237
+ if (mdz_debug_work.enabled)
238
+ mdz_debug_work.total++; // frames walked (mismatched-tags guard)
207
239
  const entry = state.stack[j];
208
240
  if ((entry.node_type === 'Element' || entry.node_type === 'Component') &&
209
241
  entry.tag_name === name) {
@@ -1 +1 @@
1
- {"version":3,"file":"mdz_stream_parser_list.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/mdz_stream_parser_list.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAmBH,OAAO,EACN,KAAK,oBAAoB,EACzB,KAAK,SAAS,EAad,MAAM,8BAA8B,CAAC;AAEtC;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;CACf;AAoBD;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,GAC7B,OAAO,oBAAoB,EAC3B,GAAG,MAAM,EACT,QAAQ,OAAO,KACb,mBAAmB,GAAG,SAAS,GAAG,IAsDpC,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,qDAAqD;IACrD,aAAa,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAC9B,OAAO,oBAAoB,EAC3B,GAAG,MAAM,EACT,QAAQ,OAAO,KACb,oBAAoB,GAAG,SAAS,GAAG,IAuBrC,CAAC;AAgGF;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,oBAAoB,EAAE,QAAQ,OAAO,KAAG,SAY7E,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,iBAAiB,GAC7B,OAAO,oBAAoB,EAC3B,QAAQ,OAAO,KACb,OAAO,GAAG,YA+LZ,CAAC"}
1
+ {"version":3,"file":"mdz_stream_parser_list.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/mdz_stream_parser_list.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAmBH,OAAO,EACN,KAAK,oBAAoB,EACzB,KAAK,SAAS,EAad,MAAM,8BAA8B,CAAC;AAEtC;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;CACf;AAoBD;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,GAC7B,OAAO,oBAAoB,EAC3B,GAAG,MAAM,EACT,QAAQ,OAAO,KACb,mBAAmB,GAAG,SAAS,GAAG,IAsDpC,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,qDAAqD;IACrD,aAAa,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAC9B,OAAO,oBAAoB,EAC3B,GAAG,MAAM,EACT,QAAQ,OAAO,KACb,oBAAoB,GAAG,SAAS,GAAG,IAuBrC,CAAC;AAgGF;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,oBAAoB,EAAE,QAAQ,OAAO,KAAG,SAY7E,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,iBAAiB,GAC7B,OAAO,oBAAoB,EAC3B,QAAQ,OAAO,KACb,OAAO,GAAG,YA2MZ,CAAC"}
@@ -12,9 +12,9 @@
12
12
  *
13
13
  * @module
14
14
  */
15
- import { BACKTICK, HYPHEN, MAX_LIST_NUMBER_DIGITS, MIN_CODEBLOCK_BACKTICKS, NEWLINE, NINE, PERIOD, PIPE, RIGHT_ANGLE, SPACE, ZERO, is_line_whitespace, mdz_match_blockquote_prefix, mdz_blockquote_line_has_content, } from './mdz_helpers.js';
15
+ import { BACKTICK, HYPHEN, MAX_LIST_NUMBER_DIGITS, MIN_CODEBLOCK_BACKTICKS, NEWLINE, NINE, PERIOD, PIPE, RIGHT_ANGLE, SPACE, ZERO, is_line_whitespace, mdz_match_blockquote_prefix, mdz_blockquote_line_has_content } from './mdz_helpers.js';
16
16
  import { match_table_in_item_head, open_table_in_item } from './mdz_stream_parser_table.js';
17
- import { accumulate_text, alloc_id, close_all_list_levels, close_list_item, close_list_level, close_list_run, close_paragraph, emit, extend_accumulated_end, flush_text, offset, push_stack_entry, } from './mdz_stream_parser_state.js';
17
+ import { accumulate_text, alloc_id, close_all_list_levels, close_list_item, close_list_level, close_list_run, close_paragraph, emit, extend_accumulated_end, flush_text, offset, push_stack_entry } from './mdz_stream_parser_state.js';
18
18
  /**
19
19
  * Whether only line whitespace remains between `from` and the line's end —
20
20
  * `'pending'` when the buffer ends inside the run while streaming (the line
@@ -53,7 +53,7 @@ export const match_list_marker = (state, i, forced) => {
53
53
  start: i,
54
54
  marker_end: after,
55
55
  content_start: after,
56
- empty: true,
56
+ empty: true
57
57
  };
58
58
  }
59
59
  // in bounds: `blank === false` means the scan found a char at or past `after`
@@ -88,7 +88,7 @@ export const match_list_marker = (state, i, forced) => {
88
88
  start: i,
89
89
  marker_end: after,
90
90
  content_start: after,
91
- empty: true,
91
+ empty: true
92
92
  };
93
93
  }
94
94
  // in bounds: `blank === false` means the scan found a char at or past `after`
@@ -168,7 +168,7 @@ const open_list_level = (state, indent, marker) => {
168
168
  node_type: 'List',
169
169
  start,
170
170
  ordered: true,
171
- start_number: marker.number,
171
+ start_number: marker.number
172
172
  });
173
173
  }
174
174
  else {
@@ -334,8 +334,16 @@ export const process_list_line = (state, forced) => {
334
334
  }
335
335
  if (marker !== null && marker.empty) {
336
336
  // empty item: only at an indent exactly matching an open level of the
337
- // same marker type — anything else degrades below
338
- const level_idx = state.list_levels.findIndex((l) => l.indent === indent && l.ordered === marker.ordered);
337
+ // same marker type — anything else degrades below (manual loop like
338
+ // `list_continuation_target` — no per-line closure allocation)
339
+ let level_idx = -1;
340
+ for (let li = 0; li < state.list_levels.length; li++) {
341
+ const l = state.list_levels[li];
342
+ if (l.indent === indent && l.ordered === marker.ordered) {
343
+ level_idx = li;
344
+ break;
345
+ }
346
+ }
339
347
  if (level_idx !== -1) {
340
348
  close_list_run(state);
341
349
  while (state.list_levels.length - 1 > level_idx) {
@@ -370,13 +378,19 @@ export const process_list_line = (state, forced) => {
370
378
  }
371
379
  const id = alloc_id(state);
372
380
  const cb_start = offset(state, j);
373
- emit(state, { type: 'open', id, node_type: 'Codeblock', start: cb_start, lang: fence.lang });
381
+ emit(state, {
382
+ type: 'open',
383
+ id,
384
+ node_type: 'Codeblock',
385
+ start: cb_start,
386
+ lang: fence.lang
387
+ });
374
388
  state.codeblock = {
375
389
  id,
376
390
  backtick_count: fence.backtick_count,
377
391
  text_id: null,
378
392
  fence_indent: indent,
379
- start: cb_start,
393
+ start: cb_start
380
394
  };
381
395
  state.active_text_id = null;
382
396
  state.pos = fence.content_start;