@readme/markdown 14.12.1 → 14.13.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.
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Drop blank lines inside `<svg>`/`<math>` islands: their whitespace is
3
+ * insignificant XML, but a blank line ends the CommonMark HTML block and spills the
4
+ * children out as a code block (#1545). Collapsing keeps the island one block.
5
+ */
6
+ export declare function collapseForeignContentBlankLines(content: string): string;
@@ -86449,8 +86449,8 @@ function Anchor(props) {
86449
86449
 
86450
86450
 
86451
86451
 
86452
- const Card = ({ badge, children, href, kind = 'card', icon, iconColor, target, title }) => {
86453
- const Tag = href ? 'a' : 'div';
86452
+ const Card = ({ badge, children, href, kind = 'card', icon, iconColor, LinkComponent = 'a', target, title, }) => {
86453
+ const Tag = href ? LinkComponent : 'div';
86454
86454
  return (external_react_default().createElement(Tag, { className: `Card Card_${kind}`, href: href, target: target },
86455
86455
  icon && external_react_default().createElement(components_Icon, { className: "Card-icon", icon: icon, iconColor: iconColor }),
86456
86456
  external_react_default().createElement("div", { className: "Card-content" },
@@ -96476,6 +96476,12 @@ const HTML_TABLE_STRUCTURE_TAGS = new Set([
96476
96476
  'caption',
96477
96477
  'colgroup',
96478
96478
  ]);
96479
+ /**
96480
+ * The two HTML "foreign content" namespaces: SVG and MathML. Their descendants
96481
+ * (`<path>`, `<mrow>`, …) are namespaced XML, not HTML tags or components. A closed
96482
+ * set per the HTML spec, so transforms can treat these roots as opaque islands.
96483
+ */
96484
+ const FOREIGN_CONTENT_TAGS = ['svg', 'math'];
96479
96485
  /**
96480
96486
  * HTML void elements — elements that have no closing tag and no children.
96481
96487
  *
@@ -117685,6 +117691,9 @@ function getComponentName(componentName, components) {
117685
117691
 
117686
117692
 
117687
117693
 
117694
+ // Foreign-content (SVG/MathML) roots — subtrees the component transform leaves
117695
+ // untouched (their children are namespaced XML, not HTML tags/components).
117696
+ const FOREIGN_CONTENT_ROOTS = new Set(FOREIGN_CONTENT_TAGS);
117688
117697
  function isElementContentNode(node) {
117689
117698
  return node.type === 'element' || node.type === 'text' || node.type === 'comment';
117690
117699
  }
@@ -117860,6 +117869,12 @@ const rehypeMdxishComponents = ({ components, processMarkdown }) => {
117860
117869
  lib_visit(tree, 'element', (node, index, parent) => {
117861
117870
  if (index === undefined || !parent)
117862
117871
  return;
117872
+ // Skip foreign-content subtrees: their namespaced children (<path>, <mrow>, …)
117873
+ // aren't HTML tags or components, so the "unknown component" removal below would
117874
+ // otherwise delete them. (svg/math themselves are standard HTML tags, kept.)
117875
+ // eslint-disable-next-line consistent-return
117876
+ if (FOREIGN_CONTENT_ROOTS.has(node.tagName))
117877
+ return lib_SKIP;
117863
117878
  // Parse Image caption as markdown so it renders formatted (bold, code,
117864
117879
  // decoded entities) in the figcaption instead of as a raw string.
117865
117880
  // rehypeRaw strips children from <img> (void element), so we must
@@ -118171,6 +118186,81 @@ function closeSelfClosingHtmlTags(content) {
118171
118186
  return restoreCodeBlocks(result, protectedCode);
118172
118187
  }
118173
118188
 
118189
+ ;// ./processor/transform/mdxish/collapse-foreign-content-blank-lines.ts
118190
+
118191
+
118192
+ // `svg|math`, from the canonical list so this stays in sync with the component transform.
118193
+ const ROOT_ALT = FOREIGN_CONTENT_TAGS.join('|');
118194
+ // A foreign-content opener. The `[\s/>]` boundary requires a real tag delimiter after the
118195
+ // root name, so lookalikes like `<svgfoo>` and custom elements like `<svg-icon>` are ignored.
118196
+ const ANY_ROOT_RE = new RegExp(`<(?:${ROOT_ALT})(?=[\\s/>])`, 'i');
118197
+ // Tag body: swallows whole quoted attribute values so a `>` inside a quote (e.g.
118198
+ // `<svg data-x="a > b" />`) can't be mistaken for the tag terminator; other non-`>`
118199
+ // chars (including newlines) are consumed one at a time.
118200
+ const TAG_BODY = '(?:"[^"]*"|\'[^\']*\'|[^>\'"])*?';
118201
+ // One whole svg/math tag (opener, self-closer, or closer), matched whole so attributes
118202
+ // and `>` may span lines. The `[\s/>]` boundary after the root name keeps `<svgfoo>`/
118203
+ // `<svg-icon>` out. Group 1 is `/` only for a self-closer.
118204
+ const FOREIGN_TAG_RE = new RegExp(`<(?:${ROOT_ALT})(?=[\\s/>])${TAG_BODY}(/)?>|</(?:${ROOT_ALT})(?=[\\s/>])${TAG_BODY}>`, 'gi');
118205
+ // An HTML comment. Foreign markup inside one is inert and must not open an island.
118206
+ const HTML_COMMENT_RE = /<!--[\s\S]*?-->/g;
118207
+ const withinAny = (spans, offset) => spans.some(([start, end]) => offset >= start && offset < end);
118208
+ /**
118209
+ * `[start, end)` spans of every *matched* SVG/MathML pair — the regions whose blank
118210
+ * lines are known-insignificant XML. Matching whole tags (not per-line open/close
118211
+ * counts) keeps multi-line openers and self-closers balanced, so a wrapped
118212
+ * `<svg … />` can't latch and swallow the doc (#1545).
118213
+ *
118214
+ * Tags are paired innermost-first, as a parser would; an opener still unpaired at EOF
118215
+ * closed nothing and so covers nothing. That keeps a stray `<svg>` in prose from
118216
+ * swallowing every blank line after it, without hiding the real islands that follow.
118217
+ */
118218
+ function findForeignContentSpans(text) {
118219
+ const spans = [];
118220
+ // Foreign tags inside an HTML comment are inert; a stray `<svg>`/`<math>` in a comment
118221
+ // must not open an island and latch onto the rest of the doc.
118222
+ const comments = [...text.matchAll(HTML_COMMENT_RE)].map((m) => [m.index ?? 0, (m.index ?? 0) + m[0].length]);
118223
+ // Offsets of openers still waiting for their closer, innermost last.
118224
+ const openOffsets = [];
118225
+ [...text.matchAll(FOREIGN_TAG_RE)].forEach(match => {
118226
+ const offset = match.index ?? 0;
118227
+ if (withinAny(comments, offset))
118228
+ return; // markup inside an HTML comment is inert
118229
+ if (match[1] === '/')
118230
+ return; // self-closing tag opens no island
118231
+ if (match[0].startsWith('</')) {
118232
+ const start = openOffsets.pop();
118233
+ if (start !== undefined)
118234
+ spans.push([start, offset + match[0].length]); // a closer with no opener closes nothing
118235
+ }
118236
+ else {
118237
+ openOffsets.push(offset);
118238
+ }
118239
+ });
118240
+ return spans;
118241
+ }
118242
+ /**
118243
+ * Drop blank lines inside `<svg>`/`<math>` islands: their whitespace is
118244
+ * insignificant XML, but a blank line ends the CommonMark HTML block and spills the
118245
+ * children out as a code block (#1545). Collapsing keeps the island one block.
118246
+ */
118247
+ function collapseForeignContentBlankLines(content) {
118248
+ // Fast path: nothing to do when the doc has no foreign-content island.
118249
+ if (!ANY_ROOT_RE.test(content))
118250
+ return content;
118251
+ const { protectedContent, protectedCode } = protectCodeBlocks(content);
118252
+ const islands = findForeignContentSpans(protectedContent);
118253
+ // Drop blank lines inside an island; keep everything else verbatim.
118254
+ const lines = [];
118255
+ let lineStart = 0;
118256
+ protectedContent.split('\n').forEach(line => {
118257
+ if (line.trim().length > 0 || !withinAny(islands, lineStart))
118258
+ lines.push(line);
118259
+ lineStart += line.length + 1; // +1 for the '\n' that split() removed
118260
+ });
118261
+ return restoreCodeBlocks(lines.join('\n'), protectedCode);
118262
+ }
118263
+
118174
118264
  ;// ./lib/utils/mdxish/mdxish-component-tag-parser.ts
118175
118265
  // Extract the tag name (PascalCase or lowercase HTML) at the start of a tag string.
118176
118266
  const tagNamePattern = /^<([A-Za-z][A-Za-z0-9_-]*)/;
@@ -126728,6 +126818,7 @@ function loadComponents() {
126728
126818
 
126729
126819
 
126730
126820
 
126821
+
126731
126822
 
126732
126823
 
126733
126824
  const defaultTransformers = [
@@ -126742,10 +126833,11 @@ const defaultTransformers = [
126742
126833
  * Runs a series of string-level transformations before micromark/remark parsing:
126743
126834
  * 1. Canonicalize closing tags with stray whitespace (e.g., `</ td >` → `</td>`)
126744
126835
  * 2. Normalize malformed table separator syntax (e.g., `|: ---` → `| :---`)
126745
- * 3. Terminate HTML flow blocks so subsequent content isn't swallowed
126746
- * 4. Close invalid "self-closing" HTML tags (e.g., `<i />` → `<i></i>`)
126747
- * 5. Normalize compact ATX headings (e.g., `#Heading``# Heading`)
126748
- * 6. Replace snake_case component names with parser-safe placeholders
126836
+ * 3. Collapse blank lines inside `<svg>`/`<math>` so their children aren't fragmented
126837
+ * 4. Terminate HTML flow blocks so subsequent content isn't swallowed
126838
+ * 5. Close invalid "self-closing" HTML tags (e.g., `<i />` `<i></i>`)
126839
+ * 6. Normalize compact ATX headings (e.g., `#Heading` → `# Heading`)
126840
+ * 7. Replace snake_case component names with parser-safe placeholders
126749
126841
  */
126750
126842
  function preprocessContent(content, opts) {
126751
126843
  const { knownComponents } = opts;
@@ -126753,6 +126845,10 @@ function preprocessContent(content, opts) {
126753
126845
  // classification in `terminateHtmlFlowBlocks` is accurate)
126754
126846
  let result = normalizeClosingTagWhitespace(content);
126755
126847
  result = normalizeTableSeparator(result);
126848
+ // Before terminateHtmlFlowBlocks: a blank line inside an <svg>/<math> island
126849
+ // would otherwise fragment it (children spill out as an indented code block once
126850
+ // a wrapper re-parses its deindented body — #1545).
126851
+ result = collapseForeignContentBlankLines(result);
126756
126852
  result = terminateHtmlFlowBlocks(result);
126757
126853
  result = closeSelfClosingHtmlTags(result);
126758
126854
  result = normalizeCompactHeadings(result);
@@ -127368,6 +127464,8 @@ const mdxishTags_tags = (doc) => {
127368
127464
 
127369
127465
 
127370
127466
 
127467
+
127468
+
127371
127469
  /**
127372
127470
  * Removes Markdown and MDX comments.
127373
127471
  */
@@ -127378,10 +127476,16 @@ async function stripComments(doc, { mdx, mdxish } = {}) {
127378
127476
  // 1. we can rely on remarkMdx to parse MDXish
127379
127477
  // 2. we need to parse JSX comments into mdxTextExpression nodes so that the transformers can pick them up
127380
127478
  // 3. we need to claim <HTMLBlock> before htmlFlow intercepts its inner HTML tags
127479
+ // 4. we need mdxComponent to parse custom components as one node, and prevent the tag from getting escaped
127381
127480
  if (mdxish) {
127382
127481
  processor
127383
- .data('micromarkExtensions', [htmlBlockComponent(), jsxTable(), mdxExpression({ allowEmpty: true })])
127384
- .data('fromMarkdownExtensions', [htmlBlockComponentFromMarkdown(), jsxTableFromMarkdown(), mdxExpressionFromMarkdown()])
127482
+ .data('micromarkExtensions', [htmlBlockComponent(), jsxTable(), mdxComponent(), mdxExpression({ allowEmpty: true })])
127483
+ .data('fromMarkdownExtensions', [
127484
+ htmlBlockComponentFromMarkdown(),
127485
+ jsxTableFromMarkdown(),
127486
+ mdxComponentFromMarkdown(),
127487
+ mdxExpressionFromMarkdown(),
127488
+ ])
127385
127489
  .data('toMarkdownExtensions', [mdxExpressionToMarkdown()]);
127386
127490
  }
127387
127491
  processor