@readme/markdown 14.11.4 → 14.12.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/HTMLBlock/index.tsx +12 -10
- package/dist/main.js +2055 -1886
- package/dist/main.node.js +2054 -1885
- package/dist/main.node.js.map +1 -1
- package/dist/processor/compile/text.d.ts +4 -0
- package/dist/processor/transform/mdxish/components/mdx-blocks.d.ts +4 -0
- package/dist/processor/transform/mdxish/components/utils.d.ts +13 -1
- package/dist/processor/transform/mdxish/mdxish-html-blocks.d.ts +7 -6
- package/dist/processor/transform/mdxish/normalize-closing-tag-whitespace.d.ts +13 -0
- package/dist/processor/transform/mdxish/terminate-html-flow-blocks.d.ts +3 -17
- package/dist/render-fixture.node.js +2055 -1886
- package/dist/render-fixture.node.js.map +1 -1
- package/package.json +2 -2
|
@@ -91765,17 +91765,12 @@ const extractScripts = (html = '') => {
|
|
|
91765
91765
|
return [cleaned, () => scripts.map(js => window.eval(js))];
|
|
91766
91766
|
};
|
|
91767
91767
|
const HTMLBlock = ({ children = '', html: htmlProp, runScripts, safeMode: safeModeRaw = false }) => {
|
|
91768
|
-
// Determine HTML source: MDXish uses html prop (from HAST), MDX uses children
|
|
91769
|
-
|
|
91770
|
-
|
|
91771
|
-
|
|
91772
|
-
|
|
91773
|
-
|
|
91774
|
-
if (typeof children !== 'string') {
|
|
91775
|
-
throw new TypeError('HTMLBlock: children must be a string');
|
|
91776
|
-
}
|
|
91777
|
-
html = children;
|
|
91778
|
-
}
|
|
91768
|
+
// Determine HTML source: MDXish uses html prop (from HAST), MDX uses children.
|
|
91769
|
+
// A non-string child (no html prop) can't be injected as raw HTML — see the
|
|
91770
|
+
// fail-soft fallback below.
|
|
91771
|
+
const htmlSource = htmlProp !== undefined ? htmlProp : children;
|
|
91772
|
+
const nonStringChildren = typeof htmlSource !== 'string';
|
|
91773
|
+
const html = nonStringChildren ? '' : htmlSource;
|
|
91779
91774
|
// eslint-disable-next-line no-param-reassign
|
|
91780
91775
|
runScripts = typeof runScripts !== 'boolean' ? runScripts === 'true' : runScripts;
|
|
91781
91776
|
// In MDX mode, safeMode is passed in as a boolean from JSX parsing
|
|
@@ -91786,6 +91781,11 @@ const HTMLBlock = ({ children = '', html: htmlProp, runScripts, safeMode: safeMo
|
|
|
91786
91781
|
if (typeof window !== 'undefined' && typeof runScripts === 'boolean' && runScripts)
|
|
91787
91782
|
exec();
|
|
91788
91783
|
}, [runScripts, exec]);
|
|
91784
|
+
if (nonStringChildren) {
|
|
91785
|
+
// Fail soft: a non-string child (e.g. JSX that wasn't serialized back to a
|
|
91786
|
+
// raw string) should never throw, so render the child nodes directly
|
|
91787
|
+
return external_react_default().createElement("div", { className: "rdmd-html" }, children);
|
|
91788
|
+
}
|
|
91789
91789
|
if (safeMode) {
|
|
91790
91790
|
return (external_react_default().createElement("pre", { className: "html-unsafe" },
|
|
91791
91791
|
external_react_default().createElement("code", null, html)));
|
|
@@ -92855,7 +92855,7 @@ function legacyVariableFromMarkdown() {
|
|
|
92855
92855
|
*
|
|
92856
92856
|
* Unicode basic latin block.
|
|
92857
92857
|
*/
|
|
92858
|
-
const
|
|
92858
|
+
const codes = /** @type {const} */ ({
|
|
92859
92859
|
carriageReturn: -5,
|
|
92860
92860
|
lineFeed: -4,
|
|
92861
92861
|
carriageReturnLineFeed: -3,
|
|
@@ -93003,11 +93003,11 @@ const codes_codes = /** @type {const} */ ({
|
|
|
93003
93003
|
function isNameChar(code) {
|
|
93004
93004
|
if (code === null)
|
|
93005
93005
|
return false;
|
|
93006
|
-
return ((code >=
|
|
93007
|
-
(code >=
|
|
93008
|
-
(code >=
|
|
93009
|
-
code ===
|
|
93010
|
-
code ===
|
|
93006
|
+
return ((code >= codes.lowercaseA && code <= codes.lowercaseZ) ||
|
|
93007
|
+
(code >= codes.uppercaseA && code <= codes.uppercaseZ) ||
|
|
93008
|
+
(code >= codes.digit0 && code <= codes.digit9) ||
|
|
93009
|
+
code === codes.dash ||
|
|
93010
|
+
code === codes.underscore);
|
|
93011
93011
|
}
|
|
93012
93012
|
const gemojiConstruct = {
|
|
93013
93013
|
name: 'gemoji',
|
|
@@ -93017,7 +93017,7 @@ function tokenize(effects, ok, nok) {
|
|
|
93017
93017
|
let hasName = false;
|
|
93018
93018
|
// Entry point — expect opening `:`
|
|
93019
93019
|
const start = (code) => {
|
|
93020
|
-
if (code !==
|
|
93020
|
+
if (code !== codes.colon)
|
|
93021
93021
|
return nok(code);
|
|
93022
93022
|
effects.enter('gemoji');
|
|
93023
93023
|
effects.enter('gemojiMarker');
|
|
@@ -93028,7 +93028,7 @@ function tokenize(effects, ok, nok) {
|
|
|
93028
93028
|
};
|
|
93029
93029
|
// First char after `:`, branch on `+` for :+1:, otherwise start normal name
|
|
93030
93030
|
const nameStart = (code) => {
|
|
93031
|
-
if (code ===
|
|
93031
|
+
if (code === codes.plusSign) {
|
|
93032
93032
|
effects.consume(code); // +
|
|
93033
93033
|
return plusOne;
|
|
93034
93034
|
}
|
|
@@ -93043,7 +93043,7 @@ function tokenize(effects, ok, nok) {
|
|
|
93043
93043
|
// After `+`, only `1` is valid (for :+1:), anything else rejects
|
|
93044
93044
|
// this is a special case for :+1: 👍 since + isnt a normal name character
|
|
93045
93045
|
const plusOne = (code) => {
|
|
93046
|
-
if (code ===
|
|
93046
|
+
if (code === codes.digit1) {
|
|
93047
93047
|
hasName = true;
|
|
93048
93048
|
effects.consume(code); // 1
|
|
93049
93049
|
return nameEnd;
|
|
@@ -93052,7 +93052,7 @@ function tokenize(effects, ok, nok) {
|
|
|
93052
93052
|
};
|
|
93053
93053
|
// Consume name characters until we hit closing `:` or an invalid char
|
|
93054
93054
|
const name = (code) => {
|
|
93055
|
-
if (code ===
|
|
93055
|
+
if (code === codes.colon) {
|
|
93056
93056
|
if (!hasName)
|
|
93057
93057
|
return nok(code);
|
|
93058
93058
|
return nameEnd(code);
|
|
@@ -93066,7 +93066,7 @@ function tokenize(effects, ok, nok) {
|
|
|
93066
93066
|
};
|
|
93067
93067
|
// Expect closing `:`
|
|
93068
93068
|
const nameEnd = (code) => {
|
|
93069
|
-
if (code !==
|
|
93069
|
+
if (code !== codes.colon)
|
|
93070
93070
|
return nok(code);
|
|
93071
93071
|
effects.exit('gemojiName');
|
|
93072
93072
|
effects.enter('gemojiMarker');
|
|
@@ -93079,7 +93079,7 @@ function tokenize(effects, ok, nok) {
|
|
|
93079
93079
|
}
|
|
93080
93080
|
function syntax_gemoji() {
|
|
93081
93081
|
return {
|
|
93082
|
-
text: { [
|
|
93082
|
+
text: { [codes.colon]: gemojiConstruct },
|
|
93083
93083
|
};
|
|
93084
93084
|
}
|
|
93085
93085
|
|
|
@@ -93094,8 +93094,8 @@ function syntax_gemoji() {
|
|
|
93094
93094
|
|
|
93095
93095
|
function isAllowedValueChar(code) {
|
|
93096
93096
|
return (code !== null &&
|
|
93097
|
-
code !==
|
|
93098
|
-
code !==
|
|
93097
|
+
code !== codes.lessThan &&
|
|
93098
|
+
code !== codes.greaterThan &&
|
|
93099
93099
|
!markdownLineEnding(code));
|
|
93100
93100
|
}
|
|
93101
93101
|
const legacyVariableConstruct = {
|
|
@@ -93105,7 +93105,7 @@ const legacyVariableConstruct = {
|
|
|
93105
93105
|
function syntax_tokenize(effects, ok, nok) {
|
|
93106
93106
|
let hasValue = false;
|
|
93107
93107
|
const start = (code) => {
|
|
93108
|
-
if (code !==
|
|
93108
|
+
if (code !== codes.lessThan)
|
|
93109
93109
|
return nok(code);
|
|
93110
93110
|
effects.enter('legacyVariable');
|
|
93111
93111
|
effects.enter('legacyVariableMarkerStart');
|
|
@@ -93113,7 +93113,7 @@ function syntax_tokenize(effects, ok, nok) {
|
|
|
93113
93113
|
return open2;
|
|
93114
93114
|
};
|
|
93115
93115
|
const open2 = (code) => {
|
|
93116
|
-
if (code !==
|
|
93116
|
+
if (code !== codes.lessThan)
|
|
93117
93117
|
return nok(code);
|
|
93118
93118
|
effects.consume(code); // <<
|
|
93119
93119
|
effects.exit('legacyVariableMarkerStart');
|
|
@@ -93121,7 +93121,7 @@ function syntax_tokenize(effects, ok, nok) {
|
|
|
93121
93121
|
return value;
|
|
93122
93122
|
};
|
|
93123
93123
|
const value = (code) => {
|
|
93124
|
-
if (code ===
|
|
93124
|
+
if (code === codes.greaterThan) {
|
|
93125
93125
|
if (!hasValue)
|
|
93126
93126
|
return nok(code);
|
|
93127
93127
|
effects.exit('legacyVariableValue');
|
|
@@ -93136,7 +93136,7 @@ function syntax_tokenize(effects, ok, nok) {
|
|
|
93136
93136
|
return value;
|
|
93137
93137
|
};
|
|
93138
93138
|
const close2 = (code) => {
|
|
93139
|
-
if (code !==
|
|
93139
|
+
if (code !== codes.greaterThan)
|
|
93140
93140
|
return nok(code);
|
|
93141
93141
|
effects.consume(code); // >>
|
|
93142
93142
|
effects.exit('legacyVariableMarkerEnd');
|
|
@@ -93147,7 +93147,7 @@ function syntax_tokenize(effects, ok, nok) {
|
|
|
93147
93147
|
}
|
|
93148
93148
|
function legacyVariable() {
|
|
93149
93149
|
return {
|
|
93150
|
-
text: { [
|
|
93150
|
+
text: { [codes.lessThan]: legacyVariableConstruct },
|
|
93151
93151
|
};
|
|
93152
93152
|
}
|
|
93153
93153
|
|
|
@@ -96621,6 +96621,9 @@ const TOP_LEVEL_TABLE_TAG_RE = /^<(?:table|Table)(?=[\s/>])/;
|
|
|
96621
96621
|
* Uses `walkTags` so `<table>`s inside code spans / fenced blocks (masked away)
|
|
96622
96622
|
* are never matched.
|
|
96623
96623
|
*
|
|
96624
|
+
* `<table>`s inside an `<HTMLBlock>` body are also ignored: that body is opaque
|
|
96625
|
+
* raw HTML, so lifting a table out of it would corrupt the block.
|
|
96626
|
+
*
|
|
96624
96627
|
* Note: An implicitly-closed table (no `</table>`, so htmlparser2 synthesizes the
|
|
96625
96628
|
* close at a later tag) is skipped: splitting there would swallow whatever
|
|
96626
96629
|
* followed the table into the fragment and drop it, so we leave such a node
|
|
@@ -96628,21 +96631,35 @@ const TOP_LEVEL_TABLE_TAG_RE = /^<(?:table|Table)(?=[\s/>])/;
|
|
|
96628
96631
|
*/
|
|
96629
96632
|
const findTableRanges = (html) => {
|
|
96630
96633
|
const ranges = [];
|
|
96631
|
-
let
|
|
96634
|
+
let tableDepth = 0;
|
|
96635
|
+
let htmlBlockDepth = 0;
|
|
96632
96636
|
let start = 0;
|
|
96633
96637
|
walkTags(html, {
|
|
96634
|
-
onOpen: ({ name, start: openStart, isStrayCloser }) => {
|
|
96635
|
-
if (
|
|
96638
|
+
onOpen: ({ name, start: openStart, isSelfClosing, isStrayCloser }) => {
|
|
96639
|
+
if (isStrayCloser)
|
|
96636
96640
|
return;
|
|
96637
|
-
|
|
96641
|
+
// `<HTMLBlock/>` has no body to protect; only a real open enters one.
|
|
96642
|
+
if (name === 'HTMLBlock') {
|
|
96643
|
+
if (!isSelfClosing)
|
|
96644
|
+
htmlBlockDepth += 1;
|
|
96645
|
+
return;
|
|
96646
|
+
}
|
|
96647
|
+
if (htmlBlockDepth > 0 || name.toLowerCase() !== 'table')
|
|
96648
|
+
return;
|
|
96649
|
+
if (tableDepth === 0)
|
|
96638
96650
|
start = openStart;
|
|
96639
|
-
|
|
96651
|
+
tableDepth += 1;
|
|
96640
96652
|
},
|
|
96641
96653
|
onClose: ({ name, end, implicit }) => {
|
|
96642
|
-
if (
|
|
96654
|
+
if (name === 'HTMLBlock') {
|
|
96655
|
+
if (!implicit && htmlBlockDepth > 0)
|
|
96656
|
+
htmlBlockDepth -= 1;
|
|
96643
96657
|
return;
|
|
96644
|
-
|
|
96645
|
-
if (
|
|
96658
|
+
}
|
|
96659
|
+
if (implicit || htmlBlockDepth > 0 || name.toLowerCase() !== 'table' || tableDepth === 0)
|
|
96660
|
+
return;
|
|
96661
|
+
tableDepth -= 1;
|
|
96662
|
+
if (tableDepth === 0)
|
|
96646
96663
|
ranges.push({ start, end });
|
|
96647
96664
|
},
|
|
96648
96665
|
});
|
|
@@ -96662,7 +96679,9 @@ const splitHtmlWithNestedTables = (node) => {
|
|
|
96662
96679
|
// This is a top-level table, so we don't need to split it
|
|
96663
96680
|
if (TOP_LEVEL_TABLE_TAG_RE.test(value))
|
|
96664
96681
|
return null;
|
|
96665
|
-
// No table text anywhere
|
|
96682
|
+
// No table text anywhere → skip the htmlparser2 walk entirely. (A `<table>` that
|
|
96683
|
+
// only appears inside an `<HTMLBlock>` body still yields no ranges below, so it's
|
|
96684
|
+
// left whole for `mdxishHtmlBlocks` to convert to an html-block next.)
|
|
96666
96685
|
if (!/<\/?table/i.test(value))
|
|
96667
96686
|
return null;
|
|
96668
96687
|
const ranges = findTableRanges(value);
|
|
@@ -117497,6 +117516,19 @@ const compile_list_item_listItem = (node, parent, state, info) => {
|
|
|
117497
117516
|
const plain_plain = (node) => node.value;
|
|
117498
117517
|
/* harmony default export */ const compile_plain = (plain_plain);
|
|
117499
117518
|
|
|
117519
|
+
;// ./processor/compile/text.ts
|
|
117520
|
+
|
|
117521
|
+
// A `_` flanked by word characters can never open or close emphasis under
|
|
117522
|
+
// CommonMark's flanking rules, so the escape mdast-util-to-markdown adds to
|
|
117523
|
+
// intraword underscores is unnecessary and only produces noisy `\_` diffs.
|
|
117524
|
+
// Uses Unicode letter/number classes so non-ASCII words (e.g. `é_pay`) match.
|
|
117525
|
+
const INTRAWORD_UNDERSCORE_ESCAPE = /(?<=[\p{L}\p{N}_])\\_(?=[\p{L}\p{N}_]|\\_)/gu;
|
|
117526
|
+
const compile_text_text = (node, parent, state, info) => {
|
|
117527
|
+
const serialized = handle.text(node, parent, state, info);
|
|
117528
|
+
return serialized.replace(INTRAWORD_UNDERSCORE_ESCAPE, '_');
|
|
117529
|
+
};
|
|
117530
|
+
/* harmony default export */ const compile_text = (compile_text_text);
|
|
117531
|
+
|
|
117500
117532
|
;// ./processor/compile/index.ts
|
|
117501
117533
|
|
|
117502
117534
|
|
|
@@ -117509,11 +117541,11 @@ const plain_plain = (node) => node.value;
|
|
|
117509
117541
|
|
|
117510
117542
|
|
|
117511
117543
|
|
|
117544
|
+
|
|
117512
117545
|
function compilers(mdxish = false) {
|
|
117513
117546
|
const data = this.data();
|
|
117514
117547
|
const toMarkdownExtensions = data.toMarkdownExtensions || (data.toMarkdownExtensions = []);
|
|
117515
117548
|
const handlers = {
|
|
117516
|
-
...(mdxish && { [enums_NodeTypes.anchor]: compile_anchor }),
|
|
117517
117549
|
[enums_NodeTypes.callout]: compile_callout,
|
|
117518
117550
|
[enums_NodeTypes.codeTabs]: compile_code_tabs,
|
|
117519
117551
|
[enums_NodeTypes.embedBlock]: compile_embed,
|
|
@@ -117521,15 +117553,18 @@ function compilers(mdxish = false) {
|
|
|
117521
117553
|
[enums_NodeTypes.glossary]: compile_compatibility,
|
|
117522
117554
|
[enums_NodeTypes.htmlBlock]: html_block,
|
|
117523
117555
|
[enums_NodeTypes.reusableContent]: compile_compatibility,
|
|
117524
|
-
...(mdxish && { [enums_NodeTypes.variable]: compile_variable }),
|
|
117525
117556
|
embed: compile_compatibility,
|
|
117526
117557
|
escape: compile_compatibility,
|
|
117527
117558
|
figure: compile_compatibility,
|
|
117528
117559
|
html: compile_compatibility,
|
|
117529
117560
|
i: compile_compatibility,
|
|
117530
|
-
...(mdxish && { listItem: list_item }),
|
|
117531
117561
|
plain: compile_plain,
|
|
117532
117562
|
yaml: compile_compatibility,
|
|
117563
|
+
// needed only for mdxish
|
|
117564
|
+
...(mdxish && { [enums_NodeTypes.anchor]: compile_anchor }),
|
|
117565
|
+
...(mdxish && { listItem: list_item }),
|
|
117566
|
+
...(mdxish && { text: compile_text }),
|
|
117567
|
+
...(mdxish && { [enums_NodeTypes.variable]: compile_variable }),
|
|
117533
117568
|
};
|
|
117534
117569
|
toMarkdownExtensions.push({ extensions: [{ handlers }] });
|
|
117535
117570
|
}
|
|
@@ -118388,6 +118423,55 @@ function emptyTaskListItemFromMarkdown() {
|
|
|
118388
118423
|
};
|
|
118389
118424
|
}
|
|
118390
118425
|
|
|
118426
|
+
;// ./lib/mdast-util/jsx-table/index.ts
|
|
118427
|
+
const jsx_table_contextMap = new WeakMap();
|
|
118428
|
+
function findJsxTableToken() {
|
|
118429
|
+
const events = this.tokenStack;
|
|
118430
|
+
for (let i = events.length - 1; i >= 0; i -= 1) {
|
|
118431
|
+
if (events[i][0].type === 'jsxTable')
|
|
118432
|
+
return events[i][0];
|
|
118433
|
+
}
|
|
118434
|
+
return undefined;
|
|
118435
|
+
}
|
|
118436
|
+
function enterJsxTable(token) {
|
|
118437
|
+
jsx_table_contextMap.set(token, { chunks: [], lastEndLine: token.start.line });
|
|
118438
|
+
this.enter({ type: 'html', value: '' }, token);
|
|
118439
|
+
}
|
|
118440
|
+
function exitJsxTableData(token) {
|
|
118441
|
+
const tableToken = findJsxTableToken.call(this);
|
|
118442
|
+
if (!tableToken)
|
|
118443
|
+
return;
|
|
118444
|
+
const ctx = jsx_table_contextMap.get(tableToken);
|
|
118445
|
+
if (ctx) {
|
|
118446
|
+
const gap = token.start.line - ctx.lastEndLine;
|
|
118447
|
+
if (ctx.chunks.length > 0 && gap > 0) {
|
|
118448
|
+
ctx.chunks.push('\n'.repeat(gap));
|
|
118449
|
+
}
|
|
118450
|
+
ctx.chunks.push(this.sliceSerialize(token));
|
|
118451
|
+
ctx.lastEndLine = token.end.line;
|
|
118452
|
+
}
|
|
118453
|
+
}
|
|
118454
|
+
function exitJsxTable(token) {
|
|
118455
|
+
const ctx = jsx_table_contextMap.get(token);
|
|
118456
|
+
const node = this.stack[this.stack.length - 1];
|
|
118457
|
+
if (ctx) {
|
|
118458
|
+
node.value = ctx.chunks.join('');
|
|
118459
|
+
jsx_table_contextMap.delete(token);
|
|
118460
|
+
}
|
|
118461
|
+
this.exit(token);
|
|
118462
|
+
}
|
|
118463
|
+
function jsx_table_jsxTableFromMarkdown() {
|
|
118464
|
+
return {
|
|
118465
|
+
enter: {
|
|
118466
|
+
jsxTable: enterJsxTable,
|
|
118467
|
+
},
|
|
118468
|
+
exit: {
|
|
118469
|
+
jsxTableData: exitJsxTableData,
|
|
118470
|
+
jsxTable: exitJsxTable,
|
|
118471
|
+
},
|
|
118472
|
+
};
|
|
118473
|
+
}
|
|
118474
|
+
|
|
118391
118475
|
;// ./lib/mdast-util/magic-block/index.ts
|
|
118392
118476
|
const magic_block_contextMap = new WeakMap();
|
|
118393
118477
|
/**
|
|
@@ -118577,867 +118661,16 @@ function mdx_component_mdxComponentFromMarkdown() {
|
|
|
118577
118661
|
};
|
|
118578
118662
|
}
|
|
118579
118663
|
|
|
118580
|
-
;// ./
|
|
118581
|
-
|
|
118582
|
-
|
|
118583
|
-
/**
|
|
118584
|
-
* Known magic block types that the tokenizer will recognize.
|
|
118585
|
-
* Unknown types will not be tokenized as magic blocks.
|
|
118586
|
-
*/
|
|
118587
|
-
const KNOWN_BLOCK_TYPES = new Set([
|
|
118588
|
-
'code',
|
|
118589
|
-
'api-header',
|
|
118590
|
-
'image',
|
|
118591
|
-
'callout',
|
|
118592
|
-
'parameters',
|
|
118593
|
-
'table',
|
|
118594
|
-
'embed',
|
|
118595
|
-
'html',
|
|
118596
|
-
'recipe',
|
|
118597
|
-
'tutorial-tile',
|
|
118598
|
-
]);
|
|
118599
|
-
/**
|
|
118600
|
-
* Check if a character is valid for a magic block type identifier.
|
|
118601
|
-
* Types can contain alphanumeric characters and hyphens (e.g., "api-header", "tutorial-tile")
|
|
118602
|
-
*/
|
|
118603
|
-
function isTypeChar(code) {
|
|
118604
|
-
return asciiAlphanumeric(code) || code === codes_codes.dash;
|
|
118605
|
-
}
|
|
118606
|
-
/**
|
|
118607
|
-
* Creates the opening marker state machine: [block:
|
|
118608
|
-
* Returns the first state function to start parsing.
|
|
118609
|
-
*/
|
|
118610
|
-
function createOpeningMarkerParser(effects, nok, onComplete) {
|
|
118611
|
-
const expectB = (code) => {
|
|
118612
|
-
if (code !== codes_codes.lowercaseB)
|
|
118613
|
-
return nok(code);
|
|
118614
|
-
effects.consume(code);
|
|
118615
|
-
return expectL;
|
|
118616
|
-
};
|
|
118617
|
-
const expectL = (code) => {
|
|
118618
|
-
if (code !== codes_codes.lowercaseL)
|
|
118619
|
-
return nok(code);
|
|
118620
|
-
effects.consume(code);
|
|
118621
|
-
return expectO;
|
|
118622
|
-
};
|
|
118623
|
-
const expectO = (code) => {
|
|
118624
|
-
if (code !== codes_codes.lowercaseO)
|
|
118625
|
-
return nok(code);
|
|
118626
|
-
effects.consume(code);
|
|
118627
|
-
return expectC;
|
|
118628
|
-
};
|
|
118629
|
-
const expectC = (code) => {
|
|
118630
|
-
if (code !== codes_codes.lowercaseC)
|
|
118631
|
-
return nok(code);
|
|
118632
|
-
effects.consume(code);
|
|
118633
|
-
return expectK;
|
|
118634
|
-
};
|
|
118635
|
-
const expectK = (code) => {
|
|
118636
|
-
if (code !== codes_codes.lowercaseK)
|
|
118637
|
-
return nok(code);
|
|
118638
|
-
effects.consume(code);
|
|
118639
|
-
return expectColon;
|
|
118640
|
-
};
|
|
118641
|
-
const expectColon = (code) => {
|
|
118642
|
-
if (code !== codes_codes.colon)
|
|
118643
|
-
return nok(code);
|
|
118644
|
-
effects.consume(code);
|
|
118645
|
-
effects.exit('magicBlockMarkerStart');
|
|
118646
|
-
effects.enter('magicBlockType');
|
|
118647
|
-
return onComplete;
|
|
118648
|
-
};
|
|
118649
|
-
return expectB;
|
|
118650
|
-
}
|
|
118651
|
-
/**
|
|
118652
|
-
* Creates the type capture state machine.
|
|
118653
|
-
* Captures type characters until ] and validates against known types.
|
|
118654
|
-
*/
|
|
118655
|
-
function createTypeCaptureParser(effects, nok, onComplete, blockTypeRef) {
|
|
118656
|
-
const captureTypeFirst = (code) => {
|
|
118657
|
-
// Reject empty type name [block:]
|
|
118658
|
-
if (code === codes_codes.rightSquareBracket) {
|
|
118659
|
-
return nok(code);
|
|
118660
|
-
}
|
|
118661
|
-
if (isTypeChar(code)) {
|
|
118662
|
-
blockTypeRef.value += String.fromCharCode(code);
|
|
118663
|
-
effects.consume(code);
|
|
118664
|
-
return captureType;
|
|
118665
|
-
}
|
|
118666
|
-
return nok(code);
|
|
118667
|
-
};
|
|
118668
|
-
const captureType = (code) => {
|
|
118669
|
-
if (code === codes_codes.rightSquareBracket) {
|
|
118670
|
-
if (!KNOWN_BLOCK_TYPES.has(blockTypeRef.value)) {
|
|
118671
|
-
return nok(code);
|
|
118672
|
-
}
|
|
118673
|
-
effects.exit('magicBlockType');
|
|
118674
|
-
effects.enter('magicBlockMarkerTypeEnd');
|
|
118675
|
-
effects.consume(code);
|
|
118676
|
-
effects.exit('magicBlockMarkerTypeEnd');
|
|
118677
|
-
return onComplete;
|
|
118678
|
-
}
|
|
118679
|
-
if (isTypeChar(code)) {
|
|
118680
|
-
blockTypeRef.value += String.fromCharCode(code);
|
|
118681
|
-
effects.consume(code);
|
|
118682
|
-
return captureType;
|
|
118683
|
-
}
|
|
118684
|
-
return nok(code);
|
|
118685
|
-
};
|
|
118686
|
-
return { first: captureTypeFirst, remaining: captureType };
|
|
118687
|
-
}
|
|
118688
|
-
/**
|
|
118689
|
-
* Creates the closing marker state machine: /block]
|
|
118690
|
-
* Handles partial matches by calling onMismatch to fall back to data capture.
|
|
118691
|
-
*/
|
|
118692
|
-
function createClosingMarkerParser(effects, onSuccess, onMismatch, onEof, jsonState) {
|
|
118693
|
-
const handleMismatch = (code) => {
|
|
118694
|
-
if (jsonState && code === codes_codes.quotationMark) {
|
|
118695
|
-
jsonState.inString = true;
|
|
118696
|
-
}
|
|
118697
|
-
return onMismatch(code);
|
|
118698
|
-
};
|
|
118699
|
-
const expectSlash = (code) => {
|
|
118700
|
-
if (code === null)
|
|
118701
|
-
return onEof(code);
|
|
118702
|
-
if (code !== codes_codes.slash)
|
|
118703
|
-
return handleMismatch(code);
|
|
118704
|
-
effects.consume(code);
|
|
118705
|
-
return expectB;
|
|
118706
|
-
};
|
|
118707
|
-
const expectB = (code) => {
|
|
118708
|
-
if (code === null)
|
|
118709
|
-
return onEof(code);
|
|
118710
|
-
if (code !== codes_codes.lowercaseB)
|
|
118711
|
-
return handleMismatch(code);
|
|
118712
|
-
effects.consume(code);
|
|
118713
|
-
return expectL;
|
|
118714
|
-
};
|
|
118715
|
-
const expectL = (code) => {
|
|
118716
|
-
if (code === null)
|
|
118717
|
-
return onEof(code);
|
|
118718
|
-
if (code !== codes_codes.lowercaseL)
|
|
118719
|
-
return handleMismatch(code);
|
|
118720
|
-
effects.consume(code);
|
|
118721
|
-
return expectO;
|
|
118722
|
-
};
|
|
118723
|
-
const expectO = (code) => {
|
|
118724
|
-
if (code === null)
|
|
118725
|
-
return onEof(code);
|
|
118726
|
-
if (code !== codes_codes.lowercaseO)
|
|
118727
|
-
return handleMismatch(code);
|
|
118728
|
-
effects.consume(code);
|
|
118729
|
-
return expectC;
|
|
118730
|
-
};
|
|
118731
|
-
const expectC = (code) => {
|
|
118732
|
-
if (code === null)
|
|
118733
|
-
return onEof(code);
|
|
118734
|
-
if (code !== codes_codes.lowercaseC)
|
|
118735
|
-
return handleMismatch(code);
|
|
118736
|
-
effects.consume(code);
|
|
118737
|
-
return expectK;
|
|
118738
|
-
};
|
|
118739
|
-
const expectK = (code) => {
|
|
118740
|
-
if (code === null)
|
|
118741
|
-
return onEof(code);
|
|
118742
|
-
if (code !== codes_codes.lowercaseK)
|
|
118743
|
-
return handleMismatch(code);
|
|
118744
|
-
effects.consume(code);
|
|
118745
|
-
return expectBracket;
|
|
118746
|
-
};
|
|
118747
|
-
const expectBracket = (code) => {
|
|
118748
|
-
if (code === null)
|
|
118749
|
-
return onEof(code);
|
|
118750
|
-
if (code !== codes_codes.rightSquareBracket)
|
|
118751
|
-
return handleMismatch(code);
|
|
118752
|
-
effects.consume(code);
|
|
118753
|
-
return onSuccess;
|
|
118754
|
-
};
|
|
118755
|
-
return { expectSlash };
|
|
118756
|
-
}
|
|
118757
|
-
/**
|
|
118758
|
-
* Partial construct for checking non-lazy continuation.
|
|
118759
|
-
* This is used by the flow tokenizer to check if we can continue
|
|
118760
|
-
* parsing on the next line.
|
|
118761
|
-
*/
|
|
118762
|
-
const syntax_nonLazyContinuation = {
|
|
118763
|
-
partial: true,
|
|
118764
|
-
tokenize: syntax_tokenizeNonLazyContinuation,
|
|
118765
|
-
};
|
|
118766
|
-
/**
|
|
118767
|
-
* Tokenizer for non-lazy continuation checking.
|
|
118768
|
-
* Returns ok if the next line is non-lazy (can continue), nok if lazy.
|
|
118769
|
-
*/
|
|
118770
|
-
function syntax_tokenizeNonLazyContinuation(effects, ok, nok) {
|
|
118771
|
-
const lineStart = (code) => {
|
|
118772
|
-
// `this` here refers to the micromark parser
|
|
118773
|
-
// since we are just passing functions as references and not actually calling them
|
|
118774
|
-
// micromarks's internal parser will call this automatically with appropriate arguments
|
|
118775
|
-
return this.parser.lazy[this.now().line] ? nok(code) : ok(code);
|
|
118776
|
-
};
|
|
118777
|
-
const start = (code) => {
|
|
118778
|
-
if (code === null) {
|
|
118779
|
-
return nok(code);
|
|
118780
|
-
}
|
|
118781
|
-
if (!markdownLineEnding(code)) {
|
|
118782
|
-
return nok(code);
|
|
118783
|
-
}
|
|
118784
|
-
effects.enter('magicBlockLineEnding');
|
|
118785
|
-
effects.consume(code);
|
|
118786
|
-
effects.exit('magicBlockLineEnding');
|
|
118787
|
-
return lineStart;
|
|
118788
|
-
};
|
|
118789
|
-
return start;
|
|
118790
|
-
}
|
|
118664
|
+
;// ./node_modules/micromark-util-symbol/lib/types.js
|
|
118791
118665
|
/**
|
|
118792
|
-
*
|
|
118793
|
-
*
|
|
118794
|
-
* This extension handles both single-line and multiline magic blocks:
|
|
118795
|
-
* - Flow construct (concrete): Handles block-level multiline magic blocks at document level
|
|
118796
|
-
* - Text construct: Handles inline magic blocks in lists, paragraphs, etc.
|
|
118666
|
+
* This module is compiled away!
|
|
118797
118667
|
*
|
|
118798
|
-
*
|
|
118799
|
-
*
|
|
118800
|
-
|
|
118801
|
-
|
|
118802
|
-
|
|
118803
|
-
|
|
118804
|
-
// Marked as concrete to prevent interruption by containers
|
|
118805
|
-
flow: {
|
|
118806
|
-
[codes_codes.leftSquareBracket]: {
|
|
118807
|
-
name: 'magicBlock',
|
|
118808
|
-
concrete: true,
|
|
118809
|
-
tokenize: tokenizeMagicBlockFlow,
|
|
118810
|
-
},
|
|
118811
|
-
},
|
|
118812
|
-
// Text construct - handles magic blocks in inline contexts (lists, paragraphs)
|
|
118813
|
-
text: {
|
|
118814
|
-
[codes_codes.leftSquareBracket]: {
|
|
118815
|
-
name: 'magicBlock',
|
|
118816
|
-
tokenize: tokenizeMagicBlockText,
|
|
118817
|
-
},
|
|
118818
|
-
},
|
|
118819
|
-
};
|
|
118820
|
-
}
|
|
118821
|
-
/**
|
|
118822
|
-
* Flow tokenizer for block-level magic blocks (multiline).
|
|
118823
|
-
* Uses the continuation checking pattern from code fences.
|
|
118824
|
-
*/
|
|
118825
|
-
function tokenizeMagicBlockFlow(effects, ok, nok) {
|
|
118826
|
-
// State for tracking JSON content
|
|
118827
|
-
const jsonState = { escapeNext: false, inString: false };
|
|
118828
|
-
const blockTypeRef = { value: '' };
|
|
118829
|
-
let seenOpenBrace = false;
|
|
118830
|
-
// Create shared parsers for opening marker and type capture
|
|
118831
|
-
const typeParser = createTypeCaptureParser(effects, nok, beforeData, blockTypeRef);
|
|
118832
|
-
const openingMarkerParser = createOpeningMarkerParser(effects, nok, typeParser.first);
|
|
118833
|
-
return start;
|
|
118834
|
-
function start(code) {
|
|
118835
|
-
if (code !== codes_codes.leftSquareBracket)
|
|
118836
|
-
return nok(code);
|
|
118837
|
-
effects.enter('magicBlock');
|
|
118838
|
-
effects.enter('magicBlockMarkerStart');
|
|
118839
|
-
effects.consume(code);
|
|
118840
|
-
return openingMarkerParser;
|
|
118841
|
-
}
|
|
118842
|
-
/**
|
|
118843
|
-
* State before data content - handles line endings or starts data capture.
|
|
118844
|
-
*/
|
|
118845
|
-
function beforeData(code) {
|
|
118846
|
-
// EOF - magic block must be closed
|
|
118847
|
-
if (code === null) {
|
|
118848
|
-
effects.exit('magicBlock');
|
|
118849
|
-
return nok(code);
|
|
118850
|
-
}
|
|
118851
|
-
// Line ending before any data - check continuation
|
|
118852
|
-
if (markdownLineEnding(code)) {
|
|
118853
|
-
return effects.check(syntax_nonLazyContinuation, continuationOkBeforeData, after)(code);
|
|
118854
|
-
}
|
|
118855
|
-
// Check for closing marker directly (without entering data)
|
|
118856
|
-
// This handles cases like [block:type]\n{}\n\n[/block] where there are
|
|
118857
|
-
// newlines after the data object
|
|
118858
|
-
if (code === codes_codes.leftSquareBracket) {
|
|
118859
|
-
effects.enter('magicBlockMarkerEnd');
|
|
118860
|
-
effects.consume(code);
|
|
118861
|
-
return expectSlashFromContinuation;
|
|
118862
|
-
}
|
|
118863
|
-
// If we've already seen the opening brace, just continue capturing data
|
|
118864
|
-
if (seenOpenBrace) {
|
|
118865
|
-
effects.enter('magicBlockData');
|
|
118866
|
-
return captureData(code);
|
|
118867
|
-
}
|
|
118868
|
-
// Skip whitespace (spaces/tabs) before the data - stay in beforeData
|
|
118869
|
-
// Don't enter magicBlockData token yet until we confirm there's a '{'
|
|
118870
|
-
if (code === codes_codes.space || code === codes_codes.horizontalTab) {
|
|
118871
|
-
return beforeDataWhitespace(code);
|
|
118872
|
-
}
|
|
118873
|
-
// Data must start with '{' for valid JSON
|
|
118874
|
-
if (code !== codes_codes.leftCurlyBrace) {
|
|
118875
|
-
effects.exit('magicBlock');
|
|
118876
|
-
return nok(code);
|
|
118877
|
-
}
|
|
118878
|
-
// We have '{' - enter data token and start capturing
|
|
118879
|
-
seenOpenBrace = true;
|
|
118880
|
-
effects.enter('magicBlockData');
|
|
118881
|
-
return captureData(code);
|
|
118882
|
-
}
|
|
118883
|
-
/**
|
|
118884
|
-
* Consume whitespace before the data without creating a token.
|
|
118885
|
-
* Uses a temporary token to satisfy micromark's requirement.
|
|
118886
|
-
*/
|
|
118887
|
-
function beforeDataWhitespace(code) {
|
|
118888
|
-
if (code === null) {
|
|
118889
|
-
effects.exit('magicBlock');
|
|
118890
|
-
return nok(code);
|
|
118891
|
-
}
|
|
118892
|
-
if (markdownLineEnding(code)) {
|
|
118893
|
-
return effects.check(syntax_nonLazyContinuation, continuationOkBeforeData, after)(code);
|
|
118894
|
-
}
|
|
118895
|
-
if (code === codes_codes.space || code === codes_codes.horizontalTab) {
|
|
118896
|
-
// We need to consume this but can't without a token - use magicBlockData
|
|
118897
|
-
// and track that we haven't seen '{' yet
|
|
118898
|
-
effects.enter('magicBlockData');
|
|
118899
|
-
effects.consume(code);
|
|
118900
|
-
return beforeDataWhitespaceContinue;
|
|
118901
|
-
}
|
|
118902
|
-
if (code === codes_codes.leftCurlyBrace) {
|
|
118903
|
-
seenOpenBrace = true;
|
|
118904
|
-
effects.enter('magicBlockData');
|
|
118905
|
-
return captureData(code);
|
|
118906
|
-
}
|
|
118907
|
-
effects.exit('magicBlock');
|
|
118908
|
-
return nok(code);
|
|
118909
|
-
}
|
|
118910
|
-
/**
|
|
118911
|
-
* Continue consuming whitespace or validate the opening brace.
|
|
118912
|
-
*/
|
|
118913
|
-
function beforeDataWhitespaceContinue(code) {
|
|
118914
|
-
if (code === null) {
|
|
118915
|
-
effects.exit('magicBlockData');
|
|
118916
|
-
effects.exit('magicBlock');
|
|
118917
|
-
return nok(code);
|
|
118918
|
-
}
|
|
118919
|
-
if (markdownLineEnding(code)) {
|
|
118920
|
-
effects.exit('magicBlockData');
|
|
118921
|
-
return effects.check(syntax_nonLazyContinuation, continuationOk, after)(code);
|
|
118922
|
-
}
|
|
118923
|
-
if (code === codes_codes.space || code === codes_codes.horizontalTab) {
|
|
118924
|
-
effects.consume(code);
|
|
118925
|
-
return beforeDataWhitespaceContinue;
|
|
118926
|
-
}
|
|
118927
|
-
if (code === codes_codes.leftCurlyBrace) {
|
|
118928
|
-
seenOpenBrace = true;
|
|
118929
|
-
return captureData(code);
|
|
118930
|
-
}
|
|
118931
|
-
effects.exit('magicBlockData');
|
|
118932
|
-
effects.exit('magicBlock');
|
|
118933
|
-
return nok(code);
|
|
118934
|
-
}
|
|
118935
|
-
/**
|
|
118936
|
-
* Continuation OK before we've entered data token.
|
|
118937
|
-
*/
|
|
118938
|
-
function continuationOkBeforeData(code) {
|
|
118939
|
-
effects.enter('magicBlockLineEnding');
|
|
118940
|
-
effects.consume(code);
|
|
118941
|
-
effects.exit('magicBlockLineEnding');
|
|
118942
|
-
return beforeData; // Stay in beforeData state - don't enter magicBlockData yet
|
|
118943
|
-
}
|
|
118944
|
-
function captureData(code) {
|
|
118945
|
-
// EOF - magic block must be closed
|
|
118946
|
-
if (code === null) {
|
|
118947
|
-
effects.exit('magicBlockData');
|
|
118948
|
-
effects.exit('magicBlock');
|
|
118949
|
-
return nok(code);
|
|
118950
|
-
}
|
|
118951
|
-
// At line ending, check if we can continue on the next line
|
|
118952
|
-
if (markdownLineEnding(code)) {
|
|
118953
|
-
effects.exit('magicBlockData');
|
|
118954
|
-
return effects.check(syntax_nonLazyContinuation, continuationOk, after)(code);
|
|
118955
|
-
}
|
|
118956
|
-
if (jsonState.escapeNext) {
|
|
118957
|
-
jsonState.escapeNext = false;
|
|
118958
|
-
effects.consume(code);
|
|
118959
|
-
return captureData;
|
|
118960
|
-
}
|
|
118961
|
-
if (jsonState.inString) {
|
|
118962
|
-
if (code === codes_codes.backslash) {
|
|
118963
|
-
jsonState.escapeNext = true;
|
|
118964
|
-
effects.consume(code);
|
|
118965
|
-
return captureData;
|
|
118966
|
-
}
|
|
118967
|
-
if (code === codes_codes.quotationMark) {
|
|
118968
|
-
jsonState.inString = false;
|
|
118969
|
-
}
|
|
118970
|
-
effects.consume(code);
|
|
118971
|
-
return captureData;
|
|
118972
|
-
}
|
|
118973
|
-
if (code === codes_codes.quotationMark) {
|
|
118974
|
-
jsonState.inString = true;
|
|
118975
|
-
effects.consume(code);
|
|
118976
|
-
return captureData;
|
|
118977
|
-
}
|
|
118978
|
-
if (code === codes_codes.leftSquareBracket) {
|
|
118979
|
-
effects.exit('magicBlockData');
|
|
118980
|
-
effects.enter('magicBlockMarkerEnd');
|
|
118981
|
-
effects.consume(code);
|
|
118982
|
-
return expectSlash;
|
|
118983
|
-
}
|
|
118984
|
-
effects.consume(code);
|
|
118985
|
-
return captureData;
|
|
118986
|
-
}
|
|
118987
|
-
/**
|
|
118988
|
-
* Called when non-lazy continuation check passes - we can continue parsing.
|
|
118989
|
-
*/
|
|
118990
|
-
function continuationOk(code) {
|
|
118991
|
-
// Consume the line ending
|
|
118992
|
-
effects.enter('magicBlockLineEnding');
|
|
118993
|
-
effects.consume(code);
|
|
118994
|
-
effects.exit('magicBlockLineEnding');
|
|
118995
|
-
return continuationStart;
|
|
118996
|
-
}
|
|
118997
|
-
/**
|
|
118998
|
-
* Start of continuation line - check for more line endings, closing marker, or start capturing data.
|
|
118999
|
-
*/
|
|
119000
|
-
function continuationStart(code) {
|
|
119001
|
-
// Handle consecutive line endings
|
|
119002
|
-
if (code === null) {
|
|
119003
|
-
effects.exit('magicBlock');
|
|
119004
|
-
return nok(code);
|
|
119005
|
-
}
|
|
119006
|
-
if (markdownLineEnding(code)) {
|
|
119007
|
-
return effects.check(syntax_nonLazyContinuation, continuationOkBeforeData, after)(code);
|
|
119008
|
-
}
|
|
119009
|
-
// Check if this is the start of the closing marker [/block]
|
|
119010
|
-
// If so, handle it directly without entering magicBlockData
|
|
119011
|
-
if (code === codes_codes.leftSquareBracket) {
|
|
119012
|
-
effects.enter('magicBlockMarkerEnd');
|
|
119013
|
-
effects.consume(code);
|
|
119014
|
-
return expectSlashFromContinuation;
|
|
119015
|
-
}
|
|
119016
|
-
effects.enter('magicBlockData');
|
|
119017
|
-
return captureData(code);
|
|
119018
|
-
}
|
|
119019
|
-
/**
|
|
119020
|
-
* Check for closing marker slash when coming from continuation.
|
|
119021
|
-
* If not a closing marker, create an empty data token and continue.
|
|
119022
|
-
*/
|
|
119023
|
-
function expectSlashFromContinuation(code) {
|
|
119024
|
-
if (code === null) {
|
|
119025
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119026
|
-
effects.exit('magicBlock');
|
|
119027
|
-
return nok(code);
|
|
119028
|
-
}
|
|
119029
|
-
if (markdownLineEnding(code)) {
|
|
119030
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119031
|
-
return effects.check(syntax_nonLazyContinuation, continuationOkBeforeData, after)(code);
|
|
119032
|
-
}
|
|
119033
|
-
if (code === codes_codes.slash) {
|
|
119034
|
-
effects.consume(code);
|
|
119035
|
-
return expectClosingB;
|
|
119036
|
-
}
|
|
119037
|
-
// Not a closing marker - this is data content
|
|
119038
|
-
// Exit marker and enter data
|
|
119039
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119040
|
-
effects.enter('magicBlockData');
|
|
119041
|
-
// The [ was consumed by the marker, so we need to conceptually "have it" in our data
|
|
119042
|
-
// But since we already consumed it into the marker, we need a different approach
|
|
119043
|
-
// Re-classify: consume this character as data and continue
|
|
119044
|
-
if (code === codes_codes.quotationMark)
|
|
119045
|
-
jsonState.inString = true;
|
|
119046
|
-
effects.consume(code);
|
|
119047
|
-
return captureData;
|
|
119048
|
-
}
|
|
119049
|
-
function expectSlash(code) {
|
|
119050
|
-
if (code === null) {
|
|
119051
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119052
|
-
effects.exit('magicBlock');
|
|
119053
|
-
return nok(code);
|
|
119054
|
-
}
|
|
119055
|
-
// At line ending during marker parsing
|
|
119056
|
-
if (markdownLineEnding(code)) {
|
|
119057
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119058
|
-
return effects.check(syntax_nonLazyContinuation, continuationOk, after)(code);
|
|
119059
|
-
}
|
|
119060
|
-
if (code !== codes_codes.slash) {
|
|
119061
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119062
|
-
effects.enter('magicBlockData');
|
|
119063
|
-
if (code === codes_codes.quotationMark)
|
|
119064
|
-
jsonState.inString = true;
|
|
119065
|
-
effects.consume(code);
|
|
119066
|
-
return captureData;
|
|
119067
|
-
}
|
|
119068
|
-
effects.consume(code);
|
|
119069
|
-
return expectClosingB;
|
|
119070
|
-
}
|
|
119071
|
-
function expectClosingB(code) {
|
|
119072
|
-
if (code === null) {
|
|
119073
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119074
|
-
effects.exit('magicBlock');
|
|
119075
|
-
return nok(code);
|
|
119076
|
-
}
|
|
119077
|
-
if (code !== codes_codes.lowercaseB) {
|
|
119078
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119079
|
-
effects.enter('magicBlockData');
|
|
119080
|
-
if (code === codes_codes.quotationMark)
|
|
119081
|
-
jsonState.inString = true;
|
|
119082
|
-
effects.consume(code);
|
|
119083
|
-
return captureData;
|
|
119084
|
-
}
|
|
119085
|
-
effects.consume(code);
|
|
119086
|
-
return expectClosingL;
|
|
119087
|
-
}
|
|
119088
|
-
function expectClosingL(code) {
|
|
119089
|
-
if (code === null) {
|
|
119090
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119091
|
-
effects.exit('magicBlock');
|
|
119092
|
-
return nok(code);
|
|
119093
|
-
}
|
|
119094
|
-
if (code !== codes_codes.lowercaseL) {
|
|
119095
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119096
|
-
effects.enter('magicBlockData');
|
|
119097
|
-
if (code === codes_codes.quotationMark)
|
|
119098
|
-
jsonState.inString = true;
|
|
119099
|
-
effects.consume(code);
|
|
119100
|
-
return captureData;
|
|
119101
|
-
}
|
|
119102
|
-
effects.consume(code);
|
|
119103
|
-
return expectClosingO;
|
|
119104
|
-
}
|
|
119105
|
-
function expectClosingO(code) {
|
|
119106
|
-
if (code === null) {
|
|
119107
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119108
|
-
effects.exit('magicBlock');
|
|
119109
|
-
return nok(code);
|
|
119110
|
-
}
|
|
119111
|
-
if (code !== codes_codes.lowercaseO) {
|
|
119112
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119113
|
-
effects.enter('magicBlockData');
|
|
119114
|
-
if (code === codes_codes.quotationMark)
|
|
119115
|
-
jsonState.inString = true;
|
|
119116
|
-
effects.consume(code);
|
|
119117
|
-
return captureData;
|
|
119118
|
-
}
|
|
119119
|
-
effects.consume(code);
|
|
119120
|
-
return expectClosingC;
|
|
119121
|
-
}
|
|
119122
|
-
function expectClosingC(code) {
|
|
119123
|
-
if (code === null) {
|
|
119124
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119125
|
-
effects.exit('magicBlock');
|
|
119126
|
-
return nok(code);
|
|
119127
|
-
}
|
|
119128
|
-
if (code !== codes_codes.lowercaseC) {
|
|
119129
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119130
|
-
effects.enter('magicBlockData');
|
|
119131
|
-
if (code === codes_codes.quotationMark)
|
|
119132
|
-
jsonState.inString = true;
|
|
119133
|
-
effects.consume(code);
|
|
119134
|
-
return captureData;
|
|
119135
|
-
}
|
|
119136
|
-
effects.consume(code);
|
|
119137
|
-
return expectClosingK;
|
|
119138
|
-
}
|
|
119139
|
-
function expectClosingK(code) {
|
|
119140
|
-
if (code === null) {
|
|
119141
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119142
|
-
effects.exit('magicBlock');
|
|
119143
|
-
return nok(code);
|
|
119144
|
-
}
|
|
119145
|
-
if (code !== codes_codes.lowercaseK) {
|
|
119146
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119147
|
-
effects.enter('magicBlockData');
|
|
119148
|
-
if (code === codes_codes.quotationMark)
|
|
119149
|
-
jsonState.inString = true;
|
|
119150
|
-
effects.consume(code);
|
|
119151
|
-
return captureData;
|
|
119152
|
-
}
|
|
119153
|
-
effects.consume(code);
|
|
119154
|
-
return expectClosingBracket;
|
|
119155
|
-
}
|
|
119156
|
-
function expectClosingBracket(code) {
|
|
119157
|
-
if (code === null) {
|
|
119158
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119159
|
-
effects.exit('magicBlock');
|
|
119160
|
-
return nok(code);
|
|
119161
|
-
}
|
|
119162
|
-
if (code !== codes_codes.rightSquareBracket) {
|
|
119163
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119164
|
-
effects.enter('magicBlockData');
|
|
119165
|
-
if (code === codes_codes.quotationMark)
|
|
119166
|
-
jsonState.inString = true;
|
|
119167
|
-
effects.consume(code);
|
|
119168
|
-
return captureData;
|
|
119169
|
-
}
|
|
119170
|
-
effects.consume(code);
|
|
119171
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119172
|
-
// Check for trailing whitespace on the same line
|
|
119173
|
-
return consumeTrailing;
|
|
119174
|
-
}
|
|
119175
|
-
/**
|
|
119176
|
-
* Consume trailing whitespace (spaces/tabs) on the same line after [/block].
|
|
119177
|
-
* For concrete flow constructs, we must end at eol/eof or fail.
|
|
119178
|
-
* Trailing whitespace is consumed; other content causes nok (text tokenizer handles it).
|
|
119179
|
-
*/
|
|
119180
|
-
function consumeTrailing(code) {
|
|
119181
|
-
// End of file - done
|
|
119182
|
-
if (code === null) {
|
|
119183
|
-
effects.exit('magicBlock');
|
|
119184
|
-
return ok(code);
|
|
119185
|
-
}
|
|
119186
|
-
// Line ending - done
|
|
119187
|
-
if (markdownLineEnding(code)) {
|
|
119188
|
-
effects.exit('magicBlock');
|
|
119189
|
-
return ok(code);
|
|
119190
|
-
}
|
|
119191
|
-
// Space or tab - consume as trailing whitespace
|
|
119192
|
-
if (code === codes_codes.space || code === codes_codes.horizontalTab) {
|
|
119193
|
-
effects.enter('magicBlockTrailing');
|
|
119194
|
-
effects.consume(code);
|
|
119195
|
-
return consumeTrailingContinue;
|
|
119196
|
-
}
|
|
119197
|
-
// Any other character - fail flow tokenizer, let text tokenizer handle it
|
|
119198
|
-
effects.exit('magicBlock');
|
|
119199
|
-
return nok(code);
|
|
119200
|
-
}
|
|
119201
|
-
/**
|
|
119202
|
-
* Continue consuming trailing whitespace.
|
|
119203
|
-
*/
|
|
119204
|
-
function consumeTrailingContinue(code) {
|
|
119205
|
-
// End of file - done
|
|
119206
|
-
if (code === null) {
|
|
119207
|
-
effects.exit('magicBlockTrailing');
|
|
119208
|
-
effects.exit('magicBlock');
|
|
119209
|
-
return ok(code);
|
|
119210
|
-
}
|
|
119211
|
-
// Line ending - done
|
|
119212
|
-
if (markdownLineEnding(code)) {
|
|
119213
|
-
effects.exit('magicBlockTrailing');
|
|
119214
|
-
effects.exit('magicBlock');
|
|
119215
|
-
return ok(code);
|
|
119216
|
-
}
|
|
119217
|
-
// More space or tab - keep consuming
|
|
119218
|
-
if (code === codes_codes.space || code === codes_codes.horizontalTab) {
|
|
119219
|
-
effects.consume(code);
|
|
119220
|
-
return consumeTrailingContinue;
|
|
119221
|
-
}
|
|
119222
|
-
// Non-whitespace after whitespace - fail flow tokenizer
|
|
119223
|
-
effects.exit('magicBlockTrailing');
|
|
119224
|
-
effects.exit('magicBlock');
|
|
119225
|
-
return nok(code);
|
|
119226
|
-
}
|
|
119227
|
-
/**
|
|
119228
|
-
* Called when we can't continue (lazy line or EOF) - exit the construct.
|
|
119229
|
-
*/
|
|
119230
|
-
function after(code) {
|
|
119231
|
-
effects.exit('magicBlock');
|
|
119232
|
-
return nok(code);
|
|
119233
|
-
}
|
|
119234
|
-
}
|
|
119235
|
-
/**
|
|
119236
|
-
* Text tokenizer for single-line magic blocks only.
|
|
119237
|
-
* Used in inline contexts like list items and paragraphs.
|
|
119238
|
-
* Multiline blocks are handled by the flow tokenizer.
|
|
119239
|
-
*/
|
|
119240
|
-
function tokenizeMagicBlockText(effects, ok, nok) {
|
|
119241
|
-
// State for tracking JSON content
|
|
119242
|
-
const jsonState = { escapeNext: false, inString: false };
|
|
119243
|
-
const blockTypeRef = { value: '' };
|
|
119244
|
-
let seenOpenBrace = false;
|
|
119245
|
-
// Create shared parsers for opening marker and type capture
|
|
119246
|
-
const typeParser = createTypeCaptureParser(effects, nok, beforeData, blockTypeRef);
|
|
119247
|
-
const openingMarkerParser = createOpeningMarkerParser(effects, nok, typeParser.first);
|
|
119248
|
-
// Success handler for closing marker - exits tokens and returns ok
|
|
119249
|
-
const closingSuccess = (code) => {
|
|
119250
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119251
|
-
effects.exit('magicBlock');
|
|
119252
|
-
return ok(code);
|
|
119253
|
-
};
|
|
119254
|
-
// Mismatch handler - falls back to data capture
|
|
119255
|
-
const closingMismatch = (code) => {
|
|
119256
|
-
effects.exit('magicBlockMarkerEnd');
|
|
119257
|
-
effects.enter('magicBlockData');
|
|
119258
|
-
if (code === codes_codes.quotationMark)
|
|
119259
|
-
jsonState.inString = true;
|
|
119260
|
-
effects.consume(code);
|
|
119261
|
-
return captureData;
|
|
119262
|
-
};
|
|
119263
|
-
// EOF handler
|
|
119264
|
-
const closingEof = (_code) => nok(_code);
|
|
119265
|
-
// Create closing marker parsers
|
|
119266
|
-
const closingFromBeforeData = createClosingMarkerParser(effects, closingSuccess, closingMismatch, closingEof, jsonState);
|
|
119267
|
-
const closingFromData = createClosingMarkerParser(effects, closingSuccess, closingMismatch, closingEof, jsonState);
|
|
119268
|
-
return start;
|
|
119269
|
-
function start(code) {
|
|
119270
|
-
if (code !== codes_codes.leftSquareBracket)
|
|
119271
|
-
return nok(code);
|
|
119272
|
-
effects.enter('magicBlock');
|
|
119273
|
-
effects.enter('magicBlockMarkerStart');
|
|
119274
|
-
effects.consume(code);
|
|
119275
|
-
return openingMarkerParser;
|
|
119276
|
-
}
|
|
119277
|
-
/**
|
|
119278
|
-
* State before data content - handles line endings before entering data token.
|
|
119279
|
-
* Whitespace before '{' is allowed.
|
|
119280
|
-
*/
|
|
119281
|
-
function beforeData(code) {
|
|
119282
|
-
// Fail on EOF - magic block must be closed
|
|
119283
|
-
if (code === null) {
|
|
119284
|
-
return nok(code);
|
|
119285
|
-
}
|
|
119286
|
-
// Handle line endings before any data - consume them without entering data token
|
|
119287
|
-
if (markdownLineEnding(code)) {
|
|
119288
|
-
effects.enter('magicBlockLineEnding');
|
|
119289
|
-
effects.consume(code);
|
|
119290
|
-
effects.exit('magicBlockLineEnding');
|
|
119291
|
-
return beforeData;
|
|
119292
|
-
}
|
|
119293
|
-
// Check for closing marker directly (without entering data)
|
|
119294
|
-
if (code === codes_codes.leftSquareBracket) {
|
|
119295
|
-
effects.enter('magicBlockMarkerEnd');
|
|
119296
|
-
effects.consume(code);
|
|
119297
|
-
return closingFromBeforeData.expectSlash;
|
|
119298
|
-
}
|
|
119299
|
-
// If we've already seen the opening brace, just continue capturing data
|
|
119300
|
-
if (seenOpenBrace) {
|
|
119301
|
-
effects.enter('magicBlockData');
|
|
119302
|
-
return captureData(code);
|
|
119303
|
-
}
|
|
119304
|
-
// Skip whitespace (spaces/tabs) before the data
|
|
119305
|
-
if (code === codes_codes.space || code === codes_codes.horizontalTab) {
|
|
119306
|
-
return beforeDataWhitespace(code);
|
|
119307
|
-
}
|
|
119308
|
-
// Data must start with '{' for valid JSON
|
|
119309
|
-
if (code !== codes_codes.leftCurlyBrace) {
|
|
119310
|
-
return nok(code);
|
|
119311
|
-
}
|
|
119312
|
-
// We have '{' - enter data token and start capturing
|
|
119313
|
-
seenOpenBrace = true;
|
|
119314
|
-
effects.enter('magicBlockData');
|
|
119315
|
-
return captureData(code);
|
|
119316
|
-
}
|
|
119317
|
-
/**
|
|
119318
|
-
* Consume whitespace before the data.
|
|
119319
|
-
*/
|
|
119320
|
-
function beforeDataWhitespace(code) {
|
|
119321
|
-
if (code === null) {
|
|
119322
|
-
return nok(code);
|
|
119323
|
-
}
|
|
119324
|
-
if (markdownLineEnding(code)) {
|
|
119325
|
-
effects.enter('magicBlockLineEnding');
|
|
119326
|
-
effects.consume(code);
|
|
119327
|
-
effects.exit('magicBlockLineEnding');
|
|
119328
|
-
return beforeData;
|
|
119329
|
-
}
|
|
119330
|
-
if (code === codes_codes.space || code === codes_codes.horizontalTab) {
|
|
119331
|
-
effects.enter('magicBlockData');
|
|
119332
|
-
effects.consume(code);
|
|
119333
|
-
return beforeDataWhitespaceContinue;
|
|
119334
|
-
}
|
|
119335
|
-
if (code === codes_codes.leftCurlyBrace) {
|
|
119336
|
-
seenOpenBrace = true;
|
|
119337
|
-
effects.enter('magicBlockData');
|
|
119338
|
-
return captureData(code);
|
|
119339
|
-
}
|
|
119340
|
-
return nok(code);
|
|
119341
|
-
}
|
|
119342
|
-
/**
|
|
119343
|
-
* Continue consuming whitespace or validate the opening brace.
|
|
119344
|
-
*/
|
|
119345
|
-
function beforeDataWhitespaceContinue(code) {
|
|
119346
|
-
if (code === null) {
|
|
119347
|
-
effects.exit('magicBlockData');
|
|
119348
|
-
return nok(code);
|
|
119349
|
-
}
|
|
119350
|
-
if (markdownLineEnding(code)) {
|
|
119351
|
-
effects.exit('magicBlockData');
|
|
119352
|
-
effects.enter('magicBlockLineEnding');
|
|
119353
|
-
effects.consume(code);
|
|
119354
|
-
effects.exit('magicBlockLineEnding');
|
|
119355
|
-
return beforeData;
|
|
119356
|
-
}
|
|
119357
|
-
if (code === codes_codes.space || code === codes_codes.horizontalTab) {
|
|
119358
|
-
effects.consume(code);
|
|
119359
|
-
return beforeDataWhitespaceContinue;
|
|
119360
|
-
}
|
|
119361
|
-
if (code === codes_codes.leftCurlyBrace) {
|
|
119362
|
-
seenOpenBrace = true;
|
|
119363
|
-
return captureData(code);
|
|
119364
|
-
}
|
|
119365
|
-
effects.exit('magicBlockData');
|
|
119366
|
-
return nok(code);
|
|
119367
|
-
}
|
|
119368
|
-
function captureData(code) {
|
|
119369
|
-
// Fail on EOF - magic block must be closed
|
|
119370
|
-
if (code === null) {
|
|
119371
|
-
effects.exit('magicBlockData');
|
|
119372
|
-
return nok(code);
|
|
119373
|
-
}
|
|
119374
|
-
// Handle multiline magic blocks within text/paragraphs
|
|
119375
|
-
// Exit data, consume line ending with proper token, then re-enter data
|
|
119376
|
-
if (markdownLineEnding(code)) {
|
|
119377
|
-
effects.exit('magicBlockData');
|
|
119378
|
-
effects.enter('magicBlockLineEnding');
|
|
119379
|
-
effects.consume(code);
|
|
119380
|
-
effects.exit('magicBlockLineEnding');
|
|
119381
|
-
return beforeData; // Go back to beforeData to handle potential empty lines
|
|
119382
|
-
}
|
|
119383
|
-
if (jsonState.escapeNext) {
|
|
119384
|
-
jsonState.escapeNext = false;
|
|
119385
|
-
effects.consume(code);
|
|
119386
|
-
return captureData;
|
|
119387
|
-
}
|
|
119388
|
-
if (jsonState.inString) {
|
|
119389
|
-
if (code === codes_codes.backslash) {
|
|
119390
|
-
jsonState.escapeNext = true;
|
|
119391
|
-
effects.consume(code);
|
|
119392
|
-
return captureData;
|
|
119393
|
-
}
|
|
119394
|
-
if (code === codes_codes.quotationMark) {
|
|
119395
|
-
jsonState.inString = false;
|
|
119396
|
-
}
|
|
119397
|
-
effects.consume(code);
|
|
119398
|
-
return captureData;
|
|
119399
|
-
}
|
|
119400
|
-
if (code === codes_codes.quotationMark) {
|
|
119401
|
-
jsonState.inString = true;
|
|
119402
|
-
effects.consume(code);
|
|
119403
|
-
return captureData;
|
|
119404
|
-
}
|
|
119405
|
-
if (code === codes_codes.leftSquareBracket) {
|
|
119406
|
-
effects.exit('magicBlockData');
|
|
119407
|
-
effects.enter('magicBlockMarkerEnd');
|
|
119408
|
-
effects.consume(code);
|
|
119409
|
-
return closingFromData.expectSlash;
|
|
119410
|
-
}
|
|
119411
|
-
effects.consume(code);
|
|
119412
|
-
return captureData;
|
|
119413
|
-
}
|
|
119414
|
-
}
|
|
119415
|
-
/* harmony default export */ const syntax = ((/* unused pure expression or super */ null && (syntax_magicBlock)));
|
|
119416
|
-
|
|
119417
|
-
;// ./lib/micromark/magic-block/index.ts
|
|
119418
|
-
/**
|
|
119419
|
-
* Micromark extension for magic block syntax.
|
|
119420
|
-
*
|
|
119421
|
-
* Usage:
|
|
119422
|
-
* ```ts
|
|
119423
|
-
* import { magicBlock } from './lib/micromark/magic-block';
|
|
119424
|
-
*
|
|
119425
|
-
* const processor = unified()
|
|
119426
|
-
* .data('micromarkExtensions', [magicBlock()])
|
|
119427
|
-
* ```
|
|
119428
|
-
*/
|
|
119429
|
-
|
|
119430
|
-
|
|
119431
|
-
;// ./node_modules/micromark-util-symbol/lib/types.js
|
|
119432
|
-
/**
|
|
119433
|
-
* This module is compiled away!
|
|
119434
|
-
*
|
|
119435
|
-
* Here is the list of all types of tokens exposed by micromark, with a short
|
|
119436
|
-
* explanation of what they include and where they are found.
|
|
119437
|
-
* In picking names, generally, the rule is to be as explicit as possible
|
|
119438
|
-
* instead of reusing names.
|
|
119439
|
-
* For example, there is a `definitionDestination` and a `resourceDestination`,
|
|
119440
|
-
* instead of one shared name.
|
|
118668
|
+
* Here is the list of all types of tokens exposed by micromark, with a short
|
|
118669
|
+
* explanation of what they include and where they are found.
|
|
118670
|
+
* In picking names, generally, the rule is to be as explicit as possible
|
|
118671
|
+
* instead of reusing names.
|
|
118672
|
+
* For example, there is a `definitionDestination` and a `resourceDestination`,
|
|
118673
|
+
* instead of one shared name.
|
|
119441
118674
|
*/
|
|
119442
118675
|
|
|
119443
118676
|
// Note: when changing the next record, you must also change `TokenTypeMap`
|
|
@@ -119883,36 +119116,18 @@ const types_types = /** @type {const} */ ({
|
|
|
119883
119116
|
chunkString: 'chunkString'
|
|
119884
119117
|
})
|
|
119885
119118
|
|
|
119886
|
-
;// ./lib/micromark/
|
|
119887
|
-
|
|
119888
|
-
|
|
119889
|
-
|
|
119119
|
+
;// ./lib/micromark/jsx-table/syntax.ts
|
|
119890
119120
|
|
|
119891
119121
|
|
|
119892
|
-
// Raw tags (type-1: pre/script/style/textarea) and block tags (type-6: div,
|
|
119893
|
-
// section, …) always start a block, so they stay flow even with trailing
|
|
119894
|
-
// content. Other lowercase tags (i, span, …) follow the type-7 rule and only
|
|
119895
|
-
// stay flow when nothing trails the close tag.
|
|
119896
|
-
const htmlFlowTagNames = new Set([...htmlRawNames, ...htmlBlockNames]);
|
|
119897
|
-
// Lowercase type-6 block tags claimable in flow even without a `{…}` attribute, so
|
|
119898
|
-
// blank lines between nested JSX siblings don't fragment the block. Excludes table
|
|
119899
|
-
// tags (mdxishTables owns their blank lines) and voids (never close).
|
|
119900
|
-
const plainBlockClaimTagNames = new Set([...htmlBlockNames].filter(tag => !HTML_TABLE_STRUCTURE_TAGS.has(tag) && !HTML_VOID_ELEMENTS.has(tag)));
|
|
119901
119122
|
const syntax_nonLazyContinuationStart = {
|
|
119902
119123
|
tokenize: syntax_tokenizeNonLazyContinuationStart,
|
|
119903
119124
|
partial: true,
|
|
119904
119125
|
};
|
|
119905
|
-
|
|
119906
|
-
// that merely starts with a tag? Run via `effects.check` so it never consumes.
|
|
119907
|
-
const markupOnlyContinuation = {
|
|
119908
|
-
tokenize: tokenizeMarkupOnlyContinuation,
|
|
119909
|
-
partial: true,
|
|
119910
|
-
};
|
|
119911
|
-
function resolveToMdxComponent(events) {
|
|
119126
|
+
function resolveToJsxTable(events) {
|
|
119912
119127
|
let index = events.length;
|
|
119913
119128
|
while (index > 0) {
|
|
119914
119129
|
index -= 1;
|
|
119915
|
-
if (events[index][0] === 'enter' && events[index][1].type === '
|
|
119130
|
+
if (events[index][0] === 'enter' && events[index][1].type === 'jsxTable') {
|
|
119916
119131
|
break;
|
|
119917
119132
|
}
|
|
119918
119133
|
}
|
|
@@ -119923,123 +119138,1229 @@ function resolveToMdxComponent(events) {
|
|
|
119923
119138
|
}
|
|
119924
119139
|
return events;
|
|
119925
119140
|
}
|
|
119926
|
-
const
|
|
119927
|
-
name: '
|
|
119928
|
-
tokenize:
|
|
119929
|
-
resolveTo:
|
|
119141
|
+
const jsxTableConstruct = {
|
|
119142
|
+
name: 'jsxTable',
|
|
119143
|
+
tokenize: tokenizeJsxTable,
|
|
119144
|
+
resolveTo: resolveToJsxTable,
|
|
119930
119145
|
concrete: true,
|
|
119931
119146
|
};
|
|
119932
|
-
|
|
119933
|
-
|
|
119934
|
-
|
|
119935
|
-
|
|
119936
|
-
|
|
119937
|
-
|
|
119938
|
-
|
|
119939
|
-
|
|
119940
|
-
|
|
119941
|
-
|
|
119942
|
-
|
|
119943
|
-
* **Text** — runs inside paragraphs / inline context. Claims lowercase tags and
|
|
119944
|
-
* inline PascalCase components (`INLINE_COMPONENT_TAGS` — Anchor, Glossary), both
|
|
119945
|
-
* gated on at least one `{…}` brace attribute. All other PascalCase stays
|
|
119946
|
-
* flow-only, matching how ReadMe's custom components are authored. Aborts on line
|
|
119947
|
-
* endings (inline constructs don't span lines) and exits immediately after
|
|
119948
|
-
* `</tag>` so the paragraph's inline parser picks up the trailing text.
|
|
119949
|
-
*/
|
|
119950
|
-
function createTokenize(mode) {
|
|
119951
|
-
const isFlow = mode === 'flow';
|
|
119952
|
-
return function tokenize(effects, ok, nok) {
|
|
119953
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
119954
|
-
const self = this;
|
|
119955
|
-
let tagName = '';
|
|
119956
|
-
let depth = 0;
|
|
119957
|
-
let closingTagName = '';
|
|
119958
|
-
// For lowercase tags we only want to claim the block if it uses JSX
|
|
119959
|
-
// attribute expression syntax (`attr={...}`). Plain HTML should fall
|
|
119960
|
-
// through to CommonMark html-flow. Flow mode claims any PascalCase block
|
|
119961
|
-
// component; text mode claims only inline PascalCase components
|
|
119962
|
-
// (INLINE_COMPONENT_TAGS — Anchor, Glossary), also brace-gated.
|
|
119963
|
-
let isLowercaseTag = false;
|
|
119964
|
-
let sawBraceAttr = false;
|
|
119965
|
-
// A plain lowercase block tag claimed without a `{…}` attribute, gated by
|
|
119966
|
-
// `plainClaimLineStart`: after a blank line it may only continue on a tag line.
|
|
119967
|
-
let isPlainBlockClaim = false;
|
|
119968
|
-
let pendingBlankLine = false;
|
|
119969
|
-
// Code span tracking
|
|
119970
|
-
let codeSpanOpenSize = 0;
|
|
119971
|
-
let codeSpanCloseSize = 0;
|
|
119972
|
-
// Fenced code block tracking
|
|
119973
|
-
let fenceChar = null;
|
|
119974
|
-
let fenceLength = 0;
|
|
119975
|
-
let fenceCloseLength = 0;
|
|
119976
|
-
let atLineStart = false;
|
|
119977
|
-
// True once this construct consumes any line ending; lets `afterClose`
|
|
119978
|
-
// treat only single-line lowercase tags as inline candidates.
|
|
119979
|
-
let sawLineEnding = false;
|
|
119980
|
-
// Bail when the opener line has unmatched tag-like tokens in its body.
|
|
119981
|
-
// `<Foo>_<Bar>.csv` leaves opens > closes; matched shapes like
|
|
119982
|
-
// `<Callout>x <strong>y</strong>` balance to 0. Without this,
|
|
119983
|
-
// `concrete: true` causes orphan openers to eat sibling blockquotes.
|
|
119984
|
-
let onOpenerLine = false;
|
|
119985
|
-
let openerLineHasContent = false;
|
|
119986
|
-
let openerLineOpens = 0;
|
|
119987
|
-
let openerLineCloses = 0;
|
|
119988
|
-
// Attribute parsing state
|
|
119989
|
-
let quoteChar = null;
|
|
119990
|
-
let braceDepth = 0;
|
|
119991
|
-
let inTemplateLit = false; // true when inside a template literal (for line continuation)
|
|
119992
|
-
// Stack of braceDepth values at each ${...} interpolation entry point.
|
|
119993
|
-
// When a } brings braceDepth back to a saved value, we return to the
|
|
119994
|
-
// template literal instead of continuing in the brace expression.
|
|
119995
|
-
const templateStack = [];
|
|
119996
|
-
const isAlpha = (code) => (code >= codes_codes.uppercaseA && code <= codes_codes.uppercaseZ) ||
|
|
119997
|
-
(code >= codes_codes.lowercaseA && code <= codes_codes.lowercaseZ);
|
|
119998
|
-
const isSameCaseAsTag = (code) => isLowercaseTag
|
|
119999
|
-
? code >= codes_codes.lowercaseA && code <= codes_codes.lowercaseZ
|
|
120000
|
-
: code >= codes_codes.uppercaseA && code <= codes_codes.uppercaseZ;
|
|
120001
|
-
// Shared brace-expression state machine. The two call sites differ only in where
|
|
120002
|
-
// to continue after a line ending and where to return when braceDepth reaches zero.
|
|
120003
|
-
function createBraceExprStates(continuationStart, afterBraceClose) {
|
|
120004
|
-
function braceExpr(code) {
|
|
120005
|
-
if (code === null)
|
|
120006
|
-
return nok(code);
|
|
120007
|
-
if (markdownLineEnding(code)) {
|
|
120008
|
-
if (!isFlow)
|
|
120009
|
-
return nok(code);
|
|
120010
|
-
effects.exit('mdxComponentData');
|
|
120011
|
-
return continuationStart(code);
|
|
120012
|
-
}
|
|
120013
|
-
if (code === codes_codes.quotationMark || code === codes_codes.apostrophe) {
|
|
120014
|
-
quoteChar = code;
|
|
120015
|
-
effects.consume(code);
|
|
120016
|
-
return braceString;
|
|
120017
|
-
}
|
|
120018
|
-
if (code === codes_codes.graveAccent) {
|
|
120019
|
-
inTemplateLit = true;
|
|
120020
|
-
effects.consume(code);
|
|
120021
|
-
return braceTemplateLiteral;
|
|
120022
|
-
}
|
|
120023
|
-
if (code === codes_codes.leftCurlyBrace) {
|
|
120024
|
-
braceDepth += 1;
|
|
120025
|
-
effects.consume(code);
|
|
120026
|
-
return braceExpr;
|
|
120027
|
-
}
|
|
120028
|
-
if (code === codes_codes.rightCurlyBrace) {
|
|
120029
|
-
braceDepth -= 1;
|
|
120030
|
-
effects.consume(code);
|
|
120031
|
-
if (templateStack.length > 0 && braceDepth === templateStack[templateStack.length - 1]) {
|
|
120032
|
-
templateStack.pop();
|
|
120033
|
-
inTemplateLit = true;
|
|
120034
|
-
return braceTemplateLiteral;
|
|
120035
|
-
}
|
|
120036
|
-
if (braceDepth === 0) {
|
|
120037
|
-
return afterBraceClose;
|
|
120038
|
-
}
|
|
120039
|
-
return braceExpr;
|
|
120040
|
-
}
|
|
119147
|
+
function tokenizeJsxTable(effects, ok, nok) {
|
|
119148
|
+
let codeSpanOpenSize = 0;
|
|
119149
|
+
let codeSpanCloseSize = 0;
|
|
119150
|
+
let depth = 1;
|
|
119151
|
+
const ABLE_SUFFIX = [codes.lowercaseA, codes.lowercaseB, codes.lowercaseL, codes.lowercaseE];
|
|
119152
|
+
/** Build a state chain that matches a sequence of character codes. */
|
|
119153
|
+
function matchChars(chars, onMatch, onFail) {
|
|
119154
|
+
if (chars.length === 0)
|
|
119155
|
+
return onMatch;
|
|
119156
|
+
return ((code) => {
|
|
119157
|
+
if (code === chars[0]) {
|
|
120041
119158
|
effects.consume(code);
|
|
120042
|
-
return
|
|
119159
|
+
return matchChars(chars.slice(1), onMatch, onFail);
|
|
119160
|
+
}
|
|
119161
|
+
return onFail(code);
|
|
119162
|
+
});
|
|
119163
|
+
}
|
|
119164
|
+
return start;
|
|
119165
|
+
function start(code) {
|
|
119166
|
+
if (code !== codes.lessThan)
|
|
119167
|
+
return nok(code);
|
|
119168
|
+
effects.enter('jsxTable');
|
|
119169
|
+
effects.enter('jsxTableData');
|
|
119170
|
+
effects.consume(code);
|
|
119171
|
+
return afterLessThan;
|
|
119172
|
+
}
|
|
119173
|
+
function afterLessThan(code) {
|
|
119174
|
+
if (code === codes.uppercaseT || code === codes.lowercaseT) {
|
|
119175
|
+
effects.consume(code);
|
|
119176
|
+
return matchChars(ABLE_SUFFIX, afterTagName, nok);
|
|
119177
|
+
}
|
|
119178
|
+
return nok(code);
|
|
119179
|
+
}
|
|
119180
|
+
function afterTagName(code) {
|
|
119181
|
+
if (code === codes.greaterThan || code === codes.slash || code === codes.space || code === codes.horizontalTab) {
|
|
119182
|
+
effects.consume(code);
|
|
119183
|
+
return body;
|
|
119184
|
+
}
|
|
119185
|
+
return nok(code);
|
|
119186
|
+
}
|
|
119187
|
+
function body(code) {
|
|
119188
|
+
// Reject unclosed <Table> so it falls back to normal HTML block parsing
|
|
119189
|
+
// instead of swallowing all subsequent content to EOF
|
|
119190
|
+
if (code === null) {
|
|
119191
|
+
return nok(code);
|
|
119192
|
+
}
|
|
119193
|
+
if (markdownLineEnding(code)) {
|
|
119194
|
+
effects.exit('jsxTableData');
|
|
119195
|
+
return continuationStart(code);
|
|
119196
|
+
}
|
|
119197
|
+
if (code === codes.backslash) {
|
|
119198
|
+
effects.consume(code);
|
|
119199
|
+
return escapedChar;
|
|
119200
|
+
}
|
|
119201
|
+
if (code === codes.lessThan) {
|
|
119202
|
+
effects.consume(code);
|
|
119203
|
+
return closeSlash;
|
|
119204
|
+
}
|
|
119205
|
+
// Skip over backtick code spans so `</Table>` in inline code isn't
|
|
119206
|
+
// treated as the closing tag
|
|
119207
|
+
if (code === codes.graveAccent) {
|
|
119208
|
+
codeSpanOpenSize = 0;
|
|
119209
|
+
return countOpenTicks(code);
|
|
119210
|
+
}
|
|
119211
|
+
effects.consume(code);
|
|
119212
|
+
return body;
|
|
119213
|
+
}
|
|
119214
|
+
function countOpenTicks(code) {
|
|
119215
|
+
if (code === codes.graveAccent) {
|
|
119216
|
+
codeSpanOpenSize += 1;
|
|
119217
|
+
effects.consume(code);
|
|
119218
|
+
return countOpenTicks;
|
|
119219
|
+
}
|
|
119220
|
+
return inCodeSpan(code);
|
|
119221
|
+
}
|
|
119222
|
+
function inCodeSpan(code) {
|
|
119223
|
+
if (code === null || markdownLineEnding(code))
|
|
119224
|
+
return body(code);
|
|
119225
|
+
if (code === codes.graveAccent) {
|
|
119226
|
+
codeSpanCloseSize = 0;
|
|
119227
|
+
return countCloseTicks(code);
|
|
119228
|
+
}
|
|
119229
|
+
effects.consume(code);
|
|
119230
|
+
return inCodeSpan;
|
|
119231
|
+
}
|
|
119232
|
+
function countCloseTicks(code) {
|
|
119233
|
+
if (code === codes.graveAccent) {
|
|
119234
|
+
codeSpanCloseSize += 1;
|
|
119235
|
+
effects.consume(code);
|
|
119236
|
+
return countCloseTicks;
|
|
119237
|
+
}
|
|
119238
|
+
return codeSpanCloseSize === codeSpanOpenSize ? body(code) : inCodeSpan(code);
|
|
119239
|
+
}
|
|
119240
|
+
function escapedChar(code) {
|
|
119241
|
+
if (code === null || markdownLineEnding(code)) {
|
|
119242
|
+
return body(code);
|
|
119243
|
+
}
|
|
119244
|
+
effects.consume(code);
|
|
119245
|
+
return body;
|
|
119246
|
+
}
|
|
119247
|
+
function closeSlash(code) {
|
|
119248
|
+
if (code === codes.slash) {
|
|
119249
|
+
effects.consume(code);
|
|
119250
|
+
return closeTagFirstChar;
|
|
119251
|
+
}
|
|
119252
|
+
if (code === codes.uppercaseT || code === codes.lowercaseT) {
|
|
119253
|
+
effects.consume(code);
|
|
119254
|
+
return matchChars(ABLE_SUFFIX, openAfterTagName, body);
|
|
119255
|
+
}
|
|
119256
|
+
return body(code);
|
|
119257
|
+
}
|
|
119258
|
+
function closeTagFirstChar(code) {
|
|
119259
|
+
if (code === codes.uppercaseT || code === codes.lowercaseT) {
|
|
119260
|
+
effects.consume(code);
|
|
119261
|
+
return matchChars(ABLE_SUFFIX, closeGt, body);
|
|
119262
|
+
}
|
|
119263
|
+
return body(code);
|
|
119264
|
+
}
|
|
119265
|
+
function openAfterTagName(code) {
|
|
119266
|
+
if (code === codes.greaterThan || code === codes.slash || code === codes.space || code === codes.horizontalTab) {
|
|
119267
|
+
depth += 1;
|
|
119268
|
+
effects.consume(code);
|
|
119269
|
+
return body;
|
|
119270
|
+
}
|
|
119271
|
+
return body(code);
|
|
119272
|
+
}
|
|
119273
|
+
function closeGt(code) {
|
|
119274
|
+
if (code === codes.greaterThan) {
|
|
119275
|
+
depth -= 1;
|
|
119276
|
+
effects.consume(code);
|
|
119277
|
+
if (depth === 0) {
|
|
119278
|
+
return afterClose;
|
|
119279
|
+
}
|
|
119280
|
+
return body;
|
|
119281
|
+
}
|
|
119282
|
+
return body(code);
|
|
119283
|
+
}
|
|
119284
|
+
function afterClose(code) {
|
|
119285
|
+
if (code === null || markdownLineEnding(code)) {
|
|
119286
|
+
effects.exit('jsxTableData');
|
|
119287
|
+
effects.exit('jsxTable');
|
|
119288
|
+
return ok(code);
|
|
119289
|
+
}
|
|
119290
|
+
effects.consume(code);
|
|
119291
|
+
return afterClose;
|
|
119292
|
+
}
|
|
119293
|
+
// Line ending handling — follows the htmlFlow pattern
|
|
119294
|
+
function continuationStart(code) {
|
|
119295
|
+
return effects.check(syntax_nonLazyContinuationStart, continuationStartNonLazy, continuationAfter)(code);
|
|
119296
|
+
}
|
|
119297
|
+
function continuationStartNonLazy(code) {
|
|
119298
|
+
effects.enter(types_types.lineEnding);
|
|
119299
|
+
effects.consume(code);
|
|
119300
|
+
effects.exit(types_types.lineEnding);
|
|
119301
|
+
return continuationBefore;
|
|
119302
|
+
}
|
|
119303
|
+
function continuationBefore(code) {
|
|
119304
|
+
if (code === null || markdownLineEnding(code)) {
|
|
119305
|
+
return continuationStart(code);
|
|
119306
|
+
}
|
|
119307
|
+
effects.enter('jsxTableData');
|
|
119308
|
+
return body(code);
|
|
119309
|
+
}
|
|
119310
|
+
function continuationAfter(code) {
|
|
119311
|
+
// At EOF without </Table>, reject so content isn't swallowed
|
|
119312
|
+
if (code === null) {
|
|
119313
|
+
return nok(code);
|
|
119314
|
+
}
|
|
119315
|
+
effects.exit('jsxTable');
|
|
119316
|
+
return ok(code);
|
|
119317
|
+
}
|
|
119318
|
+
}
|
|
119319
|
+
function syntax_tokenizeNonLazyContinuationStart(effects, ok, nok) {
|
|
119320
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
119321
|
+
const self = this;
|
|
119322
|
+
return start;
|
|
119323
|
+
function start(code) {
|
|
119324
|
+
if (markdownLineEnding(code)) {
|
|
119325
|
+
effects.enter(types_types.lineEnding);
|
|
119326
|
+
effects.consume(code);
|
|
119327
|
+
effects.exit(types_types.lineEnding);
|
|
119328
|
+
return after;
|
|
119329
|
+
}
|
|
119330
|
+
return nok(code);
|
|
119331
|
+
}
|
|
119332
|
+
function after(code) {
|
|
119333
|
+
if (self.parser.lazy[self.now().line]) {
|
|
119334
|
+
return nok(code);
|
|
119335
|
+
}
|
|
119336
|
+
return ok(code);
|
|
119337
|
+
}
|
|
119338
|
+
}
|
|
119339
|
+
/**
|
|
119340
|
+
* Micromark extension that tokenizes `<Table>...</Table>` and `<table>...</table>`
|
|
119341
|
+
* as a single flow block.
|
|
119342
|
+
*
|
|
119343
|
+
* Prevents CommonMark HTML block type 6 from fragmenting table blocks at blank lines.
|
|
119344
|
+
*/
|
|
119345
|
+
function syntax_jsxTable() {
|
|
119346
|
+
return {
|
|
119347
|
+
flow: {
|
|
119348
|
+
[codes.lessThan]: [jsxTableConstruct],
|
|
119349
|
+
},
|
|
119350
|
+
};
|
|
119351
|
+
}
|
|
119352
|
+
|
|
119353
|
+
;// ./lib/micromark/jsx-table/index.ts
|
|
119354
|
+
|
|
119355
|
+
|
|
119356
|
+
;// ./lib/micromark/magic-block/syntax.ts
|
|
119357
|
+
|
|
119358
|
+
|
|
119359
|
+
/**
|
|
119360
|
+
* Known magic block types that the tokenizer will recognize.
|
|
119361
|
+
* Unknown types will not be tokenized as magic blocks.
|
|
119362
|
+
*/
|
|
119363
|
+
const KNOWN_BLOCK_TYPES = new Set([
|
|
119364
|
+
'code',
|
|
119365
|
+
'api-header',
|
|
119366
|
+
'image',
|
|
119367
|
+
'callout',
|
|
119368
|
+
'parameters',
|
|
119369
|
+
'table',
|
|
119370
|
+
'embed',
|
|
119371
|
+
'html',
|
|
119372
|
+
'recipe',
|
|
119373
|
+
'tutorial-tile',
|
|
119374
|
+
]);
|
|
119375
|
+
/**
|
|
119376
|
+
* Check if a character is valid for a magic block type identifier.
|
|
119377
|
+
* Types can contain alphanumeric characters and hyphens (e.g., "api-header", "tutorial-tile")
|
|
119378
|
+
*/
|
|
119379
|
+
function isTypeChar(code) {
|
|
119380
|
+
return asciiAlphanumeric(code) || code === codes.dash;
|
|
119381
|
+
}
|
|
119382
|
+
/**
|
|
119383
|
+
* Creates the opening marker state machine: [block:
|
|
119384
|
+
* Returns the first state function to start parsing.
|
|
119385
|
+
*/
|
|
119386
|
+
function createOpeningMarkerParser(effects, nok, onComplete) {
|
|
119387
|
+
const expectB = (code) => {
|
|
119388
|
+
if (code !== codes.lowercaseB)
|
|
119389
|
+
return nok(code);
|
|
119390
|
+
effects.consume(code);
|
|
119391
|
+
return expectL;
|
|
119392
|
+
};
|
|
119393
|
+
const expectL = (code) => {
|
|
119394
|
+
if (code !== codes.lowercaseL)
|
|
119395
|
+
return nok(code);
|
|
119396
|
+
effects.consume(code);
|
|
119397
|
+
return expectO;
|
|
119398
|
+
};
|
|
119399
|
+
const expectO = (code) => {
|
|
119400
|
+
if (code !== codes.lowercaseO)
|
|
119401
|
+
return nok(code);
|
|
119402
|
+
effects.consume(code);
|
|
119403
|
+
return expectC;
|
|
119404
|
+
};
|
|
119405
|
+
const expectC = (code) => {
|
|
119406
|
+
if (code !== codes.lowercaseC)
|
|
119407
|
+
return nok(code);
|
|
119408
|
+
effects.consume(code);
|
|
119409
|
+
return expectK;
|
|
119410
|
+
};
|
|
119411
|
+
const expectK = (code) => {
|
|
119412
|
+
if (code !== codes.lowercaseK)
|
|
119413
|
+
return nok(code);
|
|
119414
|
+
effects.consume(code);
|
|
119415
|
+
return expectColon;
|
|
119416
|
+
};
|
|
119417
|
+
const expectColon = (code) => {
|
|
119418
|
+
if (code !== codes.colon)
|
|
119419
|
+
return nok(code);
|
|
119420
|
+
effects.consume(code);
|
|
119421
|
+
effects.exit('magicBlockMarkerStart');
|
|
119422
|
+
effects.enter('magicBlockType');
|
|
119423
|
+
return onComplete;
|
|
119424
|
+
};
|
|
119425
|
+
return expectB;
|
|
119426
|
+
}
|
|
119427
|
+
/**
|
|
119428
|
+
* Creates the type capture state machine.
|
|
119429
|
+
* Captures type characters until ] and validates against known types.
|
|
119430
|
+
*/
|
|
119431
|
+
function createTypeCaptureParser(effects, nok, onComplete, blockTypeRef) {
|
|
119432
|
+
const captureTypeFirst = (code) => {
|
|
119433
|
+
// Reject empty type name [block:]
|
|
119434
|
+
if (code === codes.rightSquareBracket) {
|
|
119435
|
+
return nok(code);
|
|
119436
|
+
}
|
|
119437
|
+
if (isTypeChar(code)) {
|
|
119438
|
+
blockTypeRef.value += String.fromCharCode(code);
|
|
119439
|
+
effects.consume(code);
|
|
119440
|
+
return captureType;
|
|
119441
|
+
}
|
|
119442
|
+
return nok(code);
|
|
119443
|
+
};
|
|
119444
|
+
const captureType = (code) => {
|
|
119445
|
+
if (code === codes.rightSquareBracket) {
|
|
119446
|
+
if (!KNOWN_BLOCK_TYPES.has(blockTypeRef.value)) {
|
|
119447
|
+
return nok(code);
|
|
119448
|
+
}
|
|
119449
|
+
effects.exit('magicBlockType');
|
|
119450
|
+
effects.enter('magicBlockMarkerTypeEnd');
|
|
119451
|
+
effects.consume(code);
|
|
119452
|
+
effects.exit('magicBlockMarkerTypeEnd');
|
|
119453
|
+
return onComplete;
|
|
119454
|
+
}
|
|
119455
|
+
if (isTypeChar(code)) {
|
|
119456
|
+
blockTypeRef.value += String.fromCharCode(code);
|
|
119457
|
+
effects.consume(code);
|
|
119458
|
+
return captureType;
|
|
119459
|
+
}
|
|
119460
|
+
return nok(code);
|
|
119461
|
+
};
|
|
119462
|
+
return { first: captureTypeFirst, remaining: captureType };
|
|
119463
|
+
}
|
|
119464
|
+
/**
|
|
119465
|
+
* Creates the closing marker state machine: /block]
|
|
119466
|
+
* Handles partial matches by calling onMismatch to fall back to data capture.
|
|
119467
|
+
*/
|
|
119468
|
+
function createClosingMarkerParser(effects, onSuccess, onMismatch, onEof, jsonState) {
|
|
119469
|
+
const handleMismatch = (code) => {
|
|
119470
|
+
if (jsonState && code === codes.quotationMark) {
|
|
119471
|
+
jsonState.inString = true;
|
|
119472
|
+
}
|
|
119473
|
+
return onMismatch(code);
|
|
119474
|
+
};
|
|
119475
|
+
const expectSlash = (code) => {
|
|
119476
|
+
if (code === null)
|
|
119477
|
+
return onEof(code);
|
|
119478
|
+
if (code !== codes.slash)
|
|
119479
|
+
return handleMismatch(code);
|
|
119480
|
+
effects.consume(code);
|
|
119481
|
+
return expectB;
|
|
119482
|
+
};
|
|
119483
|
+
const expectB = (code) => {
|
|
119484
|
+
if (code === null)
|
|
119485
|
+
return onEof(code);
|
|
119486
|
+
if (code !== codes.lowercaseB)
|
|
119487
|
+
return handleMismatch(code);
|
|
119488
|
+
effects.consume(code);
|
|
119489
|
+
return expectL;
|
|
119490
|
+
};
|
|
119491
|
+
const expectL = (code) => {
|
|
119492
|
+
if (code === null)
|
|
119493
|
+
return onEof(code);
|
|
119494
|
+
if (code !== codes.lowercaseL)
|
|
119495
|
+
return handleMismatch(code);
|
|
119496
|
+
effects.consume(code);
|
|
119497
|
+
return expectO;
|
|
119498
|
+
};
|
|
119499
|
+
const expectO = (code) => {
|
|
119500
|
+
if (code === null)
|
|
119501
|
+
return onEof(code);
|
|
119502
|
+
if (code !== codes.lowercaseO)
|
|
119503
|
+
return handleMismatch(code);
|
|
119504
|
+
effects.consume(code);
|
|
119505
|
+
return expectC;
|
|
119506
|
+
};
|
|
119507
|
+
const expectC = (code) => {
|
|
119508
|
+
if (code === null)
|
|
119509
|
+
return onEof(code);
|
|
119510
|
+
if (code !== codes.lowercaseC)
|
|
119511
|
+
return handleMismatch(code);
|
|
119512
|
+
effects.consume(code);
|
|
119513
|
+
return expectK;
|
|
119514
|
+
};
|
|
119515
|
+
const expectK = (code) => {
|
|
119516
|
+
if (code === null)
|
|
119517
|
+
return onEof(code);
|
|
119518
|
+
if (code !== codes.lowercaseK)
|
|
119519
|
+
return handleMismatch(code);
|
|
119520
|
+
effects.consume(code);
|
|
119521
|
+
return expectBracket;
|
|
119522
|
+
};
|
|
119523
|
+
const expectBracket = (code) => {
|
|
119524
|
+
if (code === null)
|
|
119525
|
+
return onEof(code);
|
|
119526
|
+
if (code !== codes.rightSquareBracket)
|
|
119527
|
+
return handleMismatch(code);
|
|
119528
|
+
effects.consume(code);
|
|
119529
|
+
return onSuccess;
|
|
119530
|
+
};
|
|
119531
|
+
return { expectSlash };
|
|
119532
|
+
}
|
|
119533
|
+
/**
|
|
119534
|
+
* Partial construct for checking non-lazy continuation.
|
|
119535
|
+
* This is used by the flow tokenizer to check if we can continue
|
|
119536
|
+
* parsing on the next line.
|
|
119537
|
+
*/
|
|
119538
|
+
const syntax_nonLazyContinuation = {
|
|
119539
|
+
partial: true,
|
|
119540
|
+
tokenize: syntax_tokenizeNonLazyContinuation,
|
|
119541
|
+
};
|
|
119542
|
+
/**
|
|
119543
|
+
* Tokenizer for non-lazy continuation checking.
|
|
119544
|
+
* Returns ok if the next line is non-lazy (can continue), nok if lazy.
|
|
119545
|
+
*/
|
|
119546
|
+
function syntax_tokenizeNonLazyContinuation(effects, ok, nok) {
|
|
119547
|
+
const lineStart = (code) => {
|
|
119548
|
+
// `this` here refers to the micromark parser
|
|
119549
|
+
// since we are just passing functions as references and not actually calling them
|
|
119550
|
+
// micromarks's internal parser will call this automatically with appropriate arguments
|
|
119551
|
+
return this.parser.lazy[this.now().line] ? nok(code) : ok(code);
|
|
119552
|
+
};
|
|
119553
|
+
const start = (code) => {
|
|
119554
|
+
if (code === null) {
|
|
119555
|
+
return nok(code);
|
|
119556
|
+
}
|
|
119557
|
+
if (!markdownLineEnding(code)) {
|
|
119558
|
+
return nok(code);
|
|
119559
|
+
}
|
|
119560
|
+
effects.enter('magicBlockLineEnding');
|
|
119561
|
+
effects.consume(code);
|
|
119562
|
+
effects.exit('magicBlockLineEnding');
|
|
119563
|
+
return lineStart;
|
|
119564
|
+
};
|
|
119565
|
+
return start;
|
|
119566
|
+
}
|
|
119567
|
+
/**
|
|
119568
|
+
* Create a micromark extension for magic block syntax.
|
|
119569
|
+
*
|
|
119570
|
+
* This extension handles both single-line and multiline magic blocks:
|
|
119571
|
+
* - Flow construct (concrete): Handles block-level multiline magic blocks at document level
|
|
119572
|
+
* - Text construct: Handles inline magic blocks in lists, paragraphs, etc.
|
|
119573
|
+
*
|
|
119574
|
+
* The flow construct is marked as "concrete" which prevents it from being
|
|
119575
|
+
* interrupted by container markers (like `>` for blockquotes or `-` for lists).
|
|
119576
|
+
*/
|
|
119577
|
+
function syntax_magicBlock() {
|
|
119578
|
+
return {
|
|
119579
|
+
// Flow construct - handles block-level magic blocks at document root
|
|
119580
|
+
// Marked as concrete to prevent interruption by containers
|
|
119581
|
+
flow: {
|
|
119582
|
+
[codes.leftSquareBracket]: {
|
|
119583
|
+
name: 'magicBlock',
|
|
119584
|
+
concrete: true,
|
|
119585
|
+
tokenize: tokenizeMagicBlockFlow,
|
|
119586
|
+
},
|
|
119587
|
+
},
|
|
119588
|
+
// Text construct - handles magic blocks in inline contexts (lists, paragraphs)
|
|
119589
|
+
text: {
|
|
119590
|
+
[codes.leftSquareBracket]: {
|
|
119591
|
+
name: 'magicBlock',
|
|
119592
|
+
tokenize: tokenizeMagicBlockText,
|
|
119593
|
+
},
|
|
119594
|
+
},
|
|
119595
|
+
};
|
|
119596
|
+
}
|
|
119597
|
+
/**
|
|
119598
|
+
* Flow tokenizer for block-level magic blocks (multiline).
|
|
119599
|
+
* Uses the continuation checking pattern from code fences.
|
|
119600
|
+
*/
|
|
119601
|
+
function tokenizeMagicBlockFlow(effects, ok, nok) {
|
|
119602
|
+
// State for tracking JSON content
|
|
119603
|
+
const jsonState = { escapeNext: false, inString: false };
|
|
119604
|
+
const blockTypeRef = { value: '' };
|
|
119605
|
+
let seenOpenBrace = false;
|
|
119606
|
+
// Create shared parsers for opening marker and type capture
|
|
119607
|
+
const typeParser = createTypeCaptureParser(effects, nok, beforeData, blockTypeRef);
|
|
119608
|
+
const openingMarkerParser = createOpeningMarkerParser(effects, nok, typeParser.first);
|
|
119609
|
+
return start;
|
|
119610
|
+
function start(code) {
|
|
119611
|
+
if (code !== codes.leftSquareBracket)
|
|
119612
|
+
return nok(code);
|
|
119613
|
+
effects.enter('magicBlock');
|
|
119614
|
+
effects.enter('magicBlockMarkerStart');
|
|
119615
|
+
effects.consume(code);
|
|
119616
|
+
return openingMarkerParser;
|
|
119617
|
+
}
|
|
119618
|
+
/**
|
|
119619
|
+
* State before data content - handles line endings or starts data capture.
|
|
119620
|
+
*/
|
|
119621
|
+
function beforeData(code) {
|
|
119622
|
+
// EOF - magic block must be closed
|
|
119623
|
+
if (code === null) {
|
|
119624
|
+
effects.exit('magicBlock');
|
|
119625
|
+
return nok(code);
|
|
119626
|
+
}
|
|
119627
|
+
// Line ending before any data - check continuation
|
|
119628
|
+
if (markdownLineEnding(code)) {
|
|
119629
|
+
return effects.check(syntax_nonLazyContinuation, continuationOkBeforeData, after)(code);
|
|
119630
|
+
}
|
|
119631
|
+
// Check for closing marker directly (without entering data)
|
|
119632
|
+
// This handles cases like [block:type]\n{}\n\n[/block] where there are
|
|
119633
|
+
// newlines after the data object
|
|
119634
|
+
if (code === codes.leftSquareBracket) {
|
|
119635
|
+
effects.enter('magicBlockMarkerEnd');
|
|
119636
|
+
effects.consume(code);
|
|
119637
|
+
return expectSlashFromContinuation;
|
|
119638
|
+
}
|
|
119639
|
+
// If we've already seen the opening brace, just continue capturing data
|
|
119640
|
+
if (seenOpenBrace) {
|
|
119641
|
+
effects.enter('magicBlockData');
|
|
119642
|
+
return captureData(code);
|
|
119643
|
+
}
|
|
119644
|
+
// Skip whitespace (spaces/tabs) before the data - stay in beforeData
|
|
119645
|
+
// Don't enter magicBlockData token yet until we confirm there's a '{'
|
|
119646
|
+
if (code === codes.space || code === codes.horizontalTab) {
|
|
119647
|
+
return beforeDataWhitespace(code);
|
|
119648
|
+
}
|
|
119649
|
+
// Data must start with '{' for valid JSON
|
|
119650
|
+
if (code !== codes.leftCurlyBrace) {
|
|
119651
|
+
effects.exit('magicBlock');
|
|
119652
|
+
return nok(code);
|
|
119653
|
+
}
|
|
119654
|
+
// We have '{' - enter data token and start capturing
|
|
119655
|
+
seenOpenBrace = true;
|
|
119656
|
+
effects.enter('magicBlockData');
|
|
119657
|
+
return captureData(code);
|
|
119658
|
+
}
|
|
119659
|
+
/**
|
|
119660
|
+
* Consume whitespace before the data without creating a token.
|
|
119661
|
+
* Uses a temporary token to satisfy micromark's requirement.
|
|
119662
|
+
*/
|
|
119663
|
+
function beforeDataWhitespace(code) {
|
|
119664
|
+
if (code === null) {
|
|
119665
|
+
effects.exit('magicBlock');
|
|
119666
|
+
return nok(code);
|
|
119667
|
+
}
|
|
119668
|
+
if (markdownLineEnding(code)) {
|
|
119669
|
+
return effects.check(syntax_nonLazyContinuation, continuationOkBeforeData, after)(code);
|
|
119670
|
+
}
|
|
119671
|
+
if (code === codes.space || code === codes.horizontalTab) {
|
|
119672
|
+
// We need to consume this but can't without a token - use magicBlockData
|
|
119673
|
+
// and track that we haven't seen '{' yet
|
|
119674
|
+
effects.enter('magicBlockData');
|
|
119675
|
+
effects.consume(code);
|
|
119676
|
+
return beforeDataWhitespaceContinue;
|
|
119677
|
+
}
|
|
119678
|
+
if (code === codes.leftCurlyBrace) {
|
|
119679
|
+
seenOpenBrace = true;
|
|
119680
|
+
effects.enter('magicBlockData');
|
|
119681
|
+
return captureData(code);
|
|
119682
|
+
}
|
|
119683
|
+
effects.exit('magicBlock');
|
|
119684
|
+
return nok(code);
|
|
119685
|
+
}
|
|
119686
|
+
/**
|
|
119687
|
+
* Continue consuming whitespace or validate the opening brace.
|
|
119688
|
+
*/
|
|
119689
|
+
function beforeDataWhitespaceContinue(code) {
|
|
119690
|
+
if (code === null) {
|
|
119691
|
+
effects.exit('magicBlockData');
|
|
119692
|
+
effects.exit('magicBlock');
|
|
119693
|
+
return nok(code);
|
|
119694
|
+
}
|
|
119695
|
+
if (markdownLineEnding(code)) {
|
|
119696
|
+
effects.exit('magicBlockData');
|
|
119697
|
+
return effects.check(syntax_nonLazyContinuation, continuationOk, after)(code);
|
|
119698
|
+
}
|
|
119699
|
+
if (code === codes.space || code === codes.horizontalTab) {
|
|
119700
|
+
effects.consume(code);
|
|
119701
|
+
return beforeDataWhitespaceContinue;
|
|
119702
|
+
}
|
|
119703
|
+
if (code === codes.leftCurlyBrace) {
|
|
119704
|
+
seenOpenBrace = true;
|
|
119705
|
+
return captureData(code);
|
|
119706
|
+
}
|
|
119707
|
+
effects.exit('magicBlockData');
|
|
119708
|
+
effects.exit('magicBlock');
|
|
119709
|
+
return nok(code);
|
|
119710
|
+
}
|
|
119711
|
+
/**
|
|
119712
|
+
* Continuation OK before we've entered data token.
|
|
119713
|
+
*/
|
|
119714
|
+
function continuationOkBeforeData(code) {
|
|
119715
|
+
effects.enter('magicBlockLineEnding');
|
|
119716
|
+
effects.consume(code);
|
|
119717
|
+
effects.exit('magicBlockLineEnding');
|
|
119718
|
+
return beforeData; // Stay in beforeData state - don't enter magicBlockData yet
|
|
119719
|
+
}
|
|
119720
|
+
function captureData(code) {
|
|
119721
|
+
// EOF - magic block must be closed
|
|
119722
|
+
if (code === null) {
|
|
119723
|
+
effects.exit('magicBlockData');
|
|
119724
|
+
effects.exit('magicBlock');
|
|
119725
|
+
return nok(code);
|
|
119726
|
+
}
|
|
119727
|
+
// At line ending, check if we can continue on the next line
|
|
119728
|
+
if (markdownLineEnding(code)) {
|
|
119729
|
+
effects.exit('magicBlockData');
|
|
119730
|
+
return effects.check(syntax_nonLazyContinuation, continuationOk, after)(code);
|
|
119731
|
+
}
|
|
119732
|
+
if (jsonState.escapeNext) {
|
|
119733
|
+
jsonState.escapeNext = false;
|
|
119734
|
+
effects.consume(code);
|
|
119735
|
+
return captureData;
|
|
119736
|
+
}
|
|
119737
|
+
if (jsonState.inString) {
|
|
119738
|
+
if (code === codes.backslash) {
|
|
119739
|
+
jsonState.escapeNext = true;
|
|
119740
|
+
effects.consume(code);
|
|
119741
|
+
return captureData;
|
|
119742
|
+
}
|
|
119743
|
+
if (code === codes.quotationMark) {
|
|
119744
|
+
jsonState.inString = false;
|
|
119745
|
+
}
|
|
119746
|
+
effects.consume(code);
|
|
119747
|
+
return captureData;
|
|
119748
|
+
}
|
|
119749
|
+
if (code === codes.quotationMark) {
|
|
119750
|
+
jsonState.inString = true;
|
|
119751
|
+
effects.consume(code);
|
|
119752
|
+
return captureData;
|
|
119753
|
+
}
|
|
119754
|
+
if (code === codes.leftSquareBracket) {
|
|
119755
|
+
effects.exit('magicBlockData');
|
|
119756
|
+
effects.enter('magicBlockMarkerEnd');
|
|
119757
|
+
effects.consume(code);
|
|
119758
|
+
return expectSlash;
|
|
119759
|
+
}
|
|
119760
|
+
effects.consume(code);
|
|
119761
|
+
return captureData;
|
|
119762
|
+
}
|
|
119763
|
+
/**
|
|
119764
|
+
* Called when non-lazy continuation check passes - we can continue parsing.
|
|
119765
|
+
*/
|
|
119766
|
+
function continuationOk(code) {
|
|
119767
|
+
// Consume the line ending
|
|
119768
|
+
effects.enter('magicBlockLineEnding');
|
|
119769
|
+
effects.consume(code);
|
|
119770
|
+
effects.exit('magicBlockLineEnding');
|
|
119771
|
+
return continuationStart;
|
|
119772
|
+
}
|
|
119773
|
+
/**
|
|
119774
|
+
* Start of continuation line - check for more line endings, closing marker, or start capturing data.
|
|
119775
|
+
*/
|
|
119776
|
+
function continuationStart(code) {
|
|
119777
|
+
// Handle consecutive line endings
|
|
119778
|
+
if (code === null) {
|
|
119779
|
+
effects.exit('magicBlock');
|
|
119780
|
+
return nok(code);
|
|
119781
|
+
}
|
|
119782
|
+
if (markdownLineEnding(code)) {
|
|
119783
|
+
return effects.check(syntax_nonLazyContinuation, continuationOkBeforeData, after)(code);
|
|
119784
|
+
}
|
|
119785
|
+
// Check if this is the start of the closing marker [/block]
|
|
119786
|
+
// If so, handle it directly without entering magicBlockData
|
|
119787
|
+
if (code === codes.leftSquareBracket) {
|
|
119788
|
+
effects.enter('magicBlockMarkerEnd');
|
|
119789
|
+
effects.consume(code);
|
|
119790
|
+
return expectSlashFromContinuation;
|
|
119791
|
+
}
|
|
119792
|
+
effects.enter('magicBlockData');
|
|
119793
|
+
return captureData(code);
|
|
119794
|
+
}
|
|
119795
|
+
/**
|
|
119796
|
+
* Check for closing marker slash when coming from continuation.
|
|
119797
|
+
* If not a closing marker, create an empty data token and continue.
|
|
119798
|
+
*/
|
|
119799
|
+
function expectSlashFromContinuation(code) {
|
|
119800
|
+
if (code === null) {
|
|
119801
|
+
effects.exit('magicBlockMarkerEnd');
|
|
119802
|
+
effects.exit('magicBlock');
|
|
119803
|
+
return nok(code);
|
|
119804
|
+
}
|
|
119805
|
+
if (markdownLineEnding(code)) {
|
|
119806
|
+
effects.exit('magicBlockMarkerEnd');
|
|
119807
|
+
return effects.check(syntax_nonLazyContinuation, continuationOkBeforeData, after)(code);
|
|
119808
|
+
}
|
|
119809
|
+
if (code === codes.slash) {
|
|
119810
|
+
effects.consume(code);
|
|
119811
|
+
return expectClosingB;
|
|
119812
|
+
}
|
|
119813
|
+
// Not a closing marker - this is data content
|
|
119814
|
+
// Exit marker and enter data
|
|
119815
|
+
effects.exit('magicBlockMarkerEnd');
|
|
119816
|
+
effects.enter('magicBlockData');
|
|
119817
|
+
// The [ was consumed by the marker, so we need to conceptually "have it" in our data
|
|
119818
|
+
// But since we already consumed it into the marker, we need a different approach
|
|
119819
|
+
// Re-classify: consume this character as data and continue
|
|
119820
|
+
if (code === codes.quotationMark)
|
|
119821
|
+
jsonState.inString = true;
|
|
119822
|
+
effects.consume(code);
|
|
119823
|
+
return captureData;
|
|
119824
|
+
}
|
|
119825
|
+
function expectSlash(code) {
|
|
119826
|
+
if (code === null) {
|
|
119827
|
+
effects.exit('magicBlockMarkerEnd');
|
|
119828
|
+
effects.exit('magicBlock');
|
|
119829
|
+
return nok(code);
|
|
119830
|
+
}
|
|
119831
|
+
// At line ending during marker parsing
|
|
119832
|
+
if (markdownLineEnding(code)) {
|
|
119833
|
+
effects.exit('magicBlockMarkerEnd');
|
|
119834
|
+
return effects.check(syntax_nonLazyContinuation, continuationOk, after)(code);
|
|
119835
|
+
}
|
|
119836
|
+
if (code !== codes.slash) {
|
|
119837
|
+
effects.exit('magicBlockMarkerEnd');
|
|
119838
|
+
effects.enter('magicBlockData');
|
|
119839
|
+
if (code === codes.quotationMark)
|
|
119840
|
+
jsonState.inString = true;
|
|
119841
|
+
effects.consume(code);
|
|
119842
|
+
return captureData;
|
|
119843
|
+
}
|
|
119844
|
+
effects.consume(code);
|
|
119845
|
+
return expectClosingB;
|
|
119846
|
+
}
|
|
119847
|
+
function expectClosingB(code) {
|
|
119848
|
+
if (code === null) {
|
|
119849
|
+
effects.exit('magicBlockMarkerEnd');
|
|
119850
|
+
effects.exit('magicBlock');
|
|
119851
|
+
return nok(code);
|
|
119852
|
+
}
|
|
119853
|
+
if (code !== codes.lowercaseB) {
|
|
119854
|
+
effects.exit('magicBlockMarkerEnd');
|
|
119855
|
+
effects.enter('magicBlockData');
|
|
119856
|
+
if (code === codes.quotationMark)
|
|
119857
|
+
jsonState.inString = true;
|
|
119858
|
+
effects.consume(code);
|
|
119859
|
+
return captureData;
|
|
119860
|
+
}
|
|
119861
|
+
effects.consume(code);
|
|
119862
|
+
return expectClosingL;
|
|
119863
|
+
}
|
|
119864
|
+
function expectClosingL(code) {
|
|
119865
|
+
if (code === null) {
|
|
119866
|
+
effects.exit('magicBlockMarkerEnd');
|
|
119867
|
+
effects.exit('magicBlock');
|
|
119868
|
+
return nok(code);
|
|
119869
|
+
}
|
|
119870
|
+
if (code !== codes.lowercaseL) {
|
|
119871
|
+
effects.exit('magicBlockMarkerEnd');
|
|
119872
|
+
effects.enter('magicBlockData');
|
|
119873
|
+
if (code === codes.quotationMark)
|
|
119874
|
+
jsonState.inString = true;
|
|
119875
|
+
effects.consume(code);
|
|
119876
|
+
return captureData;
|
|
119877
|
+
}
|
|
119878
|
+
effects.consume(code);
|
|
119879
|
+
return expectClosingO;
|
|
119880
|
+
}
|
|
119881
|
+
function expectClosingO(code) {
|
|
119882
|
+
if (code === null) {
|
|
119883
|
+
effects.exit('magicBlockMarkerEnd');
|
|
119884
|
+
effects.exit('magicBlock');
|
|
119885
|
+
return nok(code);
|
|
119886
|
+
}
|
|
119887
|
+
if (code !== codes.lowercaseO) {
|
|
119888
|
+
effects.exit('magicBlockMarkerEnd');
|
|
119889
|
+
effects.enter('magicBlockData');
|
|
119890
|
+
if (code === codes.quotationMark)
|
|
119891
|
+
jsonState.inString = true;
|
|
119892
|
+
effects.consume(code);
|
|
119893
|
+
return captureData;
|
|
119894
|
+
}
|
|
119895
|
+
effects.consume(code);
|
|
119896
|
+
return expectClosingC;
|
|
119897
|
+
}
|
|
119898
|
+
function expectClosingC(code) {
|
|
119899
|
+
if (code === null) {
|
|
119900
|
+
effects.exit('magicBlockMarkerEnd');
|
|
119901
|
+
effects.exit('magicBlock');
|
|
119902
|
+
return nok(code);
|
|
119903
|
+
}
|
|
119904
|
+
if (code !== codes.lowercaseC) {
|
|
119905
|
+
effects.exit('magicBlockMarkerEnd');
|
|
119906
|
+
effects.enter('magicBlockData');
|
|
119907
|
+
if (code === codes.quotationMark)
|
|
119908
|
+
jsonState.inString = true;
|
|
119909
|
+
effects.consume(code);
|
|
119910
|
+
return captureData;
|
|
119911
|
+
}
|
|
119912
|
+
effects.consume(code);
|
|
119913
|
+
return expectClosingK;
|
|
119914
|
+
}
|
|
119915
|
+
function expectClosingK(code) {
|
|
119916
|
+
if (code === null) {
|
|
119917
|
+
effects.exit('magicBlockMarkerEnd');
|
|
119918
|
+
effects.exit('magicBlock');
|
|
119919
|
+
return nok(code);
|
|
119920
|
+
}
|
|
119921
|
+
if (code !== codes.lowercaseK) {
|
|
119922
|
+
effects.exit('magicBlockMarkerEnd');
|
|
119923
|
+
effects.enter('magicBlockData');
|
|
119924
|
+
if (code === codes.quotationMark)
|
|
119925
|
+
jsonState.inString = true;
|
|
119926
|
+
effects.consume(code);
|
|
119927
|
+
return captureData;
|
|
119928
|
+
}
|
|
119929
|
+
effects.consume(code);
|
|
119930
|
+
return expectClosingBracket;
|
|
119931
|
+
}
|
|
119932
|
+
function expectClosingBracket(code) {
|
|
119933
|
+
if (code === null) {
|
|
119934
|
+
effects.exit('magicBlockMarkerEnd');
|
|
119935
|
+
effects.exit('magicBlock');
|
|
119936
|
+
return nok(code);
|
|
119937
|
+
}
|
|
119938
|
+
if (code !== codes.rightSquareBracket) {
|
|
119939
|
+
effects.exit('magicBlockMarkerEnd');
|
|
119940
|
+
effects.enter('magicBlockData');
|
|
119941
|
+
if (code === codes.quotationMark)
|
|
119942
|
+
jsonState.inString = true;
|
|
119943
|
+
effects.consume(code);
|
|
119944
|
+
return captureData;
|
|
119945
|
+
}
|
|
119946
|
+
effects.consume(code);
|
|
119947
|
+
effects.exit('magicBlockMarkerEnd');
|
|
119948
|
+
// Check for trailing whitespace on the same line
|
|
119949
|
+
return consumeTrailing;
|
|
119950
|
+
}
|
|
119951
|
+
/**
|
|
119952
|
+
* Consume trailing whitespace (spaces/tabs) on the same line after [/block].
|
|
119953
|
+
* For concrete flow constructs, we must end at eol/eof or fail.
|
|
119954
|
+
* Trailing whitespace is consumed; other content causes nok (text tokenizer handles it).
|
|
119955
|
+
*/
|
|
119956
|
+
function consumeTrailing(code) {
|
|
119957
|
+
// End of file - done
|
|
119958
|
+
if (code === null) {
|
|
119959
|
+
effects.exit('magicBlock');
|
|
119960
|
+
return ok(code);
|
|
119961
|
+
}
|
|
119962
|
+
// Line ending - done
|
|
119963
|
+
if (markdownLineEnding(code)) {
|
|
119964
|
+
effects.exit('magicBlock');
|
|
119965
|
+
return ok(code);
|
|
119966
|
+
}
|
|
119967
|
+
// Space or tab - consume as trailing whitespace
|
|
119968
|
+
if (code === codes.space || code === codes.horizontalTab) {
|
|
119969
|
+
effects.enter('magicBlockTrailing');
|
|
119970
|
+
effects.consume(code);
|
|
119971
|
+
return consumeTrailingContinue;
|
|
119972
|
+
}
|
|
119973
|
+
// Any other character - fail flow tokenizer, let text tokenizer handle it
|
|
119974
|
+
effects.exit('magicBlock');
|
|
119975
|
+
return nok(code);
|
|
119976
|
+
}
|
|
119977
|
+
/**
|
|
119978
|
+
* Continue consuming trailing whitespace.
|
|
119979
|
+
*/
|
|
119980
|
+
function consumeTrailingContinue(code) {
|
|
119981
|
+
// End of file - done
|
|
119982
|
+
if (code === null) {
|
|
119983
|
+
effects.exit('magicBlockTrailing');
|
|
119984
|
+
effects.exit('magicBlock');
|
|
119985
|
+
return ok(code);
|
|
119986
|
+
}
|
|
119987
|
+
// Line ending - done
|
|
119988
|
+
if (markdownLineEnding(code)) {
|
|
119989
|
+
effects.exit('magicBlockTrailing');
|
|
119990
|
+
effects.exit('magicBlock');
|
|
119991
|
+
return ok(code);
|
|
119992
|
+
}
|
|
119993
|
+
// More space or tab - keep consuming
|
|
119994
|
+
if (code === codes.space || code === codes.horizontalTab) {
|
|
119995
|
+
effects.consume(code);
|
|
119996
|
+
return consumeTrailingContinue;
|
|
119997
|
+
}
|
|
119998
|
+
// Non-whitespace after whitespace - fail flow tokenizer
|
|
119999
|
+
effects.exit('magicBlockTrailing');
|
|
120000
|
+
effects.exit('magicBlock');
|
|
120001
|
+
return nok(code);
|
|
120002
|
+
}
|
|
120003
|
+
/**
|
|
120004
|
+
* Called when we can't continue (lazy line or EOF) - exit the construct.
|
|
120005
|
+
*/
|
|
120006
|
+
function after(code) {
|
|
120007
|
+
effects.exit('magicBlock');
|
|
120008
|
+
return nok(code);
|
|
120009
|
+
}
|
|
120010
|
+
}
|
|
120011
|
+
/**
|
|
120012
|
+
* Text tokenizer for single-line magic blocks only.
|
|
120013
|
+
* Used in inline contexts like list items and paragraphs.
|
|
120014
|
+
* Multiline blocks are handled by the flow tokenizer.
|
|
120015
|
+
*/
|
|
120016
|
+
function tokenizeMagicBlockText(effects, ok, nok) {
|
|
120017
|
+
// State for tracking JSON content
|
|
120018
|
+
const jsonState = { escapeNext: false, inString: false };
|
|
120019
|
+
const blockTypeRef = { value: '' };
|
|
120020
|
+
let seenOpenBrace = false;
|
|
120021
|
+
// Create shared parsers for opening marker and type capture
|
|
120022
|
+
const typeParser = createTypeCaptureParser(effects, nok, beforeData, blockTypeRef);
|
|
120023
|
+
const openingMarkerParser = createOpeningMarkerParser(effects, nok, typeParser.first);
|
|
120024
|
+
// Success handler for closing marker - exits tokens and returns ok
|
|
120025
|
+
const closingSuccess = (code) => {
|
|
120026
|
+
effects.exit('magicBlockMarkerEnd');
|
|
120027
|
+
effects.exit('magicBlock');
|
|
120028
|
+
return ok(code);
|
|
120029
|
+
};
|
|
120030
|
+
// Mismatch handler - falls back to data capture
|
|
120031
|
+
const closingMismatch = (code) => {
|
|
120032
|
+
effects.exit('magicBlockMarkerEnd');
|
|
120033
|
+
effects.enter('magicBlockData');
|
|
120034
|
+
if (code === codes.quotationMark)
|
|
120035
|
+
jsonState.inString = true;
|
|
120036
|
+
effects.consume(code);
|
|
120037
|
+
return captureData;
|
|
120038
|
+
};
|
|
120039
|
+
// EOF handler
|
|
120040
|
+
const closingEof = (_code) => nok(_code);
|
|
120041
|
+
// Create closing marker parsers
|
|
120042
|
+
const closingFromBeforeData = createClosingMarkerParser(effects, closingSuccess, closingMismatch, closingEof, jsonState);
|
|
120043
|
+
const closingFromData = createClosingMarkerParser(effects, closingSuccess, closingMismatch, closingEof, jsonState);
|
|
120044
|
+
return start;
|
|
120045
|
+
function start(code) {
|
|
120046
|
+
if (code !== codes.leftSquareBracket)
|
|
120047
|
+
return nok(code);
|
|
120048
|
+
effects.enter('magicBlock');
|
|
120049
|
+
effects.enter('magicBlockMarkerStart');
|
|
120050
|
+
effects.consume(code);
|
|
120051
|
+
return openingMarkerParser;
|
|
120052
|
+
}
|
|
120053
|
+
/**
|
|
120054
|
+
* State before data content - handles line endings before entering data token.
|
|
120055
|
+
* Whitespace before '{' is allowed.
|
|
120056
|
+
*/
|
|
120057
|
+
function beforeData(code) {
|
|
120058
|
+
// Fail on EOF - magic block must be closed
|
|
120059
|
+
if (code === null) {
|
|
120060
|
+
return nok(code);
|
|
120061
|
+
}
|
|
120062
|
+
// Handle line endings before any data - consume them without entering data token
|
|
120063
|
+
if (markdownLineEnding(code)) {
|
|
120064
|
+
effects.enter('magicBlockLineEnding');
|
|
120065
|
+
effects.consume(code);
|
|
120066
|
+
effects.exit('magicBlockLineEnding');
|
|
120067
|
+
return beforeData;
|
|
120068
|
+
}
|
|
120069
|
+
// Check for closing marker directly (without entering data)
|
|
120070
|
+
if (code === codes.leftSquareBracket) {
|
|
120071
|
+
effects.enter('magicBlockMarkerEnd');
|
|
120072
|
+
effects.consume(code);
|
|
120073
|
+
return closingFromBeforeData.expectSlash;
|
|
120074
|
+
}
|
|
120075
|
+
// If we've already seen the opening brace, just continue capturing data
|
|
120076
|
+
if (seenOpenBrace) {
|
|
120077
|
+
effects.enter('magicBlockData');
|
|
120078
|
+
return captureData(code);
|
|
120079
|
+
}
|
|
120080
|
+
// Skip whitespace (spaces/tabs) before the data
|
|
120081
|
+
if (code === codes.space || code === codes.horizontalTab) {
|
|
120082
|
+
return beforeDataWhitespace(code);
|
|
120083
|
+
}
|
|
120084
|
+
// Data must start with '{' for valid JSON
|
|
120085
|
+
if (code !== codes.leftCurlyBrace) {
|
|
120086
|
+
return nok(code);
|
|
120087
|
+
}
|
|
120088
|
+
// We have '{' - enter data token and start capturing
|
|
120089
|
+
seenOpenBrace = true;
|
|
120090
|
+
effects.enter('magicBlockData');
|
|
120091
|
+
return captureData(code);
|
|
120092
|
+
}
|
|
120093
|
+
/**
|
|
120094
|
+
* Consume whitespace before the data.
|
|
120095
|
+
*/
|
|
120096
|
+
function beforeDataWhitespace(code) {
|
|
120097
|
+
if (code === null) {
|
|
120098
|
+
return nok(code);
|
|
120099
|
+
}
|
|
120100
|
+
if (markdownLineEnding(code)) {
|
|
120101
|
+
effects.enter('magicBlockLineEnding');
|
|
120102
|
+
effects.consume(code);
|
|
120103
|
+
effects.exit('magicBlockLineEnding');
|
|
120104
|
+
return beforeData;
|
|
120105
|
+
}
|
|
120106
|
+
if (code === codes.space || code === codes.horizontalTab) {
|
|
120107
|
+
effects.enter('magicBlockData');
|
|
120108
|
+
effects.consume(code);
|
|
120109
|
+
return beforeDataWhitespaceContinue;
|
|
120110
|
+
}
|
|
120111
|
+
if (code === codes.leftCurlyBrace) {
|
|
120112
|
+
seenOpenBrace = true;
|
|
120113
|
+
effects.enter('magicBlockData');
|
|
120114
|
+
return captureData(code);
|
|
120115
|
+
}
|
|
120116
|
+
return nok(code);
|
|
120117
|
+
}
|
|
120118
|
+
/**
|
|
120119
|
+
* Continue consuming whitespace or validate the opening brace.
|
|
120120
|
+
*/
|
|
120121
|
+
function beforeDataWhitespaceContinue(code) {
|
|
120122
|
+
if (code === null) {
|
|
120123
|
+
effects.exit('magicBlockData');
|
|
120124
|
+
return nok(code);
|
|
120125
|
+
}
|
|
120126
|
+
if (markdownLineEnding(code)) {
|
|
120127
|
+
effects.exit('magicBlockData');
|
|
120128
|
+
effects.enter('magicBlockLineEnding');
|
|
120129
|
+
effects.consume(code);
|
|
120130
|
+
effects.exit('magicBlockLineEnding');
|
|
120131
|
+
return beforeData;
|
|
120132
|
+
}
|
|
120133
|
+
if (code === codes.space || code === codes.horizontalTab) {
|
|
120134
|
+
effects.consume(code);
|
|
120135
|
+
return beforeDataWhitespaceContinue;
|
|
120136
|
+
}
|
|
120137
|
+
if (code === codes.leftCurlyBrace) {
|
|
120138
|
+
seenOpenBrace = true;
|
|
120139
|
+
return captureData(code);
|
|
120140
|
+
}
|
|
120141
|
+
effects.exit('magicBlockData');
|
|
120142
|
+
return nok(code);
|
|
120143
|
+
}
|
|
120144
|
+
function captureData(code) {
|
|
120145
|
+
// Fail on EOF - magic block must be closed
|
|
120146
|
+
if (code === null) {
|
|
120147
|
+
effects.exit('magicBlockData');
|
|
120148
|
+
return nok(code);
|
|
120149
|
+
}
|
|
120150
|
+
// Handle multiline magic blocks within text/paragraphs
|
|
120151
|
+
// Exit data, consume line ending with proper token, then re-enter data
|
|
120152
|
+
if (markdownLineEnding(code)) {
|
|
120153
|
+
effects.exit('magicBlockData');
|
|
120154
|
+
effects.enter('magicBlockLineEnding');
|
|
120155
|
+
effects.consume(code);
|
|
120156
|
+
effects.exit('magicBlockLineEnding');
|
|
120157
|
+
return beforeData; // Go back to beforeData to handle potential empty lines
|
|
120158
|
+
}
|
|
120159
|
+
if (jsonState.escapeNext) {
|
|
120160
|
+
jsonState.escapeNext = false;
|
|
120161
|
+
effects.consume(code);
|
|
120162
|
+
return captureData;
|
|
120163
|
+
}
|
|
120164
|
+
if (jsonState.inString) {
|
|
120165
|
+
if (code === codes.backslash) {
|
|
120166
|
+
jsonState.escapeNext = true;
|
|
120167
|
+
effects.consume(code);
|
|
120168
|
+
return captureData;
|
|
120169
|
+
}
|
|
120170
|
+
if (code === codes.quotationMark) {
|
|
120171
|
+
jsonState.inString = false;
|
|
120172
|
+
}
|
|
120173
|
+
effects.consume(code);
|
|
120174
|
+
return captureData;
|
|
120175
|
+
}
|
|
120176
|
+
if (code === codes.quotationMark) {
|
|
120177
|
+
jsonState.inString = true;
|
|
120178
|
+
effects.consume(code);
|
|
120179
|
+
return captureData;
|
|
120180
|
+
}
|
|
120181
|
+
if (code === codes.leftSquareBracket) {
|
|
120182
|
+
effects.exit('magicBlockData');
|
|
120183
|
+
effects.enter('magicBlockMarkerEnd');
|
|
120184
|
+
effects.consume(code);
|
|
120185
|
+
return closingFromData.expectSlash;
|
|
120186
|
+
}
|
|
120187
|
+
effects.consume(code);
|
|
120188
|
+
return captureData;
|
|
120189
|
+
}
|
|
120190
|
+
}
|
|
120191
|
+
/* harmony default export */ const syntax = ((/* unused pure expression or super */ null && (syntax_magicBlock)));
|
|
120192
|
+
|
|
120193
|
+
;// ./lib/micromark/magic-block/index.ts
|
|
120194
|
+
/**
|
|
120195
|
+
* Micromark extension for magic block syntax.
|
|
120196
|
+
*
|
|
120197
|
+
* Usage:
|
|
120198
|
+
* ```ts
|
|
120199
|
+
* import { magicBlock } from './lib/micromark/magic-block';
|
|
120200
|
+
*
|
|
120201
|
+
* const processor = unified()
|
|
120202
|
+
* .data('micromarkExtensions', [magicBlock()])
|
|
120203
|
+
* ```
|
|
120204
|
+
*/
|
|
120205
|
+
|
|
120206
|
+
|
|
120207
|
+
;// ./lib/micromark/mdx-component/syntax.ts
|
|
120208
|
+
|
|
120209
|
+
|
|
120210
|
+
|
|
120211
|
+
|
|
120212
|
+
|
|
120213
|
+
// Raw tags (type-1: pre/script/style/textarea) and block tags (type-6: div,
|
|
120214
|
+
// section, …) always start a block, so they stay flow even with trailing
|
|
120215
|
+
// content. Other lowercase tags (i, span, …) follow the type-7 rule and only
|
|
120216
|
+
// stay flow when nothing trails the close tag.
|
|
120217
|
+
const htmlFlowTagNames = new Set([...htmlRawNames, ...htmlBlockNames]);
|
|
120218
|
+
// Lowercase type-6 block tags claimable in flow even without a `{…}` attribute, so
|
|
120219
|
+
// blank lines between nested JSX siblings don't fragment the block. Excludes table
|
|
120220
|
+
// tags (mdxishTables owns their blank lines) and voids (never close).
|
|
120221
|
+
const plainBlockClaimTagNames = new Set([...htmlBlockNames].filter(tag => !HTML_TABLE_STRUCTURE_TAGS.has(tag) && !HTML_VOID_ELEMENTS.has(tag)));
|
|
120222
|
+
const mdx_component_syntax_nonLazyContinuationStart = {
|
|
120223
|
+
tokenize: mdx_component_syntax_tokenizeNonLazyContinuationStart,
|
|
120224
|
+
partial: true,
|
|
120225
|
+
};
|
|
120226
|
+
// Lookahead for `plainClaimLineStart`: is this line markup-only, or a paragraph
|
|
120227
|
+
// that merely starts with a tag? Run via `effects.check` so it never consumes.
|
|
120228
|
+
const markupOnlyContinuation = {
|
|
120229
|
+
tokenize: tokenizeMarkupOnlyContinuation,
|
|
120230
|
+
partial: true,
|
|
120231
|
+
};
|
|
120232
|
+
function resolveToMdxComponent(events) {
|
|
120233
|
+
let index = events.length;
|
|
120234
|
+
while (index > 0) {
|
|
120235
|
+
index -= 1;
|
|
120236
|
+
if (events[index][0] === 'enter' && events[index][1].type === 'mdxComponent') {
|
|
120237
|
+
break;
|
|
120238
|
+
}
|
|
120239
|
+
}
|
|
120240
|
+
if (index > 1 && events[index - 2][1].type === types_types.linePrefix) {
|
|
120241
|
+
events[index][1].start = events[index - 2][1].start;
|
|
120242
|
+
events[index + 1][1].start = events[index - 2][1].start;
|
|
120243
|
+
events.splice(index - 2, 2);
|
|
120244
|
+
}
|
|
120245
|
+
return events;
|
|
120246
|
+
}
|
|
120247
|
+
const mdxComponentFlowConstruct = {
|
|
120248
|
+
name: 'mdxComponent',
|
|
120249
|
+
tokenize: createTokenize('flow'),
|
|
120250
|
+
resolveTo: resolveToMdxComponent,
|
|
120251
|
+
concrete: true,
|
|
120252
|
+
};
|
|
120253
|
+
const mdxComponentTextConstruct = {
|
|
120254
|
+
name: 'mdxComponentText',
|
|
120255
|
+
tokenize: createTokenize('text'),
|
|
120256
|
+
};
|
|
120257
|
+
/**
|
|
120258
|
+
* Factory for both flow (block) and text (inline) variants.
|
|
120259
|
+
*
|
|
120260
|
+
* **Flow** — the original behavior: claims PascalCase components (always) and
|
|
120261
|
+
* lowercase HTML tags that carry at least one `{…}` attribute expression.
|
|
120262
|
+
* Multi-line, concrete, `afterClose` consumes the rest of the line.
|
|
120263
|
+
*
|
|
120264
|
+
* **Text** — runs inside paragraphs / inline context. Claims lowercase tags and
|
|
120265
|
+
* inline PascalCase components (`INLINE_COMPONENT_TAGS` — Anchor, Glossary), both
|
|
120266
|
+
* gated on at least one `{…}` brace attribute. All other PascalCase stays
|
|
120267
|
+
* flow-only, matching how ReadMe's custom components are authored. Aborts on line
|
|
120268
|
+
* endings (inline constructs don't span lines) and exits immediately after
|
|
120269
|
+
* `</tag>` so the paragraph's inline parser picks up the trailing text.
|
|
120270
|
+
*/
|
|
120271
|
+
function createTokenize(mode) {
|
|
120272
|
+
const isFlow = mode === 'flow';
|
|
120273
|
+
return function tokenize(effects, ok, nok) {
|
|
120274
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
120275
|
+
const self = this;
|
|
120276
|
+
let tagName = '';
|
|
120277
|
+
let depth = 0;
|
|
120278
|
+
let closingTagName = '';
|
|
120279
|
+
// For lowercase tags we only want to claim the block if it uses JSX
|
|
120280
|
+
// attribute expression syntax (`attr={...}`). Plain HTML should fall
|
|
120281
|
+
// through to CommonMark html-flow. Flow mode claims any PascalCase block
|
|
120282
|
+
// component; text mode claims only inline PascalCase components
|
|
120283
|
+
// (INLINE_COMPONENT_TAGS — Anchor, Glossary), also brace-gated.
|
|
120284
|
+
let isLowercaseTag = false;
|
|
120285
|
+
let sawBraceAttr = false;
|
|
120286
|
+
// A plain lowercase block tag claimed without a `{…}` attribute, gated by
|
|
120287
|
+
// `plainClaimLineStart`: after a blank line it may only continue on a tag line.
|
|
120288
|
+
let isPlainBlockClaim = false;
|
|
120289
|
+
let pendingBlankLine = false;
|
|
120290
|
+
// Code span tracking
|
|
120291
|
+
let codeSpanOpenSize = 0;
|
|
120292
|
+
let codeSpanCloseSize = 0;
|
|
120293
|
+
// Fenced code block tracking
|
|
120294
|
+
let fenceChar = null;
|
|
120295
|
+
let fenceLength = 0;
|
|
120296
|
+
let fenceCloseLength = 0;
|
|
120297
|
+
let atLineStart = false;
|
|
120298
|
+
// True once this construct consumes any line ending; lets `afterClose`
|
|
120299
|
+
// treat only single-line lowercase tags as inline candidates.
|
|
120300
|
+
let sawLineEnding = false;
|
|
120301
|
+
// Bail when the opener line has unmatched tag-like tokens in its body.
|
|
120302
|
+
// `<Foo>_<Bar>.csv` leaves opens > closes; matched shapes like
|
|
120303
|
+
// `<Callout>x <strong>y</strong>` balance to 0. Without this,
|
|
120304
|
+
// `concrete: true` causes orphan openers to eat sibling blockquotes.
|
|
120305
|
+
let onOpenerLine = false;
|
|
120306
|
+
let openerLineHasContent = false;
|
|
120307
|
+
let openerLineOpens = 0;
|
|
120308
|
+
let openerLineCloses = 0;
|
|
120309
|
+
// Attribute parsing state
|
|
120310
|
+
let quoteChar = null;
|
|
120311
|
+
let braceDepth = 0;
|
|
120312
|
+
let inTemplateLit = false; // true when inside a template literal (for line continuation)
|
|
120313
|
+
// Stack of braceDepth values at each ${...} interpolation entry point.
|
|
120314
|
+
// When a } brings braceDepth back to a saved value, we return to the
|
|
120315
|
+
// template literal instead of continuing in the brace expression.
|
|
120316
|
+
const templateStack = [];
|
|
120317
|
+
const isAlpha = (code) => (code >= codes.uppercaseA && code <= codes.uppercaseZ) ||
|
|
120318
|
+
(code >= codes.lowercaseA && code <= codes.lowercaseZ);
|
|
120319
|
+
const isSameCaseAsTag = (code) => isLowercaseTag
|
|
120320
|
+
? code >= codes.lowercaseA && code <= codes.lowercaseZ
|
|
120321
|
+
: code >= codes.uppercaseA && code <= codes.uppercaseZ;
|
|
120322
|
+
// Shared brace-expression state machine. The two call sites differ only in where
|
|
120323
|
+
// to continue after a line ending and where to return when braceDepth reaches zero.
|
|
120324
|
+
function createBraceExprStates(continuationStart, afterBraceClose) {
|
|
120325
|
+
function braceExpr(code) {
|
|
120326
|
+
if (code === null)
|
|
120327
|
+
return nok(code);
|
|
120328
|
+
if (markdownLineEnding(code)) {
|
|
120329
|
+
if (!isFlow)
|
|
120330
|
+
return nok(code);
|
|
120331
|
+
effects.exit('mdxComponentData');
|
|
120332
|
+
return continuationStart(code);
|
|
120333
|
+
}
|
|
120334
|
+
if (code === codes.quotationMark || code === codes.apostrophe) {
|
|
120335
|
+
quoteChar = code;
|
|
120336
|
+
effects.consume(code);
|
|
120337
|
+
return braceString;
|
|
120338
|
+
}
|
|
120339
|
+
if (code === codes.graveAccent) {
|
|
120340
|
+
inTemplateLit = true;
|
|
120341
|
+
effects.consume(code);
|
|
120342
|
+
return braceTemplateLiteral;
|
|
120343
|
+
}
|
|
120344
|
+
if (code === codes.leftCurlyBrace) {
|
|
120345
|
+
braceDepth += 1;
|
|
120346
|
+
effects.consume(code);
|
|
120347
|
+
return braceExpr;
|
|
120348
|
+
}
|
|
120349
|
+
if (code === codes.rightCurlyBrace) {
|
|
120350
|
+
braceDepth -= 1;
|
|
120351
|
+
effects.consume(code);
|
|
120352
|
+
if (templateStack.length > 0 && braceDepth === templateStack[templateStack.length - 1]) {
|
|
120353
|
+
templateStack.pop();
|
|
120354
|
+
inTemplateLit = true;
|
|
120355
|
+
return braceTemplateLiteral;
|
|
120356
|
+
}
|
|
120357
|
+
if (braceDepth === 0) {
|
|
120358
|
+
return afterBraceClose;
|
|
120359
|
+
}
|
|
120360
|
+
return braceExpr;
|
|
120361
|
+
}
|
|
120362
|
+
effects.consume(code);
|
|
120363
|
+
return braceExpr;
|
|
120043
120364
|
}
|
|
120044
120365
|
function braceString(code) {
|
|
120045
120366
|
if (code === null)
|
|
@@ -120050,7 +120371,7 @@ function createTokenize(mode) {
|
|
|
120050
120371
|
effects.exit('mdxComponentData');
|
|
120051
120372
|
return continuationStart(code);
|
|
120052
120373
|
}
|
|
120053
|
-
if (code ===
|
|
120374
|
+
if (code === codes.backslash) {
|
|
120054
120375
|
effects.consume(code);
|
|
120055
120376
|
return braceStringEscape;
|
|
120056
120377
|
}
|
|
@@ -120078,16 +120399,16 @@ function createTokenize(mode) {
|
|
|
120078
120399
|
effects.exit('mdxComponentData');
|
|
120079
120400
|
return continuationStart(code);
|
|
120080
120401
|
}
|
|
120081
|
-
if (code ===
|
|
120402
|
+
if (code === codes.graveAccent) {
|
|
120082
120403
|
inTemplateLit = false;
|
|
120083
120404
|
effects.consume(code);
|
|
120084
120405
|
return braceExpr;
|
|
120085
120406
|
}
|
|
120086
|
-
if (code ===
|
|
120407
|
+
if (code === codes.backslash) {
|
|
120087
120408
|
effects.consume(code);
|
|
120088
120409
|
return braceTemplateLiteralEscape;
|
|
120089
120410
|
}
|
|
120090
|
-
if (code ===
|
|
120411
|
+
if (code === codes.dollarSign) {
|
|
120091
120412
|
effects.consume(code);
|
|
120092
120413
|
return braceTemplateLiteralDollar;
|
|
120093
120414
|
}
|
|
@@ -120102,7 +120423,7 @@ function createTokenize(mode) {
|
|
|
120102
120423
|
return braceTemplateLiteral;
|
|
120103
120424
|
}
|
|
120104
120425
|
function braceTemplateLiteralDollar(code) {
|
|
120105
|
-
if (code ===
|
|
120426
|
+
if (code === codes.leftCurlyBrace) {
|
|
120106
120427
|
templateStack.push(braceDepth);
|
|
120107
120428
|
braceDepth += 1;
|
|
120108
120429
|
inTemplateLit = false;
|
|
@@ -120118,7 +120439,7 @@ function createTokenize(mode) {
|
|
|
120118
120439
|
return start;
|
|
120119
120440
|
// ── Start ──────────────────────────────────────────────────────────────
|
|
120120
120441
|
function start(code) {
|
|
120121
|
-
if (code !==
|
|
120442
|
+
if (code !== codes.lessThan)
|
|
120122
120443
|
return nok(code);
|
|
120123
120444
|
effects.enter('mdxComponent');
|
|
120124
120445
|
effects.enter('mdxComponentData');
|
|
@@ -120130,7 +120451,7 @@ function createTokenize(mode) {
|
|
|
120130
120451
|
// Uppercase A-Z → PascalCase MDX component. Flow mode claims block
|
|
120131
120452
|
// components; text mode only claims inline components (Anchor, Glossary),
|
|
120132
120453
|
// which is enforced once the full name is known in `tagNameRest`.
|
|
120133
|
-
if (code !== null && code >=
|
|
120454
|
+
if (code !== null && code >= codes.uppercaseA && code <= codes.uppercaseZ) {
|
|
120134
120455
|
tagName = String.fromCharCode(code);
|
|
120135
120456
|
isLowercaseTag = false;
|
|
120136
120457
|
sawBraceAttr = false;
|
|
@@ -120140,7 +120461,7 @@ function createTokenize(mode) {
|
|
|
120140
120461
|
// Lowercase a-z → HTML tag (claim only if `{...}` attr appears). In
|
|
120141
120462
|
// flow mode, refuse to interrupt a paragraph — same rule as html-flow
|
|
120142
120463
|
// type-7. The text variant picks these up during inline parsing.
|
|
120143
|
-
if (code !== null && code >=
|
|
120464
|
+
if (code !== null && code >= codes.lowercaseA && code <= codes.lowercaseZ) {
|
|
120144
120465
|
if (isFlow && self.interrupt)
|
|
120145
120466
|
return nok(code);
|
|
120146
120467
|
tagName = String.fromCharCode(code);
|
|
@@ -120153,10 +120474,10 @@ function createTokenize(mode) {
|
|
|
120153
120474
|
}
|
|
120154
120475
|
function tagNameRest(code) {
|
|
120155
120476
|
if (code !== null &&
|
|
120156
|
-
((code >=
|
|
120157
|
-
(code >=
|
|
120158
|
-
(code >=
|
|
120159
|
-
code ===
|
|
120477
|
+
((code >= codes.uppercaseA && code <= codes.uppercaseZ) ||
|
|
120478
|
+
(code >= codes.lowercaseA && code <= codes.lowercaseZ) ||
|
|
120479
|
+
(code >= codes.digit0 && code <= codes.digit9) ||
|
|
120480
|
+
code === codes.underscore)) {
|
|
120160
120481
|
tagName += String.fromCharCode(code);
|
|
120161
120482
|
effects.consume(code);
|
|
120162
120483
|
return tagNameRest;
|
|
@@ -120191,14 +120512,14 @@ function createTokenize(mode) {
|
|
|
120191
120512
|
return openTagContinuationStart(code);
|
|
120192
120513
|
}
|
|
120193
120514
|
// Self-closing />
|
|
120194
|
-
if (code ===
|
|
120515
|
+
if (code === codes.slash) {
|
|
120195
120516
|
if (requiresBraceAttr && !sawBraceAttr)
|
|
120196
120517
|
return nok(code);
|
|
120197
120518
|
effects.consume(code);
|
|
120198
120519
|
return selfCloseGt;
|
|
120199
120520
|
}
|
|
120200
120521
|
// End of opening tag
|
|
120201
|
-
if (code ===
|
|
120522
|
+
if (code === codes.greaterThan) {
|
|
120202
120523
|
if (requiresBraceAttr && !sawBraceAttr) {
|
|
120203
120524
|
// Plain lowercase block tags stay claimable in flow, gated per line by
|
|
120204
120525
|
// `plainClaimLineStart`; everything else falls through to CommonMark.
|
|
@@ -120211,13 +120532,13 @@ function createTokenize(mode) {
|
|
|
120211
120532
|
return body;
|
|
120212
120533
|
}
|
|
120213
120534
|
// Quoted attribute value
|
|
120214
|
-
if (code ===
|
|
120535
|
+
if (code === codes.quotationMark || code === codes.apostrophe) {
|
|
120215
120536
|
quoteChar = code;
|
|
120216
120537
|
effects.consume(code);
|
|
120217
120538
|
return inQuotedAttr;
|
|
120218
120539
|
}
|
|
120219
120540
|
// JSX expression attribute
|
|
120220
|
-
if (code ===
|
|
120541
|
+
if (code === codes.leftCurlyBrace) {
|
|
120221
120542
|
braceDepth = 1;
|
|
120222
120543
|
sawBraceAttr = true;
|
|
120223
120544
|
effects.consume(code);
|
|
@@ -120235,7 +120556,7 @@ function createTokenize(mode) {
|
|
|
120235
120556
|
effects.exit('mdxComponentData');
|
|
120236
120557
|
return openTagContinuationStart(code);
|
|
120237
120558
|
}
|
|
120238
|
-
if (code ===
|
|
120559
|
+
if (code === codes.backslash) {
|
|
120239
120560
|
effects.consume(code);
|
|
120240
120561
|
return inQuotedAttrEscape;
|
|
120241
120562
|
}
|
|
@@ -120255,7 +120576,7 @@ function createTokenize(mode) {
|
|
|
120255
120576
|
return inQuotedAttr;
|
|
120256
120577
|
}
|
|
120257
120578
|
function selfCloseGt(code) {
|
|
120258
|
-
if (code ===
|
|
120579
|
+
if (code === codes.greaterThan) {
|
|
120259
120580
|
effects.consume(code);
|
|
120260
120581
|
// Self-closing tag completes the token
|
|
120261
120582
|
return afterClose;
|
|
@@ -120265,7 +120586,7 @@ function createTokenize(mode) {
|
|
|
120265
120586
|
}
|
|
120266
120587
|
// Continuation for multi-line opening tags
|
|
120267
120588
|
function openTagContinuationStart(code) {
|
|
120268
|
-
return effects.check(
|
|
120589
|
+
return effects.check(mdx_component_syntax_nonLazyContinuationStart, openTagContinuationNonLazy, continuationAfter)(code);
|
|
120269
120590
|
}
|
|
120270
120591
|
function openTagContinuationNonLazy(code) {
|
|
120271
120592
|
sawLineEnding = true;
|
|
@@ -120308,25 +120629,25 @@ function createTokenize(mode) {
|
|
|
120308
120629
|
atLineStart = true;
|
|
120309
120630
|
return bodyContinuationStart(code);
|
|
120310
120631
|
}
|
|
120311
|
-
if (code !==
|
|
120632
|
+
if (code !== codes.space && code !== codes.horizontalTab) {
|
|
120312
120633
|
openerLineHasContent = true;
|
|
120313
120634
|
}
|
|
120314
|
-
if (code ===
|
|
120635
|
+
if (code === codes.backslash) {
|
|
120315
120636
|
effects.consume(code);
|
|
120316
120637
|
return bodyEscapedChar;
|
|
120317
120638
|
}
|
|
120318
|
-
if (code ===
|
|
120639
|
+
if (code === codes.lessThan) {
|
|
120319
120640
|
effects.consume(code);
|
|
120320
120641
|
return bodyLessThan;
|
|
120321
120642
|
}
|
|
120322
120643
|
// Code span tracking
|
|
120323
|
-
if (code ===
|
|
120644
|
+
if (code === codes.graveAccent) {
|
|
120324
120645
|
codeSpanOpenSize = 0;
|
|
120325
120646
|
return countOpenTicks(code);
|
|
120326
120647
|
}
|
|
120327
120648
|
// JSX expression child — track braces/template literals so the closing
|
|
120328
120649
|
// backtick of `{`...`}` is not misread as a code span opener
|
|
120329
|
-
if (code ===
|
|
120650
|
+
if (code === codes.leftCurlyBrace) {
|
|
120330
120651
|
braceDepth = 1;
|
|
120331
120652
|
inTemplateLit = false;
|
|
120332
120653
|
effects.consume(code);
|
|
@@ -120346,14 +120667,14 @@ function createTokenize(mode) {
|
|
|
120346
120667
|
}
|
|
120347
120668
|
// ── Code span handling ─────────────────────────────────────────────────
|
|
120348
120669
|
function countOpenTicks(code) {
|
|
120349
|
-
if (code ===
|
|
120670
|
+
if (code === codes.graveAccent) {
|
|
120350
120671
|
codeSpanOpenSize += 1;
|
|
120351
120672
|
effects.consume(code);
|
|
120352
120673
|
return countOpenTicks;
|
|
120353
120674
|
}
|
|
120354
120675
|
// 3+ backticks at line start = fenced code block
|
|
120355
120676
|
if (atLineStart && codeSpanOpenSize >= 3) {
|
|
120356
|
-
fenceChar =
|
|
120677
|
+
fenceChar = codes.graveAccent;
|
|
120357
120678
|
fenceLength = codeSpanOpenSize;
|
|
120358
120679
|
atLineStart = false;
|
|
120359
120680
|
return inFencedCode(code);
|
|
@@ -120363,7 +120684,7 @@ function createTokenize(mode) {
|
|
|
120363
120684
|
function inCodeSpan(code) {
|
|
120364
120685
|
if (code === null || markdownLineEnding(code))
|
|
120365
120686
|
return body(code);
|
|
120366
|
-
if (code ===
|
|
120687
|
+
if (code === codes.graveAccent) {
|
|
120367
120688
|
codeSpanCloseSize = 0;
|
|
120368
120689
|
return countCloseTicks(code);
|
|
120369
120690
|
}
|
|
@@ -120371,7 +120692,7 @@ function createTokenize(mode) {
|
|
|
120371
120692
|
return inCodeSpan;
|
|
120372
120693
|
}
|
|
120373
120694
|
function countCloseTicks(code) {
|
|
120374
|
-
if (code ===
|
|
120695
|
+
if (code === codes.graveAccent) {
|
|
120375
120696
|
codeSpanCloseSize += 1;
|
|
120376
120697
|
effects.consume(code);
|
|
120377
120698
|
return countCloseTicks;
|
|
@@ -120390,7 +120711,7 @@ function createTokenize(mode) {
|
|
|
120390
120711
|
return inFencedCode;
|
|
120391
120712
|
}
|
|
120392
120713
|
function fencedCodeContinuationStart(code) {
|
|
120393
|
-
return effects.check(
|
|
120714
|
+
return effects.check(mdx_component_syntax_nonLazyContinuationStart, fencedCodeContinuationNonLazy, continuationAfter)(code);
|
|
120394
120715
|
}
|
|
120395
120716
|
function fencedCodeContinuationNonLazy(code) {
|
|
120396
120717
|
sawLineEnding = true;
|
|
@@ -120405,6 +120726,16 @@ function createTokenize(mode) {
|
|
|
120405
120726
|
}
|
|
120406
120727
|
effects.enter('mdxComponentData');
|
|
120407
120728
|
fenceCloseLength = 0;
|
|
120729
|
+
return fencedCodeMaybeClose(code);
|
|
120730
|
+
}
|
|
120731
|
+
// Skip leading indentation before the closing-fence check: an indented fence
|
|
120732
|
+
// (the norm in a component body) closes on an equally-indented line, else the
|
|
120733
|
+
// closer is never matched and scanning runs to EOF (CX-3704).
|
|
120734
|
+
function fencedCodeMaybeClose(code) {
|
|
120735
|
+
if (markdownSpace(code)) {
|
|
120736
|
+
effects.consume(code);
|
|
120737
|
+
return fencedCodeMaybeClose;
|
|
120738
|
+
}
|
|
120408
120739
|
// Check for closing fence
|
|
120409
120740
|
if (code === fenceChar) {
|
|
120410
120741
|
fenceCloseLength = 1;
|
|
@@ -120434,7 +120765,7 @@ function createTokenize(mode) {
|
|
|
120434
120765
|
return body(code);
|
|
120435
120766
|
}
|
|
120436
120767
|
// Only spaces/tabs allowed after closing fence
|
|
120437
|
-
if (code ===
|
|
120768
|
+
if (code === codes.space || code === codes.horizontalTab) {
|
|
120438
120769
|
effects.consume(code);
|
|
120439
120770
|
return fenceCloseTrailing;
|
|
120440
120771
|
}
|
|
@@ -120443,7 +120774,7 @@ function createTokenize(mode) {
|
|
|
120443
120774
|
}
|
|
120444
120775
|
// ── Tilde fenced code detection ────────────────────────────────────────
|
|
120445
120776
|
function bodyAfterLineStart(code) {
|
|
120446
|
-
if (code ===
|
|
120777
|
+
if (code === codes.tilde) {
|
|
120447
120778
|
fenceCloseLength = 1;
|
|
120448
120779
|
effects.consume(code);
|
|
120449
120780
|
return countTildes;
|
|
@@ -120452,13 +120783,13 @@ function createTokenize(mode) {
|
|
|
120452
120783
|
return body(code);
|
|
120453
120784
|
}
|
|
120454
120785
|
function countTildes(code) {
|
|
120455
|
-
if (code ===
|
|
120786
|
+
if (code === codes.tilde) {
|
|
120456
120787
|
fenceCloseLength += 1;
|
|
120457
120788
|
effects.consume(code);
|
|
120458
120789
|
return countTildes;
|
|
120459
120790
|
}
|
|
120460
120791
|
if (fenceCloseLength >= 3) {
|
|
120461
|
-
fenceChar =
|
|
120792
|
+
fenceChar = codes.tilde;
|
|
120462
120793
|
fenceLength = fenceCloseLength;
|
|
120463
120794
|
return inFencedCode(code);
|
|
120464
120795
|
}
|
|
@@ -120468,7 +120799,7 @@ function createTokenize(mode) {
|
|
|
120468
120799
|
}
|
|
120469
120800
|
// ── Tag detection inside body ──────────────────────────────────────────
|
|
120470
120801
|
function bodyLessThan(code) {
|
|
120471
|
-
if (code ===
|
|
120802
|
+
if (code === codes.slash) {
|
|
120472
120803
|
if (onOpenerLine)
|
|
120473
120804
|
openerLineCloses += 1;
|
|
120474
120805
|
effects.consume(code);
|
|
@@ -120495,10 +120826,10 @@ function createTokenize(mode) {
|
|
|
120495
120826
|
// ── Nested opening tag ─────────────────────────────────────────────────
|
|
120496
120827
|
function nestedOpenTagName(code) {
|
|
120497
120828
|
if (code !== null &&
|
|
120498
|
-
((code >=
|
|
120499
|
-
(code >=
|
|
120500
|
-
(code >=
|
|
120501
|
-
code ===
|
|
120829
|
+
((code >= codes.uppercaseA && code <= codes.uppercaseZ) ||
|
|
120830
|
+
(code >= codes.lowercaseA && code <= codes.lowercaseZ) ||
|
|
120831
|
+
(code >= codes.digit0 && code <= codes.digit9) ||
|
|
120832
|
+
code === codes.underscore)) {
|
|
120502
120833
|
closingTagName += String.fromCharCode(code);
|
|
120503
120834
|
effects.consume(code);
|
|
120504
120835
|
return nestedOpenTagName;
|
|
@@ -120506,10 +120837,10 @@ function createTokenize(mode) {
|
|
|
120506
120837
|
// Same-name opener followed by a tag-end char bumps depth. A line ending
|
|
120507
120838
|
// counts too: Prettier puts a newline right after the name (`<div\n …\n>`).
|
|
120508
120839
|
if (closingTagName === tagName &&
|
|
120509
|
-
(code ===
|
|
120510
|
-
code ===
|
|
120511
|
-
code ===
|
|
120512
|
-
code ===
|
|
120840
|
+
(code === codes.greaterThan ||
|
|
120841
|
+
code === codes.slash ||
|
|
120842
|
+
code === codes.space ||
|
|
120843
|
+
code === codes.horizontalTab ||
|
|
120513
120844
|
markdownLineEnding(code))) {
|
|
120514
120845
|
depth += 1;
|
|
120515
120846
|
}
|
|
@@ -120528,15 +120859,15 @@ function createTokenize(mode) {
|
|
|
120528
120859
|
}
|
|
120529
120860
|
function closingTagNameRest(code) {
|
|
120530
120861
|
if (code !== null &&
|
|
120531
|
-
((code >=
|
|
120532
|
-
(code >=
|
|
120533
|
-
(code >=
|
|
120534
|
-
code ===
|
|
120862
|
+
((code >= codes.uppercaseA && code <= codes.uppercaseZ) ||
|
|
120863
|
+
(code >= codes.lowercaseA && code <= codes.lowercaseZ) ||
|
|
120864
|
+
(code >= codes.digit0 && code <= codes.digit9) ||
|
|
120865
|
+
code === codes.underscore)) {
|
|
120535
120866
|
closingTagName += String.fromCharCode(code);
|
|
120536
120867
|
effects.consume(code);
|
|
120537
120868
|
return closingTagNameRest;
|
|
120538
120869
|
}
|
|
120539
|
-
if (closingTagName === tagName && code ===
|
|
120870
|
+
if (closingTagName === tagName && code === codes.greaterThan) {
|
|
120540
120871
|
depth -= 1;
|
|
120541
120872
|
effects.consume(code);
|
|
120542
120873
|
if (depth === 0) {
|
|
@@ -120588,7 +120919,7 @@ function createTokenize(mode) {
|
|
|
120588
120919
|
}
|
|
120589
120920
|
// ── Body continuation (line endings) ───────────────────────────────────
|
|
120590
120921
|
function bodyContinuationStart(code) {
|
|
120591
|
-
return effects.check(
|
|
120922
|
+
return effects.check(mdx_component_syntax_nonLazyContinuationStart, bodyContinuationNonLazy, continuationAfter)(code);
|
|
120592
120923
|
}
|
|
120593
120924
|
function bodyContinuationNonLazy(code) {
|
|
120594
120925
|
sawLineEnding = true;
|
|
@@ -120620,9 +120951,16 @@ function createTokenize(mode) {
|
|
|
120620
120951
|
}
|
|
120621
120952
|
// Dispatch a non-blank continuation line: fenced code at line start, else body.
|
|
120622
120953
|
function bodyLineStart(code) {
|
|
120623
|
-
|
|
120954
|
+
// Skip leading indentation while staying "at line start" so an indented
|
|
120955
|
+
// fence is still recognized. Otherwise the first space clears `atLineStart`
|
|
120956
|
+
// and its content — including any unbalanced `{` — stays live text (CX-3704).
|
|
120957
|
+
if (atLineStart && markdownSpace(code)) {
|
|
120958
|
+
effects.consume(code);
|
|
120959
|
+
return bodyLineStart;
|
|
120960
|
+
}
|
|
120961
|
+
if (atLineStart && code === codes.tilde)
|
|
120624
120962
|
return bodyAfterLineStart(code);
|
|
120625
|
-
if (atLineStart && code ===
|
|
120963
|
+
if (atLineStart && code === codes.graveAccent) {
|
|
120626
120964
|
codeSpanOpenSize = 0;
|
|
120627
120965
|
// Leave `atLineStart` set — `countOpenTicks` needs it to tell a fence from an
|
|
120628
120966
|
// inline code span once the run of backticks is fully counted; it's cleared once
|
|
@@ -120637,7 +120975,7 @@ function createTokenize(mode) {
|
|
|
120637
120975
|
// fence) refuses so CommonMark html-flow reparses it exactly as it does today.
|
|
120638
120976
|
function plainClaimLineStart(code) {
|
|
120639
120977
|
// Leading whitespace only → treat as a blank line, matching CommonMark.
|
|
120640
|
-
if (code ===
|
|
120978
|
+
if (code === codes.space || code === codes.horizontalTab) {
|
|
120641
120979
|
effects.consume(code);
|
|
120642
120980
|
return plainClaimLineStart;
|
|
120643
120981
|
}
|
|
@@ -120650,7 +120988,7 @@ function createTokenize(mode) {
|
|
|
120650
120988
|
// paragraph that merely starts with a tag must fall back so its markdown
|
|
120651
120989
|
// parses and rehype-raw re-nests it into the wrapper.
|
|
120652
120990
|
if (pendingBlankLine) {
|
|
120653
|
-
if (code !==
|
|
120991
|
+
if (code !== codes.lessThan)
|
|
120654
120992
|
return nok(code);
|
|
120655
120993
|
return effects.check(markupOnlyContinuation, plainClaimContinue, nok)(code);
|
|
120656
120994
|
}
|
|
@@ -120670,7 +121008,7 @@ function createTokenize(mode) {
|
|
|
120670
121008
|
}
|
|
120671
121009
|
};
|
|
120672
121010
|
}
|
|
120673
|
-
function
|
|
121011
|
+
function mdx_component_syntax_tokenizeNonLazyContinuationStart(effects, ok, nok) {
|
|
120674
121012
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
120675
121013
|
const self = this;
|
|
120676
121014
|
return start;
|
|
@@ -120703,7 +121041,7 @@ function tokenizeMarkupOnlyContinuation(effects, ok, nok) {
|
|
|
120703
121041
|
return afterLessThan;
|
|
120704
121042
|
}
|
|
120705
121043
|
function afterLessThan(code) {
|
|
120706
|
-
if (code ===
|
|
121044
|
+
if (code === codes.slash) {
|
|
120707
121045
|
effects.consume(code);
|
|
120708
121046
|
return afterSlash;
|
|
120709
121047
|
}
|
|
@@ -120722,7 +121060,7 @@ function tokenizeMarkupOnlyContinuation(effects, ok, nok) {
|
|
|
120722
121060
|
function scanToLineEnd(code) {
|
|
120723
121061
|
if (code === null || markdownLineEnding(code)) {
|
|
120724
121062
|
effects.exit(types_types.data);
|
|
120725
|
-
return lastNonSpace ===
|
|
121063
|
+
return lastNonSpace === codes.greaterThan ? ok(code) : nok(code);
|
|
120726
121064
|
}
|
|
120727
121065
|
if (!markdownSpace(code))
|
|
120728
121066
|
lastNonSpace = code;
|
|
@@ -120755,8 +121093,8 @@ function tokenizeMarkupOnlyContinuation(effects, ok, nok) {
|
|
|
120755
121093
|
*/
|
|
120756
121094
|
function syntax_mdxComponent() {
|
|
120757
121095
|
return {
|
|
120758
|
-
flow: { [
|
|
120759
|
-
text: { [
|
|
121096
|
+
flow: { [codes.lessThan]: [mdxComponentFlowConstruct] },
|
|
121097
|
+
text: { [codes.lessThan]: [mdxComponentTextConstruct] },
|
|
120760
121098
|
};
|
|
120761
121099
|
}
|
|
120762
121100
|
|
|
@@ -120778,9 +121116,20 @@ function syntax_mdxComponent() {
|
|
|
120778
121116
|
|
|
120779
121117
|
|
|
120780
121118
|
|
|
121119
|
+
|
|
121120
|
+
|
|
121121
|
+
|
|
121122
|
+
|
|
121123
|
+
|
|
121124
|
+
|
|
120781
121125
|
const buildInlineMdProcessor = (safeMode) => {
|
|
120782
|
-
|
|
121126
|
+
// `jsxTable` must be present so a `<Table>`/`<table>` nested in a component
|
|
121127
|
+
// body (e.g. a `<Callout>`) is captured as one html node. Without it, blank
|
|
121128
|
+
// lines between rows let CommonMark HTML block type 6 fragment the table and
|
|
121129
|
+
// its rows spill out as text / indented code blocks (CX-3705).
|
|
121130
|
+
const micromarkExts = [syntax_jsxTable(), syntax_mdxComponent(), syntax_gemoji(), legacyVariable(), syntax_magicBlock()];
|
|
120783
121131
|
const fromMarkdownExts = [
|
|
121132
|
+
jsx_table_jsxTableFromMarkdown(),
|
|
120784
121133
|
mdx_component_mdxComponentFromMarkdown(),
|
|
120785
121134
|
gemojiFromMarkdown(),
|
|
120786
121135
|
legacyVariableFromMarkdown(),
|
|
@@ -120840,6 +121189,65 @@ const toMdxJsxTextElement = (name, attributes, children, position) => ({
|
|
|
120840
121189
|
children,
|
|
120841
121190
|
...(position ? { position } : {}),
|
|
120842
121191
|
});
|
|
121192
|
+
// Raw-body tags (pre/script/style/textarea) must stay byte-exact; table
|
|
121193
|
+
// structure (`table` + `tableTags`) is owned by `mdxishTables` and figures by
|
|
121194
|
+
// `mdxishJsxToMdast`, both of which run later on raw html nodes.
|
|
121195
|
+
const NON_PROMOTABLE_PLAIN_TAGS = new Set([...htmlRawNames, ...tableTags, 'table', 'figure', 'figcaption']);
|
|
121196
|
+
const NESTED_TABLE_RE = /<table[\s>]/i;
|
|
121197
|
+
const isMarkdownPromotableHtmlTag = (tag) => !NON_PROMOTABLE_PLAIN_TAGS.has(tag);
|
|
121198
|
+
// Expression nodes count as plain so `<div>{1+1}</div>` keeps its current
|
|
121199
|
+
// literal-brace behavior; variables/glossary already resolve inside raw html.
|
|
121200
|
+
const PLAIN_CONTENT_TYPES = new Set([
|
|
121201
|
+
'paragraph',
|
|
121202
|
+
'text',
|
|
121203
|
+
'html',
|
|
121204
|
+
'mdxTextExpression',
|
|
121205
|
+
'mdxFlowExpression',
|
|
121206
|
+
enums_NodeTypes.variable,
|
|
121207
|
+
enums_NodeTypes.glossary,
|
|
121208
|
+
]);
|
|
121209
|
+
// Promoting plain HTML is only worth bypassing rehype-raw's parse5 pass when
|
|
121210
|
+
// the body parses into an actual markdown construct.
|
|
121211
|
+
const containsMarkdownConstruct = (nodes) => nodes.some(node => !PLAIN_CONTENT_TYPES.has(node.type) ||
|
|
121212
|
+
('children' in node && Array.isArray(node.children) && containsMarkdownConstruct(node.children)));
|
|
121213
|
+
/**
|
|
121214
|
+
* Index of the `</tag>` that balances the already-consumed opening tag (the
|
|
121215
|
+
* caller starts us one level deep). `lastIndexOf` mis-slices sibling same-tag
|
|
121216
|
+
* pairs like `<div>**a**</div><div>**b**</div>`, so we depth-match instead —
|
|
121217
|
+
* delegating to `walkTags` (htmlparser2) so quoted attributes (`title="</div>"`),
|
|
121218
|
+
* code spans, and legacy `<<VARIABLE>>` are handled for free. Returns -1 when
|
|
121219
|
+
* the wrapper is left open.
|
|
121220
|
+
*/
|
|
121221
|
+
function findBalancedClosingTagIndex(content, tag) {
|
|
121222
|
+
const target = tag.toLowerCase();
|
|
121223
|
+
const canonicalCloserLength = tag.length + 3; // `</tag>`
|
|
121224
|
+
// The caller already stripped the opening tag, so re-attach one: htmlparser2
|
|
121225
|
+
// drops an unmatched closer, and we want it balanced. Offsets shift by the
|
|
121226
|
+
// prefix length.
|
|
121227
|
+
const prefix = `<${tag}>`;
|
|
121228
|
+
let depth = 0;
|
|
121229
|
+
let closeIndex = -1;
|
|
121230
|
+
walkTags(prefix + content, {
|
|
121231
|
+
onOpen: ({ name, isSelfClosing, isStrayCloser }) => {
|
|
121232
|
+
if (closeIndex >= 0 || isSelfClosing || isStrayCloser)
|
|
121233
|
+
return;
|
|
121234
|
+
if (name.toLowerCase() === target)
|
|
121235
|
+
depth += 1;
|
|
121236
|
+
},
|
|
121237
|
+
onClose: ({ name, start, end, implicit }) => {
|
|
121238
|
+
if (closeIndex >= 0 || implicit || name.toLowerCase() !== target)
|
|
121239
|
+
return;
|
|
121240
|
+
// Only canonical `</tag>` closers — the caller slices by that length, so a
|
|
121241
|
+
// whitespaced `</tag >` would misalign; leaving it unmatched keeps it raw.
|
|
121242
|
+
if (end - start !== canonicalCloserLength)
|
|
121243
|
+
return;
|
|
121244
|
+
depth -= 1;
|
|
121245
|
+
if (depth === 0)
|
|
121246
|
+
closeIndex = start - prefix.length;
|
|
121247
|
+
},
|
|
121248
|
+
});
|
|
121249
|
+
return closeIndex;
|
|
121250
|
+
}
|
|
120843
121251
|
|
|
120844
121252
|
;// ./processor/transform/mdxish/components/inline-html.ts
|
|
120845
121253
|
|
|
@@ -120971,70 +121379,168 @@ const mdxishInlineMdxComponents = () => tree => {
|
|
|
120971
121379
|
};
|
|
120972
121380
|
/* harmony default export */ const inline_mdx_blocks = (mdxishInlineMdxComponents);
|
|
120973
121381
|
|
|
121382
|
+
;// ./processor/transform/mdxish/terminate-html-flow-blocks.ts
|
|
121383
|
+
|
|
121384
|
+
|
|
121385
|
+
|
|
121386
|
+
const STANDALONE_HTML_LINE_REGEX = /^(<[a-z][^<>]*>|<\/[a-z][^<>]*>)+\s*$/;
|
|
121387
|
+
const HTML_LINE_WITH_CONTENT_REGEX = /^<[a-z][^<>]*>.*<\/[a-z][^<>]*>(?:[^<]*)$/;
|
|
121388
|
+
// A line that is exactly one lowercase opening (or self-closing) tag — the shape
|
|
121389
|
+
// that opens a CommonMark type-6/7 HTML block and swallows the lines below it.
|
|
121390
|
+
const SINGLE_OPENING_TAG_REGEX = /^<[a-z][^<>]*>$/;
|
|
121391
|
+
// Tags whose contents must be preserved as is, inserting a blank line after the
|
|
121392
|
+
// opener corrupts the payload.
|
|
121393
|
+
// htmlRawNames here refer to <pre>, <textarea>, <script>, <style>
|
|
121394
|
+
const RAW_CONTENT_TAGS = [...htmlRawNames, ...HTML_TABLE_STRUCTURE_TAGS];
|
|
121395
|
+
// The `(?=[\s/>])` lookahead avoids false matches on lookalike names like `<script-foo>`.
|
|
121396
|
+
const RAW_CONTENT_TAG_MATCHERS = RAW_CONTENT_TAGS.map(tag => ({
|
|
121397
|
+
open: new RegExp(`<${tag}(?=[\\s/>])[^>]*?(?<!/)>`, 'gi'),
|
|
121398
|
+
close: new RegExp(`</${tag}(?=[\\s>])[^>]*>`, 'gi'),
|
|
121399
|
+
}));
|
|
121400
|
+
function isLineHtml(line) {
|
|
121401
|
+
return STANDALONE_HTML_LINE_REGEX.test(line) || HTML_LINE_WITH_CONTENT_REGEX.test(line);
|
|
121402
|
+
}
|
|
121403
|
+
// Per-tag {opens, closes} counts of RAW_CONTENT_TAGS on one line — feeds both the
|
|
121404
|
+
// per-line net-open check and the cumulative still-open depth tracking.
|
|
121405
|
+
function countRawContentTags(line) {
|
|
121406
|
+
return RAW_CONTENT_TAG_MATCHERS.map(({ open, close }) => ({
|
|
121407
|
+
opens: (line.match(open) ?? []).length,
|
|
121408
|
+
closes: (line.match(close) ?? []).length,
|
|
121409
|
+
}));
|
|
121410
|
+
}
|
|
121411
|
+
// Indentation width in columns, counting a tab as 4 per CommonMark.
|
|
121412
|
+
function indentWidth(line) {
|
|
121413
|
+
const leading = line.match(/^[ \t]*/)?.[0] ?? '';
|
|
121414
|
+
return leading.replace(/\t/g, ' ').length;
|
|
121415
|
+
}
|
|
121416
|
+
/**
|
|
121417
|
+
* Decides whether a blank line belongs between `line` and `next` so the HTML
|
|
121418
|
+
* flow block opened on `line` terminates and `next` parses as markdown.
|
|
121419
|
+
*/
|
|
121420
|
+
function shouldTerminateBetween(line, next, { insideRawContent, lineLeavesRawOpen }) {
|
|
121421
|
+
if (next.trim().length === 0)
|
|
121422
|
+
return false;
|
|
121423
|
+
const currentIndent = indentWidth(line);
|
|
121424
|
+
const nextIndent = indentWidth(next);
|
|
121425
|
+
// 4+ columns is CommonMark indented-code territory: an inserted blank line
|
|
121426
|
+
// would turn the next line into a code block instead of freeing it (#1344).
|
|
121427
|
+
if (currentIndent > 3 || nextIndent > 3)
|
|
121428
|
+
return false;
|
|
121429
|
+
const currentTrimmed = line.trim();
|
|
121430
|
+
const nextTrimmed = next.trim();
|
|
121431
|
+
if (!isLineHtml(currentTrimmed) || isLineHtml(nextTrimmed) || lineLeavesRawOpen) {
|
|
121432
|
+
return false;
|
|
121433
|
+
}
|
|
121434
|
+
// Column-0 pairs keep the original (pre-relaxation) rule, deliberately ignoring
|
|
121435
|
+
// `insideRawContent`: one unclosed <pre>/<table> typo would otherwise suppress
|
|
121436
|
+
// termination for the whole rest of the document.
|
|
121437
|
+
if (currentIndent === 0 && nextIndent === 0)
|
|
121438
|
+
return true;
|
|
121439
|
+
// Indented shapes (either line at 1–3 columns) are stricter: only a lone opening
|
|
121440
|
+
// tag followed by markdown. A next line opening a tag or expression must stay
|
|
121441
|
+
// glued for the mdxComponent tokenizer; raw-content payloads stay byte-exact.
|
|
121442
|
+
return (!insideRawContent &&
|
|
121443
|
+
SINGLE_OPENING_TAG_REGEX.test(currentTrimmed) &&
|
|
121444
|
+
!nextTrimmed.startsWith('<') &&
|
|
121445
|
+
!nextTrimmed.startsWith('{'));
|
|
121446
|
+
}
|
|
121447
|
+
/**
|
|
121448
|
+
* CommonMark HTML blocks (types 6/7) end only at a blank line, so markdown on the
|
|
121449
|
+
* next line is swallowed as HTML (`## heading` after `<div>` renders as literal text).
|
|
121450
|
+
* Inserts the missing blank line; the gating rules live in `shouldTerminateBetween`.
|
|
121451
|
+
*
|
|
121452
|
+
* @link https://spec.commonmark.org/0.29/#html-blocks
|
|
121453
|
+
*/
|
|
121454
|
+
function terminateHtmlFlowBlocks(content) {
|
|
121455
|
+
const { protectedContent, protectedCode } = protectCodeBlocks(content);
|
|
121456
|
+
const lines = protectedContent.split('\n');
|
|
121457
|
+
const result = [];
|
|
121458
|
+
// Per-tag count of still-open raw-content elements at the current boundary.
|
|
121459
|
+
const rawContentDepths = RAW_CONTENT_TAG_MATCHERS.map(() => 0);
|
|
121460
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
121461
|
+
const line = lines[i];
|
|
121462
|
+
result.push(line);
|
|
121463
|
+
const tagCounts = countRawContentTags(line);
|
|
121464
|
+
tagCounts.forEach(({ opens, closes }, tagIndex) => {
|
|
121465
|
+
rawContentDepths[tagIndex] = Math.max(0, rawContentDepths[tagIndex] + opens - closes);
|
|
121466
|
+
});
|
|
121467
|
+
const next = lines[i + 1];
|
|
121468
|
+
const rawContentFacts = {
|
|
121469
|
+
insideRawContent: rawContentDepths.some(depth => depth > 0),
|
|
121470
|
+
lineLeavesRawOpen: tagCounts.some(({ opens, closes }) => opens > closes),
|
|
121471
|
+
};
|
|
121472
|
+
if (next !== undefined && shouldTerminateBetween(line, next, rawContentFacts)) {
|
|
121473
|
+
result.push('');
|
|
121474
|
+
}
|
|
121475
|
+
}
|
|
121476
|
+
return restoreCodeBlocks(result.join('\n'), protectedCode);
|
|
121477
|
+
}
|
|
121478
|
+
|
|
120974
121479
|
;// ./processor/transform/mdxish/components/mdx-blocks.ts
|
|
120975
121480
|
|
|
120976
121481
|
|
|
120977
121482
|
|
|
120978
121483
|
|
|
120979
121484
|
|
|
120980
|
-
|
|
121485
|
+
|
|
121486
|
+
|
|
121487
|
+
// Matches a JSX attribute expression (e.g. `key={i}`) anywhere in a string. */
|
|
120981
121488
|
const NESTED_ATTR_EXPRESSION_RE = /[\w-]+\s*=\s*\{/;
|
|
120982
|
-
|
|
120983
|
-
|
|
120984
|
-
|
|
120985
|
-
|
|
120986
|
-
|
|
121489
|
+
// Name shape mirrors `componentTagPattern`; the lookbehind skips the inner tag
|
|
121490
|
+
// of a legacy `<<VARIABLE>>`.
|
|
121491
|
+
const NESTED_COMPONENT_TAG_RE = /(?<!<)<([A-Z][A-Za-z0-9_]*)[\s/>]/g;
|
|
121492
|
+
// Excludes tags with dedicated transformers (`Table`, `HTMLBlock`, inline
|
|
121493
|
+
// components), which expect their wrapper to stay raw.
|
|
121494
|
+
const hasNestedGenericComponentTag = (content) => [...content.matchAll(NESTED_COMPONENT_TAG_RE)].some(match => !GENERIC_MDX_COMPONENT_EXCLUDED_TAGS.has(match[1]));
|
|
121495
|
+
/**
|
|
121496
|
+
* Strip the shared leading indentation from a component body so readability indentation
|
|
121497
|
+
* isn't parsed as indented code (4+ spaces), e.g. ` <p>` / ` text` -> `<p>` / ` text`.
|
|
121498
|
+
* Relative indentation is kept, so content genuinely 4+ columns deeper stays code. We
|
|
121499
|
+
* only strip when a line actually reaches 4 columns; otherwise the body is left as-is so
|
|
121500
|
+
* its leading whitespace survives as text nodes (mixed component + HTML content needs it).
|
|
120987
121501
|
*/
|
|
120988
121502
|
function safeDeindent(text) {
|
|
120989
121503
|
const lines = text.split('\n');
|
|
120990
121504
|
const nonEmptyLines = lines.filter(line => line.trim().length > 0);
|
|
120991
121505
|
if (nonEmptyLines.length === 0)
|
|
120992
121506
|
return text;
|
|
120993
|
-
|
|
120994
|
-
|
|
120995
|
-
|
|
120996
|
-
|
|
120997
|
-
|
|
120998
|
-
const stripAmount =
|
|
121507
|
+
// Indent counts characters (tab = 1), unlike indentWidth's CommonMark columns
|
|
121508
|
+
// (tab = 4) in terminate-html-flow-blocks.
|
|
121509
|
+
const indents = nonEmptyLines.map(line => line.match(/^(\s*)/)?.[1].length ?? 0);
|
|
121510
|
+
const minIndent = Math.min(...indents);
|
|
121511
|
+
const maxIndent = Math.max(...indents);
|
|
121512
|
+
const stripAmount = maxIndent > 3 ? minIndent : 0;
|
|
120999
121513
|
if (stripAmount === 0)
|
|
121000
121514
|
return text;
|
|
121001
121515
|
return lines.map(line => line.slice(stripAmount)).join('\n');
|
|
121002
121516
|
}
|
|
121003
121517
|
/**
|
|
121004
|
-
* Parse markdown
|
|
121005
|
-
*
|
|
121006
|
-
*
|
|
121518
|
+
* Parse component-body markdown into mdast children. Dedenting shifts columns and
|
|
121519
|
+
* stales the top-level `terminateHtmlFlowBlocks` decisions, so that one preprocessor
|
|
121520
|
+
* re-runs here; other column-anchored fixups (compact headings, tables) do not.
|
|
121007
121521
|
*/
|
|
121008
121522
|
const parseMdChildren = (value, safeMode) => {
|
|
121009
|
-
const parsed = getInlineMdProcessor({ safeMode }).parse(safeDeindent(value).trim());
|
|
121523
|
+
const parsed = getInlineMdProcessor({ safeMode }).parse(terminateHtmlFlowBlocks(safeDeindent(value).trim()));
|
|
121010
121524
|
return parsed.children || [];
|
|
121011
121525
|
};
|
|
121012
|
-
|
|
121013
|
-
|
|
121014
|
-
*/
|
|
121526
|
+
// Parses trailing content into sibling nodes and re-queues the parent so any
|
|
121527
|
+
// components among them get processed.
|
|
121015
121528
|
const parseSibling = (stack, parent, index, sibling, safeMode) => {
|
|
121016
121529
|
const siblingNodes = parseMdChildren(sibling, safeMode);
|
|
121017
|
-
// The new sibling nodes might contain new components to be processed
|
|
121018
121530
|
if (siblingNodes.length > 0) {
|
|
121019
121531
|
parent.children.splice(index + 1, 0, ...siblingNodes);
|
|
121020
121532
|
stack.push(parent);
|
|
121021
121533
|
}
|
|
121022
121534
|
};
|
|
121023
|
-
|
|
121024
|
-
|
|
121025
|
-
* component doesn't claim trailing content the tokenizer swallowed into one node.
|
|
121026
|
-
*/
|
|
121535
|
+
// Ends the position at `consumedLength` so the component doesn't claim trailing
|
|
121536
|
+
// content the tokenizer swallowed into the same html node.
|
|
121027
121537
|
const positionEndingAtConsumed = (nodePosition, value, consumedLength) => {
|
|
121028
121538
|
if (!nodePosition?.start)
|
|
121029
121539
|
return nodePosition;
|
|
121030
121540
|
return { start: nodePosition.start, end: pointAfter(nodePosition.start, value.slice(0, consumedLength)) };
|
|
121031
121541
|
};
|
|
121032
|
-
|
|
121033
|
-
|
|
121034
|
-
* this node's span in the original source. Used in the trailing-content path so
|
|
121035
|
-
* the offset is computed against the real source bytes (including blockquote/list
|
|
121036
|
-
* prefixes that were stripped from the html node's value).
|
|
121037
|
-
*/
|
|
121542
|
+
// Like `positionEndingAtConsumed`, but measures against the original source so
|
|
121543
|
+
// blockquote/list prefixes stripped from the html node's value are counted.
|
|
121038
121544
|
const positionEndingAtClosingTagInSource = (nodePosition, closingTag, source) => {
|
|
121039
121545
|
if (!nodePosition?.start || !nodePosition.end)
|
|
121040
121546
|
return nodePosition;
|
|
@@ -121045,9 +121551,6 @@ const positionEndingAtClosingTagInSource = (nodePosition, closingTag, source) =>
|
|
|
121045
121551
|
const consumed = nodeSource.slice(0, closingTagOffset + closingTag.length);
|
|
121046
121552
|
return { start: nodePosition.start, end: pointAfter(nodePosition.start, consumed) };
|
|
121047
121553
|
};
|
|
121048
|
-
/**
|
|
121049
|
-
* Create an MdxJsxFlowElement node from component data.
|
|
121050
|
-
*/
|
|
121051
121554
|
const createComponentNode = ({ tag, attributes, children, startPosition, endPosition }) => ({
|
|
121052
121555
|
type: 'mdxJsxFlowElement',
|
|
121053
121556
|
name: tag,
|
|
@@ -121069,6 +121572,10 @@ const substituteNodeWithMdxNode = (parent, index, mdxNode) => {
|
|
|
121069
121572
|
* This transformer identifies these patterns and converts them to proper MDX JSX elements so they
|
|
121070
121573
|
* can be accurately recognized and rendered later with their component definition code.
|
|
121071
121574
|
*
|
|
121575
|
+
* Note: The main goal is to promote PascalCase tags to MDX elements, but we want to promote
|
|
121576
|
+
* normal HTML to MDX elements in some cases so they get the full custom parsing behavior.
|
|
121577
|
+
* E.g. tags with JSX expressions, nested components, etc.
|
|
121578
|
+
*
|
|
121072
121579
|
* The mdx-component micromark tokenizer ensures that multi-line components are captured
|
|
121073
121580
|
* as single HTML nodes, so this transformer only needs to handle two cases:
|
|
121074
121581
|
*
|
|
@@ -121100,8 +121607,7 @@ const mdx_blocks_mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
|
121100
121607
|
if ('children' in node && Array.isArray(node.children)) {
|
|
121101
121608
|
stack.push(node);
|
|
121102
121609
|
}
|
|
121103
|
-
// Only
|
|
121104
|
-
// which means a potential unparsed MDX component
|
|
121610
|
+
// Only html nodes can be an unparsed MDX component.
|
|
121105
121611
|
const value = node.value;
|
|
121106
121612
|
if (node.type !== 'html' || typeof value !== 'string')
|
|
121107
121613
|
return;
|
|
@@ -121110,32 +121616,34 @@ const mdx_blocks_mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
|
121110
121616
|
if (!parsed)
|
|
121111
121617
|
return;
|
|
121112
121618
|
const { tag, attributes, selfClosing, contentAfterTag = '' } = parsed;
|
|
121113
|
-
//
|
|
121114
|
-
// so consumed-length math maps back onto the node's real source offsets.
|
|
121619
|
+
// Offsets so consumed-length math maps back onto the node's real source.
|
|
121115
121620
|
const leadingWhitespace = value.length - value.trimStart().length;
|
|
121116
|
-
// Index right after the opening tag's `>` within `trimmed`.
|
|
121117
121621
|
const openingTagEnd = trimmed.length - contentAfterTag.length;
|
|
121118
|
-
// Skip tags that have dedicated transformers
|
|
121119
121622
|
if (GENERIC_MDX_COMPONENT_EXCLUDED_TAGS.has(tag))
|
|
121120
|
-
return;
|
|
121623
|
+
return; // owned by dedicated transformers
|
|
121121
121624
|
const isPascal = isPascalCase(tag);
|
|
121122
|
-
//
|
|
121123
|
-
//
|
|
121124
|
-
//
|
|
121125
|
-
//
|
|
121126
|
-
// inline, which is how ReadMe's custom components are modeled).
|
|
121625
|
+
// ==== SPECIAL CASES TO PROMOTE NORMAL HTML TO MDX ELEMENTS ====
|
|
121626
|
+
// Lowercase inline tags with `{…}` attributes belong to
|
|
121627
|
+
// mdxishInlineComponentBlocks; leave them as html for that pass. PascalCase
|
|
121628
|
+
// components stay flow-level even when inline (ReadMe's component model).
|
|
121127
121629
|
if (!isPascal && parent.type === 'paragraph')
|
|
121128
121630
|
return;
|
|
121129
|
-
//
|
|
121130
|
-
//
|
|
121131
|
-
// JSX
|
|
121132
|
-
//
|
|
121133
|
-
// `
|
|
121134
|
-
//
|
|
121135
|
-
|
|
121136
|
-
|
|
121137
|
-
const
|
|
121138
|
-
|
|
121631
|
+
// A lowercase wrapper is only promoted when it (or a descendant) carries a
|
|
121632
|
+
// JSX expression or nests a component; otherwise it would swallow that inner
|
|
121633
|
+
// JSX/component as literal text that rehype-raw's parse5 pass can't handle.
|
|
121634
|
+
// Table-structural wrappers are excluded from both — `mdxishTables` re-parses
|
|
121635
|
+
// those, so a `{…}` in a cell (e.g. `<code>--depth={n}</code>`) must not
|
|
121636
|
+
// accidentally promote the table to an MDX element prematurely.
|
|
121637
|
+
const isTableStructuralTag = tag === 'table' || tableTags.has(tag);
|
|
121638
|
+
const hasNestedExpressionAttr = !selfClosing && !isTableStructuralTag && NESTED_ATTR_EXPRESSION_RE.test(contentAfterTag);
|
|
121639
|
+
const hasNestedComponentTag = !selfClosing && !isTableStructuralTag && hasNestedGenericComponentTag(contentAfterTag);
|
|
121640
|
+
// Promotion: By default commonmark doesn't parse markdown in single line HTML tags (e.g. <div>**bold**</div>)
|
|
121641
|
+
// To support that, we try to promote them to MDX elements so the markdown gets parsed
|
|
121642
|
+
const isPlainLowercaseHtml = !isPascal && !hasExpressionAttr(attributes) && !hasNestedExpressionAttr && !hasNestedComponentTag;
|
|
121643
|
+
const plainClosingTagIndex = isPlainLowercaseHtml && !selfClosing && isMarkdownPromotableHtmlTag(tag) && !NESTED_TABLE_RE.test(contentAfterTag)
|
|
121644
|
+
? findBalancedClosingTagIndex(contentAfterTag, tag)
|
|
121645
|
+
: -1;
|
|
121646
|
+
if (isPlainLowercaseHtml && plainClosingTagIndex < 0)
|
|
121139
121647
|
return;
|
|
121140
121648
|
const closingTagStr = `</${tag}>`;
|
|
121141
121649
|
// Case 1: Self-closing tag
|
|
@@ -121149,7 +121657,6 @@ const mdx_blocks_mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
|
121149
121657
|
endPosition: positionEndingAtConsumed(node.position, value, leadingWhitespace + openingTagEnd),
|
|
121150
121658
|
});
|
|
121151
121659
|
substituteNodeWithMdxNode(parent, index, componentNode);
|
|
121152
|
-
// Check and parse if there's relevant content after the current closing tag
|
|
121153
121660
|
const remainingContent = contentAfterTag.trim();
|
|
121154
121661
|
if (remainingContent) {
|
|
121155
121662
|
parseSibling(stack, parent, index, remainingContent, safeMode);
|
|
@@ -121157,18 +121664,27 @@ const mdx_blocks_mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
|
121157
121664
|
return;
|
|
121158
121665
|
}
|
|
121159
121666
|
// Case 2: Self-contained block (closing tag in content)
|
|
121160
|
-
|
|
121161
|
-
|
|
121162
|
-
|
|
121163
|
-
// Pass raw (untrimmed) content so dedent in parseMdChildren can
|
|
121164
|
-
// normalize indentation before trimming
|
|
121667
|
+
const closingTagIndex = isPlainLowercaseHtml ? plainClosingTagIndex : contentAfterTag.lastIndexOf(closingTagStr);
|
|
121668
|
+
if (closingTagIndex >= 0) {
|
|
121669
|
+
// Untrimmed so parseMdChildren can dedent before trimming.
|
|
121165
121670
|
const componentInnerContent = contentAfterTag.substring(0, closingTagIndex);
|
|
121166
121671
|
const contentAfterClose = contentAfterTag.substring(closingTagIndex + closingTagStr.length).trim();
|
|
121167
|
-
let parsedChildren =
|
|
121168
|
-
|
|
121169
|
-
|
|
121170
|
-
|
|
121171
|
-
|
|
121672
|
+
let parsedChildren = [];
|
|
121673
|
+
if (componentInnerContent.trim()) {
|
|
121674
|
+
try {
|
|
121675
|
+
parsedChildren = parseMdChildren(componentInnerContent, safeMode);
|
|
121676
|
+
}
|
|
121677
|
+
catch (error) {
|
|
121678
|
+
// Plain HTML bodies can hold anything (e.g. stray braces the strict
|
|
121679
|
+
// expression parser rejects) — keep the node raw instead of throwing.
|
|
121680
|
+
if (isPlainLowercaseHtml)
|
|
121681
|
+
return;
|
|
121682
|
+
throw error;
|
|
121683
|
+
}
|
|
121684
|
+
}
|
|
121685
|
+
if (isPlainLowercaseHtml && !containsMarkdownConstruct(parsedChildren))
|
|
121686
|
+
return;
|
|
121687
|
+
// Lowercase tags are usually inline; unwrap a sole paragraph so their
|
|
121172
121688
|
// phrasing content isn't spuriously block-wrapped.
|
|
121173
121689
|
if (!isPascal && parsedChildren.length === 1 && parsedChildren[0].type === 'paragraph') {
|
|
121174
121690
|
parsedChildren = parsedChildren[0].children;
|
|
@@ -121178,12 +121694,9 @@ const mdx_blocks_mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
|
121178
121694
|
attributes,
|
|
121179
121695
|
children: parsedChildren,
|
|
121180
121696
|
startPosition: node.position,
|
|
121181
|
-
//
|
|
121182
|
-
//
|
|
121183
|
-
//
|
|
121184
|
-
// node's value has '> '/space prefixes stripped for blockquotes/list items, so
|
|
121185
|
-
// positionEndingAtConsumed would undercount source offsets. When the entire node
|
|
121186
|
-
// is consumed, use the original node position directly.
|
|
121697
|
+
// With trailing content, end precisely at the closing tag. Prefer source
|
|
121698
|
+
// offsets when available (the node's value strips blockquote/list
|
|
121699
|
+
// prefixes); otherwise fall back to the whole node position.
|
|
121187
121700
|
endPosition: contentAfterClose
|
|
121188
121701
|
? source
|
|
121189
121702
|
? positionEndingAtClosingTagInSource(node.position, closingTagStr, source)
|
|
@@ -121191,17 +121704,16 @@ const mdx_blocks_mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
|
121191
121704
|
: node.position,
|
|
121192
121705
|
});
|
|
121193
121706
|
substituteNodeWithMdxNode(parent, index, componentNode);
|
|
121194
|
-
//
|
|
121707
|
+
// Re-queue whichever side may hold further components.
|
|
121195
121708
|
if (contentAfterClose) {
|
|
121196
121709
|
parseSibling(stack, parent, index, contentAfterClose, safeMode);
|
|
121197
121710
|
}
|
|
121198
121711
|
else if (componentNode.children.length > 0) {
|
|
121199
|
-
// The content inside the component block might contain new components to be processed
|
|
121200
121712
|
stack.push(componentNode);
|
|
121201
121713
|
}
|
|
121202
121714
|
}
|
|
121203
121715
|
};
|
|
121204
|
-
//
|
|
121716
|
+
// Depth-first so nodes keep their source order.
|
|
121205
121717
|
while (stack.length) {
|
|
121206
121718
|
const parent = stack.pop();
|
|
121207
121719
|
if (parent?.children) {
|
|
@@ -123372,21 +123884,21 @@ function resolveEntity(name) {
|
|
|
123372
123884
|
function tokenizeLooseHtmlEntity(effects, ok, nok) {
|
|
123373
123885
|
let length = 0;
|
|
123374
123886
|
const start = (code) => {
|
|
123375
|
-
if (code !==
|
|
123887
|
+
if (code !== codes.ampersand)
|
|
123376
123888
|
return nok(code);
|
|
123377
123889
|
effects.enter('looseHtmlEntity');
|
|
123378
123890
|
effects.consume(code);
|
|
123379
123891
|
return afterAmpersand;
|
|
123380
123892
|
};
|
|
123381
123893
|
const afterAmpersand = (code) => {
|
|
123382
|
-
if (code ===
|
|
123894
|
+
if (code === codes.numberSign) {
|
|
123383
123895
|
effects.consume(code);
|
|
123384
123896
|
return afterHash;
|
|
123385
123897
|
}
|
|
123386
123898
|
return accumulateNamed(code);
|
|
123387
123899
|
};
|
|
123388
123900
|
const afterHash = (code) => {
|
|
123389
|
-
if (code ===
|
|
123901
|
+
if (code === codes.lowercaseX || code === codes.uppercaseX) {
|
|
123390
123902
|
effects.consume(code);
|
|
123391
123903
|
return accumulateHex;
|
|
123392
123904
|
}
|
|
@@ -123400,7 +123912,7 @@ function tokenizeLooseHtmlEntity(effects, ok, nok) {
|
|
|
123400
123912
|
}
|
|
123401
123913
|
if (length === 0)
|
|
123402
123914
|
return nok(code);
|
|
123403
|
-
if (code ===
|
|
123915
|
+
if (code === codes.semicolon)
|
|
123404
123916
|
return nok(code);
|
|
123405
123917
|
effects.exit('looseHtmlEntity');
|
|
123406
123918
|
return ok(code);
|
|
@@ -123413,7 +123925,7 @@ function tokenizeLooseHtmlEntity(effects, ok, nok) {
|
|
|
123413
123925
|
}
|
|
123414
123926
|
if (length === 0)
|
|
123415
123927
|
return nok(code);
|
|
123416
|
-
if (code ===
|
|
123928
|
+
if (code === codes.semicolon)
|
|
123417
123929
|
return nok(code);
|
|
123418
123930
|
effects.exit('looseHtmlEntity');
|
|
123419
123931
|
return ok(code);
|
|
@@ -123426,7 +123938,7 @@ function tokenizeLooseHtmlEntity(effects, ok, nok) {
|
|
|
123426
123938
|
}
|
|
123427
123939
|
if (length === 0)
|
|
123428
123940
|
return nok(code);
|
|
123429
|
-
if (code ===
|
|
123941
|
+
if (code === codes.semicolon)
|
|
123430
123942
|
return nok(code);
|
|
123431
123943
|
effects.exit('looseHtmlEntity');
|
|
123432
123944
|
return ok(code);
|
|
@@ -123461,7 +123973,7 @@ function exitLooseHtmlEntity(token) {
|
|
|
123461
123973
|
}
|
|
123462
123974
|
function looseHtmlEntity() {
|
|
123463
123975
|
return {
|
|
123464
|
-
text: { [
|
|
123976
|
+
text: { [codes.ampersand]: looseHtmlEntityConstruct },
|
|
123465
123977
|
};
|
|
123466
123978
|
}
|
|
123467
123979
|
function looseHtmlEntityFromMarkdown() {
|
|
@@ -124154,9 +124666,6 @@ const magicBlockTransformer = (options = {}) => tree => {
|
|
|
124154
124666
|
// single-line `<div>…</div>`). CommonMark slurps the whole div as one `html`
|
|
124155
124667
|
// node, so the tokenizer never sees the HTMLBlock — we recover it here.
|
|
124156
124668
|
const RAW_HTML_BLOCK_RE = /<HTMLBlock\b([^>]*)>\s*\{\s*`((?:[^`\\]|\\.)*)`\s*\}\s*<\/HTMLBlock>/g;
|
|
124157
|
-
// Opening `<HTMLBlock …>` as its own `html` node — produced inside a paragraph
|
|
124158
|
-
// when an HTMLBlock appears inline alongside text.
|
|
124159
|
-
const HTML_BLOCK_OPEN_RE = /^<HTMLBlock\b([^>]*)>$/;
|
|
124160
124669
|
/**
|
|
124161
124670
|
* Builds the canonical `html-block` MDAST node the renderer expects.
|
|
124162
124671
|
*/
|
|
@@ -124237,13 +124746,14 @@ const splitRawHtmlBlocks = (node) => {
|
|
|
124237
124746
|
/**
|
|
124238
124747
|
* Converts every `<HTMLBlock>` shape that survives parsing into the canonical
|
|
124239
124748
|
* `html-block` MDAST node, reading the body from the tokenizer's template-literal
|
|
124240
|
-
* expression.
|
|
124749
|
+
* expression. Two shapes occur:
|
|
124241
124750
|
*
|
|
124242
|
-
* 1. JSX element (`mdxJsxFlowElement`/`mdxJsxTextElement`) —
|
|
124243
|
-
*
|
|
124244
|
-
*
|
|
124245
|
-
*
|
|
124246
|
-
*
|
|
124751
|
+
* 1. JSX element (`mdxJsxFlowElement`/`mdxJsxTextElement`) — table cells, after
|
|
124752
|
+
* their remarkMdx re-parse (that re-parse runs without the htmlBlockComponent
|
|
124753
|
+
* tokenizer, so `<HTMLBlock>` arrives as JSX rather than an opaque `html` node).
|
|
124754
|
+
* 2. Raw `html` blob (`splitRawHtmlBlocks`) — the htmlBlockComponent tokenizer's
|
|
124755
|
+
* opaque output (top-level and inline), or an `<HTMLBlock>` embedded in a
|
|
124756
|
+
* larger raw-HTML node like an inline `<div>` that the tokenizer never saw.
|
|
124247
124757
|
*
|
|
124248
124758
|
* Runs *after* `mdxishTables` so table cells are re-parsed first;
|
|
124249
124759
|
* `mdxishTables` recognizes the still-JSX `<HTMLBlock>` element when deciding to
|
|
@@ -124268,36 +124778,6 @@ const mdxishHtmlBlocks = () => tree => {
|
|
|
124268
124778
|
if (replacement)
|
|
124269
124779
|
parent.children.splice(index, 1, ...replacement);
|
|
124270
124780
|
});
|
|
124271
|
-
// Shape 3: inline within a paragraph — `<HTMLBlock>` open/close arrive as
|
|
124272
|
-
// separate `html` siblings with the template-literal expression between them.
|
|
124273
|
-
lib_visit(tree, 'paragraph', (paragraph) => {
|
|
124274
|
-
// An html-block is block content, so it isn't a valid PhrasingContent child;
|
|
124275
|
-
// widen to RootContent (which HTMLBlock belongs to) for the in-place splice.
|
|
124276
|
-
const children = paragraph.children;
|
|
124277
|
-
for (let i = 0; i < children.length; i += 1) {
|
|
124278
|
-
const open = children[i];
|
|
124279
|
-
const openMatch = open.type === 'html' ? open.value.match(HTML_BLOCK_OPEN_RE) : null;
|
|
124280
|
-
if (!openMatch)
|
|
124281
|
-
continue; // eslint-disable-line no-continue
|
|
124282
|
-
const closeIdx = children.findIndex((child, j) => j > i && child.type === 'html' && child.value === '</HTMLBlock>');
|
|
124283
|
-
if (closeIdx === -1)
|
|
124284
|
-
continue; // eslint-disable-line no-continue
|
|
124285
|
-
const body = children
|
|
124286
|
-
.slice(i + 1, closeIdx)
|
|
124287
|
-
.map(child => {
|
|
124288
|
-
if (child.type === 'mdxTextExpression' || child.type === 'mdxFlowExpression') {
|
|
124289
|
-
return extractTemplateLiteral(child.value);
|
|
124290
|
-
}
|
|
124291
|
-
// Preserve raw text from any other phrasing sibling (e.g. stray
|
|
124292
|
-
// whitespace or content the tokenizer didn't claim) so it isn't
|
|
124293
|
-
// silently dropped from the html payload.
|
|
124294
|
-
return 'value' in child && typeof child.value === 'string' ? child.value : '';
|
|
124295
|
-
})
|
|
124296
|
-
.join('');
|
|
124297
|
-
const openingTagIndent = (open.position?.start.column ?? 1) - 1;
|
|
124298
|
-
children.splice(i, closeIdx - i + 1, htmlBlockFromRaw(openMatch[1], body, open.position, openingTagIndent));
|
|
124299
|
-
}
|
|
124300
|
-
});
|
|
124301
124781
|
};
|
|
124302
124782
|
/* harmony default export */ const mdxish_html_blocks = (mdxishHtmlBlocks);
|
|
124303
124783
|
|
|
@@ -124997,6 +125477,29 @@ const mdxishMermaidTransformer = () => (tree) => {
|
|
|
124997
125477
|
};
|
|
124998
125478
|
/* harmony default export */ const mdxish_mermaid = (mdxishMermaidTransformer);
|
|
124999
125479
|
|
|
125480
|
+
;// ./processor/transform/mdxish/normalize-closing-tag-whitespace.ts
|
|
125481
|
+
|
|
125482
|
+
|
|
125483
|
+
// Spaces/tabs only — newlines would let prose `<` / `>` across lines look like one tag.
|
|
125484
|
+
const SPACED_CLOSING_TAG_RE = /<\/[ \t]*([a-zA-Z][a-zA-Z0-9-]*)[ \t]*>/g;
|
|
125485
|
+
/**
|
|
125486
|
+
* Canonicalize spaced closing tags (`</ td >` → `</td>`) for known HTML names.
|
|
125487
|
+
*
|
|
125488
|
+
* In HTML, `</` + whitespace is a bogus comment, so `</ table >` never closes the
|
|
125489
|
+
* table (jsxTable misses it → empty table + pre; CX-3706). Only standard HTML tags;
|
|
125490
|
+
* custom components, prose (`a </ b`), and code blocks are left alone.
|
|
125491
|
+
*
|
|
125492
|
+
* @example
|
|
125493
|
+
* normalizeClosingTagWhitespace('</ td >') // '</td>'
|
|
125494
|
+
* normalizeClosingTagWhitespace('</table >') // '</table>'
|
|
125495
|
+
* normalizeClosingTagWhitespace('a </ b >') // unchanged
|
|
125496
|
+
*/
|
|
125497
|
+
function normalizeClosingTagWhitespace(content) {
|
|
125498
|
+
const { protectedContent, protectedCode } = protectCodeBlocks(content);
|
|
125499
|
+
const result = protectedContent.replace(SPACED_CLOSING_TAG_RE, (match, tagName) => STANDARD_HTML_TAGS.has(tagName.toLowerCase()) ? `</${tagName}>` : match);
|
|
125500
|
+
return restoreCodeBlocks(result, protectedCode);
|
|
125501
|
+
}
|
|
125502
|
+
|
|
125000
125503
|
;// ./processor/transform/mdxish/normalize-compact-headings.ts
|
|
125001
125504
|
|
|
125002
125505
|
/**
|
|
@@ -125450,74 +125953,7 @@ function normalizeTableSeparator(content) {
|
|
|
125450
125953
|
});
|
|
125451
125954
|
return normalizedLines.join('\n');
|
|
125452
125955
|
}
|
|
125453
|
-
/* harmony default export */ const normalize_table_separator = ((/* unused pure expression or super */ null && (normalizeTableSeparator)));
|
|
125454
|
-
|
|
125455
|
-
;// ./processor/transform/mdxish/terminate-html-flow-blocks.ts
|
|
125456
|
-
|
|
125457
|
-
|
|
125458
|
-
|
|
125459
|
-
const STANDALONE_HTML_LINE_REGEX = /^(<[a-z][^<>]*>|<\/[a-z][^<>]*>)+\s*$/;
|
|
125460
|
-
const HTML_LINE_WITH_CONTENT_REGEX = /^<[a-z][^<>]*>.*<\/[a-z][^<>]*>(?:[^<]*)$/;
|
|
125461
|
-
// Tags whose contents must be preserved as is, inserting a blank line after the
|
|
125462
|
-
// opener corrupts the payload.
|
|
125463
|
-
// htmlRawNames here refer to <pre>, <textarea>, <script>, <style>
|
|
125464
|
-
const RAW_CONTENT_TAGS = [...htmlRawNames, ...HTML_TABLE_STRUCTURE_TAGS];
|
|
125465
|
-
// The `(?=[\s/>])` lookahead avoids false matches on lookalike names like `<script-foo>`.
|
|
125466
|
-
const RAW_CONTENT_TAG_MATCHERS = RAW_CONTENT_TAGS.map(tag => ({
|
|
125467
|
-
open: new RegExp(`<${tag}(?=[\\s/>])[^>]*?(?<!/)>`, 'gi'),
|
|
125468
|
-
close: new RegExp(`</${tag}(?=[\\s>])[^>]*>`, 'gi'),
|
|
125469
|
-
}));
|
|
125470
|
-
function isLineHtml(line) {
|
|
125471
|
-
return STANDALONE_HTML_LINE_REGEX.test(line) || HTML_LINE_WITH_CONTENT_REGEX.test(line);
|
|
125472
|
-
}
|
|
125473
|
-
// True if any RAW_CONTENT_TAGS opener on this line is not closed on the same line.
|
|
125474
|
-
function hasUnclosedRawContentOpener(line) {
|
|
125475
|
-
return RAW_CONTENT_TAG_MATCHERS.some(({ open, close }) => {
|
|
125476
|
-
const opens = (line.match(open) ?? []).length;
|
|
125477
|
-
const closes = (line.match(close) ?? []).length;
|
|
125478
|
-
return opens > closes;
|
|
125479
|
-
});
|
|
125480
|
-
}
|
|
125481
|
-
/**
|
|
125482
|
-
* Preprocessor to terminate HTML flow blocks.
|
|
125483
|
-
*
|
|
125484
|
-
* In CommonMark, HTML blocks (types 6 and 7) only terminate on a blank line.
|
|
125485
|
-
* Without one, any content on the next line is consumed as part of the HTML block
|
|
125486
|
-
* and never parsed as its own construct. For example, a `[block:callout]` immediately
|
|
125487
|
-
* following `<div><p></p></div>` gets swallowed into the HTML flow token.
|
|
125488
|
-
*
|
|
125489
|
-
* @link https://spec.commonmark.org/0.29/#html-blocks
|
|
125490
|
-
*
|
|
125491
|
-
* This preprocessor inserts a blank line after standalone HTML lines when the next
|
|
125492
|
-
* line is non-blank and not an HTML construct, ensuring micromark's HTML flow
|
|
125493
|
-
* tokenizer terminates and subsequent content is parsed independently.
|
|
125494
|
-
*
|
|
125495
|
-
* Conditions:
|
|
125496
|
-
* 1. Only non-indented lines with lowercase tag names are considered. Uppercase tags
|
|
125497
|
-
* (e.g. `<Table>`, `<MyComponent>`) are JSX custom components and don't trigger
|
|
125498
|
-
* CommonMark HTML blocks.
|
|
125499
|
-
* 2. Lines inside protected blocks (e.g. fenced code) are left untouched.
|
|
125500
|
-
* 3. Lines with an unclosed RAW_CONTENT_TAGS opener are exempted.
|
|
125501
|
-
*/
|
|
125502
|
-
function terminateHtmlFlowBlocks(content) {
|
|
125503
|
-
const { protectedContent, protectedCode } = protectCodeBlocks(content);
|
|
125504
|
-
const lines = protectedContent.split('\n');
|
|
125505
|
-
const result = [];
|
|
125506
|
-
for (let i = 0; i < lines.length; i += 1) {
|
|
125507
|
-
result.push(lines[i]);
|
|
125508
|
-
// Skip blank & indented lines
|
|
125509
|
-
if (i >= lines.length - 1 || lines[i + 1].trim().length === 0 || lines[i + 1].startsWith(' ') || lines[i + 1].startsWith('\t')) {
|
|
125510
|
-
// eslint-disable-next-line no-continue
|
|
125511
|
-
continue;
|
|
125512
|
-
}
|
|
125513
|
-
const isCurrentLineHtml = isLineHtml(lines[i]);
|
|
125514
|
-
const isNextLineHtml = isLineHtml(lines[i + 1]);
|
|
125515
|
-
if (isCurrentLineHtml && !isNextLineHtml && !hasUnclosedRawContentOpener(lines[i])) {
|
|
125516
|
-
result.push('');
|
|
125517
|
-
}
|
|
125518
|
-
}
|
|
125519
|
-
return restoreCodeBlocks(result.join('\n'), protectedCode);
|
|
125520
|
-
}
|
|
125956
|
+
/* harmony default export */ const normalize_table_separator = ((/* unused pure expression or super */ null && (normalizeTableSeparator)));
|
|
125521
125957
|
|
|
125522
125958
|
;// ./processor/transform/mdxish/variables-code.ts
|
|
125523
125959
|
|
|
@@ -125675,25 +126111,25 @@ const variablesTextTransformer = () => tree => {
|
|
|
125675
126111
|
};
|
|
125676
126112
|
/* harmony default export */ const variables_text = (variablesTextTransformer);
|
|
125677
126113
|
|
|
125678
|
-
;// ./lib/mdast-util/
|
|
125679
|
-
const
|
|
125680
|
-
function
|
|
126114
|
+
;// ./lib/mdast-util/html-block-component/index.ts
|
|
126115
|
+
const html_block_component_contextMap = new WeakMap();
|
|
126116
|
+
function findHtmlBlockComponentToken() {
|
|
125681
126117
|
const events = this.tokenStack;
|
|
125682
126118
|
for (let i = events.length - 1; i >= 0; i -= 1) {
|
|
125683
|
-
if (events[i][0].type === '
|
|
126119
|
+
if (events[i][0].type === 'htmlBlockComponent')
|
|
125684
126120
|
return events[i][0];
|
|
125685
126121
|
}
|
|
125686
126122
|
return undefined;
|
|
125687
126123
|
}
|
|
125688
|
-
function
|
|
125689
|
-
|
|
126124
|
+
function enterHtmlBlockComponent(token) {
|
|
126125
|
+
html_block_component_contextMap.set(token, { chunks: [], lastEndLine: token.start.line });
|
|
125690
126126
|
this.enter({ type: 'html', value: '' }, token);
|
|
125691
126127
|
}
|
|
125692
|
-
function
|
|
125693
|
-
const
|
|
125694
|
-
if (!
|
|
126128
|
+
function exitHtmlBlockComponentData(token) {
|
|
126129
|
+
const componentToken = findHtmlBlockComponentToken.call(this);
|
|
126130
|
+
if (!componentToken)
|
|
125695
126131
|
return;
|
|
125696
|
-
const ctx =
|
|
126132
|
+
const ctx = html_block_component_contextMap.get(componentToken);
|
|
125697
126133
|
if (ctx) {
|
|
125698
126134
|
const gap = token.start.line - ctx.lastEndLine;
|
|
125699
126135
|
if (ctx.chunks.length > 0 && gap > 0) {
|
|
@@ -125703,27 +126139,304 @@ function exitJsxTableData(token) {
|
|
|
125703
126139
|
ctx.lastEndLine = token.end.line;
|
|
125704
126140
|
}
|
|
125705
126141
|
}
|
|
125706
|
-
function
|
|
125707
|
-
const ctx =
|
|
126142
|
+
function exitHtmlBlockComponent(token) {
|
|
126143
|
+
const ctx = html_block_component_contextMap.get(token);
|
|
125708
126144
|
const node = this.stack[this.stack.length - 1];
|
|
125709
126145
|
if (ctx) {
|
|
125710
126146
|
node.value = ctx.chunks.join('');
|
|
125711
|
-
|
|
126147
|
+
html_block_component_contextMap.delete(token);
|
|
125712
126148
|
}
|
|
125713
126149
|
this.exit(token);
|
|
125714
126150
|
}
|
|
125715
|
-
function
|
|
126151
|
+
function html_block_component_htmlBlockComponentFromMarkdown() {
|
|
125716
126152
|
return {
|
|
125717
126153
|
enter: {
|
|
125718
|
-
|
|
126154
|
+
htmlBlockComponent: enterHtmlBlockComponent,
|
|
125719
126155
|
},
|
|
125720
126156
|
exit: {
|
|
125721
|
-
|
|
125722
|
-
|
|
126157
|
+
htmlBlockComponentData: exitHtmlBlockComponentData,
|
|
126158
|
+
htmlBlockComponent: exitHtmlBlockComponent,
|
|
126159
|
+
},
|
|
126160
|
+
};
|
|
126161
|
+
}
|
|
126162
|
+
|
|
126163
|
+
;// ./lib/micromark/html-block-component/syntax.ts
|
|
126164
|
+
|
|
126165
|
+
|
|
126166
|
+
const TAG_SUFFIX = [
|
|
126167
|
+
codes.uppercaseT,
|
|
126168
|
+
codes.uppercaseM,
|
|
126169
|
+
codes.uppercaseL,
|
|
126170
|
+
codes.uppercaseB,
|
|
126171
|
+
codes.lowercaseL,
|
|
126172
|
+
codes.lowercaseO,
|
|
126173
|
+
codes.lowercaseC,
|
|
126174
|
+
codes.lowercaseK,
|
|
126175
|
+
];
|
|
126176
|
+
// ---------------------------------------------------------------------------
|
|
126177
|
+
// Shared tokenizer factory
|
|
126178
|
+
// ---------------------------------------------------------------------------
|
|
126179
|
+
/**
|
|
126180
|
+
* Creates a tokenize function for `<HTMLBlock>...</HTMLBlock>`.
|
|
126181
|
+
*
|
|
126182
|
+
* - **flow** (block-level): supports multiline content via line continuations,
|
|
126183
|
+
* consumes trailing whitespace after the closing tag.
|
|
126184
|
+
* - **text** (inline): single-line only, exits immediately after the closing tag.
|
|
126185
|
+
*/
|
|
126186
|
+
function syntax_createTokenize(mode) {
|
|
126187
|
+
return function tokenize(effects, ok, nok) {
|
|
126188
|
+
let depth = 1;
|
|
126189
|
+
function matchChars(chars, onMatch, onFail) {
|
|
126190
|
+
if (chars.length === 0)
|
|
126191
|
+
return onMatch;
|
|
126192
|
+
const next = (code) => {
|
|
126193
|
+
if (code === chars[0]) {
|
|
126194
|
+
effects.consume(code);
|
|
126195
|
+
return matchChars(chars.slice(1), onMatch, onFail);
|
|
126196
|
+
}
|
|
126197
|
+
return onFail(code);
|
|
126198
|
+
};
|
|
126199
|
+
return next;
|
|
126200
|
+
}
|
|
126201
|
+
function matchTagName(onMatch, onFail) {
|
|
126202
|
+
const next = (code) => {
|
|
126203
|
+
if (code === codes.uppercaseH) {
|
|
126204
|
+
effects.consume(code);
|
|
126205
|
+
return matchChars(TAG_SUFFIX, onMatch, onFail);
|
|
126206
|
+
}
|
|
126207
|
+
return onFail(code);
|
|
126208
|
+
};
|
|
126209
|
+
return next;
|
|
126210
|
+
}
|
|
126211
|
+
return start;
|
|
126212
|
+
function start(code) {
|
|
126213
|
+
if (code !== codes.lessThan)
|
|
126214
|
+
return nok(code);
|
|
126215
|
+
effects.enter('htmlBlockComponent');
|
|
126216
|
+
effects.enter('htmlBlockComponentData');
|
|
126217
|
+
effects.consume(code);
|
|
126218
|
+
return matchTagName(afterTagName, nok);
|
|
126219
|
+
}
|
|
126220
|
+
function afterTagName(code) {
|
|
126221
|
+
if (code === codes.greaterThan) {
|
|
126222
|
+
effects.consume(code);
|
|
126223
|
+
return body;
|
|
126224
|
+
}
|
|
126225
|
+
if (code === codes.space || code === codes.horizontalTab) {
|
|
126226
|
+
effects.consume(code);
|
|
126227
|
+
return inAttributes;
|
|
126228
|
+
}
|
|
126229
|
+
if (mode === 'flow' && markdownLineEnding(code)) {
|
|
126230
|
+
effects.exit('htmlBlockComponentData');
|
|
126231
|
+
return attributeContinuationStart(code);
|
|
126232
|
+
}
|
|
126233
|
+
if (code === codes.slash) {
|
|
126234
|
+
effects.consume(code);
|
|
126235
|
+
return selfClose;
|
|
126236
|
+
}
|
|
126237
|
+
return nok(code);
|
|
126238
|
+
}
|
|
126239
|
+
function inAttributes(code) {
|
|
126240
|
+
if (code === codes.greaterThan) {
|
|
126241
|
+
effects.consume(code);
|
|
126242
|
+
return body;
|
|
126243
|
+
}
|
|
126244
|
+
if (code === null) {
|
|
126245
|
+
return nok(code);
|
|
126246
|
+
}
|
|
126247
|
+
if (markdownLineEnding(code)) {
|
|
126248
|
+
if (mode === 'text')
|
|
126249
|
+
return nok(code);
|
|
126250
|
+
effects.exit('htmlBlockComponentData');
|
|
126251
|
+
return attributeContinuationStart(code);
|
|
126252
|
+
}
|
|
126253
|
+
effects.consume(code);
|
|
126254
|
+
return inAttributes;
|
|
126255
|
+
}
|
|
126256
|
+
function attributeContinuationStart(code) {
|
|
126257
|
+
return effects.check(html_block_component_syntax_nonLazyContinuationStart, attributeContinuationNonLazy, continuationAfter)(code);
|
|
126258
|
+
}
|
|
126259
|
+
function attributeContinuationNonLazy(code) {
|
|
126260
|
+
effects.enter(types_types.lineEnding);
|
|
126261
|
+
effects.consume(code);
|
|
126262
|
+
effects.exit(types_types.lineEnding);
|
|
126263
|
+
return attributeContinuationBefore;
|
|
126264
|
+
}
|
|
126265
|
+
function attributeContinuationBefore(code) {
|
|
126266
|
+
if (code === null || markdownLineEnding(code)) {
|
|
126267
|
+
return attributeContinuationStart(code);
|
|
126268
|
+
}
|
|
126269
|
+
effects.enter('htmlBlockComponentData');
|
|
126270
|
+
return inAttributes(code);
|
|
126271
|
+
}
|
|
126272
|
+
function selfClose(code) {
|
|
126273
|
+
if (code === codes.greaterThan) {
|
|
126274
|
+
effects.consume(code);
|
|
126275
|
+
return mode === 'flow' ? afterClose : done(code);
|
|
126276
|
+
}
|
|
126277
|
+
return nok(code);
|
|
126278
|
+
}
|
|
126279
|
+
function body(code) {
|
|
126280
|
+
if (code === null)
|
|
126281
|
+
return nok(code);
|
|
126282
|
+
if (markdownLineEnding(code)) {
|
|
126283
|
+
if (mode === 'text') {
|
|
126284
|
+
// Text constructs operate on paragraph content which spans lines
|
|
126285
|
+
effects.consume(code);
|
|
126286
|
+
return body;
|
|
126287
|
+
}
|
|
126288
|
+
effects.exit('htmlBlockComponentData');
|
|
126289
|
+
return continuationStart(code);
|
|
126290
|
+
}
|
|
126291
|
+
if (code === codes.lessThan) {
|
|
126292
|
+
effects.consume(code);
|
|
126293
|
+
return closeSlash;
|
|
126294
|
+
}
|
|
126295
|
+
effects.consume(code);
|
|
126296
|
+
return body;
|
|
126297
|
+
}
|
|
126298
|
+
function closeSlash(code) {
|
|
126299
|
+
if (code === codes.slash) {
|
|
126300
|
+
effects.consume(code);
|
|
126301
|
+
return matchTagName(closeGt, body);
|
|
126302
|
+
}
|
|
126303
|
+
return matchTagName(openAfterTagName, body)(code);
|
|
126304
|
+
}
|
|
126305
|
+
function openAfterTagName(code) {
|
|
126306
|
+
if (code === codes.greaterThan || code === codes.space || code === codes.horizontalTab) {
|
|
126307
|
+
depth += 1;
|
|
126308
|
+
effects.consume(code);
|
|
126309
|
+
return body;
|
|
126310
|
+
}
|
|
126311
|
+
return body(code);
|
|
126312
|
+
}
|
|
126313
|
+
function closeGt(code) {
|
|
126314
|
+
if (code === codes.greaterThan) {
|
|
126315
|
+
depth -= 1;
|
|
126316
|
+
effects.consume(code);
|
|
126317
|
+
if (depth === 0) {
|
|
126318
|
+
return mode === 'flow' ? afterClose : done(code);
|
|
126319
|
+
}
|
|
126320
|
+
return body;
|
|
126321
|
+
}
|
|
126322
|
+
return body(code);
|
|
126323
|
+
}
|
|
126324
|
+
// -- flow-only states ---------------------------------------------------
|
|
126325
|
+
function afterClose(code) {
|
|
126326
|
+
if (code === null || markdownLineEnding(code)) {
|
|
126327
|
+
return done(code);
|
|
126328
|
+
}
|
|
126329
|
+
if (code === codes.space || code === codes.horizontalTab) {
|
|
126330
|
+
effects.consume(code);
|
|
126331
|
+
return afterClose;
|
|
126332
|
+
}
|
|
126333
|
+
// Reject so the block re-parses as a paragraph, deferring to the
|
|
126334
|
+
// text tokenizer which preserves trailing content in the same line.
|
|
126335
|
+
return nok(code);
|
|
126336
|
+
}
|
|
126337
|
+
// -- flow-only: line continuation ---------------------------------------
|
|
126338
|
+
function continuationStart(code) {
|
|
126339
|
+
return effects.check(html_block_component_syntax_nonLazyContinuationStart, continuationStartNonLazy, continuationAfter)(code);
|
|
126340
|
+
}
|
|
126341
|
+
function continuationStartNonLazy(code) {
|
|
126342
|
+
effects.enter(types_types.lineEnding);
|
|
126343
|
+
effects.consume(code);
|
|
126344
|
+
effects.exit(types_types.lineEnding);
|
|
126345
|
+
return continuationBefore;
|
|
126346
|
+
}
|
|
126347
|
+
function continuationBefore(code) {
|
|
126348
|
+
if (code === null || markdownLineEnding(code)) {
|
|
126349
|
+
return continuationStart(code);
|
|
126350
|
+
}
|
|
126351
|
+
effects.enter('htmlBlockComponentData');
|
|
126352
|
+
return body(code);
|
|
126353
|
+
}
|
|
126354
|
+
function continuationAfter(code) {
|
|
126355
|
+
if (code === null)
|
|
126356
|
+
return nok(code);
|
|
126357
|
+
effects.exit('htmlBlockComponent');
|
|
126358
|
+
return ok(code);
|
|
126359
|
+
}
|
|
126360
|
+
// -- shared exit --------------------------------------------------------
|
|
126361
|
+
function done(_code) {
|
|
126362
|
+
effects.exit('htmlBlockComponentData');
|
|
126363
|
+
effects.exit('htmlBlockComponent');
|
|
126364
|
+
return ok(_code);
|
|
126365
|
+
}
|
|
126366
|
+
};
|
|
126367
|
+
}
|
|
126368
|
+
// ---------------------------------------------------------------------------
|
|
126369
|
+
// Flow construct (block-level)
|
|
126370
|
+
// ---------------------------------------------------------------------------
|
|
126371
|
+
const html_block_component_syntax_nonLazyContinuationStart = {
|
|
126372
|
+
tokenize: html_block_component_syntax_tokenizeNonLazyContinuationStart,
|
|
126373
|
+
partial: true,
|
|
126374
|
+
};
|
|
126375
|
+
function resolveToHtmlBlockComponent(events) {
|
|
126376
|
+
let index = events.length;
|
|
126377
|
+
while (index > 0) {
|
|
126378
|
+
index -= 1;
|
|
126379
|
+
if (events[index][0] === 'enter' && events[index][1].type === 'htmlBlockComponent') {
|
|
126380
|
+
break;
|
|
126381
|
+
}
|
|
126382
|
+
}
|
|
126383
|
+
if (index > 1 && events[index - 2][1].type === types_types.linePrefix) {
|
|
126384
|
+
events[index][1].start = events[index - 2][1].start;
|
|
126385
|
+
events[index + 1][1].start = events[index - 2][1].start;
|
|
126386
|
+
events.splice(index - 2, 2);
|
|
126387
|
+
}
|
|
126388
|
+
return events;
|
|
126389
|
+
}
|
|
126390
|
+
const htmlBlockComponentFlowConstruct = {
|
|
126391
|
+
name: 'htmlBlockComponent',
|
|
126392
|
+
tokenize: syntax_createTokenize('flow'),
|
|
126393
|
+
resolveTo: resolveToHtmlBlockComponent,
|
|
126394
|
+
concrete: true,
|
|
126395
|
+
};
|
|
126396
|
+
function html_block_component_syntax_tokenizeNonLazyContinuationStart(effects, ok, nok) {
|
|
126397
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
126398
|
+
const self = this;
|
|
126399
|
+
return start;
|
|
126400
|
+
function start(code) {
|
|
126401
|
+
if (markdownLineEnding(code)) {
|
|
126402
|
+
effects.enter(types_types.lineEnding);
|
|
126403
|
+
effects.consume(code);
|
|
126404
|
+
effects.exit(types_types.lineEnding);
|
|
126405
|
+
return after;
|
|
126406
|
+
}
|
|
126407
|
+
return nok(code);
|
|
126408
|
+
}
|
|
126409
|
+
function after(code) {
|
|
126410
|
+
if (self.parser.lazy[self.now().line]) {
|
|
126411
|
+
return nok(code);
|
|
126412
|
+
}
|
|
126413
|
+
return ok(code);
|
|
126414
|
+
}
|
|
126415
|
+
}
|
|
126416
|
+
// ---------------------------------------------------------------------------
|
|
126417
|
+
// Text construct (inline)
|
|
126418
|
+
// ---------------------------------------------------------------------------
|
|
126419
|
+
const htmlBlockComponentTextConstruct = {
|
|
126420
|
+
name: 'htmlBlockComponent',
|
|
126421
|
+
tokenize: syntax_createTokenize('text'),
|
|
126422
|
+
};
|
|
126423
|
+
// ---------------------------------------------------------------------------
|
|
126424
|
+
// Extension
|
|
126425
|
+
// ---------------------------------------------------------------------------
|
|
126426
|
+
function syntax_htmlBlockComponent() {
|
|
126427
|
+
return {
|
|
126428
|
+
flow: {
|
|
126429
|
+
[codes.lessThan]: [htmlBlockComponentFlowConstruct],
|
|
126430
|
+
},
|
|
126431
|
+
text: {
|
|
126432
|
+
[codes.lessThan]: [htmlBlockComponentTextConstruct],
|
|
125723
126433
|
},
|
|
125724
126434
|
};
|
|
125725
126435
|
}
|
|
125726
126436
|
|
|
126437
|
+
;// ./lib/micromark/html-block-component/index.ts
|
|
126438
|
+
|
|
126439
|
+
|
|
125727
126440
|
;// ./lib/micromark/jsx-comment/syntax.ts
|
|
125728
126441
|
|
|
125729
126442
|
|
|
@@ -125745,7 +126458,7 @@ function jsx_table_jsxTableFromMarkdown() {
|
|
|
125745
126458
|
function tokenizeJsxComment(effects, ok, nok) {
|
|
125746
126459
|
return start;
|
|
125747
126460
|
function start(code) {
|
|
125748
|
-
if (code !==
|
|
126461
|
+
if (code !== codes.leftCurlyBrace)
|
|
125749
126462
|
return nok(code);
|
|
125750
126463
|
effects.enter('mdxFlowExpression');
|
|
125751
126464
|
effects.enter('mdxFlowExpressionMarker');
|
|
@@ -125754,7 +126467,7 @@ function tokenizeJsxComment(effects, ok, nok) {
|
|
|
125754
126467
|
return expectSlash;
|
|
125755
126468
|
}
|
|
125756
126469
|
function expectSlash(code) {
|
|
125757
|
-
if (code !==
|
|
126470
|
+
if (code !== codes.slash) {
|
|
125758
126471
|
effects.exit('mdxFlowExpression');
|
|
125759
126472
|
return nok(code);
|
|
125760
126473
|
}
|
|
@@ -125763,7 +126476,7 @@ function tokenizeJsxComment(effects, ok, nok) {
|
|
|
125763
126476
|
return expectStar;
|
|
125764
126477
|
}
|
|
125765
126478
|
function expectStar(code) {
|
|
125766
|
-
if (code !==
|
|
126479
|
+
if (code !== codes.asterisk) {
|
|
125767
126480
|
effects.exit('mdxFlowExpressionChunk');
|
|
125768
126481
|
effects.exit('mdxFlowExpression');
|
|
125769
126482
|
return nok(code);
|
|
@@ -125790,7 +126503,7 @@ function tokenizeJsxComment(effects, ok, nok) {
|
|
|
125790
126503
|
effects.exit('mdxFlowExpressionChunk');
|
|
125791
126504
|
return before(code);
|
|
125792
126505
|
}
|
|
125793
|
-
if (code ===
|
|
126506
|
+
if (code === codes.asterisk) {
|
|
125794
126507
|
effects.consume(code);
|
|
125795
126508
|
return maybeClosed;
|
|
125796
126509
|
}
|
|
@@ -125802,11 +126515,11 @@ function tokenizeJsxComment(effects, ok, nok) {
|
|
|
125802
126515
|
effects.exit('mdxFlowExpressionChunk');
|
|
125803
126516
|
return before(code);
|
|
125804
126517
|
}
|
|
125805
|
-
if (code ===
|
|
126518
|
+
if (code === codes.slash) {
|
|
125806
126519
|
effects.consume(code);
|
|
125807
126520
|
return expectClosingBrace;
|
|
125808
126521
|
}
|
|
125809
|
-
if (code ===
|
|
126522
|
+
if (code === codes.asterisk) {
|
|
125810
126523
|
effects.consume(code);
|
|
125811
126524
|
return maybeClosed;
|
|
125812
126525
|
}
|
|
@@ -125818,7 +126531,7 @@ function tokenizeJsxComment(effects, ok, nok) {
|
|
|
125818
126531
|
effects.exit('mdxFlowExpressionChunk');
|
|
125819
126532
|
return before(code);
|
|
125820
126533
|
}
|
|
125821
|
-
if (code ===
|
|
126534
|
+
if (code === codes.rightCurlyBrace) {
|
|
125822
126535
|
effects.exit('mdxFlowExpressionChunk');
|
|
125823
126536
|
effects.enter('mdxFlowExpressionMarker');
|
|
125824
126537
|
effects.consume(code);
|
|
@@ -125826,7 +126539,7 @@ function tokenizeJsxComment(effects, ok, nok) {
|
|
|
125826
126539
|
effects.exit('mdxFlowExpression');
|
|
125827
126540
|
return ok;
|
|
125828
126541
|
}
|
|
125829
|
-
if (code ===
|
|
126542
|
+
if (code === codes.asterisk) {
|
|
125830
126543
|
effects.consume(code);
|
|
125831
126544
|
return maybeClosed;
|
|
125832
126545
|
}
|
|
@@ -125837,7 +126550,7 @@ function tokenizeJsxComment(effects, ok, nok) {
|
|
|
125837
126550
|
function jsxComment() {
|
|
125838
126551
|
return {
|
|
125839
126552
|
flow: {
|
|
125840
|
-
[
|
|
126553
|
+
[codes.leftCurlyBrace]: {
|
|
125841
126554
|
name: 'jsxComment',
|
|
125842
126555
|
concrete: true,
|
|
125843
126556
|
tokenize: tokenizeJsxComment,
|
|
@@ -125846,243 +126559,6 @@ function jsxComment() {
|
|
|
125846
126559
|
};
|
|
125847
126560
|
}
|
|
125848
126561
|
|
|
125849
|
-
;// ./lib/micromark/jsx-table/syntax.ts
|
|
125850
|
-
|
|
125851
|
-
|
|
125852
|
-
const jsx_table_syntax_nonLazyContinuationStart = {
|
|
125853
|
-
tokenize: jsx_table_syntax_tokenizeNonLazyContinuationStart,
|
|
125854
|
-
partial: true,
|
|
125855
|
-
};
|
|
125856
|
-
function resolveToJsxTable(events) {
|
|
125857
|
-
let index = events.length;
|
|
125858
|
-
while (index > 0) {
|
|
125859
|
-
index -= 1;
|
|
125860
|
-
if (events[index][0] === 'enter' && events[index][1].type === 'jsxTable') {
|
|
125861
|
-
break;
|
|
125862
|
-
}
|
|
125863
|
-
}
|
|
125864
|
-
if (index > 1 && events[index - 2][1].type === types_types.linePrefix) {
|
|
125865
|
-
events[index][1].start = events[index - 2][1].start;
|
|
125866
|
-
events[index + 1][1].start = events[index - 2][1].start;
|
|
125867
|
-
events.splice(index - 2, 2);
|
|
125868
|
-
}
|
|
125869
|
-
return events;
|
|
125870
|
-
}
|
|
125871
|
-
const jsxTableConstruct = {
|
|
125872
|
-
name: 'jsxTable',
|
|
125873
|
-
tokenize: tokenizeJsxTable,
|
|
125874
|
-
resolveTo: resolveToJsxTable,
|
|
125875
|
-
concrete: true,
|
|
125876
|
-
};
|
|
125877
|
-
function tokenizeJsxTable(effects, ok, nok) {
|
|
125878
|
-
let codeSpanOpenSize = 0;
|
|
125879
|
-
let codeSpanCloseSize = 0;
|
|
125880
|
-
let depth = 1;
|
|
125881
|
-
const ABLE_SUFFIX = [codes_codes.lowercaseA, codes_codes.lowercaseB, codes_codes.lowercaseL, codes_codes.lowercaseE];
|
|
125882
|
-
/** Build a state chain that matches a sequence of character codes. */
|
|
125883
|
-
function matchChars(chars, onMatch, onFail) {
|
|
125884
|
-
if (chars.length === 0)
|
|
125885
|
-
return onMatch;
|
|
125886
|
-
return ((code) => {
|
|
125887
|
-
if (code === chars[0]) {
|
|
125888
|
-
effects.consume(code);
|
|
125889
|
-
return matchChars(chars.slice(1), onMatch, onFail);
|
|
125890
|
-
}
|
|
125891
|
-
return onFail(code);
|
|
125892
|
-
});
|
|
125893
|
-
}
|
|
125894
|
-
return start;
|
|
125895
|
-
function start(code) {
|
|
125896
|
-
if (code !== codes_codes.lessThan)
|
|
125897
|
-
return nok(code);
|
|
125898
|
-
effects.enter('jsxTable');
|
|
125899
|
-
effects.enter('jsxTableData');
|
|
125900
|
-
effects.consume(code);
|
|
125901
|
-
return afterLessThan;
|
|
125902
|
-
}
|
|
125903
|
-
function afterLessThan(code) {
|
|
125904
|
-
if (code === codes_codes.uppercaseT || code === codes_codes.lowercaseT) {
|
|
125905
|
-
effects.consume(code);
|
|
125906
|
-
return matchChars(ABLE_SUFFIX, afterTagName, nok);
|
|
125907
|
-
}
|
|
125908
|
-
return nok(code);
|
|
125909
|
-
}
|
|
125910
|
-
function afterTagName(code) {
|
|
125911
|
-
if (code === codes_codes.greaterThan || code === codes_codes.slash || code === codes_codes.space || code === codes_codes.horizontalTab) {
|
|
125912
|
-
effects.consume(code);
|
|
125913
|
-
return body;
|
|
125914
|
-
}
|
|
125915
|
-
return nok(code);
|
|
125916
|
-
}
|
|
125917
|
-
function body(code) {
|
|
125918
|
-
// Reject unclosed <Table> so it falls back to normal HTML block parsing
|
|
125919
|
-
// instead of swallowing all subsequent content to EOF
|
|
125920
|
-
if (code === null) {
|
|
125921
|
-
return nok(code);
|
|
125922
|
-
}
|
|
125923
|
-
if (markdownLineEnding(code)) {
|
|
125924
|
-
effects.exit('jsxTableData');
|
|
125925
|
-
return continuationStart(code);
|
|
125926
|
-
}
|
|
125927
|
-
if (code === codes_codes.backslash) {
|
|
125928
|
-
effects.consume(code);
|
|
125929
|
-
return escapedChar;
|
|
125930
|
-
}
|
|
125931
|
-
if (code === codes_codes.lessThan) {
|
|
125932
|
-
effects.consume(code);
|
|
125933
|
-
return closeSlash;
|
|
125934
|
-
}
|
|
125935
|
-
// Skip over backtick code spans so `</Table>` in inline code isn't
|
|
125936
|
-
// treated as the closing tag
|
|
125937
|
-
if (code === codes_codes.graveAccent) {
|
|
125938
|
-
codeSpanOpenSize = 0;
|
|
125939
|
-
return countOpenTicks(code);
|
|
125940
|
-
}
|
|
125941
|
-
effects.consume(code);
|
|
125942
|
-
return body;
|
|
125943
|
-
}
|
|
125944
|
-
function countOpenTicks(code) {
|
|
125945
|
-
if (code === codes_codes.graveAccent) {
|
|
125946
|
-
codeSpanOpenSize += 1;
|
|
125947
|
-
effects.consume(code);
|
|
125948
|
-
return countOpenTicks;
|
|
125949
|
-
}
|
|
125950
|
-
return inCodeSpan(code);
|
|
125951
|
-
}
|
|
125952
|
-
function inCodeSpan(code) {
|
|
125953
|
-
if (code === null || markdownLineEnding(code))
|
|
125954
|
-
return body(code);
|
|
125955
|
-
if (code === codes_codes.graveAccent) {
|
|
125956
|
-
codeSpanCloseSize = 0;
|
|
125957
|
-
return countCloseTicks(code);
|
|
125958
|
-
}
|
|
125959
|
-
effects.consume(code);
|
|
125960
|
-
return inCodeSpan;
|
|
125961
|
-
}
|
|
125962
|
-
function countCloseTicks(code) {
|
|
125963
|
-
if (code === codes_codes.graveAccent) {
|
|
125964
|
-
codeSpanCloseSize += 1;
|
|
125965
|
-
effects.consume(code);
|
|
125966
|
-
return countCloseTicks;
|
|
125967
|
-
}
|
|
125968
|
-
return codeSpanCloseSize === codeSpanOpenSize ? body(code) : inCodeSpan(code);
|
|
125969
|
-
}
|
|
125970
|
-
function escapedChar(code) {
|
|
125971
|
-
if (code === null || markdownLineEnding(code)) {
|
|
125972
|
-
return body(code);
|
|
125973
|
-
}
|
|
125974
|
-
effects.consume(code);
|
|
125975
|
-
return body;
|
|
125976
|
-
}
|
|
125977
|
-
function closeSlash(code) {
|
|
125978
|
-
if (code === codes_codes.slash) {
|
|
125979
|
-
effects.consume(code);
|
|
125980
|
-
return closeTagFirstChar;
|
|
125981
|
-
}
|
|
125982
|
-
if (code === codes_codes.uppercaseT || code === codes_codes.lowercaseT) {
|
|
125983
|
-
effects.consume(code);
|
|
125984
|
-
return matchChars(ABLE_SUFFIX, openAfterTagName, body);
|
|
125985
|
-
}
|
|
125986
|
-
return body(code);
|
|
125987
|
-
}
|
|
125988
|
-
function closeTagFirstChar(code) {
|
|
125989
|
-
if (code === codes_codes.uppercaseT || code === codes_codes.lowercaseT) {
|
|
125990
|
-
effects.consume(code);
|
|
125991
|
-
return matchChars(ABLE_SUFFIX, closeGt, body);
|
|
125992
|
-
}
|
|
125993
|
-
return body(code);
|
|
125994
|
-
}
|
|
125995
|
-
function openAfterTagName(code) {
|
|
125996
|
-
if (code === codes_codes.greaterThan || code === codes_codes.slash || code === codes_codes.space || code === codes_codes.horizontalTab) {
|
|
125997
|
-
depth += 1;
|
|
125998
|
-
effects.consume(code);
|
|
125999
|
-
return body;
|
|
126000
|
-
}
|
|
126001
|
-
return body(code);
|
|
126002
|
-
}
|
|
126003
|
-
function closeGt(code) {
|
|
126004
|
-
if (code === codes_codes.greaterThan) {
|
|
126005
|
-
depth -= 1;
|
|
126006
|
-
effects.consume(code);
|
|
126007
|
-
if (depth === 0) {
|
|
126008
|
-
return afterClose;
|
|
126009
|
-
}
|
|
126010
|
-
return body;
|
|
126011
|
-
}
|
|
126012
|
-
return body(code);
|
|
126013
|
-
}
|
|
126014
|
-
function afterClose(code) {
|
|
126015
|
-
if (code === null || markdownLineEnding(code)) {
|
|
126016
|
-
effects.exit('jsxTableData');
|
|
126017
|
-
effects.exit('jsxTable');
|
|
126018
|
-
return ok(code);
|
|
126019
|
-
}
|
|
126020
|
-
effects.consume(code);
|
|
126021
|
-
return afterClose;
|
|
126022
|
-
}
|
|
126023
|
-
// Line ending handling — follows the htmlFlow pattern
|
|
126024
|
-
function continuationStart(code) {
|
|
126025
|
-
return effects.check(jsx_table_syntax_nonLazyContinuationStart, continuationStartNonLazy, continuationAfter)(code);
|
|
126026
|
-
}
|
|
126027
|
-
function continuationStartNonLazy(code) {
|
|
126028
|
-
effects.enter(types_types.lineEnding);
|
|
126029
|
-
effects.consume(code);
|
|
126030
|
-
effects.exit(types_types.lineEnding);
|
|
126031
|
-
return continuationBefore;
|
|
126032
|
-
}
|
|
126033
|
-
function continuationBefore(code) {
|
|
126034
|
-
if (code === null || markdownLineEnding(code)) {
|
|
126035
|
-
return continuationStart(code);
|
|
126036
|
-
}
|
|
126037
|
-
effects.enter('jsxTableData');
|
|
126038
|
-
return body(code);
|
|
126039
|
-
}
|
|
126040
|
-
function continuationAfter(code) {
|
|
126041
|
-
// At EOF without </Table>, reject so content isn't swallowed
|
|
126042
|
-
if (code === null) {
|
|
126043
|
-
return nok(code);
|
|
126044
|
-
}
|
|
126045
|
-
effects.exit('jsxTable');
|
|
126046
|
-
return ok(code);
|
|
126047
|
-
}
|
|
126048
|
-
}
|
|
126049
|
-
function jsx_table_syntax_tokenizeNonLazyContinuationStart(effects, ok, nok) {
|
|
126050
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
126051
|
-
const self = this;
|
|
126052
|
-
return start;
|
|
126053
|
-
function start(code) {
|
|
126054
|
-
if (markdownLineEnding(code)) {
|
|
126055
|
-
effects.enter(types_types.lineEnding);
|
|
126056
|
-
effects.consume(code);
|
|
126057
|
-
effects.exit(types_types.lineEnding);
|
|
126058
|
-
return after;
|
|
126059
|
-
}
|
|
126060
|
-
return nok(code);
|
|
126061
|
-
}
|
|
126062
|
-
function after(code) {
|
|
126063
|
-
if (self.parser.lazy[self.now().line]) {
|
|
126064
|
-
return nok(code);
|
|
126065
|
-
}
|
|
126066
|
-
return ok(code);
|
|
126067
|
-
}
|
|
126068
|
-
}
|
|
126069
|
-
/**
|
|
126070
|
-
* Micromark extension that tokenizes `<Table>...</Table>` and `<table>...</table>`
|
|
126071
|
-
* as a single flow block.
|
|
126072
|
-
*
|
|
126073
|
-
* Prevents CommonMark HTML block type 6 from fragmenting table blocks at blank lines.
|
|
126074
|
-
*/
|
|
126075
|
-
function syntax_jsxTable() {
|
|
126076
|
-
return {
|
|
126077
|
-
flow: {
|
|
126078
|
-
[codes_codes.lessThan]: [jsxTableConstruct],
|
|
126079
|
-
},
|
|
126080
|
-
};
|
|
126081
|
-
}
|
|
126082
|
-
|
|
126083
|
-
;// ./lib/micromark/jsx-table/index.ts
|
|
126084
|
-
|
|
126085
|
-
|
|
126086
126562
|
;// ./lib/micromark/mdx-expression-lenient/syntax.ts
|
|
126087
126563
|
|
|
126088
126564
|
|
|
@@ -126102,7 +126578,7 @@ function tokenizeTextExpression(effects, ok, nok) {
|
|
|
126102
126578
|
let depth = 0;
|
|
126103
126579
|
return start;
|
|
126104
126580
|
function start(code) {
|
|
126105
|
-
if (code !==
|
|
126581
|
+
if (code !== codes.leftCurlyBrace)
|
|
126106
126582
|
return nok(code);
|
|
126107
126583
|
effects.enter('mdxTextExpression');
|
|
126108
126584
|
effects.enter('mdxTextExpressionMarker');
|
|
@@ -126111,7 +126587,7 @@ function tokenizeTextExpression(effects, ok, nok) {
|
|
|
126111
126587
|
return before;
|
|
126112
126588
|
}
|
|
126113
126589
|
function before(code) {
|
|
126114
|
-
if (code ===
|
|
126590
|
+
if (code === codes.eof) {
|
|
126115
126591
|
effects.exit('mdxTextExpression');
|
|
126116
126592
|
return nok(code);
|
|
126117
126593
|
}
|
|
@@ -126121,24 +126597,24 @@ function tokenizeTextExpression(effects, ok, nok) {
|
|
|
126121
126597
|
effects.exit('lineEnding');
|
|
126122
126598
|
return before;
|
|
126123
126599
|
}
|
|
126124
|
-
if (code ===
|
|
126600
|
+
if (code === codes.rightCurlyBrace && depth === 0) {
|
|
126125
126601
|
return close(code);
|
|
126126
126602
|
}
|
|
126127
126603
|
effects.enter('mdxTextExpressionChunk');
|
|
126128
126604
|
return inside(code);
|
|
126129
126605
|
}
|
|
126130
126606
|
function inside(code) {
|
|
126131
|
-
if (code ===
|
|
126607
|
+
if (code === codes.eof || markdownLineEnding(code)) {
|
|
126132
126608
|
effects.exit('mdxTextExpressionChunk');
|
|
126133
126609
|
return before(code);
|
|
126134
126610
|
}
|
|
126135
|
-
if (code ===
|
|
126611
|
+
if (code === codes.rightCurlyBrace && depth === 0) {
|
|
126136
126612
|
effects.exit('mdxTextExpressionChunk');
|
|
126137
126613
|
return close(code);
|
|
126138
126614
|
}
|
|
126139
|
-
if (code ===
|
|
126615
|
+
if (code === codes.leftCurlyBrace)
|
|
126140
126616
|
depth += 1;
|
|
126141
|
-
else if (code ===
|
|
126617
|
+
else if (code === codes.rightCurlyBrace)
|
|
126142
126618
|
depth -= 1;
|
|
126143
126619
|
effects.consume(code);
|
|
126144
126620
|
return inside;
|
|
@@ -126154,7 +126630,7 @@ function tokenizeTextExpression(effects, ok, nok) {
|
|
|
126154
126630
|
function mdxExpressionLenient() {
|
|
126155
126631
|
return {
|
|
126156
126632
|
text: {
|
|
126157
|
-
[
|
|
126633
|
+
[codes.leftCurlyBrace]: {
|
|
126158
126634
|
name: 'mdxTextExpression',
|
|
126159
126635
|
tokenize: tokenizeTextExpression,
|
|
126160
126636
|
},
|
|
@@ -126258,6 +126734,9 @@ function loadComponents() {
|
|
|
126258
126734
|
|
|
126259
126735
|
|
|
126260
126736
|
|
|
126737
|
+
|
|
126738
|
+
|
|
126739
|
+
|
|
126261
126740
|
|
|
126262
126741
|
|
|
126263
126742
|
|
|
@@ -126272,15 +126751,19 @@ const defaultTransformers = [
|
|
|
126272
126751
|
* CommonMark/remark limitations and reach parity with legacy (rdmd) rendering.
|
|
126273
126752
|
*
|
|
126274
126753
|
* Runs a series of string-level transformations before micromark/remark parsing:
|
|
126275
|
-
* 1.
|
|
126276
|
-
* 2.
|
|
126277
|
-
* 3.
|
|
126278
|
-
* 4.
|
|
126279
|
-
* 5.
|
|
126754
|
+
* 1. Canonicalize closing tags with stray whitespace (e.g., `</ td >` → `</td>`)
|
|
126755
|
+
* 2. Normalize malformed table separator syntax (e.g., `|: ---` → `| :---`)
|
|
126756
|
+
* 3. Terminate HTML flow blocks so subsequent content isn't swallowed
|
|
126757
|
+
* 4. Close invalid "self-closing" HTML tags (e.g., `<i />` → `<i></i>`)
|
|
126758
|
+
* 5. Normalize compact ATX headings (e.g., `#Heading` → `# Heading`)
|
|
126759
|
+
* 6. Replace snake_case component names with parser-safe placeholders
|
|
126280
126760
|
*/
|
|
126281
126761
|
function preprocessContent(content, opts) {
|
|
126282
126762
|
const { knownComponents } = opts;
|
|
126283
|
-
|
|
126763
|
+
// Runs first so `jsxTable` sees a literal `</table>` (and the HTML-line
|
|
126764
|
+
// classification in `terminateHtmlFlowBlocks` is accurate)
|
|
126765
|
+
let result = normalizeClosingTagWhitespace(content);
|
|
126766
|
+
result = normalizeTableSeparator(result);
|
|
126284
126767
|
result = terminateHtmlFlowBlocks(result);
|
|
126285
126768
|
result = closeSelfClosingHtmlTags(result);
|
|
126286
126769
|
result = normalizeCompactHeadings(result);
|
|
@@ -126309,6 +126792,7 @@ function mdxishAstProcessor(mdContent, opts = {}) {
|
|
|
126309
126792
|
syntax_gemoji(),
|
|
126310
126793
|
legacyVariable(),
|
|
126311
126794
|
looseHtmlEntity(),
|
|
126795
|
+
syntax_htmlBlockComponent(),
|
|
126312
126796
|
];
|
|
126313
126797
|
const fromMarkdownExts = [
|
|
126314
126798
|
jsx_table_jsxTableFromMarkdown(),
|
|
@@ -126318,6 +126802,7 @@ function mdxishAstProcessor(mdContent, opts = {}) {
|
|
|
126318
126802
|
legacyVariableFromMarkdown(),
|
|
126319
126803
|
emptyTaskListItemFromMarkdown(),
|
|
126320
126804
|
looseHtmlEntityFromMarkdown(),
|
|
126805
|
+
html_block_component_htmlBlockComponentFromMarkdown(),
|
|
126321
126806
|
];
|
|
126322
126807
|
if (!safeMode) {
|
|
126323
126808
|
// Insert mdx expression (text-only, no flow) after gemoji at index 3
|
|
@@ -126331,6 +126816,10 @@ function mdxishAstProcessor(mdContent, opts = {}) {
|
|
|
126331
126816
|
// JSX comment tokenizer must come before magicBlock so it claims `{/* ... */}` first
|
|
126332
126817
|
micromarkExts.unshift(jsxComment());
|
|
126333
126818
|
}
|
|
126819
|
+
// Claim `<HTMLBlock>` as one opaque token so broad tokenizers can't fragment its body
|
|
126820
|
+
// We put this last as micromark tries the last-registered extension first, so push (not unshift) to win the `<` race.
|
|
126821
|
+
// micromarkExts.push(htmlBlockComponent());
|
|
126822
|
+
// fromMarkdownExts.push(htmlBlockComponentFromMarkdown());
|
|
126334
126823
|
const processor = lib_unified()
|
|
126335
126824
|
.data('micromarkExtensions', micromarkExts)
|
|
126336
126825
|
.data('fromMarkdownExtensions', fromMarkdownExts)
|
|
@@ -126386,6 +126875,12 @@ function mdxishMdastToMd(mdast) {
|
|
|
126386
126875
|
.use(remarkStringify, {
|
|
126387
126876
|
bullet: '-',
|
|
126388
126877
|
emphasis: '_',
|
|
126878
|
+
// Escape literal braces in text so they don't parse as (often
|
|
126879
|
+
// unterminated) MDX expressions on the next round trip.
|
|
126880
|
+
unsafe: [
|
|
126881
|
+
{ character: '{', inConstruct: 'phrasing' },
|
|
126882
|
+
{ character: '}', inConstruct: 'phrasing' },
|
|
126883
|
+
],
|
|
126389
126884
|
});
|
|
126390
126885
|
return processor.stringify(processor.runSync(mdast));
|
|
126391
126886
|
}
|
|
@@ -126868,332 +127363,6 @@ const mdxishTags_tags = (doc) => {
|
|
|
126868
127363
|
};
|
|
126869
127364
|
/* harmony default export */ const mdxishTags = ((/* unused pure expression or super */ null && (mdxishTags_tags)));
|
|
126870
127365
|
|
|
126871
|
-
;// ./lib/mdast-util/html-block-component/index.ts
|
|
126872
|
-
const html_block_component_contextMap = new WeakMap();
|
|
126873
|
-
function findHtmlBlockComponentToken() {
|
|
126874
|
-
const events = this.tokenStack;
|
|
126875
|
-
for (let i = events.length - 1; i >= 0; i -= 1) {
|
|
126876
|
-
if (events[i][0].type === 'htmlBlockComponent')
|
|
126877
|
-
return events[i][0];
|
|
126878
|
-
}
|
|
126879
|
-
return undefined;
|
|
126880
|
-
}
|
|
126881
|
-
function enterHtmlBlockComponent(token) {
|
|
126882
|
-
html_block_component_contextMap.set(token, { chunks: [], lastEndLine: token.start.line });
|
|
126883
|
-
this.enter({ type: 'html', value: '' }, token);
|
|
126884
|
-
}
|
|
126885
|
-
function exitHtmlBlockComponentData(token) {
|
|
126886
|
-
const componentToken = findHtmlBlockComponentToken.call(this);
|
|
126887
|
-
if (!componentToken)
|
|
126888
|
-
return;
|
|
126889
|
-
const ctx = html_block_component_contextMap.get(componentToken);
|
|
126890
|
-
if (ctx) {
|
|
126891
|
-
const gap = token.start.line - ctx.lastEndLine;
|
|
126892
|
-
if (ctx.chunks.length > 0 && gap > 0) {
|
|
126893
|
-
ctx.chunks.push('\n'.repeat(gap));
|
|
126894
|
-
}
|
|
126895
|
-
ctx.chunks.push(this.sliceSerialize(token));
|
|
126896
|
-
ctx.lastEndLine = token.end.line;
|
|
126897
|
-
}
|
|
126898
|
-
}
|
|
126899
|
-
function exitHtmlBlockComponent(token) {
|
|
126900
|
-
const ctx = html_block_component_contextMap.get(token);
|
|
126901
|
-
const node = this.stack[this.stack.length - 1];
|
|
126902
|
-
if (ctx) {
|
|
126903
|
-
node.value = ctx.chunks.join('');
|
|
126904
|
-
html_block_component_contextMap.delete(token);
|
|
126905
|
-
}
|
|
126906
|
-
this.exit(token);
|
|
126907
|
-
}
|
|
126908
|
-
function html_block_component_htmlBlockComponentFromMarkdown() {
|
|
126909
|
-
return {
|
|
126910
|
-
enter: {
|
|
126911
|
-
htmlBlockComponent: enterHtmlBlockComponent,
|
|
126912
|
-
},
|
|
126913
|
-
exit: {
|
|
126914
|
-
htmlBlockComponentData: exitHtmlBlockComponentData,
|
|
126915
|
-
htmlBlockComponent: exitHtmlBlockComponent,
|
|
126916
|
-
},
|
|
126917
|
-
};
|
|
126918
|
-
}
|
|
126919
|
-
|
|
126920
|
-
;// ./lib/micromark/html-block-component/syntax.ts
|
|
126921
|
-
|
|
126922
|
-
|
|
126923
|
-
const TAG_SUFFIX = [
|
|
126924
|
-
codes_codes.uppercaseT,
|
|
126925
|
-
codes_codes.uppercaseM,
|
|
126926
|
-
codes_codes.uppercaseL,
|
|
126927
|
-
codes_codes.uppercaseB,
|
|
126928
|
-
codes_codes.lowercaseL,
|
|
126929
|
-
codes_codes.lowercaseO,
|
|
126930
|
-
codes_codes.lowercaseC,
|
|
126931
|
-
codes_codes.lowercaseK,
|
|
126932
|
-
];
|
|
126933
|
-
// ---------------------------------------------------------------------------
|
|
126934
|
-
// Shared tokenizer factory
|
|
126935
|
-
// ---------------------------------------------------------------------------
|
|
126936
|
-
/**
|
|
126937
|
-
* Creates a tokenize function for `<HTMLBlock>...</HTMLBlock>`.
|
|
126938
|
-
*
|
|
126939
|
-
* - **flow** (block-level): supports multiline content via line continuations,
|
|
126940
|
-
* consumes trailing whitespace after the closing tag.
|
|
126941
|
-
* - **text** (inline): single-line only, exits immediately after the closing tag.
|
|
126942
|
-
*/
|
|
126943
|
-
function syntax_createTokenize(mode) {
|
|
126944
|
-
return function tokenize(effects, ok, nok) {
|
|
126945
|
-
let depth = 1;
|
|
126946
|
-
function matchChars(chars, onMatch, onFail) {
|
|
126947
|
-
if (chars.length === 0)
|
|
126948
|
-
return onMatch;
|
|
126949
|
-
const next = (code) => {
|
|
126950
|
-
if (code === chars[0]) {
|
|
126951
|
-
effects.consume(code);
|
|
126952
|
-
return matchChars(chars.slice(1), onMatch, onFail);
|
|
126953
|
-
}
|
|
126954
|
-
return onFail(code);
|
|
126955
|
-
};
|
|
126956
|
-
return next;
|
|
126957
|
-
}
|
|
126958
|
-
function matchTagName(onMatch, onFail) {
|
|
126959
|
-
const next = (code) => {
|
|
126960
|
-
if (code === codes_codes.uppercaseH) {
|
|
126961
|
-
effects.consume(code);
|
|
126962
|
-
return matchChars(TAG_SUFFIX, onMatch, onFail);
|
|
126963
|
-
}
|
|
126964
|
-
return onFail(code);
|
|
126965
|
-
};
|
|
126966
|
-
return next;
|
|
126967
|
-
}
|
|
126968
|
-
return start;
|
|
126969
|
-
function start(code) {
|
|
126970
|
-
if (code !== codes_codes.lessThan)
|
|
126971
|
-
return nok(code);
|
|
126972
|
-
effects.enter('htmlBlockComponent');
|
|
126973
|
-
effects.enter('htmlBlockComponentData');
|
|
126974
|
-
effects.consume(code);
|
|
126975
|
-
return matchTagName(afterTagName, nok);
|
|
126976
|
-
}
|
|
126977
|
-
function afterTagName(code) {
|
|
126978
|
-
if (code === codes_codes.greaterThan) {
|
|
126979
|
-
effects.consume(code);
|
|
126980
|
-
return body;
|
|
126981
|
-
}
|
|
126982
|
-
if (code === codes_codes.space || code === codes_codes.horizontalTab) {
|
|
126983
|
-
effects.consume(code);
|
|
126984
|
-
return inAttributes;
|
|
126985
|
-
}
|
|
126986
|
-
if (mode === 'flow' && markdownLineEnding(code)) {
|
|
126987
|
-
effects.exit('htmlBlockComponentData');
|
|
126988
|
-
return attributeContinuationStart(code);
|
|
126989
|
-
}
|
|
126990
|
-
if (code === codes_codes.slash) {
|
|
126991
|
-
effects.consume(code);
|
|
126992
|
-
return selfClose;
|
|
126993
|
-
}
|
|
126994
|
-
return nok(code);
|
|
126995
|
-
}
|
|
126996
|
-
function inAttributes(code) {
|
|
126997
|
-
if (code === codes_codes.greaterThan) {
|
|
126998
|
-
effects.consume(code);
|
|
126999
|
-
return body;
|
|
127000
|
-
}
|
|
127001
|
-
if (code === null) {
|
|
127002
|
-
return nok(code);
|
|
127003
|
-
}
|
|
127004
|
-
if (markdownLineEnding(code)) {
|
|
127005
|
-
if (mode === 'text')
|
|
127006
|
-
return nok(code);
|
|
127007
|
-
effects.exit('htmlBlockComponentData');
|
|
127008
|
-
return attributeContinuationStart(code);
|
|
127009
|
-
}
|
|
127010
|
-
effects.consume(code);
|
|
127011
|
-
return inAttributes;
|
|
127012
|
-
}
|
|
127013
|
-
function attributeContinuationStart(code) {
|
|
127014
|
-
return effects.check(html_block_component_syntax_nonLazyContinuationStart, attributeContinuationNonLazy, continuationAfter)(code);
|
|
127015
|
-
}
|
|
127016
|
-
function attributeContinuationNonLazy(code) {
|
|
127017
|
-
effects.enter(types_types.lineEnding);
|
|
127018
|
-
effects.consume(code);
|
|
127019
|
-
effects.exit(types_types.lineEnding);
|
|
127020
|
-
return attributeContinuationBefore;
|
|
127021
|
-
}
|
|
127022
|
-
function attributeContinuationBefore(code) {
|
|
127023
|
-
if (code === null || markdownLineEnding(code)) {
|
|
127024
|
-
return attributeContinuationStart(code);
|
|
127025
|
-
}
|
|
127026
|
-
effects.enter('htmlBlockComponentData');
|
|
127027
|
-
return inAttributes(code);
|
|
127028
|
-
}
|
|
127029
|
-
function selfClose(code) {
|
|
127030
|
-
if (code === codes_codes.greaterThan) {
|
|
127031
|
-
effects.consume(code);
|
|
127032
|
-
return mode === 'flow' ? afterClose : done(code);
|
|
127033
|
-
}
|
|
127034
|
-
return nok(code);
|
|
127035
|
-
}
|
|
127036
|
-
function body(code) {
|
|
127037
|
-
if (code === null)
|
|
127038
|
-
return nok(code);
|
|
127039
|
-
if (markdownLineEnding(code)) {
|
|
127040
|
-
if (mode === 'text') {
|
|
127041
|
-
// Text constructs operate on paragraph content which spans lines
|
|
127042
|
-
effects.consume(code);
|
|
127043
|
-
return body;
|
|
127044
|
-
}
|
|
127045
|
-
effects.exit('htmlBlockComponentData');
|
|
127046
|
-
return continuationStart(code);
|
|
127047
|
-
}
|
|
127048
|
-
if (code === codes_codes.lessThan) {
|
|
127049
|
-
effects.consume(code);
|
|
127050
|
-
return closeSlash;
|
|
127051
|
-
}
|
|
127052
|
-
effects.consume(code);
|
|
127053
|
-
return body;
|
|
127054
|
-
}
|
|
127055
|
-
function closeSlash(code) {
|
|
127056
|
-
if (code === codes_codes.slash) {
|
|
127057
|
-
effects.consume(code);
|
|
127058
|
-
return matchTagName(closeGt, body);
|
|
127059
|
-
}
|
|
127060
|
-
return matchTagName(openAfterTagName, body)(code);
|
|
127061
|
-
}
|
|
127062
|
-
function openAfterTagName(code) {
|
|
127063
|
-
if (code === codes_codes.greaterThan || code === codes_codes.space || code === codes_codes.horizontalTab) {
|
|
127064
|
-
depth += 1;
|
|
127065
|
-
effects.consume(code);
|
|
127066
|
-
return body;
|
|
127067
|
-
}
|
|
127068
|
-
return body(code);
|
|
127069
|
-
}
|
|
127070
|
-
function closeGt(code) {
|
|
127071
|
-
if (code === codes_codes.greaterThan) {
|
|
127072
|
-
depth -= 1;
|
|
127073
|
-
effects.consume(code);
|
|
127074
|
-
if (depth === 0) {
|
|
127075
|
-
return mode === 'flow' ? afterClose : done(code);
|
|
127076
|
-
}
|
|
127077
|
-
return body;
|
|
127078
|
-
}
|
|
127079
|
-
return body(code);
|
|
127080
|
-
}
|
|
127081
|
-
// -- flow-only states ---------------------------------------------------
|
|
127082
|
-
function afterClose(code) {
|
|
127083
|
-
if (code === null || markdownLineEnding(code)) {
|
|
127084
|
-
return done(code);
|
|
127085
|
-
}
|
|
127086
|
-
if (code === codes_codes.space || code === codes_codes.horizontalTab) {
|
|
127087
|
-
effects.consume(code);
|
|
127088
|
-
return afterClose;
|
|
127089
|
-
}
|
|
127090
|
-
// Reject so the block re-parses as a paragraph, deferring to the
|
|
127091
|
-
// text tokenizer which preserves trailing content in the same line.
|
|
127092
|
-
return nok(code);
|
|
127093
|
-
}
|
|
127094
|
-
// -- flow-only: line continuation ---------------------------------------
|
|
127095
|
-
function continuationStart(code) {
|
|
127096
|
-
return effects.check(html_block_component_syntax_nonLazyContinuationStart, continuationStartNonLazy, continuationAfter)(code);
|
|
127097
|
-
}
|
|
127098
|
-
function continuationStartNonLazy(code) {
|
|
127099
|
-
effects.enter(types_types.lineEnding);
|
|
127100
|
-
effects.consume(code);
|
|
127101
|
-
effects.exit(types_types.lineEnding);
|
|
127102
|
-
return continuationBefore;
|
|
127103
|
-
}
|
|
127104
|
-
function continuationBefore(code) {
|
|
127105
|
-
if (code === null || markdownLineEnding(code)) {
|
|
127106
|
-
return continuationStart(code);
|
|
127107
|
-
}
|
|
127108
|
-
effects.enter('htmlBlockComponentData');
|
|
127109
|
-
return body(code);
|
|
127110
|
-
}
|
|
127111
|
-
function continuationAfter(code) {
|
|
127112
|
-
if (code === null)
|
|
127113
|
-
return nok(code);
|
|
127114
|
-
effects.exit('htmlBlockComponent');
|
|
127115
|
-
return ok(code);
|
|
127116
|
-
}
|
|
127117
|
-
// -- shared exit --------------------------------------------------------
|
|
127118
|
-
function done(_code) {
|
|
127119
|
-
effects.exit('htmlBlockComponentData');
|
|
127120
|
-
effects.exit('htmlBlockComponent');
|
|
127121
|
-
return ok(_code);
|
|
127122
|
-
}
|
|
127123
|
-
};
|
|
127124
|
-
}
|
|
127125
|
-
// ---------------------------------------------------------------------------
|
|
127126
|
-
// Flow construct (block-level)
|
|
127127
|
-
// ---------------------------------------------------------------------------
|
|
127128
|
-
const html_block_component_syntax_nonLazyContinuationStart = {
|
|
127129
|
-
tokenize: html_block_component_syntax_tokenizeNonLazyContinuationStart,
|
|
127130
|
-
partial: true,
|
|
127131
|
-
};
|
|
127132
|
-
function resolveToHtmlBlockComponent(events) {
|
|
127133
|
-
let index = events.length;
|
|
127134
|
-
while (index > 0) {
|
|
127135
|
-
index -= 1;
|
|
127136
|
-
if (events[index][0] === 'enter' && events[index][1].type === 'htmlBlockComponent') {
|
|
127137
|
-
break;
|
|
127138
|
-
}
|
|
127139
|
-
}
|
|
127140
|
-
if (index > 1 && events[index - 2][1].type === types_types.linePrefix) {
|
|
127141
|
-
events[index][1].start = events[index - 2][1].start;
|
|
127142
|
-
events[index + 1][1].start = events[index - 2][1].start;
|
|
127143
|
-
events.splice(index - 2, 2);
|
|
127144
|
-
}
|
|
127145
|
-
return events;
|
|
127146
|
-
}
|
|
127147
|
-
const htmlBlockComponentFlowConstruct = {
|
|
127148
|
-
name: 'htmlBlockComponent',
|
|
127149
|
-
tokenize: syntax_createTokenize('flow'),
|
|
127150
|
-
resolveTo: resolveToHtmlBlockComponent,
|
|
127151
|
-
concrete: true,
|
|
127152
|
-
};
|
|
127153
|
-
function html_block_component_syntax_tokenizeNonLazyContinuationStart(effects, ok, nok) {
|
|
127154
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
127155
|
-
const self = this;
|
|
127156
|
-
return start;
|
|
127157
|
-
function start(code) {
|
|
127158
|
-
if (markdownLineEnding(code)) {
|
|
127159
|
-
effects.enter(types_types.lineEnding);
|
|
127160
|
-
effects.consume(code);
|
|
127161
|
-
effects.exit(types_types.lineEnding);
|
|
127162
|
-
return after;
|
|
127163
|
-
}
|
|
127164
|
-
return nok(code);
|
|
127165
|
-
}
|
|
127166
|
-
function after(code) {
|
|
127167
|
-
if (self.parser.lazy[self.now().line]) {
|
|
127168
|
-
return nok(code);
|
|
127169
|
-
}
|
|
127170
|
-
return ok(code);
|
|
127171
|
-
}
|
|
127172
|
-
}
|
|
127173
|
-
// ---------------------------------------------------------------------------
|
|
127174
|
-
// Text construct (inline)
|
|
127175
|
-
// ---------------------------------------------------------------------------
|
|
127176
|
-
const htmlBlockComponentTextConstruct = {
|
|
127177
|
-
name: 'htmlBlockComponent',
|
|
127178
|
-
tokenize: syntax_createTokenize('text'),
|
|
127179
|
-
};
|
|
127180
|
-
// ---------------------------------------------------------------------------
|
|
127181
|
-
// Extension
|
|
127182
|
-
// ---------------------------------------------------------------------------
|
|
127183
|
-
function syntax_htmlBlockComponent() {
|
|
127184
|
-
return {
|
|
127185
|
-
flow: {
|
|
127186
|
-
[codes.lessThan]: [htmlBlockComponentFlowConstruct],
|
|
127187
|
-
},
|
|
127188
|
-
text: {
|
|
127189
|
-
[codes.lessThan]: [htmlBlockComponentTextConstruct],
|
|
127190
|
-
},
|
|
127191
|
-
};
|
|
127192
|
-
}
|
|
127193
|
-
|
|
127194
|
-
;// ./lib/micromark/html-block-component/index.ts
|
|
127195
|
-
|
|
127196
|
-
|
|
127197
127366
|
;// ./lib/stripComments.ts
|
|
127198
127367
|
|
|
127199
127368
|
|