@mintlify/cli 4.0.1462 → 4.0.1464

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.
@@ -1520,6 +1520,33 @@ function partitionForBlockType(parsed, blockType) {
1520
1520
  var _a;
1521
1521
  return partitionAttrs(parsed, (_a = BLOCK_TYPE_KNOWN_ATTRS[blockType]) !== null && _a !== void 0 ? _a : []);
1522
1522
  }
1523
+ var STRUCTURED_FLOW_COMPONENTS = /* @__PURE__ */ new Map([
1524
+ [BLOCK_TYPES.callout, true],
1525
+ [BLOCK_TYPES.column, true],
1526
+ [BLOCK_TYPES.expandable, true],
1527
+ [BLOCK_TYPES.frame, true],
1528
+ [BLOCK_TYPES.paramField, true],
1529
+ ["Prompt", false],
1530
+ [BLOCK_TYPES.responseField, true],
1531
+ [BLOCK_TYPES.tab, true],
1532
+ [BLOCK_TYPES.update, true],
1533
+ [BLOCK_TYPES.visibility, false],
1534
+ [BLOCK_TYPES.accordion, false],
1535
+ [BLOCK_TYPES.accordionGroup, false],
1536
+ [BLOCK_TYPES.card, false],
1537
+ [BLOCK_TYPES.codeGroup, false],
1538
+ [BLOCK_TYPES.columns, false],
1539
+ [BLOCK_TYPES.requestExample, false],
1540
+ [BLOCK_TYPES.responseExample, false],
1541
+ [BLOCK_TYPES.steps, false],
1542
+ [BLOCK_TYPES.tabs, false]
1543
+ ]);
1544
+ function isContainerOnlyComponent(name, schema2) {
1545
+ var _a;
1546
+ const type2 = schema2.nodes[name];
1547
+ return !!type2 && !type2.isInline && !((_a = type2.spec.group) !== null && _a !== void 0 ? _a : "").split(" ").includes("block");
1548
+ }
1549
+ var withRequiredContent = (nodeType, content) => STRUCTURED_FLOW_COMPONENTS.get(nodeType) && content.length === 0 ? [{ type: "paragraph" }] : content;
1523
1550
  function handleFlowJsx(node, ctx, transformNode2, mapJsxChildren2) {
1524
1551
  if (!node.name)
1525
1552
  return [];
@@ -1530,7 +1557,7 @@ function handleFlowJsx(node, ctx, transformNode2, mapJsxChildren2) {
1530
1557
  }
1531
1558
  }
1532
1559
  function handleFlowJsxInner(node, ctx, transformNode2, mapJsxChildren2) {
1533
- var _a;
1560
+ var _a, _b;
1534
1561
  if (!node.name)
1535
1562
  return [];
1536
1563
  if (/^h[1-6]$/.test(node.name)) {
@@ -1558,7 +1585,7 @@ function handleFlowJsxInner(node, ctx, transformNode2, mapJsxChildren2) {
1558
1585
  return {
1559
1586
  type: BLOCK_TYPES.frame,
1560
1587
  attrs: partitionAttrs(frameAttrs, FRAME_ATTRS),
1561
- content: mapJsxChildren2(node, ctx)
1588
+ content: withRequiredContent(BLOCK_TYPES.frame, mapJsxChildren2(node, ctx))
1562
1589
  };
1563
1590
  }
1564
1591
  const isCallout = CALLOUT_TYPES.includes(node.name);
@@ -1596,13 +1623,13 @@ function handleFlowJsxInner(node, ctx, transformNode2, mapJsxChildren2) {
1596
1623
  if (node.name === BLOCK_TYPES.tree) {
1597
1624
  return handleTree(node);
1598
1625
  }
1599
- if (isCallout || node.name !== BLOCK_TYPES.step && Object.values(BLOCK_TYPES).includes(node.name)) {
1600
- const targetType = isCallout ? BLOCK_TYPES.callout : node.name;
1626
+ const targetType = isCallout ? BLOCK_TYPES.callout : node.name;
1627
+ if ((isCallout || node.name !== BLOCK_TYPES.step && Object.values(BLOCK_TYPES).includes(node.name)) && (ctx.hasGroupParent || !isContainerOnlyComponent(targetType, (_b = ctx.schema) !== null && _b !== void 0 ? _b : mintlifySchema))) {
1601
1628
  const parsedAttrs = parseMdxAttributes(node.attributes);
1602
1629
  return {
1603
1630
  type: targetType,
1604
1631
  attrs: Object.assign(Object.assign({}, isCallout ? parseCalloutAttrs(node.name, parsedAttrs) : partitionForBlockType(parsedAttrs, targetType)), ctx.hasGroupParent && { __hasGroupParent: true }),
1605
- content: mapJsxChildren2(node, ctx)
1632
+ content: withRequiredContent(targetType, mapJsxChildren2(node, ctx))
1606
1633
  };
1607
1634
  }
1608
1635
  if (node.name === "table" && !hasSpannedCell(node) && !hasTableClass(node)) {
@@ -1659,28 +1686,42 @@ function createTitleNode(type2, title, ctx, transformNode2) {
1659
1686
  return Object.assign({ type: type2 }, content.length > 0 ? { content } : {});
1660
1687
  }
1661
1688
  function handleSteps(node, ctx, transformNode2, mapJsxChildren2) {
1662
- const stepChildren = componentChildren(node, BLOCK_TYPES.step);
1663
- const pmStepChildren = stepChildren.map((stepChild, index) => {
1664
- const stepAttrs = parseMdxAttributes(stepChild.attributes);
1665
- const titleText = stepAttrs.title;
1666
- const titleNode = createTitleNode(BLOCK_TYPES.stepTitle, titleText, ctx, transformNode2);
1667
- const bodyContent = mapJsxChildren2(stepChild, ctx);
1668
- const bodyNode = {
1669
- type: BLOCK_TYPES.stepBody,
1670
- content: bodyContent.length > 0 ? bodyContent : [{ type: "paragraph" }]
1671
- };
1672
- return {
1673
- type: BLOCK_TYPES.step,
1674
- attrs: Object.assign(Object.assign(Object.assign({}, partitionAttrs(stepAttrs, STEP_ATTRS, ["title"])), ctx.hasGroupParent && { __hasGroupParent: true }), { __childIndex: index, __isLastInGroup: index === stepChildren.length - 1 }),
1675
- content: [titleNode, bodyNode]
1676
- };
1677
- });
1689
+ const children = flattenJsxParagraphs(node).children;
1690
+ const stepChildren = [];
1691
+ for (const child of children) {
1692
+ if (child.type === "text" && child.value.trim() === "")
1693
+ continue;
1694
+ if (child.type !== "mdxJsxFlowElement" || child.name !== BLOCK_TYPES.step) {
1695
+ return { type: BLOCK_TYPES.unknownTag, attrs: { mdxJsxNode: node } };
1696
+ }
1697
+ stepChildren.push(child);
1698
+ }
1699
+ const pmStepChildren = stepChildren.map((stepChild, index) => handleStep(stepChild, ctx, transformNode2, mapJsxChildren2, {
1700
+ index,
1701
+ isLast: index === stepChildren.length - 1
1702
+ }));
1678
1703
  return {
1679
1704
  type: BLOCK_TYPES.steps,
1680
1705
  attrs: Object.assign(Object.assign({}, partitionAttrs(parseMdxAttributes(node.attributes), [])), ctx.hasGroupParent && { __hasGroupParent: true }),
1681
1706
  content: pmStepChildren
1682
1707
  };
1683
1708
  }
1709
+ function handleStep(node, ctx, transformNode2, mapJsxChildren2, groupPosition) {
1710
+ const stepAttrs = parseMdxAttributes(node.attributes);
1711
+ const titleText = stepAttrs.title;
1712
+ const bodyContent = mapJsxChildren2(node, ctx);
1713
+ return {
1714
+ type: BLOCK_TYPES.step,
1715
+ attrs: Object.assign(Object.assign(Object.assign({}, partitionAttrs(stepAttrs, STEP_ATTRS, ["title"])), ctx.hasGroupParent && { __hasGroupParent: true }), { __childIndex: groupPosition.index, __isLastInGroup: groupPosition.isLast }),
1716
+ content: [
1717
+ createTitleNode(BLOCK_TYPES.stepTitle, titleText, ctx, transformNode2),
1718
+ {
1719
+ type: BLOCK_TYPES.stepBody,
1720
+ content: bodyContent.length > 0 ? bodyContent : [{ type: "paragraph" }]
1721
+ }
1722
+ ]
1723
+ };
1724
+ }
1684
1725
  function handleAccordion(node, ctx, transformNode2, mapJsxChildren2) {
1685
1726
  const attrs2 = parseMdxAttributes(node.attributes);
1686
1727
  const titleText = attrs2.title;
@@ -1740,7 +1781,7 @@ function handleToggleContent(node, ctx, transformNode2, mapJsxChildren2) {
1740
1781
  type: childType,
1741
1782
  attrs: Object.assign(Object.assign({}, partitionChild(parseMdxAttributes(child.attributes))), { __isHidden: index !== 0, __hasGroupParent: true }),
1742
1783
  // We should only set isHidden to false for <Tab />, not the children inside the tab
1743
- content: mapJsxChildren2(child, Object.assign(Object.assign({}, ctx), { hasGroupParent: node.name !== BLOCK_TYPES.tabs, isHidden: node.name === BLOCK_TYPES.tabs ? false : index !== 0 }))
1784
+ content: withRequiredContent(childType, mapJsxChildren2(child, Object.assign(Object.assign({}, ctx), { hasGroupParent: node.name !== BLOCK_TYPES.tabs, isHidden: node.name === BLOCK_TYPES.tabs ? false : index !== 0 })))
1744
1785
  }));
1745
1786
  return {
1746
1787
  type: (_d = node.name) !== null && _d !== void 0 ? _d : BLOCK_TYPES.tabs,
@@ -1748,6 +1789,12 @@ function handleToggleContent(node, ctx, transformNode2, mapJsxChildren2) {
1748
1789
  content: pmChildren
1749
1790
  };
1750
1791
  }
1792
+ if (mapJsxChildren2(node, ctx).length > 0) {
1793
+ return {
1794
+ type: BLOCK_TYPES.unknownTag,
1795
+ attrs: { mdxJsxNode: node }
1796
+ };
1797
+ }
1751
1798
  return {
1752
1799
  type: (_e = node.name) !== null && _e !== void 0 ? _e : BLOCK_TYPES.tabs,
1753
1800
  attrs: partitionWrapper(parseMdxAttributes(node.attributes)),
@@ -1756,25 +1803,14 @@ function handleToggleContent(node, ctx, transformNode2, mapJsxChildren2) {
1756
1803
  }
1757
1804
  function handleColumns(node, ctx, mapJsxChildren2) {
1758
1805
  const attrs2 = partitionAttrs(parseMdxAttributes(node.attributes), COLUMNS_ATTRS);
1759
- const columnChildren = componentChildren(node, BLOCK_TYPES.column);
1760
- if (columnChildren.length > 0) {
1761
- const pmChildren = columnChildren.map((child) => {
1762
- const content = mapJsxChildren2(child, Object.assign(Object.assign({}, ctx), { hasGroupParent: true }));
1763
- return {
1764
- type: BLOCK_TYPES.column,
1765
- content: content.length > 0 ? content : [{ type: "paragraph" }]
1766
- };
1767
- });
1768
- return {
1769
- type: BLOCK_TYPES.columns,
1770
- attrs: Object.assign(Object.assign({}, attrs2), ctx.hasGroupParent && { __hasGroupParent: true }),
1771
- content: pmChildren
1772
- };
1773
- }
1806
+ const content = mapJsxChildren2(node, Object.assign(Object.assign({}, ctx), { hasGroupParent: true })).map((child) => {
1807
+ var _a;
1808
+ return child.type === BLOCK_TYPES.column ? Object.assign(Object.assign({}, child), { content: withRequiredContent(BLOCK_TYPES.column, (_a = child.content) !== null && _a !== void 0 ? _a : []) }) : child;
1809
+ });
1774
1810
  return {
1775
1811
  type: BLOCK_TYPES.columns,
1776
- attrs: attrs2,
1777
- content: mapJsxChildren2(node, ctx)
1812
+ attrs: Object.assign(Object.assign({}, attrs2), ctx.hasGroupParent && { __hasGroupParent: true }),
1813
+ content
1778
1814
  };
1779
1815
  }
1780
1816
  function parseColorItemNode(node) {
@@ -2382,20 +2418,8 @@ function buildMarkdownTableCellContent(children, ctx, transformNode2) {
2382
2418
  return children.flatMap((child) => flattenNodeContent(transformNode2(child, ctx)));
2383
2419
  }
2384
2420
  function handleParagraph(node, ctx, transformNode2, mapChildren2) {
2385
- var _a, _b, _c, _d;
2386
- if (node.children.length === 1 && ((_a = node.children[0]) === null || _a === void 0 ? void 0 : _a.type) === "mdxJsxTextElement" && ((_b = node.children[0]) === null || _b === void 0 ? void 0 : _b.name)) {
2387
- const result = transformNode2(node.children[0], ctx);
2388
- const nodes2 = flattenNodeContent(result);
2389
- const schema3 = (_c = ctx.schema) !== null && _c !== void 0 ? _c : mintlifySchema;
2390
- const allInline = nodes2.length > 0 && nodes2.every((child) => {
2391
- var _a2;
2392
- return ((_a2 = schema3.nodes[child.type]) === null || _a2 === void 0 ? void 0 : _a2.isInline) === true;
2393
- });
2394
- if (allInline) {
2395
- return { type: "paragraph", content: nodes2 };
2396
- }
2397
- return result;
2398
- }
2421
+ var _a;
2422
+ const schema2 = (_a = ctx.schema) !== null && _a !== void 0 ? _a : mintlifySchema;
2399
2423
  const hasImages = node.children.some((child) => child.type === "image" || child.type === "mdxJsxTextElement" && child.name === "img");
2400
2424
  if (hasImages) {
2401
2425
  const hasTextContent = node.children.some((child) => child.type === "text" || child.type === "emphasis" || child.type === "strong" || child.type === "link" || child.type === "inlineCode" || child.type === "delete" || child.type === "mdxJsxTextElement" && child.name !== "img");
@@ -2415,7 +2439,7 @@ function handleParagraph(node, ctx, transformNode2, mapChildren2) {
2415
2439
  }
2416
2440
  }
2417
2441
  }
2418
- return { type: "paragraph", content: content2.filter(Boolean) };
2442
+ return splitParagraphAroundBlocks(content2, schema2);
2419
2443
  }
2420
2444
  const blocks = [];
2421
2445
  for (const child of node.children) {
@@ -2430,7 +2454,6 @@ function handleParagraph(node, ctx, transformNode2, mapChildren2) {
2430
2454
  return blocks.length > 0 ? blocks : [];
2431
2455
  }
2432
2456
  const content = mapChildren2(node, ctx);
2433
- const schema2 = (_d = ctx.schema) !== null && _d !== void 0 ? _d : mintlifySchema;
2434
2457
  if (content.every((child) => isInlineNode(child, schema2))) {
2435
2458
  return { type: "paragraph", content };
2436
2459
  }
@@ -2443,15 +2466,15 @@ function splitParagraphAroundBlocks(content, schema2) {
2443
2466
  });
2444
2467
  }
2445
2468
  function trimParagraph(paragraph) {
2446
- var _a;
2469
+ var _a, _b, _c;
2447
2470
  const content = [...(_a = paragraph.content) !== null && _a !== void 0 ? _a : []];
2448
2471
  const first = content[0];
2449
- if ((first === null || first === void 0 ? void 0 : first.type) === "text" && first.text) {
2472
+ if ((first === null || first === void 0 ? void 0 : first.type) === "text" && first.text && !((_b = first.marks) === null || _b === void 0 ? void 0 : _b.some((mark) => mark.type === "code"))) {
2450
2473
  content[0] = Object.assign(Object.assign({}, first), { text: first.text.replace(/^\s+/, "") });
2451
2474
  }
2452
2475
  const lastIndex = content.length - 1;
2453
2476
  const last = content[lastIndex];
2454
- if ((last === null || last === void 0 ? void 0 : last.type) === "text" && last.text) {
2477
+ if ((last === null || last === void 0 ? void 0 : last.type) === "text" && last.text && !((_c = last.marks) === null || _c === void 0 ? void 0 : _c.some((mark) => mark.type === "code"))) {
2455
2478
  content[lastIndex] = Object.assign(Object.assign({}, last), { text: last.text.replace(/\s+$/, "") });
2456
2479
  }
2457
2480
  return Object.assign(Object.assign({}, paragraph), { content: content.filter((n) => n.type !== "text" || n.text !== "") });
@@ -2520,7 +2543,8 @@ function mdastToPm(mdast, source = "", options) {
2520
2543
  const frontmatter = extractFrontmatter(mdast);
2521
2544
  const context = { source, frontmatter, schema: schema2 };
2522
2545
  visit2(mdast, (node) => {
2523
- if (node.type !== "list" && node.type !== "mdxJsxFlowElement") {
2546
+ const promptNeedsSourcePosition = node.type === "mdxJsxTextElement" && node.name === "Prompt";
2547
+ if (node.type !== "list" && node.type !== "mdxJsxFlowElement" && !promptNeedsSourcePosition) {
2524
2548
  delete node.position;
2525
2549
  }
2526
2550
  });
@@ -2535,7 +2559,7 @@ function mdastToPm(mdast, source = "", options) {
2535
2559
  return { doc, frontmatter };
2536
2560
  }
2537
2561
  function transformNode(node, ctx) {
2538
- var _a, _b, _c;
2562
+ var _a, _b, _c, _d;
2539
2563
  if (!node)
2540
2564
  return [];
2541
2565
  switch (node.type) {
@@ -2632,8 +2656,14 @@ function transformNode(node, ctx) {
2632
2656
  };
2633
2657
  case "yaml":
2634
2658
  return [];
2635
- case "mdxJsxTextElement":
2636
- return handleInlineJsx(node, ctx, mapChildren);
2659
+ case "mdxJsxTextElement": {
2660
+ if (!node.name || !STRUCTURED_FLOW_COMPONENTS.has(node.name) || isContainerOnlyComponent(node.name, (_d = ctx.schema) !== null && _d !== void 0 ? _d : mintlifySchema)) {
2661
+ return handleInlineJsx(node, ctx, mapChildren);
2662
+ }
2663
+ const flowResult = handleFlowJsx(Object.assign(Object.assign({}, node), { type: "mdxJsxFlowElement", children: node.children.length > 0 ? [{ type: "paragraph", children: node.children }] : [] }), ctx, transformNode, mapJsxChildren);
2664
+ const flowNodes = Array.isArray(flowResult) ? flowResult : [flowResult];
2665
+ return flowNodes.length > 0 ? flowResult : handleInlineJsx(node, ctx, mapChildren);
2666
+ }
2637
2667
  case "mdxJsxFlowElement":
2638
2668
  return handleFlowJsx(node, ctx, transformNode, mapJsxChildren);
2639
2669
  case "mdxjsEsm":
@@ -9992,13 +10022,20 @@ function isWordChar(ch) {
9992
10022
  var SerializerState = class {
9993
10023
  constructor(options = {}) {
9994
10024
  var _a, _b, _c, _d;
9995
- this.out = "";
10025
+ this.chunks = [];
10026
+ this.chunkStarts = [];
10027
+ this.outLength = 0;
10028
+ this.tail = "";
10029
+ this.trailingSpaces = 0;
10030
+ this.topLevelLead = null;
9996
10031
  this.delim = "";
9997
10032
  this.closed = false;
9998
10033
  this.inTable = false;
9999
10034
  this.inCodeSection = false;
10000
10035
  this.hasReferenceDefinitions = false;
10001
10036
  this.indentSize = 2;
10037
+ this.sourceMap = null;
10038
+ this.nodePath = [];
10002
10039
  this.options = {
10003
10040
  tightLists: (_a = options.tightLists) !== null && _a !== void 0 ? _a : false,
10004
10041
  indentSize: (_b = options.indentSize) !== null && _b !== void 0 ? _b : 2,
@@ -10008,29 +10045,209 @@ var SerializerState = class {
10008
10045
  this.indentSize = this.options.indentSize;
10009
10046
  this.hasReferenceDefinitions = this.options.hasReferenceDefinitions;
10010
10047
  }
10048
+ /** The serialized output */
10049
+ get out() {
10050
+ var _a;
10051
+ if (this.chunks.length > 1) {
10052
+ const joined = this.chunks.join("");
10053
+ this.chunks = [joined];
10054
+ this.chunkStarts = [0];
10055
+ }
10056
+ return (_a = this.chunks[0]) !== null && _a !== void 0 ? _a : "";
10057
+ }
10058
+ set out(value) {
10059
+ this.chunks = [];
10060
+ this.chunkStarts = [];
10061
+ this.outLength = 0;
10062
+ this.tail = "";
10063
+ this.trailingSpaces = 0;
10064
+ this.append(value);
10065
+ }
10066
+ get length() {
10067
+ return this.outLength;
10068
+ }
10069
+ get trailingSpaceCount() {
10070
+ return this.trailingSpaces;
10071
+ }
10072
+ /** Output written at or after `offset`. */
10073
+ sliceFrom(offset) {
10074
+ var _a, _b;
10075
+ let lo = 0;
10076
+ let hi = this.chunkStarts.length - 1;
10077
+ while (lo < hi) {
10078
+ const mid = lo + hi + 1 >> 1;
10079
+ if (((_a = this.chunkStarts[mid]) !== null && _a !== void 0 ? _a : 0) <= offset)
10080
+ lo = mid;
10081
+ else
10082
+ hi = mid - 1;
10083
+ }
10084
+ const first = this.chunks[lo];
10085
+ if (first === void 0)
10086
+ return "";
10087
+ return first.slice(offset - ((_b = this.chunkStarts[lo]) !== null && _b !== void 0 ? _b : 0)) + this.chunks.slice(lo + 1).join("");
10088
+ }
10089
+ /** Drop the last `count` characters of the output. */
10090
+ truncate(count) {
10091
+ var _a, _b, _c;
10092
+ let remaining = count;
10093
+ while (remaining > 0 && this.chunks.length > 0) {
10094
+ const last = (_a = this.chunks[this.chunks.length - 1]) !== null && _a !== void 0 ? _a : "";
10095
+ if (last.length <= remaining) {
10096
+ remaining -= last.length;
10097
+ this.chunks.pop();
10098
+ this.chunkStarts.pop();
10099
+ } else {
10100
+ this.chunks[this.chunks.length - 1] = last.slice(0, last.length - remaining);
10101
+ remaining = 0;
10102
+ }
10103
+ }
10104
+ this.outLength -= count - remaining;
10105
+ this.tail = "";
10106
+ this.trailingSpaces = 0;
10107
+ for (let i = this.chunks.length - 1; i >= 0 && this.tail.length < 2; i--) {
10108
+ this.tail = (((_b = this.chunks[i]) !== null && _b !== void 0 ? _b : "") + this.tail).slice(-2);
10109
+ }
10110
+ for (let i = this.chunks.length - 1; i >= 0; i--) {
10111
+ const chunk = (_c = this.chunks[i]) !== null && _c !== void 0 ? _c : "";
10112
+ let j = chunk.length;
10113
+ while (j > 0 && chunk.charCodeAt(j - 1) === 32)
10114
+ j--;
10115
+ this.trailingSpaces += chunk.length - j;
10116
+ if (j > 0)
10117
+ break;
10118
+ }
10119
+ }
10120
+ append(content) {
10121
+ if (content.length === 0)
10122
+ return;
10123
+ this.chunkStarts.push(this.outLength);
10124
+ this.chunks.push(content);
10125
+ this.outLength += content.length;
10126
+ this.tail = (this.tail + content).slice(-2);
10127
+ let i = content.length;
10128
+ while (i > 0 && content.charCodeAt(i - 1) === 32)
10129
+ i--;
10130
+ this.trailingSpaces = i === 0 ? this.trailingSpaces + content.length : content.length - i;
10131
+ const lead = this.topLevelLead;
10132
+ if (lead && !lead.content) {
10133
+ let j = 0;
10134
+ while (j < content.length && content.charCodeAt(j) === 10)
10135
+ j++;
10136
+ lead.lead += j;
10137
+ if (j < content.length)
10138
+ lead.content = true;
10139
+ }
10140
+ }
10141
+ beginBlock(index) {
10142
+ if (!this.sourceMap)
10143
+ return 0;
10144
+ this.nodePath.push(index);
10145
+ if (this.nodePath.length === 1)
10146
+ this.topLevelLead = { lead: 0, content: false };
10147
+ return this.outLength;
10148
+ }
10149
+ endBlock(start) {
10150
+ var _a, _b;
10151
+ if (!this.sourceMap)
10152
+ return;
10153
+ if (this.nodePath.length === 1) {
10154
+ const lead = (_b = (_a = this.topLevelLead) === null || _a === void 0 ? void 0 : _a.lead) !== null && _b !== void 0 ? _b : 0;
10155
+ this.topLevelLead = null;
10156
+ this.sourceMap.push({
10157
+ path: [...this.nodePath],
10158
+ start: start + lead,
10159
+ end: this.outLength,
10160
+ kind: "block"
10161
+ });
10162
+ }
10163
+ this.nodePath.pop();
10164
+ }
10165
+ recordTextSuffix(index, length, pmStart, pmEnd) {
10166
+ if (!this.sourceMap || this.inTable)
10167
+ return;
10168
+ this.sourceMap.push({
10169
+ path: [...this.nodePath, index],
10170
+ start: this.outLength - length,
10171
+ end: this.outLength,
10172
+ kind: "text",
10173
+ pmStart,
10174
+ pmEnd
10175
+ });
10176
+ }
10177
+ takeTextSuffix(length) {
10178
+ if (!this.sourceMap || length === 0)
10179
+ return null;
10180
+ const entry = this.sourceMap.at(-1);
10181
+ if ((entry === null || entry === void 0 ? void 0 : entry.kind) !== "text" || entry.end !== this.outLength || entry.end - entry.start < length || entry.pmEnd - entry.pmStart < length) {
10182
+ return null;
10183
+ }
10184
+ const mapping = Object.assign({ path: [...entry.path], kind: "text", pmStart: entry.pmEnd - length, pmEnd: entry.pmEnd }, entry.offsetEncoding && { offsetEncoding: entry.offsetEncoding });
10185
+ entry.end -= length;
10186
+ entry.pmEnd -= length;
10187
+ if (entry.start === entry.end)
10188
+ this.sourceMap.pop();
10189
+ return mapping;
10190
+ }
10191
+ recordTextRange(mapping, start, end) {
10192
+ if (!this.sourceMap || this.inTable)
10193
+ return;
10194
+ this.sourceMap.push(Object.assign(Object.assign({}, mapping), { start, end }));
10195
+ }
10196
+ withNodePath(index, render) {
10197
+ if (!this.sourceMap)
10198
+ return render();
10199
+ this.nodePath.push(index);
10200
+ try {
10201
+ return render();
10202
+ } finally {
10203
+ this.nodePath.pop();
10204
+ }
10205
+ }
10206
+ recordLiteralTextRange(path, start, end) {
10207
+ if (!this.sourceMap || this.inTable)
10208
+ return;
10209
+ this.sourceMap.push({
10210
+ path: [...this.nodePath, ...path],
10211
+ start,
10212
+ end,
10213
+ kind: "text",
10214
+ pmStart: 0,
10215
+ pmEnd: end - start,
10216
+ offsetEncoding: "identity"
10217
+ });
10218
+ }
10219
+ importTextEntries(entries, pathPrefix, mapOffset) {
10220
+ if (!this.sourceMap)
10221
+ return;
10222
+ for (const entry of entries) {
10223
+ if (entry.kind !== "text")
10224
+ continue;
10225
+ this.sourceMap.push(Object.assign({ path: [...this.nodePath, ...pathPrefix, ...entry.path], start: mapOffset(entry.start), end: mapOffset(entry.end), kind: "text", pmStart: entry.pmStart, pmEnd: entry.pmEnd }, entry.offsetEncoding && { offsetEncoding: entry.offsetEncoding }));
10226
+ }
10227
+ }
10011
10228
  /**
10012
10229
  * Writes content to the output, handling closed blocks and current delimiters.
10013
10230
  */
10014
10231
  write(content) {
10015
10232
  if (this.closed) {
10016
- this.out += "\n";
10233
+ this.append("\n");
10017
10234
  this.closed = false;
10018
10235
  }
10019
- if (this.delim && this.out.endsWith("\n") && content.length > 0 && content[0] !== "\n") {
10020
- this.out += this.delim;
10236
+ if (this.delim && this.tail.endsWith("\n") && content.length > 0 && content[0] !== "\n") {
10237
+ this.append(this.delim);
10021
10238
  }
10022
- this.out += content;
10239
+ this.append(content);
10023
10240
  }
10024
10241
  ensureNewLine() {
10025
- if (!this.out.endsWith("\n")) {
10026
- this.out += "\n";
10242
+ if (!this.tail.endsWith("\n")) {
10243
+ this.append("\n");
10027
10244
  }
10028
10245
  }
10029
10246
  ensureBlankLine() {
10030
- if (this.out.endsWith("\n\n")) {
10247
+ if (this.tail.endsWith("\n\n")) {
10031
10248
  return;
10032
10249
  }
10033
- this.out += this.out.endsWith("\n") ? "\n" : "\n\n";
10250
+ this.append(this.tail.endsWith("\n") ? "\n" : "\n\n");
10034
10251
  }
10035
10252
  /**
10036
10253
  * Marks the current block as closed. Appropriate spacing will be added on the next write().
@@ -10245,18 +10462,41 @@ function writeJsxAttributesInline(state, attrs2) {
10245
10462
  }
10246
10463
 
10247
10464
  // ../editor/dist/converter/serialize/handlers/markdown.js
10465
+ var offsetMapperForLines = (source, parentContentStarts) => {
10466
+ const sourceLineStarts = [0];
10467
+ for (let index = 0; index < source.length; index++) {
10468
+ if (source[index] === "\n")
10469
+ sourceLineStarts.push(index + 1);
10470
+ }
10471
+ return (offset) => {
10472
+ var _a, _b, _c, _d;
10473
+ const clamped = Math.min(Math.max(offset, 0), source.length);
10474
+ let lineIndex = sourceLineStarts.length - 1;
10475
+ while (lineIndex > 0 && ((_a = sourceLineStarts[lineIndex]) !== null && _a !== void 0 ? _a : 0) > clamped)
10476
+ lineIndex--;
10477
+ const sourceLineStart = (_b = sourceLineStarts[lineIndex]) !== null && _b !== void 0 ? _b : 0;
10478
+ const parentLineStart = (_d = (_c = parentContentStarts[lineIndex]) !== null && _c !== void 0 ? _c : parentContentStarts.at(-1)) !== null && _d !== void 0 ? _d : 0;
10479
+ return parentLineStart + clamped - sourceLineStart;
10480
+ };
10481
+ };
10248
10482
  function renderBlockquote(state, node, renderNode2) {
10249
- var _a;
10483
+ var _a, _b;
10250
10484
  for (let i = 0; i < node.childCount; i++) {
10251
10485
  const child = node.child(i);
10252
10486
  const childState = new SerializerState(state.options);
10487
+ childState.sourceMap = state.sourceMap ? [] : null;
10253
10488
  renderNode2(childState, child, node, i);
10254
- const lines = childState.out.replace(/\n+$/, "").split("\n");
10489
+ const childOutput = childState.out.replace(/\n+$/, "");
10490
+ const lines = childOutput.split("\n");
10491
+ const parentContentStarts = [];
10255
10492
  for (let j = 0; j < lines.length; j++) {
10256
10493
  const line = (_a = lines[j]) !== null && _a !== void 0 ? _a : "";
10257
- state.write(line.length > 0 ? `> ${line}` : ">");
10494
+ state.write(line.length > 0 ? "> " : ">");
10495
+ parentContentStarts.push(state.length);
10496
+ state.write(line);
10258
10497
  state.ensureNewLine();
10259
10498
  }
10499
+ state.importTextEntries((_b = childState.sourceMap) !== null && _b !== void 0 ? _b : [], [i], offsetMapperForLines(childOutput, parentContentStarts));
10260
10500
  if (i < node.childCount - 1) {
10261
10501
  state.write(">");
10262
10502
  state.ensureNewLine();
@@ -10265,7 +10505,7 @@ function renderBlockquote(state, node, renderNode2) {
10265
10505
  state.closeBlock();
10266
10506
  }
10267
10507
  function renderList(state, node, ordered, renderContent2) {
10268
- var _a;
10508
+ var _a, _b;
10269
10509
  const start = node.attrs.start || 1;
10270
10510
  const isTight = typeof node.attrs.tight === "boolean" ? node.attrs.tight : state.options.tightLists;
10271
10511
  for (let i = 0; i < node.childCount; i++) {
@@ -10275,19 +10515,30 @@ function renderList(state, node, ordered, renderContent2) {
10275
10515
  const prefix = (ordered ? `${start + i}. ` : "- ") + taskMarker;
10276
10516
  const indent = " ".repeat(prefix.length);
10277
10517
  const itemState = new SerializerState(state.options);
10518
+ itemState.sourceMap = state.sourceMap ? [] : null;
10278
10519
  renderContent2(itemState, child);
10279
- const lines = itemState.out.split("\n");
10520
+ const itemOutput = itemState.out;
10521
+ const lines = itemOutput.split("\n");
10522
+ const parentContentStarts = [];
10280
10523
  for (let j = 0; j < lines.length; j++) {
10281
10524
  const line = (_a = lines[j]) !== null && _a !== void 0 ? _a : "";
10282
10525
  if (j === 0) {
10283
- state.write(prefix + line);
10526
+ state.write(prefix);
10527
+ parentContentStarts.push(state.length);
10528
+ state.write(line);
10284
10529
  } else if (line.length > 0) {
10285
10530
  state.ensureNewLine();
10286
- state.write(indent + line);
10531
+ state.write(indent);
10532
+ parentContentStarts.push(state.length);
10533
+ state.write(line);
10287
10534
  } else if (!isTight && j < lines.length - 1) {
10288
10535
  state.ensureBlankLine();
10536
+ parentContentStarts.push(state.length);
10537
+ } else {
10538
+ parentContentStarts.push(state.length);
10289
10539
  }
10290
10540
  }
10541
+ state.importTextEntries((_b = itemState.sourceMap) !== null && _b !== void 0 ? _b : [], [i], offsetMapperForLines(itemOutput, parentContentStarts));
10291
10542
  state.ensureNewLine();
10292
10543
  }
10293
10544
  state.closeBlock();
@@ -10546,7 +10797,21 @@ function renderTitledComponent(state, node, name, renderContent2, renderInline2,
10546
10797
  }
10547
10798
  const titleAttribute = isJSXContent(title) ? title.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") : title;
10548
10799
  const extractedAttrs = titleAttribute ? Object.assign({ title: titleAttribute }, node.attrs) : Object.assign({}, node.attrs);
10800
+ const outputStart = state.length;
10549
10801
  renderComponentWithAttrs(state, node, name, extractedAttrs, renderContent2, excludeAttrs);
10802
+ const titleText = titleChild === null || titleChild === void 0 ? void 0 : titleChild.firstChild;
10803
+ if (!(titleText === null || titleText === void 0 ? void 0 : titleText.isText) || titleText.text !== title)
10804
+ return;
10805
+ const rendered = state.sliceFrom(outputStart);
10806
+ const openingStart = rendered.indexOf(`<${name}`);
10807
+ const openingEnd = rendered.indexOf("\n", openingStart);
10808
+ const attributeStart = rendered.indexOf("title=", openingStart);
10809
+ const valueStart = rendered.indexOf(title, attributeStart + "title=".length);
10810
+ if (openingStart < 0 || openingEnd < 0 || attributeStart < 0 || valueStart < 0)
10811
+ return;
10812
+ if (attributeStart >= openingEnd || valueStart + title.length > openingEnd)
10813
+ return;
10814
+ state.recordLiteralTextRange([0, 0], outputStart + valueStart, outputStart + valueStart + title.length);
10550
10815
  }
10551
10816
  function renderGenericComponent(state, node, name, renderContent2, excludeAttrs = []) {
10552
10817
  renderComponentWithAttrs(state, node, name, node.attrs, renderContent2, excludeAttrs);
@@ -10943,6 +11208,10 @@ var MARK_PRESERVING_INLINE = /* @__PURE__ */ new Set([
10943
11208
  BLOCK_TYPES.inlineImage,
10944
11209
  BLOCK_TYPES.inlineUnknownTag
10945
11210
  ]);
11211
+ var serializableMarks = (marks2) => marks2.filter((mark) => {
11212
+ const { open, close } = getMarkStrings(mark);
11213
+ return open.length > 0 || close.length > 0;
11214
+ });
10946
11215
  function reorderMarksForLink(marks2, parent, childIndex) {
10947
11216
  if (marks2.length < 2)
10948
11217
  return marks2;
@@ -10994,15 +11263,17 @@ function renderInline(state, node, renderNode2, inlineRenderers2) {
10994
11263
  earliestClose = Math.min(earliestClose, codeIndex);
10995
11264
  }
10996
11265
  let trailingSpace = "";
11266
+ let trailingTextMapping = null;
10997
11267
  const closingFlanking = [...closingIndices].some((idx) => {
10998
11268
  const m = active[idx];
10999
11269
  return m !== void 0 && usesFlanking(m);
11000
11270
  });
11001
11271
  if (closingFlanking) {
11002
- const match = state.out.match(/ +$/);
11003
- if (match) {
11004
- trailingSpace = match[0];
11005
- state.out = state.out.slice(0, -trailingSpace.length);
11272
+ const spaces = state.trailingSpaceCount;
11273
+ if (spaces > 0) {
11274
+ trailingSpace = " ".repeat(spaces);
11275
+ trailingTextMapping = state.takeTextSuffix(spaces);
11276
+ state.truncate(spaces);
11006
11277
  }
11007
11278
  }
11008
11279
  for (let i = active.length - 1; i >= earliestClose; i--) {
@@ -11021,7 +11292,11 @@ function renderInline(state, node, renderNode2, inlineRenderers2) {
11021
11292
  }
11022
11293
  active = active.slice(0, earliestClose);
11023
11294
  if (trailingSpace) {
11295
+ const trailingStart = state.length;
11024
11296
  state.write(trailingSpace);
11297
+ if (trailingTextMapping) {
11298
+ state.recordTextRange(trailingTextMapping, trailingStart, state.length);
11299
+ }
11025
11300
  }
11026
11301
  for (const mark of continuing) {
11027
11302
  if (mark.type.name === "code") {
@@ -11052,32 +11327,35 @@ function renderInline(state, node, renderNode2, inlineRenderers2) {
11052
11327
  let text = child.text || "";
11053
11328
  if (!text)
11054
11329
  continue;
11055
- const openingFlanking = child.marks.some((m) => usesFlanking(m) && !active.some((a) => a.eq(m)));
11330
+ const textLength = text.length;
11331
+ let pmOffset = 0;
11332
+ const childMarks = serializableMarks(child.marks);
11333
+ const openingFlanking = childMarks.some((m) => usesFlanking(m) && !active.some((a) => a.eq(m)));
11056
11334
  if (openingFlanking) {
11057
11335
  const leadingMatch = text.match(/^( +)/);
11058
11336
  if (leadingMatch) {
11059
11337
  state.write(leadingMatch[0]);
11338
+ state.recordTextSuffix(i, leadingMatch[0].length, 0, leadingMatch[0].length);
11339
+ pmOffset = leadingMatch[0].length;
11060
11340
  text = text.slice(leadingMatch[0].length);
11061
11341
  if (!text)
11062
11342
  continue;
11063
11343
  }
11064
11344
  }
11065
- const marks2 = reorderMarksForLink(child.marks, node, i);
11345
+ const marks2 = reorderMarksForLink(childMarks, node, i);
11066
11346
  transitionMarks(marks2);
11067
- if (active.some((m) => m.type.name === "code")) {
11068
- state.write(state.escCodeText(text));
11069
- } else {
11070
- state.write(state.esc(text, { inLinkText: active.some((m) => m.type.name === "link") }));
11071
- }
11347
+ const written = active.some((m) => m.type.name === "code") ? state.escCodeText(text) : state.esc(text, { inLinkText: active.some((m) => m.type.name === "link") });
11348
+ state.write(written);
11349
+ state.recordTextSuffix(i, written.length, pmOffset, textLength);
11072
11350
  } else {
11073
11351
  if (typeName === BLOCK_TYPES.inlineImage) {
11074
- transitionMarks(reorderMarksForLink(child.marks, node, i));
11352
+ transitionMarks(reorderMarksForLink(serializableMarks(child.marks), node, i));
11075
11353
  inlineRenderers2.renderInlineImage(state, child);
11076
11354
  continue;
11077
11355
  }
11078
11356
  if (typeName === BLOCK_TYPES.inlineUnknownTag) {
11079
- transitionMarks(reorderMarksForLink(child.marks, node, i));
11080
- inlineRenderers2.renderUnknownTag(state, child);
11357
+ transitionMarks(reorderMarksForLink(serializableMarks(child.marks), node, i));
11358
+ state.withNodePath(i, () => inlineRenderers2.renderUnknownTag(state, child));
11081
11359
  continue;
11082
11360
  }
11083
11361
  transitionMarks([]);
@@ -11088,7 +11366,7 @@ function renderInline(state, node, renderNode2, inlineRenderers2) {
11088
11366
  } else if (typeName === BLOCK_TYPES.badge) {
11089
11367
  inlineRenderers2.renderBadge(state, child);
11090
11368
  } else if (typeName === BLOCK_TYPES.tooltip) {
11091
- inlineRenderers2.renderTooltip(state, child);
11369
+ state.withNodePath(i, () => inlineRenderers2.renderTooltip(state, child));
11092
11370
  } else if (typeName === BLOCK_TYPES.inlineMath) {
11093
11371
  if (child.attrs.expression) {
11094
11372
  state.write(`$$${child.attrs.expression}$$`);
@@ -11104,7 +11382,7 @@ function renderTextNode(state, node) {
11104
11382
  const text = node.text || "";
11105
11383
  if (!text)
11106
11384
  return;
11107
- const marks2 = node.marks;
11385
+ const marks2 = serializableMarks(node.marks);
11108
11386
  let openMarks = "";
11109
11387
  let closeMarks = "";
11110
11388
  for (const mark of marks2) {
@@ -11242,8 +11520,12 @@ function hasReferenceDefinitions(doc) {
11242
11520
  return found;
11243
11521
  }
11244
11522
  function pmToMdx(doc, options = {}) {
11523
+ return serializeDoc(doc, options, null).mdx;
11524
+ }
11525
+ function serializeDoc(doc, options, sourceMap) {
11245
11526
  const { frontmatter } = options, serializerOptions = __rest2(options, ["frontmatter"]);
11246
11527
  const state = new SerializerState(Object.assign(Object.assign({}, serializerOptions), { hasReferenceDefinitions: hasReferenceDefinitions(doc) }));
11528
+ state.sourceMap = sourceMap;
11247
11529
  if (frontmatter && Object.keys(frontmatter).length > 0) {
11248
11530
  const entries = Object.entries(filterFrontmatterRecord(frontmatter));
11249
11531
  if (entries.length > 0) {
@@ -11260,19 +11542,20 @@ function pmToMdx(doc, options = {}) {
11260
11542
  if (options.removeTrailingNewline !== false && result.endsWith("\n")) {
11261
11543
  result = result.replace(/\n+$/, "");
11262
11544
  }
11263
- return result;
11545
+ return { mdx: result, sourceMap: sourceMap !== null && sourceMap !== void 0 ? sourceMap : [] };
11264
11546
  }
11265
11547
  function renderContent(state, node) {
11266
11548
  for (let i = 0; i < node.childCount; i++) {
11267
11549
  const child = node.child(i);
11268
11550
  if (i > 0) {
11269
11551
  state.ensureNewLine();
11270
- const prev = node.child(i - 1);
11271
- if (needsBlankLine(prev, child)) {
11552
+ if (needsBlankLine(node.child(i - 1), child)) {
11272
11553
  state.ensureNewLine();
11273
11554
  }
11274
11555
  }
11556
+ const start = state.beginBlock(i);
11275
11557
  renderNode(state, child, node, i);
11558
+ state.endBlock(start);
11276
11559
  }
11277
11560
  }
11278
11561
  function needsBlankLine(prev, current) {