@readme/markdown 13.5.0 → 13.6.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.
- package/components/Callout/style.scss +8 -0
- package/dist/enums.d.ts +1 -0
- package/dist/lib/ast-processor.d.ts +2 -2
- package/dist/main.css +1 -1
- package/dist/main.css.map +1 -1
- package/dist/main.js +244 -52
- package/dist/main.node.js +244 -52
- package/dist/main.node.js.map +1 -1
- package/dist/processor/transform/mdxish/constants.d.ts +5 -0
- package/dist/processor/transform/mdxish/mdxish-inline-components.d.ts +11 -0
- package/package.json +1 -1
package/dist/main.node.js
CHANGED
|
@@ -61232,6 +61232,7 @@ function remarkMdx(options) {
|
|
|
61232
61232
|
;// ./enums.ts
|
|
61233
61233
|
var NodeTypes;
|
|
61234
61234
|
(function (NodeTypes) {
|
|
61235
|
+
NodeTypes["anchor"] = "readme-anchor";
|
|
61235
61236
|
NodeTypes["callout"] = "rdme-callout";
|
|
61236
61237
|
NodeTypes["codeTabs"] = "code-tabs";
|
|
61237
61238
|
NodeTypes["embedBlock"] = "embed-block";
|
|
@@ -73245,6 +73246,13 @@ const extractText = (node) => {
|
|
|
73245
73246
|
|
|
73246
73247
|
|
|
73247
73248
|
|
|
73249
|
+
|
|
73250
|
+
|
|
73251
|
+
|
|
73252
|
+
|
|
73253
|
+
|
|
73254
|
+
const titleParser = unified().use(remarkParse).use(remarkGfm);
|
|
73255
|
+
const toMarkdownExtensions = [gfmStrikethroughToMarkdown()];
|
|
73248
73256
|
const callouts_regex = `^(${emoji_regex().source}|⚠)(\\s+|$)`;
|
|
73249
73257
|
const findFirst = (node) => {
|
|
73250
73258
|
if ('children' in node)
|
|
@@ -73361,31 +73369,65 @@ const processBlockquote = (node, index, parent) => {
|
|
|
73361
73369
|
// Example: "> ⚠️ **Bold heading**\nBody text here"
|
|
73362
73370
|
const bodyChildren = splitParagraphAtNewline(firstParagraph);
|
|
73363
73371
|
const didSplit = bodyChildren !== null;
|
|
73364
|
-
// Extract heading text after removing the icon prefix.
|
|
73365
|
-
// Use `plain()` to handle complex markdown structures (bold, inline code, etc.)
|
|
73366
|
-
const headingText = lib_plain(firstParagraph)
|
|
73367
|
-
.toString()
|
|
73368
|
-
.slice(match.length);
|
|
73369
|
-
// Clean up the raw AST by removing the icon prefix from the first text node
|
|
73370
73372
|
removeIconPrefix(firstParagraph, match.length);
|
|
73371
|
-
const
|
|
73373
|
+
const firstText = findFirst(firstParagraph);
|
|
73374
|
+
const rawValue = firstText?.value ?? '';
|
|
73375
|
+
const hasContent = rawValue.trim().length > 0 || firstParagraph.children.length > 1;
|
|
73376
|
+
const empty = !hasContent;
|
|
73372
73377
|
const theme = themes[icon] || 'default';
|
|
73373
|
-
|
|
73374
|
-
|
|
73375
|
-
|
|
73376
|
-
//
|
|
73377
|
-
|
|
73378
|
-
|
|
73378
|
+
if (hasContent || didSplit) {
|
|
73379
|
+
const headingMatch = rawValue.match(/^(#{1,6})\s*/);
|
|
73380
|
+
// # heading syntax is handled via direct AST manipulation so we can
|
|
73381
|
+
// set the depth while preserving the original inline children (bold, etc.)
|
|
73382
|
+
if (headingMatch) {
|
|
73383
|
+
firstText.value = rawValue.slice(headingMatch[0].length);
|
|
73384
|
+
const heading = wrapHeading(node);
|
|
73385
|
+
heading.depth = headingMatch[1].length;
|
|
73386
|
+
node.children[0] = heading;
|
|
73387
|
+
node.children[0].position.start.offset += match.length;
|
|
73388
|
+
node.children[0].position.start.column += match.length;
|
|
73389
|
+
}
|
|
73390
|
+
else {
|
|
73391
|
+
const headingText = toMarkdown({ type: 'root', children: [firstParagraph] }, {
|
|
73392
|
+
extensions: toMarkdownExtensions,
|
|
73393
|
+
})
|
|
73394
|
+
.trim()
|
|
73395
|
+
.replace(/^\\(?=[>#+\-*])/, '');
|
|
73396
|
+
const parsedTitle = titleParser.parse(headingText);
|
|
73397
|
+
const parsedFirstChild = parsedTitle.children[0];
|
|
73398
|
+
// Block-level syntax ("> quote", "- list") produces non-paragraph nodes;
|
|
73399
|
+
// inline text parses as a paragraph and falls through to wrapHeading().
|
|
73400
|
+
if (parsedFirstChild && parsedFirstChild.type !== 'paragraph') {
|
|
73401
|
+
// Strip positions from re-parsed nodes since they're relative to the heading text, not the original source
|
|
73402
|
+
visit(parsedTitle, (n) => {
|
|
73403
|
+
delete n.position;
|
|
73404
|
+
});
|
|
73405
|
+
const heading = wrapHeading(node);
|
|
73406
|
+
heading.children = parsedTitle.children;
|
|
73407
|
+
delete heading.position;
|
|
73408
|
+
node.children[0] = heading;
|
|
73409
|
+
}
|
|
73410
|
+
else {
|
|
73411
|
+
node.children[0] = wrapHeading(node);
|
|
73412
|
+
node.children[0].position.start.offset += match.length;
|
|
73413
|
+
node.children[0].position.start.column += match.length;
|
|
73414
|
+
}
|
|
73415
|
+
}
|
|
73379
73416
|
}
|
|
73380
73417
|
// Insert body content as a separate paragraph after the heading
|
|
73381
73418
|
if (bodyChildren) {
|
|
73419
|
+
const headingPosition = node.children[0].position;
|
|
73382
73420
|
node.children.splice(1, 0, {
|
|
73383
73421
|
type: 'paragraph',
|
|
73384
73422
|
children: bodyChildren,
|
|
73385
|
-
|
|
73386
|
-
|
|
73387
|
-
|
|
73388
|
-
|
|
73423
|
+
...(headingPosition && firstParagraphOriginalEnd
|
|
73424
|
+
? {
|
|
73425
|
+
position: {
|
|
73426
|
+
start: headingPosition.end,
|
|
73427
|
+
end: firstParagraphOriginalEnd,
|
|
73428
|
+
},
|
|
73429
|
+
}
|
|
73430
|
+
: {}),
|
|
73389
73431
|
});
|
|
73390
73432
|
}
|
|
73391
73433
|
Object.assign(node, {
|
|
@@ -73402,11 +73444,24 @@ const processBlockquote = (node, index, parent) => {
|
|
|
73402
73444
|
}
|
|
73403
73445
|
};
|
|
73404
73446
|
const calloutTransformer = () => {
|
|
73405
|
-
|
|
73406
|
-
visit(
|
|
73447
|
+
const processNode = (root) => {
|
|
73448
|
+
visit(root, 'blockquote', (node, index, parent) => {
|
|
73407
73449
|
processBlockquote(node, index, parent);
|
|
73450
|
+
if (node.type === NodeTypes.callout) {
|
|
73451
|
+
// SKIP prevents re-processing synthetic blockquotes in parsed title content
|
|
73452
|
+
// (e.g., blockquotes from "> Quote" titles). Recursively process body children
|
|
73453
|
+
// (index 1+, skipping the heading at 0) to handle nested callouts.
|
|
73454
|
+
for (let i = 1; i < node.children.length; i += 1) {
|
|
73455
|
+
processNode(node.children[i]);
|
|
73456
|
+
}
|
|
73457
|
+
return SKIP;
|
|
73458
|
+
}
|
|
73459
|
+
return undefined;
|
|
73408
73460
|
});
|
|
73409
73461
|
};
|
|
73462
|
+
return (tree) => {
|
|
73463
|
+
processNode(tree);
|
|
73464
|
+
};
|
|
73410
73465
|
};
|
|
73411
73466
|
/* harmony default export */ const callouts = (calloutTransformer);
|
|
73412
73467
|
|
|
@@ -73431,8 +73486,18 @@ const codeTabsTransformer = ({ copyButtons } = {}) => (tree) => {
|
|
|
73431
73486
|
const sibling = parent.children[walker];
|
|
73432
73487
|
if (!isCode(sibling))
|
|
73433
73488
|
break;
|
|
73489
|
+
// Check that the two code blocks are truly adjacent (no blank lines or
|
|
73490
|
+
// other content between them). The `gap` is the number of raw characters
|
|
73491
|
+
// between the end of the previous block and the start of this one.
|
|
73492
|
+
// For a LF-separated pair the gap equals `start.column` (the newline
|
|
73493
|
+
// char(s) plus any indentation). CRLF line endings add one extra byte
|
|
73494
|
+
// (\r) without advancing the line count, so we also accept
|
|
73495
|
+
// `start.column + 1` provided the blocks are still on consecutive lines.
|
|
73434
73496
|
const olderSibling = parent.children[walker - 1];
|
|
73435
|
-
|
|
73497
|
+
const gap = sibling.position.start.offset - olderSibling.position.end.offset;
|
|
73498
|
+
const lineDiff = sibling.position.start.line - olderSibling.position.end.line;
|
|
73499
|
+
const isCRLF = gap === sibling.position.start.column + 1 && lineDiff === 1;
|
|
73500
|
+
if (gap !== sibling.position.start.column && !isCRLF)
|
|
73436
73501
|
break;
|
|
73437
73502
|
children.push(sibling);
|
|
73438
73503
|
// eslint-disable-next-line no-plusplus
|
|
@@ -91366,6 +91431,13 @@ function legacyVariable() {
|
|
|
91366
91431
|
*/
|
|
91367
91432
|
|
|
91368
91433
|
|
|
91434
|
+
;// ./processor/transform/mdxish/constants.ts
|
|
91435
|
+
/**
|
|
91436
|
+
* Inline component tags handled by mdxish-inline-components.ts.
|
|
91437
|
+
* Also excluded from block-level handling in mdxish-component-blocks.ts.
|
|
91438
|
+
*/
|
|
91439
|
+
const INLINE_COMPONENT_TAGS = new Set(['Anchor']);
|
|
91440
|
+
|
|
91369
91441
|
;// ./processor/transform/mdxish/mdxish-component-blocks.ts
|
|
91370
91442
|
|
|
91371
91443
|
|
|
@@ -91373,6 +91445,7 @@ function legacyVariable() {
|
|
|
91373
91445
|
|
|
91374
91446
|
|
|
91375
91447
|
|
|
91448
|
+
|
|
91376
91449
|
const pascalCaseTagPattern = /^<([A-Z][A-Za-z0-9_]*)([^>]*?)(\/?)>([\s\S]*)?$/;
|
|
91377
91450
|
const tagAttributePattern = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
|
|
91378
91451
|
/**
|
|
@@ -91385,10 +91458,8 @@ const MAX_LOOKAHEAD = 30;
|
|
|
91385
91458
|
* These components either have special parsing requirements that the generic component
|
|
91386
91459
|
* block transformer cannot handle correctly, or are inline components that we don't
|
|
91387
91460
|
* want to convert to mdxJsxFlowElement which is a block level element.
|
|
91388
|
-
*
|
|
91389
|
-
* Glossary and Anchor are inline components.
|
|
91390
91461
|
*/
|
|
91391
|
-
const EXCLUDED_TAGS = new Set(['HTMLBlock', 'Table', 'Glossary',
|
|
91462
|
+
const EXCLUDED_TAGS = new Set(['HTMLBlock', 'Table', 'Glossary', ...INLINE_COMPONENT_TAGS]);
|
|
91392
91463
|
const inlineMdProcessor = unified()
|
|
91393
91464
|
.data('micromarkExtensions', [legacyVariable()])
|
|
91394
91465
|
.data('fromMarkdownExtensions', [legacyVariableFromMarkdown(), emptyTaskListItemFromMarkdown()])
|
|
@@ -91652,10 +91723,10 @@ const mdxishComponentBlocks = () => tree => {
|
|
|
91652
91723
|
const extraChildren = contentAfterTag ? parseMdChildren(contentAfterTag.trimStart()) : [];
|
|
91653
91724
|
// Collect all intermediate siblings between opening tag and closing tag
|
|
91654
91725
|
const intermediateChildren = parent.children.slice(index + 1, closingIndex);
|
|
91655
|
-
// For paragraph siblings, include the paragraph
|
|
91726
|
+
// For paragraph siblings, include the full paragraph (with closing tag stripped)
|
|
91656
91727
|
// For HTML siblings, include any content parsed from before the closing tag
|
|
91657
91728
|
const closingChildren = strippedParagraph
|
|
91658
|
-
? strippedParagraph.children
|
|
91729
|
+
? (strippedParagraph.children.length > 0 ? [strippedParagraph] : [])
|
|
91659
91730
|
: extraClosingChildren;
|
|
91660
91731
|
const componentNode = createComponentNode({
|
|
91661
91732
|
tag,
|
|
@@ -114033,7 +114104,7 @@ function getComponentName(componentName, components) {
|
|
|
114033
114104
|
|
|
114034
114105
|
|
|
114035
114106
|
|
|
114036
|
-
const
|
|
114107
|
+
const mdxish_components_INLINE_COMPONENT_TAGS = new Set(['anchor', 'glossary']);
|
|
114037
114108
|
function isElementContentNode(node) {
|
|
114038
114109
|
return node.type === 'element' || node.type === 'text' || node.type === 'comment';
|
|
114039
114110
|
}
|
|
@@ -114115,7 +114186,7 @@ function parseTextChildren(node, processMarkdown, components) {
|
|
|
114115
114186
|
const hast = processMarkdown(child.value.trim());
|
|
114116
114187
|
const children = (hast.children ?? []).filter(isElementContentNode);
|
|
114117
114188
|
// For inline components, preserve plain text instead of wrapping in <p>
|
|
114118
|
-
if (
|
|
114189
|
+
if (mdxish_components_INLINE_COMPONENT_TAGS.has(node.tagName.toLowerCase()) && isSingleParagraphTextNode(children)) {
|
|
114119
114190
|
return [child];
|
|
114120
114191
|
}
|
|
114121
114192
|
return children;
|
|
@@ -114488,10 +114559,14 @@ function extractBalancedBraces(content, start) {
|
|
|
114488
114559
|
return { content: content.slice(start, pos - 1), end: pos };
|
|
114489
114560
|
}
|
|
114490
114561
|
/**
|
|
114491
|
-
* Escapes
|
|
114492
|
-
* Handles
|
|
114562
|
+
* Escapes problematic braces in content to prevent MDX expression parsing errors.
|
|
114563
|
+
* Handles three cases:
|
|
114564
|
+
* 1. Unbalanced braces (e.g., `{foo` without closing `}`)
|
|
114565
|
+
* 2. Paragraph-spanning expressions (e.g., `{\n\n}` where blank line splits paragraphs)
|
|
114566
|
+
* 3. Skips HTML elements to prevent backslashes appearing in output
|
|
114567
|
+
*
|
|
114493
114568
|
*/
|
|
114494
|
-
function
|
|
114569
|
+
function escapeProblematicBraces(content) {
|
|
114495
114570
|
// Skip HTML elements — their content should never be escaped because
|
|
114496
114571
|
// rehypeRaw parses them into hast elements, making `\` literal text in output
|
|
114497
114572
|
const htmlElements = [];
|
|
@@ -114500,16 +114575,19 @@ function escapeUnbalancedBraces(content) {
|
|
|
114500
114575
|
htmlElements.push(match);
|
|
114501
114576
|
return `___HTML_ELEM_${idx}___`;
|
|
114502
114577
|
});
|
|
114503
|
-
const
|
|
114504
|
-
const unbalanced = new Set();
|
|
114505
|
-
let strDelim = null;
|
|
114506
|
-
let strEscaped = false;
|
|
114578
|
+
const toEscape = new Set();
|
|
114507
114579
|
// Convert to array of Unicode code points to handle emojis and multi-byte characters correctly
|
|
114508
114580
|
const chars = Array.from(safe);
|
|
114581
|
+
let strDelim = null;
|
|
114582
|
+
let strEscaped = false;
|
|
114583
|
+
// Stack of open braces with their state
|
|
114584
|
+
const openStack = [];
|
|
114585
|
+
// Track position of last newline (outside strings) to detect blank lines
|
|
114586
|
+
let lastNewlinePos = -2; // -2 means no recent newline
|
|
114509
114587
|
for (let i = 0; i < chars.length; i += 1) {
|
|
114510
114588
|
const ch = chars[i];
|
|
114511
|
-
// Track
|
|
114512
|
-
if (
|
|
114589
|
+
// Track string delimiters inside expressions to ignore braces within them
|
|
114590
|
+
if (openStack.length > 0) {
|
|
114513
114591
|
if (strDelim) {
|
|
114514
114592
|
if (strEscaped)
|
|
114515
114593
|
strEscaped = false;
|
|
@@ -114525,6 +114603,20 @@ function escapeUnbalancedBraces(content) {
|
|
|
114525
114603
|
// eslint-disable-next-line no-continue
|
|
114526
114604
|
continue;
|
|
114527
114605
|
}
|
|
114606
|
+
// Track newlines to detect blank lines (paragraph boundaries)
|
|
114607
|
+
if (ch === '\n') {
|
|
114608
|
+
// Check if this newline creates a blank line (only whitespace since last newline)
|
|
114609
|
+
if (lastNewlinePos >= 0) {
|
|
114610
|
+
const between = chars.slice(lastNewlinePos + 1, i).join('');
|
|
114611
|
+
if (/^[ \t]*$/.test(between)) {
|
|
114612
|
+
// This is a blank line - mark all open expressions as paragraph-spanning
|
|
114613
|
+
openStack.forEach(entry => {
|
|
114614
|
+
entry.hasBlankLine = true;
|
|
114615
|
+
});
|
|
114616
|
+
}
|
|
114617
|
+
}
|
|
114618
|
+
lastNewlinePos = i;
|
|
114619
|
+
}
|
|
114528
114620
|
}
|
|
114529
114621
|
// Skip already-escaped braces (count preceding backslashes)
|
|
114530
114622
|
if (ch === '{' || ch === '}') {
|
|
@@ -114536,21 +114628,33 @@ function escapeUnbalancedBraces(content) {
|
|
|
114536
114628
|
continue;
|
|
114537
114629
|
}
|
|
114538
114630
|
}
|
|
114539
|
-
if (ch === '{')
|
|
114540
|
-
|
|
114631
|
+
if (ch === '{') {
|
|
114632
|
+
openStack.push({ pos: i, hasBlankLine: false });
|
|
114633
|
+
lastNewlinePos = -2; // Reset newline tracking for new expression
|
|
114634
|
+
}
|
|
114541
114635
|
else if (ch === '}') {
|
|
114542
|
-
if (
|
|
114543
|
-
|
|
114544
|
-
|
|
114545
|
-
|
|
114636
|
+
if (openStack.length > 0) {
|
|
114637
|
+
const entry = openStack.pop();
|
|
114638
|
+
// If expression spans paragraph boundary, escape both braces
|
|
114639
|
+
if (entry.hasBlankLine) {
|
|
114640
|
+
toEscape.add(entry.pos);
|
|
114641
|
+
toEscape.add(i);
|
|
114642
|
+
}
|
|
114643
|
+
}
|
|
114644
|
+
else {
|
|
114645
|
+
// Unbalanced closing brace (no matching open)
|
|
114646
|
+
toEscape.add(i);
|
|
114647
|
+
}
|
|
114546
114648
|
}
|
|
114547
114649
|
}
|
|
114548
|
-
|
|
114549
|
-
|
|
114550
|
-
//
|
|
114551
|
-
|
|
114650
|
+
// Any remaining open braces are unbalanced
|
|
114651
|
+
openStack.forEach(entry => toEscape.add(entry.pos));
|
|
114652
|
+
// If there are no problematic braces, return safe content as-is;
|
|
114653
|
+
// otherwise, escape each problematic `{` or `}` so MDX doesn't treat them as expressions.
|
|
114654
|
+
let result = toEscape.size === 0
|
|
114552
114655
|
? safe
|
|
114553
|
-
: chars.map((ch, i) => (
|
|
114656
|
+
: chars.map((ch, i) => (toEscape.has(i) ? `\\${ch}` : ch)).join('');
|
|
114657
|
+
// Restore HTML elements
|
|
114554
114658
|
if (htmlElements.length > 0) {
|
|
114555
114659
|
result = result.replace(/___HTML_ELEM_(\d+)___/g, (_m, idx) => htmlElements[parseInt(idx, 10)]);
|
|
114556
114660
|
}
|
|
@@ -114648,8 +114752,9 @@ function preprocessJSXExpressions(content, context = {}) {
|
|
|
114648
114752
|
// For inline expressions, we use a library to parse the expression & evaluate it later
|
|
114649
114753
|
// For attribute expressions, it was difficult to use a library to parse them, so do it manually
|
|
114650
114754
|
processed = evaluateAttributeExpressions(protectedContent, context, protectedCode);
|
|
114651
|
-
// Step 3: Escape
|
|
114652
|
-
|
|
114755
|
+
// Step 3: Escape problematic braces to prevent MDX expression parsing errors
|
|
114756
|
+
// This handles both unbalanced braces and paragraph-spanning expressions in one pass
|
|
114757
|
+
processed = escapeProblematicBraces(processed);
|
|
114653
114758
|
// Step 4: Restore protected code blocks
|
|
114654
114759
|
processed = restoreCodeBlocks(processed, protectedCode);
|
|
114655
114760
|
return processed;
|
|
@@ -116414,10 +116519,82 @@ const mdxishHtmlBlocks = () => tree => {
|
|
|
116414
116519
|
};
|
|
116415
116520
|
/* harmony default export */ const mdxish_html_blocks = (mdxishHtmlBlocks);
|
|
116416
116521
|
|
|
116522
|
+
;// ./processor/transform/mdxish/mdxish-inline-components.ts
|
|
116523
|
+
|
|
116524
|
+
|
|
116525
|
+
|
|
116526
|
+
// Matches any PascalCase inline component opening tag. Groups: (name, attrs).
|
|
116527
|
+
// Uses [A-Za-z0-9_]* to match block version in mdxish-component-blocks.ts
|
|
116528
|
+
const INLINE_COMPONENT_OPEN_RE = /^<([A-Z][A-Za-z0-9_]*)(\s[^>]*)?>$/;
|
|
116529
|
+
function toMdxJsxTextElement(name, attributes, children) {
|
|
116530
|
+
return {
|
|
116531
|
+
type: 'mdxJsxTextElement',
|
|
116532
|
+
name,
|
|
116533
|
+
attributes,
|
|
116534
|
+
children,
|
|
116535
|
+
};
|
|
116536
|
+
}
|
|
116537
|
+
/**
|
|
116538
|
+
* Transforms inline html component nodes (e.g. <Anchor>) into proper MDAST phrasing content.
|
|
116539
|
+
*
|
|
116540
|
+
* Inline components are excluded from mdxishComponentBlocks (which only handles block-level
|
|
116541
|
+
* elements), so they remain as scattered html/text/html sibling nodes inside a paragraph.
|
|
116542
|
+
* This plugin merges them into a single typed MDAST node.
|
|
116543
|
+
*/
|
|
116544
|
+
const mdxishInlineComponents = () => tree => {
|
|
116545
|
+
visit(tree, 'html', (node, index, parent) => {
|
|
116546
|
+
if (!parent || index === undefined)
|
|
116547
|
+
return;
|
|
116548
|
+
const match = node.value?.match(INLINE_COMPONENT_OPEN_RE);
|
|
116549
|
+
if (!match)
|
|
116550
|
+
return;
|
|
116551
|
+
const [, name, attrStr] = match;
|
|
116552
|
+
if (!INLINE_COMPONENT_TAGS.has(name))
|
|
116553
|
+
return;
|
|
116554
|
+
// Parse attributes directly - preserves all attribute types (strings, booleans, objects, arrays)
|
|
116555
|
+
const attributes = parseAttributes(attrStr ?? '');
|
|
116556
|
+
// Find closing tag with whitespace-tolerant matching
|
|
116557
|
+
let closeIdx = index + 1;
|
|
116558
|
+
while (closeIdx < parent.children.length) {
|
|
116559
|
+
const sib = parent.children[closeIdx];
|
|
116560
|
+
if (sib.type === 'html' && sib.value?.trim() === `</${name}>`)
|
|
116561
|
+
break;
|
|
116562
|
+
closeIdx += 1;
|
|
116563
|
+
}
|
|
116564
|
+
if (closeIdx >= parent.children.length)
|
|
116565
|
+
return;
|
|
116566
|
+
// Extract all nodes between opening tag (index) and closing tag (closeIdx).
|
|
116567
|
+
// These are the inline component's children (e.g., text, emphasis, links).
|
|
116568
|
+
// Example: "<Anchor>click **here**</Anchor>" → children = [text, strong]
|
|
116569
|
+
const children = parent.children.slice(index + 1, closeIdx);
|
|
116570
|
+
const newNode = toMdxJsxTextElement(name, attributes, children);
|
|
116571
|
+
parent.children.splice(index, closeIdx - index + 1, newNode);
|
|
116572
|
+
});
|
|
116573
|
+
};
|
|
116574
|
+
/* harmony default export */ const mdxish_inline_components = (mdxishInlineComponents);
|
|
116575
|
+
|
|
116417
116576
|
;// ./processor/transform/mdxish/mdxish-jsx-to-mdast.ts
|
|
116418
116577
|
|
|
116419
116578
|
|
|
116420
116579
|
|
|
116580
|
+
const transformAnchor = (jsx) => {
|
|
116581
|
+
const attrs = getAttrs(jsx);
|
|
116582
|
+
const { href = '', label, target, title } = attrs;
|
|
116583
|
+
return {
|
|
116584
|
+
type: NodeTypes.anchor,
|
|
116585
|
+
children: jsx.children,
|
|
116586
|
+
data: {
|
|
116587
|
+
hName: 'Anchor',
|
|
116588
|
+
hProperties: {
|
|
116589
|
+
href,
|
|
116590
|
+
...(label && { label }),
|
|
116591
|
+
...(target && { target }),
|
|
116592
|
+
...(title && { title }),
|
|
116593
|
+
},
|
|
116594
|
+
},
|
|
116595
|
+
position: jsx.position,
|
|
116596
|
+
};
|
|
116597
|
+
};
|
|
116421
116598
|
const transformImage = (jsx) => {
|
|
116422
116599
|
const attrs = getAttrs(jsx);
|
|
116423
116600
|
const { align, alt = '', border, caption, className, height, lazy, src = '', title = '', width } = attrs;
|
|
@@ -116471,7 +116648,7 @@ const transformCallout = (jsx) => {
|
|
|
116471
116648
|
};
|
|
116472
116649
|
const transformEmbed = (jsx) => {
|
|
116473
116650
|
const attrs = getAttrs(jsx);
|
|
116474
|
-
const { favicon, html, iframe, image, providerName, providerUrl, title = '', url = '' } = attrs;
|
|
116651
|
+
const { favicon, height, html, iframe, image, providerName, providerUrl, title = '', typeOfEmbed, url = '', width } = attrs;
|
|
116475
116652
|
return {
|
|
116476
116653
|
type: NodeTypes.embedBlock,
|
|
116477
116654
|
title,
|
|
@@ -116482,11 +116659,14 @@ const transformEmbed = (jsx) => {
|
|
|
116482
116659
|
title,
|
|
116483
116660
|
url,
|
|
116484
116661
|
...(favicon && { favicon }),
|
|
116662
|
+
...(height && { height }),
|
|
116485
116663
|
...(html && { html }),
|
|
116486
116664
|
...(iframe !== undefined && { iframe }),
|
|
116487
116665
|
...(image && { image }),
|
|
116488
116666
|
...(providerName && { providerName }),
|
|
116489
116667
|
...(providerUrl && { providerUrl }),
|
|
116668
|
+
...(typeOfEmbed && { typeOfEmbed }),
|
|
116669
|
+
...(width && { width }),
|
|
116490
116670
|
},
|
|
116491
116671
|
},
|
|
116492
116672
|
position: jsx.position,
|
|
@@ -116582,7 +116762,7 @@ const COMPONENT_MAP = {
|
|
|
116582
116762
|
* This is controlled by the `newEditorTypes` flag to maintain backwards compatibility.
|
|
116583
116763
|
*/
|
|
116584
116764
|
const mdxishJsxToMdast = () => tree => {
|
|
116585
|
-
//
|
|
116765
|
+
// Block JSX components (Image, Callout, Embed, Recipe)
|
|
116586
116766
|
visit(tree, 'mdxJsxFlowElement', (node, index, parent) => {
|
|
116587
116767
|
if (!parent || index === undefined || !node.name)
|
|
116588
116768
|
return;
|
|
@@ -116593,6 +116773,15 @@ const mdxishJsxToMdast = () => tree => {
|
|
|
116593
116773
|
// Replace the JSX node with the MDAST node
|
|
116594
116774
|
parent.children[index] = newNode;
|
|
116595
116775
|
});
|
|
116776
|
+
// Inline JSX components (Anchor)
|
|
116777
|
+
visit(tree, 'mdxJsxTextElement', (node, index, parent) => {
|
|
116778
|
+
if (!parent || index === undefined || !node.name)
|
|
116779
|
+
return;
|
|
116780
|
+
if (node.name === 'Anchor') {
|
|
116781
|
+
const newNode = transformAnchor(node);
|
|
116782
|
+
parent.children[index] = newNode;
|
|
116783
|
+
}
|
|
116784
|
+
});
|
|
116596
116785
|
// Transform magic block images (type: 'image') to image-block
|
|
116597
116786
|
// Note: Standard markdown images are wrapped in paragraphs and handled by imageTransformer
|
|
116598
116787
|
// Magic block images are direct children of root, so we handle them here
|
|
@@ -118186,6 +118375,7 @@ function loadComponents() {
|
|
|
118186
118375
|
|
|
118187
118376
|
|
|
118188
118377
|
|
|
118378
|
+
|
|
118189
118379
|
|
|
118190
118380
|
|
|
118191
118381
|
const defaultTransformers = [callouts, code_tabs, gemoji_, transform_embeds];
|
|
@@ -118247,7 +118437,9 @@ function mdxishAstProcessor(mdContent, opts = {}) {
|
|
|
118247
118437
|
.use(restore_snake_case_component_name, { mapping: snakeCaseMapping })
|
|
118248
118438
|
.use(mdxish_tables)
|
|
118249
118439
|
.use(mdxish_html_blocks)
|
|
118250
|
-
.use(newEditorTypes ?
|
|
118440
|
+
.use(newEditorTypes ? mdxish_inline_components : undefined) // Merge inline html components (e.g. <Anchor>) into MDAST nodes
|
|
118441
|
+
.use(newEditorTypes ? mdxish_jsx_to_mdast : undefined) // Convert block JSX elements to MDAST types
|
|
118442
|
+
.use(safeMode ? undefined : evaluate_expressions, { context: jsxContext }) // Evaluate MDX expressions using jsxContext
|
|
118251
118443
|
.use(variables_text) // Parse {user.*} patterns from text nodes
|
|
118252
118444
|
.use(useTailwind ? transform_tailwind : undefined, { components: tempComponentsMap })
|
|
118253
118445
|
.use(remarkGfm);
|