@readme/markdown 11.12.0 → 11.12.1
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.
package/dist/main.js
CHANGED
|
@@ -70584,77 +70584,197 @@ const mdxToHast = () => tree => {
|
|
|
70584
70584
|
;// ./processor/transform/mdxish/mdxish-component-blocks.ts
|
|
70585
70585
|
|
|
70586
70586
|
|
|
70587
|
-
const
|
|
70588
|
-
const
|
|
70587
|
+
const pascalCaseTagPattern = /^<([A-Z][A-Za-z0-9_]*)([^>]*?)(\/?)>([\s\S]*)?$/;
|
|
70588
|
+
const tagAttributePattern = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
|
|
70589
|
+
/**
|
|
70590
|
+
* Maximum number of siblings to scan forward when looking for a closing tag
|
|
70591
|
+
* to avoid scanning too far and degrading performance
|
|
70592
|
+
*/
|
|
70593
|
+
const MAX_LOOKAHEAD = 30;
|
|
70594
|
+
/**
|
|
70595
|
+
* Tags that have dedicated transformers and should NOT be handled by this plugin.
|
|
70596
|
+
* These components have special parsing requirements that the generic component
|
|
70597
|
+
* block transformer cannot handle correctly.
|
|
70598
|
+
*/
|
|
70599
|
+
const EXCLUDED_TAGS = new Set(['HTMLBlock', 'Table']);
|
|
70589
70600
|
const inlineMdProcessor = unified().use(remarkParse);
|
|
70590
70601
|
const isClosingTag = (value, tag) => value.trim() === `</${tag}>`;
|
|
70591
|
-
|
|
70592
|
-
|
|
70593
|
-
|
|
70594
|
-
return { paragraph: node, found: false };
|
|
70595
|
-
const children = [...node.children];
|
|
70596
|
-
const closingIndex = children.findIndex(child => child.type === 'html' && isClosingTag(child.value || '', tag));
|
|
70597
|
-
if (closingIndex === -1)
|
|
70598
|
-
return { paragraph: node, found: false };
|
|
70599
|
-
children.splice(closingIndex, 1);
|
|
70600
|
-
return {
|
|
70601
|
-
paragraph: { ...node, children },
|
|
70602
|
-
found: true,
|
|
70603
|
-
};
|
|
70604
|
-
};
|
|
70605
|
-
// Replace two child nodes (opening HTML tag + paragraph) with a single replacement node
|
|
70606
|
-
const replaceChild = (parent, index, replacement) => {
|
|
70607
|
-
parent.children.splice(index, 2, replacement);
|
|
70608
|
-
};
|
|
70609
|
-
// Parse markdown inside a component's inline content into mdast children.
|
|
70602
|
+
/**
|
|
70603
|
+
* Parse markdown content into mdast children nodes.
|
|
70604
|
+
*/
|
|
70610
70605
|
const parseMdChildren = (value) => {
|
|
70611
70606
|
const parsed = inlineMdProcessor.parse(value);
|
|
70612
70607
|
return parsed.children || [];
|
|
70613
70608
|
};
|
|
70614
|
-
|
|
70615
|
-
|
|
70609
|
+
/**
|
|
70610
|
+
* Convert raw attribute string into mdxJsxAttribute entries.
|
|
70611
|
+
* Handles both key-value attributes (theme="info") and boolean attributes (empty).
|
|
70612
|
+
*/
|
|
70616
70613
|
const parseAttributes = (raw) => {
|
|
70617
70614
|
const attributes = [];
|
|
70618
70615
|
const attrString = raw.trim();
|
|
70619
70616
|
if (!attrString)
|
|
70620
70617
|
return attributes;
|
|
70621
|
-
|
|
70622
|
-
|
|
70623
|
-
let match = attributePattern.exec(attrString);
|
|
70618
|
+
tagAttributePattern.lastIndex = 0;
|
|
70619
|
+
let match = tagAttributePattern.exec(attrString);
|
|
70624
70620
|
while (match !== null) {
|
|
70625
70621
|
const [, attrName, attrValue] = match;
|
|
70626
|
-
// Boolean attribute (no value) -> set to null
|
|
70627
|
-
// Attribute with value -> clean and set string value
|
|
70628
|
-
// Note: Attribute value types can't directly be numbers & booleans. String, nulls, undefined are supported.
|
|
70629
70622
|
const value = attrValue ? attrValue.replace(/^['"]|['"]$/g, '') : null;
|
|
70630
|
-
attributes.push({
|
|
70631
|
-
|
|
70632
|
-
name: attrName,
|
|
70633
|
-
value,
|
|
70634
|
-
});
|
|
70635
|
-
match = attributePattern.exec(attrString);
|
|
70623
|
+
attributes.push({ type: 'mdxJsxAttribute', name: attrName, value });
|
|
70624
|
+
match = tagAttributePattern.exec(attrString);
|
|
70636
70625
|
}
|
|
70637
70626
|
return attributes;
|
|
70638
70627
|
};
|
|
70639
|
-
|
|
70628
|
+
/**
|
|
70629
|
+
* Parse an HTML tag string into structured data.
|
|
70630
|
+
*/
|
|
70640
70631
|
const parseTag = (value) => {
|
|
70641
|
-
const match = value.match(
|
|
70632
|
+
const match = value.match(pascalCaseTagPattern);
|
|
70642
70633
|
if (!match)
|
|
70643
70634
|
return null;
|
|
70644
|
-
const [, tag, attrString = '', selfClosing = '',
|
|
70645
|
-
const attributes = parseAttributes(attrString);
|
|
70635
|
+
const [, tag, attrString = '', selfClosing = '', contentAfterTag = ''] = match;
|
|
70646
70636
|
return {
|
|
70647
70637
|
tag,
|
|
70648
|
-
attributes,
|
|
70638
|
+
attributes: parseAttributes(attrString),
|
|
70649
70639
|
selfClosing: !!selfClosing,
|
|
70650
|
-
|
|
70640
|
+
contentAfterTag,
|
|
70651
70641
|
};
|
|
70652
70642
|
};
|
|
70653
|
-
|
|
70654
|
-
|
|
70643
|
+
/**
|
|
70644
|
+
* Create an MdxJsxFlowElement node from component data.
|
|
70645
|
+
*/
|
|
70646
|
+
const createComponentNode = ({ tag, attributes, children, startPosition, endPosition }) => ({
|
|
70647
|
+
type: 'mdxJsxFlowElement',
|
|
70648
|
+
name: tag,
|
|
70649
|
+
attributes,
|
|
70650
|
+
children,
|
|
70651
|
+
position: {
|
|
70652
|
+
start: startPosition?.start,
|
|
70653
|
+
end: endPosition?.end ?? startPosition?.end,
|
|
70654
|
+
},
|
|
70655
|
+
});
|
|
70656
|
+
/**
|
|
70657
|
+
* Remove a closing tag from a paragraph's children and return the updated paragraph.
|
|
70658
|
+
*/
|
|
70659
|
+
const stripClosingTagFromParagraph = (node, tag) => {
|
|
70660
|
+
if (!Array.isArray(node.children))
|
|
70661
|
+
return { paragraph: node, found: false };
|
|
70662
|
+
const children = [...node.children];
|
|
70663
|
+
const closingIndex = children.findIndex(child => child.type === 'html' && isClosingTag(child.value || '', tag));
|
|
70664
|
+
if (closingIndex === -1)
|
|
70665
|
+
return { paragraph: node, found: false };
|
|
70666
|
+
children.splice(closingIndex, 1);
|
|
70667
|
+
return { paragraph: { ...node, children }, found: true };
|
|
70668
|
+
};
|
|
70669
|
+
/**
|
|
70670
|
+
* Scan forward through siblings to find a closing tag.
|
|
70671
|
+
* Handles:
|
|
70672
|
+
* - Exact match HTML siblings (e.g., `</Tag>`)
|
|
70673
|
+
* - HTML siblings with embedded closing tag (e.g., `...\n</Tag>`)
|
|
70674
|
+
* - Paragraph siblings containing the closing tag as a child
|
|
70675
|
+
*
|
|
70676
|
+
* Returns null if not found within MAX_LOOKAHEAD siblings
|
|
70677
|
+
*/
|
|
70678
|
+
const scanForClosingTag = (parent, startIndex, tag) => {
|
|
70679
|
+
const closingTagStr = `</${tag}>`;
|
|
70680
|
+
const maxIndex = Math.min(startIndex + MAX_LOOKAHEAD, parent.children.length);
|
|
70681
|
+
let i = startIndex + 1;
|
|
70682
|
+
for (; i < maxIndex; i += 1) {
|
|
70683
|
+
const sibling = parent.children[i];
|
|
70684
|
+
// Check HTML siblings
|
|
70685
|
+
if (sibling.type === 'html') {
|
|
70686
|
+
const siblingValue = sibling.value || '';
|
|
70687
|
+
// Exact match (standalone closing tag)
|
|
70688
|
+
if (isClosingTag(siblingValue, tag)) {
|
|
70689
|
+
return { closingIndex: i, extraClosingChildren: [] };
|
|
70690
|
+
}
|
|
70691
|
+
// Embedded closing tag (closing tag at end of HTML block content)
|
|
70692
|
+
if (siblingValue.includes(closingTagStr)) {
|
|
70693
|
+
const contentBeforeClose = siblingValue.substring(0, siblingValue.lastIndexOf(closingTagStr)).trim();
|
|
70694
|
+
const extraChildren = contentBeforeClose
|
|
70695
|
+
? parseMdChildren(contentBeforeClose)
|
|
70696
|
+
: [];
|
|
70697
|
+
return { closingIndex: i, extraClosingChildren: extraChildren };
|
|
70698
|
+
}
|
|
70699
|
+
}
|
|
70700
|
+
// Check paragraph siblings
|
|
70701
|
+
if (sibling.type === 'paragraph') {
|
|
70702
|
+
const { paragraph, found } = stripClosingTagFromParagraph(sibling, tag);
|
|
70703
|
+
if (found) {
|
|
70704
|
+
return { closingIndex: i, extraClosingChildren: [], strippedParagraph: paragraph };
|
|
70705
|
+
}
|
|
70706
|
+
}
|
|
70707
|
+
}
|
|
70708
|
+
if (i < parent.children.length) {
|
|
70709
|
+
// eslint-disable-next-line no-console
|
|
70710
|
+
console.warn(`Closing tag </${tag}> not found within ${MAX_LOOKAHEAD} siblings, stopping scan`);
|
|
70711
|
+
}
|
|
70712
|
+
return null;
|
|
70713
|
+
};
|
|
70714
|
+
const substituteNodeWithMdxNode = (parent, index, mdxNode) => {
|
|
70715
|
+
parent.children.splice(index, 1, mdxNode);
|
|
70716
|
+
};
|
|
70717
|
+
/**
|
|
70718
|
+
* Transform PascalCase HTML nodes into mdxJsxFlowElement nodes.
|
|
70719
|
+
*
|
|
70720
|
+
* Remark parses unknown/custom component tags as raw HTML nodes.
|
|
70721
|
+
* These are the custom readme MDX syntax for components.
|
|
70722
|
+
* This transformer identifies these patterns and converts them to proper MDX JSX elements so they
|
|
70723
|
+
* can be accurately recognized and rendered later with their component definition code.
|
|
70724
|
+
* Though for some tags, we need to handle them specially
|
|
70725
|
+
*
|
|
70726
|
+
* ## Supported HTML Structures
|
|
70727
|
+
*
|
|
70728
|
+
* ### 1. Self-closing tags
|
|
70729
|
+
* ```
|
|
70730
|
+
* <Component />
|
|
70731
|
+
* ```
|
|
70732
|
+
* Parsed as: `html: "<Component />"`
|
|
70733
|
+
*
|
|
70734
|
+
* ### 2. Self-contained blocks (entire component in single HTML node)
|
|
70735
|
+
* ```
|
|
70736
|
+
* <Button>Click me</Button>
|
|
70737
|
+
* ```
|
|
70738
|
+
* ```
|
|
70739
|
+
* <Component>
|
|
70740
|
+
* <h2>Title</h2>
|
|
70741
|
+
* <p>Content</p>
|
|
70742
|
+
* </Component>
|
|
70743
|
+
* ```
|
|
70744
|
+
* Parsed as: `html: "<Component>\n <h2>Title</h2>\n <p>Content</p>\n</Component>"`
|
|
70745
|
+
* The opening tag, content, and closing tag are all captured in one HTML node.
|
|
70746
|
+
*
|
|
70747
|
+
* ### 3. Multi-sibling components (closing tag in a following sibling)
|
|
70748
|
+
* Handles various structures where the closing tag is in a later sibling, such as:
|
|
70749
|
+
*
|
|
70750
|
+
* #### 3a. Block components (closing tag in sibling paragraph)
|
|
70751
|
+
* ```
|
|
70752
|
+
* <Callout>
|
|
70753
|
+
* Some **markdown** content
|
|
70754
|
+
* </Callout>
|
|
70755
|
+
* ```
|
|
70756
|
+
*
|
|
70757
|
+
* #### 3b. Multi-paragraph components (closing tag several siblings away)
|
|
70758
|
+
* ```
|
|
70759
|
+
* <Callout>
|
|
70760
|
+
*
|
|
70761
|
+
* First paragraph
|
|
70762
|
+
*
|
|
70763
|
+
* Second paragraph
|
|
70764
|
+
* </Callout>
|
|
70765
|
+
* ```
|
|
70766
|
+
*
|
|
70767
|
+
* #### 3c. Nested components split by blank lines (closing tag embedded in HTML sibling)
|
|
70768
|
+
* ```
|
|
70769
|
+
* <Outer>
|
|
70770
|
+
* <Inner>content</Inner>
|
|
70771
|
+
*
|
|
70772
|
+
* <Inner>content</Inner>
|
|
70773
|
+
* </Outer>
|
|
70774
|
+
* ```
|
|
70775
|
+
*/
|
|
70655
70776
|
const mdxishComponentBlocks = () => tree => {
|
|
70656
70777
|
const stack = [tree];
|
|
70657
|
-
// Process children depth-first, rewriting opening/closing component HTML pairs
|
|
70658
70778
|
const processChildNode = (parent, index) => {
|
|
70659
70779
|
const node = parent.children[index];
|
|
70660
70780
|
if (!node)
|
|
@@ -70662,46 +70782,66 @@ const mdxishComponentBlocks = () => tree => {
|
|
|
70662
70782
|
if ('children' in node && Array.isArray(node.children)) {
|
|
70663
70783
|
stack.push(node);
|
|
70664
70784
|
}
|
|
70785
|
+
// Only visit HTML nodes with an actual html tag
|
|
70665
70786
|
const value = node.value;
|
|
70666
70787
|
if (node.type !== 'html' || typeof value !== 'string')
|
|
70667
70788
|
return;
|
|
70668
70789
|
const parsed = parseTag(value);
|
|
70669
70790
|
if (!parsed)
|
|
70670
70791
|
return;
|
|
70671
|
-
const { tag, attributes, selfClosing,
|
|
70672
|
-
|
|
70792
|
+
const { tag, attributes, selfClosing, contentAfterTag = '' } = parsed;
|
|
70793
|
+
// Skip tags that have dedicated transformers
|
|
70794
|
+
if (EXCLUDED_TAGS.has(tag))
|
|
70795
|
+
return;
|
|
70796
|
+
const closingTagStr = `</${tag}>`;
|
|
70797
|
+
// Case 1: Self-closing tag
|
|
70673
70798
|
if (selfClosing) {
|
|
70674
|
-
const componentNode = {
|
|
70675
|
-
|
|
70676
|
-
name: tag,
|
|
70799
|
+
const componentNode = createComponentNode({
|
|
70800
|
+
tag,
|
|
70677
70801
|
attributes,
|
|
70678
70802
|
children: [],
|
|
70679
|
-
|
|
70680
|
-
};
|
|
70681
|
-
parent
|
|
70803
|
+
startPosition: node.position,
|
|
70804
|
+
});
|
|
70805
|
+
substituteNodeWithMdxNode(parent, index, componentNode);
|
|
70682
70806
|
return;
|
|
70683
70807
|
}
|
|
70684
|
-
|
|
70685
|
-
if (
|
|
70808
|
+
// Case 2: Self-contained block (closing tag in content)
|
|
70809
|
+
if (contentAfterTag.includes(closingTagStr)) {
|
|
70810
|
+
const componentInnerContent = contentAfterTag.substring(0, contentAfterTag.lastIndexOf(closingTagStr)).trim();
|
|
70811
|
+
const componentNode = createComponentNode({
|
|
70812
|
+
tag,
|
|
70813
|
+
attributes,
|
|
70814
|
+
children: componentInnerContent ? parseMdChildren(componentInnerContent) : [],
|
|
70815
|
+
startPosition: node.position,
|
|
70816
|
+
});
|
|
70817
|
+
substituteNodeWithMdxNode(parent, index, componentNode);
|
|
70686
70818
|
return;
|
|
70687
|
-
|
|
70688
|
-
|
|
70819
|
+
}
|
|
70820
|
+
// Case 3: Multi-sibling component (closing tag in a following sibling)
|
|
70821
|
+
// Scans forward through siblings to find closing tag in HTML or paragraph nodes
|
|
70822
|
+
const scanResult = scanForClosingTag(parent, index, tag);
|
|
70823
|
+
if (!scanResult)
|
|
70689
70824
|
return;
|
|
70690
|
-
const
|
|
70691
|
-
|
|
70692
|
-
|
|
70825
|
+
const { closingIndex, extraClosingChildren, strippedParagraph } = scanResult;
|
|
70826
|
+
const extraChildren = contentAfterTag ? parseMdChildren(contentAfterTag.trimStart()) : [];
|
|
70827
|
+
// Collect all intermediate siblings between opening tag and closing tag
|
|
70828
|
+
const intermediateChildren = parent.children.slice(index + 1, closingIndex);
|
|
70829
|
+
// For paragraph siblings, include the paragraph's children (with closing tag stripped)
|
|
70830
|
+
// For HTML siblings, include any content parsed from before the closing tag
|
|
70831
|
+
const closingChildren = strippedParagraph
|
|
70832
|
+
? strippedParagraph.children
|
|
70833
|
+
: extraClosingChildren;
|
|
70834
|
+
const componentNode = createComponentNode({
|
|
70835
|
+
tag,
|
|
70693
70836
|
attributes,
|
|
70694
|
-
children: [
|
|
70695
|
-
|
|
70696
|
-
|
|
70697
|
-
|
|
70698
|
-
|
|
70699
|
-
|
|
70700
|
-
end: next.position?.end,
|
|
70701
|
-
},
|
|
70702
|
-
};
|
|
70703
|
-
replaceChild(parent, index, componentNode);
|
|
70837
|
+
children: [...extraChildren, ...intermediateChildren, ...closingChildren],
|
|
70838
|
+
startPosition: node.position,
|
|
70839
|
+
endPosition: parent.children[closingIndex]?.position,
|
|
70840
|
+
});
|
|
70841
|
+
// Remove all nodes from opening tag to closing tag (inclusive) and replace with component node
|
|
70842
|
+
parent.children.splice(index, closingIndex - index + 1, componentNode);
|
|
70704
70843
|
};
|
|
70844
|
+
// Travel the tree depth-first
|
|
70705
70845
|
while (stack.length) {
|
|
70706
70846
|
const parent = stack.pop();
|
|
70707
70847
|
if (parent?.children) {
|
|
@@ -92845,8 +92985,11 @@ function smartCamelCase(str) {
|
|
|
92845
92985
|
}
|
|
92846
92986
|
// Sort by length (longest first) to prevent shorter matches (e.g., "column" in "columns")
|
|
92847
92987
|
const sortedBoundaries = [...allBoundaries].sort((a, b) => b.length - a.length);
|
|
92988
|
+
// Use case-sensitive matching ('g' not 'gi') so that once a letter is
|
|
92989
|
+
// capitalized by a longer boundary, shorter boundaries won't re-match it.
|
|
92990
|
+
// This prevents issues like 'iconcolor' becoming 'iconColOr' instead of 'iconColor'.
|
|
92848
92991
|
return sortedBoundaries.reduce((res, word) => {
|
|
92849
|
-
const regex = new RegExp(`(${word})([a-z])`, '
|
|
92992
|
+
const regex = new RegExp(`(${word})([a-z])`, 'g');
|
|
92850
92993
|
return res.replace(regex, (_, prefix, nextChar) => prefix.toLowerCase() + nextChar.toUpperCase());
|
|
92851
92994
|
}, str);
|
|
92852
92995
|
}
|
|
@@ -92972,7 +93115,21 @@ const htmlBlockHandler = (_state, node) => {
|
|
|
92972
93115
|
children: [],
|
|
92973
93116
|
};
|
|
92974
93117
|
};
|
|
93118
|
+
// Convert embed magic blocks to Embed components
|
|
93119
|
+
const embedHandler = (state, node) => {
|
|
93120
|
+
// Assert to get the minimum properties we need
|
|
93121
|
+
const { data } = node;
|
|
93122
|
+
return {
|
|
93123
|
+
type: 'element',
|
|
93124
|
+
// To differentiate between regular embeds and magic block embeds,
|
|
93125
|
+
// magic block embeds have a certain hName
|
|
93126
|
+
tagName: data?.hName === NodeTypes.embedBlock ? 'Embed' : 'embed',
|
|
93127
|
+
properties: data?.hProperties,
|
|
93128
|
+
children: state.all(node),
|
|
93129
|
+
};
|
|
93130
|
+
};
|
|
92975
93131
|
const mdxComponentHandlers = {
|
|
93132
|
+
embed: embedHandler,
|
|
92976
93133
|
mdxFlowExpression: mdxExpressionHandler,
|
|
92977
93134
|
mdxJsxFlowElement: mdxJsxElementHandler,
|
|
92978
93135
|
mdxJsxTextElement: mdxJsxElementHandler,
|
|
@@ -93817,14 +93974,17 @@ function parseMagicBlock(raw, options = {}) {
|
|
|
93817
93974
|
else {
|
|
93818
93975
|
children.push(...titleBlocks, ...bodyBlocks);
|
|
93819
93976
|
}
|
|
93977
|
+
// If there is no title or title is empty
|
|
93978
|
+
const empty = !titleBlocks.length || !titleBlocks[0].children[0]?.value;
|
|
93820
93979
|
// Create mdxJsxFlowElement directly for mdxish
|
|
93821
93980
|
const calloutElement = {
|
|
93822
93981
|
type: 'mdxJsxFlowElement',
|
|
93823
93982
|
name: 'Callout',
|
|
93824
|
-
attributes: toAttributes({ icon, theme: theme || 'default', type: theme || 'default' }, [
|
|
93983
|
+
attributes: toAttributes({ icon, theme: theme || 'default', type: theme || 'default', empty }, [
|
|
93825
93984
|
'icon',
|
|
93826
93985
|
'theme',
|
|
93827
93986
|
'type',
|
|
93987
|
+
'empty',
|
|
93828
93988
|
]),
|
|
93829
93989
|
children: children,
|
|
93830
93990
|
};
|
|
@@ -93882,9 +94042,9 @@ function parseMagicBlock(raw, options = {}) {
|
|
|
93882
94042
|
return [
|
|
93883
94043
|
wrapPinnedBlocks({
|
|
93884
94044
|
children: [
|
|
93885
|
-
{ children: [{ type: 'text', value: title ||
|
|
94045
|
+
{ children: [{ type: 'text', value: title || '' }], title: embedJson.provider, type: 'link', url },
|
|
93886
94046
|
],
|
|
93887
|
-
data: { hName: '
|
|
94047
|
+
data: { hName: 'embed-block', hProperties: { ...embedJson, href: url, html, title, url } },
|
|
93888
94048
|
type: 'embed',
|
|
93889
94049
|
}, json),
|
|
93890
94050
|
];
|
|
@@ -94214,6 +94374,45 @@ const restoreSnakeCaseComponentNames = (options) => {
|
|
|
94214
94374
|
};
|
|
94215
94375
|
/* harmony default export */ const restore_snake_case_component_name = (restoreSnakeCaseComponentNames);
|
|
94216
94376
|
|
|
94377
|
+
;// ./processor/transform/mdxish/retain-boolean-attributes.ts
|
|
94378
|
+
|
|
94379
|
+
// Private Use Area character (U+E000) which is extremely unlikely to appear in real content.
|
|
94380
|
+
const TEMP_TRUE_BOOLEAN_VALUE = 'readme-this-is-a-temporary-boolean-attribute-\uE000';
|
|
94381
|
+
const TEMP_FALSE_BOOLEAN_VALUE = 'readme-this-is-a-temporary-boolean-attribute-\uE001';
|
|
94382
|
+
/**
|
|
94383
|
+
* Preserves boolean properties when passed to rehypeRaw because
|
|
94384
|
+
* rehypeRaw converts boolean properties in nodes to strings (e.g. true -> ""),
|
|
94385
|
+
* which can change the truthiness of the property. Hence we need to preserve the boolean properties.
|
|
94386
|
+
*/
|
|
94387
|
+
const preserveBooleanProperties = () => tree => {
|
|
94388
|
+
visit(tree, 'element', (node) => {
|
|
94389
|
+
if (!node.properties)
|
|
94390
|
+
return;
|
|
94391
|
+
Object.entries(node.properties).forEach(([key, value]) => {
|
|
94392
|
+
if (typeof value === 'boolean') {
|
|
94393
|
+
node.properties[key] = value ? TEMP_TRUE_BOOLEAN_VALUE : TEMP_FALSE_BOOLEAN_VALUE;
|
|
94394
|
+
}
|
|
94395
|
+
});
|
|
94396
|
+
});
|
|
94397
|
+
return tree;
|
|
94398
|
+
};
|
|
94399
|
+
const restoreBooleanProperties = () => tree => {
|
|
94400
|
+
visit(tree, 'element', (node) => {
|
|
94401
|
+
if (!node.properties)
|
|
94402
|
+
return;
|
|
94403
|
+
Object.entries(node.properties).forEach(([key, value]) => {
|
|
94404
|
+
if (value === TEMP_TRUE_BOOLEAN_VALUE) {
|
|
94405
|
+
node.properties[key] = true;
|
|
94406
|
+
}
|
|
94407
|
+
else if (value === TEMP_FALSE_BOOLEAN_VALUE) {
|
|
94408
|
+
node.properties[key] = false;
|
|
94409
|
+
}
|
|
94410
|
+
});
|
|
94411
|
+
});
|
|
94412
|
+
return tree;
|
|
94413
|
+
};
|
|
94414
|
+
|
|
94415
|
+
|
|
94217
94416
|
;// ./processor/transform/mdxish/variables-text.ts
|
|
94218
94417
|
|
|
94219
94418
|
|
|
@@ -94241,6 +94440,8 @@ const variablesTextTransformer = () => tree => {
|
|
|
94241
94440
|
if (parent.type === 'inlineCode')
|
|
94242
94441
|
return;
|
|
94243
94442
|
const text = node.value;
|
|
94443
|
+
if (typeof text !== 'string' || !text.trim())
|
|
94444
|
+
return;
|
|
94244
94445
|
if (!text.includes('{user.') && !text.includes('{user['))
|
|
94245
94446
|
return;
|
|
94246
94447
|
const matches = [...text.matchAll(USER_VAR_REGEX)];
|
|
@@ -94393,6 +94594,7 @@ function loadComponents() {
|
|
|
94393
94594
|
|
|
94394
94595
|
|
|
94395
94596
|
|
|
94597
|
+
|
|
94396
94598
|
|
|
94397
94599
|
|
|
94398
94600
|
const defaultTransformers = [callouts, code_tabs, gemoji_, transform_embeds];
|
|
@@ -94439,7 +94641,9 @@ function mdxish(mdContent, opts = {}) {
|
|
|
94439
94641
|
.use(useTailwind ? transform_tailwind : undefined, { components: tempComponentsMap })
|
|
94440
94642
|
.use(remarkGfm)
|
|
94441
94643
|
.use(remarkRehype, { allowDangerousHtml: true, handlers: mdxComponentHandlers })
|
|
94644
|
+
.use(preserveBooleanProperties) // RehypeRaw converts boolean properties to empty strings
|
|
94442
94645
|
.use(rehypeRaw, { passThrough: ['html-block'] })
|
|
94646
|
+
.use(restoreBooleanProperties)
|
|
94443
94647
|
.use(rehypeSlug)
|
|
94444
94648
|
.use(rehypeMdxishComponents, {
|
|
94445
94649
|
components,
|