@vectojs/markdown 0.10.0 → 0.12.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.
@@ -45,6 +45,8 @@ export declare class CodeBlock extends UIComponent {
45
45
  private rawLines;
46
46
  private cellWidth;
47
47
  private source;
48
+ /** Bumped by {@link buildLines} and {@link setSelectable}; read by `Scene`. */
49
+ private contentEpoch;
48
50
  private lang;
49
51
  private theme;
50
52
  private lineH;
@@ -56,6 +58,7 @@ export declare class CodeBlock extends UIComponent {
56
58
  setCode(code: string, lang?: string): this;
57
59
  /** Enable or disable browser-native selection for this code block. */
58
60
  setSelectable(selectable: boolean): this;
61
+ getContentEpoch(): number;
59
62
  /**
60
63
  * Change the block's box width.
61
64
  *
@@ -542,6 +545,71 @@ export declare class Markdown extends UIComponent {
542
545
  private paragraphImage;
543
546
  /** One table cell entity, shared by the render arm and the streamed-table path. */
544
547
  private tableCellRichText;
548
+ /**
549
+ * Token types a list item's fast path can render as one `RichText`.
550
+ *
551
+ * An ALLOWLIST, deliberately, following `markstream-vue`'s
552
+ * `SIMPLE_INLINE_TYPES` (`SimpleInlineRenderer/simpleInline.ts:15-31`): a block
553
+ * type is excluded by OMISSION, so a token this renderer has never heard of
554
+ * falls out of the fast path automatically instead of being silently flattened
555
+ * to its raw text. A denylist fails the other way, and the failure is quiet —
556
+ * a formula painted as literal TeX rather than an error — which is why this
557
+ * defect survived so long.
558
+ *
559
+ * Deliberately small, because a list item's DIRECT children are far less varied
560
+ * than they look. Probed against marked 18.0.7: every inline construct
561
+ * (`strong`, `em`, `del`, `codespan`, `link`, `image`, `br`, `escape`, `html`,
562
+ * `inlineMath`) arrives nested one level DEEPER, inside a container whose own
563
+ * type is `text` — so a tight item's direct child list is `text` and nothing
564
+ * else. Listing those inline types here would be dead code.
565
+ *
566
+ * `space` and `checkbox` are included because both are inert here. A blank line
567
+ * between an item's paragraph and its block sibling produces a `space`, and
568
+ * marked unshifts a `checkbox` into every TIGHT GFM task item — the box itself
569
+ * is drawn from `item.task`/`item.checked` by `listItemSpans`, so the token
570
+ * renders nothing on its own. Omitting `checkbox` sent every task item down the
571
+ * block path and moved its marker into a nested entity, which broke four
572
+ * task-list assertions in `Markdown.test.ts`.
573
+ */
574
+ private static readonly INLINE_ITEM_TOKENS;
575
+ /**
576
+ * Does this item consist purely of inline content?
577
+ *
578
+ * True keeps the single-`RichText` fast path, which is not merely an
579
+ * optimization: `updateStreamedList` reuses `stack.children[i]` by calling
580
+ * `setSpans` on it, so an item that becomes a `Stack` forfeits streamed reuse
581
+ * for its entire list. Only pay for a block container when an item holds a
582
+ * block.
583
+ *
584
+ * A lone `paragraph` counts as inline. A LOOSE list re-lexes every item's
585
+ * inline content from `text` to `paragraph` — adding one blank line anywhere
586
+ * flips `token.loose` for the whole list — so treating a single paragraph as a
587
+ * block would drop the fast path for every item of every loose list, the common
588
+ * shape in real prose, for no rendering benefit.
589
+ */
590
+ private itemIsInlineOnly;
591
+ /**
592
+ * Build a list item that holds block-level children.
593
+ *
594
+ * The item becomes a vertical `Stack`: its leading inline run (carrying the
595
+ * marker) first, then every remaining child rendered through the same
596
+ * `renderToken` the document level uses, indented to clear the marker.
597
+ *
598
+ * Recursing rather than special-casing the types we know about is the point — a
599
+ * display formula, a fence, a table, a blockquote, a nested list, an `hr` and a
600
+ * second paragraph all render exactly as they would at indent 0, and a block
601
+ * type added later works here for free.
602
+ *
603
+ * Only the FIRST child can be the lead. Everything after it becomes a block,
604
+ * including a second `paragraph`: an item's two paragraphs are two blocks, and
605
+ * folding them into the lead run would concatenate them into one line with no
606
+ * separation.
607
+ *
608
+ * The lead `RichText` is emitted even when the item has no inline text, because
609
+ * it carries the marker — an item that is nothing but a formula still shows its
610
+ * bullet or ordinal.
611
+ */
612
+ private listItemBlockStack;
545
613
  private listItemSpans;
546
614
  /** Construct the `RichText` for one list item. */
547
615
  private listItemRichText;
package/dist/index.js CHANGED
@@ -1127,6 +1127,8 @@ var CodeBlock = class extends import_ui.UIComponent {
1127
1127
  rawLines = null;
1128
1128
  cellWidth = 0;
1129
1129
  source;
1130
+ /** Bumped by {@link buildLines} and {@link setSelectable}; read by `Scene`. */
1131
+ contentEpoch = 0;
1130
1132
  lang;
1131
1133
  theme;
1132
1134
  lineH = 24;
@@ -1155,9 +1157,13 @@ var CodeBlock = class extends import_ui.UIComponent {
1155
1157
  /** Enable or disable browser-native selection for this code block. */
1156
1158
  setSelectable(selectable) {
1157
1159
  this.selectable = selectable;
1160
+ this.contentEpoch++;
1158
1161
  this.scene?.markDirty();
1159
1162
  return this;
1160
1163
  }
1164
+ getContentEpoch() {
1165
+ return this.contentEpoch;
1166
+ }
1161
1167
  /**
1162
1168
  * Change the block's box width.
1163
1169
  *
@@ -1225,6 +1231,7 @@ var CodeBlock = class extends import_ui.UIComponent {
1225
1231
  * lands mid-line, so that line's text (and therefore its tokenization) changes.
1226
1232
  */
1227
1233
  buildLines(code) {
1234
+ this.contentEpoch++;
1228
1235
  const rawLines = code.split(/\r\n|\r|\n/);
1229
1236
  const previous = this.rawLines;
1230
1237
  let reusable = 0;
@@ -1524,7 +1531,7 @@ function renderInlineToRichText(tokens, fallbackText, font, color, maxWidth, the
1524
1531
  onLinkClick
1525
1532
  });
1526
1533
  }
1527
- var Markdown = class extends import_ui.UIComponent {
1534
+ var Markdown = class _Markdown extends import_ui.UIComponent {
1528
1535
  content;
1529
1536
  maxWidth;
1530
1537
  theme;
@@ -2573,6 +2580,109 @@ var Markdown = class extends import_ui.UIComponent {
2573
2580
  onLinkClick: this.onLinkClick
2574
2581
  });
2575
2582
  }
2583
+ /**
2584
+ * Token types a list item's fast path can render as one `RichText`.
2585
+ *
2586
+ * An ALLOWLIST, deliberately, following `markstream-vue`'s
2587
+ * `SIMPLE_INLINE_TYPES` (`SimpleInlineRenderer/simpleInline.ts:15-31`): a block
2588
+ * type is excluded by OMISSION, so a token this renderer has never heard of
2589
+ * falls out of the fast path automatically instead of being silently flattened
2590
+ * to its raw text. A denylist fails the other way, and the failure is quiet —
2591
+ * a formula painted as literal TeX rather than an error — which is why this
2592
+ * defect survived so long.
2593
+ *
2594
+ * Deliberately small, because a list item's DIRECT children are far less varied
2595
+ * than they look. Probed against marked 18.0.7: every inline construct
2596
+ * (`strong`, `em`, `del`, `codespan`, `link`, `image`, `br`, `escape`, `html`,
2597
+ * `inlineMath`) arrives nested one level DEEPER, inside a container whose own
2598
+ * type is `text` — so a tight item's direct child list is `text` and nothing
2599
+ * else. Listing those inline types here would be dead code.
2600
+ *
2601
+ * `space` and `checkbox` are included because both are inert here. A blank line
2602
+ * between an item's paragraph and its block sibling produces a `space`, and
2603
+ * marked unshifts a `checkbox` into every TIGHT GFM task item — the box itself
2604
+ * is drawn from `item.task`/`item.checked` by `listItemSpans`, so the token
2605
+ * renders nothing on its own. Omitting `checkbox` sent every task item down the
2606
+ * block path and moved its marker into a nested entity, which broke four
2607
+ * task-list assertions in `Markdown.test.ts`.
2608
+ */
2609
+ static INLINE_ITEM_TOKENS = /* @__PURE__ */ new Set([
2610
+ "text",
2611
+ "space",
2612
+ "checkbox"
2613
+ ]);
2614
+ /**
2615
+ * Does this item consist purely of inline content?
2616
+ *
2617
+ * True keeps the single-`RichText` fast path, which is not merely an
2618
+ * optimization: `updateStreamedList` reuses `stack.children[i]` by calling
2619
+ * `setSpans` on it, so an item that becomes a `Stack` forfeits streamed reuse
2620
+ * for its entire list. Only pay for a block container when an item holds a
2621
+ * block.
2622
+ *
2623
+ * A lone `paragraph` counts as inline. A LOOSE list re-lexes every item's
2624
+ * inline content from `text` to `paragraph` — adding one blank line anywhere
2625
+ * flips `token.loose` for the whole list — so treating a single paragraph as a
2626
+ * block would drop the fast path for every item of every loose list, the common
2627
+ * shape in real prose, for no rendering benefit.
2628
+ */
2629
+ itemIsInlineOnly(item) {
2630
+ const children = item.tokens;
2631
+ if (!children || children.length === 0) return true;
2632
+ if (children.length === 1 && children[0].type === "paragraph") return true;
2633
+ return children.every((child) => _Markdown.INLINE_ITEM_TOKENS.has(child.type));
2634
+ }
2635
+ /**
2636
+ * Build a list item that holds block-level children.
2637
+ *
2638
+ * The item becomes a vertical `Stack`: its leading inline run (carrying the
2639
+ * marker) first, then every remaining child rendered through the same
2640
+ * `renderToken` the document level uses, indented to clear the marker.
2641
+ *
2642
+ * Recursing rather than special-casing the types we know about is the point — a
2643
+ * display formula, a fence, a table, a blockquote, a nested list, an `hr` and a
2644
+ * second paragraph all render exactly as they would at indent 0, and a block
2645
+ * type added later works here for free.
2646
+ *
2647
+ * Only the FIRST child can be the lead. Everything after it becomes a block,
2648
+ * including a second `paragraph`: an item's two paragraphs are two blocks, and
2649
+ * folding them into the lead run would concatenate them into one line with no
2650
+ * separation.
2651
+ *
2652
+ * The lead `RichText` is emitted even when the item has no inline text, because
2653
+ * it carries the marker — an item that is nothing but a formula still shows its
2654
+ * bullet or ordinal.
2655
+ */
2656
+ listItemBlockStack(token, index, availableWidth, t) {
2657
+ const item = token.items[index];
2658
+ const children = item.tokens ?? [];
2659
+ const stack = new import_ui.Stack({ direction: "vertical", gap: 4 });
2660
+ const first = children[0];
2661
+ const leadChildren = first && (first.type === "text" || first.type === "paragraph") ? [first] : [];
2662
+ const leadToken = {
2663
+ ...token,
2664
+ items: token.items.map((it, i) => i === index ? { ...it, tokens: leadChildren } : it)
2665
+ };
2666
+ stack.add(this.listItemRichText(leadToken, index, availableWidth, t));
2667
+ const indent = Math.round(t.fontSize);
2668
+ const childMetrics = {
2669
+ marginBefore: 0,
2670
+ marginAfter: 0,
2671
+ indentStart: indent,
2672
+ availableWidth: Math.max(1, availableWidth - indent)
2673
+ };
2674
+ for (let i = leadChildren.length; i < children.length; i++) {
2675
+ const el = this.renderTokenWithMetrics(children[i], childMetrics);
2676
+ if (!el) continue;
2677
+ const wrapper = new MarkdownContainer();
2678
+ el.x = indent;
2679
+ wrapper.add(el);
2680
+ wrapper.width = el.width + indent;
2681
+ wrapper.height = el.height;
2682
+ stack.add(wrapper);
2683
+ }
2684
+ return stack;
2685
+ }
2576
2686
  listItemSpans(token, index) {
2577
2687
  const item = token.items[index];
2578
2688
  const num = Number(token.start ?? 1) + index;
@@ -2652,18 +2762,23 @@ var Markdown = class extends import_ui.UIComponent {
2652
2762
  const lastRetained = oldToken.items.length - 1;
2653
2763
  for (let i = 0; i < lastRetained; i++) {
2654
2764
  if (oldToken.items[i].text !== newToken.items[i].text) return false;
2765
+ const isStack = stack.children[i] instanceof import_ui.Stack;
2766
+ if (isStack !== !this.itemIsInlineOnly(newToken.items[i])) return false;
2655
2767
  }
2656
2768
  const availableWidth = this.activeBlockMetrics?.availableWidth ?? this.maxWidth;
2657
2769
  const t = this.theme;
2658
2770
  const tailEntity = stack.children[lastRetained];
2659
2771
  if (oldToken.items[lastRetained].text !== newToken.items[lastRetained].text) {
2772
+ if (!this.itemIsInlineOnly(newToken.items[lastRetained])) return false;
2660
2773
  if (!("setSpans" in tailEntity)) return false;
2661
2774
  tailEntity.setSpans(
2662
2775
  this.listItemSpans(newToken, lastRetained)
2663
2776
  );
2664
2777
  }
2665
2778
  for (let i = oldToken.items.length; i < newToken.items.length; i++) {
2666
- stack.add(this.listItemRichText(newToken, i, availableWidth, t));
2779
+ stack.add(
2780
+ this.itemIsInlineOnly(newToken.items[i]) ? this.listItemRichText(newToken, i, availableWidth, t) : this.listItemBlockStack(newToken, i, availableWidth, t)
2781
+ );
2667
2782
  }
2668
2783
  const last = stack.children.at(-1);
2669
2784
  if (last) stack.resizeLastChild(last);
@@ -3427,7 +3542,9 @@ var Markdown = class extends import_ui.UIComponent {
3427
3542
  const listToken = token;
3428
3543
  const listStack = new import_ui.Stack({ direction: "vertical", gap: 6 });
3429
3544
  for (let i = 0; i < listToken.items.length; i++) {
3430
- listStack.add(this.listItemRichText(listToken, i, availableWidth, t));
3545
+ listStack.add(
3546
+ this.itemIsInlineOnly(listToken.items[i]) ? this.listItemRichText(listToken, i, availableWidth, t) : this.listItemBlockStack(listToken, i, availableWidth, t)
3547
+ );
3431
3548
  }
3432
3549
  return listStack;
3433
3550
  }
package/dist/index.mjs CHANGED
@@ -1095,6 +1095,8 @@ var CodeBlock = class extends UIComponent {
1095
1095
  rawLines = null;
1096
1096
  cellWidth = 0;
1097
1097
  source;
1098
+ /** Bumped by {@link buildLines} and {@link setSelectable}; read by `Scene`. */
1099
+ contentEpoch = 0;
1098
1100
  lang;
1099
1101
  theme;
1100
1102
  lineH = 24;
@@ -1123,9 +1125,13 @@ var CodeBlock = class extends UIComponent {
1123
1125
  /** Enable or disable browser-native selection for this code block. */
1124
1126
  setSelectable(selectable) {
1125
1127
  this.selectable = selectable;
1128
+ this.contentEpoch++;
1126
1129
  this.scene?.markDirty();
1127
1130
  return this;
1128
1131
  }
1132
+ getContentEpoch() {
1133
+ return this.contentEpoch;
1134
+ }
1129
1135
  /**
1130
1136
  * Change the block's box width.
1131
1137
  *
@@ -1193,6 +1199,7 @@ var CodeBlock = class extends UIComponent {
1193
1199
  * lands mid-line, so that line's text (and therefore its tokenization) changes.
1194
1200
  */
1195
1201
  buildLines(code) {
1202
+ this.contentEpoch++;
1196
1203
  const rawLines = code.split(/\r\n|\r|\n/);
1197
1204
  const previous = this.rawLines;
1198
1205
  let reusable = 0;
@@ -1492,7 +1499,7 @@ function renderInlineToRichText(tokens, fallbackText, font, color, maxWidth, the
1492
1499
  onLinkClick
1493
1500
  });
1494
1501
  }
1495
- var Markdown = class extends UIComponent {
1502
+ var Markdown = class _Markdown extends UIComponent {
1496
1503
  content;
1497
1504
  maxWidth;
1498
1505
  theme;
@@ -2541,6 +2548,109 @@ var Markdown = class extends UIComponent {
2541
2548
  onLinkClick: this.onLinkClick
2542
2549
  });
2543
2550
  }
2551
+ /**
2552
+ * Token types a list item's fast path can render as one `RichText`.
2553
+ *
2554
+ * An ALLOWLIST, deliberately, following `markstream-vue`'s
2555
+ * `SIMPLE_INLINE_TYPES` (`SimpleInlineRenderer/simpleInline.ts:15-31`): a block
2556
+ * type is excluded by OMISSION, so a token this renderer has never heard of
2557
+ * falls out of the fast path automatically instead of being silently flattened
2558
+ * to its raw text. A denylist fails the other way, and the failure is quiet —
2559
+ * a formula painted as literal TeX rather than an error — which is why this
2560
+ * defect survived so long.
2561
+ *
2562
+ * Deliberately small, because a list item's DIRECT children are far less varied
2563
+ * than they look. Probed against marked 18.0.7: every inline construct
2564
+ * (`strong`, `em`, `del`, `codespan`, `link`, `image`, `br`, `escape`, `html`,
2565
+ * `inlineMath`) arrives nested one level DEEPER, inside a container whose own
2566
+ * type is `text` — so a tight item's direct child list is `text` and nothing
2567
+ * else. Listing those inline types here would be dead code.
2568
+ *
2569
+ * `space` and `checkbox` are included because both are inert here. A blank line
2570
+ * between an item's paragraph and its block sibling produces a `space`, and
2571
+ * marked unshifts a `checkbox` into every TIGHT GFM task item — the box itself
2572
+ * is drawn from `item.task`/`item.checked` by `listItemSpans`, so the token
2573
+ * renders nothing on its own. Omitting `checkbox` sent every task item down the
2574
+ * block path and moved its marker into a nested entity, which broke four
2575
+ * task-list assertions in `Markdown.test.ts`.
2576
+ */
2577
+ static INLINE_ITEM_TOKENS = /* @__PURE__ */ new Set([
2578
+ "text",
2579
+ "space",
2580
+ "checkbox"
2581
+ ]);
2582
+ /**
2583
+ * Does this item consist purely of inline content?
2584
+ *
2585
+ * True keeps the single-`RichText` fast path, which is not merely an
2586
+ * optimization: `updateStreamedList` reuses `stack.children[i]` by calling
2587
+ * `setSpans` on it, so an item that becomes a `Stack` forfeits streamed reuse
2588
+ * for its entire list. Only pay for a block container when an item holds a
2589
+ * block.
2590
+ *
2591
+ * A lone `paragraph` counts as inline. A LOOSE list re-lexes every item's
2592
+ * inline content from `text` to `paragraph` — adding one blank line anywhere
2593
+ * flips `token.loose` for the whole list — so treating a single paragraph as a
2594
+ * block would drop the fast path for every item of every loose list, the common
2595
+ * shape in real prose, for no rendering benefit.
2596
+ */
2597
+ itemIsInlineOnly(item) {
2598
+ const children = item.tokens;
2599
+ if (!children || children.length === 0) return true;
2600
+ if (children.length === 1 && children[0].type === "paragraph") return true;
2601
+ return children.every((child) => _Markdown.INLINE_ITEM_TOKENS.has(child.type));
2602
+ }
2603
+ /**
2604
+ * Build a list item that holds block-level children.
2605
+ *
2606
+ * The item becomes a vertical `Stack`: its leading inline run (carrying the
2607
+ * marker) first, then every remaining child rendered through the same
2608
+ * `renderToken` the document level uses, indented to clear the marker.
2609
+ *
2610
+ * Recursing rather than special-casing the types we know about is the point — a
2611
+ * display formula, a fence, a table, a blockquote, a nested list, an `hr` and a
2612
+ * second paragraph all render exactly as they would at indent 0, and a block
2613
+ * type added later works here for free.
2614
+ *
2615
+ * Only the FIRST child can be the lead. Everything after it becomes a block,
2616
+ * including a second `paragraph`: an item's two paragraphs are two blocks, and
2617
+ * folding them into the lead run would concatenate them into one line with no
2618
+ * separation.
2619
+ *
2620
+ * The lead `RichText` is emitted even when the item has no inline text, because
2621
+ * it carries the marker — an item that is nothing but a formula still shows its
2622
+ * bullet or ordinal.
2623
+ */
2624
+ listItemBlockStack(token, index, availableWidth, t) {
2625
+ const item = token.items[index];
2626
+ const children = item.tokens ?? [];
2627
+ const stack = new Stack({ direction: "vertical", gap: 4 });
2628
+ const first = children[0];
2629
+ const leadChildren = first && (first.type === "text" || first.type === "paragraph") ? [first] : [];
2630
+ const leadToken = {
2631
+ ...token,
2632
+ items: token.items.map((it, i) => i === index ? { ...it, tokens: leadChildren } : it)
2633
+ };
2634
+ stack.add(this.listItemRichText(leadToken, index, availableWidth, t));
2635
+ const indent = Math.round(t.fontSize);
2636
+ const childMetrics = {
2637
+ marginBefore: 0,
2638
+ marginAfter: 0,
2639
+ indentStart: indent,
2640
+ availableWidth: Math.max(1, availableWidth - indent)
2641
+ };
2642
+ for (let i = leadChildren.length; i < children.length; i++) {
2643
+ const el = this.renderTokenWithMetrics(children[i], childMetrics);
2644
+ if (!el) continue;
2645
+ const wrapper = new MarkdownContainer();
2646
+ el.x = indent;
2647
+ wrapper.add(el);
2648
+ wrapper.width = el.width + indent;
2649
+ wrapper.height = el.height;
2650
+ stack.add(wrapper);
2651
+ }
2652
+ return stack;
2653
+ }
2544
2654
  listItemSpans(token, index) {
2545
2655
  const item = token.items[index];
2546
2656
  const num = Number(token.start ?? 1) + index;
@@ -2620,18 +2730,23 @@ var Markdown = class extends UIComponent {
2620
2730
  const lastRetained = oldToken.items.length - 1;
2621
2731
  for (let i = 0; i < lastRetained; i++) {
2622
2732
  if (oldToken.items[i].text !== newToken.items[i].text) return false;
2733
+ const isStack = stack.children[i] instanceof Stack;
2734
+ if (isStack !== !this.itemIsInlineOnly(newToken.items[i])) return false;
2623
2735
  }
2624
2736
  const availableWidth = this.activeBlockMetrics?.availableWidth ?? this.maxWidth;
2625
2737
  const t = this.theme;
2626
2738
  const tailEntity = stack.children[lastRetained];
2627
2739
  if (oldToken.items[lastRetained].text !== newToken.items[lastRetained].text) {
2740
+ if (!this.itemIsInlineOnly(newToken.items[lastRetained])) return false;
2628
2741
  if (!("setSpans" in tailEntity)) return false;
2629
2742
  tailEntity.setSpans(
2630
2743
  this.listItemSpans(newToken, lastRetained)
2631
2744
  );
2632
2745
  }
2633
2746
  for (let i = oldToken.items.length; i < newToken.items.length; i++) {
2634
- stack.add(this.listItemRichText(newToken, i, availableWidth, t));
2747
+ stack.add(
2748
+ this.itemIsInlineOnly(newToken.items[i]) ? this.listItemRichText(newToken, i, availableWidth, t) : this.listItemBlockStack(newToken, i, availableWidth, t)
2749
+ );
2635
2750
  }
2636
2751
  const last = stack.children.at(-1);
2637
2752
  if (last) stack.resizeLastChild(last);
@@ -3395,7 +3510,9 @@ var Markdown = class extends UIComponent {
3395
3510
  const listToken = token;
3396
3511
  const listStack = new Stack({ direction: "vertical", gap: 6 });
3397
3512
  for (let i = 0; i < listToken.items.length; i++) {
3398
- listStack.add(this.listItemRichText(listToken, i, availableWidth, t));
3513
+ listStack.add(
3514
+ this.itemIsInlineOnly(listToken.items[i]) ? this.listItemRichText(listToken, i, availableWidth, t) : this.listItemBlockStack(listToken, i, availableWidth, t)
3515
+ );
3399
3516
  }
3400
3517
  return listStack;
3401
3518
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vectojs/markdown",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },