@readme/markdown 15.5.0 → 15.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/constants.d.ts +2 -0
- package/dist/lib/utils/mdxish/mdxish-expression.d.ts +1 -1
- package/dist/main.js +338 -180
- package/dist/main.node.js +338 -180
- package/dist/main.node.js.map +1 -1
- package/dist/processor/transform/mdxish/repair-mistaken-table-closers.d.ts +1 -1
- package/dist/processor/transform/mdxish/variables-text.d.ts +11 -0
- package/dist/render-fixture.node.js +338 -180
- package/dist/render-fixture.node.js.map +1 -1
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -11423,7 +11423,7 @@ module.exports = function () {
|
|
|
11423
11423
|
|
|
11424
11424
|
/***/ },
|
|
11425
11425
|
|
|
11426
|
-
/***/
|
|
11426
|
+
/***/ 1595
|
|
11427
11427
|
(module, __webpack_exports__, __webpack_require__) {
|
|
11428
11428
|
|
|
11429
11429
|
"use strict";
|
|
@@ -13106,6 +13106,8 @@ var parseOptions = function parseOptions() {
|
|
|
13106
13106
|
* Pattern to match component tags (PascalCase or snake_case)
|
|
13107
13107
|
*/
|
|
13108
13108
|
const componentTagPattern = /<(\/?[A-Z][A-Za-z0-9_]*)([^>]*?)(\/?)>/g;
|
|
13109
|
+
/** A bare component name, the same shape `componentTagPattern` accepts inside `<…>`. */
|
|
13110
|
+
const componentNamePattern = /^[A-Z][A-Za-z0-9_]*$/;
|
|
13109
13111
|
/**
|
|
13110
13112
|
* MDAST flow (block-level) content types that cannot be represented
|
|
13111
13113
|
* inside GFM table cells. Used to decide whether a table should be
|
|
@@ -76740,6 +76742,14 @@ function syntax_createTokenize(mode) {
|
|
|
76740
76742
|
}
|
|
76741
76743
|
// ── Tag detection inside body ──────────────────────────────────────────
|
|
76742
76744
|
function bodyLessThan(code) {
|
|
76745
|
+
// A second `<` means legacy variable syntax (`<<var>>`), not a tag: the name that
|
|
76746
|
+
// follows belongs to the variable. Counting it as a nested opener would leave the
|
|
76747
|
+
// body unbalanced and lose the claim on this block.
|
|
76748
|
+
if (code === codes.lessThan) {
|
|
76749
|
+
effects.consume(code);
|
|
76750
|
+
atLineStart = false;
|
|
76751
|
+
return bodyAngleRun;
|
|
76752
|
+
}
|
|
76743
76753
|
if (code === codes.slash) {
|
|
76744
76754
|
if (onOpenerLine)
|
|
76745
76755
|
openerLineCloses += 1;
|
|
@@ -76764,6 +76774,14 @@ function syntax_createTokenize(mode) {
|
|
|
76764
76774
|
atLineStart = false;
|
|
76765
76775
|
return body(code);
|
|
76766
76776
|
}
|
|
76777
|
+
function bodyAngleRun(code) {
|
|
76778
|
+
if (code === codes.lessThan) {
|
|
76779
|
+
effects.consume(code);
|
|
76780
|
+
return bodyAngleRun;
|
|
76781
|
+
}
|
|
76782
|
+
atLineStart = false;
|
|
76783
|
+
return body(code);
|
|
76784
|
+
}
|
|
76767
76785
|
// ── Nested opening tag ─────────────────────────────────────────────────
|
|
76768
76786
|
function nestedOpenTagName(code) {
|
|
76769
76787
|
if (code !== null &&
|
|
@@ -76984,11 +77002,61 @@ function mdxComponent() {
|
|
|
76984
77002
|
;// ./lib/micromark/mdx-expression-lenient/syntax.ts
|
|
76985
77003
|
|
|
76986
77004
|
|
|
77005
|
+
|
|
77006
|
+
/**
|
|
77007
|
+
* The flow constructs allowed to end a multiline run, per parser. Everything but `<`: a
|
|
77008
|
+
* `<Component>` on its own line is the very shape the flow construct exists to keep together.
|
|
77009
|
+
*/
|
|
77010
|
+
const interrupters = new WeakMap();
|
|
77011
|
+
const flowInterrupters = (flow) => {
|
|
77012
|
+
let record = interrupters.get(flow);
|
|
77013
|
+
if (!record) {
|
|
77014
|
+
record = Object.fromEntries(Object.entries(flow).filter(([code]) => Number(code) !== codes.lessThan));
|
|
77015
|
+
interrupters.set(flow, record);
|
|
77016
|
+
}
|
|
77017
|
+
return record;
|
|
77018
|
+
};
|
|
77019
|
+
/**
|
|
77020
|
+
* Lookahead run at every line ending of a flow run, mirroring the paragraph continuation check
|
|
77021
|
+
* in `micromark-core-commonmark/lib/content.js`: `ok` when the next line continues the run,
|
|
77022
|
+
* `nok` when it would start a fenced code block, heading, or thematic break — which the run
|
|
77023
|
+
* must then leave alone rather than swallow. A blank line (including whitespace-only) ends the
|
|
77024
|
+
* run too, unless `blankContinues`: see `nestedLineContinues`.
|
|
77025
|
+
*/
|
|
77026
|
+
function tokenizeLineContinues(blankContinues) {
|
|
77027
|
+
return function tokenize(effects, ok, nok) {
|
|
77028
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
77029
|
+
const self = this;
|
|
77030
|
+
return start;
|
|
77031
|
+
function start(code) {
|
|
77032
|
+
effects.enter(types.lineEnding);
|
|
77033
|
+
effects.consume(code);
|
|
77034
|
+
effects.exit(types.lineEnding);
|
|
77035
|
+
return factorySpace(effects, prefixed, types.linePrefix);
|
|
77036
|
+
}
|
|
77037
|
+
// The paragraph rule also exempts lines indented 4+ columns (indented code can't interrupt);
|
|
77038
|
+
// mdxish disables indented code, so an indented line may still start a block here.
|
|
77039
|
+
function prefixed(code) {
|
|
77040
|
+
if (code === codes.eof)
|
|
77041
|
+
return nok(code);
|
|
77042
|
+
if (markdownLineEnding(code))
|
|
77043
|
+
return blankContinues ? ok(code) : nok(code);
|
|
77044
|
+
return effects.interrupt(flowInterrupters(self.parser.constructs.flow), nok, ok)(code);
|
|
77045
|
+
}
|
|
77046
|
+
};
|
|
77047
|
+
}
|
|
77048
|
+
const lineContinues = { tokenize: tokenizeLineContinues(false), partial: true };
|
|
77049
|
+
/**
|
|
77050
|
+
* Inside an open `{`, `(` or `[` a blank line is JavaScript formatting (between statements in a
|
|
77051
|
+
* callback, inside a JSX branch), so it may not end the run. At depth zero it's far more likely
|
|
77052
|
+
* a prose paragraph break after a stray `{`, and ending the run there keeps the paragraphs apart.
|
|
77053
|
+
*/
|
|
77054
|
+
const nestedLineContinues = { tokenize: tokenizeLineContinues(true), partial: true };
|
|
76987
77055
|
/**
|
|
76988
|
-
* Lenient MDX
|
|
77056
|
+
* Lenient MDX expression tokenizer (agnostic / no acorn).
|
|
76989
77057
|
*
|
|
76990
77058
|
* Matches a balanced `{ ... }` run — tracking nested braces and spanning soft
|
|
76991
|
-
* line breaks — and emits the standard `
|
|
77059
|
+
* line breaks — and emits the standard `mdx*Expression*` tokens so the
|
|
76992
77060
|
* upstream `mdxExpressionFromMarkdown()` builds the node.
|
|
76993
77061
|
*
|
|
76994
77062
|
* Reimplements the official micromark mdxExpression, but an unbalanced brace that
|
|
@@ -76996,70 +77064,115 @@ function mdxComponent() {
|
|
|
76996
77064
|
* and the `{` renders as literal text, making the pipeline forgiving of stray
|
|
76997
77065
|
* braces that upstream would hard-error on.
|
|
76998
77066
|
*/
|
|
76999
|
-
function
|
|
77000
|
-
|
|
77001
|
-
return
|
|
77002
|
-
|
|
77003
|
-
|
|
77004
|
-
|
|
77005
|
-
|
|
77006
|
-
|
|
77007
|
-
|
|
77008
|
-
|
|
77009
|
-
|
|
77010
|
-
|
|
77011
|
-
|
|
77012
|
-
|
|
77013
|
-
|
|
77014
|
-
|
|
77067
|
+
function tokenizeExpression(variant) {
|
|
77068
|
+
const isFlow = variant === 'mdxFlowExpression';
|
|
77069
|
+
return function tokenize(effects, ok, nok) {
|
|
77070
|
+
// Read eagerly: micromark calls `tokenize` with a fresh context per attempt, so this is the
|
|
77071
|
+
// value for this attempt, and the state functions below don't receive `this` at all.
|
|
77072
|
+
const { interrupt } = this;
|
|
77073
|
+
let depth = 0;
|
|
77074
|
+
let nesting = 0;
|
|
77075
|
+
let multiline = false;
|
|
77076
|
+
return start;
|
|
77077
|
+
function start(code) {
|
|
77078
|
+
if (code !== codes.leftCurlyBrace)
|
|
77079
|
+
return nok(code);
|
|
77080
|
+
// Never end a paragraph. A `{` continuing the line above is prose or a magic-block body
|
|
77081
|
+
// (`[block:callout]` puts one on the next line), not a block of its own.
|
|
77082
|
+
if (isFlow && interrupt)
|
|
77083
|
+
return nok(code);
|
|
77084
|
+
effects.enter(variant);
|
|
77085
|
+
effects.enter(`${variant}Marker`);
|
|
77086
|
+
effects.consume(code);
|
|
77087
|
+
effects.exit(`${variant}Marker`);
|
|
77088
|
+
return before;
|
|
77015
77089
|
}
|
|
77016
|
-
|
|
77017
|
-
|
|
77090
|
+
function before(code) {
|
|
77091
|
+
if (code === codes.eof)
|
|
77092
|
+
return end(code);
|
|
77093
|
+
if (markdownLineEnding(code)) {
|
|
77094
|
+
// A text run lives in a paragraph micromark has already bounded. A flow run bounds
|
|
77095
|
+
// itself: a blank line or an interrupting block ends it, so a stray `{` can't claim
|
|
77096
|
+
// the rest of the document, and `{\n\n}` stays two literal paragraphs.
|
|
77097
|
+
if (!isFlow)
|
|
77098
|
+
return lineEnding(code);
|
|
77099
|
+
return effects.check(depth > 0 || nesting > 0 ? nestedLineContinues : lineContinues, lineEnding, end)(code);
|
|
77100
|
+
}
|
|
77101
|
+
if (code === codes.rightCurlyBrace && depth === 0)
|
|
77102
|
+
return close(code);
|
|
77103
|
+
effects.enter(`${variant}Chunk`);
|
|
77104
|
+
return inside(code);
|
|
77105
|
+
}
|
|
77106
|
+
function lineEnding(code) {
|
|
77107
|
+
multiline = true;
|
|
77108
|
+
effects.enter(types.lineEnding);
|
|
77018
77109
|
effects.consume(code);
|
|
77019
|
-
effects.exit(
|
|
77110
|
+
effects.exit(types.lineEnding);
|
|
77020
77111
|
return before;
|
|
77021
77112
|
}
|
|
77022
|
-
|
|
77023
|
-
|
|
77113
|
+
function end(code) {
|
|
77114
|
+
effects.exit(variant);
|
|
77115
|
+
return nok(code);
|
|
77024
77116
|
}
|
|
77025
|
-
|
|
77026
|
-
|
|
77027
|
-
|
|
77028
|
-
|
|
77029
|
-
|
|
77030
|
-
|
|
77031
|
-
|
|
77117
|
+
function inside(code) {
|
|
77118
|
+
if (code === codes.eof || markdownLineEnding(code)) {
|
|
77119
|
+
effects.exit(`${variant}Chunk`);
|
|
77120
|
+
return before(code);
|
|
77121
|
+
}
|
|
77122
|
+
if (code === codes.rightCurlyBrace && depth === 0) {
|
|
77123
|
+
effects.exit(`${variant}Chunk`);
|
|
77124
|
+
return close(code);
|
|
77125
|
+
}
|
|
77126
|
+
if (code === codes.leftCurlyBrace)
|
|
77127
|
+
depth += 1;
|
|
77128
|
+
else if (code === codes.rightCurlyBrace)
|
|
77129
|
+
depth -= 1;
|
|
77130
|
+
else if (code === codes.leftParenthesis || code === codes.leftSquareBracket)
|
|
77131
|
+
nesting += 1;
|
|
77132
|
+
else if (code === codes.rightParenthesis || code === codes.rightSquareBracket)
|
|
77133
|
+
nesting -= 1;
|
|
77134
|
+
effects.consume(code);
|
|
77135
|
+
return inside;
|
|
77032
77136
|
}
|
|
77033
|
-
|
|
77034
|
-
effects.
|
|
77035
|
-
|
|
77137
|
+
function close(code) {
|
|
77138
|
+
effects.enter(`${variant}Marker`);
|
|
77139
|
+
effects.consume(code);
|
|
77140
|
+
effects.exit(`${variant}Marker`);
|
|
77141
|
+
effects.exit(variant);
|
|
77142
|
+
if (!isFlow)
|
|
77143
|
+
return ok;
|
|
77144
|
+
// A run that closes on the line it opened stays a text expression inside its paragraph:
|
|
77145
|
+
// claiming it as flow would strip the `<p>` every standalone `{expr}` line renders with.
|
|
77146
|
+
return multiline ? after : nok;
|
|
77036
77147
|
}
|
|
77037
|
-
|
|
77038
|
-
|
|
77039
|
-
|
|
77040
|
-
|
|
77041
|
-
|
|
77042
|
-
|
|
77043
|
-
}
|
|
77044
|
-
function close(code) {
|
|
77045
|
-
effects.enter('mdxTextExpressionMarker');
|
|
77046
|
-
effects.consume(code);
|
|
77047
|
-
effects.exit('mdxTextExpressionMarker');
|
|
77048
|
-
effects.exit('mdxTextExpression');
|
|
77049
|
-
return ok;
|
|
77050
|
-
}
|
|
77148
|
+
function after(code) {
|
|
77149
|
+
return markdownSpace(code) ? factorySpace(effects, lineEnd, types.whitespace)(code) : lineEnd(code);
|
|
77150
|
+
}
|
|
77151
|
+
function lineEnd(code) {
|
|
77152
|
+
return code === codes.eof || markdownLineEnding(code) ? ok(code) : nok(code);
|
|
77153
|
+
}
|
|
77154
|
+
};
|
|
77051
77155
|
}
|
|
77052
77156
|
function mdxExpressionLenient() {
|
|
77053
77157
|
return {
|
|
77158
|
+
flow: {
|
|
77159
|
+
[codes.leftCurlyBrace]: {
|
|
77160
|
+
name: 'mdxFlowExpression',
|
|
77161
|
+
tokenize: tokenizeExpression('mdxFlowExpression'),
|
|
77162
|
+
},
|
|
77163
|
+
},
|
|
77054
77164
|
text: {
|
|
77055
77165
|
[codes.leftCurlyBrace]: {
|
|
77056
77166
|
name: 'mdxTextExpression',
|
|
77057
|
-
tokenize:
|
|
77167
|
+
tokenize: tokenizeExpression('mdxTextExpression'),
|
|
77058
77168
|
},
|
|
77059
77169
|
},
|
|
77060
77170
|
};
|
|
77061
77171
|
}
|
|
77062
77172
|
|
|
77173
|
+
;// ./lib/micromark/mdx-expression-lenient/index.ts
|
|
77174
|
+
|
|
77175
|
+
|
|
77063
77176
|
;// ./lib/micromark/mdxish-extensions.ts
|
|
77064
77177
|
|
|
77065
77178
|
|
|
@@ -81629,6 +81742,17 @@ const tablesToJsx = () => tree => {
|
|
|
81629
81742
|
;// ./processor/transform/tailwind.tsx
|
|
81630
81743
|
|
|
81631
81744
|
|
|
81745
|
+
|
|
81746
|
+
|
|
81747
|
+
/** Whitespace-only text is layout between blocks, not inline flow. */
|
|
81748
|
+
const isInlineContent = (node) => phrasing(node) && !(node.type === 'text' && node.value.trim() === '');
|
|
81749
|
+
/**
|
|
81750
|
+
* Whether the child at `index` sits in inline flow: its parent only allows
|
|
81751
|
+
* phrasing content (e.g. a paragraph), or it is flanked by phrasing siblings
|
|
81752
|
+
* (e.g. `<div>text <Image /> text</div>`, whose children skip the paragraph).
|
|
81753
|
+
*/
|
|
81754
|
+
const isInlineInContext = (index, parent) => INLINE_ONLY_PARENT_TYPES.has(parent.type) ||
|
|
81755
|
+
parent.children.some((sibling, siblingIndex) => siblingIndex !== index && isInlineContent(sibling));
|
|
81632
81756
|
const injectTailwindRoot = ({ components = {} }) => (node, index, parent) => {
|
|
81633
81757
|
if (!('name' in node))
|
|
81634
81758
|
return;
|
|
@@ -81637,7 +81761,7 @@ const injectTailwindRoot = ({ components = {} }) => (node, index, parent) => {
|
|
|
81637
81761
|
if (!('children' in parent))
|
|
81638
81762
|
return;
|
|
81639
81763
|
const attrs = {
|
|
81640
|
-
flow: node.type === 'mdxJsxFlowElement',
|
|
81764
|
+
flow: node.type === 'mdxJsxFlowElement' && !isInlineInContext(index, parent),
|
|
81641
81765
|
};
|
|
81642
81766
|
const wrapper = {
|
|
81643
81767
|
type: node.type,
|
|
@@ -104125,6 +104249,111 @@ const parseTag = (value, opts = {}) => {
|
|
|
104125
104249
|
};
|
|
104126
104250
|
};
|
|
104127
104251
|
|
|
104252
|
+
;// ./processor/transform/mdxish/variables-text.ts
|
|
104253
|
+
|
|
104254
|
+
|
|
104255
|
+
/**
|
|
104256
|
+
* Matches {user.<field>} patterns:
|
|
104257
|
+
* - {user.name}
|
|
104258
|
+
* - {user.email}
|
|
104259
|
+
* - {user['field']}
|
|
104260
|
+
* - {user["field"]}
|
|
104261
|
+
*
|
|
104262
|
+
* Captures the field name in group 1 (dot notation) or group 2 (bracket notation)
|
|
104263
|
+
*/
|
|
104264
|
+
const USER_VAR_REGEX = /\{user\.(\w+)\}|\{user\[['"](\w+)['"]\]\}/g;
|
|
104265
|
+
/**
|
|
104266
|
+
* The lone `{user.<field>}` reference an expression node holds, or `null` when the node isn't an
|
|
104267
|
+
* expression or holds anything else (`{1 + 1}`, a CSS-looking body, two references in one brace).
|
|
104268
|
+
* Exported so promotion gates can tell a variable reference apart from an expression that must
|
|
104269
|
+
* stay literal.
|
|
104270
|
+
*/
|
|
104271
|
+
function soleUserVariableExpression(node) {
|
|
104272
|
+
if (node.type !== 'mdxFlowExpression' && node.type !== 'mdxTextExpression')
|
|
104273
|
+
return null;
|
|
104274
|
+
const { value } = node;
|
|
104275
|
+
const wrapped = `{${(value ?? '').trim()}}`;
|
|
104276
|
+
const matches = [...wrapped.matchAll(USER_VAR_REGEX)];
|
|
104277
|
+
if (matches.length !== 1 || matches[0][0] !== wrapped)
|
|
104278
|
+
return null;
|
|
104279
|
+
return { name: matches[0][1] || matches[0][2], wrapped };
|
|
104280
|
+
}
|
|
104281
|
+
function makeVariableNode(varName, rawValue) {
|
|
104282
|
+
return {
|
|
104283
|
+
type: NodeTypes.variable,
|
|
104284
|
+
data: {
|
|
104285
|
+
hName: 'Variable',
|
|
104286
|
+
hProperties: { name: varName },
|
|
104287
|
+
},
|
|
104288
|
+
value: rawValue,
|
|
104289
|
+
};
|
|
104290
|
+
}
|
|
104291
|
+
/**
|
|
104292
|
+
* A remark plugin that parses {user.<field>} patterns from text nodes and
|
|
104293
|
+
* mdx expression nodes, creating Variable nodes for runtime resolution.
|
|
104294
|
+
*
|
|
104295
|
+
* Handles:
|
|
104296
|
+
* - `text` nodes: when safeMode is true or after expression evaluation
|
|
104297
|
+
* - `mdxTextExpression` nodes: when mdxExpression has parsed {user.*} before evaluation
|
|
104298
|
+
* - `mdxFlowExpression` nodes: when {user.*} appears on its own line (e.g. inside JSX table cells)
|
|
104299
|
+
*
|
|
104300
|
+
* Supports any user field: name, email, email_verified, exp, iat, etc.
|
|
104301
|
+
*/
|
|
104302
|
+
function visitExpressionNode(node, index, parent) {
|
|
104303
|
+
if (index === undefined || !parent)
|
|
104304
|
+
return;
|
|
104305
|
+
const match = soleUserVariableExpression(node);
|
|
104306
|
+
if (!match)
|
|
104307
|
+
return;
|
|
104308
|
+
parent.children.splice(index, 1, makeVariableNode(match.name, match.wrapped));
|
|
104309
|
+
}
|
|
104310
|
+
const variablesTextTransformer = () => tree => {
|
|
104311
|
+
visit(tree, 'mdxTextExpression', (node, index, parent) => {
|
|
104312
|
+
visitExpressionNode(node, index, parent);
|
|
104313
|
+
});
|
|
104314
|
+
visit(tree, 'mdxFlowExpression', (node, index, parent) => {
|
|
104315
|
+
visitExpressionNode(node, index, parent);
|
|
104316
|
+
});
|
|
104317
|
+
visit(tree, 'text', (node, index, parent) => {
|
|
104318
|
+
if (index === undefined || !parent)
|
|
104319
|
+
return;
|
|
104320
|
+
// Skip if inside inline code
|
|
104321
|
+
if (parent.type === 'inlineCode')
|
|
104322
|
+
return;
|
|
104323
|
+
const text = node.value;
|
|
104324
|
+
if (typeof text !== 'string' || !text.trim())
|
|
104325
|
+
return;
|
|
104326
|
+
if (!text.includes('{user.') && !text.includes('{user['))
|
|
104327
|
+
return;
|
|
104328
|
+
const matches = [...text.matchAll(USER_VAR_REGEX)];
|
|
104329
|
+
if (matches.length === 0)
|
|
104330
|
+
return;
|
|
104331
|
+
const parts = [];
|
|
104332
|
+
let lastIndex = 0;
|
|
104333
|
+
matches.forEach(match => {
|
|
104334
|
+
const matchIndex = match.index ?? 0;
|
|
104335
|
+
// Add text before the match
|
|
104336
|
+
if (matchIndex > lastIndex) {
|
|
104337
|
+
parts.push({ type: 'text', value: text.slice(lastIndex, matchIndex) });
|
|
104338
|
+
}
|
|
104339
|
+
// Extract variable name from either capture group (dot or bracket notation)
|
|
104340
|
+
const varName = match[1] || match[2];
|
|
104341
|
+
parts.push(makeVariableNode(varName, match[0]));
|
|
104342
|
+
lastIndex = matchIndex + match[0].length;
|
|
104343
|
+
});
|
|
104344
|
+
// Add remaining text after last match
|
|
104345
|
+
if (lastIndex < text.length) {
|
|
104346
|
+
parts.push({ type: 'text', value: text.slice(lastIndex) });
|
|
104347
|
+
}
|
|
104348
|
+
// Replace node with parts
|
|
104349
|
+
if (parts.length > 1 || (parts.length === 1 && parts[0].type !== 'text')) {
|
|
104350
|
+
parent.children.splice(index, 1, ...parts);
|
|
104351
|
+
}
|
|
104352
|
+
});
|
|
104353
|
+
return tree;
|
|
104354
|
+
};
|
|
104355
|
+
/* harmony default export */ const variables_text = (variablesTextTransformer);
|
|
104356
|
+
|
|
104128
104357
|
;// ./processor/transform/mdxish/components/utils.ts
|
|
104129
104358
|
|
|
104130
104359
|
|
|
@@ -104202,19 +104431,15 @@ const NON_PROMOTABLE_PLAIN_TAGS = new Set([...htmlRawNames, ...tableTags, 'table
|
|
|
104202
104431
|
const NESTED_TABLE_RE = /<table[\s>]/i;
|
|
104203
104432
|
const isMarkdownPromotableHtmlTag = (tag) => !NON_PROMOTABLE_PLAIN_TAGS.has(tag);
|
|
104204
104433
|
// Expression nodes count as plain so `<div>{1+1}</div>` keeps its current
|
|
104205
|
-
// literal-brace behavior
|
|
104206
|
-
|
|
104207
|
-
|
|
104208
|
-
'text',
|
|
104209
|
-
'html',
|
|
104210
|
-
'mdxTextExpression',
|
|
104211
|
-
'mdxFlowExpression',
|
|
104212
|
-
NodeTypes.variable,
|
|
104213
|
-
NodeTypes.glossary,
|
|
104214
|
-
]);
|
|
104434
|
+
// literal-brace behavior — authors put CSS-shaped braces in these bodies, and only
|
|
104435
|
+
// a reference that names a real variable may resolve.
|
|
104436
|
+
const PLAIN_CONTENT_TYPES = new Set(['paragraph', 'text', 'html', 'mdxTextExpression', 'mdxFlowExpression']);
|
|
104215
104437
|
// Promoting plain HTML is only worth bypassing rehype-raw's parse5 pass when
|
|
104216
|
-
// the body parses into an actual markdown construct.
|
|
104438
|
+
// the body parses into an actual markdown construct. Variables and glossary terms
|
|
104439
|
+
// count: parse5 renders `<<var>>` as a stray `<` plus a `<var>` tag, so a body that
|
|
104440
|
+
// holds nothing else still has to be promoted to resolve.
|
|
104217
104441
|
const containsMarkdownConstruct = (nodes) => nodes.some(node => !PLAIN_CONTENT_TYPES.has(node.type) ||
|
|
104442
|
+
soleUserVariableExpression(node) !== null ||
|
|
104218
104443
|
('children' in node && Array.isArray(node.children) && containsMarkdownConstruct(node.children)));
|
|
104219
104444
|
/**
|
|
104220
104445
|
* Index of the `</tag>` that balances the already-consumed opening tag (the
|
|
@@ -104980,6 +105205,7 @@ const evaluateExports = () => (tree, file) => {
|
|
|
104980
105205
|
|
|
104981
105206
|
|
|
104982
105207
|
|
|
105208
|
+
|
|
104983
105209
|
const parseExpression = (expression) => jsxAcornParser.parse(expression, { ecmaVersion: 'latest', sourceType: 'module' });
|
|
104984
105210
|
/**
|
|
104985
105211
|
* Recursively report whether an estree value contains any JSX element or fragment node.
|
|
@@ -104996,22 +105222,16 @@ const containsJsxNode = (value) => {
|
|
|
104996
105222
|
return true;
|
|
104997
105223
|
return Object.values(value).some(containsJsxNode);
|
|
104998
105224
|
};
|
|
104999
|
-
/** Read the component name off a JSX element name node (`Foo`, `Foo.Bar`, `foo:Bar`). */
|
|
105000
105225
|
const jsxElementName = (name) => {
|
|
105001
105226
|
if (name === null || typeof name !== 'object')
|
|
105002
105227
|
return undefined;
|
|
105003
105228
|
const node = name;
|
|
105004
|
-
if (node.type
|
|
105005
|
-
return
|
|
105006
|
-
|
|
105007
|
-
if (node.type === 'JSXMemberExpression')
|
|
105008
|
-
return jsxElementName(node.object);
|
|
105009
|
-
if (node.type === 'JSXNamespacedName')
|
|
105010
|
-
return jsxElementName(node.namespace);
|
|
105011
|
-
return undefined;
|
|
105229
|
+
if (node.type !== 'JSXIdentifier' || typeof node.name !== 'string')
|
|
105230
|
+
return undefined;
|
|
105231
|
+
return componentNamePattern.test(node.name) ? node.name : undefined;
|
|
105012
105232
|
};
|
|
105013
105233
|
/**
|
|
105014
|
-
* Collect the
|
|
105234
|
+
* Collect the component names an expression uses as JSX tags. Parsed rather than pattern
|
|
105015
105235
|
* matched: `{count < Max ? <Foo/> : <Bar/>}` puts a capitalized name straight after a `<` without
|
|
105016
105236
|
* it being a tag, and only the parser can tell the two apart. Unparseable input yields nothing —
|
|
105017
105237
|
* evaluation is about to throw on it anyway.
|
|
@@ -105035,8 +105255,7 @@ const jsxComponentNames = (expression) => {
|
|
|
105035
105255
|
const node = value;
|
|
105036
105256
|
if (node.type === 'JSXOpeningElement') {
|
|
105037
105257
|
const name = jsxElementName(node.name);
|
|
105038
|
-
|
|
105039
|
-
if (name && /^[A-Z]/.test(name))
|
|
105258
|
+
if (name)
|
|
105040
105259
|
names.add(name);
|
|
105041
105260
|
}
|
|
105042
105261
|
Object.values(node).forEach(walk);
|
|
@@ -105195,7 +105414,8 @@ function renderFallbackHtml(element) {
|
|
|
105195
105414
|
const rawNode = { type: 'raw', value: __WEBPACK_CJS_EXPORT_renderToStaticMarkup__(element) };
|
|
105196
105415
|
return [rawNode];
|
|
105197
105416
|
}
|
|
105198
|
-
catch {
|
|
105417
|
+
catch (error) {
|
|
105418
|
+
console.warn('[mdxish] Could not render expression result:', error);
|
|
105199
105419
|
return [];
|
|
105200
105420
|
}
|
|
105201
105421
|
}
|
|
@@ -105253,6 +105473,7 @@ function reactElementToHast(node) {
|
|
|
105253
105473
|
|
|
105254
105474
|
|
|
105255
105475
|
|
|
105476
|
+
|
|
105256
105477
|
/**
|
|
105257
105478
|
* Bind the components a given expression actually uses as tags. Scoped per expression on purpose:
|
|
105258
105479
|
* binding the whole hash would shadow same-named globals (a `math` component would break
|
|
@@ -105281,17 +105502,28 @@ const isRenderable = (value) => {
|
|
|
105281
105502
|
return true;
|
|
105282
105503
|
return Array.isArray(value) && value.some(isRenderable);
|
|
105283
105504
|
};
|
|
105505
|
+
const isPhrasingTag = (tagName) => lib_phrasing({ type: 'element', tagName, properties: {}, children: [] });
|
|
105284
105506
|
/**
|
|
105285
|
-
* Whether an expression evaluated to block-level content.
|
|
105286
|
-
* unless
|
|
105287
|
-
*
|
|
105507
|
+
* Whether an expression evaluated to block-level content. A capitalized tag is a component,
|
|
105508
|
+
* block-level unless it's on the inline list (so a `Table` component isn't mistaken for an inline
|
|
105509
|
+
* `<table>`); a lowercase tag is HTML, block-level unless it's phrasing content. A `raw` node is
|
|
105510
|
+
* HTML from `renderFallbackHtml`, so it's parsed and judged by the same rule.
|
|
105288
105511
|
*/
|
|
105289
105512
|
const isBlockResult = (children) => children.some(child => {
|
|
105513
|
+
if (child.type === 'raw')
|
|
105514
|
+
return isBlockResult(fromHtml(child.value, { fragment: true }).children);
|
|
105290
105515
|
if (child.type !== 'element' && child.type !== 'mdx-jsx')
|
|
105291
105516
|
return false;
|
|
105292
105517
|
const { tagName } = child;
|
|
105293
|
-
return
|
|
105518
|
+
return /^[A-Z]/.test(tagName) ? !INLINE_COMPONENT_TAGS.has(tagName) : !isPhrasingTag(tagName);
|
|
105294
105519
|
});
|
|
105520
|
+
const JSX_ELEMENT_TYPES = new Set(['mdxJsxFlowElement', 'mdxJsxTextElement']);
|
|
105521
|
+
const wrapInParagraph = (child) => ({
|
|
105522
|
+
type: 'paragraph',
|
|
105523
|
+
children: [child],
|
|
105524
|
+
position: child.position,
|
|
105525
|
+
});
|
|
105526
|
+
const placeText = (text, needsBlock) => (needsBlock ? wrapInParagraph(text) : text);
|
|
105295
105527
|
/** Turn a non-renderable evaluation result into a text node. */
|
|
105296
105528
|
const createTextNode = (result, position) => {
|
|
105297
105529
|
if (result === null || result === undefined)
|
|
@@ -105327,6 +105559,7 @@ const evaluateExpressions = ({ components, variables } = {}) => (tree, file) =>
|
|
|
105327
105559
|
const expression = value?.trim();
|
|
105328
105560
|
if (!expression)
|
|
105329
105561
|
return;
|
|
105562
|
+
const needsBlock = expressionNode.type === 'mdxFlowExpression' && !JSX_ELEMENT_TYPES.has(parent.type);
|
|
105330
105563
|
try {
|
|
105331
105564
|
const scope = { ...componentScope(expression, components ?? {}), ...baseScope };
|
|
105332
105565
|
const result = evalExpression(expression, scope);
|
|
@@ -105335,10 +105568,17 @@ const evaluateExpressions = ({ components, variables } = {}) => (tree, file) =>
|
|
|
105335
105568
|
// passes through rehypeRaw/parse5 step later in the pipeline. This ensures that the
|
|
105336
105569
|
// expression result is not parsed by parse5 and fragmenting the nesting that is valid JSX
|
|
105337
105570
|
// but invalid HTML — e.g. an `<a>` wrapping `<a>`.
|
|
105338
|
-
|
|
105571
|
+
const hChildren = reactElementToHast(result);
|
|
105572
|
+
expressionNode.data = { ...expressionNode.data, hChildren };
|
|
105573
|
+
// An inline result in a block slot renders inside a `<p>`, as its one-line form does.
|
|
105574
|
+
// Retyping it as a text expression makes it legal paragraph content.
|
|
105575
|
+
if (needsBlock && !isBlockResult(hChildren)) {
|
|
105576
|
+
const inline = { ...expressionNode, type: 'mdxTextExpression' };
|
|
105577
|
+
parent.children.splice(index, 1, wrapInParagraph(inline));
|
|
105578
|
+
}
|
|
105339
105579
|
}
|
|
105340
105580
|
else {
|
|
105341
|
-
parent.children.splice(index, 1, createTextNode(result, position));
|
|
105581
|
+
parent.children.splice(index, 1, placeText(createTextNode(result, position), needsBlock));
|
|
105342
105582
|
}
|
|
105343
105583
|
}
|
|
105344
105584
|
catch (_error) {
|
|
@@ -105346,7 +105586,8 @@ const evaluateExpressions = ({ components, variables } = {}) => (tree, file) =>
|
|
|
105346
105586
|
// parser treats contents as code, so backslash escapes aren't applied;
|
|
105347
105587
|
// restore them here so e.g. `{\!}` round-trips to `{!}`.
|
|
105348
105588
|
const processed = expression.replace(/\\([!-/:-@[-`{-~])/g, '$1');
|
|
105349
|
-
|
|
105589
|
+
const literal = { type: 'text', value: `{${processed}}`, position };
|
|
105590
|
+
parent.children.splice(index, 1, placeText(literal, needsBlock));
|
|
105350
105591
|
}
|
|
105351
105592
|
});
|
|
105352
105593
|
// A text expression is parsed inside a paragraph, but its result can be block content: a
|
|
@@ -107059,12 +107300,20 @@ function removeJSXComments(content) {
|
|
|
107059
107300
|
const OPAQUE_CONTAINERS = new Set(['pre', 'textarea', 'htmlblock']);
|
|
107060
107301
|
/** The missing-slash typo shape: an attribute-less, non-self-closing opener. */
|
|
107061
107302
|
const BARE_OPENER_SOURCE_RE = /^<[A-Za-z]+\s*>$/;
|
|
107062
|
-
/** The opener
|
|
107063
|
-
const
|
|
107064
|
-
|
|
107303
|
+
/** The opener is immediately preceded by a complete tag, so the prefix is markup and not prose. */
|
|
107304
|
+
const PREFIX_ENDS_WITH_TAG_RE = /<[^<>]*>\s*$/;
|
|
107305
|
+
/**
|
|
107306
|
+
* The opener finishes its line, preceded by nothing but whitespace or by markup.
|
|
107307
|
+
* Requiring markup (not merely "something") keeps a markdown block prefix such as
|
|
107308
|
+
* a `>` quote marker from qualifying, while allowing the closer to trail a cell or
|
|
107309
|
+
* `</thead>` on a single-line table.
|
|
107310
|
+
*/
|
|
107311
|
+
const endsLineAfterMarkup = (content, start, end) => {
|
|
107065
107312
|
const lineEnd = content.indexOf('\n', end);
|
|
107066
|
-
|
|
107067
|
-
|
|
107313
|
+
if (content.slice(end, lineEnd === -1 ? content.length : lineEnd).trim() !== '')
|
|
107314
|
+
return false;
|
|
107315
|
+
const prefix = content.slice(content.lastIndexOf('\n', start - 1) + 1, start);
|
|
107316
|
+
return prefix.trim() === '' || PREFIX_ENDS_WITH_TAG_RE.test(prefix);
|
|
107068
107317
|
};
|
|
107069
107318
|
/**
|
|
107070
107319
|
* Rewrites a bare `<table>` that is almost certainly a missing-slash closer
|
|
@@ -107072,7 +107321,7 @@ const isAloneOnLine = (content, start, end) => {
|
|
|
107072
107321
|
* Customer docs (CX-3850) close tables with a second bare opener; without this,
|
|
107073
107322
|
* the never-terminated HTML flow block swallows the markdown that follows.
|
|
107074
107323
|
*
|
|
107075
|
-
* A candidate is a bare opener
|
|
107324
|
+
* A candidate is a bare opener that finishes its line while a table is already open.
|
|
107076
107325
|
* It is judged a typo only when its element ends implicitly (no explicit
|
|
107077
107326
|
* `</table>`) without ever acquiring table-structure children — so genuine
|
|
107078
107327
|
* nested tables, whatever precedes their rows, are left alone.
|
|
@@ -107101,7 +107350,7 @@ function repairMistakenTableClosers(content) {
|
|
|
107101
107350
|
start,
|
|
107102
107351
|
end,
|
|
107103
107352
|
hasStructureChild: false,
|
|
107104
|
-
isCandidate: stack.length > 0 && BARE_OPENER_SOURCE_RE.test(source) &&
|
|
107353
|
+
isCandidate: stack.length > 0 && BARE_OPENER_SOURCE_RE.test(source) && endsLineAfterMarkup(content, start, end),
|
|
107105
107354
|
});
|
|
107106
107355
|
}
|
|
107107
107356
|
else if (opaqueDepth === 0 && tableTags.has(lower) && stack.length > 0) {
|
|
@@ -107541,97 +107790,6 @@ const variablesCodeResolver = ({ variables } = {}) => tree => {
|
|
|
107541
107790
|
};
|
|
107542
107791
|
/* harmony default export */ const variables_code = (variablesCodeResolver);
|
|
107543
107792
|
|
|
107544
|
-
;// ./processor/transform/mdxish/variables-text.ts
|
|
107545
|
-
|
|
107546
|
-
|
|
107547
|
-
/**
|
|
107548
|
-
* Matches {user.<field>} patterns:
|
|
107549
|
-
* - {user.name}
|
|
107550
|
-
* - {user.email}
|
|
107551
|
-
* - {user['field']}
|
|
107552
|
-
* - {user["field"]}
|
|
107553
|
-
*
|
|
107554
|
-
* Captures the field name in group 1 (dot notation) or group 2 (bracket notation)
|
|
107555
|
-
*/
|
|
107556
|
-
const USER_VAR_REGEX = /\{user\.(\w+)\}|\{user\[['"](\w+)['"]\]\}/g;
|
|
107557
|
-
function makeVariableNode(varName, rawValue) {
|
|
107558
|
-
return {
|
|
107559
|
-
type: NodeTypes.variable,
|
|
107560
|
-
data: {
|
|
107561
|
-
hName: 'Variable',
|
|
107562
|
-
hProperties: { name: varName },
|
|
107563
|
-
},
|
|
107564
|
-
value: rawValue,
|
|
107565
|
-
};
|
|
107566
|
-
}
|
|
107567
|
-
/**
|
|
107568
|
-
* A remark plugin that parses {user.<field>} patterns from text nodes and
|
|
107569
|
-
* mdx expression nodes, creating Variable nodes for runtime resolution.
|
|
107570
|
-
*
|
|
107571
|
-
* Handles:
|
|
107572
|
-
* - `text` nodes: when safeMode is true or after expression evaluation
|
|
107573
|
-
* - `mdxTextExpression` nodes: when mdxExpression has parsed {user.*} before evaluation
|
|
107574
|
-
* - `mdxFlowExpression` nodes: when {user.*} appears on its own line (e.g. inside JSX table cells)
|
|
107575
|
-
*
|
|
107576
|
-
* Supports any user field: name, email, email_verified, exp, iat, etc.
|
|
107577
|
-
*/
|
|
107578
|
-
function visitExpressionNode(node, index, parent) {
|
|
107579
|
-
if (index === undefined || !parent)
|
|
107580
|
-
return;
|
|
107581
|
-
const wrapped = `{${(node.value ?? '').trim()}}`;
|
|
107582
|
-
const matches = [...wrapped.matchAll(USER_VAR_REGEX)];
|
|
107583
|
-
if (matches.length !== 1)
|
|
107584
|
-
return;
|
|
107585
|
-
const varName = matches[0][1] || matches[0][2];
|
|
107586
|
-
parent.children.splice(index, 1, makeVariableNode(varName, wrapped));
|
|
107587
|
-
}
|
|
107588
|
-
const variablesTextTransformer = () => tree => {
|
|
107589
|
-
visit(tree, 'mdxTextExpression', (node, index, parent) => {
|
|
107590
|
-
visitExpressionNode(node, index, parent);
|
|
107591
|
-
});
|
|
107592
|
-
visit(tree, 'mdxFlowExpression', (node, index, parent) => {
|
|
107593
|
-
visitExpressionNode(node, index, parent);
|
|
107594
|
-
});
|
|
107595
|
-
visit(tree, 'text', (node, index, parent) => {
|
|
107596
|
-
if (index === undefined || !parent)
|
|
107597
|
-
return;
|
|
107598
|
-
// Skip if inside inline code
|
|
107599
|
-
if (parent.type === 'inlineCode')
|
|
107600
|
-
return;
|
|
107601
|
-
const text = node.value;
|
|
107602
|
-
if (typeof text !== 'string' || !text.trim())
|
|
107603
|
-
return;
|
|
107604
|
-
if (!text.includes('{user.') && !text.includes('{user['))
|
|
107605
|
-
return;
|
|
107606
|
-
const matches = [...text.matchAll(USER_VAR_REGEX)];
|
|
107607
|
-
if (matches.length === 0)
|
|
107608
|
-
return;
|
|
107609
|
-
const parts = [];
|
|
107610
|
-
let lastIndex = 0;
|
|
107611
|
-
matches.forEach(match => {
|
|
107612
|
-
const matchIndex = match.index ?? 0;
|
|
107613
|
-
// Add text before the match
|
|
107614
|
-
if (matchIndex > lastIndex) {
|
|
107615
|
-
parts.push({ type: 'text', value: text.slice(lastIndex, matchIndex) });
|
|
107616
|
-
}
|
|
107617
|
-
// Extract variable name from either capture group (dot or bracket notation)
|
|
107618
|
-
const varName = match[1] || match[2];
|
|
107619
|
-
parts.push(makeVariableNode(varName, match[0]));
|
|
107620
|
-
lastIndex = matchIndex + match[0].length;
|
|
107621
|
-
});
|
|
107622
|
-
// Add remaining text after last match
|
|
107623
|
-
if (lastIndex < text.length) {
|
|
107624
|
-
parts.push({ type: 'text', value: text.slice(lastIndex) });
|
|
107625
|
-
}
|
|
107626
|
-
// Replace node with parts
|
|
107627
|
-
if (parts.length > 1 || (parts.length === 1 && parts[0].type !== 'text')) {
|
|
107628
|
-
parent.children.splice(index, 1, ...parts);
|
|
107629
|
-
}
|
|
107630
|
-
});
|
|
107631
|
-
return tree;
|
|
107632
|
-
};
|
|
107633
|
-
/* harmony default export */ const variables_text = (variablesTextTransformer);
|
|
107634
|
-
|
|
107635
107793
|
;// ./lib/utils/mdxish/mdxish-load-components.ts
|
|
107636
107794
|
|
|
107637
107795
|
|
|
@@ -108833,7 +108991,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"*":["about","acceptCharset","accessK
|
|
|
108833
108991
|
/******/ // startup
|
|
108834
108992
|
/******/ // Load entry module and return exports
|
|
108835
108993
|
/******/ // This entry module used 'module' so it can't be inlined
|
|
108836
|
-
/******/ let __webpack_exports__ = __webpack_require__(
|
|
108994
|
+
/******/ let __webpack_exports__ = __webpack_require__(1595);
|
|
108837
108995
|
/******/
|
|
108838
108996
|
/******/ return __webpack_exports__;
|
|
108839
108997
|
/******/ })()
|