@readme/markdown 14.4.1 → 14.6.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.node.js CHANGED
@@ -24835,10 +24835,12 @@ const LightboxPortal = ({ children }) => {
24835
24835
  return (0,external_react_dom_namespaceObject.createPortal)(children, document.body);
24836
24836
  };
24837
24837
  const Image = (Props) => {
24838
- const { align = '', alt = '', border: borderProp = false, caption, className = '', framed: framedProp = false, height = 'auto', src, title = '', width = 'auto', lazy = true, children, } = Props;
24838
+ const { align = '', alt = '', border: borderProp = false, caption, className = '', framed: framedProp = false, height = 'auto', src, title = '', width = 'auto', lazy = true, children, wrap: wrapProp, } = Props;
24839
24839
  // Normalize border/framed: MDXish passes {false} as the string "false", not a boolean
24840
24840
  const border = borderProp === true || borderProp === 'true';
24841
24841
  const framed = framedProp === true || framedProp === 'true';
24842
+ // Default (undefined) keeps legacy behavior: left/right images float and wrap text.
24843
+ const noWrap = (align === 'left' || align === 'right') && (wrapProp === false || wrapProp === 'false');
24842
24844
  const [lightbox, setLightbox] = external_react_.useState(false);
24843
24845
  if (className === 'emoji') {
24844
24846
  return external_react_.createElement("img", { alt: alt, height: height, loading: lazy ? 'lazy' : 'eager', src: src, title: title, width: width });
@@ -24868,7 +24870,8 @@ const Image = (Props) => {
24868
24870
  setLightbox(!lightbox);
24869
24871
  };
24870
24872
  // Framed images center the <img> itself; outer wrapper handles left/right alignment via text-align.
24871
- const imgElement = (external_react_.createElement("img", { alt: alt, className: `img ${caption || children || framed ? 'img-align-center' : align ? `img-align-${align}` : ''} ${border ? 'border' : ''}`, height: height, loading: lazy ? 'lazy' : 'eager', src: src, title: title, width: width }));
24873
+ const imgClass = `img ${caption || children || framed ? 'img-align-center' : align ? `img-align-${align}` : ''} ${border ? 'border' : ''}${noWrap ? ' img-no-wrap' : ''}`;
24874
+ const imgElement = (external_react_.createElement("img", { alt: alt, className: imgClass, height: height, loading: lazy ? 'lazy' : 'eager', src: src, title: title, width: width }));
24872
24875
  const closedLightbox = (ariaLabel, content) => (external_react_.createElement("span", { "aria-label": ariaLabel, className: "img lightbox closed", onClick: toggle, onKeyDown: handleKeyDown, role: 'button', tabIndex: 0 },
24873
24876
  external_react_.createElement("span", { className: "lightbox-inner" }, content)));
24874
24877
  const lightboxOverlay = lightbox ? (external_react_.createElement(LightboxPortal, null,
@@ -24880,14 +24883,18 @@ const Image = (Props) => {
24880
24883
  external_react_.createElement("button", { "aria-label": "Minimize image", className: "lightbox-close", onClick: toggle, type: "button" },
24881
24884
  external_react_.createElement("i", { "aria-hidden": "true", className: "fa-solid fa-xmark" }))))) : null;
24882
24885
  if (framed) {
24883
- const frameClass = `img-frame img-frame-${align || 'center'}`;
24886
+ const frameClass = `img-frame img-frame-${align || 'center'}${noWrap ? ' img-no-wrap' : ''}`;
24887
+ // Only left/right wrapping frames shrink to fit; for those, hoist percentage
24888
+ // widths onto the wrapper since they can't resolve against a shrink-to-fit parent.
24889
+ const isClamped = (align === 'left' || align === 'right') && !noWrap;
24890
+ const frameStyle = isClamped && typeof width === 'string' && width.endsWith('%') ? { width } : undefined;
24884
24891
  if (children || caption) {
24885
- return (external_react_.createElement("figure", { className: frameClass },
24892
+ return (external_react_.createElement("figure", { className: frameClass, style: frameStyle },
24886
24893
  closedLightbox(alt || 'Expand image', imgElement),
24887
24894
  lightboxOverlay,
24888
24895
  external_react_.createElement("figcaption", null, children || caption)));
24889
24896
  }
24890
- return (external_react_.createElement("div", { className: frameClass },
24897
+ return (external_react_.createElement("div", { className: frameClass, style: frameStyle },
24891
24898
  closedLightbox(alt || 'Expand image', imgElement),
24892
24899
  lightboxOverlay));
24893
24900
  }
@@ -96047,6 +96054,57 @@ const remapPositionsToOriginal = (tree, originalSource, inserts) => {
96047
96054
  });
96048
96055
  };
96049
96056
 
96057
+ ;// ./processor/transform/mdxish/tables/repair-expression-escapes.ts
96058
+
96059
+ /**
96060
+ * mdxjs hands the contents of every `{…}` to acorn as a JavaScript expression.
96061
+ * A bare backslash is only legal inside a string/template literal in JS, so a
96062
+ * markdown-style escape such as `{customer\_id}` — common when authors escape an
96063
+ * underscore out of habit — makes acorn throw "Could not parse expression with
96064
+ * acorn", which drops parsing for the whole surrounding `<Table>`.
96065
+ *
96066
+ * This pass deletes backslashes that sit in JS *code* position inside a `{…}`
96067
+ * expression. Backslashes within a '…', "…" or `…` literal are valid escapes
96068
+ * and are left untouched. Scoped to the malformed-retry path; the happy path
96069
+ * never runs it.
96070
+ */
96071
+ const repairExpressionEscapes = (html) => {
96072
+ const inserts = [];
96073
+ let braceDepth = 0;
96074
+ // Active string/template delimiter while scanning inside an expression, or null.
96075
+ let stringChar = null;
96076
+ for (let i = 0; i < html.length; i += 1) {
96077
+ const ch = html[i];
96078
+ if (stringChar) {
96079
+ // Inside a JS string/template literal a backslash escapes the next char
96080
+ // and is valid, so skip the pair untouched (this also prevents an escaped
96081
+ // quote from prematurely closing the literal).
96082
+ if (ch === '\\') {
96083
+ i += 1;
96084
+ }
96085
+ else if (ch === stringChar) {
96086
+ stringChar = null;
96087
+ }
96088
+ }
96089
+ else if (braceDepth > 0 && (ch === '"' || ch === "'" || ch === '`')) {
96090
+ stringChar = ch;
96091
+ }
96092
+ else if (ch === '{') {
96093
+ braceDepth += 1;
96094
+ }
96095
+ else if (ch === '}') {
96096
+ if (braceDepth > 0)
96097
+ braceDepth -= 1;
96098
+ }
96099
+ else if (braceDepth > 0 && ch === '\\') {
96100
+ // A backslash in code position inside an expression is always a syntax
96101
+ // error; delete it so acorn can parse the remaining expression.
96102
+ inserts.push({ offset: i, text: '', consumes: 1 });
96103
+ }
96104
+ }
96105
+ return applyInserts(html, inserts);
96106
+ };
96107
+
96050
96108
  ;// ./node_modules/html-tags/html-tags.json
96051
96109
  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
96110
  // EXTERNAL MODULE: ./node_modules/react-html-attributes/dist/index.js
@@ -96297,6 +96355,7 @@ const repairUnclosedTags = (html) => {
96297
96355
 
96298
96356
 
96299
96357
 
96358
+
96300
96359
 
96301
96360
  const isTableCell = (node) => isMDXElement(node) && ['th', 'td'].includes(node.name);
96302
96361
  const tableTypes = {
@@ -96308,6 +96367,9 @@ const tableTypes = {
96308
96367
  // register them manually so we control ordering against our other tokenizers.
96309
96368
  // The fallback omits these so blank-line-separated markdown inside cells still
96310
96369
  // parses when mdxjs throws on malformed JSX.
96370
+ //
96371
+ // mdx parsing is used because it heavily simplifies the parsing of the table structure;
96372
+ // it can identify the rows and cells. The heavy lifting is done by it
96311
96373
  const buildTableNodeProcessor = (withMdx) => unified()
96312
96374
  .data('micromarkExtensions', [...(withMdx ? [mdxjs()] : []), syntax_gemoji(), legacyVariable()])
96313
96375
  .data('fromMarkdownExtensions', [
@@ -96542,22 +96604,29 @@ const mdxishTables = () => tree => {
96542
96604
  // Main logic to transform table node to its parts
96543
96605
  // Because the processor uses remarkMdx, it is stricter in what it accepts
96544
96606
  // 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
96607
+ // To get around that, we have some fallback logics after trying to repair the table content.
96546
96608
  let parsed = parseTableNode(tableNodeProcessor, node);
96547
96609
  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 });
96610
+ // Try a sequence of targeted repairs and re-parse
96611
+ // after each, stopping at the first that yields a parseable tree:
96612
+ // - repairUnclosedTags: unclosed/orphan HTML tags
96613
+ // - normalizeTagSpacing: a line mixing text and an opening tag
96614
+ // (e.g. `text <div> \n <div> text`)
96615
+ // - repairExpressionEscapes: backslash escapes inside a `{…}` expression
96616
+ // These repairs are created after seeing real customer content that has failed to parse
96617
+ const repairs = [
96618
+ repairUnclosedTags,
96619
+ normalizeTagSpacing,
96620
+ repairExpressionEscapes,
96621
+ ];
96622
+ // Stops at the first repair that yields a parseable tree
96623
+ repairs.some(repair => {
96624
+ const { value, inserts } = repair(node.value);
96625
+ if (value !== node.value) {
96626
+ parsed = parseTableNode(tableNodeProcessor, { ...node, value }, { inserts, originalSource: node.value });
96559
96627
  }
96560
- }
96628
+ return Boolean(parsed);
96629
+ });
96561
96630
  }
96562
96631
  if (parsed) {
96563
96632
  // If the table is parsed successfully, we can now process it further
@@ -96578,6 +96647,8 @@ const mdxishTables = () => tree => {
96578
96647
  return;
96579
96648
  parent.children.splice(index, 1, ...fallback.children);
96580
96649
  }
96650
+ // Otherwise, there's no point in trying to parse the table content further
96651
+ // More repairs are needed in that case
96581
96652
  });
96582
96653
  return tree;
96583
96654
  };
@@ -123897,7 +123968,7 @@ const transformAnchor = (jsx) => {
123897
123968
  */
123898
123969
  const transformImage = (jsx) => {
123899
123970
  const attrs = getAttrs(jsx);
123900
- const { align, alt = '', border, caption, className, framed, height, lazy, src = '', title = '', width } = attrs;
123971
+ const { align, alt = '', border, caption, className, framed, height, lazy, src = '', title = '', width, wrap, } = attrs;
123901
123972
  const validAlign = toImageAlign(align);
123902
123973
  const sizing = width !== undefined ? String(width) : undefined;
123903
123974
  const hProperties = {
@@ -123913,6 +123984,7 @@ const transformImage = (jsx) => {
123913
123984
  ...(lazy !== undefined && { lazy: toBool(lazy) }),
123914
123985
  ...(sizing && { sizing }),
123915
123986
  ...(sizing && { width: sizing }),
123987
+ ...(wrap !== undefined && { wrap: toBool(wrap) }),
123916
123988
  };
123917
123989
  return {
123918
123990
  type: NodeTypes.imageBlock,
@@ -123929,6 +124001,7 @@ const transformImage = (jsx) => {
123929
124001
  src,
123930
124002
  title,
123931
124003
  width: sizing,
124004
+ ...(wrap !== undefined && { wrap: toBool(wrap) }),
123932
124005
  data: {
123933
124006
  hName: 'img',
123934
124007
  hProperties,