@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.node.js
CHANGED
|
@@ -19045,7 +19045,7 @@ module.exports = function () {
|
|
|
19045
19045
|
|
|
19046
19046
|
/***/ },
|
|
19047
19047
|
|
|
19048
|
-
/***/
|
|
19048
|
+
/***/ 6261
|
|
19049
19049
|
(module, __webpack_exports__, __webpack_require__) {
|
|
19050
19050
|
|
|
19051
19051
|
"use strict";
|
|
@@ -25638,6 +25638,8 @@ const parseOptions = (userOpts = {}) => {
|
|
|
25638
25638
|
* Pattern to match component tags (PascalCase or snake_case)
|
|
25639
25639
|
*/
|
|
25640
25640
|
const componentTagPattern = /<(\/?[A-Z][A-Za-z0-9_]*)([^>]*?)(\/?)>/g;
|
|
25641
|
+
/** A bare component name, the same shape `componentTagPattern` accepts inside `<…>`. */
|
|
25642
|
+
const componentNamePattern = /^[A-Z][A-Za-z0-9_]*$/;
|
|
25641
25643
|
/**
|
|
25642
25644
|
* MDAST flow (block-level) content types that cannot be represented
|
|
25643
25645
|
* inside GFM table cells. Used to decide whether a table should be
|
|
@@ -96923,6 +96925,14 @@ function syntax_createTokenize(mode) {
|
|
|
96923
96925
|
}
|
|
96924
96926
|
// ── Tag detection inside body ──────────────────────────────────────────
|
|
96925
96927
|
function bodyLessThan(code) {
|
|
96928
|
+
// A second `<` means legacy variable syntax (`<<var>>`), not a tag: the name that
|
|
96929
|
+
// follows belongs to the variable. Counting it as a nested opener would leave the
|
|
96930
|
+
// body unbalanced and lose the claim on this block.
|
|
96931
|
+
if (code === codes.lessThan) {
|
|
96932
|
+
effects.consume(code);
|
|
96933
|
+
atLineStart = false;
|
|
96934
|
+
return bodyAngleRun;
|
|
96935
|
+
}
|
|
96926
96936
|
if (code === codes.slash) {
|
|
96927
96937
|
if (onOpenerLine)
|
|
96928
96938
|
openerLineCloses += 1;
|
|
@@ -96947,6 +96957,14 @@ function syntax_createTokenize(mode) {
|
|
|
96947
96957
|
atLineStart = false;
|
|
96948
96958
|
return body(code);
|
|
96949
96959
|
}
|
|
96960
|
+
function bodyAngleRun(code) {
|
|
96961
|
+
if (code === codes.lessThan) {
|
|
96962
|
+
effects.consume(code);
|
|
96963
|
+
return bodyAngleRun;
|
|
96964
|
+
}
|
|
96965
|
+
atLineStart = false;
|
|
96966
|
+
return body(code);
|
|
96967
|
+
}
|
|
96950
96968
|
// ── Nested opening tag ─────────────────────────────────────────────────
|
|
96951
96969
|
function nestedOpenTagName(code) {
|
|
96952
96970
|
if (code !== null &&
|
|
@@ -97167,11 +97185,61 @@ function mdxComponent() {
|
|
|
97167
97185
|
;// ./lib/micromark/mdx-expression-lenient/syntax.ts
|
|
97168
97186
|
|
|
97169
97187
|
|
|
97188
|
+
|
|
97189
|
+
/**
|
|
97190
|
+
* The flow constructs allowed to end a multiline run, per parser. Everything but `<`: a
|
|
97191
|
+
* `<Component>` on its own line is the very shape the flow construct exists to keep together.
|
|
97192
|
+
*/
|
|
97193
|
+
const interrupters = new WeakMap();
|
|
97194
|
+
const flowInterrupters = (flow) => {
|
|
97195
|
+
let record = interrupters.get(flow);
|
|
97196
|
+
if (!record) {
|
|
97197
|
+
record = Object.fromEntries(Object.entries(flow).filter(([code]) => Number(code) !== codes.lessThan));
|
|
97198
|
+
interrupters.set(flow, record);
|
|
97199
|
+
}
|
|
97200
|
+
return record;
|
|
97201
|
+
};
|
|
97202
|
+
/**
|
|
97203
|
+
* Lookahead run at every line ending of a flow run, mirroring the paragraph continuation check
|
|
97204
|
+
* in `micromark-core-commonmark/lib/content.js`: `ok` when the next line continues the run,
|
|
97205
|
+
* `nok` when it would start a fenced code block, heading, or thematic break — which the run
|
|
97206
|
+
* must then leave alone rather than swallow. A blank line (including whitespace-only) ends the
|
|
97207
|
+
* run too, unless `blankContinues`: see `nestedLineContinues`.
|
|
97208
|
+
*/
|
|
97209
|
+
function tokenizeLineContinues(blankContinues) {
|
|
97210
|
+
return function tokenize(effects, ok, nok) {
|
|
97211
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
97212
|
+
const self = this;
|
|
97213
|
+
return start;
|
|
97214
|
+
function start(code) {
|
|
97215
|
+
effects.enter(types_types.lineEnding);
|
|
97216
|
+
effects.consume(code);
|
|
97217
|
+
effects.exit(types_types.lineEnding);
|
|
97218
|
+
return factorySpace(effects, prefixed, types_types.linePrefix);
|
|
97219
|
+
}
|
|
97220
|
+
// The paragraph rule also exempts lines indented 4+ columns (indented code can't interrupt);
|
|
97221
|
+
// mdxish disables indented code, so an indented line may still start a block here.
|
|
97222
|
+
function prefixed(code) {
|
|
97223
|
+
if (code === codes.eof)
|
|
97224
|
+
return nok(code);
|
|
97225
|
+
if (markdownLineEnding(code))
|
|
97226
|
+
return blankContinues ? ok(code) : nok(code);
|
|
97227
|
+
return effects.interrupt(flowInterrupters(self.parser.constructs.flow), nok, ok)(code);
|
|
97228
|
+
}
|
|
97229
|
+
};
|
|
97230
|
+
}
|
|
97231
|
+
const lineContinues = { tokenize: tokenizeLineContinues(false), partial: true };
|
|
97232
|
+
/**
|
|
97233
|
+
* Inside an open `{`, `(` or `[` a blank line is JavaScript formatting (between statements in a
|
|
97234
|
+
* callback, inside a JSX branch), so it may not end the run. At depth zero it's far more likely
|
|
97235
|
+
* a prose paragraph break after a stray `{`, and ending the run there keeps the paragraphs apart.
|
|
97236
|
+
*/
|
|
97237
|
+
const nestedLineContinues = { tokenize: tokenizeLineContinues(true), partial: true };
|
|
97170
97238
|
/**
|
|
97171
|
-
* Lenient MDX
|
|
97239
|
+
* Lenient MDX expression tokenizer (agnostic / no acorn).
|
|
97172
97240
|
*
|
|
97173
97241
|
* Matches a balanced `{ ... }` run — tracking nested braces and spanning soft
|
|
97174
|
-
* line breaks — and emits the standard `
|
|
97242
|
+
* line breaks — and emits the standard `mdx*Expression*` tokens so the
|
|
97175
97243
|
* upstream `mdxExpressionFromMarkdown()` builds the node.
|
|
97176
97244
|
*
|
|
97177
97245
|
* Reimplements the official micromark mdxExpression, but an unbalanced brace that
|
|
@@ -97179,70 +97247,115 @@ function mdxComponent() {
|
|
|
97179
97247
|
* and the `{` renders as literal text, making the pipeline forgiving of stray
|
|
97180
97248
|
* braces that upstream would hard-error on.
|
|
97181
97249
|
*/
|
|
97182
|
-
function
|
|
97183
|
-
|
|
97184
|
-
return
|
|
97185
|
-
|
|
97186
|
-
|
|
97187
|
-
|
|
97188
|
-
|
|
97189
|
-
|
|
97190
|
-
|
|
97191
|
-
|
|
97192
|
-
|
|
97193
|
-
|
|
97194
|
-
|
|
97195
|
-
|
|
97196
|
-
|
|
97197
|
-
|
|
97250
|
+
function tokenizeExpression(variant) {
|
|
97251
|
+
const isFlow = variant === 'mdxFlowExpression';
|
|
97252
|
+
return function tokenize(effects, ok, nok) {
|
|
97253
|
+
// Read eagerly: micromark calls `tokenize` with a fresh context per attempt, so this is the
|
|
97254
|
+
// value for this attempt, and the state functions below don't receive `this` at all.
|
|
97255
|
+
const { interrupt } = this;
|
|
97256
|
+
let depth = 0;
|
|
97257
|
+
let nesting = 0;
|
|
97258
|
+
let multiline = false;
|
|
97259
|
+
return start;
|
|
97260
|
+
function start(code) {
|
|
97261
|
+
if (code !== codes.leftCurlyBrace)
|
|
97262
|
+
return nok(code);
|
|
97263
|
+
// Never end a paragraph. A `{` continuing the line above is prose or a magic-block body
|
|
97264
|
+
// (`[block:callout]` puts one on the next line), not a block of its own.
|
|
97265
|
+
if (isFlow && interrupt)
|
|
97266
|
+
return nok(code);
|
|
97267
|
+
effects.enter(variant);
|
|
97268
|
+
effects.enter(`${variant}Marker`);
|
|
97269
|
+
effects.consume(code);
|
|
97270
|
+
effects.exit(`${variant}Marker`);
|
|
97271
|
+
return before;
|
|
97198
97272
|
}
|
|
97199
|
-
|
|
97200
|
-
|
|
97273
|
+
function before(code) {
|
|
97274
|
+
if (code === codes.eof)
|
|
97275
|
+
return end(code);
|
|
97276
|
+
if (markdownLineEnding(code)) {
|
|
97277
|
+
// A text run lives in a paragraph micromark has already bounded. A flow run bounds
|
|
97278
|
+
// itself: a blank line or an interrupting block ends it, so a stray `{` can't claim
|
|
97279
|
+
// the rest of the document, and `{\n\n}` stays two literal paragraphs.
|
|
97280
|
+
if (!isFlow)
|
|
97281
|
+
return lineEnding(code);
|
|
97282
|
+
return effects.check(depth > 0 || nesting > 0 ? nestedLineContinues : lineContinues, lineEnding, end)(code);
|
|
97283
|
+
}
|
|
97284
|
+
if (code === codes.rightCurlyBrace && depth === 0)
|
|
97285
|
+
return close(code);
|
|
97286
|
+
effects.enter(`${variant}Chunk`);
|
|
97287
|
+
return inside(code);
|
|
97288
|
+
}
|
|
97289
|
+
function lineEnding(code) {
|
|
97290
|
+
multiline = true;
|
|
97291
|
+
effects.enter(types_types.lineEnding);
|
|
97201
97292
|
effects.consume(code);
|
|
97202
|
-
effects.exit(
|
|
97293
|
+
effects.exit(types_types.lineEnding);
|
|
97203
97294
|
return before;
|
|
97204
97295
|
}
|
|
97205
|
-
|
|
97206
|
-
|
|
97296
|
+
function end(code) {
|
|
97297
|
+
effects.exit(variant);
|
|
97298
|
+
return nok(code);
|
|
97207
97299
|
}
|
|
97208
|
-
|
|
97209
|
-
|
|
97210
|
-
|
|
97211
|
-
|
|
97212
|
-
|
|
97213
|
-
|
|
97214
|
-
|
|
97300
|
+
function inside(code) {
|
|
97301
|
+
if (code === codes.eof || markdownLineEnding(code)) {
|
|
97302
|
+
effects.exit(`${variant}Chunk`);
|
|
97303
|
+
return before(code);
|
|
97304
|
+
}
|
|
97305
|
+
if (code === codes.rightCurlyBrace && depth === 0) {
|
|
97306
|
+
effects.exit(`${variant}Chunk`);
|
|
97307
|
+
return close(code);
|
|
97308
|
+
}
|
|
97309
|
+
if (code === codes.leftCurlyBrace)
|
|
97310
|
+
depth += 1;
|
|
97311
|
+
else if (code === codes.rightCurlyBrace)
|
|
97312
|
+
depth -= 1;
|
|
97313
|
+
else if (code === codes.leftParenthesis || code === codes.leftSquareBracket)
|
|
97314
|
+
nesting += 1;
|
|
97315
|
+
else if (code === codes.rightParenthesis || code === codes.rightSquareBracket)
|
|
97316
|
+
nesting -= 1;
|
|
97317
|
+
effects.consume(code);
|
|
97318
|
+
return inside;
|
|
97215
97319
|
}
|
|
97216
|
-
|
|
97217
|
-
effects.
|
|
97218
|
-
|
|
97320
|
+
function close(code) {
|
|
97321
|
+
effects.enter(`${variant}Marker`);
|
|
97322
|
+
effects.consume(code);
|
|
97323
|
+
effects.exit(`${variant}Marker`);
|
|
97324
|
+
effects.exit(variant);
|
|
97325
|
+
if (!isFlow)
|
|
97326
|
+
return ok;
|
|
97327
|
+
// A run that closes on the line it opened stays a text expression inside its paragraph:
|
|
97328
|
+
// claiming it as flow would strip the `<p>` every standalone `{expr}` line renders with.
|
|
97329
|
+
return multiline ? after : nok;
|
|
97219
97330
|
}
|
|
97220
|
-
|
|
97221
|
-
|
|
97222
|
-
|
|
97223
|
-
|
|
97224
|
-
|
|
97225
|
-
|
|
97226
|
-
}
|
|
97227
|
-
function close(code) {
|
|
97228
|
-
effects.enter('mdxTextExpressionMarker');
|
|
97229
|
-
effects.consume(code);
|
|
97230
|
-
effects.exit('mdxTextExpressionMarker');
|
|
97231
|
-
effects.exit('mdxTextExpression');
|
|
97232
|
-
return ok;
|
|
97233
|
-
}
|
|
97331
|
+
function after(code) {
|
|
97332
|
+
return markdownSpace(code) ? factorySpace(effects, lineEnd, types_types.whitespace)(code) : lineEnd(code);
|
|
97333
|
+
}
|
|
97334
|
+
function lineEnd(code) {
|
|
97335
|
+
return code === codes.eof || markdownLineEnding(code) ? ok(code) : nok(code);
|
|
97336
|
+
}
|
|
97337
|
+
};
|
|
97234
97338
|
}
|
|
97235
97339
|
function mdxExpressionLenient() {
|
|
97236
97340
|
return {
|
|
97341
|
+
flow: {
|
|
97342
|
+
[codes.leftCurlyBrace]: {
|
|
97343
|
+
name: 'mdxFlowExpression',
|
|
97344
|
+
tokenize: tokenizeExpression('mdxFlowExpression'),
|
|
97345
|
+
},
|
|
97346
|
+
},
|
|
97237
97347
|
text: {
|
|
97238
97348
|
[codes.leftCurlyBrace]: {
|
|
97239
97349
|
name: 'mdxTextExpression',
|
|
97240
|
-
tokenize:
|
|
97350
|
+
tokenize: tokenizeExpression('mdxTextExpression'),
|
|
97241
97351
|
},
|
|
97242
97352
|
},
|
|
97243
97353
|
};
|
|
97244
97354
|
}
|
|
97245
97355
|
|
|
97356
|
+
;// ./lib/micromark/mdx-expression-lenient/index.ts
|
|
97357
|
+
|
|
97358
|
+
|
|
97246
97359
|
;// ./lib/micromark/mdxish-extensions.ts
|
|
97247
97360
|
|
|
97248
97361
|
|
|
@@ -101812,6 +101925,17 @@ const tablesToJsx = () => tree => {
|
|
|
101812
101925
|
;// ./processor/transform/tailwind.tsx
|
|
101813
101926
|
|
|
101814
101927
|
|
|
101928
|
+
|
|
101929
|
+
|
|
101930
|
+
/** Whitespace-only text is layout between blocks, not inline flow. */
|
|
101931
|
+
const isInlineContent = (node) => phrasing(node) && !(node.type === 'text' && node.value.trim() === '');
|
|
101932
|
+
/**
|
|
101933
|
+
* Whether the child at `index` sits in inline flow: its parent only allows
|
|
101934
|
+
* phrasing content (e.g. a paragraph), or it is flanked by phrasing siblings
|
|
101935
|
+
* (e.g. `<div>text <Image /> text</div>`, whose children skip the paragraph).
|
|
101936
|
+
*/
|
|
101937
|
+
const isInlineInContext = (index, parent) => INLINE_ONLY_PARENT_TYPES.has(parent.type) ||
|
|
101938
|
+
parent.children.some((sibling, siblingIndex) => siblingIndex !== index && isInlineContent(sibling));
|
|
101815
101939
|
const injectTailwindRoot = ({ components = {} }) => (node, index, parent) => {
|
|
101816
101940
|
if (!('name' in node))
|
|
101817
101941
|
return;
|
|
@@ -101820,7 +101944,7 @@ const injectTailwindRoot = ({ components = {} }) => (node, index, parent) => {
|
|
|
101820
101944
|
if (!('children' in parent))
|
|
101821
101945
|
return;
|
|
101822
101946
|
const attrs = {
|
|
101823
|
-
flow: node.type === 'mdxJsxFlowElement',
|
|
101947
|
+
flow: node.type === 'mdxJsxFlowElement' && !isInlineInContext(index, parent),
|
|
101824
101948
|
};
|
|
101825
101949
|
const wrapper = {
|
|
101826
101950
|
type: node.type,
|
|
@@ -124308,6 +124432,111 @@ const parseTag = (value, opts = {}) => {
|
|
|
124308
124432
|
};
|
|
124309
124433
|
};
|
|
124310
124434
|
|
|
124435
|
+
;// ./processor/transform/mdxish/variables-text.ts
|
|
124436
|
+
|
|
124437
|
+
|
|
124438
|
+
/**
|
|
124439
|
+
* Matches {user.<field>} patterns:
|
|
124440
|
+
* - {user.name}
|
|
124441
|
+
* - {user.email}
|
|
124442
|
+
* - {user['field']}
|
|
124443
|
+
* - {user["field"]}
|
|
124444
|
+
*
|
|
124445
|
+
* Captures the field name in group 1 (dot notation) or group 2 (bracket notation)
|
|
124446
|
+
*/
|
|
124447
|
+
const USER_VAR_REGEX = /\{user\.(\w+)\}|\{user\[['"](\w+)['"]\]\}/g;
|
|
124448
|
+
/**
|
|
124449
|
+
* The lone `{user.<field>}` reference an expression node holds, or `null` when the node isn't an
|
|
124450
|
+
* expression or holds anything else (`{1 + 1}`, a CSS-looking body, two references in one brace).
|
|
124451
|
+
* Exported so promotion gates can tell a variable reference apart from an expression that must
|
|
124452
|
+
* stay literal.
|
|
124453
|
+
*/
|
|
124454
|
+
function soleUserVariableExpression(node) {
|
|
124455
|
+
if (node.type !== 'mdxFlowExpression' && node.type !== 'mdxTextExpression')
|
|
124456
|
+
return null;
|
|
124457
|
+
const { value } = node;
|
|
124458
|
+
const wrapped = `{${(value ?? '').trim()}}`;
|
|
124459
|
+
const matches = [...wrapped.matchAll(USER_VAR_REGEX)];
|
|
124460
|
+
if (matches.length !== 1 || matches[0][0] !== wrapped)
|
|
124461
|
+
return null;
|
|
124462
|
+
return { name: matches[0][1] || matches[0][2], wrapped };
|
|
124463
|
+
}
|
|
124464
|
+
function makeVariableNode(varName, rawValue) {
|
|
124465
|
+
return {
|
|
124466
|
+
type: NodeTypes.variable,
|
|
124467
|
+
data: {
|
|
124468
|
+
hName: 'Variable',
|
|
124469
|
+
hProperties: { name: varName },
|
|
124470
|
+
},
|
|
124471
|
+
value: rawValue,
|
|
124472
|
+
};
|
|
124473
|
+
}
|
|
124474
|
+
/**
|
|
124475
|
+
* A remark plugin that parses {user.<field>} patterns from text nodes and
|
|
124476
|
+
* mdx expression nodes, creating Variable nodes for runtime resolution.
|
|
124477
|
+
*
|
|
124478
|
+
* Handles:
|
|
124479
|
+
* - `text` nodes: when safeMode is true or after expression evaluation
|
|
124480
|
+
* - `mdxTextExpression` nodes: when mdxExpression has parsed {user.*} before evaluation
|
|
124481
|
+
* - `mdxFlowExpression` nodes: when {user.*} appears on its own line (e.g. inside JSX table cells)
|
|
124482
|
+
*
|
|
124483
|
+
* Supports any user field: name, email, email_verified, exp, iat, etc.
|
|
124484
|
+
*/
|
|
124485
|
+
function visitExpressionNode(node, index, parent) {
|
|
124486
|
+
if (index === undefined || !parent)
|
|
124487
|
+
return;
|
|
124488
|
+
const match = soleUserVariableExpression(node);
|
|
124489
|
+
if (!match)
|
|
124490
|
+
return;
|
|
124491
|
+
parent.children.splice(index, 1, makeVariableNode(match.name, match.wrapped));
|
|
124492
|
+
}
|
|
124493
|
+
const variablesTextTransformer = () => tree => {
|
|
124494
|
+
visit(tree, 'mdxTextExpression', (node, index, parent) => {
|
|
124495
|
+
visitExpressionNode(node, index, parent);
|
|
124496
|
+
});
|
|
124497
|
+
visit(tree, 'mdxFlowExpression', (node, index, parent) => {
|
|
124498
|
+
visitExpressionNode(node, index, parent);
|
|
124499
|
+
});
|
|
124500
|
+
visit(tree, 'text', (node, index, parent) => {
|
|
124501
|
+
if (index === undefined || !parent)
|
|
124502
|
+
return;
|
|
124503
|
+
// Skip if inside inline code
|
|
124504
|
+
if (parent.type === 'inlineCode')
|
|
124505
|
+
return;
|
|
124506
|
+
const text = node.value;
|
|
124507
|
+
if (typeof text !== 'string' || !text.trim())
|
|
124508
|
+
return;
|
|
124509
|
+
if (!text.includes('{user.') && !text.includes('{user['))
|
|
124510
|
+
return;
|
|
124511
|
+
const matches = [...text.matchAll(USER_VAR_REGEX)];
|
|
124512
|
+
if (matches.length === 0)
|
|
124513
|
+
return;
|
|
124514
|
+
const parts = [];
|
|
124515
|
+
let lastIndex = 0;
|
|
124516
|
+
matches.forEach(match => {
|
|
124517
|
+
const matchIndex = match.index ?? 0;
|
|
124518
|
+
// Add text before the match
|
|
124519
|
+
if (matchIndex > lastIndex) {
|
|
124520
|
+
parts.push({ type: 'text', value: text.slice(lastIndex, matchIndex) });
|
|
124521
|
+
}
|
|
124522
|
+
// Extract variable name from either capture group (dot or bracket notation)
|
|
124523
|
+
const varName = match[1] || match[2];
|
|
124524
|
+
parts.push(makeVariableNode(varName, match[0]));
|
|
124525
|
+
lastIndex = matchIndex + match[0].length;
|
|
124526
|
+
});
|
|
124527
|
+
// Add remaining text after last match
|
|
124528
|
+
if (lastIndex < text.length) {
|
|
124529
|
+
parts.push({ type: 'text', value: text.slice(lastIndex) });
|
|
124530
|
+
}
|
|
124531
|
+
// Replace node with parts
|
|
124532
|
+
if (parts.length > 1 || (parts.length === 1 && parts[0].type !== 'text')) {
|
|
124533
|
+
parent.children.splice(index, 1, ...parts);
|
|
124534
|
+
}
|
|
124535
|
+
});
|
|
124536
|
+
return tree;
|
|
124537
|
+
};
|
|
124538
|
+
/* harmony default export */ const variables_text = (variablesTextTransformer);
|
|
124539
|
+
|
|
124311
124540
|
;// ./processor/transform/mdxish/components/utils.ts
|
|
124312
124541
|
|
|
124313
124542
|
|
|
@@ -124385,19 +124614,15 @@ const NON_PROMOTABLE_PLAIN_TAGS = new Set([...htmlRawNames, ...tableTags, 'table
|
|
|
124385
124614
|
const NESTED_TABLE_RE = /<table[\s>]/i;
|
|
124386
124615
|
const isMarkdownPromotableHtmlTag = (tag) => !NON_PROMOTABLE_PLAIN_TAGS.has(tag);
|
|
124387
124616
|
// Expression nodes count as plain so `<div>{1+1}</div>` keeps its current
|
|
124388
|
-
// literal-brace behavior
|
|
124389
|
-
|
|
124390
|
-
|
|
124391
|
-
'text',
|
|
124392
|
-
'html',
|
|
124393
|
-
'mdxTextExpression',
|
|
124394
|
-
'mdxFlowExpression',
|
|
124395
|
-
NodeTypes.variable,
|
|
124396
|
-
NodeTypes.glossary,
|
|
124397
|
-
]);
|
|
124617
|
+
// literal-brace behavior — authors put CSS-shaped braces in these bodies, and only
|
|
124618
|
+
// a reference that names a real variable may resolve.
|
|
124619
|
+
const PLAIN_CONTENT_TYPES = new Set(['paragraph', 'text', 'html', 'mdxTextExpression', 'mdxFlowExpression']);
|
|
124398
124620
|
// Promoting plain HTML is only worth bypassing rehype-raw's parse5 pass when
|
|
124399
|
-
// the body parses into an actual markdown construct.
|
|
124621
|
+
// the body parses into an actual markdown construct. Variables and glossary terms
|
|
124622
|
+
// count: parse5 renders `<<var>>` as a stray `<` plus a `<var>` tag, so a body that
|
|
124623
|
+
// holds nothing else still has to be promoted to resolve.
|
|
124400
124624
|
const containsMarkdownConstruct = (nodes) => nodes.some(node => !PLAIN_CONTENT_TYPES.has(node.type) ||
|
|
124625
|
+
soleUserVariableExpression(node) !== null ||
|
|
124401
124626
|
('children' in node && Array.isArray(node.children) && containsMarkdownConstruct(node.children)));
|
|
124402
124627
|
/**
|
|
124403
124628
|
* Index of the `</tag>` that balances the already-consumed opening tag (the
|
|
@@ -125163,6 +125388,7 @@ const evaluateExports = () => (tree, file) => {
|
|
|
125163
125388
|
|
|
125164
125389
|
|
|
125165
125390
|
|
|
125391
|
+
|
|
125166
125392
|
const parseExpression = (expression) => jsxAcornParser.parse(expression, { ecmaVersion: 'latest', sourceType: 'module' });
|
|
125167
125393
|
/**
|
|
125168
125394
|
* Recursively report whether an estree value contains any JSX element or fragment node.
|
|
@@ -125179,22 +125405,16 @@ const containsJsxNode = (value) => {
|
|
|
125179
125405
|
return true;
|
|
125180
125406
|
return Object.values(value).some(containsJsxNode);
|
|
125181
125407
|
};
|
|
125182
|
-
/** Read the component name off a JSX element name node (`Foo`, `Foo.Bar`, `foo:Bar`). */
|
|
125183
125408
|
const jsxElementName = (name) => {
|
|
125184
125409
|
if (name === null || typeof name !== 'object')
|
|
125185
125410
|
return undefined;
|
|
125186
125411
|
const node = name;
|
|
125187
|
-
if (node.type
|
|
125188
|
-
return
|
|
125189
|
-
|
|
125190
|
-
if (node.type === 'JSXMemberExpression')
|
|
125191
|
-
return jsxElementName(node.object);
|
|
125192
|
-
if (node.type === 'JSXNamespacedName')
|
|
125193
|
-
return jsxElementName(node.namespace);
|
|
125194
|
-
return undefined;
|
|
125412
|
+
if (node.type !== 'JSXIdentifier' || typeof node.name !== 'string')
|
|
125413
|
+
return undefined;
|
|
125414
|
+
return componentNamePattern.test(node.name) ? node.name : undefined;
|
|
125195
125415
|
};
|
|
125196
125416
|
/**
|
|
125197
|
-
* Collect the
|
|
125417
|
+
* Collect the component names an expression uses as JSX tags. Parsed rather than pattern
|
|
125198
125418
|
* matched: `{count < Max ? <Foo/> : <Bar/>}` puts a capitalized name straight after a `<` without
|
|
125199
125419
|
* it being a tag, and only the parser can tell the two apart. Unparseable input yields nothing —
|
|
125200
125420
|
* evaluation is about to throw on it anyway.
|
|
@@ -125218,8 +125438,7 @@ const jsxComponentNames = (expression) => {
|
|
|
125218
125438
|
const node = value;
|
|
125219
125439
|
if (node.type === 'JSXOpeningElement') {
|
|
125220
125440
|
const name = jsxElementName(node.name);
|
|
125221
|
-
|
|
125222
|
-
if (name && /^[A-Z]/.test(name))
|
|
125441
|
+
if (name)
|
|
125223
125442
|
names.add(name);
|
|
125224
125443
|
}
|
|
125225
125444
|
Object.values(node).forEach(walk);
|
|
@@ -125378,7 +125597,8 @@ function renderFallbackHtml(element) {
|
|
|
125378
125597
|
const rawNode = { type: 'raw', value: __WEBPACK_CJS_EXPORT_renderToStaticMarkup__(element) };
|
|
125379
125598
|
return [rawNode];
|
|
125380
125599
|
}
|
|
125381
|
-
catch {
|
|
125600
|
+
catch (error) {
|
|
125601
|
+
console.warn('[mdxish] Could not render expression result:', error);
|
|
125382
125602
|
return [];
|
|
125383
125603
|
}
|
|
125384
125604
|
}
|
|
@@ -125436,6 +125656,7 @@ function reactElementToHast(node) {
|
|
|
125436
125656
|
|
|
125437
125657
|
|
|
125438
125658
|
|
|
125659
|
+
|
|
125439
125660
|
/**
|
|
125440
125661
|
* Bind the components a given expression actually uses as tags. Scoped per expression on purpose:
|
|
125441
125662
|
* binding the whole hash would shadow same-named globals (a `math` component would break
|
|
@@ -125464,17 +125685,28 @@ const isRenderable = (value) => {
|
|
|
125464
125685
|
return true;
|
|
125465
125686
|
return Array.isArray(value) && value.some(isRenderable);
|
|
125466
125687
|
};
|
|
125688
|
+
const isPhrasingTag = (tagName) => lib_phrasing({ type: 'element', tagName, properties: {}, children: [] });
|
|
125467
125689
|
/**
|
|
125468
|
-
* Whether an expression evaluated to block-level content.
|
|
125469
|
-
* unless
|
|
125470
|
-
*
|
|
125690
|
+
* Whether an expression evaluated to block-level content. A capitalized tag is a component,
|
|
125691
|
+
* block-level unless it's on the inline list (so a `Table` component isn't mistaken for an inline
|
|
125692
|
+
* `<table>`); a lowercase tag is HTML, block-level unless it's phrasing content. A `raw` node is
|
|
125693
|
+
* HTML from `renderFallbackHtml`, so it's parsed and judged by the same rule.
|
|
125471
125694
|
*/
|
|
125472
125695
|
const isBlockResult = (children) => children.some(child => {
|
|
125696
|
+
if (child.type === 'raw')
|
|
125697
|
+
return isBlockResult(fromHtml(child.value, { fragment: true }).children);
|
|
125473
125698
|
if (child.type !== 'element' && child.type !== 'mdx-jsx')
|
|
125474
125699
|
return false;
|
|
125475
125700
|
const { tagName } = child;
|
|
125476
|
-
return
|
|
125701
|
+
return /^[A-Z]/.test(tagName) ? !INLINE_COMPONENT_TAGS.has(tagName) : !isPhrasingTag(tagName);
|
|
125477
125702
|
});
|
|
125703
|
+
const JSX_ELEMENT_TYPES = new Set(['mdxJsxFlowElement', 'mdxJsxTextElement']);
|
|
125704
|
+
const wrapInParagraph = (child) => ({
|
|
125705
|
+
type: 'paragraph',
|
|
125706
|
+
children: [child],
|
|
125707
|
+
position: child.position,
|
|
125708
|
+
});
|
|
125709
|
+
const placeText = (text, needsBlock) => (needsBlock ? wrapInParagraph(text) : text);
|
|
125478
125710
|
/** Turn a non-renderable evaluation result into a text node. */
|
|
125479
125711
|
const createTextNode = (result, position) => {
|
|
125480
125712
|
if (result === null || result === undefined)
|
|
@@ -125510,6 +125742,7 @@ const evaluateExpressions = ({ components, variables } = {}) => (tree, file) =>
|
|
|
125510
125742
|
const expression = value?.trim();
|
|
125511
125743
|
if (!expression)
|
|
125512
125744
|
return;
|
|
125745
|
+
const needsBlock = expressionNode.type === 'mdxFlowExpression' && !JSX_ELEMENT_TYPES.has(parent.type);
|
|
125513
125746
|
try {
|
|
125514
125747
|
const scope = { ...componentScope(expression, components ?? {}), ...baseScope };
|
|
125515
125748
|
const result = evalExpression(expression, scope);
|
|
@@ -125518,10 +125751,17 @@ const evaluateExpressions = ({ components, variables } = {}) => (tree, file) =>
|
|
|
125518
125751
|
// passes through rehypeRaw/parse5 step later in the pipeline. This ensures that the
|
|
125519
125752
|
// expression result is not parsed by parse5 and fragmenting the nesting that is valid JSX
|
|
125520
125753
|
// but invalid HTML — e.g. an `<a>` wrapping `<a>`.
|
|
125521
|
-
|
|
125754
|
+
const hChildren = reactElementToHast(result);
|
|
125755
|
+
expressionNode.data = { ...expressionNode.data, hChildren };
|
|
125756
|
+
// An inline result in a block slot renders inside a `<p>`, as its one-line form does.
|
|
125757
|
+
// Retyping it as a text expression makes it legal paragraph content.
|
|
125758
|
+
if (needsBlock && !isBlockResult(hChildren)) {
|
|
125759
|
+
const inline = { ...expressionNode, type: 'mdxTextExpression' };
|
|
125760
|
+
parent.children.splice(index, 1, wrapInParagraph(inline));
|
|
125761
|
+
}
|
|
125522
125762
|
}
|
|
125523
125763
|
else {
|
|
125524
|
-
parent.children.splice(index, 1, createTextNode(result, position));
|
|
125764
|
+
parent.children.splice(index, 1, placeText(createTextNode(result, position), needsBlock));
|
|
125525
125765
|
}
|
|
125526
125766
|
}
|
|
125527
125767
|
catch (_error) {
|
|
@@ -125529,7 +125769,8 @@ const evaluateExpressions = ({ components, variables } = {}) => (tree, file) =>
|
|
|
125529
125769
|
// parser treats contents as code, so backslash escapes aren't applied;
|
|
125530
125770
|
// restore them here so e.g. `{\!}` round-trips to `{!}`.
|
|
125531
125771
|
const processed = expression.replace(/\\([!-/:-@[-`{-~])/g, '$1');
|
|
125532
|
-
|
|
125772
|
+
const literal = { type: 'text', value: `{${processed}}`, position };
|
|
125773
|
+
parent.children.splice(index, 1, placeText(literal, needsBlock));
|
|
125533
125774
|
}
|
|
125534
125775
|
});
|
|
125535
125776
|
// A text expression is parsed inside a paragraph, but its result can be block content: a
|
|
@@ -127242,12 +127483,20 @@ function removeJSXComments(content) {
|
|
|
127242
127483
|
const OPAQUE_CONTAINERS = new Set(['pre', 'textarea', 'htmlblock']);
|
|
127243
127484
|
/** The missing-slash typo shape: an attribute-less, non-self-closing opener. */
|
|
127244
127485
|
const BARE_OPENER_SOURCE_RE = /^<[A-Za-z]+\s*>$/;
|
|
127245
|
-
/** The opener
|
|
127246
|
-
const
|
|
127247
|
-
|
|
127486
|
+
/** The opener is immediately preceded by a complete tag, so the prefix is markup and not prose. */
|
|
127487
|
+
const PREFIX_ENDS_WITH_TAG_RE = /<[^<>]*>\s*$/;
|
|
127488
|
+
/**
|
|
127489
|
+
* The opener finishes its line, preceded by nothing but whitespace or by markup.
|
|
127490
|
+
* Requiring markup (not merely "something") keeps a markdown block prefix such as
|
|
127491
|
+
* a `>` quote marker from qualifying, while allowing the closer to trail a cell or
|
|
127492
|
+
* `</thead>` on a single-line table.
|
|
127493
|
+
*/
|
|
127494
|
+
const endsLineAfterMarkup = (content, start, end) => {
|
|
127248
127495
|
const lineEnd = content.indexOf('\n', end);
|
|
127249
|
-
|
|
127250
|
-
|
|
127496
|
+
if (content.slice(end, lineEnd === -1 ? content.length : lineEnd).trim() !== '')
|
|
127497
|
+
return false;
|
|
127498
|
+
const prefix = content.slice(content.lastIndexOf('\n', start - 1) + 1, start);
|
|
127499
|
+
return prefix.trim() === '' || PREFIX_ENDS_WITH_TAG_RE.test(prefix);
|
|
127251
127500
|
};
|
|
127252
127501
|
/**
|
|
127253
127502
|
* Rewrites a bare `<table>` that is almost certainly a missing-slash closer
|
|
@@ -127255,7 +127504,7 @@ const isAloneOnLine = (content, start, end) => {
|
|
|
127255
127504
|
* Customer docs (CX-3850) close tables with a second bare opener; without this,
|
|
127256
127505
|
* the never-terminated HTML flow block swallows the markdown that follows.
|
|
127257
127506
|
*
|
|
127258
|
-
* A candidate is a bare opener
|
|
127507
|
+
* A candidate is a bare opener that finishes its line while a table is already open.
|
|
127259
127508
|
* It is judged a typo only when its element ends implicitly (no explicit
|
|
127260
127509
|
* `</table>`) without ever acquiring table-structure children — so genuine
|
|
127261
127510
|
* nested tables, whatever precedes their rows, are left alone.
|
|
@@ -127284,7 +127533,7 @@ function repairMistakenTableClosers(content) {
|
|
|
127284
127533
|
start,
|
|
127285
127534
|
end,
|
|
127286
127535
|
hasStructureChild: false,
|
|
127287
|
-
isCandidate: stack.length > 0 && BARE_OPENER_SOURCE_RE.test(source) &&
|
|
127536
|
+
isCandidate: stack.length > 0 && BARE_OPENER_SOURCE_RE.test(source) && endsLineAfterMarkup(content, start, end),
|
|
127288
127537
|
});
|
|
127289
127538
|
}
|
|
127290
127539
|
else if (opaqueDepth === 0 && tableTags.has(lower) && stack.length > 0) {
|
|
@@ -127724,97 +127973,6 @@ const variablesCodeResolver = ({ variables } = {}) => tree => {
|
|
|
127724
127973
|
};
|
|
127725
127974
|
/* harmony default export */ const variables_code = (variablesCodeResolver);
|
|
127726
127975
|
|
|
127727
|
-
;// ./processor/transform/mdxish/variables-text.ts
|
|
127728
|
-
|
|
127729
|
-
|
|
127730
|
-
/**
|
|
127731
|
-
* Matches {user.<field>} patterns:
|
|
127732
|
-
* - {user.name}
|
|
127733
|
-
* - {user.email}
|
|
127734
|
-
* - {user['field']}
|
|
127735
|
-
* - {user["field"]}
|
|
127736
|
-
*
|
|
127737
|
-
* Captures the field name in group 1 (dot notation) or group 2 (bracket notation)
|
|
127738
|
-
*/
|
|
127739
|
-
const USER_VAR_REGEX = /\{user\.(\w+)\}|\{user\[['"](\w+)['"]\]\}/g;
|
|
127740
|
-
function makeVariableNode(varName, rawValue) {
|
|
127741
|
-
return {
|
|
127742
|
-
type: NodeTypes.variable,
|
|
127743
|
-
data: {
|
|
127744
|
-
hName: 'Variable',
|
|
127745
|
-
hProperties: { name: varName },
|
|
127746
|
-
},
|
|
127747
|
-
value: rawValue,
|
|
127748
|
-
};
|
|
127749
|
-
}
|
|
127750
|
-
/**
|
|
127751
|
-
* A remark plugin that parses {user.<field>} patterns from text nodes and
|
|
127752
|
-
* mdx expression nodes, creating Variable nodes for runtime resolution.
|
|
127753
|
-
*
|
|
127754
|
-
* Handles:
|
|
127755
|
-
* - `text` nodes: when safeMode is true or after expression evaluation
|
|
127756
|
-
* - `mdxTextExpression` nodes: when mdxExpression has parsed {user.*} before evaluation
|
|
127757
|
-
* - `mdxFlowExpression` nodes: when {user.*} appears on its own line (e.g. inside JSX table cells)
|
|
127758
|
-
*
|
|
127759
|
-
* Supports any user field: name, email, email_verified, exp, iat, etc.
|
|
127760
|
-
*/
|
|
127761
|
-
function visitExpressionNode(node, index, parent) {
|
|
127762
|
-
if (index === undefined || !parent)
|
|
127763
|
-
return;
|
|
127764
|
-
const wrapped = `{${(node.value ?? '').trim()}}`;
|
|
127765
|
-
const matches = [...wrapped.matchAll(USER_VAR_REGEX)];
|
|
127766
|
-
if (matches.length !== 1)
|
|
127767
|
-
return;
|
|
127768
|
-
const varName = matches[0][1] || matches[0][2];
|
|
127769
|
-
parent.children.splice(index, 1, makeVariableNode(varName, wrapped));
|
|
127770
|
-
}
|
|
127771
|
-
const variablesTextTransformer = () => tree => {
|
|
127772
|
-
visit(tree, 'mdxTextExpression', (node, index, parent) => {
|
|
127773
|
-
visitExpressionNode(node, index, parent);
|
|
127774
|
-
});
|
|
127775
|
-
visit(tree, 'mdxFlowExpression', (node, index, parent) => {
|
|
127776
|
-
visitExpressionNode(node, index, parent);
|
|
127777
|
-
});
|
|
127778
|
-
visit(tree, 'text', (node, index, parent) => {
|
|
127779
|
-
if (index === undefined || !parent)
|
|
127780
|
-
return;
|
|
127781
|
-
// Skip if inside inline code
|
|
127782
|
-
if (parent.type === 'inlineCode')
|
|
127783
|
-
return;
|
|
127784
|
-
const text = node.value;
|
|
127785
|
-
if (typeof text !== 'string' || !text.trim())
|
|
127786
|
-
return;
|
|
127787
|
-
if (!text.includes('{user.') && !text.includes('{user['))
|
|
127788
|
-
return;
|
|
127789
|
-
const matches = [...text.matchAll(USER_VAR_REGEX)];
|
|
127790
|
-
if (matches.length === 0)
|
|
127791
|
-
return;
|
|
127792
|
-
const parts = [];
|
|
127793
|
-
let lastIndex = 0;
|
|
127794
|
-
matches.forEach(match => {
|
|
127795
|
-
const matchIndex = match.index ?? 0;
|
|
127796
|
-
// Add text before the match
|
|
127797
|
-
if (matchIndex > lastIndex) {
|
|
127798
|
-
parts.push({ type: 'text', value: text.slice(lastIndex, matchIndex) });
|
|
127799
|
-
}
|
|
127800
|
-
// Extract variable name from either capture group (dot or bracket notation)
|
|
127801
|
-
const varName = match[1] || match[2];
|
|
127802
|
-
parts.push(makeVariableNode(varName, match[0]));
|
|
127803
|
-
lastIndex = matchIndex + match[0].length;
|
|
127804
|
-
});
|
|
127805
|
-
// Add remaining text after last match
|
|
127806
|
-
if (lastIndex < text.length) {
|
|
127807
|
-
parts.push({ type: 'text', value: text.slice(lastIndex) });
|
|
127808
|
-
}
|
|
127809
|
-
// Replace node with parts
|
|
127810
|
-
if (parts.length > 1 || (parts.length === 1 && parts[0].type !== 'text')) {
|
|
127811
|
-
parent.children.splice(index, 1, ...parts);
|
|
127812
|
-
}
|
|
127813
|
-
});
|
|
127814
|
-
return tree;
|
|
127815
|
-
};
|
|
127816
|
-
/* harmony default export */ const variables_text = (variablesTextTransformer);
|
|
127817
|
-
|
|
127818
127976
|
;// ./lib/utils/mdxish/mdxish-load-components.ts
|
|
127819
127977
|
|
|
127820
127978
|
|
|
@@ -129075,7 +129233,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"*":["about","acceptCharset","accessK
|
|
|
129075
129233
|
/******/ // startup
|
|
129076
129234
|
/******/ // Load entry module and return exports
|
|
129077
129235
|
/******/ // This entry module used 'module' so it can't be inlined
|
|
129078
|
-
/******/ let __webpack_exports__ = __webpack_require__(
|
|
129236
|
+
/******/ let __webpack_exports__ = __webpack_require__(6261);
|
|
129079
129237
|
/******/ module.exports = __webpack_exports__;
|
|
129080
129238
|
/******/
|
|
129081
129239
|
/******/ })()
|