@readme/markdown 14.13.1 → 14.14.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.
@@ -68469,6 +68469,13 @@ const mdast_mdast = (text, opts = {}) => {
68469
68469
  * to parse expressions containing JSX.
68470
68470
  */
68471
68471
  const jsxAcornParser = Parser.extend(acorn_jsx_default()());
68472
+ /**
68473
+ * Disables CommonMark's indented-code-block construct (4+ spaces)
68474
+ * The micromark tokenizers use follow the CommonMark specification: https://spec.commonmark.org/0.28/#indented-code-blocks
68475
+ * So any lines indented 4+ spaces are considered as a code block,
68476
+ * which is unexpected from users that used MDX before.
68477
+ */
68478
+ const disableIndentedCode = { disable: { null: ['codeIndented'] } };
68472
68479
  /**
68473
68480
  * Evaluate a JavaScript expression source and return its value.
68474
68481
  *
@@ -92197,6 +92204,10 @@ const tailwindPrefix = 'readme-tailwind';
92197
92204
 
92198
92205
 
92199
92206
  const TailwindRoot = ({ children, flow }) => {
92207
+ // `styles/gfm.scss` spaces the wrapped block children through this element and
92208
+ // relies on their margins collapsing through it. Keep it a plain block — no
92209
+ // border, padding, or block formatting context (overflow, display: flow-root/
92210
+ // flex/grid) — or the spacing breaks.
92200
92211
  const Tag = flow ? 'div' : 'span';
92201
92212
  return external_react_default().createElement(Tag, { className: tailwindPrefix }, children);
92202
92213
  };
@@ -112665,185 +112676,70 @@ const hast = (text, opts = {}) => {
112665
112676
  };
112666
112677
  /* harmony default export */ const lib_hast = ((/* unused pure expression or super */ null && (hast)));
112667
112678
 
112668
- ;// ./processor/migration/emphasis.ts
112669
-
112670
- const emphasis_strongTest = (node) => ['emphasis', 'strong'].includes(node.type);
112671
- const addSpaceBefore = (index, parent) => {
112672
- if (!(index > 0 && parent.children[index - 1]))
112673
- return;
112674
- const prev = parent.children[index - 1];
112675
- if (!('value' in prev) || prev.value.endsWith(' ') || prev.type === 'escape')
112676
- return;
112677
- parent.children.splice(index, 0, { type: 'text', value: ' ' });
112678
- };
112679
- const addSpaceAfter = (index, parent) => {
112680
- if (!(index < parent.children.length - 1 && parent.children[index + 1]))
112681
- return;
112682
- const nextChild = parent.children[index + 1];
112683
- if (!('value' in nextChild) || nextChild.value.startsWith(' '))
112684
- return;
112685
- parent.children.splice(index + 1, 0, { type: 'text', value: ' ' });
112686
- };
112687
- const trimEmphasis = (node, index, parent) => {
112688
- let trimmed = false;
112689
- lib_visit(node, 'text', (child) => {
112690
- const newValue = child.value.trimStart();
112691
- if (newValue !== child.value) {
112692
- trimmed = true;
112693
- child.value = newValue;
112694
- }
112695
- return EXIT;
112696
- });
112697
- lib_visit(node, 'text', (child) => {
112698
- const newValue = child.value.trimEnd();
112699
- if (newValue !== child.value) {
112700
- trimmed = true;
112701
- child.value = newValue;
112702
- }
112703
- return EXIT;
112704
- }, true);
112705
- if (trimmed) {
112706
- addSpaceBefore(index, parent);
112707
- addSpaceAfter(index, parent);
112708
- }
112709
- };
112710
- const emphasisTransfomer = () => (tree) => {
112711
- lib_visit(tree, emphasis_strongTest, trimEmphasis);
112712
- return tree;
112713
- };
112714
- /* harmony default export */ const migration_emphasis = (emphasisTransfomer);
112679
+ ;// ./node_modules/rehype-parse/lib/index.js
112680
+ /**
112681
+ * @import {Root} from 'hast'
112682
+ * @import {Options as FromHtmlOptions} from 'hast-util-from-html'
112683
+ * @import {Parser, Processor} from 'unified'
112684
+ */
112715
112685
 
112716
- ;// ./processor/migration/images.ts
112686
+ /**
112687
+ * @typedef {Omit<FromHtmlOptions, 'onerror'> & RehypeParseFields} Options
112688
+ * Configuration.
112689
+ *
112690
+ * @typedef RehypeParseFields
112691
+ * Extra fields.
112692
+ * @property {boolean | null | undefined} [emitParseErrors=false]
112693
+ * Whether to emit parse errors while parsing (default: `false`).
112694
+ *
112695
+ * > 👉 **Note**: parse errors are currently being added to HTML.
112696
+ * > Not all errors emitted by parse5 (or us) are specced yet.
112697
+ * > Some documentation may still be missing.
112698
+ */
112717
112699
 
112718
- const images_imageTransformer = () => tree => {
112719
- lib_visit(tree, 'image', (image) => {
112720
- if (image.data?.hProperties?.className === 'border') {
112721
- image.data.hProperties.border = true;
112722
- }
112723
- });
112724
- };
112725
- /* harmony default export */ const migration_images = (images_imageTransformer);
112726
112700
 
112727
- ;// ./processor/migration/linkReference.ts
112728
112701
 
112729
- const linkReferenceTransformer = () => (tree) => {
112730
- lib_visit(tree, 'linkReference', (node, index, parent) => {
112731
- const definitions = {};
112732
- lib_visit(tree, 'definition', (def) => {
112733
- definitions[def.identifier] = def;
112734
- });
112735
- if (node.label === node.identifier && parent) {
112736
- if (!(node.identifier in definitions)) {
112737
- parent.children[index] = {
112738
- type: 'text',
112739
- value: `[${node.label}]`,
112740
- position: node.position,
112741
- };
112742
- }
112743
- }
112744
- });
112745
- return tree;
112746
- };
112747
- /* harmony default export */ const migration_linkReference = (linkReferenceTransformer);
112702
+ /**
112703
+ * Plugin to add support for parsing from HTML.
112704
+ *
112705
+ * > 👉 **Note**: this is not an XML parser.
112706
+ * > It supports SVG as embedded in HTML.
112707
+ * > It does not support the features available in XML.
112708
+ * > Passing SVG files might break but fragments of modern SVG should be fine.
112709
+ * > Use [`xast-util-from-xml`][xast-util-from-xml] to parse XML.
112710
+ *
112711
+ * @param {Options | null | undefined} [options]
112712
+ * Configuration (optional).
112713
+ * @returns {undefined}
112714
+ * Nothing.
112715
+ */
112716
+ function rehypeParse(options) {
112717
+ /** @type {Processor<Root>} */
112718
+ // @ts-expect-error: TS in JSDoc generates wrong types if `this` is typed regularly.
112719
+ const self = this
112720
+ const {emitParseErrors, ...settings} = {...self.data('settings'), ...options}
112748
112721
 
112749
- ;// ./processor/migration/table-cell.ts
112722
+ self.parser = parser
112750
112723
 
112751
- const magicIndex = (i, j) => `${i === 0 ? 'h' : `${i - 1}`}-${j}`;
112752
- const isInlineHtml = node => node.type === 'html' && !node.block;
112753
- // @note: This regex is detect malformed lists that were created by the
112754
- // markdown editor. Consider the following markdown:
112755
- //
112756
- // ```
112757
- // * item 1
112758
- // * item 2
112759
- // * item 3
112760
- // ```
112761
- //
112762
- // This is a perfectly valid list. But when you put that text into a table
112763
- // cell, the editor does **bad** things. After a save and load cycle, it gets
112764
- // converted to this:
112765
- //
112766
- // ```
112767
- // \_ item 1
112768
- // \_ item 2
112769
- // \* item 3
112770
- // ```
112771
- //
112772
- // The following regex attempts to detect this pattern, and we'll convert it to
112773
- // something more standard.
112774
- const psuedoListRegex = /^(?![ \t]*([*_]+).*\1[ \t]*$)(?<ws>[ \t]*)\\?([*_])\s*(?<item>.*)$/gm;
112775
- const migrateTableCells = (vfile, rdmd) => (table) => {
112776
- let json;
112777
- try {
112778
- const { position } = table;
112779
- if (position) {
112780
- json = JSON.parse(vfile
112781
- .toString()
112782
- .slice(position.start.offset, position.end.offset)
112783
- .replace(/.*\[block:parameters\](.*)\[\/block\].*/s, '$1'));
112784
- }
112785
- }
112786
- catch (err) {
112787
- /**
112788
- * This failure case is already handled by the following logic. Plus,
112789
- * because it's being handled internally, there's no way for our
112790
- * migration script to catch the error or keep track of it, and it just
112791
- * ends up blowing up the output logs.
112792
- */
112793
- // console.error(err);
112794
- }
112795
- lib_visit(table, 'tableRow', (row, i) => {
112796
- lib_visit(row, 'tableCell', (cell, j) => {
112797
- let children = cell.children;
112798
- if (json && json.data[magicIndex(i, j)]) {
112799
- const string = json.data[magicIndex(i, j)].replace(psuedoListRegex, '$<ws>- $<item>');
112800
- children = rdmd.mdast(string).children;
112724
+ /**
112725
+ * @type {Parser<Root>}
112726
+ */
112727
+ function parser(document, file) {
112728
+ return fromHtml(document, {
112729
+ ...settings,
112730
+ onerror: emitParseErrors
112731
+ ? function (message) {
112732
+ if (file.path) {
112733
+ message.name = file.path + ':' + message.name
112734
+ message.file = file.path
112801
112735
  }
112802
- cell.children =
112803
- children.length > 1 && !children.some(isInlineHtml)
112804
- ? children
112805
- : [{ type: 'paragraph', children }];
112806
- return lib_SKIP;
112807
- });
112808
- return lib_SKIP;
112809
- });
112810
- lib_visit(table, 'inlineCode', (code) => {
112811
- if (code.value.includes('\n')) {
112812
- code.type = 'code';
112813
- }
112814
- });
112815
- };
112816
- function tableCellTransformer() {
112817
- const rdmd = this.data('rdmd');
112818
- return (tree, vfile) => {
112819
- lib_visit(tree, 'table', migrateTableCells(vfile, rdmd));
112820
- return tree;
112821
- };
112822
- }
112823
- /* harmony default export */ const table_cell = (tableCellTransformer);
112824
-
112825
- ;// ./processor/migration/index.ts
112826
-
112827
-
112828
-
112829
-
112830
- const transformers = [migration_emphasis, migration_images, migration_linkReference, table_cell];
112831
- /* harmony default export */ const migration = ((/* unused pure expression or super */ null && (transformers)));
112832
112736
 
112833
- ;// ./lib/mdastV6.ts
112834
-
112835
- const migrationNormalize = (doc) => {
112836
- return doc.replaceAll(/^(<!--.*?)\\-->$/gms, '$1-->');
112837
- };
112838
- const mdastV6_mdastV6 = (doc, { rdmd }) => {
112839
- const [_normalizedDoc] = rdmd.setup(doc);
112840
- const normalizedDoc = migrationNormalize(_normalizedDoc);
112841
- const proc = rdmd.processor().use(migrationTransformers).data('rdmd', rdmd);
112842
- const tree = proc.parse(normalizedDoc);
112843
- proc.runSync(tree, normalizedDoc);
112844
- return tree;
112845
- };
112846
- /* harmony default export */ const lib_mdastV6 = ((/* unused pure expression or super */ null && (mdastV6_mdastV6)));
112737
+ file.messages.push(message)
112738
+ }
112739
+ : undefined
112740
+ })
112741
+ }
112742
+ }
112847
112743
 
112848
112744
  ;// ./node_modules/hast-util-is-element/lib/index.js
112849
112745
  /**
@@ -117370,6 +117266,227 @@ function rehypeRemark(destination, options) {
117370
117266
  }
117371
117267
  }
117372
117268
 
117269
+ ;// ./lib/htmlToMarkdown.ts
117270
+
117271
+
117272
+
117273
+
117274
+
117275
+ /**
117276
+ * Converts an HTML fragment to GitHub-flavored Markdown.
117277
+ *
117278
+ * `remark-gfm` is load-bearing: without it, `<table>` and `<del>` input throws
117279
+ * at serialization. `iframe` (default: becomes a link) and `noscript` (default:
117280
+ * keeps its text) are dropped by the handlers so raw markup never leaks;
117281
+ * `script`, `style`, and `template` already drop by default and are overridden
117282
+ * defensively. HTML comments are dropped via `nodeHandlers`.
117283
+ */
117284
+ const processor = lib_unified()
117285
+ .use(rehypeParse, { fragment: true })
117286
+ .use(rehypeRemark, {
117287
+ // A comment is a `comment` node, not an element, so it goes in
117288
+ // `nodeHandlers` rather than `handlers`.
117289
+ handlers: {
117290
+ iframe: () => undefined,
117291
+ noscript: () => undefined,
117292
+ script: () => undefined,
117293
+ style: () => undefined,
117294
+ template: () => undefined,
117295
+ },
117296
+ nodeHandlers: { comment: () => undefined },
117297
+ })
117298
+ .use(lib_remarkGfm)
117299
+ .use(lib_remarkStringify, { bullet: '-', emphasis: '_', fences: true });
117300
+ /**
117301
+ * Returns the Markdown form of `html`, or an empty string when there is no
117302
+ * usable input. Synchronous, so it can run inside non-async serializers.
117303
+ */
117304
+ function htmlToMarkdown(html) {
117305
+ if (typeof html !== 'string' || !html.trim())
117306
+ return '';
117307
+ return processor.processSync(html).toString().trim();
117308
+ }
117309
+
117310
+ ;// ./processor/migration/emphasis.ts
117311
+
117312
+ const emphasis_strongTest = (node) => ['emphasis', 'strong'].includes(node.type);
117313
+ const addSpaceBefore = (index, parent) => {
117314
+ if (!(index > 0 && parent.children[index - 1]))
117315
+ return;
117316
+ const prev = parent.children[index - 1];
117317
+ if (!('value' in prev) || prev.value.endsWith(' ') || prev.type === 'escape')
117318
+ return;
117319
+ parent.children.splice(index, 0, { type: 'text', value: ' ' });
117320
+ };
117321
+ const addSpaceAfter = (index, parent) => {
117322
+ if (!(index < parent.children.length - 1 && parent.children[index + 1]))
117323
+ return;
117324
+ const nextChild = parent.children[index + 1];
117325
+ if (!('value' in nextChild) || nextChild.value.startsWith(' '))
117326
+ return;
117327
+ parent.children.splice(index + 1, 0, { type: 'text', value: ' ' });
117328
+ };
117329
+ const trimEmphasis = (node, index, parent) => {
117330
+ let trimmed = false;
117331
+ lib_visit(node, 'text', (child) => {
117332
+ const newValue = child.value.trimStart();
117333
+ if (newValue !== child.value) {
117334
+ trimmed = true;
117335
+ child.value = newValue;
117336
+ }
117337
+ return EXIT;
117338
+ });
117339
+ lib_visit(node, 'text', (child) => {
117340
+ const newValue = child.value.trimEnd();
117341
+ if (newValue !== child.value) {
117342
+ trimmed = true;
117343
+ child.value = newValue;
117344
+ }
117345
+ return EXIT;
117346
+ }, true);
117347
+ if (trimmed) {
117348
+ addSpaceBefore(index, parent);
117349
+ addSpaceAfter(index, parent);
117350
+ }
117351
+ };
117352
+ const emphasisTransfomer = () => (tree) => {
117353
+ lib_visit(tree, emphasis_strongTest, trimEmphasis);
117354
+ return tree;
117355
+ };
117356
+ /* harmony default export */ const migration_emphasis = (emphasisTransfomer);
117357
+
117358
+ ;// ./processor/migration/images.ts
117359
+
117360
+ const images_imageTransformer = () => tree => {
117361
+ lib_visit(tree, 'image', (image) => {
117362
+ if (image.data?.hProperties?.className === 'border') {
117363
+ image.data.hProperties.border = true;
117364
+ }
117365
+ });
117366
+ };
117367
+ /* harmony default export */ const migration_images = (images_imageTransformer);
117368
+
117369
+ ;// ./processor/migration/linkReference.ts
117370
+
117371
+ const linkReferenceTransformer = () => (tree) => {
117372
+ lib_visit(tree, 'linkReference', (node, index, parent) => {
117373
+ const definitions = {};
117374
+ lib_visit(tree, 'definition', (def) => {
117375
+ definitions[def.identifier] = def;
117376
+ });
117377
+ if (node.label === node.identifier && parent) {
117378
+ if (!(node.identifier in definitions)) {
117379
+ parent.children[index] = {
117380
+ type: 'text',
117381
+ value: `[${node.label}]`,
117382
+ position: node.position,
117383
+ };
117384
+ }
117385
+ }
117386
+ });
117387
+ return tree;
117388
+ };
117389
+ /* harmony default export */ const migration_linkReference = (linkReferenceTransformer);
117390
+
117391
+ ;// ./processor/migration/table-cell.ts
117392
+
117393
+ const magicIndex = (i, j) => `${i === 0 ? 'h' : `${i - 1}`}-${j}`;
117394
+ const isInlineHtml = node => node.type === 'html' && !node.block;
117395
+ // @note: This regex is detect malformed lists that were created by the
117396
+ // markdown editor. Consider the following markdown:
117397
+ //
117398
+ // ```
117399
+ // * item 1
117400
+ // * item 2
117401
+ // * item 3
117402
+ // ```
117403
+ //
117404
+ // This is a perfectly valid list. But when you put that text into a table
117405
+ // cell, the editor does **bad** things. After a save and load cycle, it gets
117406
+ // converted to this:
117407
+ //
117408
+ // ```
117409
+ // \_ item 1
117410
+ // \_ item 2
117411
+ // \* item 3
117412
+ // ```
117413
+ //
117414
+ // The following regex attempts to detect this pattern, and we'll convert it to
117415
+ // something more standard.
117416
+ const psuedoListRegex = /^(?![ \t]*([*_]+).*\1[ \t]*$)(?<ws>[ \t]*)\\?([*_])\s*(?<item>.*)$/gm;
117417
+ const migrateTableCells = (vfile, rdmd) => (table) => {
117418
+ let json;
117419
+ try {
117420
+ const { position } = table;
117421
+ if (position) {
117422
+ json = JSON.parse(vfile
117423
+ .toString()
117424
+ .slice(position.start.offset, position.end.offset)
117425
+ .replace(/.*\[block:parameters\](.*)\[\/block\].*/s, '$1'));
117426
+ }
117427
+ }
117428
+ catch (err) {
117429
+ /**
117430
+ * This failure case is already handled by the following logic. Plus,
117431
+ * because it's being handled internally, there's no way for our
117432
+ * migration script to catch the error or keep track of it, and it just
117433
+ * ends up blowing up the output logs.
117434
+ */
117435
+ // console.error(err);
117436
+ }
117437
+ lib_visit(table, 'tableRow', (row, i) => {
117438
+ lib_visit(row, 'tableCell', (cell, j) => {
117439
+ let children = cell.children;
117440
+ if (json && json.data[magicIndex(i, j)]) {
117441
+ const string = json.data[magicIndex(i, j)].replace(psuedoListRegex, '$<ws>- $<item>');
117442
+ children = rdmd.mdast(string).children;
117443
+ }
117444
+ cell.children =
117445
+ children.length > 1 && !children.some(isInlineHtml)
117446
+ ? children
117447
+ : [{ type: 'paragraph', children }];
117448
+ return lib_SKIP;
117449
+ });
117450
+ return lib_SKIP;
117451
+ });
117452
+ lib_visit(table, 'inlineCode', (code) => {
117453
+ if (code.value.includes('\n')) {
117454
+ code.type = 'code';
117455
+ }
117456
+ });
117457
+ };
117458
+ function tableCellTransformer() {
117459
+ const rdmd = this.data('rdmd');
117460
+ return (tree, vfile) => {
117461
+ lib_visit(tree, 'table', migrateTableCells(vfile, rdmd));
117462
+ return tree;
117463
+ };
117464
+ }
117465
+ /* harmony default export */ const table_cell = (tableCellTransformer);
117466
+
117467
+ ;// ./processor/migration/index.ts
117468
+
117469
+
117470
+
117471
+
117472
+ const transformers = [migration_emphasis, migration_images, migration_linkReference, table_cell];
117473
+ /* harmony default export */ const migration = ((/* unused pure expression or super */ null && (transformers)));
117474
+
117475
+ ;// ./lib/mdastV6.ts
117476
+
117477
+ const migrationNormalize = (doc) => {
117478
+ return doc.replaceAll(/^(<!--.*?)\\-->$/gms, '$1-->');
117479
+ };
117480
+ const mdastV6_mdastV6 = (doc, { rdmd }) => {
117481
+ const [_normalizedDoc] = rdmd.setup(doc);
117482
+ const normalizedDoc = migrationNormalize(_normalizedDoc);
117483
+ const proc = rdmd.processor().use(migrationTransformers).data('rdmd', rdmd);
117484
+ const tree = proc.parse(normalizedDoc);
117485
+ proc.runSync(tree, normalizedDoc);
117486
+ return tree;
117487
+ };
117488
+ /* harmony default export */ const lib_mdastV6 = ((/* unused pure expression or super */ null && (mdastV6_mdastV6)));
117489
+
117373
117490
  ;// ./processor/compile/anchor.ts
117374
117491
 
117375
117492
 
@@ -117862,7 +117979,7 @@ function normalizeProperties(node) {
117862
117979
  * Identifies custom MDX components and recursively parses markdown children.
117863
117980
  * Replaces tagName with PascalCase component name for React component resolution.
117864
117981
  *
117865
- * @see {@link https://github.com/readmeio/rmdx/blob/main/docs/mdxish-flow.md}
117982
+ * @see .claude/context/MDXish/Processor Overview.md
117866
117983
  * @param {Options} options - Configuration options
117867
117984
  * @param {CustomComponents} options.components - Available custom components
117868
117985
  * @param {Function} options.processMarkdown - Function to process markdown content
@@ -120360,6 +120477,13 @@ const htmlFlowTagNames = new Set([...htmlRawNames, ...htmlBlockNames]);
120360
120477
  // blank lines between nested JSX siblings don't fragment the block. Excludes table
120361
120478
  // tags (mdxishTables owns their blank lines) and voids (never close).
120362
120479
  const plainBlockClaimTagNames = new Set([...htmlBlockNames].filter(tag => !HTML_TABLE_STRUCTURE_TAGS.has(tag) && !HTML_VOID_ELEMENTS.has(tag)));
120480
+ const foreignContentTags = new Set(FOREIGN_CONTENT_TAGS);
120481
+ // Type-7 lowercase tags (a, span, button, and unknown names): CommonMark ends their
120482
+ // block at a blank line, fragmenting 4+ column children into indented code. Claimable
120483
+ // only in block-wrapper shape (see `blockWrapperOpenerRest`); lookalike openers
120484
+ // (`<https://…>`) never find a closer, so their claim retreats cleanly to CommonMark.
120485
+ // Voids never close and raw/foreign-content bodies have dedicated owners.
120486
+ const isBlockWrapperClaimTagName = (tag) => !htmlFlowTagNames.has(tag) && !HTML_VOID_ELEMENTS.has(tag) && !foreignContentTags.has(tag);
120363
120487
  // Both are 4 columns per CommonMark, but they mean different things: a tab advances
120364
120488
  // to the next multiple of TAB_STOP_WIDTH, and INDENTED_CODE_MIN_COLUMNS is the depth
120365
120489
  // at which a line would fragment into indented code. Named separately so the two
@@ -120424,6 +120548,11 @@ function createTokenize(mode) {
120424
120548
  // `plainClaimLineStart`: after a blank line it may only continue on a tag line.
120425
120549
  let isPlainBlockClaim = false;
120426
120550
  let pendingBlankLine = false;
120551
+ // Type-7 tag claimed pending the block-wrapper (opener alone on its line) check.
120552
+ let pendingBlockWrapperClaim = false;
120553
+ // True once a block-wrapper claim is confirmed; relaxes the top-of-body island gate
120554
+ // below (type-7 fallback is the fragmentation bug, not intentional indented code).
120555
+ let isBlockWrapperClaim = false;
120427
120556
  // Leading indent columns of the current plain-claim line, reset per line; ≥4 is
120428
120557
  // where CommonMark would fragment the island as indented code. Tabs advance to the
120429
120558
  // next 4-column stop — the same rule `expandIndentToColumns`
@@ -120669,16 +120798,11 @@ function createTokenize(mode) {
120669
120798
  }
120670
120799
  // End of opening tag
120671
120800
  if (code === codes.greaterThan) {
120672
- if (requiresBraceAttr && !sawBraceAttr) {
120673
- // Plain lowercase block tags stay claimable in flow, gated per line by
120674
- // `plainClaimLineStart`; everything else falls through to CommonMark.
120675
- if (!isFlow || !plainBlockClaimTagNames.has(tagName))
120676
- return nok(code);
120677
- isPlainBlockClaim = true;
120678
- }
120801
+ if (requiresBraceAttr && !sawBraceAttr && !claimBraceLessTag())
120802
+ return nok(code);
120679
120803
  effects.consume(code);
120680
120804
  onOpenerLine = isFlow;
120681
- return body;
120805
+ return pendingBlockWrapperClaim ? blockWrapperOpenerRest : body;
120682
120806
  }
120683
120807
  // Quoted attribute value
120684
120808
  if (code === codes.quotationMark || code === codes.apostrophe) {
@@ -120733,6 +120857,35 @@ function createTokenize(mode) {
120733
120857
  // `/ ` without `>` is just part of the attribute area
120734
120858
  return afterOpenTagName(code);
120735
120859
  }
120860
+ // Whether a brace-less lowercase flow tag is claimable: type-6 tags immediately,
120861
+ // type-7 tags pending the block-wrapper check; anything else is CommonMark's.
120862
+ function claimBraceLessTag() {
120863
+ if (!isFlow)
120864
+ return false;
120865
+ if (plainBlockClaimTagNames.has(tagName)) {
120866
+ isPlainBlockClaim = true;
120867
+ return true;
120868
+ }
120869
+ if (isBlockWrapperClaimTagName(tagName)) {
120870
+ pendingBlockWrapperClaim = true;
120871
+ return true;
120872
+ }
120873
+ return false;
120874
+ }
120875
+ // A type-7 tag is claimed only as a block wrapper: opener alone on its line
120876
+ // (trailing spaces ok). Inline content after the opener bails to CommonMark.
120877
+ function blockWrapperOpenerRest(code) {
120878
+ if (markdownSpace(code)) {
120879
+ effects.consume(code);
120880
+ return blockWrapperOpenerRest;
120881
+ }
120882
+ if (!markdownLineEnding(code))
120883
+ return nok(code);
120884
+ pendingBlockWrapperClaim = false;
120885
+ isPlainBlockClaim = true;
120886
+ isBlockWrapperClaim = true;
120887
+ return body(code);
120888
+ }
120736
120889
  // Continuation for multi-line opening tags
120737
120890
  function openTagContinuationStart(code) {
120738
120891
  return effects.check(continuation_checks_nonLazyContinuationStart, openTagContinuationNonLazy, continuationAfter)(code);
@@ -121128,10 +121281,16 @@ function createTokenize(mode) {
121128
121281
  // continue on a tag line (`<…`); any markdown island (`**bold**`, `[block:…]`, a
121129
121282
  // fence) refuses so CommonMark html-flow reparses it exactly as it does today.
121130
121283
  function plainClaimLineStart(code) {
121131
- // Leading whitespace only → treat as a blank line, matching CommonMark.
121132
- if (code === codes.space || code === codes.horizontalTab) {
121133
- plainClaimIndentColumns +=
121134
- code === codes.horizontalTab ? TAB_STOP_WIDTH - (plainClaimIndentColumns % TAB_STOP_WIDTH) : 1;
121284
+ // Leading whitespace only → treat as a blank line, matching CommonMark. A tab
121285
+ // advances to the next stop; its trailing `virtualSpace` fillers add nothing
121286
+ // but must still be consumed or they'd read as line content below.
121287
+ if (markdownSpace(code)) {
121288
+ if (code === codes.horizontalTab) {
121289
+ plainClaimIndentColumns += TAB_STOP_WIDTH - (plainClaimIndentColumns % TAB_STOP_WIDTH);
121290
+ }
121291
+ else if (code === codes.space) {
121292
+ plainClaimIndentColumns += 1;
121293
+ }
121135
121294
  effects.consume(code);
121136
121295
  return plainClaimLineStart;
121137
121296
  }
@@ -121143,10 +121302,11 @@ function createTokenize(mode) {
121143
121302
  if (pendingBlankLine) {
121144
121303
  // A 4+ col island nested under other tags is cosmetic nesting indent, not code:
121145
121304
  // keep claiming so promotion dedents + re-parses it as markdown (RM-17560).
121146
- // Tags whose bodies stay raw are excludeda claimed island there would never
121147
- // be re-parsed and would leak as literal text.
121305
+ // Block-wrapper claims extend this to top-of-body islandstheir CommonMark
121306
+ // fallback is the fragmentation bug, not intentional indented code. Tags whose
121307
+ // bodies stay raw are excluded: a claimed island there would leak as literal text.
121148
121308
  if (plainClaimIndentColumns >= INDENTED_CODE_MIN_COLUMNS &&
121149
- sawPlainBlockBodyContent &&
121309
+ (sawPlainBlockBodyContent || isBlockWrapperClaim) &&
121150
121310
  !NON_REPARSED_BODY_TAGS.has(tagName)) {
121151
121311
  return plainClaimContinue(code);
121152
121312
  }
@@ -121225,6 +121385,7 @@ function syntax_mdxComponent() {
121225
121385
 
121226
121386
 
121227
121387
 
121388
+
121228
121389
 
121229
121390
 
121230
121391
  const buildInlineMdProcessor = (safeMode) => {
@@ -121232,7 +121393,7 @@ const buildInlineMdProcessor = (safeMode) => {
121232
121393
  // body (e.g. a `<Callout>`) is captured as one html node. Without it, blank
121233
121394
  // lines between rows let CommonMark HTML block type 6 fragment the table and
121234
121395
  // its rows spill out as text / indented code blocks (CX-3705).
121235
- const micromarkExts = [syntax_jsxTable(), syntax_mdxComponent(), syntax_gemoji(), legacyVariable(), syntax_magicBlock()];
121396
+ const micromarkExts = [disableIndentedCode, syntax_jsxTable(), syntax_mdxComponent(), syntax_gemoji(), legacyVariable(), syntax_magicBlock()];
121236
121397
  const fromMarkdownExts = [
121237
121398
  jsx_table_jsxTableFromMarkdown(),
121238
121399
  mdx_component_mdxComponentFromMarkdown(),
@@ -122541,71 +122702,6 @@ const generateSlugForHeadings = () => (tree) => {
122541
122702
  // EXTERNAL MODULE: ./node_modules/@readme/variable/dist/index.js
122542
122703
  var variable_dist = __webpack_require__(4355);
122543
122704
  var variable_dist_default = /*#__PURE__*/__webpack_require__.n(variable_dist);
122544
- ;// ./node_modules/rehype-parse/lib/index.js
122545
- /**
122546
- * @import {Root} from 'hast'
122547
- * @import {Options as FromHtmlOptions} from 'hast-util-from-html'
122548
- * @import {Parser, Processor} from 'unified'
122549
- */
122550
-
122551
- /**
122552
- * @typedef {Omit<FromHtmlOptions, 'onerror'> & RehypeParseFields} Options
122553
- * Configuration.
122554
- *
122555
- * @typedef RehypeParseFields
122556
- * Extra fields.
122557
- * @property {boolean | null | undefined} [emitParseErrors=false]
122558
- * Whether to emit parse errors while parsing (default: `false`).
122559
- *
122560
- * > 👉 **Note**: parse errors are currently being added to HTML.
122561
- * > Not all errors emitted by parse5 (or us) are specced yet.
122562
- * > Some documentation may still be missing.
122563
- */
122564
-
122565
-
122566
-
122567
- /**
122568
- * Plugin to add support for parsing from HTML.
122569
- *
122570
- * > 👉 **Note**: this is not an XML parser.
122571
- * > It supports SVG as embedded in HTML.
122572
- * > It does not support the features available in XML.
122573
- * > Passing SVG files might break but fragments of modern SVG should be fine.
122574
- * > Use [`xast-util-from-xml`][xast-util-from-xml] to parse XML.
122575
- *
122576
- * @param {Options | null | undefined} [options]
122577
- * Configuration (optional).
122578
- * @returns {undefined}
122579
- * Nothing.
122580
- */
122581
- function rehypeParse(options) {
122582
- /** @type {Processor<Root>} */
122583
- // @ts-expect-error: TS in JSDoc generates wrong types if `this` is typed regularly.
122584
- const self = this
122585
- const {emitParseErrors, ...settings} = {...self.data('settings'), ...options}
122586
-
122587
- self.parser = parser
122588
-
122589
- /**
122590
- * @type {Parser<Root>}
122591
- */
122592
- function parser(document, file) {
122593
- return fromHtml(document, {
122594
- ...settings,
122595
- onerror: emitParseErrors
122596
- ? function (message) {
122597
- if (file.path) {
122598
- message.name = file.path + ':' + message.name
122599
- message.file = file.path
122600
- }
122601
-
122602
- file.messages.push(message)
122603
- }
122604
- : undefined
122605
- })
122606
- }
122607
- }
122608
-
122609
122705
  ;// ./node_modules/hast-util-to-html/lib/handle/comment.js
122610
122706
  /**
122611
122707
  * @typedef {import('hast').Comment} Comment
@@ -126951,6 +127047,7 @@ function mdxishAstProcessor(mdContent, opts = {}) {
126951
127047
  // Parser extension for MDX expressions {}
126952
127048
  const mdxExprTextOnly = mdxExpressionLenient();
126953
127049
  const micromarkExts = [
127050
+ disableIndentedCode,
126954
127051
  syntax_jsxTable(),
126955
127052
  syntax_magicBlock(),
126956
127053
  syntax_mdxComponent(),
@@ -127053,7 +127150,7 @@ function mdxishMdastToMd(mdast) {
127053
127150
  * Processes markdown content with MDX syntax support and returns a HAST.
127054
127151
  * Detects and renders custom component tags from the components hash.
127055
127152
  *
127056
- * @see {@link https://github.com/readmeio/rmdx/blob/main/docs/mdxish-flow.md}
127153
+ * @see .claude/context/MDXish/Processor Overview.md
127057
127154
  */
127058
127155
  function mdxish_mdxish(mdContent, opts = {}) {
127059
127156
  const { components: userComponents = {}, safeMode = false, variables } = opts;
@@ -127337,7 +127434,7 @@ function buildRMDXModule(content, headings, tocHast, opts) {
127337
127434
  * @param opts - The options for the render
127338
127435
  * @returns The React component
127339
127436
  *
127340
- * @see {@link https://github.com/readmeio/rmdx/blob/main/docs/mdxish-flow.md}
127437
+ * @see .claude/context/MDXish/Processor Overview.md
127341
127438
  */
127342
127439
  const renderMdxish = (tree, opts = {}) => {
127343
127440
  const { components: userComponents = {}, variables, ...contextOpts } = opts;
@@ -127627,6 +127724,7 @@ async function stripComments(doc, { mdx, mdxish } = {}) {
127627
127724
 
127628
127725
 
127629
127726
 
127727
+
127630
127728
  ;// ./lib/render-fixture/renderFixture.ts
127631
127729
 
127632
127730