@readme/markdown 13.0.0 → 13.1.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/components/Tabs/style.scss +2 -2
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/mdxish.d.ts +10 -0
- package/dist/main.css +1 -1
- package/dist/main.css.map +1 -1
- package/dist/main.js +436 -151
- package/dist/main.node.js +436 -151
- package/dist/main.node.js.map +1 -1
- package/package.json +1 -1
package/dist/main.node.js
CHANGED
|
@@ -73306,6 +73306,59 @@ const isCalloutStructure = (node) => {
|
|
|
73306
73306
|
const firstTextChild = firstChild.children?.[0];
|
|
73307
73307
|
return firstTextChild?.type === 'text';
|
|
73308
73308
|
};
|
|
73309
|
+
/**
|
|
73310
|
+
* Finds the first text node containing a newline in a paragraph's children.
|
|
73311
|
+
* Returns the index and the newline position within that text node.
|
|
73312
|
+
*/
|
|
73313
|
+
const findNewlineInParagraph = (paragraph) => {
|
|
73314
|
+
for (let i = 0; i < paragraph.children.length; i += 1) {
|
|
73315
|
+
const child = paragraph.children[i];
|
|
73316
|
+
if (child.type === 'text' && typeof child.value === 'string') {
|
|
73317
|
+
const newlineIndex = child.value.indexOf('\n');
|
|
73318
|
+
if (newlineIndex !== -1) {
|
|
73319
|
+
return { index: i, newlineIndex };
|
|
73320
|
+
}
|
|
73321
|
+
}
|
|
73322
|
+
}
|
|
73323
|
+
return null;
|
|
73324
|
+
};
|
|
73325
|
+
/**
|
|
73326
|
+
* Splits a paragraph at the first newline, separating heading content (before \n)
|
|
73327
|
+
* from body content (after \n). Mutates the paragraph to contain only heading children.
|
|
73328
|
+
*/
|
|
73329
|
+
const splitParagraphAtNewline = (paragraph) => {
|
|
73330
|
+
const splitPoint = findNewlineInParagraph(paragraph);
|
|
73331
|
+
if (!splitPoint)
|
|
73332
|
+
return null;
|
|
73333
|
+
const { index, newlineIndex } = splitPoint;
|
|
73334
|
+
const originalChildren = paragraph.children;
|
|
73335
|
+
const textNode = originalChildren[index];
|
|
73336
|
+
const beforeNewline = textNode.value.slice(0, newlineIndex);
|
|
73337
|
+
const afterNewline = textNode.value.slice(newlineIndex + 1);
|
|
73338
|
+
// Split paragraph: heading = children[0..index-1] + text before newline
|
|
73339
|
+
const headingChildren = originalChildren.slice(0, index);
|
|
73340
|
+
if (beforeNewline.length > 0 || headingChildren.length === 0) {
|
|
73341
|
+
headingChildren.push({ type: 'text', value: beforeNewline });
|
|
73342
|
+
}
|
|
73343
|
+
paragraph.children = headingChildren;
|
|
73344
|
+
// Body = text after newline + remaining children from original array
|
|
73345
|
+
const bodyChildren = [];
|
|
73346
|
+
if (afterNewline.length > 0) {
|
|
73347
|
+
bodyChildren.push({ type: 'text', value: afterNewline });
|
|
73348
|
+
}
|
|
73349
|
+
bodyChildren.push(...originalChildren.slice(index + 1));
|
|
73350
|
+
return bodyChildren.length > 0 ? bodyChildren : null;
|
|
73351
|
+
};
|
|
73352
|
+
/**
|
|
73353
|
+
* Removes the icon/match prefix from the first text node in a paragraph.
|
|
73354
|
+
* This is needed to clean up the raw AST after we've extracted the icon.
|
|
73355
|
+
*/
|
|
73356
|
+
const removeIconPrefix = (paragraph, prefixLength) => {
|
|
73357
|
+
const firstTextNode = findFirst(paragraph);
|
|
73358
|
+
if (firstTextNode && 'value' in firstTextNode && typeof firstTextNode.value === 'string') {
|
|
73359
|
+
firstTextNode.value = firstTextNode.value.slice(prefixLength);
|
|
73360
|
+
}
|
|
73361
|
+
};
|
|
73309
73362
|
const processBlockquote = (node, index, parent) => {
|
|
73310
73363
|
if (!isCalloutStructure(node)) {
|
|
73311
73364
|
// Only stringify empty blockquotes (no extractable text content)
|
|
@@ -73330,22 +73383,39 @@ const processBlockquote = (node, index, parent) => {
|
|
|
73330
73383
|
const firstParagraph = node.children[0];
|
|
73331
73384
|
const startText = lib_plain(firstParagraph).toString();
|
|
73332
73385
|
const [match, icon] = startText.match(callouts_regex) || [];
|
|
73386
|
+
const firstParagraphOriginalEnd = firstParagraph.position.end;
|
|
73333
73387
|
if (icon && match) {
|
|
73334
|
-
|
|
73335
|
-
|
|
73388
|
+
// Handle cases where heading and body are on the same line separated by a newline.
|
|
73389
|
+
// Example: "> ⚠️ **Bold heading**\nBody text here"
|
|
73390
|
+
const bodyChildren = splitParagraphAtNewline(firstParagraph);
|
|
73391
|
+
const didSplit = bodyChildren !== null;
|
|
73392
|
+
// Extract heading text after removing the icon prefix.
|
|
73393
|
+
// Use `plain()` to handle complex markdown structures (bold, inline code, etc.)
|
|
73394
|
+
const headingText = lib_plain(firstParagraph)
|
|
73395
|
+
.toString()
|
|
73396
|
+
.slice(match.length);
|
|
73397
|
+
// Clean up the raw AST by removing the icon prefix from the first text node
|
|
73398
|
+
removeIconPrefix(firstParagraph, match.length);
|
|
73399
|
+
const empty = !headingText.length && firstParagraph.children.length === 1;
|
|
73336
73400
|
const theme = themes[icon] || 'default';
|
|
73337
|
-
|
|
73338
|
-
if (
|
|
73339
|
-
firstChild.value = firstChild.value.slice(match.length);
|
|
73340
|
-
}
|
|
73341
|
-
if (heading) {
|
|
73401
|
+
// Convert the first paragraph (first children of node) to a heading if it has content or was split
|
|
73402
|
+
if (headingText || didSplit) {
|
|
73342
73403
|
node.children[0] = wrapHeading(node);
|
|
73343
|
-
//
|
|
73344
|
-
// character that was stripped off, so that the start position of the
|
|
73345
|
-
// heading/text matches where it actually starts.
|
|
73404
|
+
// Adjust position to account for the stripped icon prefix
|
|
73346
73405
|
node.children[0].position.start.offset += match.length;
|
|
73347
73406
|
node.children[0].position.start.column += match.length;
|
|
73348
73407
|
}
|
|
73408
|
+
// Insert body content as a separate paragraph after the heading
|
|
73409
|
+
if (bodyChildren) {
|
|
73410
|
+
node.children.splice(1, 0, {
|
|
73411
|
+
type: 'paragraph',
|
|
73412
|
+
children: bodyChildren,
|
|
73413
|
+
position: {
|
|
73414
|
+
start: node.children[0].position.end,
|
|
73415
|
+
end: firstParagraphOriginalEnd,
|
|
73416
|
+
},
|
|
73417
|
+
});
|
|
73418
|
+
}
|
|
73349
73419
|
Object.assign(node, {
|
|
73350
73420
|
type: NodeTypes.callout,
|
|
73351
73421
|
data: {
|
|
@@ -106760,7 +106830,7 @@ const CUSTOM_PROP_BOUNDARIES = [
|
|
|
106760
106830
|
/**
|
|
106761
106831
|
* Tags that should be passed through and handled at runtime (not by the mdxish plugin)
|
|
106762
106832
|
*/
|
|
106763
|
-
const RUNTIME_COMPONENT_TAGS = new Set(['Variable', 'variable', 'rdme-pin']);
|
|
106833
|
+
const RUNTIME_COMPONENT_TAGS = new Set(['Variable', 'variable', 'html-block', 'rdme-pin']);
|
|
106764
106834
|
/**
|
|
106765
106835
|
* Standard HTML tags that should never be treated as custom components.
|
|
106766
106836
|
* Uses the html-tags package, converted to a Set<string> for efficient lookups.
|
|
@@ -114056,6 +114126,349 @@ const evaluateExpressions = ({ context = {} } = {}) => tree => {
|
|
|
114056
114126
|
};
|
|
114057
114127
|
/* harmony default export */ const evaluate_expressions = (evaluateExpressions);
|
|
114058
114128
|
|
|
114129
|
+
;// ./processor/transform/mdxish/normalize-malformed-md-syntax.ts
|
|
114130
|
+
|
|
114131
|
+
// Marker patterns for multi-node emphasis detection
|
|
114132
|
+
const MARKER_PATTERNS = [
|
|
114133
|
+
{ isBold: true, marker: '**' },
|
|
114134
|
+
{ isBold: true, marker: '__' },
|
|
114135
|
+
{ isBold: false, marker: '*' },
|
|
114136
|
+
{ isBold: false, marker: '_' },
|
|
114137
|
+
];
|
|
114138
|
+
// Patterns to detect for bold (** and __) and italic (* and _) syntax:
|
|
114139
|
+
// Bold: ** text**, **text **, word** text**, ** text **
|
|
114140
|
+
// Italic: * text*, *text *, word* text*, * text *
|
|
114141
|
+
// Same patterns for underscore variants
|
|
114142
|
+
// We use separate patterns for each marker type to allow this flexibility.
|
|
114143
|
+
// Pattern for ** bold **
|
|
114144
|
+
// Groups: 1=wordBefore, 2=marker, 3=contentWithSpaceAfter, 4=trailingSpace1, 5=contentWithSpaceBefore, 6=trailingSpace2, 7=afterChar
|
|
114145
|
+
// trailingSpace1 is for "** text **" pattern, trailingSpace2 is for "**text **" pattern
|
|
114146
|
+
const asteriskBoldRegex = /([^*\s]+)?\s*(\*\*)(?:\s+((?:[^*\n]|\*(?!\*))+?)(\s*)\2|((?:[^*\n]|\*(?!\*))+?)(\s+)\2)(\S|$)?/g;
|
|
114147
|
+
// Pattern for __ bold __
|
|
114148
|
+
const underscoreBoldRegex = /([^_\s]+)?\s*(__)(?:\s+((?:[^_\n]|_(?!_))+?)(\s*)\2|((?:[^_\n]|_(?!_))+?)(\s+)\2)(\S|$)?/g;
|
|
114149
|
+
// Pattern for * italic *
|
|
114150
|
+
const asteriskItalicRegex = /([^*\s]+)?\s*(\*)(?!\*)(?:\s+([^*\n]+?)(\s*)\2|([^*\n]+?)(\s+)\2)(\S|$)?/g;
|
|
114151
|
+
// Pattern for _ italic _
|
|
114152
|
+
const underscoreItalicRegex = /([^_\s]+)?\s*(_)(?!_)(?:\s+([^_\n]+?)(\s*)\2|([^_\n]+?)(\s+)\2)(\S|$)?/g;
|
|
114153
|
+
// CommonMark ignores intraword underscores or asteriks, but we want to italicize/bold the inner part
|
|
114154
|
+
// Pattern for intraword _word_ in words like hello_world_
|
|
114155
|
+
const intrawordUnderscoreItalicRegex = /(\w)_(?!_)([a-zA-Z0-9]+)_(?![\w_])/g;
|
|
114156
|
+
// Pattern for intraword __word__ in words like hello__world__
|
|
114157
|
+
const intrawordUnderscoreBoldRegex = /(\w)__([a-zA-Z0-9]+)__(?![\w_])/g;
|
|
114158
|
+
// Pattern for intraword *word* in words like hello*world*
|
|
114159
|
+
const intrawordAsteriskItalicRegex = /(\w)\*(?!\*)([a-zA-Z0-9]+)\*(?![\w*])/g;
|
|
114160
|
+
// Pattern for intraword **word** in words like hello**world**
|
|
114161
|
+
const intrawordAsteriskBoldRegex = /(\w)\*\*([a-zA-Z0-9]+)\*\*(?![\w*])/g;
|
|
114162
|
+
/**
|
|
114163
|
+
* Finds opening emphasis marker in a text value.
|
|
114164
|
+
* Returns marker info if found, null otherwise.
|
|
114165
|
+
*/
|
|
114166
|
+
function findOpeningMarker(text) {
|
|
114167
|
+
const results = MARKER_PATTERNS.map(({ isBold, marker }) => {
|
|
114168
|
+
if (marker === '*' && text.startsWith('**'))
|
|
114169
|
+
return null;
|
|
114170
|
+
if (marker === '_' && text.startsWith('__'))
|
|
114171
|
+
return null;
|
|
114172
|
+
if (text.startsWith(marker) && text.length > marker.length) {
|
|
114173
|
+
return { isBold, marker, textAfter: text.slice(marker.length), textBefore: '' };
|
|
114174
|
+
}
|
|
114175
|
+
const idx = text.indexOf(marker);
|
|
114176
|
+
if (idx > 0 && !/\s/.test(text[idx - 1])) {
|
|
114177
|
+
if (marker === '*' && text.slice(idx).startsWith('**'))
|
|
114178
|
+
return null;
|
|
114179
|
+
if (marker === '_' && text.slice(idx).startsWith('__'))
|
|
114180
|
+
return null;
|
|
114181
|
+
const after = text.slice(idx + marker.length);
|
|
114182
|
+
if (after.length > 0) {
|
|
114183
|
+
return { isBold, marker, textAfter: after, textBefore: text.slice(0, idx) };
|
|
114184
|
+
}
|
|
114185
|
+
}
|
|
114186
|
+
return null;
|
|
114187
|
+
});
|
|
114188
|
+
return results.find(r => r !== null) ?? null;
|
|
114189
|
+
}
|
|
114190
|
+
/**
|
|
114191
|
+
* Finds the end/closing marker in a text node for multi-node emphasis.
|
|
114192
|
+
*/
|
|
114193
|
+
function findEndMarker(text, marker) {
|
|
114194
|
+
const spacePattern = ` ${marker}`;
|
|
114195
|
+
const spaceIdx = text.indexOf(spacePattern);
|
|
114196
|
+
if (spaceIdx >= 0) {
|
|
114197
|
+
if (marker === '*' && text.slice(spaceIdx + 1).startsWith('**'))
|
|
114198
|
+
return null;
|
|
114199
|
+
if (marker === '_' && text.slice(spaceIdx + 1).startsWith('__'))
|
|
114200
|
+
return null;
|
|
114201
|
+
return {
|
|
114202
|
+
textAfter: text.slice(spaceIdx + spacePattern.length),
|
|
114203
|
+
textBefore: text.slice(0, spaceIdx),
|
|
114204
|
+
};
|
|
114205
|
+
}
|
|
114206
|
+
if (text.startsWith(marker)) {
|
|
114207
|
+
if (marker === '*' && text.startsWith('**'))
|
|
114208
|
+
return null;
|
|
114209
|
+
if (marker === '_' && text.startsWith('__'))
|
|
114210
|
+
return null;
|
|
114211
|
+
return {
|
|
114212
|
+
textAfter: text.slice(marker.length),
|
|
114213
|
+
textBefore: '',
|
|
114214
|
+
};
|
|
114215
|
+
}
|
|
114216
|
+
return null;
|
|
114217
|
+
}
|
|
114218
|
+
/**
|
|
114219
|
+
* Scan children for an opening emphasis marker in a text node.
|
|
114220
|
+
*/
|
|
114221
|
+
function findOpeningInChildren(children) {
|
|
114222
|
+
let result = null;
|
|
114223
|
+
children.some((child, idx) => {
|
|
114224
|
+
if (child.type !== 'text')
|
|
114225
|
+
return false;
|
|
114226
|
+
const found = findOpeningMarker(child.value);
|
|
114227
|
+
if (found) {
|
|
114228
|
+
result = { idx, opening: found };
|
|
114229
|
+
return true;
|
|
114230
|
+
}
|
|
114231
|
+
return false;
|
|
114232
|
+
});
|
|
114233
|
+
return result;
|
|
114234
|
+
}
|
|
114235
|
+
/**
|
|
114236
|
+
* Scan children (after openingIdx) for a closing emphasis marker.
|
|
114237
|
+
*/
|
|
114238
|
+
function findClosingInChildren(children, openingIdx, marker) {
|
|
114239
|
+
let result = null;
|
|
114240
|
+
children.slice(openingIdx + 1).some((child, relativeIdx) => {
|
|
114241
|
+
if (child.type !== 'text')
|
|
114242
|
+
return false;
|
|
114243
|
+
const found = findEndMarker(child.value, marker);
|
|
114244
|
+
if (found) {
|
|
114245
|
+
result = { closingIdx: openingIdx + 1 + relativeIdx, closing: found };
|
|
114246
|
+
return true;
|
|
114247
|
+
}
|
|
114248
|
+
return false;
|
|
114249
|
+
});
|
|
114250
|
+
return result;
|
|
114251
|
+
}
|
|
114252
|
+
/**
|
|
114253
|
+
* Build the replacement nodes for a matched emphasis pair.
|
|
114254
|
+
*/
|
|
114255
|
+
function buildReplacementNodes(container, { opening, openingIdx, closing, closingIdx }) {
|
|
114256
|
+
const newNodes = [];
|
|
114257
|
+
if (opening.textBefore) {
|
|
114258
|
+
newNodes.push({ type: 'text', value: `${opening.textBefore} ` });
|
|
114259
|
+
}
|
|
114260
|
+
const emphasisChildren = [];
|
|
114261
|
+
const openingText = opening.textAfter.replace(/^\s+/, '');
|
|
114262
|
+
if (openingText) {
|
|
114263
|
+
emphasisChildren.push({ type: 'text', value: openingText });
|
|
114264
|
+
}
|
|
114265
|
+
container.children.slice(openingIdx + 1, closingIdx).forEach(child => {
|
|
114266
|
+
emphasisChildren.push(child);
|
|
114267
|
+
});
|
|
114268
|
+
const closingText = closing.textBefore.replace(/\s+$/, '');
|
|
114269
|
+
if (closingText) {
|
|
114270
|
+
emphasisChildren.push({ type: 'text', value: closingText });
|
|
114271
|
+
}
|
|
114272
|
+
if (emphasisChildren.length > 0) {
|
|
114273
|
+
const emphasisNode = opening.isBold
|
|
114274
|
+
? { type: 'strong', children: emphasisChildren }
|
|
114275
|
+
: { type: 'emphasis', children: emphasisChildren };
|
|
114276
|
+
newNodes.push(emphasisNode);
|
|
114277
|
+
}
|
|
114278
|
+
if (closing.textAfter) {
|
|
114279
|
+
newNodes.push({ type: 'text', value: closing.textAfter });
|
|
114280
|
+
}
|
|
114281
|
+
return newNodes;
|
|
114282
|
+
}
|
|
114283
|
+
/**
|
|
114284
|
+
* Find and transform one multi-node emphasis pair in the container.
|
|
114285
|
+
* Returns true if a pair was found and transformed, false otherwise.
|
|
114286
|
+
*/
|
|
114287
|
+
function processOneEmphasisPair(container) {
|
|
114288
|
+
const openingResult = findOpeningInChildren(container.children);
|
|
114289
|
+
if (!openingResult)
|
|
114290
|
+
return false;
|
|
114291
|
+
const { idx: openingIdx, opening } = openingResult;
|
|
114292
|
+
const closingResult = findClosingInChildren(container.children, openingIdx, opening.marker);
|
|
114293
|
+
if (!closingResult)
|
|
114294
|
+
return false;
|
|
114295
|
+
const { closingIdx, closing } = closingResult;
|
|
114296
|
+
const newNodes = buildReplacementNodes(container, { opening, openingIdx, closing, closingIdx });
|
|
114297
|
+
const deleteCount = closingIdx - openingIdx + 1;
|
|
114298
|
+
container.children.splice(openingIdx, deleteCount, ...newNodes);
|
|
114299
|
+
return true;
|
|
114300
|
+
}
|
|
114301
|
+
/**
|
|
114302
|
+
* Handle malformed emphasis that spans multiple AST nodes.
|
|
114303
|
+
* E.g., "**bold [link](url)**" where markers are in different text nodes.
|
|
114304
|
+
*/
|
|
114305
|
+
function visitMultiNodeEmphasis(tree) {
|
|
114306
|
+
const containerTypes = ['paragraph', 'heading', 'tableCell', 'listItem', 'blockquote'];
|
|
114307
|
+
visit(tree, node => {
|
|
114308
|
+
if (!containerTypes.includes(node.type))
|
|
114309
|
+
return;
|
|
114310
|
+
if (!('children' in node) || !Array.isArray(node.children))
|
|
114311
|
+
return;
|
|
114312
|
+
const container = node;
|
|
114313
|
+
let foundPair = true;
|
|
114314
|
+
while (foundPair) {
|
|
114315
|
+
foundPair = processOneEmphasisPair(container);
|
|
114316
|
+
}
|
|
114317
|
+
});
|
|
114318
|
+
}
|
|
114319
|
+
/**
|
|
114320
|
+
* A remark plugin that normalizes malformed bold and italic markers in text nodes.
|
|
114321
|
+
* Detects patterns like `** bold**`, `Hello** Wrong Bold**`, `__ bold__`, `Hello__ Wrong Bold__`,
|
|
114322
|
+
* `* italic*`, `Hello* Wrong Italic*`, `_ italic_`, or `Hello_ Wrong Italic_`
|
|
114323
|
+
* and converts them to proper strong/emphasis nodes, matching the behavior of the legacy rdmd engine.
|
|
114324
|
+
*
|
|
114325
|
+
* Supports both asterisk (`**bold**`, `*italic*`) and underscore (`__bold__`, `_italic_`) syntax.
|
|
114326
|
+
* Also supports snake_case content like `** some_snake_case**`.
|
|
114327
|
+
*
|
|
114328
|
+
* This runs after remark-parse, which (in v11+) is strict and doesn't parse
|
|
114329
|
+
* malformed emphasis syntax. This plugin post-processes the AST to handle these cases.
|
|
114330
|
+
*/
|
|
114331
|
+
const normalizeEmphasisAST = () => (tree) => {
|
|
114332
|
+
visit(tree, 'text', function visitor(node, index, parent) {
|
|
114333
|
+
if (index === undefined || !parent)
|
|
114334
|
+
return undefined;
|
|
114335
|
+
// Skip if inside code blocks or inline code
|
|
114336
|
+
if (parent.type === 'inlineCode' || parent.type === 'code') {
|
|
114337
|
+
return undefined;
|
|
114338
|
+
}
|
|
114339
|
+
const text = node.value;
|
|
114340
|
+
const allMatches = [];
|
|
114341
|
+
[...text.matchAll(asteriskBoldRegex)].forEach(match => {
|
|
114342
|
+
allMatches.push({ isBold: true, marker: '**', match });
|
|
114343
|
+
});
|
|
114344
|
+
[...text.matchAll(underscoreBoldRegex)].forEach(match => {
|
|
114345
|
+
allMatches.push({ isBold: true, marker: '__', match });
|
|
114346
|
+
});
|
|
114347
|
+
[...text.matchAll(asteriskItalicRegex)].forEach(match => {
|
|
114348
|
+
allMatches.push({ isBold: false, marker: '*', match });
|
|
114349
|
+
});
|
|
114350
|
+
[...text.matchAll(underscoreItalicRegex)].forEach(match => {
|
|
114351
|
+
allMatches.push({ isBold: false, marker: '_', match });
|
|
114352
|
+
});
|
|
114353
|
+
[...text.matchAll(intrawordUnderscoreItalicRegex)].forEach(match => {
|
|
114354
|
+
allMatches.push({ isBold: false, isIntraword: true, marker: '_', match });
|
|
114355
|
+
});
|
|
114356
|
+
[...text.matchAll(intrawordUnderscoreBoldRegex)].forEach(match => {
|
|
114357
|
+
allMatches.push({ isBold: true, isIntraword: true, marker: '__', match });
|
|
114358
|
+
});
|
|
114359
|
+
[...text.matchAll(intrawordAsteriskItalicRegex)].forEach(match => {
|
|
114360
|
+
allMatches.push({ isBold: false, isIntraword: true, marker: '*', match });
|
|
114361
|
+
});
|
|
114362
|
+
[...text.matchAll(intrawordAsteriskBoldRegex)].forEach(match => {
|
|
114363
|
+
allMatches.push({ isBold: true, isIntraword: true, marker: '**', match });
|
|
114364
|
+
});
|
|
114365
|
+
if (allMatches.length === 0)
|
|
114366
|
+
return undefined;
|
|
114367
|
+
allMatches.sort((a, b) => (a.match.index ?? 0) - (b.match.index ?? 0));
|
|
114368
|
+
const filteredMatches = [];
|
|
114369
|
+
let lastEnd = 0;
|
|
114370
|
+
allMatches.forEach(info => {
|
|
114371
|
+
const start = info.match.index ?? 0;
|
|
114372
|
+
const end = start + info.match[0].length;
|
|
114373
|
+
if (start >= lastEnd) {
|
|
114374
|
+
filteredMatches.push(info);
|
|
114375
|
+
lastEnd = end;
|
|
114376
|
+
}
|
|
114377
|
+
});
|
|
114378
|
+
if (filteredMatches.length === 0)
|
|
114379
|
+
return undefined;
|
|
114380
|
+
const parts = [];
|
|
114381
|
+
let lastIndex = 0;
|
|
114382
|
+
filteredMatches.forEach(({ isBold, isIntraword, marker, match }) => {
|
|
114383
|
+
const matchIndex = match.index ?? 0;
|
|
114384
|
+
const fullMatch = match[0];
|
|
114385
|
+
if (isIntraword) {
|
|
114386
|
+
// handles cases like hello_world_ where we only want to italicize 'world'
|
|
114387
|
+
const charBefore = match[1] || ''; // e.g., "l" in "hello_world_"
|
|
114388
|
+
const content = match[2]; // e.g., "world"
|
|
114389
|
+
const combinedBefore = text.slice(lastIndex, matchIndex) + charBefore;
|
|
114390
|
+
if (combinedBefore) {
|
|
114391
|
+
parts.push({ type: 'text', value: combinedBefore });
|
|
114392
|
+
}
|
|
114393
|
+
if (isBold) {
|
|
114394
|
+
parts.push({
|
|
114395
|
+
type: 'strong',
|
|
114396
|
+
children: [{ type: 'text', value: content }],
|
|
114397
|
+
});
|
|
114398
|
+
}
|
|
114399
|
+
else {
|
|
114400
|
+
parts.push({
|
|
114401
|
+
type: 'emphasis',
|
|
114402
|
+
children: [{ type: 'text', value: content }],
|
|
114403
|
+
});
|
|
114404
|
+
}
|
|
114405
|
+
lastIndex = matchIndex + fullMatch.length;
|
|
114406
|
+
return;
|
|
114407
|
+
}
|
|
114408
|
+
if (matchIndex > lastIndex) {
|
|
114409
|
+
const beforeText = text.slice(lastIndex, matchIndex);
|
|
114410
|
+
if (beforeText) {
|
|
114411
|
+
parts.push({ type: 'text', value: beforeText });
|
|
114412
|
+
}
|
|
114413
|
+
}
|
|
114414
|
+
const wordBefore = match[1]; // e.g., "Hello" in "Hello** Wrong Bold**"
|
|
114415
|
+
const contentWithSpaceAfter = match[3]; // Content when there's a space after opening markers
|
|
114416
|
+
const trailingSpace1 = match[4] || ''; // Space before closing markers (for "** text **" pattern)
|
|
114417
|
+
const contentWithSpaceBefore = match[5]; // Content when there's only a space before closing markers
|
|
114418
|
+
const trailingSpace2 = match[6] || ''; // Space before closing markers (for "**text **" pattern)
|
|
114419
|
+
const trailingSpace = trailingSpace1 || trailingSpace2; // Combined trailing space
|
|
114420
|
+
const content = (contentWithSpaceAfter || contentWithSpaceBefore || '').trim();
|
|
114421
|
+
const afterChar = match[7]; // Character after closing markers (if any)
|
|
114422
|
+
const markerPos = fullMatch.indexOf(marker);
|
|
114423
|
+
const spacesBeforeMarkers = wordBefore
|
|
114424
|
+
? fullMatch.slice(wordBefore.length, markerPos)
|
|
114425
|
+
: fullMatch.slice(0, markerPos);
|
|
114426
|
+
const shouldAddSpace = !!contentWithSpaceAfter && !!wordBefore && !spacesBeforeMarkers;
|
|
114427
|
+
if (wordBefore) {
|
|
114428
|
+
const spacing = spacesBeforeMarkers + (shouldAddSpace ? ' ' : '');
|
|
114429
|
+
parts.push({ type: 'text', value: wordBefore + spacing });
|
|
114430
|
+
}
|
|
114431
|
+
else if (spacesBeforeMarkers) {
|
|
114432
|
+
parts.push({ type: 'text', value: spacesBeforeMarkers });
|
|
114433
|
+
}
|
|
114434
|
+
if (content) {
|
|
114435
|
+
if (isBold) {
|
|
114436
|
+
parts.push({
|
|
114437
|
+
type: 'strong',
|
|
114438
|
+
children: [{ type: 'text', value: content }],
|
|
114439
|
+
});
|
|
114440
|
+
}
|
|
114441
|
+
else {
|
|
114442
|
+
parts.push({
|
|
114443
|
+
type: 'emphasis',
|
|
114444
|
+
children: [{ type: 'text', value: content }],
|
|
114445
|
+
});
|
|
114446
|
+
}
|
|
114447
|
+
}
|
|
114448
|
+
if (afterChar) {
|
|
114449
|
+
const prefix = trailingSpace ? ' ' : '';
|
|
114450
|
+
parts.push({ type: 'text', value: prefix + afterChar });
|
|
114451
|
+
}
|
|
114452
|
+
lastIndex = matchIndex + fullMatch.length;
|
|
114453
|
+
});
|
|
114454
|
+
if (lastIndex < text.length) {
|
|
114455
|
+
const remainingText = text.slice(lastIndex);
|
|
114456
|
+
if (remainingText) {
|
|
114457
|
+
parts.push({ type: 'text', value: remainingText });
|
|
114458
|
+
}
|
|
114459
|
+
}
|
|
114460
|
+
if (parts.length > 0) {
|
|
114461
|
+
parent.children.splice(index, 1, ...parts);
|
|
114462
|
+
return [SKIP, index + parts.length];
|
|
114463
|
+
}
|
|
114464
|
+
return undefined;
|
|
114465
|
+
});
|
|
114466
|
+
// Handle malformed emphasis spanning multiple nodes (e.g., **text [link](url) **)
|
|
114467
|
+
visitMultiNodeEmphasis(tree);
|
|
114468
|
+
return tree;
|
|
114469
|
+
};
|
|
114470
|
+
/* harmony default export */ const normalize_malformed_md_syntax = (normalizeEmphasisAST);
|
|
114471
|
+
|
|
114059
114472
|
;// ./processor/transform/mdxish/magic-blocks/placeholder.ts
|
|
114060
114473
|
const EMPTY_IMAGE_PLACEHOLDER = {
|
|
114061
114474
|
type: 'image',
|
|
@@ -114108,6 +114521,7 @@ const EMPTY_CODE_PLACEHOLDER = {
|
|
|
114108
114521
|
|
|
114109
114522
|
|
|
114110
114523
|
|
|
114524
|
+
|
|
114111
114525
|
/**
|
|
114112
114526
|
* Wraps a node in a "pinned" container if sidebar: true is set.
|
|
114113
114527
|
*/
|
|
@@ -114135,7 +114549,8 @@ const imgWidthBySize = new Proxy(imgSizeValues, {
|
|
|
114135
114549
|
});
|
|
114136
114550
|
const textToInline = (text) => [{ type: 'text', value: text }];
|
|
114137
114551
|
const textToBlock = (text) => [{ children: textToInline(text), type: 'paragraph' }];
|
|
114138
|
-
|
|
114552
|
+
/** Parses markdown and html to markdown nodes */
|
|
114553
|
+
const contentParser = unified().use(remarkParse).use(remarkGfm).use(normalize_malformed_md_syntax);
|
|
114139
114554
|
const parseTableCell = (text) => {
|
|
114140
114555
|
if (!text.trim())
|
|
114141
114556
|
return [{ type: 'text', value: '' }];
|
|
@@ -115173,139 +115588,6 @@ function restoreSnakeCase(placeholderName, mapping) {
|
|
|
115173
115588
|
return matchingKey ? mapping[matchingKey] : placeholderName;
|
|
115174
115589
|
}
|
|
115175
115590
|
|
|
115176
|
-
;// ./processor/transform/mdxish/normalize-malformed-md-syntax.ts
|
|
115177
|
-
|
|
115178
|
-
// Patterns to detect for bold (** and __) and italic (* and _) syntax:
|
|
115179
|
-
// Bold: ** text**, **text **, word** text**, ** text **
|
|
115180
|
-
// Italic: * text*, *text *, word* text*, * text *
|
|
115181
|
-
// Same patterns for underscore variants
|
|
115182
|
-
// We use separate patterns for each marker type to allow this flexibility.
|
|
115183
|
-
// Pattern for ** bold **
|
|
115184
|
-
// Groups: 1=wordBefore, 2=marker, 3=contentWithSpaceAfter, 4=trailingSpace1, 5=contentWithSpaceBefore, 6=trailingSpace2, 7=afterChar
|
|
115185
|
-
// trailingSpace1 is for "** text **" pattern, trailingSpace2 is for "**text **" pattern
|
|
115186
|
-
const asteriskBoldRegex = /([^*\s]+)?\s*(\*\*)(?:\s+((?:[^*\n]|\*(?!\*))+?)(\s*)\2|((?:[^*\n]|\*(?!\*))+?)(\s+)\2)(\S|$)?/g;
|
|
115187
|
-
// Pattern for __ bold __
|
|
115188
|
-
const underscoreBoldRegex = /([^_\s]+)?\s*(__)(?:\s+((?:[^_\n]|_(?!_))+?)(\s*)\2|((?:[^_\n]|_(?!_))+?)(\s+)\2)(\S|$)?/g;
|
|
115189
|
-
// Pattern for * italic *
|
|
115190
|
-
const asteriskItalicRegex = /([^*\s]+)?\s*(\*)(?!\*)(?:\s+([^*\n]+?)(\s*)\2|([^*\n]+?)(\s+)\2)(\S|$)?/g;
|
|
115191
|
-
// Pattern for _ italic _
|
|
115192
|
-
const underscoreItalicRegex = /([^_\s]+)?\s*(_)(?!_)(?:\s+([^_\n]+?)(\s*)\2|([^_\n]+?)(\s+)\2)(\S|$)?/g;
|
|
115193
|
-
/**
|
|
115194
|
-
* A remark plugin that normalizes malformed bold and italic markers in text nodes.
|
|
115195
|
-
* Detects patterns like `** bold**`, `Hello** Wrong Bold**`, `__ bold__`, `Hello__ Wrong Bold__`,
|
|
115196
|
-
* `* italic*`, `Hello* Wrong Italic*`, `_ italic_`, or `Hello_ Wrong Italic_`
|
|
115197
|
-
* and converts them to proper strong/emphasis nodes, matching the behavior of the legacy rdmd engine.
|
|
115198
|
-
*
|
|
115199
|
-
* Supports both asterisk (`**bold**`, `*italic*`) and underscore (`__bold__`, `_italic_`) syntax.
|
|
115200
|
-
* Also supports snake_case content like `** some_snake_case**`.
|
|
115201
|
-
*
|
|
115202
|
-
* This runs after remark-parse, which (in v11+) is strict and doesn't parse
|
|
115203
|
-
* malformed emphasis syntax. This plugin post-processes the AST to handle these cases.
|
|
115204
|
-
*/
|
|
115205
|
-
const normalizeEmphasisAST = () => (tree) => {
|
|
115206
|
-
visit(tree, 'text', function visitor(node, index, parent) {
|
|
115207
|
-
if (index === undefined || !parent)
|
|
115208
|
-
return undefined;
|
|
115209
|
-
// Skip if inside code blocks or inline code
|
|
115210
|
-
if (parent.type === 'inlineCode' || parent.type === 'code') {
|
|
115211
|
-
return undefined;
|
|
115212
|
-
}
|
|
115213
|
-
const text = node.value;
|
|
115214
|
-
const allMatches = [];
|
|
115215
|
-
[...text.matchAll(asteriskBoldRegex)].forEach(match => {
|
|
115216
|
-
allMatches.push({ isBold: true, marker: '**', match });
|
|
115217
|
-
});
|
|
115218
|
-
[...text.matchAll(underscoreBoldRegex)].forEach(match => {
|
|
115219
|
-
allMatches.push({ isBold: true, marker: '__', match });
|
|
115220
|
-
});
|
|
115221
|
-
[...text.matchAll(asteriskItalicRegex)].forEach(match => {
|
|
115222
|
-
allMatches.push({ isBold: false, marker: '*', match });
|
|
115223
|
-
});
|
|
115224
|
-
[...text.matchAll(underscoreItalicRegex)].forEach(match => {
|
|
115225
|
-
allMatches.push({ isBold: false, marker: '_', match });
|
|
115226
|
-
});
|
|
115227
|
-
if (allMatches.length === 0)
|
|
115228
|
-
return undefined;
|
|
115229
|
-
allMatches.sort((a, b) => (a.match.index ?? 0) - (b.match.index ?? 0));
|
|
115230
|
-
const filteredMatches = [];
|
|
115231
|
-
let lastEnd = 0;
|
|
115232
|
-
allMatches.forEach(info => {
|
|
115233
|
-
const start = info.match.index ?? 0;
|
|
115234
|
-
const end = start + info.match[0].length;
|
|
115235
|
-
if (start >= lastEnd) {
|
|
115236
|
-
filteredMatches.push(info);
|
|
115237
|
-
lastEnd = end;
|
|
115238
|
-
}
|
|
115239
|
-
});
|
|
115240
|
-
if (filteredMatches.length === 0)
|
|
115241
|
-
return undefined;
|
|
115242
|
-
const parts = [];
|
|
115243
|
-
let lastIndex = 0;
|
|
115244
|
-
filteredMatches.forEach(({ match, marker, isBold }) => {
|
|
115245
|
-
const matchIndex = match.index ?? 0;
|
|
115246
|
-
const fullMatch = match[0];
|
|
115247
|
-
if (matchIndex > lastIndex) {
|
|
115248
|
-
const beforeText = text.slice(lastIndex, matchIndex);
|
|
115249
|
-
if (beforeText) {
|
|
115250
|
-
parts.push({ type: 'text', value: beforeText });
|
|
115251
|
-
}
|
|
115252
|
-
}
|
|
115253
|
-
const wordBefore = match[1]; // e.g., "Hello" in "Hello** Wrong Bold**"
|
|
115254
|
-
const contentWithSpaceAfter = match[3]; // Content when there's a space after opening markers
|
|
115255
|
-
const trailingSpace1 = match[4] || ''; // Space before closing markers (for "** text **" pattern)
|
|
115256
|
-
const contentWithSpaceBefore = match[5]; // Content when there's only a space before closing markers
|
|
115257
|
-
const trailingSpace2 = match[6] || ''; // Space before closing markers (for "**text **" pattern)
|
|
115258
|
-
const trailingSpace = trailingSpace1 || trailingSpace2; // Combined trailing space
|
|
115259
|
-
const content = (contentWithSpaceAfter || contentWithSpaceBefore || '').trim();
|
|
115260
|
-
const afterChar = match[7]; // Character after closing markers (if any)
|
|
115261
|
-
const markerPos = fullMatch.indexOf(marker);
|
|
115262
|
-
const spacesBeforeMarkers = wordBefore
|
|
115263
|
-
? fullMatch.slice(wordBefore.length, markerPos)
|
|
115264
|
-
: fullMatch.slice(0, markerPos);
|
|
115265
|
-
const shouldAddSpace = !!contentWithSpaceAfter && !!wordBefore && !spacesBeforeMarkers;
|
|
115266
|
-
if (wordBefore) {
|
|
115267
|
-
const spacing = spacesBeforeMarkers + (shouldAddSpace ? ' ' : '');
|
|
115268
|
-
parts.push({ type: 'text', value: wordBefore + spacing });
|
|
115269
|
-
}
|
|
115270
|
-
else if (spacesBeforeMarkers) {
|
|
115271
|
-
parts.push({ type: 'text', value: spacesBeforeMarkers });
|
|
115272
|
-
}
|
|
115273
|
-
if (content) {
|
|
115274
|
-
if (isBold) {
|
|
115275
|
-
parts.push({
|
|
115276
|
-
type: 'strong',
|
|
115277
|
-
children: [{ type: 'text', value: content }],
|
|
115278
|
-
});
|
|
115279
|
-
}
|
|
115280
|
-
else {
|
|
115281
|
-
parts.push({
|
|
115282
|
-
type: 'emphasis',
|
|
115283
|
-
children: [{ type: 'text', value: content }],
|
|
115284
|
-
});
|
|
115285
|
-
}
|
|
115286
|
-
}
|
|
115287
|
-
if (afterChar) {
|
|
115288
|
-
const prefix = trailingSpace ? ' ' : '';
|
|
115289
|
-
parts.push({ type: 'text', value: prefix + afterChar });
|
|
115290
|
-
}
|
|
115291
|
-
lastIndex = matchIndex + fullMatch.length;
|
|
115292
|
-
});
|
|
115293
|
-
if (lastIndex < text.length) {
|
|
115294
|
-
const remainingText = text.slice(lastIndex);
|
|
115295
|
-
if (remainingText) {
|
|
115296
|
-
parts.push({ type: 'text', value: remainingText });
|
|
115297
|
-
}
|
|
115298
|
-
}
|
|
115299
|
-
if (parts.length > 0) {
|
|
115300
|
-
parent.children.splice(index, 1, ...parts);
|
|
115301
|
-
return [SKIP, index + parts.length];
|
|
115302
|
-
}
|
|
115303
|
-
return undefined;
|
|
115304
|
-
});
|
|
115305
|
-
return tree;
|
|
115306
|
-
};
|
|
115307
|
-
/* harmony default export */ const normalize_malformed_md_syntax = (normalizeEmphasisAST);
|
|
115308
|
-
|
|
115309
115591
|
;// ./processor/transform/mdxish/normalize-table-separator.ts
|
|
115310
115592
|
/**
|
|
115311
115593
|
* Preprocessor to normalize malformed GFM table separator syntax.
|
|
@@ -116777,7 +117059,7 @@ function loadComponents() {
|
|
|
116777
117059
|
|
|
116778
117060
|
const defaultTransformers = [callouts, code_tabs, gemoji_, transform_embeds];
|
|
116779
117061
|
function mdxishAstProcessor(mdContent, opts = {}) {
|
|
116780
|
-
const { components: userComponents = {}, jsxContext = {}, newEditorTypes = false, useTailwind } = opts;
|
|
117062
|
+
const { components: userComponents = {}, jsxContext = {}, newEditorTypes = false, safeMode = false, useTailwind, } = opts;
|
|
116781
117063
|
const components = {
|
|
116782
117064
|
...loadComponents(),
|
|
116783
117065
|
...userComponents,
|
|
@@ -116788,7 +117070,9 @@ function mdxishAstProcessor(mdContent, opts = {}) {
|
|
|
116788
117070
|
// Step 1: Normalize malformed table separator syntax (e.g., `|: ---` → `| :---`)
|
|
116789
117071
|
const contentAfterTableNormalization = normalizeTableSeparator(mdContent);
|
|
116790
117072
|
// Step 2: Evaluate JSX expressions in attributes
|
|
116791
|
-
const contentAfterJSXEvaluation =
|
|
117073
|
+
const contentAfterJSXEvaluation = safeMode
|
|
117074
|
+
? contentAfterTableNormalization
|
|
117075
|
+
: preprocessJSXExpressions(contentAfterTableNormalization, jsxContext);
|
|
116792
117076
|
// Step 3: Replace snake_case component names with parser-safe placeholders
|
|
116793
117077
|
const { content: parserReadyContent, mapping: snakeCaseMapping } = processSnakeCaseComponent(contentAfterJSXEvaluation, { knownComponents });
|
|
116794
117078
|
// Create string map for tailwind transformer
|
|
@@ -116803,8 +117087,8 @@ function mdxishAstProcessor(mdContent, opts = {}) {
|
|
|
116803
117087
|
text: mdxExprExt.text,
|
|
116804
117088
|
};
|
|
116805
117089
|
const processor = unified()
|
|
116806
|
-
.data('micromarkExtensions', [magicBlock(), mdxExprTextOnly])
|
|
116807
|
-
.data('fromMarkdownExtensions', [magicBlockFromMarkdown(), mdxExpressionFromMarkdown()])
|
|
117090
|
+
.data('micromarkExtensions', safeMode ? [magicBlock()] : [magicBlock(), mdxExprTextOnly])
|
|
117091
|
+
.data('fromMarkdownExtensions', safeMode ? [magicBlockFromMarkdown()] : [magicBlockFromMarkdown(), mdxExpressionFromMarkdown()])
|
|
116808
117092
|
.use(remarkParse)
|
|
116809
117093
|
.use(remarkFrontmatter)
|
|
116810
117094
|
.use(normalize_malformed_md_syntax)
|
|
@@ -116816,8 +117100,8 @@ function mdxishAstProcessor(mdContent, opts = {}) {
|
|
|
116816
117100
|
.use(mdxish_tables)
|
|
116817
117101
|
.use(mdxish_html_blocks)
|
|
116818
117102
|
.use(newEditorTypes ? mdxish_jsx_to_mdast : undefined) // Convert JSX elements to MDAST types
|
|
116819
|
-
.use(evaluate_expressions, { context: jsxContext }) // Evaluate MDX expressions using jsxContext
|
|
116820
|
-
.use(variables_text) // Parse {user.*} patterns from text
|
|
117103
|
+
.use(safeMode ? undefined : evaluate_expressions, { context: jsxContext }) // Evaluate MDX expressions using jsxContext
|
|
117104
|
+
.use(variables_text) // Parse {user.*} patterns from text
|
|
116821
117105
|
.use(useTailwind ? transform_tailwind : undefined, { components: tempComponentsMap })
|
|
116822
117106
|
.use(remarkGfm);
|
|
116823
117107
|
return {
|
|
@@ -117438,6 +117722,7 @@ async function stripComments(doc, { mdx, mdxish } = {}) {
|
|
|
117438
117722
|
|
|
117439
117723
|
|
|
117440
117724
|
|
|
117725
|
+
|
|
117441
117726
|
;// ./index.tsx
|
|
117442
117727
|
|
|
117443
117728
|
|