@readme/markdown 14.4.1 → 14.5.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/dist/main.js CHANGED
@@ -12255,13 +12255,17 @@ const Image = (Props) => {
12255
12255
  external_amd_react_commonjs_react_commonjs2_react_root_React_umd_react_.createElement("i", { "aria-hidden": "true", className: "fa-solid fa-xmark" }))))) : null;
12256
12256
  if (framed) {
12257
12257
  const frameClass = `img-frame img-frame-${align || 'center'}`;
12258
+ // Left/right frames shrink to fit, so percentage widths can't resolve
12259
+ // against the parent, hoist onto the wrapper. Center frames are full-width.
12260
+ const isClamped = align === 'left' || align === 'right';
12261
+ const frameStyle = isClamped && typeof width === 'string' && width.endsWith('%') ? { width } : undefined;
12258
12262
  if (children || caption) {
12259
- return (external_amd_react_commonjs_react_commonjs2_react_root_React_umd_react_.createElement("figure", { className: frameClass },
12263
+ return (external_amd_react_commonjs_react_commonjs2_react_root_React_umd_react_.createElement("figure", { className: frameClass, style: frameStyle },
12260
12264
  closedLightbox(alt || 'Expand image', imgElement),
12261
12265
  lightboxOverlay,
12262
12266
  external_amd_react_commonjs_react_commonjs2_react_root_React_umd_react_.createElement("figcaption", null, children || caption)));
12263
12267
  }
12264
- return (external_amd_react_commonjs_react_commonjs2_react_root_React_umd_react_.createElement("div", { className: frameClass },
12268
+ return (external_amd_react_commonjs_react_commonjs2_react_root_React_umd_react_.createElement("div", { className: frameClass, style: frameStyle },
12265
12269
  closedLightbox(alt || 'Expand image', imgElement),
12266
12270
  lightboxOverlay));
12267
12271
  }
@@ -75823,6 +75827,57 @@ const remapPositionsToOriginal = (tree, originalSource, inserts) => {
75823
75827
  });
75824
75828
  };
75825
75829
 
75830
+ ;// ./processor/transform/mdxish/tables/repair-expression-escapes.ts
75831
+
75832
+ /**
75833
+ * mdxjs hands the contents of every `{…}` to acorn as a JavaScript expression.
75834
+ * A bare backslash is only legal inside a string/template literal in JS, so a
75835
+ * markdown-style escape such as `{customer\_id}` — common when authors escape an
75836
+ * underscore out of habit — makes acorn throw "Could not parse expression with
75837
+ * acorn", which drops parsing for the whole surrounding `<Table>`.
75838
+ *
75839
+ * This pass deletes backslashes that sit in JS *code* position inside a `{…}`
75840
+ * expression. Backslashes within a '…', "…" or `…` literal are valid escapes
75841
+ * and are left untouched. Scoped to the malformed-retry path; the happy path
75842
+ * never runs it.
75843
+ */
75844
+ const repairExpressionEscapes = (html) => {
75845
+ const inserts = [];
75846
+ let braceDepth = 0;
75847
+ // Active string/template delimiter while scanning inside an expression, or null.
75848
+ let stringChar = null;
75849
+ for (let i = 0; i < html.length; i += 1) {
75850
+ const ch = html[i];
75851
+ if (stringChar) {
75852
+ // Inside a JS string/template literal a backslash escapes the next char
75853
+ // and is valid, so skip the pair untouched (this also prevents an escaped
75854
+ // quote from prematurely closing the literal).
75855
+ if (ch === '\\') {
75856
+ i += 1;
75857
+ }
75858
+ else if (ch === stringChar) {
75859
+ stringChar = null;
75860
+ }
75861
+ }
75862
+ else if (braceDepth > 0 && (ch === '"' || ch === "'" || ch === '`')) {
75863
+ stringChar = ch;
75864
+ }
75865
+ else if (ch === '{') {
75866
+ braceDepth += 1;
75867
+ }
75868
+ else if (ch === '}') {
75869
+ if (braceDepth > 0)
75870
+ braceDepth -= 1;
75871
+ }
75872
+ else if (braceDepth > 0 && ch === '\\') {
75873
+ // A backslash in code position inside an expression is always a syntax
75874
+ // error; delete it so acorn can parse the remaining expression.
75875
+ inserts.push({ offset: i, text: '', consumes: 1 });
75876
+ }
75877
+ }
75878
+ return applyInserts(html, inserts);
75879
+ };
75880
+
75826
75881
  ;// ./node_modules/html-tags/html-tags.json
75827
75882
  const html_tags_namespaceObject = /*#__PURE__*/JSON.parse('["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","label","legend","li","link","main","map","mark","math","menu","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","script","search","section","select","selectedcontent","slot","small","source","span","strong","style","sub","summary","sup","svg","table","tbody","td","template","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr"]');
75828
75883
  // EXTERNAL MODULE: ./node_modules/react-html-attributes/dist/index.js
@@ -76073,6 +76128,7 @@ const repairUnclosedTags = (html) => {
76073
76128
 
76074
76129
 
76075
76130
 
76131
+
76076
76132
 
76077
76133
  const isTableCell = (node) => isMDXElement(node) && ['th', 'td'].includes(node.name);
76078
76134
  const tableTypes = {
@@ -76084,6 +76140,9 @@ const tableTypes = {
76084
76140
  // register them manually so we control ordering against our other tokenizers.
76085
76141
  // The fallback omits these so blank-line-separated markdown inside cells still
76086
76142
  // parses when mdxjs throws on malformed JSX.
76143
+ //
76144
+ // mdx parsing is used because it heavily simplifies the parsing of the table structure;
76145
+ // it can identify the rows and cells. The heavy lifting is done by it
76087
76146
  const buildTableNodeProcessor = (withMdx) => unified()
76088
76147
  .data('micromarkExtensions', [...(withMdx ? [mdxjs()] : []), syntax_gemoji(), legacyVariable()])
76089
76148
  .data('fromMarkdownExtensions', [
@@ -76318,22 +76377,29 @@ const mdxishTables = () => tree => {
76318
76377
  // Main logic to transform table node to its parts
76319
76378
  // Because the processor uses remarkMdx, it is stricter in what it accepts
76320
76379
  // and only accepts valid MDX syntax. in the table node.
76321
- // To get around that, we have some fallback logics after trying to repair the table content
76380
+ // To get around that, we have some fallback logics after trying to repair the table content.
76322
76381
  let parsed = parseTableNode(tableNodeProcessor, node);
76323
76382
  if (!parsed) {
76324
- // First common error is unclosed HTML tags
76325
- const repaired = repairUnclosedTags(node.value);
76326
- if (repaired.value !== node.value) {
76327
- parsed = parseTableNode(tableNodeProcessor, { ...node, value: repaired.value }, { inserts: repaired.inserts, originalSource: node.value });
76328
- }
76329
- if (!parsed) {
76330
- // Second common error is having a line with text and an opening tag
76331
- // E.g. text <div> \n <div> text
76332
- const normalized = normalizeTagSpacing(node.value);
76333
- if (normalized.value !== node.value) {
76334
- parsed = parseTableNode(tableNodeProcessor, { ...node, value: normalized.value }, { inserts: normalized.inserts, originalSource: node.value });
76383
+ // Try a sequence of targeted repairs and re-parse
76384
+ // after each, stopping at the first that yields a parseable tree:
76385
+ // - repairUnclosedTags: unclosed/orphan HTML tags
76386
+ // - normalizeTagSpacing: a line mixing text and an opening tag
76387
+ // (e.g. `text <div> \n <div> text`)
76388
+ // - repairExpressionEscapes: backslash escapes inside a `{…}` expression
76389
+ // These repairs are created after seeing real customer content that has failed to parse
76390
+ const repairs = [
76391
+ repairUnclosedTags,
76392
+ normalizeTagSpacing,
76393
+ repairExpressionEscapes,
76394
+ ];
76395
+ // Stops at the first repair that yields a parseable tree
76396
+ repairs.some(repair => {
76397
+ const { value, inserts } = repair(node.value);
76398
+ if (value !== node.value) {
76399
+ parsed = parseTableNode(tableNodeProcessor, { ...node, value }, { inserts, originalSource: node.value });
76335
76400
  }
76336
- }
76401
+ return Boolean(parsed);
76402
+ });
76337
76403
  }
76338
76404
  if (parsed) {
76339
76405
  // If the table is parsed successfully, we can now process it further
@@ -76354,6 +76420,8 @@ const mdxishTables = () => tree => {
76354
76420
  return;
76355
76421
  parent.children.splice(index, 1, ...fallback.children);
76356
76422
  }
76423
+ // Otherwise, there's no point in trying to parse the table content further
76424
+ // More repairs are needed in that case
76357
76425
  });
76358
76426
  return tree;
76359
76427
  };
package/dist/main.node.js CHANGED
@@ -24881,13 +24881,17 @@ const Image = (Props) => {
24881
24881
  external_react_.createElement("i", { "aria-hidden": "true", className: "fa-solid fa-xmark" }))))) : null;
24882
24882
  if (framed) {
24883
24883
  const frameClass = `img-frame img-frame-${align || 'center'}`;
24884
+ // Left/right frames shrink to fit, so percentage widths can't resolve
24885
+ // against the parent, hoist onto the wrapper. Center frames are full-width.
24886
+ const isClamped = align === 'left' || align === 'right';
24887
+ const frameStyle = isClamped && typeof width === 'string' && width.endsWith('%') ? { width } : undefined;
24884
24888
  if (children || caption) {
24885
- return (external_react_.createElement("figure", { className: frameClass },
24889
+ return (external_react_.createElement("figure", { className: frameClass, style: frameStyle },
24886
24890
  closedLightbox(alt || 'Expand image', imgElement),
24887
24891
  lightboxOverlay,
24888
24892
  external_react_.createElement("figcaption", null, children || caption)));
24889
24893
  }
24890
- return (external_react_.createElement("div", { className: frameClass },
24894
+ return (external_react_.createElement("div", { className: frameClass, style: frameStyle },
24891
24895
  closedLightbox(alt || 'Expand image', imgElement),
24892
24896
  lightboxOverlay));
24893
24897
  }
@@ -96047,6 +96051,57 @@ const remapPositionsToOriginal = (tree, originalSource, inserts) => {
96047
96051
  });
96048
96052
  };
96049
96053
 
96054
+ ;// ./processor/transform/mdxish/tables/repair-expression-escapes.ts
96055
+
96056
+ /**
96057
+ * mdxjs hands the contents of every `{…}` to acorn as a JavaScript expression.
96058
+ * A bare backslash is only legal inside a string/template literal in JS, so a
96059
+ * markdown-style escape such as `{customer\_id}` — common when authors escape an
96060
+ * underscore out of habit — makes acorn throw "Could not parse expression with
96061
+ * acorn", which drops parsing for the whole surrounding `<Table>`.
96062
+ *
96063
+ * This pass deletes backslashes that sit in JS *code* position inside a `{…}`
96064
+ * expression. Backslashes within a '…', "…" or `…` literal are valid escapes
96065
+ * and are left untouched. Scoped to the malformed-retry path; the happy path
96066
+ * never runs it.
96067
+ */
96068
+ const repairExpressionEscapes = (html) => {
96069
+ const inserts = [];
96070
+ let braceDepth = 0;
96071
+ // Active string/template delimiter while scanning inside an expression, or null.
96072
+ let stringChar = null;
96073
+ for (let i = 0; i < html.length; i += 1) {
96074
+ const ch = html[i];
96075
+ if (stringChar) {
96076
+ // Inside a JS string/template literal a backslash escapes the next char
96077
+ // and is valid, so skip the pair untouched (this also prevents an escaped
96078
+ // quote from prematurely closing the literal).
96079
+ if (ch === '\\') {
96080
+ i += 1;
96081
+ }
96082
+ else if (ch === stringChar) {
96083
+ stringChar = null;
96084
+ }
96085
+ }
96086
+ else if (braceDepth > 0 && (ch === '"' || ch === "'" || ch === '`')) {
96087
+ stringChar = ch;
96088
+ }
96089
+ else if (ch === '{') {
96090
+ braceDepth += 1;
96091
+ }
96092
+ else if (ch === '}') {
96093
+ if (braceDepth > 0)
96094
+ braceDepth -= 1;
96095
+ }
96096
+ else if (braceDepth > 0 && ch === '\\') {
96097
+ // A backslash in code position inside an expression is always a syntax
96098
+ // error; delete it so acorn can parse the remaining expression.
96099
+ inserts.push({ offset: i, text: '', consumes: 1 });
96100
+ }
96101
+ }
96102
+ return applyInserts(html, inserts);
96103
+ };
96104
+
96050
96105
  ;// ./node_modules/html-tags/html-tags.json
96051
96106
  const html_tags_namespaceObject = /*#__PURE__*/JSON.parse('["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","label","legend","li","link","main","map","mark","math","menu","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","script","search","section","select","selectedcontent","slot","small","source","span","strong","style","sub","summary","sup","svg","table","tbody","td","template","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr"]');
96052
96107
  // EXTERNAL MODULE: ./node_modules/react-html-attributes/dist/index.js
@@ -96297,6 +96352,7 @@ const repairUnclosedTags = (html) => {
96297
96352
 
96298
96353
 
96299
96354
 
96355
+
96300
96356
 
96301
96357
  const isTableCell = (node) => isMDXElement(node) && ['th', 'td'].includes(node.name);
96302
96358
  const tableTypes = {
@@ -96308,6 +96364,9 @@ const tableTypes = {
96308
96364
  // register them manually so we control ordering against our other tokenizers.
96309
96365
  // The fallback omits these so blank-line-separated markdown inside cells still
96310
96366
  // parses when mdxjs throws on malformed JSX.
96367
+ //
96368
+ // mdx parsing is used because it heavily simplifies the parsing of the table structure;
96369
+ // it can identify the rows and cells. The heavy lifting is done by it
96311
96370
  const buildTableNodeProcessor = (withMdx) => unified()
96312
96371
  .data('micromarkExtensions', [...(withMdx ? [mdxjs()] : []), syntax_gemoji(), legacyVariable()])
96313
96372
  .data('fromMarkdownExtensions', [
@@ -96542,22 +96601,29 @@ const mdxishTables = () => tree => {
96542
96601
  // Main logic to transform table node to its parts
96543
96602
  // Because the processor uses remarkMdx, it is stricter in what it accepts
96544
96603
  // and only accepts valid MDX syntax. in the table node.
96545
- // To get around that, we have some fallback logics after trying to repair the table content
96604
+ // To get around that, we have some fallback logics after trying to repair the table content.
96546
96605
  let parsed = parseTableNode(tableNodeProcessor, node);
96547
96606
  if (!parsed) {
96548
- // First common error is unclosed HTML tags
96549
- const repaired = repairUnclosedTags(node.value);
96550
- if (repaired.value !== node.value) {
96551
- parsed = parseTableNode(tableNodeProcessor, { ...node, value: repaired.value }, { inserts: repaired.inserts, originalSource: node.value });
96552
- }
96553
- if (!parsed) {
96554
- // Second common error is having a line with text and an opening tag
96555
- // E.g. text <div> \n <div> text
96556
- const normalized = normalizeTagSpacing(node.value);
96557
- if (normalized.value !== node.value) {
96558
- parsed = parseTableNode(tableNodeProcessor, { ...node, value: normalized.value }, { inserts: normalized.inserts, originalSource: node.value });
96607
+ // Try a sequence of targeted repairs and re-parse
96608
+ // after each, stopping at the first that yields a parseable tree:
96609
+ // - repairUnclosedTags: unclosed/orphan HTML tags
96610
+ // - normalizeTagSpacing: a line mixing text and an opening tag
96611
+ // (e.g. `text <div> \n <div> text`)
96612
+ // - repairExpressionEscapes: backslash escapes inside a `{…}` expression
96613
+ // These repairs are created after seeing real customer content that has failed to parse
96614
+ const repairs = [
96615
+ repairUnclosedTags,
96616
+ normalizeTagSpacing,
96617
+ repairExpressionEscapes,
96618
+ ];
96619
+ // Stops at the first repair that yields a parseable tree
96620
+ repairs.some(repair => {
96621
+ const { value, inserts } = repair(node.value);
96622
+ if (value !== node.value) {
96623
+ parsed = parseTableNode(tableNodeProcessor, { ...node, value }, { inserts, originalSource: node.value });
96559
96624
  }
96560
- }
96625
+ return Boolean(parsed);
96626
+ });
96561
96627
  }
96562
96628
  if (parsed) {
96563
96629
  // If the table is parsed successfully, we can now process it further
@@ -96578,6 +96644,8 @@ const mdxishTables = () => tree => {
96578
96644
  return;
96579
96645
  parent.children.splice(index, 1, ...fallback.children);
96580
96646
  }
96647
+ // Otherwise, there's no point in trying to parse the table content further
96648
+ // More repairs are needed in that case
96581
96649
  });
96582
96650
  return tree;
96583
96651
  };