@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.js
CHANGED
|
@@ -12179,6 +12179,9 @@ const GlossaryContext = (0,external_amd_react_commonjs_react_commonjs2_react_roo
|
|
|
12179
12179
|
|
|
12180
12180
|
|
|
12181
12181
|
|
|
12182
|
+
/** Tippy portals to document.body by default, which would break the
|
|
12183
|
+
* `.rm-ReadMe[data-color-mode] …` descendant selectors in style.scss. */
|
|
12184
|
+
const appendToReadMeRoot = (ref) => ref.closest('.rm-ReadMe') ?? document.body;
|
|
12182
12185
|
const Glossary = ({ children, term: termProp, terms }) => {
|
|
12183
12186
|
const term = (Array.isArray(children) ? children[0] : children) || termProp;
|
|
12184
12187
|
if (!term)
|
|
@@ -12186,7 +12189,7 @@ const Glossary = ({ children, term: termProp, terms }) => {
|
|
|
12186
12189
|
const foundTerm = terms.find(i => term.toLowerCase() === i?.term?.toLowerCase());
|
|
12187
12190
|
if (!foundTerm)
|
|
12188
12191
|
return external_amd_react_commonjs_react_commonjs2_react_root_React_umd_react_default().createElement("span", null, term);
|
|
12189
|
-
return (external_amd_react_commonjs_react_commonjs2_react_root_React_umd_react_default().createElement((react_default()), { content: external_amd_react_commonjs_react_commonjs2_react_root_React_umd_react_default().createElement("div", { className: "GlossaryItem-tooltip-content" },
|
|
12192
|
+
return (external_amd_react_commonjs_react_commonjs2_react_root_React_umd_react_default().createElement((react_default()), { appendTo: appendToReadMeRoot, content: external_amd_react_commonjs_react_commonjs2_react_root_React_umd_react_default().createElement("div", { className: "GlossaryItem-tooltip-content" },
|
|
12190
12193
|
external_amd_react_commonjs_react_commonjs2_react_root_React_umd_react_default().createElement("strong", { className: "GlossaryItem-term" }, foundTerm.term),
|
|
12191
12194
|
" - ",
|
|
12192
12195
|
foundTerm.definition), offset: [-5, 5], placement: "bottom-start" },
|
|
@@ -54765,12 +54768,104 @@ const mdast = (text, opts = {}) => {
|
|
|
54765
54768
|
*/
|
|
54766
54769
|
const jsxAcornParser = external_acorn_.Parser.extend(acorn_jsx_default()());
|
|
54767
54770
|
|
|
54771
|
+
;// ./lib/utils/literal-expression.ts
|
|
54772
|
+
|
|
54773
|
+
const unsupported = (description) => new Error(`not a literal expression: ${description}`);
|
|
54774
|
+
/** Narrows a resolved value for arithmetic, so operands never coerce to `NaN` or `"[object Object]"`. */
|
|
54775
|
+
const asNumber = (value) => {
|
|
54776
|
+
if (typeof value !== 'number')
|
|
54777
|
+
throw unsupported('non-numeric operand');
|
|
54778
|
+
return value;
|
|
54779
|
+
};
|
|
54780
|
+
const asOperand = (value) => {
|
|
54781
|
+
if (typeof value !== 'number' && typeof value !== 'string')
|
|
54782
|
+
throw unsupported('non-primitive operand');
|
|
54783
|
+
return value;
|
|
54784
|
+
};
|
|
54785
|
+
const ARITHMETIC_OPERATORS = {
|
|
54786
|
+
// `+` doubles as string concatenation, so it accepts a string on either side.
|
|
54787
|
+
'+': (left, right) => (typeof left === 'number' && typeof right === 'number' ? left + right : `${left}${right}`),
|
|
54788
|
+
'-': (left, right) => asNumber(left) - asNumber(right),
|
|
54789
|
+
'*': (left, right) => asNumber(left) * asNumber(right),
|
|
54790
|
+
'/': (left, right) => asNumber(left) / asNumber(right),
|
|
54791
|
+
};
|
|
54792
|
+
/** Resolve one estree node, recursing into arrays and objects. Throws for anything not on the allowlist. */
|
|
54793
|
+
const resolveNode = (node) => {
|
|
54794
|
+
switch (node.type) {
|
|
54795
|
+
case 'Literal':
|
|
54796
|
+
// Regex and bigint `Literal`s hold values a tree consumer can't serialise;
|
|
54797
|
+
// a BigInt throws outright in `JSON.stringify`.
|
|
54798
|
+
if ('regex' in node || 'bigint' in node)
|
|
54799
|
+
throw unsupported('regex or bigint literal');
|
|
54800
|
+
return node.value;
|
|
54801
|
+
case 'Identifier':
|
|
54802
|
+
if (node.name !== 'undefined')
|
|
54803
|
+
throw unsupported(`identifier \`${node.name}\``);
|
|
54804
|
+
return undefined;
|
|
54805
|
+
case 'TemplateLiteral':
|
|
54806
|
+
if (node.expressions.length)
|
|
54807
|
+
throw unsupported('template substitution');
|
|
54808
|
+
return node.quasis.map(quasi => quasi.value.cooked).join('');
|
|
54809
|
+
case 'UnaryExpression':
|
|
54810
|
+
if (node.operator !== '-')
|
|
54811
|
+
throw unsupported(`operator \`${node.operator}\``);
|
|
54812
|
+
return -asNumber(resolveNode(node.argument));
|
|
54813
|
+
case 'BinaryExpression': {
|
|
54814
|
+
const applyOperator = ARITHMETIC_OPERATORS[node.operator];
|
|
54815
|
+
if (!applyOperator)
|
|
54816
|
+
throw unsupported(`operator \`${node.operator}\``);
|
|
54817
|
+
return applyOperator(asOperand(resolveNode(node.left)), asOperand(resolveNode(node.right)));
|
|
54818
|
+
}
|
|
54819
|
+
case 'ArrayExpression':
|
|
54820
|
+
return node.elements.map(element => (element === null ? null : resolveNode(element)));
|
|
54821
|
+
case 'ObjectExpression':
|
|
54822
|
+
return node.properties.reduce((memo, property) => {
|
|
54823
|
+
if (property.type !== 'Property' || property.computed)
|
|
54824
|
+
throw unsupported('computed or spread property');
|
|
54825
|
+
const { key } = property;
|
|
54826
|
+
if (key.type !== 'Identifier' && key.type !== 'Literal')
|
|
54827
|
+
throw unsupported('property key');
|
|
54828
|
+
const name = key.type === 'Identifier' ? key.name : String(key.value);
|
|
54829
|
+
// `__proto__` would replace the object's prototype rather than add a property.
|
|
54830
|
+
if (name === '__proto__')
|
|
54831
|
+
throw unsupported('`__proto__` key');
|
|
54832
|
+
memo[name] = resolveNode(property.value);
|
|
54833
|
+
return memo;
|
|
54834
|
+
}, {});
|
|
54835
|
+
default:
|
|
54836
|
+
throw unsupported(node.type);
|
|
54837
|
+
}
|
|
54838
|
+
};
|
|
54839
|
+
/**
|
|
54840
|
+
* Resolve a JSX attribute expression's source to its value without executing it.
|
|
54841
|
+
*
|
|
54842
|
+
* Supports the literal syntax attributes actually use — `true`, `"a"`, `` `a` ``,
|
|
54843
|
+
* `undefined`, `{ textAlign: "left" }`, `["left"]`, `1 + 1`, `'https://' + 'x.com'` —
|
|
54844
|
+
* and refuses everything else, so no identifier, member access, call, assignment or
|
|
54845
|
+
* function body can ever run. The trade-off is that expressions needing a scope or a
|
|
54846
|
+
* method call (`{item.url}`, `{"a".toUpperCase()}`) throw, and callers keep the raw
|
|
54847
|
+
* source instead — the same fallback they already used for an expression that threw.
|
|
54848
|
+
* mdxish rendering is unaffected, since it resolves those later with its scoped
|
|
54849
|
+
* evaluator; only consumers reading attributes straight off the tree see the source.
|
|
54850
|
+
*
|
|
54851
|
+
* @param source expression body, without the surrounding braces
|
|
54852
|
+
* @throws if `source` is unparseable or isn't a supported literal expression
|
|
54853
|
+
*/
|
|
54854
|
+
const evaluateLiteralExpression = (source) => {
|
|
54855
|
+
const expression = jsxAcornParser.parseExpressionAt(source, 0, { ecmaVersion: 'latest' });
|
|
54856
|
+
// acorn stops at the first complete expression, so anything trailing means this isn't one.
|
|
54857
|
+
if (expression.end !== source.trimEnd().length)
|
|
54858
|
+
throw unsupported('trailing content');
|
|
54859
|
+
return resolveNode(expression);
|
|
54860
|
+
};
|
|
54861
|
+
|
|
54768
54862
|
;// ./processor/utils.ts
|
|
54769
54863
|
|
|
54770
54864
|
|
|
54771
54865
|
|
|
54772
54866
|
|
|
54773
54867
|
|
|
54868
|
+
|
|
54774
54869
|
/**
|
|
54775
54870
|
* Evaluate a JavaScript expression source and return its value.
|
|
54776
54871
|
*
|
|
@@ -54868,8 +54963,10 @@ const getAttrs = (jsx) => jsx.attributes.reduce((memo, attr) => {
|
|
|
54868
54963
|
memo[attr.name] = decode_decodeHTMLStrict(attr.value);
|
|
54869
54964
|
}
|
|
54870
54965
|
else if (attr.value?.value !== undefined) {
|
|
54966
|
+
// Expression values only survive to here when safeMode is off; `flattenAttributeExpressions`
|
|
54967
|
+
// rewrites them to plain strings at the head of the pipeline otherwise.
|
|
54871
54968
|
try {
|
|
54872
|
-
memo[attr.name] =
|
|
54969
|
+
memo[attr.name] = evaluateLiteralExpression(attr.value.value);
|
|
54873
54970
|
}
|
|
54874
54971
|
catch {
|
|
54875
54972
|
memo[attr.name] = attr.value.value;
|
|
@@ -55650,6 +55747,31 @@ const embedTransformer = () => {
|
|
|
55650
55747
|
};
|
|
55651
55748
|
/* harmony default export */ const transform_embeds = (embedTransformer);
|
|
55652
55749
|
|
|
55750
|
+
;// ./processor/transform/flatten-attribute-expressions.ts
|
|
55751
|
+
|
|
55752
|
+
|
|
55753
|
+
/**
|
|
55754
|
+
* Rewrites JSX attribute expressions (`icon={String(1 + 3)}`) into plain string attributes
|
|
55755
|
+
* holding their literal source, so nothing downstream can evaluate them.
|
|
55756
|
+
*
|
|
55757
|
+
* This is the RMDX counterpart to mdxish's `preserveExpressionsAsText` parse option: safeMode's
|
|
55758
|
+
* contract is enforced once, at the head of the pipeline, rather than at every `getAttrs()` call
|
|
55759
|
+
* site. Only registered when safeMode is on.
|
|
55760
|
+
*/
|
|
55761
|
+
const flattenAttributeExpressions = () => tree => {
|
|
55762
|
+
visit(tree, isMDXElement, (node) => {
|
|
55763
|
+
node.attributes.forEach(attr => {
|
|
55764
|
+
if (!('name' in attr))
|
|
55765
|
+
return;
|
|
55766
|
+
if (attr.value === null || typeof attr.value === 'string')
|
|
55767
|
+
return;
|
|
55768
|
+
attr.value = attr.value.value;
|
|
55769
|
+
});
|
|
55770
|
+
});
|
|
55771
|
+
return tree;
|
|
55772
|
+
};
|
|
55773
|
+
/* harmony default export */ const flatten_attribute_expressions = (flattenAttributeExpressions);
|
|
55774
|
+
|
|
55653
55775
|
;// ./node_modules/gemoji/index.js
|
|
55654
55776
|
/**
|
|
55655
55777
|
* @typedef Gemoji
|
|
@@ -76954,13 +77076,36 @@ const MARKER_PATTERNS = [
|
|
|
76954
77076
|
// Pattern for ** bold **
|
|
76955
77077
|
// Groups: 1=wordBefore, 2=marker, 3=contentWithSpaceAfter, 4=trailingSpace1, 5=contentWithSpaceBefore, 6=trailingSpace2, 7=afterChar
|
|
76956
77078
|
// trailingSpace1 is for "** text **" pattern, trailingSpace2 is for "**text **" pattern
|
|
76957
|
-
|
|
77079
|
+
//
|
|
77080
|
+
// The wordBefore and whitespace prefixes are deliberately bounded ({1,64} /
|
|
77081
|
+
// {0,8}) rather than unbounded (+ / *). An unbounded prefix makes matchAll
|
|
77082
|
+
// re-scan an arbitrarily long run from every character position, which turns
|
|
77083
|
+
// the pass O(n²) on text nodes containing huge unbroken tokens (pasted base64
|
|
77084
|
+
// payloads, minified code). Bounding the prefix caps the backtracking per
|
|
77085
|
+
// position; a prefix longer than the bound just starts the match later, and
|
|
77086
|
+
// the cut-off chars flow into the preceding text node instead — adjacent text
|
|
77087
|
+
// parts are merged before splicing, so the emitted AST is unchanged.
|
|
77088
|
+
//
|
|
77089
|
+
// The content quantifiers are bounded too ({1,500}). The underscore content
|
|
77090
|
+
// clauses can scan across `_` (needed for snake_case content), so without a
|
|
77091
|
+
// bound every `_` in a marker-dense token (base64url, snake_case identifiers)
|
|
77092
|
+
// re-scans to end-of-line looking for a closer — O(n²) again. Content already
|
|
77093
|
+
// can't cross a newline, and 500 chars covers any sentence-length emphasis
|
|
77094
|
+
// phrase; longer spans stay unnormalized rather than costing quadratic scans.
|
|
77095
|
+
const asteriskBoldRegex = /([^*\s]{1,64})?\s{0,8}(\*\*)(?:\s+((?:[^*\n]|\*(?!\*)){1,500}?)(\s*)\2|((?:[^*\n]|\*(?!\*)){1,500}?)(\s+)\2)(\S|$)?/g;
|
|
76958
77096
|
// Pattern for __ bold __
|
|
76959
|
-
const underscoreBoldRegex = /([^_\s]
|
|
77097
|
+
const underscoreBoldRegex = /([^_\s]{1,64})?\s{0,8}(__)(?:\s+((?:__(?! )|_(?!_)|[^_\n]){1,500}?)(\s*)\2|((?:__(?! )|_(?!_)|[^_\n]){1,500}?)(\s+)\2)(\S|$)?/g;
|
|
76960
77098
|
// Pattern for * italic *
|
|
76961
|
-
const asteriskItalicRegex = /([^*\s]
|
|
77099
|
+
const asteriskItalicRegex = /([^*\s]{1,64})?\s{0,8}(\*)(?!\*)(?:\s+([^*\n]{1,500}?)(\s*)\2|([^*\n]{1,500}?)(\s+)\2)(\S|$)?/g;
|
|
76962
77100
|
// Pattern for _ italic _
|
|
76963
|
-
const underscoreItalicRegex = /([^_\s]
|
|
77101
|
+
const underscoreItalicRegex = /([^_\s]{1,64})?\s{0,8}(_)(?!_)(?:\s+((?:[^_\n]|_(?! )){1,500}?)(\s*)\2|((?:[^_\n]|_(?! )){1,500}?)(\s+)\2)(\S|$)?/g;
|
|
77102
|
+
// Every loose alternation requires whitespace beside a marker — after the
|
|
77103
|
+
// opening (`** text**`) or before the closing (`**text **`) — so
|
|
77104
|
+
// marker-beside-whitespace is an exact gate for the loose families. A single
|
|
77105
|
+
// linear probe skips them entirely on marker-dense tokens whose markers are
|
|
77106
|
+
// all intraword (base64url payloads, snake_case identifiers).
|
|
77107
|
+
const asteriskBesideWhitespaceRegex = /\*\s|\s\*/;
|
|
77108
|
+
const underscoreBesideWhitespaceRegex = /_\s|\s_/;
|
|
76964
77109
|
// CommonMark ignores intraword underscores or asteriks, but we want to italicize/bold the inner part
|
|
76965
77110
|
// Pattern for intraword _word_ in words like hello_world_
|
|
76966
77111
|
const intrawordUnderscoreItalicRegex = /(\w)_(?!_)([a-zA-Z0-9]+)_(?![\w_])/g;
|
|
@@ -76970,6 +77115,23 @@ const intrawordUnderscoreBoldRegex = /(\w)__([a-zA-Z0-9]+)__(?![\w_])/g;
|
|
|
76970
77115
|
const intrawordAsteriskItalicRegex = /(\w)\*(?!\*)([a-zA-Z0-9]+)\*(?![\w*])/g;
|
|
76971
77116
|
// Pattern for intraword **word** in words like hello**world**
|
|
76972
77117
|
const intrawordAsteriskBoldRegex = /(\w)\*\*([a-zA-Z0-9]+)\*\*(?![\w*])/g;
|
|
77118
|
+
// All regex families, in match-precedence order: collected matches are
|
|
77119
|
+
// stable-sorted by match.index, so at an equal index the earlier row wins the
|
|
77120
|
+
// overlap filter — keep this order. `gate` names the per-node precondition
|
|
77121
|
+
// (see the gate record in the visitor) checked before the family's regex
|
|
77122
|
+
// runs, so a node that can't possibly match never pays for a full scan: the
|
|
77123
|
+
// intraword families need their marker character present, and the loose
|
|
77124
|
+
// families additionally need that marker beside whitespace.
|
|
77125
|
+
const REGEX_FAMILIES = [
|
|
77126
|
+
{ regex: asteriskBoldRegex, isBold: true, marker: '**', gate: 'asteriskLoose' },
|
|
77127
|
+
{ regex: underscoreBoldRegex, isBold: true, marker: '__', gate: 'underscoreLoose' },
|
|
77128
|
+
{ regex: asteriskItalicRegex, isBold: false, marker: '*', gate: 'asteriskLoose' },
|
|
77129
|
+
{ regex: underscoreItalicRegex, isBold: false, marker: '_', gate: 'underscoreLoose' },
|
|
77130
|
+
{ regex: intrawordUnderscoreItalicRegex, isBold: false, isIntraword: true, marker: '_', gate: 'underscore' },
|
|
77131
|
+
{ regex: intrawordUnderscoreBoldRegex, isBold: true, isIntraword: true, marker: '__', gate: 'underscore' },
|
|
77132
|
+
{ regex: intrawordAsteriskItalicRegex, isBold: false, isIntraword: true, marker: '*', gate: 'asterisk' },
|
|
77133
|
+
{ regex: intrawordAsteriskBoldRegex, isBold: true, isIntraword: true, marker: '**', gate: 'asterisk' },
|
|
77134
|
+
];
|
|
76973
77135
|
/**
|
|
76974
77136
|
* Finds opening emphasis marker in a text value.
|
|
76975
77137
|
* Returns marker info if found, null otherwise.
|
|
@@ -77161,6 +77323,21 @@ function isInsideInlineHtmlCode(index, parent) {
|
|
|
77161
77323
|
* malformed emphasis syntax. This plugin post-processes the AST to handle these cases.
|
|
77162
77324
|
*/
|
|
77163
77325
|
const normalizeEmphasisAST = () => (tree) => {
|
|
77326
|
+
// Back-scanning siblings for <code>…</code> html pairs costs O(children)
|
|
77327
|
+
// per text node — O(children²) per parent, which bites on marker-dense
|
|
77328
|
+
// paragraphs where micromark emits thousands of inline children. Most
|
|
77329
|
+
// parents have no html children at all, so cache that check per parent and
|
|
77330
|
+
// skip the back-scan entirely. The cached flag survives our splices: they
|
|
77331
|
+
// only ever swap text nodes for text/strong/emphasis, never html.
|
|
77332
|
+
const hasHtmlChild = new WeakMap();
|
|
77333
|
+
const mayBeInsideInlineHtmlCode = (index, parent) => {
|
|
77334
|
+
let flag = hasHtmlChild.get(parent);
|
|
77335
|
+
if (flag === undefined) {
|
|
77336
|
+
flag = parent.children.some(child => child.type === 'html');
|
|
77337
|
+
hasHtmlChild.set(parent, flag);
|
|
77338
|
+
}
|
|
77339
|
+
return flag && isInsideInlineHtmlCode(index, parent);
|
|
77340
|
+
};
|
|
77164
77341
|
visit(tree, 'text', function visitor(node, index, parent) {
|
|
77165
77342
|
if (index === undefined || !parent)
|
|
77166
77343
|
return undefined;
|
|
@@ -77172,41 +77349,39 @@ const normalizeEmphasisAST = () => (tree) => {
|
|
|
77172
77349
|
// raw HTML <code>...</code> inside table cells, which the table re-parser
|
|
77173
77350
|
// parses as MDX JSX (not as an mdast `inlineCode` node).
|
|
77174
77351
|
if ((parent.type === 'mdxJsxTextElement' || parent.type === 'mdxJsxFlowElement') &&
|
|
77175
|
-
'name' in parent &&
|
|
77352
|
+
'name' in parent &&
|
|
77353
|
+
parent.name === 'code') {
|
|
77176
77354
|
return undefined;
|
|
77177
77355
|
}
|
|
77356
|
+
const text = node.value;
|
|
77357
|
+
// The regexes below can't match without their marker character, but
|
|
77358
|
+
// running them anyway costs a scan of the whole node — ruinous on huge
|
|
77359
|
+
// pasted payloads (base64 attachments, minified code). Checked before the
|
|
77360
|
+
// html-sibling scan so marker-free text never pays for that either.
|
|
77361
|
+
const hasAsterisk = text.includes('*');
|
|
77362
|
+
const hasUnderscore = text.includes('_');
|
|
77363
|
+
if (!hasAsterisk && !hasUnderscore)
|
|
77364
|
+
return undefined;
|
|
77178
77365
|
// In GFM tables, inline <code>...</code> is represented as sibling `html`
|
|
77179
77366
|
// nodes rather than as an mdxJsxTextElement, so the check above doesn't
|
|
77180
77367
|
// apply. Scan backwards through siblings to see if we are enclosed by a
|
|
77181
77368
|
// <code>…</code> inline HTML pair.
|
|
77182
|
-
if (
|
|
77369
|
+
if (mayBeInsideInlineHtmlCode(index, parent)) {
|
|
77183
77370
|
return undefined;
|
|
77184
77371
|
}
|
|
77185
|
-
const
|
|
77372
|
+
const gates = {
|
|
77373
|
+
asterisk: hasAsterisk,
|
|
77374
|
+
asteriskLoose: hasAsterisk && asteriskBesideWhitespaceRegex.test(text),
|
|
77375
|
+
underscore: hasUnderscore,
|
|
77376
|
+
underscoreLoose: hasUnderscore && underscoreBesideWhitespaceRegex.test(text),
|
|
77377
|
+
};
|
|
77186
77378
|
const allMatches = [];
|
|
77187
|
-
|
|
77188
|
-
|
|
77189
|
-
|
|
77190
|
-
|
|
77191
|
-
|
|
77192
|
-
|
|
77193
|
-
[...text.matchAll(asteriskItalicRegex)].forEach(match => {
|
|
77194
|
-
allMatches.push({ isBold: false, marker: '*', match });
|
|
77195
|
-
});
|
|
77196
|
-
[...text.matchAll(underscoreItalicRegex)].forEach(match => {
|
|
77197
|
-
allMatches.push({ isBold: false, marker: '_', match });
|
|
77198
|
-
});
|
|
77199
|
-
[...text.matchAll(intrawordUnderscoreItalicRegex)].forEach(match => {
|
|
77200
|
-
allMatches.push({ isBold: false, isIntraword: true, marker: '_', match });
|
|
77201
|
-
});
|
|
77202
|
-
[...text.matchAll(intrawordUnderscoreBoldRegex)].forEach(match => {
|
|
77203
|
-
allMatches.push({ isBold: true, isIntraword: true, marker: '__', match });
|
|
77204
|
-
});
|
|
77205
|
-
[...text.matchAll(intrawordAsteriskItalicRegex)].forEach(match => {
|
|
77206
|
-
allMatches.push({ isBold: false, isIntraword: true, marker: '*', match });
|
|
77207
|
-
});
|
|
77208
|
-
[...text.matchAll(intrawordAsteriskBoldRegex)].forEach(match => {
|
|
77209
|
-
allMatches.push({ isBold: true, isIntraword: true, marker: '**', match });
|
|
77379
|
+
REGEX_FAMILIES.forEach(({ regex, gate, ...info }) => {
|
|
77380
|
+
if (!gates[gate])
|
|
77381
|
+
return;
|
|
77382
|
+
[...text.matchAll(regex)].forEach(match => {
|
|
77383
|
+
allMatches.push({ ...info, match });
|
|
77384
|
+
});
|
|
77210
77385
|
});
|
|
77211
77386
|
if (allMatches.length === 0)
|
|
77212
77387
|
return undefined;
|
|
@@ -77303,9 +77478,22 @@ const normalizeEmphasisAST = () => (tree) => {
|
|
|
77303
77478
|
parts.push({ type: 'text', value: remainingText });
|
|
77304
77479
|
}
|
|
77305
77480
|
}
|
|
77306
|
-
|
|
77307
|
-
|
|
77308
|
-
|
|
77481
|
+
// Merge adjacent text parts so the emitted AST doesn't depend on where a
|
|
77482
|
+
// match happened to start (the bounded prefixes above can shift a match
|
|
77483
|
+
// start rightward, splitting what used to be a single text node).
|
|
77484
|
+
const mergedParts = parts.reduce((acc, part) => {
|
|
77485
|
+
const prev = acc[acc.length - 1];
|
|
77486
|
+
if (part.type === 'text' && prev?.type === 'text') {
|
|
77487
|
+
prev.value += part.value;
|
|
77488
|
+
}
|
|
77489
|
+
else {
|
|
77490
|
+
acc.push(part);
|
|
77491
|
+
}
|
|
77492
|
+
return acc;
|
|
77493
|
+
}, []);
|
|
77494
|
+
if (mergedParts.length > 0) {
|
|
77495
|
+
parent.children.splice(index, 1, ...mergedParts);
|
|
77496
|
+
return [SKIP, index + mergedParts.length];
|
|
77309
77497
|
}
|
|
77310
77498
|
return undefined;
|
|
77311
77499
|
});
|
|
@@ -81419,6 +81607,7 @@ const variables = ({ asMdx } = { asMdx: true }) => tree => {
|
|
|
81419
81607
|
|
|
81420
81608
|
|
|
81421
81609
|
|
|
81610
|
+
|
|
81422
81611
|
const defaultTransforms = {
|
|
81423
81612
|
calloutTransformer: callouts,
|
|
81424
81613
|
codeTabsTransformer: code_tabs,
|
|
@@ -81446,6 +81635,9 @@ const astProcessor = (opts = {}) => {
|
|
|
81446
81635
|
const components = opts.components || {};
|
|
81447
81636
|
let processor = remark()
|
|
81448
81637
|
.use(remarkMdx)
|
|
81638
|
+
// Must precede every other transformer: it strips evaluable attribute expressions so no
|
|
81639
|
+
// downstream `getAttrs()` call can reach `evaluate()`.
|
|
81640
|
+
.use(opts.safeMode ? flatten_attribute_expressions : undefined)
|
|
81449
81641
|
.use(remarkPlugins)
|
|
81450
81642
|
.use(opts.remarkPlugins)
|
|
81451
81643
|
.use(transform_variables, { asMdx: false })
|
|
@@ -96025,12 +96217,59 @@ const hastscript_lib_h = create_h_createH(node_modules_property_information_html
|
|
|
96025
96217
|
/** @type {ReturnType<createH>} */
|
|
96026
96218
|
const lib_s = create_h_createH(node_modules_property_information_svg, 'g', svg_case_sensitive_tag_names_svgCaseSensitiveTagNames)
|
|
96027
96219
|
|
|
96220
|
+
;// ./utils/user.ts
|
|
96221
|
+
/**
|
|
96222
|
+
* Coerce a user variable value to a string for substitution into markdown text.
|
|
96223
|
+
* Non-string values (arrays, objects, numbers) are stringified via JSON or `String()`
|
|
96224
|
+
* so that `<<var>>` syntax doesn't produce `[object Object]` for structured data like
|
|
96225
|
+
* JWT `keys`.
|
|
96226
|
+
*/
|
|
96227
|
+
const stringifyVariableValue = (value) => {
|
|
96228
|
+
if (typeof value === 'string')
|
|
96229
|
+
return value;
|
|
96230
|
+
if (value == null)
|
|
96231
|
+
return '';
|
|
96232
|
+
if (typeof value === 'object') {
|
|
96233
|
+
try {
|
|
96234
|
+
return JSON.stringify(value) ?? '';
|
|
96235
|
+
}
|
|
96236
|
+
catch {
|
|
96237
|
+
console.warn('[WARNING] Could not stringify a structured user variable.');
|
|
96238
|
+
return '';
|
|
96239
|
+
}
|
|
96240
|
+
}
|
|
96241
|
+
return String(value);
|
|
96242
|
+
};
|
|
96243
|
+
/**
|
|
96244
|
+
* Flatten `variables.user` into a string-keyed string-valued record by coercing
|
|
96245
|
+
* each value. Used by markdown substitution paths that need a plain
|
|
96246
|
+
* `Record<string, string>` lookup.
|
|
96247
|
+
*/
|
|
96248
|
+
const flattenUserVariables = (user) => Object.fromEntries(Object.entries(user).map(([name, value]) => [name, stringifyVariableValue(value)]));
|
|
96249
|
+
const User = (variables) => {
|
|
96250
|
+
const { user = {}, defaults = [] } = variables || {};
|
|
96251
|
+
return new Proxy(user, {
|
|
96252
|
+
get(target, attribute) {
|
|
96253
|
+
if (typeof attribute === 'symbol') {
|
|
96254
|
+
return '';
|
|
96255
|
+
}
|
|
96256
|
+
if (attribute in target) {
|
|
96257
|
+
return target[attribute];
|
|
96258
|
+
}
|
|
96259
|
+
const def = defaults.find((d) => d.name === attribute);
|
|
96260
|
+
return def ? def.default : attribute.toUpperCase();
|
|
96261
|
+
},
|
|
96262
|
+
});
|
|
96263
|
+
};
|
|
96264
|
+
/* harmony default export */ const user = (User);
|
|
96265
|
+
|
|
96028
96266
|
;// ./processor/plugin/toc.ts
|
|
96029
96267
|
|
|
96030
96268
|
|
|
96031
96269
|
|
|
96032
96270
|
|
|
96033
96271
|
|
|
96272
|
+
|
|
96034
96273
|
const HEADING_TAGS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
|
|
96035
96274
|
const isHeadingTag = (tag) => (tag ? HEADING_TAGS.includes(tag) : false);
|
|
96036
96275
|
const isStandardHtmlElement = (node) => STANDARD_HTML_TAGS.has(node.tagName.toLowerCase());
|
|
@@ -96142,7 +96381,7 @@ const flattenVariables = (variables) => {
|
|
|
96142
96381
|
if (!variables)
|
|
96143
96382
|
return {};
|
|
96144
96383
|
return {
|
|
96145
|
-
...variables.user,
|
|
96384
|
+
...flattenUserVariables(variables.user),
|
|
96146
96385
|
...Object.fromEntries((variables.defaults || []).filter(d => !(d.name in variables.user)).map(d => [d.name, d.default])),
|
|
96147
96386
|
};
|
|
96148
96387
|
};
|
|
@@ -96290,7 +96529,7 @@ const exports_exports = (doc) => {
|
|
|
96290
96529
|
|
|
96291
96530
|
const hast = (text, opts = {}) => {
|
|
96292
96531
|
const components = Object.entries(opts.components || {}).reduce((memo, [name, doc]) => {
|
|
96293
|
-
memo[name] = lib_mdast(doc);
|
|
96532
|
+
memo[name] = lib_mdast(doc, { safeMode: opts.safeMode });
|
|
96294
96533
|
return memo;
|
|
96295
96534
|
}, {});
|
|
96296
96535
|
const processor = ast_processor(opts)
|
|
@@ -106926,6 +107165,7 @@ function normalizeTableSeparator(content) {
|
|
|
106926
107165
|
;// ./processor/transform/mdxish/variables-code.ts
|
|
106927
107166
|
|
|
106928
107167
|
|
|
107168
|
+
|
|
106929
107169
|
// Single combined regex so that resolved values from one pattern are never re-scanned by the other.
|
|
106930
107170
|
const COMBINED_VARIABLE_REGEX = new RegExp(`${variable_.VARIABLE_REGEXP}|${variable_.MDX_VARIABLE_REGEXP}`, 'giu');
|
|
106931
107171
|
// Flatten variables into a single object for easy lookup
|
|
@@ -106934,7 +107174,7 @@ function variables_code_flattenVariables(variables) {
|
|
|
106934
107174
|
return {};
|
|
106935
107175
|
return {
|
|
106936
107176
|
...Object.fromEntries((variables.defaults || []).map(d => [d.name, d.default])),
|
|
106937
|
-
...variables.user,
|
|
107177
|
+
...flattenUserVariables(variables.user),
|
|
106938
107178
|
};
|
|
106939
107179
|
}
|
|
106940
107180
|
function resolveCodeVariables(value, resolvedVariables) {
|
|
@@ -107478,24 +107718,6 @@ const Contexts = ({ children, terms = [], variables = { user: {}, defaults: [] }
|
|
|
107478
107718
|
};
|
|
107479
107719
|
/* harmony default export */ const contexts = (Contexts);
|
|
107480
107720
|
|
|
107481
|
-
;// ./utils/user.ts
|
|
107482
|
-
const User = (variables) => {
|
|
107483
|
-
const { user = {}, defaults = [] } = variables || {};
|
|
107484
|
-
return new Proxy(user, {
|
|
107485
|
-
get(target, attribute) {
|
|
107486
|
-
if (typeof attribute === 'symbol') {
|
|
107487
|
-
return '';
|
|
107488
|
-
}
|
|
107489
|
-
if (attribute in target) {
|
|
107490
|
-
return target[attribute];
|
|
107491
|
-
}
|
|
107492
|
-
const def = defaults.find((d) => d.name === attribute);
|
|
107493
|
-
return def ? def.default : attribute.toUpperCase();
|
|
107494
|
-
},
|
|
107495
|
-
});
|
|
107496
|
-
};
|
|
107497
|
-
/* harmony default export */ const user = (User);
|
|
107498
|
-
|
|
107499
107721
|
;// ./lib/utils/makeUseMdxComponents.ts
|
|
107500
107722
|
|
|
107501
107723
|
|
|
@@ -107528,6 +107750,7 @@ const makeUseMDXComponents = (more = {}) => {
|
|
|
107528
107750
|
|
|
107529
107751
|
;// ./lib/utils/mdxish/mdxish-variables.ts
|
|
107530
107752
|
|
|
107753
|
+
|
|
107531
107754
|
// The `$` guard skips template-literal interpolation: `${user.name}` embeds `{user.name}`, and
|
|
107532
107755
|
// substituting it would leave a mangled `` `Hi $Name` `` behind. Those belong to an expression,
|
|
107533
107756
|
// which either evaluated already or is meant to stay literal.
|
|
@@ -107551,7 +107774,7 @@ function resolveAttributeVariables(value, user) {
|
|
|
107551
107774
|
.replace(MDX_VARIABLE_REGEX, (source, escapePrefix, name, escapeSuffix) => {
|
|
107552
107775
|
if (escapePrefix || escapeSuffix)
|
|
107553
107776
|
return source;
|
|
107554
|
-
return user[name];
|
|
107777
|
+
return stringifyVariableValue(user[name]);
|
|
107555
107778
|
});
|
|
107556
107779
|
}
|
|
107557
107780
|
|
|
@@ -107827,7 +108050,8 @@ const run_run = (string, _opts = {}) => {
|
|
|
107827
108050
|
|
|
107828
108051
|
const tags = (doc) => {
|
|
107829
108052
|
const set = new Set();
|
|
107830
|
-
|
|
108053
|
+
// Tag names never depend on evaluated attribute values, so always parse in safeMode.
|
|
108054
|
+
visit(lib_mdast(doc, { safeMode: true }), isMDXElement, (node) => {
|
|
107831
108055
|
if (node.name?.match(/^[A-Z]/)) {
|
|
107832
108056
|
set.add(node.name);
|
|
107833
108057
|
}
|
|
@@ -107843,13 +108067,14 @@ const tags = (doc) => {
|
|
|
107843
108067
|
|
|
107844
108068
|
|
|
107845
108069
|
|
|
107846
|
-
const { micromarkExtensions, fromMarkdownExtensions } = mdxishExtensions(FEATURES.tags);
|
|
108070
|
+
const { micromarkExtensions, fromMarkdownExtensions } = mdxishExtensions(FEATURES.tags, { safeMode: true });
|
|
107847
108071
|
const mdxishTags_tags = (doc) => {
|
|
107848
108072
|
const set = new Set();
|
|
107849
108073
|
const processor = remark()
|
|
107850
108074
|
.data('micromarkExtensions', micromarkExtensions)
|
|
107851
108075
|
.data('fromMarkdownExtensions', fromMarkdownExtensions)
|
|
107852
|
-
.
|
|
108076
|
+
// Tag names never depend on evaluated attribute values, so always parse in safeMode.
|
|
108077
|
+
.use(mdx_blocks, { safeMode: true })
|
|
107853
108078
|
.use(mdxish_tables);
|
|
107854
108079
|
const tree = processor.parse(doc);
|
|
107855
108080
|
visit(processor.runSync(tree), isMDXElement, (node) => {
|