@readme/markdown 14.11.3 → 14.11.4
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/Tabs/index.tsx +9 -2
- package/dist/339.node.js +2 -2
- package/dist/486.node.js +4 -4
- package/dist/main.js +470 -150
- package/dist/main.node.js +470 -150
- package/dist/main.node.js.map +1 -1
- package/dist/processor/transform/mdxish/react-element-to-hast.d.ts +8 -0
- package/dist/processor/transform/mdxish/tables/escape-crossing-emphasis.d.ts +15 -0
- package/dist/processor/transform/mdxish/tables/remap-positions.d.ts +3 -5
- package/dist/processor/transform/mdxish/tables/split-nested-tables.d.ts +11 -0
- package/dist/processor/utils.d.ts +7 -0
- package/dist/render-fixture.node.js +468 -148
- package/dist/render-fixture.node.js.map +1 -1
- package/package.json +1 -1
|
@@ -68490,6 +68490,21 @@ function evaluate(source, scope = {}) {
|
|
|
68490
68490
|
// eslint-disable-next-line no-new-func
|
|
68491
68491
|
return new Function(...names, `return (${source})`)(...values);
|
|
68492
68492
|
}
|
|
68493
|
+
/**
|
|
68494
|
+
* Advance a `Point` by the `consumed` substring that follows it, returning the
|
|
68495
|
+
* point at the consumed string's end. Lets split-out sub-nodes carry accurate
|
|
68496
|
+
* document positions so downstream offset shifting stays correct.
|
|
68497
|
+
*/
|
|
68498
|
+
const pointAfter = (start, consumed) => {
|
|
68499
|
+
const newlineIndex = consumed.lastIndexOf('\n');
|
|
68500
|
+
const newlineCount = newlineIndex === -1 ? 0 : consumed.split('\n').length - 1;
|
|
68501
|
+
return {
|
|
68502
|
+
line: start.line + newlineCount,
|
|
68503
|
+
// Same line → advance the base column; a later line → column is the run since its newline.
|
|
68504
|
+
column: newlineCount === 0 ? start.column + consumed.length : consumed.length - newlineIndex,
|
|
68505
|
+
offset: (start.offset ?? 0) + consumed.length,
|
|
68506
|
+
};
|
|
68507
|
+
};
|
|
68493
68508
|
/**
|
|
68494
68509
|
* Formats the hProperties of a node as a string, so they can be compiled back into JSX/MDX.
|
|
68495
68510
|
* This currently sets all the values to a string since we process/compile the MDX on the fly
|
|
@@ -92168,10 +92183,10 @@ const Tabs = ({ children }) => {
|
|
|
92168
92183
|
const tabs = external_react_default().Children.toArray(children);
|
|
92169
92184
|
return (external_react_default().createElement("div", { className: "TabGroup" },
|
|
92170
92185
|
external_react_default().createElement("header", null,
|
|
92171
|
-
external_react_default().createElement("nav", { className: "TabGroup-nav" }, tabs.map((tab, index) => (external_react_default().createElement("button", { key: tab.
|
|
92186
|
+
external_react_default().createElement("nav", { className: "TabGroup-nav" }, tabs.map((tab, index) => (external_react_default().createElement("button", { key: tab.key, className: `TabGroup-tab${activeTab === index ? '_active' : ''}`, onClick: () => setActiveTab(index) },
|
|
92172
92187
|
tab.props.icon && (external_react_default().createElement(components_Icon, { className: "TabGroup-icon", icon: tab.props.icon, iconColor: tab.props.iconColor })),
|
|
92173
92188
|
tab.props.title))))),
|
|
92174
|
-
external_react_default().createElement("section", null, tabs
|
|
92189
|
+
external_react_default().createElement("section", null, tabs.map((tab, index) => (external_react_default().createElement("div", { key: tab.key, hidden: index !== activeTab }, tab))))));
|
|
92175
92190
|
};
|
|
92176
92191
|
/* harmony default export */ const components_Tabs = (Tabs);
|
|
92177
92192
|
|
|
@@ -95970,6 +95985,108 @@ const applyInserts = (html, inserts) => {
|
|
|
95970
95985
|
return { value: out + html.slice(cursor), inserts: sorted };
|
|
95971
95986
|
};
|
|
95972
95987
|
|
|
95988
|
+
;// ./processor/transform/mdxish/tables/escape-crossing-emphasis.ts
|
|
95989
|
+
|
|
95990
|
+
|
|
95991
|
+
|
|
95992
|
+
// Maximal run of a single emphasis delimiter (`_`, `*`, `**`, `***`, …).
|
|
95993
|
+
const EMPHASIS_RUN_RE = /([*_])\1*/g;
|
|
95994
|
+
// String bounds (undefined) count as whitespace, not punctuation, per the
|
|
95995
|
+
// CommonMark flanking definition.
|
|
95996
|
+
const escape_crossing_emphasis_isWhitespace = (ch) => ch === undefined || unicodeWhitespace(ch.charCodeAt(0));
|
|
95997
|
+
const isPunctuation = (ch) => ch !== undefined && unicodePunctuation(ch.charCodeAt(0));
|
|
95998
|
+
/**
|
|
95999
|
+
* Whether a delimiter run can open and/or close emphasis, per CommonMark's
|
|
96000
|
+
* left/right-flanking rules. The extra `_` conditions forbid intraword
|
|
96001
|
+
* emphasis, which keeps `snake_case` from being treated as a delimiter.
|
|
96002
|
+
*/
|
|
96003
|
+
const analyzeFlanking = (source, char, start, end) => {
|
|
96004
|
+
const before = source[start - 1];
|
|
96005
|
+
const after = source[end];
|
|
96006
|
+
const leftFlanking = !escape_crossing_emphasis_isWhitespace(after) && (!isPunctuation(after) || escape_crossing_emphasis_isWhitespace(before) || isPunctuation(before));
|
|
96007
|
+
const rightFlanking = !escape_crossing_emphasis_isWhitespace(before) && (!isPunctuation(before) || escape_crossing_emphasis_isWhitespace(after) || isPunctuation(after));
|
|
96008
|
+
if (char === '_') {
|
|
96009
|
+
return {
|
|
96010
|
+
canOpen: leftFlanking && (!rightFlanking || isPunctuation(before)),
|
|
96011
|
+
canClose: rightFlanking && (!leftFlanking || isPunctuation(after)),
|
|
96012
|
+
};
|
|
96013
|
+
}
|
|
96014
|
+
return { canOpen: leftFlanking, canClose: rightFlanking };
|
|
96015
|
+
};
|
|
96016
|
+
/**
|
|
96017
|
+
* Collect HTML tag boundaries (via htmlparser2) and emphasis delimiter runs
|
|
96018
|
+
* (via regex over the masked source, so code spans and escaped `<` are skipped)
|
|
96019
|
+
* into one list ordered by position. At a shared offset a tag opener sorts
|
|
96020
|
+
* before a closer, so a self-closing tag brackets rather than swallows a run.
|
|
96021
|
+
*/
|
|
96022
|
+
const collectEvents = (html) => {
|
|
96023
|
+
const masked = maskNonTagRegions(html);
|
|
96024
|
+
const events = [];
|
|
96025
|
+
walkTags(html, {
|
|
96026
|
+
onOpen: ({ start }) => events.push({ kind: 'tagOpen', offset: start }),
|
|
96027
|
+
onClose: ({ start }) => events.push({ kind: 'tagClose', offset: start }),
|
|
96028
|
+
});
|
|
96029
|
+
EMPHASIS_RUN_RE.lastIndex = 0;
|
|
96030
|
+
let match;
|
|
96031
|
+
while ((match = EMPHASIS_RUN_RE.exec(masked)) !== null) {
|
|
96032
|
+
const [run, char] = match;
|
|
96033
|
+
const start = match.index;
|
|
96034
|
+
// eslint-disable-next-line no-continue
|
|
96035
|
+
if (html[start - 1] === '\\')
|
|
96036
|
+
continue; // already escaped
|
|
96037
|
+
events.push({ kind: 'emphasis', offset: start, char, length: run.length, flanking: analyzeFlanking(html, char, start, start + run.length) });
|
|
96038
|
+
}
|
|
96039
|
+
return events.sort((a, b) => a.offset - b.offset || (a.kind === 'tagClose' ? 1 : 0) - (b.kind === 'tagClose' ? 1 : 0));
|
|
96040
|
+
};
|
|
96041
|
+
/**
|
|
96042
|
+
* mdxjs rejects a table when a markdown emphasis run opens at one HTML
|
|
96043
|
+
* tag-nesting depth and closes at another — e.g. `_<ul><li>text_</li></ul>`,
|
|
96044
|
+
* where the `_` opens outside the list but closes inside a `<li>`. It throws
|
|
96045
|
+
* "Expected a closing tag for `<li>` before the end of `emphasis`" and the
|
|
96046
|
+
* whole `<Table>` fails to parse.
|
|
96047
|
+
*
|
|
96048
|
+
* We walk tags and emphasis together, tracking tag depth and a stack of open
|
|
96049
|
+
* emphasis. A delimiter only closes an opener at the same depth; any emphasis
|
|
96050
|
+
* still open when its enclosing tag closes (or at end of input), and any closer
|
|
96051
|
+
* with no same-depth opener, is escaped so mdxjs treats it as literal text.
|
|
96052
|
+
* Scoped to the malformed-retry path.
|
|
96053
|
+
*/
|
|
96054
|
+
const escapeCrossingEmphasis = (html) => {
|
|
96055
|
+
const open = [];
|
|
96056
|
+
const orphans = [];
|
|
96057
|
+
let depth = 0;
|
|
96058
|
+
collectEvents(html).forEach(event => {
|
|
96059
|
+
if (event.kind === 'tagOpen') {
|
|
96060
|
+
depth += 1;
|
|
96061
|
+
return;
|
|
96062
|
+
}
|
|
96063
|
+
if (event.kind === 'tagClose') {
|
|
96064
|
+
depth -= 1;
|
|
96065
|
+
// Emphasis opened deeper than the surviving depth was inside the tag that
|
|
96066
|
+
// just closed, so it crosses the boundary.
|
|
96067
|
+
while (open.length > 0 && open[open.length - 1].depth > depth) {
|
|
96068
|
+
const crossed = open.pop();
|
|
96069
|
+
if (crossed)
|
|
96070
|
+
orphans.push(crossed);
|
|
96071
|
+
}
|
|
96072
|
+
return;
|
|
96073
|
+
}
|
|
96074
|
+
const top = open[open.length - 1];
|
|
96075
|
+
if (event.flanking.canClose && top?.char === event.char && top.depth === depth) {
|
|
96076
|
+
open.pop();
|
|
96077
|
+
}
|
|
96078
|
+
else if (event.flanking.canOpen) {
|
|
96079
|
+
open.push({ char: event.char, depth, offset: event.offset, length: event.length });
|
|
96080
|
+
}
|
|
96081
|
+
else if (event.flanking.canClose) {
|
|
96082
|
+
orphans.push({ offset: event.offset, length: event.length });
|
|
96083
|
+
}
|
|
96084
|
+
});
|
|
96085
|
+
orphans.push(...open); // anything still open never closed
|
|
96086
|
+
const inserts = orphans.flatMap(({ offset, length }) => Array.from({ length }, (_unused, i) => ({ offset: offset + i, text: '\\' })));
|
|
96087
|
+
return applyInserts(html, inserts);
|
|
96088
|
+
};
|
|
96089
|
+
|
|
95973
96090
|
;// ./processor/transform/mdxish/tables/escape-stray-less-than.ts
|
|
95974
96091
|
|
|
95975
96092
|
|
|
@@ -96122,6 +96239,21 @@ const buildOffsetMapper = (inserts) => {
|
|
|
96122
96239
|
return repaired - shift;
|
|
96123
96240
|
};
|
|
96124
96241
|
};
|
|
96242
|
+
/**
|
|
96243
|
+
* Compose the per-repair offset mappers into one that maps an offset in the
|
|
96244
|
+
* fully-repaired string back to the original. `layers` are in application
|
|
96245
|
+
* order; each maps its own output space to its input space, so we apply them
|
|
96246
|
+
* last-repair-first to peel every edit back to the original coordinates.
|
|
96247
|
+
*/
|
|
96248
|
+
const composeOffsetMapper = (layers) => {
|
|
96249
|
+
const mappers = layers.map(buildOffsetMapper);
|
|
96250
|
+
return (repaired) => {
|
|
96251
|
+
let offset = repaired;
|
|
96252
|
+
for (let i = mappers.length - 1; i >= 0; i -= 1)
|
|
96253
|
+
offset = mappers[i](offset);
|
|
96254
|
+
return offset;
|
|
96255
|
+
};
|
|
96256
|
+
};
|
|
96125
96257
|
/**
|
|
96126
96258
|
* Map an offset in `source` to its 1-based `{ line, column }`. `lineStarts`
|
|
96127
96259
|
* is the precomputed array of offsets where each line begins.
|
|
@@ -96149,14 +96281,11 @@ const computeLineStarts = (source) => {
|
|
|
96149
96281
|
};
|
|
96150
96282
|
/**
|
|
96151
96283
|
* Walk `tree`, translating every node's position from the repaired source's
|
|
96152
|
-
* coordinate space back to the original source
|
|
96153
|
-
*
|
|
96154
|
-
*
|
|
96284
|
+
* coordinate space back to the original source via `mapOffset`. Line/column
|
|
96285
|
+
* are recomputed from the original source so they remain accurate even if
|
|
96286
|
+
* repairs introduced newlines.
|
|
96155
96287
|
*/
|
|
96156
|
-
const
|
|
96157
|
-
if (inserts.length === 0)
|
|
96158
|
-
return;
|
|
96159
|
-
const mapOffset = buildOffsetMapper(inserts);
|
|
96288
|
+
const remapWithMapper = (tree, originalSource, mapOffset) => {
|
|
96160
96289
|
const lineStarts = computeLineStarts(originalSource);
|
|
96161
96290
|
lib_visit(tree, child => {
|
|
96162
96291
|
if (child.position?.start) {
|
|
@@ -96175,6 +96304,15 @@ const remapPositionsToOriginal = (tree, originalSource, inserts) => {
|
|
|
96175
96304
|
}
|
|
96176
96305
|
});
|
|
96177
96306
|
};
|
|
96307
|
+
/**
|
|
96308
|
+
* Remap positions produced after a chain of repairs (each applied to the prior
|
|
96309
|
+
* one's output) back to the original source coordinates.
|
|
96310
|
+
*/
|
|
96311
|
+
const remapPositionsThroughLayers = (tree, originalSource, layers) => {
|
|
96312
|
+
if (layers.length === 0)
|
|
96313
|
+
return;
|
|
96314
|
+
remapWithMapper(tree, originalSource, composeOffsetMapper(layers));
|
|
96315
|
+
};
|
|
96178
96316
|
|
|
96179
96317
|
;// ./processor/transform/mdxish/tables/repair-expression-escapes.ts
|
|
96180
96318
|
|
|
@@ -96474,6 +96612,83 @@ const repairUnclosedTags = (html) => {
|
|
|
96474
96612
|
return applyInserts(html, inserts);
|
|
96475
96613
|
};
|
|
96476
96614
|
|
|
96615
|
+
;// ./processor/transform/mdxish/tables/split-nested-tables.ts
|
|
96616
|
+
|
|
96617
|
+
|
|
96618
|
+
const TOP_LEVEL_TABLE_TAG_RE = /^<(?:table|Table)(?=[\s/>])/;
|
|
96619
|
+
/**
|
|
96620
|
+
* Find every balanced, depth-matched `<table>…</table>` range in an html string.
|
|
96621
|
+
* Uses `walkTags` so `<table>`s inside code spans / fenced blocks (masked away)
|
|
96622
|
+
* are never matched.
|
|
96623
|
+
*
|
|
96624
|
+
* Note: An implicitly-closed table (no `</table>`, so htmlparser2 synthesizes the
|
|
96625
|
+
* close at a later tag) is skipped: splitting there would swallow whatever
|
|
96626
|
+
* followed the table into the fragment and drop it, so we leave such a node
|
|
96627
|
+
* whole for downstream raw-HTML handling instead.
|
|
96628
|
+
*/
|
|
96629
|
+
const findTableRanges = (html) => {
|
|
96630
|
+
const ranges = [];
|
|
96631
|
+
let depth = 0;
|
|
96632
|
+
let start = 0;
|
|
96633
|
+
walkTags(html, {
|
|
96634
|
+
onOpen: ({ name, start: openStart, isStrayCloser }) => {
|
|
96635
|
+
if (name.toLowerCase() !== 'table' || isStrayCloser)
|
|
96636
|
+
return;
|
|
96637
|
+
if (depth === 0)
|
|
96638
|
+
start = openStart;
|
|
96639
|
+
depth += 1;
|
|
96640
|
+
},
|
|
96641
|
+
onClose: ({ name, end, implicit }) => {
|
|
96642
|
+
if (implicit || name.toLowerCase() !== 'table' || depth === 0)
|
|
96643
|
+
return;
|
|
96644
|
+
depth -= 1;
|
|
96645
|
+
if (depth === 0)
|
|
96646
|
+
ranges.push({ start, end });
|
|
96647
|
+
},
|
|
96648
|
+
});
|
|
96649
|
+
return ranges;
|
|
96650
|
+
};
|
|
96651
|
+
/**
|
|
96652
|
+
* Given an HTML node that might contain table sequences inside it, split
|
|
96653
|
+
* the node based on the table boundaries so they become a top level node.
|
|
96654
|
+
*
|
|
96655
|
+
* The surrounding raw HTML (the wrapper's open/close tags) would be re-nested
|
|
96656
|
+
* around the parsed tables by rehype-raw.
|
|
96657
|
+
*
|
|
96658
|
+
* Returns null when there is no wrapped table to extract.
|
|
96659
|
+
*/
|
|
96660
|
+
const splitHtmlWithNestedTables = (node) => {
|
|
96661
|
+
const { value } = node;
|
|
96662
|
+
// This is a top-level table, so we don't need to split it
|
|
96663
|
+
if (TOP_LEVEL_TABLE_TAG_RE.test(value))
|
|
96664
|
+
return null;
|
|
96665
|
+
// No table text anywhere in the value → skip the htmlparser2 walk entirely.
|
|
96666
|
+
if (!/<\/?table/i.test(value))
|
|
96667
|
+
return null;
|
|
96668
|
+
const ranges = findTableRanges(value);
|
|
96669
|
+
if (ranges.length === 0)
|
|
96670
|
+
return null;
|
|
96671
|
+
const base = node.position?.start;
|
|
96672
|
+
const sliceToHtml = (from, to) => ({
|
|
96673
|
+
type: 'html',
|
|
96674
|
+
value: value.slice(from, to),
|
|
96675
|
+
...(base && {
|
|
96676
|
+
position: { start: pointAfter(base, value.slice(0, from)), end: pointAfter(base, value.slice(0, to)) },
|
|
96677
|
+
}),
|
|
96678
|
+
});
|
|
96679
|
+
const parts = [];
|
|
96680
|
+
let cursor = 0;
|
|
96681
|
+
ranges.forEach(({ start, end }) => {
|
|
96682
|
+
if (start > cursor)
|
|
96683
|
+
parts.push(sliceToHtml(cursor, start));
|
|
96684
|
+
parts.push(sliceToHtml(start, end)); // starts with `<table` → picked up by the main pass
|
|
96685
|
+
cursor = end;
|
|
96686
|
+
});
|
|
96687
|
+
if (cursor < value.length)
|
|
96688
|
+
parts.push(sliceToHtml(cursor, value.length));
|
|
96689
|
+
return parts;
|
|
96690
|
+
};
|
|
96691
|
+
|
|
96477
96692
|
;// ./processor/transform/mdxish/tables/mdxish-tables.ts
|
|
96478
96693
|
|
|
96479
96694
|
|
|
@@ -96495,6 +96710,8 @@ const repairUnclosedTags = (html) => {
|
|
|
96495
96710
|
|
|
96496
96711
|
|
|
96497
96712
|
|
|
96713
|
+
|
|
96714
|
+
|
|
96498
96715
|
|
|
96499
96716
|
|
|
96500
96717
|
|
|
@@ -96524,6 +96741,21 @@ const buildTableNodeProcessor = (withMdx) => lib_unified()
|
|
|
96524
96741
|
.use(lib_remarkGfm);
|
|
96525
96742
|
const tableNodeProcessor = buildTableNodeProcessor(true);
|
|
96526
96743
|
const fallbackTableNodeProcessor = buildTableNodeProcessor(false);
|
|
96744
|
+
// Targeted repairs for tables mdxjs rejects, tried cumulatively (each runs on
|
|
96745
|
+
// the prior's output) since one table can carry independent per-cell defects.
|
|
96746
|
+
// Each was added after seeing real customer content fail to parse:
|
|
96747
|
+
// - repairUnclosedTags: unclosed/orphan HTML tags
|
|
96748
|
+
// - normalizeTagSpacing: a line mixing text and an opening tag
|
|
96749
|
+
// - repairExpressionEscapes: backslash escapes inside a `{…}` expression
|
|
96750
|
+
// - escapeStrayLessThan: a `<` that doesn't begin a valid tag (`word <`)
|
|
96751
|
+
// - escapeCrossingEmphasis: emphasis opening/closing at different tag depths
|
|
96752
|
+
const tableRepairs = [
|
|
96753
|
+
repairUnclosedTags,
|
|
96754
|
+
normalizeTagSpacing,
|
|
96755
|
+
repairExpressionEscapes,
|
|
96756
|
+
escapeStrayLessThan,
|
|
96757
|
+
escapeCrossingEmphasis,
|
|
96758
|
+
];
|
|
96527
96759
|
/**
|
|
96528
96760
|
* Parse the HTML node that contains the full table substring
|
|
96529
96761
|
* into the table parts (headers, rows, cells).
|
|
@@ -96539,10 +96771,10 @@ const parseTableNode = (processor, node, repair) => {
|
|
|
96539
96771
|
return undefined;
|
|
96540
96772
|
}
|
|
96541
96773
|
// If `node.value` was repaired before parsing, first remap positions back to
|
|
96542
|
-
// the original (unrepaired) coordinates via the insert
|
|
96774
|
+
// the original (unrepaired) coordinates via the insert layers — otherwise the
|
|
96543
96775
|
// shift would land on synthetic characters and be inaccurate
|
|
96544
96776
|
if (repair) {
|
|
96545
|
-
|
|
96777
|
+
remapPositionsThroughLayers(parsed, repair.originalSource, repair.layers);
|
|
96546
96778
|
}
|
|
96547
96779
|
// The subparser produces positions relative to `node.value`; shift them by
|
|
96548
96780
|
// the outer node's offset/line so consumers can slice the full source.
|
|
@@ -96639,9 +96871,7 @@ const processTableNode = (node, index, parent, documentPosition) => {
|
|
|
96639
96871
|
lib_visit(node, utils_isMDXElement, (child) => {
|
|
96640
96872
|
if (child.name === 'thead')
|
|
96641
96873
|
hasThead = true;
|
|
96642
|
-
if (tableTags.has(child.name) &&
|
|
96643
|
-
Array.isArray(child.attributes) &&
|
|
96644
|
-
child.attributes.length > 0) {
|
|
96874
|
+
if (tableTags.has(child.name) && Array.isArray(child.attributes) && child.attributes.length > 0) {
|
|
96645
96875
|
hasStructuralAttributes = true;
|
|
96646
96876
|
}
|
|
96647
96877
|
});
|
|
@@ -96752,6 +96982,26 @@ const processTableNode = (node, index, parent, documentPosition) => {
|
|
|
96752
96982
|
};
|
|
96753
96983
|
parent.children[index] = mdNode;
|
|
96754
96984
|
};
|
|
96985
|
+
/**
|
|
96986
|
+
* Apply `tableRepairs` cumulatively, re-parsing after every change and stopping
|
|
96987
|
+
* once the accumulated result parses. Each layer's inserts are relative to the
|
|
96988
|
+
* string that repair received, so they stay ordered for position remapping.
|
|
96989
|
+
*/
|
|
96990
|
+
const repairAndReparse = (node) => {
|
|
96991
|
+
let repairedValue = node.value;
|
|
96992
|
+
const layers = [];
|
|
96993
|
+
let parsed;
|
|
96994
|
+
tableRepairs.some(repair => {
|
|
96995
|
+
const { value, inserts } = repair(repairedValue);
|
|
96996
|
+
if (value === repairedValue)
|
|
96997
|
+
return false;
|
|
96998
|
+
repairedValue = value;
|
|
96999
|
+
layers.push(inserts);
|
|
97000
|
+
parsed = parseTableNode(tableNodeProcessor, { ...node, value: repairedValue }, { layers, originalSource: node.value });
|
|
97001
|
+
return Boolean(parsed);
|
|
97002
|
+
});
|
|
97003
|
+
return parsed;
|
|
97004
|
+
};
|
|
96755
97005
|
/**
|
|
96756
97006
|
* Converts JSX Table elements to markdown table nodes and re-parses markdown in cells.
|
|
96757
97007
|
*
|
|
@@ -96764,42 +97014,30 @@ const processTableNode = (node, index, parent, documentPosition) => {
|
|
|
96764
97014
|
* is kept as a JSX <Table> element so that remarkRehype can properly handle the flow content.
|
|
96765
97015
|
*/
|
|
96766
97016
|
const mdxish_tables_mdxishTables = () => tree => {
|
|
97017
|
+
// Pre-pass: lift `<table>`s wrapped in a raw HTML block out into their own
|
|
97018
|
+
// html nodes so the main pass below treats them like top-level tables.
|
|
97019
|
+
lib_visit(tree, 'html', (_node, index, parent) => {
|
|
97020
|
+
const node = _node;
|
|
97021
|
+
if (typeof index !== 'number' || !parent || !('children' in parent))
|
|
97022
|
+
return;
|
|
97023
|
+
const parts = splitHtmlWithNestedTables(node);
|
|
97024
|
+
if (!parts)
|
|
97025
|
+
return;
|
|
97026
|
+
// The inserted parts can't re-trigger a split (table parts start with
|
|
97027
|
+
// `<table`; the wrapper slices hold no table), so plain in-place splicing
|
|
97028
|
+
// visits each once without looping.
|
|
97029
|
+
parent.children.splice(index, 1, ...parts);
|
|
97030
|
+
});
|
|
96767
97031
|
lib_visit(tree, 'html', (_node, index, parent) => {
|
|
96768
97032
|
const node = _node;
|
|
96769
97033
|
if (typeof index !== 'number' || !parent || !('children' in parent))
|
|
96770
97034
|
return;
|
|
96771
97035
|
if (!node.value.startsWith('<Table') && !node.value.startsWith('<table'))
|
|
96772
97036
|
return;
|
|
96773
|
-
// Main logic to transform table node to its parts
|
|
96774
97037
|
// Because the processor uses remarkMdx, it is stricter in what it accepts
|
|
96775
|
-
// and only accepts valid MDX syntax
|
|
96776
|
-
//
|
|
96777
|
-
|
|
96778
|
-
if (!parsed) {
|
|
96779
|
-
// Try a sequence of targeted repairs and re-parse
|
|
96780
|
-
// after each, stopping at the first that yields a parseable tree:
|
|
96781
|
-
// - repairUnclosedTags: unclosed/orphan HTML tags
|
|
96782
|
-
// - normalizeTagSpacing: a line mixing text and an opening tag
|
|
96783
|
-
// (e.g. `text <div> \n <div> text`)
|
|
96784
|
-
// - repairExpressionEscapes: backslash escapes inside a `{…}` expression
|
|
96785
|
-
// - escapeStrayLessThan: a `<` that doesn't begin a valid tag
|
|
96786
|
-
// (e.g. `word <`, `a <1>`)
|
|
96787
|
-
// These repairs are created after seeing real customer content that has failed to parse
|
|
96788
|
-
const repairs = [
|
|
96789
|
-
repairUnclosedTags,
|
|
96790
|
-
normalizeTagSpacing,
|
|
96791
|
-
repairExpressionEscapes,
|
|
96792
|
-
escapeStrayLessThan,
|
|
96793
|
-
];
|
|
96794
|
-
// Stops at the first repair that yields a parseable tree
|
|
96795
|
-
repairs.some(repair => {
|
|
96796
|
-
const { value, inserts } = repair(node.value);
|
|
96797
|
-
if (value !== node.value) {
|
|
96798
|
-
parsed = parseTableNode(tableNodeProcessor, { ...node, value }, { inserts, originalSource: node.value });
|
|
96799
|
-
}
|
|
96800
|
-
return Boolean(parsed);
|
|
96801
|
-
});
|
|
96802
|
-
}
|
|
97038
|
+
// and only accepts valid MDX syntax in the table node. To get around that,
|
|
97039
|
+
// fall back to the cumulative repairs when the first parse fails.
|
|
97040
|
+
const parsed = parseTableNode(tableNodeProcessor, node) ?? repairAndReparse(node);
|
|
96803
97041
|
if (parsed) {
|
|
96804
97042
|
// If the table is parsed successfully, we can now process it further
|
|
96805
97043
|
// to build on the markdown / JSX table
|
|
@@ -117668,11 +117906,10 @@ const rehypeMdxishComponents = ({ components, processMarkdown }) => {
|
|
|
117668
117906
|
;// ./processor/plugin/mdxish-handlers.ts
|
|
117669
117907
|
|
|
117670
117908
|
|
|
117671
|
-
//
|
|
117672
|
-
|
|
117673
|
-
|
|
117674
|
-
|
|
117675
|
-
});
|
|
117909
|
+
// If hChildren is populated, it means the node holds a renderable value (e.g. React)
|
|
117910
|
+
// See evaluate-expressions.ts for more details
|
|
117911
|
+
// Otherwise, it's a simple value and we fall back to text
|
|
117912
|
+
const mdxExpressionHandler = (_state, node) => node.data?.hChildren ?? { type: 'text', value: node.value || '' };
|
|
117676
117913
|
// Convert MDX JSX elements to a custom mdx-jsx hast node that bypasses rehypeRaw's
|
|
117677
117914
|
// HTML serialization round-trip; downstream normalization rewrites it to `element`.
|
|
117678
117915
|
const mdxJsxElementHandler = (state, node) => {
|
|
@@ -120739,6 +120976,7 @@ const mdxishInlineMdxComponents = () => tree => {
|
|
|
120739
120976
|
|
|
120740
120977
|
|
|
120741
120978
|
|
|
120979
|
+
|
|
120742
120980
|
/** Matches a JSX attribute expression (e.g. `key={i}`) anywhere in a string. */
|
|
120743
120981
|
const NESTED_ATTR_EXPRESSION_RE = /[\w-]+\s*=\s*\{/;
|
|
120744
120982
|
/**
|
|
@@ -120782,18 +121020,6 @@ const parseSibling = (stack, parent, index, sibling, safeMode) => {
|
|
|
120782
121020
|
stack.push(parent);
|
|
120783
121021
|
}
|
|
120784
121022
|
};
|
|
120785
|
-
/**
|
|
120786
|
-
* Advance a point by the substring of source consumed from it.
|
|
120787
|
-
*/
|
|
120788
|
-
const pointAfter = (start, consumed) => {
|
|
120789
|
-
const newlineIndex = consumed.lastIndexOf('\n');
|
|
120790
|
-
const newlineCount = newlineIndex === -1 ? 0 : consumed.split('\n').length - 1;
|
|
120791
|
-
return {
|
|
120792
|
-
line: start.line + newlineCount,
|
|
120793
|
-
column: newlineCount === 0 ? start.column + consumed.length : consumed.length - newlineIndex,
|
|
120794
|
-
offset: start.offset + consumed.length,
|
|
120795
|
-
};
|
|
120796
|
-
};
|
|
120797
121023
|
/**
|
|
120798
121024
|
* Build a position ending at `consumedLength` into the html node's value, so the
|
|
120799
121025
|
* component doesn't claim trailing content the tokenizer swallowed into one node.
|
|
@@ -121341,26 +121567,183 @@ const evalExpression = (expression, scope) => {
|
|
|
121341
121567
|
return evalJsxProgram(program, scope);
|
|
121342
121568
|
};
|
|
121343
121569
|
|
|
121344
|
-
;// ./processor/transform/mdxish/
|
|
121570
|
+
;// ./processor/transform/mdxish/style-object-to-css.ts
|
|
121345
121571
|
|
|
121572
|
+
/**
|
|
121573
|
+
* CSS properties React treats as unitless — a bare number stays as-is instead of
|
|
121574
|
+
* getting `px` appended. Mirrors React DOM's `isUnitlessNumber` whitelist.
|
|
121575
|
+
* @see https://github.com/facebook/react/blob/main/packages/react-dom-bindings/src/shared/CSSProperty.js
|
|
121576
|
+
*/
|
|
121577
|
+
const UNITLESS_CSS_PROPERTIES = new Set([
|
|
121578
|
+
'animationIterationCount',
|
|
121579
|
+
'aspectRatio',
|
|
121580
|
+
'borderImageOutset',
|
|
121581
|
+
'borderImageSlice',
|
|
121582
|
+
'borderImageWidth',
|
|
121583
|
+
'boxFlex',
|
|
121584
|
+
'boxFlexGroup',
|
|
121585
|
+
'boxOrdinalGroup',
|
|
121586
|
+
'columnCount',
|
|
121587
|
+
'columns',
|
|
121588
|
+
'flex',
|
|
121589
|
+
'flexGrow',
|
|
121590
|
+
'flexPositive',
|
|
121591
|
+
'flexShrink',
|
|
121592
|
+
'flexNegative',
|
|
121593
|
+
'flexOrder',
|
|
121594
|
+
'gridArea',
|
|
121595
|
+
'gridRow',
|
|
121596
|
+
'gridRowEnd',
|
|
121597
|
+
'gridRowSpan',
|
|
121598
|
+
'gridRowStart',
|
|
121599
|
+
'gridColumn',
|
|
121600
|
+
'gridColumnEnd',
|
|
121601
|
+
'gridColumnSpan',
|
|
121602
|
+
'gridColumnStart',
|
|
121603
|
+
'fontWeight',
|
|
121604
|
+
'lineClamp',
|
|
121605
|
+
'lineHeight',
|
|
121606
|
+
'opacity',
|
|
121607
|
+
'order',
|
|
121608
|
+
'orphans',
|
|
121609
|
+
'tabSize',
|
|
121610
|
+
'widows',
|
|
121611
|
+
'zIndex',
|
|
121612
|
+
'zoom',
|
|
121613
|
+
'fillOpacity',
|
|
121614
|
+
'floodOpacity',
|
|
121615
|
+
'stopOpacity',
|
|
121616
|
+
'strokeDasharray',
|
|
121617
|
+
'strokeDashoffset',
|
|
121618
|
+
'strokeMiterlimit',
|
|
121619
|
+
'strokeOpacity',
|
|
121620
|
+
'strokeWidth',
|
|
121621
|
+
]);
|
|
121622
|
+
/** Convert a camelCase (or CSS custom property) key into its kebab-case CSS name. */
|
|
121623
|
+
const cssPropertyName = (key) => (key.startsWith('--') ? key : key.replace(/[A-Z]/g, m => `-${m.toLowerCase()}`));
|
|
121624
|
+
/** React appends `px` to non-zero numeric values, except unitless and custom properties. */
|
|
121625
|
+
const cssPropertyValue = (key, value) => typeof value === 'number' && value !== 0 && !key.startsWith('--') && !UNITLESS_CSS_PROPERTIES.has(key)
|
|
121626
|
+
? `${value}px`
|
|
121627
|
+
: `${value}`;
|
|
121628
|
+
/**
|
|
121629
|
+
* True for a value that should be serialized as a style object rather than passed through
|
|
121630
|
+
* as an already-CSS string. React elements are excluded since they're valid objects too.
|
|
121631
|
+
*/
|
|
121632
|
+
const style_object_to_css_isPlainObject = (value) => typeof value === 'object' && value !== null && !Array.isArray(value) && !external_react_default().isValidElement(value);
|
|
121633
|
+
/**
|
|
121634
|
+
* Serialize a React-style inline style object (`{ color: "red", fontSize: 12 }`) into a
|
|
121635
|
+
* CSS declaration string (`color:red;font-size:12px`), the shape hast/HTML expects for a
|
|
121636
|
+
* `style` attribute. Empty (`undefined`/`null`/`''`) entries are dropped.
|
|
121637
|
+
*/
|
|
121638
|
+
const styleObjectToCssText = (style) => Object.entries(style)
|
|
121639
|
+
.filter(([, value]) => value !== undefined && value !== null && value !== '')
|
|
121640
|
+
.map(([key, value]) => `${cssPropertyName(key)}:${cssPropertyValue(key, value)}`)
|
|
121641
|
+
.join(';');
|
|
121346
121642
|
|
|
121643
|
+
;// ./processor/transform/mdxish/react-element-to-hast.ts
|
|
121347
121644
|
|
|
121348
121645
|
|
|
121349
|
-
|
|
121350
|
-
|
|
121351
|
-
|
|
121352
|
-
|
|
121353
|
-
|
|
121354
|
-
|
|
121646
|
+
|
|
121647
|
+
// React props that never map to an HTML/hast attribute.
|
|
121648
|
+
const RESERVED_PROPS = new Set(['children', 'key', 'ref']);
|
|
121649
|
+
/**
|
|
121650
|
+
* Translate React props into hast `properties`: reserved and function props (event handlers)
|
|
121651
|
+
* are dropped (known gap), `style` objects flatten to CSS text. Names stay as authored (`className`); the
|
|
121652
|
+
* hast → HTML boundary maps them to `class`/`for` downstream.
|
|
121653
|
+
*/
|
|
121654
|
+
function propsToHastProperties(props) {
|
|
121655
|
+
const properties = {};
|
|
121656
|
+
Object.entries(props).forEach(([key, value]) => {
|
|
121657
|
+
if (RESERVED_PROPS.has(key) || typeof value === 'function' || value === undefined)
|
|
121658
|
+
return;
|
|
121659
|
+
properties[key] = key === 'style' && style_object_to_css_isPlainObject(value) ? styleObjectToCssText(value) : value;
|
|
121660
|
+
});
|
|
121661
|
+
// Values are resolved React props, wider than hast's HTML-attribute `PropertyValue` union.
|
|
121662
|
+
return properties;
|
|
121663
|
+
}
|
|
121664
|
+
/**
|
|
121665
|
+
* Render an element with React's own renderer as a last resort, wrapped as a hast `raw` node —
|
|
121666
|
+
* the same node type markdown's literal HTML blocks produce, so it re-enters rehypeRaw's
|
|
121667
|
+
* parse5 pass normally. Used for element types this converter can't resolve on its own (wrapped
|
|
121668
|
+
* component types, or a function component that throws when called outside React, e.g. one
|
|
121669
|
+
* using hooks). It's not immune to the invalid-HTML-nesting this module otherwise avoids, but
|
|
121670
|
+
* that's a fair trade against silently dropping the content.
|
|
121671
|
+
*/
|
|
121672
|
+
function renderFallbackHtml(element) {
|
|
121673
|
+
try {
|
|
121674
|
+
const rawNode = { type: 'raw', value: (0,server_node/* renderToStaticMarkup */.qV)(element) };
|
|
121675
|
+
return [rawNode];
|
|
121355
121676
|
}
|
|
121356
|
-
|
|
121357
|
-
|
|
121358
|
-
// representation. This must come before the object check as both are a subset of it.
|
|
121359
|
-
return { type: 'html', value: (0,server_node/* renderToStaticMarkup */.qV)(external_react_default().createElement((external_react_default()).Fragment, null, result)), position };
|
|
121677
|
+
catch {
|
|
121678
|
+
return [];
|
|
121360
121679
|
}
|
|
121361
|
-
|
|
121362
|
-
|
|
121680
|
+
}
|
|
121681
|
+
/**
|
|
121682
|
+
* Convert a React element tree into hast. Emitting `mdx-jsx` nodes (rehypeRaw passthrough, later normalized to `element`)
|
|
121683
|
+
* preserves nesting that is valid JSX but not valid HTML, which parse5 would otherwise
|
|
121684
|
+
* restructure — e.g. an `<a>` wrapping another `<a>`.
|
|
121685
|
+
* Recursively converts the tree into an array of hast nodes, dealing with arrays and null/undefined/boolean values.
|
|
121686
|
+
*/
|
|
121687
|
+
function reactElementToHast(node) {
|
|
121688
|
+
if (Array.isArray(node))
|
|
121689
|
+
return node.flatMap(reactElementToHast);
|
|
121690
|
+
if (node === null || node === undefined || typeof node === 'boolean')
|
|
121691
|
+
return [];
|
|
121692
|
+
if (typeof node === 'string' || typeof node === 'number') {
|
|
121693
|
+
const textNode = { type: 'text', value: String(node) };
|
|
121694
|
+
return [textNode];
|
|
121695
|
+
}
|
|
121696
|
+
if (!external_react_default().isValidElement(node))
|
|
121697
|
+
return [];
|
|
121698
|
+
const { type, props } = node;
|
|
121699
|
+
// Fragments contribute their children with no wrapper element.
|
|
121700
|
+
if (type === (external_react_default()).Fragment)
|
|
121701
|
+
return reactElementToHast(props.children);
|
|
121702
|
+
// Resolve function components to their rendered output so the tree is plain intrinsic
|
|
121703
|
+
// elements. If invoking it directly throws (e.g. it uses hooks, which need React's own
|
|
121704
|
+
// render context), fall back to React's renderer for just this subtree.
|
|
121705
|
+
if (typeof type === 'function') {
|
|
121706
|
+
try {
|
|
121707
|
+
return reactElementToHast(type(props));
|
|
121708
|
+
}
|
|
121709
|
+
catch {
|
|
121710
|
+
return renderFallbackHtml(node);
|
|
121711
|
+
}
|
|
121363
121712
|
}
|
|
121713
|
+
// Non-intrinsic, non-callable element types — `React.memo`, `React.forwardRef`,
|
|
121714
|
+
// `Context.Provider`/`Consumer`, `React.lazy` — have no `type` we can resolve ourselves.
|
|
121715
|
+
if (typeof type !== 'string')
|
|
121716
|
+
return renderFallbackHtml(node);
|
|
121717
|
+
const mdxJsxNode = {
|
|
121718
|
+
type: 'mdx-jsx',
|
|
121719
|
+
tagName: type,
|
|
121720
|
+
properties: propsToHastProperties(props),
|
|
121721
|
+
children: reactElementToHast(props.children),
|
|
121722
|
+
};
|
|
121723
|
+
return [mdxJsxNode];
|
|
121724
|
+
}
|
|
121725
|
+
|
|
121726
|
+
;// ./processor/transform/mdxish/evaluate-expressions.ts
|
|
121727
|
+
|
|
121728
|
+
|
|
121729
|
+
|
|
121730
|
+
|
|
121731
|
+
/**
|
|
121732
|
+
* We divide the result of an expression into two categories:
|
|
121733
|
+
* 1. Renderable values: HTML, JSX, e.g. .map() returning JSX
|
|
121734
|
+
* 2. Non-renderable values: a string, number, or object, regular JS values
|
|
121735
|
+
*/
|
|
121736
|
+
const isRenderable = (value) => {
|
|
121737
|
+
if (external_react_default().isValidElement(value))
|
|
121738
|
+
return true;
|
|
121739
|
+
return Array.isArray(value) && value.some(isRenderable);
|
|
121740
|
+
};
|
|
121741
|
+
/** Turn a non-renderable evaluation result into a text node. */
|
|
121742
|
+
const createTextNode = (result, position) => {
|
|
121743
|
+
if (result === null || result === undefined)
|
|
121744
|
+
return { type: 'text', value: '', position };
|
|
121745
|
+
if (typeof result === 'object')
|
|
121746
|
+
return { type: 'text', value: JSON.stringify(result), position };
|
|
121364
121747
|
return { type: 'text', value: String(result), position };
|
|
121365
121748
|
};
|
|
121366
121749
|
/**
|
|
@@ -121376,13 +121759,23 @@ const evaluateExpressions = () => (tree, file) => {
|
|
|
121376
121759
|
lib_visit(tree, ['mdxFlowExpression', 'mdxTextExpression'], (node, index, parent) => {
|
|
121377
121760
|
if (!parent || index === null || index === undefined)
|
|
121378
121761
|
return;
|
|
121379
|
-
const
|
|
121762
|
+
const expressionNode = node;
|
|
121763
|
+
const { value, position } = expressionNode;
|
|
121380
121764
|
const expression = value?.trim();
|
|
121381
121765
|
if (!expression)
|
|
121382
121766
|
return;
|
|
121383
121767
|
try {
|
|
121384
121768
|
const result = evalExpression(expression, scope);
|
|
121385
|
-
|
|
121769
|
+
if (isRenderable(result)) {
|
|
121770
|
+
// Stash hast built straight from the React tree; `mdxExpressionHandler` emits it and it
|
|
121771
|
+
// passes through rehypeRaw/parse5 step later in the pipeline. This ensures that the
|
|
121772
|
+
// expression result is not parsed by parse5 and fragmenting the nesting that is valid JSX
|
|
121773
|
+
// but invalid HTML — e.g. an `<a>` wrapping `<a>`.
|
|
121774
|
+
expressionNode.data = { ...expressionNode.data, hChildren: reactElementToHast(result) };
|
|
121775
|
+
}
|
|
121776
|
+
else {
|
|
121777
|
+
parent.children.splice(index, 1, createTextNode(result, position));
|
|
121778
|
+
}
|
|
121386
121779
|
}
|
|
121387
121780
|
catch (_error) {
|
|
121388
121781
|
// Evaluation failed — fall back to literal `{...}` text. The expression
|
|
@@ -124713,79 +125106,6 @@ function removeJSXComments(content) {
|
|
|
124713
125106
|
return content.replace(JSX_COMMENT_REGEX, '');
|
|
124714
125107
|
}
|
|
124715
125108
|
|
|
124716
|
-
;// ./processor/transform/mdxish/style-object-to-css.ts
|
|
124717
|
-
|
|
124718
|
-
/**
|
|
124719
|
-
* CSS properties React treats as unitless — a bare number stays as-is instead of
|
|
124720
|
-
* getting `px` appended. Mirrors React DOM's `isUnitlessNumber` whitelist.
|
|
124721
|
-
* @see https://github.com/facebook/react/blob/main/packages/react-dom-bindings/src/shared/CSSProperty.js
|
|
124722
|
-
*/
|
|
124723
|
-
const UNITLESS_CSS_PROPERTIES = new Set([
|
|
124724
|
-
'animationIterationCount',
|
|
124725
|
-
'aspectRatio',
|
|
124726
|
-
'borderImageOutset',
|
|
124727
|
-
'borderImageSlice',
|
|
124728
|
-
'borderImageWidth',
|
|
124729
|
-
'boxFlex',
|
|
124730
|
-
'boxFlexGroup',
|
|
124731
|
-
'boxOrdinalGroup',
|
|
124732
|
-
'columnCount',
|
|
124733
|
-
'columns',
|
|
124734
|
-
'flex',
|
|
124735
|
-
'flexGrow',
|
|
124736
|
-
'flexPositive',
|
|
124737
|
-
'flexShrink',
|
|
124738
|
-
'flexNegative',
|
|
124739
|
-
'flexOrder',
|
|
124740
|
-
'gridArea',
|
|
124741
|
-
'gridRow',
|
|
124742
|
-
'gridRowEnd',
|
|
124743
|
-
'gridRowSpan',
|
|
124744
|
-
'gridRowStart',
|
|
124745
|
-
'gridColumn',
|
|
124746
|
-
'gridColumnEnd',
|
|
124747
|
-
'gridColumnSpan',
|
|
124748
|
-
'gridColumnStart',
|
|
124749
|
-
'fontWeight',
|
|
124750
|
-
'lineClamp',
|
|
124751
|
-
'lineHeight',
|
|
124752
|
-
'opacity',
|
|
124753
|
-
'order',
|
|
124754
|
-
'orphans',
|
|
124755
|
-
'tabSize',
|
|
124756
|
-
'widows',
|
|
124757
|
-
'zIndex',
|
|
124758
|
-
'zoom',
|
|
124759
|
-
'fillOpacity',
|
|
124760
|
-
'floodOpacity',
|
|
124761
|
-
'stopOpacity',
|
|
124762
|
-
'strokeDasharray',
|
|
124763
|
-
'strokeDashoffset',
|
|
124764
|
-
'strokeMiterlimit',
|
|
124765
|
-
'strokeOpacity',
|
|
124766
|
-
'strokeWidth',
|
|
124767
|
-
]);
|
|
124768
|
-
/** Convert a camelCase (or CSS custom property) key into its kebab-case CSS name. */
|
|
124769
|
-
const cssPropertyName = (key) => (key.startsWith('--') ? key : key.replace(/[A-Z]/g, m => `-${m.toLowerCase()}`));
|
|
124770
|
-
/** React appends `px` to non-zero numeric values, except unitless and custom properties. */
|
|
124771
|
-
const cssPropertyValue = (key, value) => typeof value === 'number' && value !== 0 && !key.startsWith('--') && !UNITLESS_CSS_PROPERTIES.has(key)
|
|
124772
|
-
? `${value}px`
|
|
124773
|
-
: `${value}`;
|
|
124774
|
-
/**
|
|
124775
|
-
* True for a value that should be serialized as a style object rather than passed through
|
|
124776
|
-
* as an already-CSS string. React elements are excluded since they're valid objects too.
|
|
124777
|
-
*/
|
|
124778
|
-
const style_object_to_css_isPlainObject = (value) => typeof value === 'object' && value !== null && !Array.isArray(value) && !external_react_default().isValidElement(value);
|
|
124779
|
-
/**
|
|
124780
|
-
* Serialize a React-style inline style object (`{ color: "red", fontSize: 12 }`) into a
|
|
124781
|
-
* CSS declaration string (`color:red;font-size:12px`), the shape hast/HTML expects for a
|
|
124782
|
-
* `style` attribute. Empty (`undefined`/`null`/`''`) entries are dropped.
|
|
124783
|
-
*/
|
|
124784
|
-
const styleObjectToCssText = (style) => Object.entries(style)
|
|
124785
|
-
.filter(([, value]) => value !== undefined && value !== null && value !== '')
|
|
124786
|
-
.map(([key, value]) => `${cssPropertyName(key)}:${cssPropertyValue(key, value)}`)
|
|
124787
|
-
.join(';');
|
|
124788
|
-
|
|
124789
125109
|
;// ./processor/transform/mdxish/resolve-deferred-attribute-expression-props.ts
|
|
124790
125110
|
|
|
124791
125111
|
|