@readme/markdown 15.0.1 → 15.1.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 +6 -6
- package/components/Cards/style.scss +2 -2
- package/components/Glossary/index.tsx +5 -0
- package/components/Glossary/style.scss +5 -3
- package/components/Image/style.scss +2 -2
- package/components/Tabs/style.scss +4 -0
- package/dist/lib/ast-processor.d.ts +1 -0
- package/dist/lib/utils/literal-expression.d.ts +16 -0
- package/dist/lib/utils/mdxish/mdxish-variables.d.ts +1 -1
- package/dist/main.css +3 -3
- package/dist/main.css.map +1 -1
- package/dist/main.js +285 -60
- package/dist/main.node.js +285 -60
- package/dist/main.node.js.map +1 -1
- package/dist/processor/transform/flatten-attribute-expressions.d.ts +11 -0
- package/dist/processor/transform/index.d.ts +2 -1
- package/dist/render-fixture.css +2 -2
- package/dist/render-fixture.css.map +1 -1
- package/dist/render-fixture.node.js +285 -60
- package/dist/render-fixture.node.js.map +1 -1
- package/dist/utils/user.d.ts +15 -2
- package/package.json +2 -2
- package/styles/mixins/dark-mode.scss +13 -0
- package/styles/mixins/when-color-mode-dark.scss +48 -0
- package/types.d.ts +1 -1
package/dist/main.node.js
CHANGED
|
@@ -24807,6 +24807,9 @@ const GlossaryContext = (0,external_react_.createContext)([]);
|
|
|
24807
24807
|
|
|
24808
24808
|
|
|
24809
24809
|
|
|
24810
|
+
/** Tippy portals to document.body by default, which would break the
|
|
24811
|
+
* `.rm-ReadMe[data-color-mode] …` descendant selectors in style.scss. */
|
|
24812
|
+
const appendToReadMeRoot = (ref) => ref.closest('.rm-ReadMe') ?? document.body;
|
|
24810
24813
|
const Glossary = ({ children, term: termProp, terms }) => {
|
|
24811
24814
|
const term = (Array.isArray(children) ? children[0] : children) || termProp;
|
|
24812
24815
|
if (!term)
|
|
@@ -24814,7 +24817,7 @@ const Glossary = ({ children, term: termProp, terms }) => {
|
|
|
24814
24817
|
const foundTerm = terms.find(i => term.toLowerCase() === i?.term?.toLowerCase());
|
|
24815
24818
|
if (!foundTerm)
|
|
24816
24819
|
return external_react_default().createElement("span", null, term);
|
|
24817
|
-
return (external_react_default().createElement(tippy_react_esm, { content: external_react_default().createElement("div", { className: "GlossaryItem-tooltip-content" },
|
|
24820
|
+
return (external_react_default().createElement(tippy_react_esm, { appendTo: appendToReadMeRoot, content: external_react_default().createElement("div", { className: "GlossaryItem-tooltip-content" },
|
|
24818
24821
|
external_react_default().createElement("strong", { className: "GlossaryItem-term" }, foundTerm.term),
|
|
24819
24822
|
" - ",
|
|
24820
24823
|
foundTerm.definition), offset: [-5, 5], placement: "bottom-start" },
|
|
@@ -74989,12 +74992,104 @@ const mdast = (text, opts = {}) => {
|
|
|
74989
74992
|
*/
|
|
74990
74993
|
const jsxAcornParser = Parser.extend(acorn_jsx_default()());
|
|
74991
74994
|
|
|
74995
|
+
;// ./lib/utils/literal-expression.ts
|
|
74996
|
+
|
|
74997
|
+
const unsupported = (description) => new Error(`not a literal expression: ${description}`);
|
|
74998
|
+
/** Narrows a resolved value for arithmetic, so operands never coerce to `NaN` or `"[object Object]"`. */
|
|
74999
|
+
const asNumber = (value) => {
|
|
75000
|
+
if (typeof value !== 'number')
|
|
75001
|
+
throw unsupported('non-numeric operand');
|
|
75002
|
+
return value;
|
|
75003
|
+
};
|
|
75004
|
+
const asOperand = (value) => {
|
|
75005
|
+
if (typeof value !== 'number' && typeof value !== 'string')
|
|
75006
|
+
throw unsupported('non-primitive operand');
|
|
75007
|
+
return value;
|
|
75008
|
+
};
|
|
75009
|
+
const ARITHMETIC_OPERATORS = {
|
|
75010
|
+
// `+` doubles as string concatenation, so it accepts a string on either side.
|
|
75011
|
+
'+': (left, right) => (typeof left === 'number' && typeof right === 'number' ? left + right : `${left}${right}`),
|
|
75012
|
+
'-': (left, right) => asNumber(left) - asNumber(right),
|
|
75013
|
+
'*': (left, right) => asNumber(left) * asNumber(right),
|
|
75014
|
+
'/': (left, right) => asNumber(left) / asNumber(right),
|
|
75015
|
+
};
|
|
75016
|
+
/** Resolve one estree node, recursing into arrays and objects. Throws for anything not on the allowlist. */
|
|
75017
|
+
const resolveNode = (node) => {
|
|
75018
|
+
switch (node.type) {
|
|
75019
|
+
case 'Literal':
|
|
75020
|
+
// Regex and bigint `Literal`s hold values a tree consumer can't serialise;
|
|
75021
|
+
// a BigInt throws outright in `JSON.stringify`.
|
|
75022
|
+
if ('regex' in node || 'bigint' in node)
|
|
75023
|
+
throw unsupported('regex or bigint literal');
|
|
75024
|
+
return node.value;
|
|
75025
|
+
case 'Identifier':
|
|
75026
|
+
if (node.name !== 'undefined')
|
|
75027
|
+
throw unsupported(`identifier \`${node.name}\``);
|
|
75028
|
+
return undefined;
|
|
75029
|
+
case 'TemplateLiteral':
|
|
75030
|
+
if (node.expressions.length)
|
|
75031
|
+
throw unsupported('template substitution');
|
|
75032
|
+
return node.quasis.map(quasi => quasi.value.cooked).join('');
|
|
75033
|
+
case 'UnaryExpression':
|
|
75034
|
+
if (node.operator !== '-')
|
|
75035
|
+
throw unsupported(`operator \`${node.operator}\``);
|
|
75036
|
+
return -asNumber(resolveNode(node.argument));
|
|
75037
|
+
case 'BinaryExpression': {
|
|
75038
|
+
const applyOperator = ARITHMETIC_OPERATORS[node.operator];
|
|
75039
|
+
if (!applyOperator)
|
|
75040
|
+
throw unsupported(`operator \`${node.operator}\``);
|
|
75041
|
+
return applyOperator(asOperand(resolveNode(node.left)), asOperand(resolveNode(node.right)));
|
|
75042
|
+
}
|
|
75043
|
+
case 'ArrayExpression':
|
|
75044
|
+
return node.elements.map(element => (element === null ? null : resolveNode(element)));
|
|
75045
|
+
case 'ObjectExpression':
|
|
75046
|
+
return node.properties.reduce((memo, property) => {
|
|
75047
|
+
if (property.type !== 'Property' || property.computed)
|
|
75048
|
+
throw unsupported('computed or spread property');
|
|
75049
|
+
const { key } = property;
|
|
75050
|
+
if (key.type !== 'Identifier' && key.type !== 'Literal')
|
|
75051
|
+
throw unsupported('property key');
|
|
75052
|
+
const name = key.type === 'Identifier' ? key.name : String(key.value);
|
|
75053
|
+
// `__proto__` would replace the object's prototype rather than add a property.
|
|
75054
|
+
if (name === '__proto__')
|
|
75055
|
+
throw unsupported('`__proto__` key');
|
|
75056
|
+
memo[name] = resolveNode(property.value);
|
|
75057
|
+
return memo;
|
|
75058
|
+
}, {});
|
|
75059
|
+
default:
|
|
75060
|
+
throw unsupported(node.type);
|
|
75061
|
+
}
|
|
75062
|
+
};
|
|
75063
|
+
/**
|
|
75064
|
+
* Resolve a JSX attribute expression's source to its value without executing it.
|
|
75065
|
+
*
|
|
75066
|
+
* Supports the literal syntax attributes actually use — `true`, `"a"`, `` `a` ``,
|
|
75067
|
+
* `undefined`, `{ textAlign: "left" }`, `["left"]`, `1 + 1`, `'https://' + 'x.com'` —
|
|
75068
|
+
* and refuses everything else, so no identifier, member access, call, assignment or
|
|
75069
|
+
* function body can ever run. The trade-off is that expressions needing a scope or a
|
|
75070
|
+
* method call (`{item.url}`, `{"a".toUpperCase()}`) throw, and callers keep the raw
|
|
75071
|
+
* source instead — the same fallback they already used for an expression that threw.
|
|
75072
|
+
* mdxish rendering is unaffected, since it resolves those later with its scoped
|
|
75073
|
+
* evaluator; only consumers reading attributes straight off the tree see the source.
|
|
75074
|
+
*
|
|
75075
|
+
* @param source expression body, without the surrounding braces
|
|
75076
|
+
* @throws if `source` is unparseable or isn't a supported literal expression
|
|
75077
|
+
*/
|
|
75078
|
+
const evaluateLiteralExpression = (source) => {
|
|
75079
|
+
const expression = jsxAcornParser.parseExpressionAt(source, 0, { ecmaVersion: 'latest' });
|
|
75080
|
+
// acorn stops at the first complete expression, so anything trailing means this isn't one.
|
|
75081
|
+
if (expression.end !== source.trimEnd().length)
|
|
75082
|
+
throw unsupported('trailing content');
|
|
75083
|
+
return resolveNode(expression);
|
|
75084
|
+
};
|
|
75085
|
+
|
|
74992
75086
|
;// ./processor/utils.ts
|
|
74993
75087
|
|
|
74994
75088
|
|
|
74995
75089
|
|
|
74996
75090
|
|
|
74997
75091
|
|
|
75092
|
+
|
|
74998
75093
|
/**
|
|
74999
75094
|
* Evaluate a JavaScript expression source and return its value.
|
|
75000
75095
|
*
|
|
@@ -75092,8 +75187,10 @@ const getAttrs = (jsx) => jsx.attributes.reduce((memo, attr) => {
|
|
|
75092
75187
|
memo[attr.name] = decode_decodeHTMLStrict(attr.value);
|
|
75093
75188
|
}
|
|
75094
75189
|
else if (attr.value?.value !== undefined) {
|
|
75190
|
+
// Expression values only survive to here when safeMode is off; `flattenAttributeExpressions`
|
|
75191
|
+
// rewrites them to plain strings at the head of the pipeline otherwise.
|
|
75095
75192
|
try {
|
|
75096
|
-
memo[attr.name] =
|
|
75193
|
+
memo[attr.name] = evaluateLiteralExpression(attr.value.value);
|
|
75097
75194
|
}
|
|
75098
75195
|
catch {
|
|
75099
75196
|
memo[attr.name] = attr.value.value;
|
|
@@ -75874,6 +75971,31 @@ const embedTransformer = () => {
|
|
|
75874
75971
|
};
|
|
75875
75972
|
/* harmony default export */ const transform_embeds = (embedTransformer);
|
|
75876
75973
|
|
|
75974
|
+
;// ./processor/transform/flatten-attribute-expressions.ts
|
|
75975
|
+
|
|
75976
|
+
|
|
75977
|
+
/**
|
|
75978
|
+
* Rewrites JSX attribute expressions (`icon={String(1 + 3)}`) into plain string attributes
|
|
75979
|
+
* holding their literal source, so nothing downstream can evaluate them.
|
|
75980
|
+
*
|
|
75981
|
+
* This is the RMDX counterpart to mdxish's `preserveExpressionsAsText` parse option: safeMode's
|
|
75982
|
+
* contract is enforced once, at the head of the pipeline, rather than at every `getAttrs()` call
|
|
75983
|
+
* site. Only registered when safeMode is on.
|
|
75984
|
+
*/
|
|
75985
|
+
const flattenAttributeExpressions = () => tree => {
|
|
75986
|
+
visit(tree, isMDXElement, (node) => {
|
|
75987
|
+
node.attributes.forEach(attr => {
|
|
75988
|
+
if (!('name' in attr))
|
|
75989
|
+
return;
|
|
75990
|
+
if (attr.value === null || typeof attr.value === 'string')
|
|
75991
|
+
return;
|
|
75992
|
+
attr.value = attr.value.value;
|
|
75993
|
+
});
|
|
75994
|
+
});
|
|
75995
|
+
return tree;
|
|
75996
|
+
};
|
|
75997
|
+
/* harmony default export */ const flatten_attribute_expressions = (flattenAttributeExpressions);
|
|
75998
|
+
|
|
75877
75999
|
;// ./node_modules/gemoji/index.js
|
|
75878
76000
|
/**
|
|
75879
76001
|
* @typedef Gemoji
|
|
@@ -97178,13 +97300,36 @@ const MARKER_PATTERNS = [
|
|
|
97178
97300
|
// Pattern for ** bold **
|
|
97179
97301
|
// Groups: 1=wordBefore, 2=marker, 3=contentWithSpaceAfter, 4=trailingSpace1, 5=contentWithSpaceBefore, 6=trailingSpace2, 7=afterChar
|
|
97180
97302
|
// trailingSpace1 is for "** text **" pattern, trailingSpace2 is for "**text **" pattern
|
|
97181
|
-
|
|
97303
|
+
//
|
|
97304
|
+
// The wordBefore and whitespace prefixes are deliberately bounded ({1,64} /
|
|
97305
|
+
// {0,8}) rather than unbounded (+ / *). An unbounded prefix makes matchAll
|
|
97306
|
+
// re-scan an arbitrarily long run from every character position, which turns
|
|
97307
|
+
// the pass O(n²) on text nodes containing huge unbroken tokens (pasted base64
|
|
97308
|
+
// payloads, minified code). Bounding the prefix caps the backtracking per
|
|
97309
|
+
// position; a prefix longer than the bound just starts the match later, and
|
|
97310
|
+
// the cut-off chars flow into the preceding text node instead — adjacent text
|
|
97311
|
+
// parts are merged before splicing, so the emitted AST is unchanged.
|
|
97312
|
+
//
|
|
97313
|
+
// The content quantifiers are bounded too ({1,500}). The underscore content
|
|
97314
|
+
// clauses can scan across `_` (needed for snake_case content), so without a
|
|
97315
|
+
// bound every `_` in a marker-dense token (base64url, snake_case identifiers)
|
|
97316
|
+
// re-scans to end-of-line looking for a closer — O(n²) again. Content already
|
|
97317
|
+
// can't cross a newline, and 500 chars covers any sentence-length emphasis
|
|
97318
|
+
// phrase; longer spans stay unnormalized rather than costing quadratic scans.
|
|
97319
|
+
const asteriskBoldRegex = /([^*\s]{1,64})?\s{0,8}(\*\*)(?:\s+((?:[^*\n]|\*(?!\*)){1,500}?)(\s*)\2|((?:[^*\n]|\*(?!\*)){1,500}?)(\s+)\2)(\S|$)?/g;
|
|
97182
97320
|
// Pattern for __ bold __
|
|
97183
|
-
const underscoreBoldRegex = /([^_\s]
|
|
97321
|
+
const underscoreBoldRegex = /([^_\s]{1,64})?\s{0,8}(__)(?:\s+((?:__(?! )|_(?!_)|[^_\n]){1,500}?)(\s*)\2|((?:__(?! )|_(?!_)|[^_\n]){1,500}?)(\s+)\2)(\S|$)?/g;
|
|
97184
97322
|
// Pattern for * italic *
|
|
97185
|
-
const asteriskItalicRegex = /([^*\s]
|
|
97323
|
+
const asteriskItalicRegex = /([^*\s]{1,64})?\s{0,8}(\*)(?!\*)(?:\s+([^*\n]{1,500}?)(\s*)\2|([^*\n]{1,500}?)(\s+)\2)(\S|$)?/g;
|
|
97186
97324
|
// Pattern for _ italic _
|
|
97187
|
-
const underscoreItalicRegex = /([^_\s]
|
|
97325
|
+
const underscoreItalicRegex = /([^_\s]{1,64})?\s{0,8}(_)(?!_)(?:\s+((?:[^_\n]|_(?! )){1,500}?)(\s*)\2|((?:[^_\n]|_(?! )){1,500}?)(\s+)\2)(\S|$)?/g;
|
|
97326
|
+
// Every loose alternation requires whitespace beside a marker — after the
|
|
97327
|
+
// opening (`** text**`) or before the closing (`**text **`) — so
|
|
97328
|
+
// marker-beside-whitespace is an exact gate for the loose families. A single
|
|
97329
|
+
// linear probe skips them entirely on marker-dense tokens whose markers are
|
|
97330
|
+
// all intraword (base64url payloads, snake_case identifiers).
|
|
97331
|
+
const asteriskBesideWhitespaceRegex = /\*\s|\s\*/;
|
|
97332
|
+
const underscoreBesideWhitespaceRegex = /_\s|\s_/;
|
|
97188
97333
|
// CommonMark ignores intraword underscores or asteriks, but we want to italicize/bold the inner part
|
|
97189
97334
|
// Pattern for intraword _word_ in words like hello_world_
|
|
97190
97335
|
const intrawordUnderscoreItalicRegex = /(\w)_(?!_)([a-zA-Z0-9]+)_(?![\w_])/g;
|
|
@@ -97194,6 +97339,23 @@ const intrawordUnderscoreBoldRegex = /(\w)__([a-zA-Z0-9]+)__(?![\w_])/g;
|
|
|
97194
97339
|
const intrawordAsteriskItalicRegex = /(\w)\*(?!\*)([a-zA-Z0-9]+)\*(?![\w*])/g;
|
|
97195
97340
|
// Pattern for intraword **word** in words like hello**world**
|
|
97196
97341
|
const intrawordAsteriskBoldRegex = /(\w)\*\*([a-zA-Z0-9]+)\*\*(?![\w*])/g;
|
|
97342
|
+
// All regex families, in match-precedence order: collected matches are
|
|
97343
|
+
// stable-sorted by match.index, so at an equal index the earlier row wins the
|
|
97344
|
+
// overlap filter — keep this order. `gate` names the per-node precondition
|
|
97345
|
+
// (see the gate record in the visitor) checked before the family's regex
|
|
97346
|
+
// runs, so a node that can't possibly match never pays for a full scan: the
|
|
97347
|
+
// intraword families need their marker character present, and the loose
|
|
97348
|
+
// families additionally need that marker beside whitespace.
|
|
97349
|
+
const REGEX_FAMILIES = [
|
|
97350
|
+
{ regex: asteriskBoldRegex, isBold: true, marker: '**', gate: 'asteriskLoose' },
|
|
97351
|
+
{ regex: underscoreBoldRegex, isBold: true, marker: '__', gate: 'underscoreLoose' },
|
|
97352
|
+
{ regex: asteriskItalicRegex, isBold: false, marker: '*', gate: 'asteriskLoose' },
|
|
97353
|
+
{ regex: underscoreItalicRegex, isBold: false, marker: '_', gate: 'underscoreLoose' },
|
|
97354
|
+
{ regex: intrawordUnderscoreItalicRegex, isBold: false, isIntraword: true, marker: '_', gate: 'underscore' },
|
|
97355
|
+
{ regex: intrawordUnderscoreBoldRegex, isBold: true, isIntraword: true, marker: '__', gate: 'underscore' },
|
|
97356
|
+
{ regex: intrawordAsteriskItalicRegex, isBold: false, isIntraword: true, marker: '*', gate: 'asterisk' },
|
|
97357
|
+
{ regex: intrawordAsteriskBoldRegex, isBold: true, isIntraword: true, marker: '**', gate: 'asterisk' },
|
|
97358
|
+
];
|
|
97197
97359
|
/**
|
|
97198
97360
|
* Finds opening emphasis marker in a text value.
|
|
97199
97361
|
* Returns marker info if found, null otherwise.
|
|
@@ -97385,6 +97547,21 @@ function isInsideInlineHtmlCode(index, parent) {
|
|
|
97385
97547
|
* malformed emphasis syntax. This plugin post-processes the AST to handle these cases.
|
|
97386
97548
|
*/
|
|
97387
97549
|
const normalizeEmphasisAST = () => (tree) => {
|
|
97550
|
+
// Back-scanning siblings for <code>…</code> html pairs costs O(children)
|
|
97551
|
+
// per text node — O(children²) per parent, which bites on marker-dense
|
|
97552
|
+
// paragraphs where micromark emits thousands of inline children. Most
|
|
97553
|
+
// parents have no html children at all, so cache that check per parent and
|
|
97554
|
+
// skip the back-scan entirely. The cached flag survives our splices: they
|
|
97555
|
+
// only ever swap text nodes for text/strong/emphasis, never html.
|
|
97556
|
+
const hasHtmlChild = new WeakMap();
|
|
97557
|
+
const mayBeInsideInlineHtmlCode = (index, parent) => {
|
|
97558
|
+
let flag = hasHtmlChild.get(parent);
|
|
97559
|
+
if (flag === undefined) {
|
|
97560
|
+
flag = parent.children.some(child => child.type === 'html');
|
|
97561
|
+
hasHtmlChild.set(parent, flag);
|
|
97562
|
+
}
|
|
97563
|
+
return flag && isInsideInlineHtmlCode(index, parent);
|
|
97564
|
+
};
|
|
97388
97565
|
visit(tree, 'text', function visitor(node, index, parent) {
|
|
97389
97566
|
if (index === undefined || !parent)
|
|
97390
97567
|
return undefined;
|
|
@@ -97396,41 +97573,39 @@ const normalizeEmphasisAST = () => (tree) => {
|
|
|
97396
97573
|
// raw HTML <code>...</code> inside table cells, which the table re-parser
|
|
97397
97574
|
// parses as MDX JSX (not as an mdast `inlineCode` node).
|
|
97398
97575
|
if ((parent.type === 'mdxJsxTextElement' || parent.type === 'mdxJsxFlowElement') &&
|
|
97399
|
-
'name' in parent &&
|
|
97576
|
+
'name' in parent &&
|
|
97577
|
+
parent.name === 'code') {
|
|
97400
97578
|
return undefined;
|
|
97401
97579
|
}
|
|
97580
|
+
const text = node.value;
|
|
97581
|
+
// The regexes below can't match without their marker character, but
|
|
97582
|
+
// running them anyway costs a scan of the whole node — ruinous on huge
|
|
97583
|
+
// pasted payloads (base64 attachments, minified code). Checked before the
|
|
97584
|
+
// html-sibling scan so marker-free text never pays for that either.
|
|
97585
|
+
const hasAsterisk = text.includes('*');
|
|
97586
|
+
const hasUnderscore = text.includes('_');
|
|
97587
|
+
if (!hasAsterisk && !hasUnderscore)
|
|
97588
|
+
return undefined;
|
|
97402
97589
|
// In GFM tables, inline <code>...</code> is represented as sibling `html`
|
|
97403
97590
|
// nodes rather than as an mdxJsxTextElement, so the check above doesn't
|
|
97404
97591
|
// apply. Scan backwards through siblings to see if we are enclosed by a
|
|
97405
97592
|
// <code>…</code> inline HTML pair.
|
|
97406
|
-
if (
|
|
97593
|
+
if (mayBeInsideInlineHtmlCode(index, parent)) {
|
|
97407
97594
|
return undefined;
|
|
97408
97595
|
}
|
|
97409
|
-
const
|
|
97596
|
+
const gates = {
|
|
97597
|
+
asterisk: hasAsterisk,
|
|
97598
|
+
asteriskLoose: hasAsterisk && asteriskBesideWhitespaceRegex.test(text),
|
|
97599
|
+
underscore: hasUnderscore,
|
|
97600
|
+
underscoreLoose: hasUnderscore && underscoreBesideWhitespaceRegex.test(text),
|
|
97601
|
+
};
|
|
97410
97602
|
const allMatches = [];
|
|
97411
|
-
|
|
97412
|
-
|
|
97413
|
-
|
|
97414
|
-
|
|
97415
|
-
|
|
97416
|
-
|
|
97417
|
-
[...text.matchAll(asteriskItalicRegex)].forEach(match => {
|
|
97418
|
-
allMatches.push({ isBold: false, marker: '*', match });
|
|
97419
|
-
});
|
|
97420
|
-
[...text.matchAll(underscoreItalicRegex)].forEach(match => {
|
|
97421
|
-
allMatches.push({ isBold: false, marker: '_', match });
|
|
97422
|
-
});
|
|
97423
|
-
[...text.matchAll(intrawordUnderscoreItalicRegex)].forEach(match => {
|
|
97424
|
-
allMatches.push({ isBold: false, isIntraword: true, marker: '_', match });
|
|
97425
|
-
});
|
|
97426
|
-
[...text.matchAll(intrawordUnderscoreBoldRegex)].forEach(match => {
|
|
97427
|
-
allMatches.push({ isBold: true, isIntraword: true, marker: '__', match });
|
|
97428
|
-
});
|
|
97429
|
-
[...text.matchAll(intrawordAsteriskItalicRegex)].forEach(match => {
|
|
97430
|
-
allMatches.push({ isBold: false, isIntraword: true, marker: '*', match });
|
|
97431
|
-
});
|
|
97432
|
-
[...text.matchAll(intrawordAsteriskBoldRegex)].forEach(match => {
|
|
97433
|
-
allMatches.push({ isBold: true, isIntraword: true, marker: '**', match });
|
|
97603
|
+
REGEX_FAMILIES.forEach(({ regex, gate, ...info }) => {
|
|
97604
|
+
if (!gates[gate])
|
|
97605
|
+
return;
|
|
97606
|
+
[...text.matchAll(regex)].forEach(match => {
|
|
97607
|
+
allMatches.push({ ...info, match });
|
|
97608
|
+
});
|
|
97434
97609
|
});
|
|
97435
97610
|
if (allMatches.length === 0)
|
|
97436
97611
|
return undefined;
|
|
@@ -97527,9 +97702,22 @@ const normalizeEmphasisAST = () => (tree) => {
|
|
|
97527
97702
|
parts.push({ type: 'text', value: remainingText });
|
|
97528
97703
|
}
|
|
97529
97704
|
}
|
|
97530
|
-
|
|
97531
|
-
|
|
97532
|
-
|
|
97705
|
+
// Merge adjacent text parts so the emitted AST doesn't depend on where a
|
|
97706
|
+
// match happened to start (the bounded prefixes above can shift a match
|
|
97707
|
+
// start rightward, splitting what used to be a single text node).
|
|
97708
|
+
const mergedParts = parts.reduce((acc, part) => {
|
|
97709
|
+
const prev = acc[acc.length - 1];
|
|
97710
|
+
if (part.type === 'text' && prev?.type === 'text') {
|
|
97711
|
+
prev.value += part.value;
|
|
97712
|
+
}
|
|
97713
|
+
else {
|
|
97714
|
+
acc.push(part);
|
|
97715
|
+
}
|
|
97716
|
+
return acc;
|
|
97717
|
+
}, []);
|
|
97718
|
+
if (mergedParts.length > 0) {
|
|
97719
|
+
parent.children.splice(index, 1, ...mergedParts);
|
|
97720
|
+
return [SKIP, index + mergedParts.length];
|
|
97533
97721
|
}
|
|
97534
97722
|
return undefined;
|
|
97535
97723
|
});
|
|
@@ -101643,6 +101831,7 @@ const variables = ({ asMdx } = { asMdx: true }) => tree => {
|
|
|
101643
101831
|
|
|
101644
101832
|
|
|
101645
101833
|
|
|
101834
|
+
|
|
101646
101835
|
const defaultTransforms = {
|
|
101647
101836
|
calloutTransformer: callouts,
|
|
101648
101837
|
codeTabsTransformer: code_tabs,
|
|
@@ -101670,6 +101859,9 @@ const astProcessor = (opts = {}) => {
|
|
|
101670
101859
|
const components = opts.components || {};
|
|
101671
101860
|
let processor = remark()
|
|
101672
101861
|
.use(remarkMdx)
|
|
101862
|
+
// Must precede every other transformer: it strips evaluable attribute expressions so no
|
|
101863
|
+
// downstream `getAttrs()` call can reach `evaluate()`.
|
|
101864
|
+
.use(opts.safeMode ? flatten_attribute_expressions : undefined)
|
|
101673
101865
|
.use(remarkPlugins)
|
|
101674
101866
|
.use(opts.remarkPlugins)
|
|
101675
101867
|
.use(transform_variables, { asMdx: false })
|
|
@@ -116249,12 +116441,59 @@ const hastscript_lib_h = create_h_createH(node_modules_property_information_html
|
|
|
116249
116441
|
/** @type {ReturnType<createH>} */
|
|
116250
116442
|
const lib_s = create_h_createH(node_modules_property_information_svg, 'g', svg_case_sensitive_tag_names_svgCaseSensitiveTagNames)
|
|
116251
116443
|
|
|
116444
|
+
;// ./utils/user.ts
|
|
116445
|
+
/**
|
|
116446
|
+
* Coerce a user variable value to a string for substitution into markdown text.
|
|
116447
|
+
* Non-string values (arrays, objects, numbers) are stringified via JSON or `String()`
|
|
116448
|
+
* so that `<<var>>` syntax doesn't produce `[object Object]` for structured data like
|
|
116449
|
+
* JWT `keys`.
|
|
116450
|
+
*/
|
|
116451
|
+
const stringifyVariableValue = (value) => {
|
|
116452
|
+
if (typeof value === 'string')
|
|
116453
|
+
return value;
|
|
116454
|
+
if (value == null)
|
|
116455
|
+
return '';
|
|
116456
|
+
if (typeof value === 'object') {
|
|
116457
|
+
try {
|
|
116458
|
+
return JSON.stringify(value) ?? '';
|
|
116459
|
+
}
|
|
116460
|
+
catch {
|
|
116461
|
+
console.warn('[WARNING] Could not stringify a structured user variable.');
|
|
116462
|
+
return '';
|
|
116463
|
+
}
|
|
116464
|
+
}
|
|
116465
|
+
return String(value);
|
|
116466
|
+
};
|
|
116467
|
+
/**
|
|
116468
|
+
* Flatten `variables.user` into a string-keyed string-valued record by coercing
|
|
116469
|
+
* each value. Used by markdown substitution paths that need a plain
|
|
116470
|
+
* `Record<string, string>` lookup.
|
|
116471
|
+
*/
|
|
116472
|
+
const flattenUserVariables = (user) => Object.fromEntries(Object.entries(user).map(([name, value]) => [name, stringifyVariableValue(value)]));
|
|
116473
|
+
const User = (variables) => {
|
|
116474
|
+
const { user = {}, defaults = [] } = variables || {};
|
|
116475
|
+
return new Proxy(user, {
|
|
116476
|
+
get(target, attribute) {
|
|
116477
|
+
if (typeof attribute === 'symbol') {
|
|
116478
|
+
return '';
|
|
116479
|
+
}
|
|
116480
|
+
if (attribute in target) {
|
|
116481
|
+
return target[attribute];
|
|
116482
|
+
}
|
|
116483
|
+
const def = defaults.find((d) => d.name === attribute);
|
|
116484
|
+
return def ? def.default : attribute.toUpperCase();
|
|
116485
|
+
},
|
|
116486
|
+
});
|
|
116487
|
+
};
|
|
116488
|
+
/* harmony default export */ const user = (User);
|
|
116489
|
+
|
|
116252
116490
|
;// ./processor/plugin/toc.ts
|
|
116253
116491
|
|
|
116254
116492
|
|
|
116255
116493
|
|
|
116256
116494
|
|
|
116257
116495
|
|
|
116496
|
+
|
|
116258
116497
|
const HEADING_TAGS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
|
|
116259
116498
|
const isHeadingTag = (tag) => (tag ? HEADING_TAGS.includes(tag) : false);
|
|
116260
116499
|
const isStandardHtmlElement = (node) => STANDARD_HTML_TAGS.has(node.tagName.toLowerCase());
|
|
@@ -116366,7 +116605,7 @@ const flattenVariables = (variables) => {
|
|
|
116366
116605
|
if (!variables)
|
|
116367
116606
|
return {};
|
|
116368
116607
|
return {
|
|
116369
|
-
...variables.user,
|
|
116608
|
+
...flattenUserVariables(variables.user),
|
|
116370
116609
|
...Object.fromEntries((variables.defaults || []).filter(d => !(d.name in variables.user)).map(d => [d.name, d.default])),
|
|
116371
116610
|
};
|
|
116372
116611
|
};
|
|
@@ -116514,7 +116753,7 @@ const exports_exports = (doc) => {
|
|
|
116514
116753
|
|
|
116515
116754
|
const hast = (text, opts = {}) => {
|
|
116516
116755
|
const components = Object.entries(opts.components || {}).reduce((memo, [name, doc]) => {
|
|
116517
|
-
memo[name] = lib_mdast(doc);
|
|
116756
|
+
memo[name] = lib_mdast(doc, { safeMode: opts.safeMode });
|
|
116518
116757
|
return memo;
|
|
116519
116758
|
}, {});
|
|
116520
116759
|
const processor = ast_processor(opts)
|
|
@@ -127150,6 +127389,7 @@ function normalizeTableSeparator(content) {
|
|
|
127150
127389
|
;// ./processor/transform/mdxish/variables-code.ts
|
|
127151
127390
|
|
|
127152
127391
|
|
|
127392
|
+
|
|
127153
127393
|
// Single combined regex so that resolved values from one pattern are never re-scanned by the other.
|
|
127154
127394
|
const COMBINED_VARIABLE_REGEX = new RegExp(`${variable_dist.VARIABLE_REGEXP}|${variable_dist.MDX_VARIABLE_REGEXP}`, 'giu');
|
|
127155
127395
|
// Flatten variables into a single object for easy lookup
|
|
@@ -127158,7 +127398,7 @@ function variables_code_flattenVariables(variables) {
|
|
|
127158
127398
|
return {};
|
|
127159
127399
|
return {
|
|
127160
127400
|
...Object.fromEntries((variables.defaults || []).map(d => [d.name, d.default])),
|
|
127161
|
-
...variables.user,
|
|
127401
|
+
...flattenUserVariables(variables.user),
|
|
127162
127402
|
};
|
|
127163
127403
|
}
|
|
127164
127404
|
function resolveCodeVariables(value, resolvedVariables) {
|
|
@@ -127702,24 +127942,6 @@ const Contexts = ({ children, terms = [], variables = { user: {}, defaults: [] }
|
|
|
127702
127942
|
};
|
|
127703
127943
|
/* harmony default export */ const contexts = (Contexts);
|
|
127704
127944
|
|
|
127705
|
-
;// ./utils/user.ts
|
|
127706
|
-
const User = (variables) => {
|
|
127707
|
-
const { user = {}, defaults = [] } = variables || {};
|
|
127708
|
-
return new Proxy(user, {
|
|
127709
|
-
get(target, attribute) {
|
|
127710
|
-
if (typeof attribute === 'symbol') {
|
|
127711
|
-
return '';
|
|
127712
|
-
}
|
|
127713
|
-
if (attribute in target) {
|
|
127714
|
-
return target[attribute];
|
|
127715
|
-
}
|
|
127716
|
-
const def = defaults.find((d) => d.name === attribute);
|
|
127717
|
-
return def ? def.default : attribute.toUpperCase();
|
|
127718
|
-
},
|
|
127719
|
-
});
|
|
127720
|
-
};
|
|
127721
|
-
/* harmony default export */ const user = (User);
|
|
127722
|
-
|
|
127723
127945
|
;// ./lib/utils/makeUseMdxComponents.ts
|
|
127724
127946
|
|
|
127725
127947
|
|
|
@@ -127752,6 +127974,7 @@ const makeUseMDXComponents = (more = {}) => {
|
|
|
127752
127974
|
|
|
127753
127975
|
;// ./lib/utils/mdxish/mdxish-variables.ts
|
|
127754
127976
|
|
|
127977
|
+
|
|
127755
127978
|
// The `$` guard skips template-literal interpolation: `${user.name}` embeds `{user.name}`, and
|
|
127756
127979
|
// substituting it would leave a mangled `` `Hi $Name` `` behind. Those belong to an expression,
|
|
127757
127980
|
// which either evaluated already or is meant to stay literal.
|
|
@@ -127775,7 +127998,7 @@ function resolveAttributeVariables(value, user) {
|
|
|
127775
127998
|
.replace(MDX_VARIABLE_REGEX, (source, escapePrefix, name, escapeSuffix) => {
|
|
127776
127999
|
if (escapePrefix || escapeSuffix)
|
|
127777
128000
|
return source;
|
|
127778
|
-
return user[name];
|
|
128001
|
+
return stringifyVariableValue(user[name]);
|
|
127779
128002
|
});
|
|
127780
128003
|
}
|
|
127781
128004
|
|
|
@@ -128051,7 +128274,8 @@ const run_run = (string, _opts = {}) => {
|
|
|
128051
128274
|
|
|
128052
128275
|
const tags = (doc) => {
|
|
128053
128276
|
const set = new Set();
|
|
128054
|
-
|
|
128277
|
+
// Tag names never depend on evaluated attribute values, so always parse in safeMode.
|
|
128278
|
+
visit(lib_mdast(doc, { safeMode: true }), isMDXElement, (node) => {
|
|
128055
128279
|
if (node.name?.match(/^[A-Z]/)) {
|
|
128056
128280
|
set.add(node.name);
|
|
128057
128281
|
}
|
|
@@ -128067,13 +128291,14 @@ const tags = (doc) => {
|
|
|
128067
128291
|
|
|
128068
128292
|
|
|
128069
128293
|
|
|
128070
|
-
const { micromarkExtensions, fromMarkdownExtensions } = mdxishExtensions(FEATURES.tags);
|
|
128294
|
+
const { micromarkExtensions, fromMarkdownExtensions } = mdxishExtensions(FEATURES.tags, { safeMode: true });
|
|
128071
128295
|
const mdxishTags_tags = (doc) => {
|
|
128072
128296
|
const set = new Set();
|
|
128073
128297
|
const processor = remark()
|
|
128074
128298
|
.data('micromarkExtensions', micromarkExtensions)
|
|
128075
128299
|
.data('fromMarkdownExtensions', fromMarkdownExtensions)
|
|
128076
|
-
.
|
|
128300
|
+
// Tag names never depend on evaluated attribute values, so always parse in safeMode.
|
|
128301
|
+
.use(mdx_blocks, { safeMode: true })
|
|
128077
128302
|
.use(mdxish_tables);
|
|
128078
128303
|
const tree = processor.parse(doc);
|
|
128079
128304
|
visit(processor.runSync(tree), isMDXElement, (node) => {
|