@readme/markdown 15.9.4 → 15.10.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
@@ -19111,7 +19111,7 @@ module.exports = function () {
19111
19111
 
19112
19112
  /***/ },
19113
19113
 
19114
- /***/ 3975
19114
+ /***/ 5893
19115
19115
  (module, __webpack_exports__, __webpack_require__) {
19116
19116
 
19117
19117
  "use strict";
@@ -19136,6 +19136,7 @@ __webpack_require__.d(__webpack_exports__, {
19136
19136
  mdx: () => (/* reexport */ lib_mdx),
19137
19137
  mdxish: () => (/* reexport */ lib_mdxish),
19138
19138
  mdxishAstProcessor: () => (/* reexport */ mdxishAstProcessor),
19139
+ mdxishHeadingIds: () => (/* reexport */ mdxishHeadingIds),
19139
19140
  mdxishMdastToMd: () => (/* reexport */ mdxishMdastToMd),
19140
19141
  mdxishTags: () => (/* reexport */ mdxishTags),
19141
19142
  migrate: () => (/* reexport */ lib_migrate),
@@ -75084,6 +75085,209 @@ const mdast = (text, opts = {}) => {
75084
75085
  };
75085
75086
  /* harmony default export */ const lib_mdast = (mdast);
75086
75087
 
75088
+ ;// ./node_modules/micromark-util-symbol/lib/codes.js
75089
+ /**
75090
+ * Character codes.
75091
+ *
75092
+ * This module is compiled away!
75093
+ *
75094
+ * micromark works based on character codes.
75095
+ * This module contains constants for the ASCII block and the replacement
75096
+ * character.
75097
+ * A couple of them are handled in a special way, such as the line endings
75098
+ * (CR, LF, and CR+LF, commonly known as end-of-line: EOLs), the tab (horizontal
75099
+ * tab) and its expansion based on what column it’s at (virtual space),
75100
+ * and the end-of-file (eof) character.
75101
+ * As values are preprocessed before handling them, the actual characters LF,
75102
+ * CR, HT, and NUL (which is present as the replacement character), are
75103
+ * guaranteed to not exist.
75104
+ *
75105
+ * Unicode basic latin block.
75106
+ */
75107
+ const codes = /** @type {const} */ ({
75108
+ carriageReturn: -5,
75109
+ lineFeed: -4,
75110
+ carriageReturnLineFeed: -3,
75111
+ horizontalTab: -2,
75112
+ virtualSpace: -1,
75113
+ eof: null,
75114
+ nul: 0,
75115
+ soh: 1,
75116
+ stx: 2,
75117
+ etx: 3,
75118
+ eot: 4,
75119
+ enq: 5,
75120
+ ack: 6,
75121
+ bel: 7,
75122
+ bs: 8,
75123
+ ht: 9, // `\t`
75124
+ lf: 10, // `\n`
75125
+ vt: 11, // `\v`
75126
+ ff: 12, // `\f`
75127
+ cr: 13, // `\r`
75128
+ so: 14,
75129
+ si: 15,
75130
+ dle: 16,
75131
+ dc1: 17,
75132
+ dc2: 18,
75133
+ dc3: 19,
75134
+ dc4: 20,
75135
+ nak: 21,
75136
+ syn: 22,
75137
+ etb: 23,
75138
+ can: 24,
75139
+ em: 25,
75140
+ sub: 26,
75141
+ esc: 27,
75142
+ fs: 28,
75143
+ gs: 29,
75144
+ rs: 30,
75145
+ us: 31,
75146
+ space: 32,
75147
+ exclamationMark: 33, // `!`
75148
+ quotationMark: 34, // `"`
75149
+ numberSign: 35, // `#`
75150
+ dollarSign: 36, // `$`
75151
+ percentSign: 37, // `%`
75152
+ ampersand: 38, // `&`
75153
+ apostrophe: 39, // `'`
75154
+ leftParenthesis: 40, // `(`
75155
+ rightParenthesis: 41, // `)`
75156
+ asterisk: 42, // `*`
75157
+ plusSign: 43, // `+`
75158
+ comma: 44, // `,`
75159
+ dash: 45, // `-`
75160
+ dot: 46, // `.`
75161
+ slash: 47, // `/`
75162
+ digit0: 48, // `0`
75163
+ digit1: 49, // `1`
75164
+ digit2: 50, // `2`
75165
+ digit3: 51, // `3`
75166
+ digit4: 52, // `4`
75167
+ digit5: 53, // `5`
75168
+ digit6: 54, // `6`
75169
+ digit7: 55, // `7`
75170
+ digit8: 56, // `8`
75171
+ digit9: 57, // `9`
75172
+ colon: 58, // `:`
75173
+ semicolon: 59, // `;`
75174
+ lessThan: 60, // `<`
75175
+ equalsTo: 61, // `=`
75176
+ greaterThan: 62, // `>`
75177
+ questionMark: 63, // `?`
75178
+ atSign: 64, // `@`
75179
+ uppercaseA: 65, // `A`
75180
+ uppercaseB: 66, // `B`
75181
+ uppercaseC: 67, // `C`
75182
+ uppercaseD: 68, // `D`
75183
+ uppercaseE: 69, // `E`
75184
+ uppercaseF: 70, // `F`
75185
+ uppercaseG: 71, // `G`
75186
+ uppercaseH: 72, // `H`
75187
+ uppercaseI: 73, // `I`
75188
+ uppercaseJ: 74, // `J`
75189
+ uppercaseK: 75, // `K`
75190
+ uppercaseL: 76, // `L`
75191
+ uppercaseM: 77, // `M`
75192
+ uppercaseN: 78, // `N`
75193
+ uppercaseO: 79, // `O`
75194
+ uppercaseP: 80, // `P`
75195
+ uppercaseQ: 81, // `Q`
75196
+ uppercaseR: 82, // `R`
75197
+ uppercaseS: 83, // `S`
75198
+ uppercaseT: 84, // `T`
75199
+ uppercaseU: 85, // `U`
75200
+ uppercaseV: 86, // `V`
75201
+ uppercaseW: 87, // `W`
75202
+ uppercaseX: 88, // `X`
75203
+ uppercaseY: 89, // `Y`
75204
+ uppercaseZ: 90, // `Z`
75205
+ leftSquareBracket: 91, // `[`
75206
+ backslash: 92, // `\`
75207
+ rightSquareBracket: 93, // `]`
75208
+ caret: 94, // `^`
75209
+ underscore: 95, // `_`
75210
+ graveAccent: 96, // `` ` ``
75211
+ lowercaseA: 97, // `a`
75212
+ lowercaseB: 98, // `b`
75213
+ lowercaseC: 99, // `c`
75214
+ lowercaseD: 100, // `d`
75215
+ lowercaseE: 101, // `e`
75216
+ lowercaseF: 102, // `f`
75217
+ lowercaseG: 103, // `g`
75218
+ lowercaseH: 104, // `h`
75219
+ lowercaseI: 105, // `i`
75220
+ lowercaseJ: 106, // `j`
75221
+ lowercaseK: 107, // `k`
75222
+ lowercaseL: 108, // `l`
75223
+ lowercaseM: 109, // `m`
75224
+ lowercaseN: 110, // `n`
75225
+ lowercaseO: 111, // `o`
75226
+ lowercaseP: 112, // `p`
75227
+ lowercaseQ: 113, // `q`
75228
+ lowercaseR: 114, // `r`
75229
+ lowercaseS: 115, // `s`
75230
+ lowercaseT: 116, // `t`
75231
+ lowercaseU: 117, // `u`
75232
+ lowercaseV: 118, // `v`
75233
+ lowercaseW: 119, // `w`
75234
+ lowercaseX: 120, // `x`
75235
+ lowercaseY: 121, // `y`
75236
+ lowercaseZ: 122, // `z`
75237
+ leftCurlyBrace: 123, // `{`
75238
+ verticalBar: 124, // `|`
75239
+ rightCurlyBrace: 125, // `}`
75240
+ tilde: 126, // `~`
75241
+ del: 127,
75242
+ // Unicode Specials block.
75243
+ byteOrderMarker: 65_279,
75244
+ // Unicode Specials block.
75245
+ replacementCharacter: 65_533 // `�`
75246
+ })
75247
+
75248
+ ;// ./lib/micromark/heading-id/syntax.ts
75249
+
75250
+
75251
+ /** One character a `{#id}` heading id may use: the ones github-slugger keeps, plus `.` and `:`. */
75252
+ const HEADING_ID_CHAR = '[\\p{L}\\p{M}\\p{N}_.:-]';
75253
+ const ID_CLOSE_REGEX = new RegExp(`^${HEADING_ID_CHAR}+\\}$`, 'u');
75254
+ const typeAt = (events, index) => events[index]?.[1].type;
75255
+ function isIdToken(events, index, context, type, value) {
75256
+ return typeAt(events, index) === type && value.test(context.sliceSerialize(events[index][1]));
75257
+ }
75258
+ /** The exit index of the heading's last content token, past any trailing space and closing `##`. */
75259
+ function contentEnd(events) {
75260
+ let end = events.length - 2;
75261
+ if (typeAt(events, end) === 'whitespace')
75262
+ end -= 2;
75263
+ if (typeAt(events, end) === 'atxHeadingSequence' && typeAt(events, end - 2) === 'whitespace')
75264
+ end -= 4;
75265
+ return end;
75266
+ }
75267
+ const resolveHeadingId = (events, context) => {
75268
+ // Each token is an enter and an exit event; these indexes point at the exits.
75269
+ const close = contentEnd(events);
75270
+ const hash = close - 2;
75271
+ const open = close - 4;
75272
+ const space = close - 6;
75273
+ const endsWithId = isIdToken(events, close, context, 'atxHeadingText', ID_CLOSE_REGEX) &&
75274
+ isIdToken(events, hash, context, 'atxHeadingSequence', /^#$/) &&
75275
+ isIdToken(events, open, context, 'atxHeadingText', /^\{$/) &&
75276
+ typeAt(events, space) === 'whitespace';
75277
+ if (!endsWithId)
75278
+ return headingAtx.resolve?.(events, context) ?? events;
75279
+ const id = { type: 'headingId', start: events[open][1].start, end: events[close][1].end };
75280
+ events.splice(space - 1, close - space + 2);
75281
+ const resolved = headingAtx.resolve?.(events, context) ?? events;
75282
+ resolved.splice(resolved.length - 1, 0, ['enter', id, context], ['exit', id, context]);
75283
+ return resolved;
75284
+ };
75285
+ const headingIdConstruct = { ...headingAtx, resolve: resolveHeadingId };
75286
+ /** The ATX heading construct, with a line-final ` {#id}` split off as a `headingId` token. */
75287
+ function headingId() {
75288
+ return { flow: { [codes.numberSign]: headingIdConstruct } };
75289
+ }
75290
+
75087
75291
  ;// ./lib/utils/jsx-acorn-parser.ts
75088
75292
 
75089
75293
 
@@ -75195,6 +75399,7 @@ const evaluateLiteralExpression = (source) => {
75195
75399
 
75196
75400
 
75197
75401
 
75402
+
75198
75403
  /**
75199
75404
  * Evaluate a JavaScript expression source and return its value.
75200
75405
  *
@@ -75311,6 +75516,24 @@ const getHPropKeys = (node) => {
75311
75516
  const hProps = getHProps(node);
75312
75517
  return Object.keys(hProps) || [];
75313
75518
  };
75519
+ /** Turn a non-renderable evaluation result into a text node. */
75520
+ const createTextNode = (result, position) => {
75521
+ if (result === null || result === undefined)
75522
+ return { type: 'text', value: '', position };
75523
+ if (typeof result === 'object')
75524
+ return { type: 'text', value: JSON.stringify(result), position };
75525
+ return { type: 'text', value: String(result), position };
75526
+ };
75527
+ const HEADING_ID_REGEX = new RegExp(`^${HEADING_ID_CHAR}+$`, 'u');
75528
+ /**
75529
+ * The id a heading's trailing `{#id}` set, when it is one the `{#id}` syntax can spell.
75530
+ *
75531
+ * Ids may use letters, numbers, `-`, `_`, `.` and `:`; anything else, like `x y`, is dropped.
75532
+ */
75533
+ const explicitHeadingId = (node) => {
75534
+ const id = node.data?.hProperties?.id;
75535
+ return typeof id === 'string' && HEADING_ID_REGEX.test(id) ? id : undefined;
75536
+ };
75314
75537
  /**
75315
75538
  * Gets the attributes of an MDX element and returns them as an object of hProperties.
75316
75539
  *
@@ -93446,6 +93669,17 @@ function gemojiFromMarkdown() {
93446
93669
  };
93447
93670
  }
93448
93671
 
93672
+ ;// ./lib/mdast-util/heading-id/index.ts
93673
+ function exitHeadingId(token) {
93674
+ const heading = this.stack[this.stack.length - 1];
93675
+ const id = this.sliceSerialize(token).slice('{#'.length, -'}'.length);
93676
+ heading.data = { ...heading.data, hProperties: { ...heading.data?.hProperties, id } };
93677
+ }
93678
+ /** Sets a heading's id from its `headingId` token. */
93679
+ function headingIdFromMarkdown() {
93680
+ return { exit: { headingId: exitHeadingId } };
93681
+ }
93682
+
93449
93683
  ;// ./lib/mdast-util/html-block-component/index.ts
93450
93684
  const contextMap = new WeakMap();
93451
93685
  function findHtmlBlockComponentToken() {
@@ -93824,166 +94058,6 @@ function mdxComponentFromMarkdown() {
93824
94058
  };
93825
94059
  }
93826
94060
 
93827
- ;// ./node_modules/micromark-util-symbol/lib/codes.js
93828
- /**
93829
- * Character codes.
93830
- *
93831
- * This module is compiled away!
93832
- *
93833
- * micromark works based on character codes.
93834
- * This module contains constants for the ASCII block and the replacement
93835
- * character.
93836
- * A couple of them are handled in a special way, such as the line endings
93837
- * (CR, LF, and CR+LF, commonly known as end-of-line: EOLs), the tab (horizontal
93838
- * tab) and its expansion based on what column it’s at (virtual space),
93839
- * and the end-of-file (eof) character.
93840
- * As values are preprocessed before handling them, the actual characters LF,
93841
- * CR, HT, and NUL (which is present as the replacement character), are
93842
- * guaranteed to not exist.
93843
- *
93844
- * Unicode basic latin block.
93845
- */
93846
- const codes = /** @type {const} */ ({
93847
- carriageReturn: -5,
93848
- lineFeed: -4,
93849
- carriageReturnLineFeed: -3,
93850
- horizontalTab: -2,
93851
- virtualSpace: -1,
93852
- eof: null,
93853
- nul: 0,
93854
- soh: 1,
93855
- stx: 2,
93856
- etx: 3,
93857
- eot: 4,
93858
- enq: 5,
93859
- ack: 6,
93860
- bel: 7,
93861
- bs: 8,
93862
- ht: 9, // `\t`
93863
- lf: 10, // `\n`
93864
- vt: 11, // `\v`
93865
- ff: 12, // `\f`
93866
- cr: 13, // `\r`
93867
- so: 14,
93868
- si: 15,
93869
- dle: 16,
93870
- dc1: 17,
93871
- dc2: 18,
93872
- dc3: 19,
93873
- dc4: 20,
93874
- nak: 21,
93875
- syn: 22,
93876
- etb: 23,
93877
- can: 24,
93878
- em: 25,
93879
- sub: 26,
93880
- esc: 27,
93881
- fs: 28,
93882
- gs: 29,
93883
- rs: 30,
93884
- us: 31,
93885
- space: 32,
93886
- exclamationMark: 33, // `!`
93887
- quotationMark: 34, // `"`
93888
- numberSign: 35, // `#`
93889
- dollarSign: 36, // `$`
93890
- percentSign: 37, // `%`
93891
- ampersand: 38, // `&`
93892
- apostrophe: 39, // `'`
93893
- leftParenthesis: 40, // `(`
93894
- rightParenthesis: 41, // `)`
93895
- asterisk: 42, // `*`
93896
- plusSign: 43, // `+`
93897
- comma: 44, // `,`
93898
- dash: 45, // `-`
93899
- dot: 46, // `.`
93900
- slash: 47, // `/`
93901
- digit0: 48, // `0`
93902
- digit1: 49, // `1`
93903
- digit2: 50, // `2`
93904
- digit3: 51, // `3`
93905
- digit4: 52, // `4`
93906
- digit5: 53, // `5`
93907
- digit6: 54, // `6`
93908
- digit7: 55, // `7`
93909
- digit8: 56, // `8`
93910
- digit9: 57, // `9`
93911
- colon: 58, // `:`
93912
- semicolon: 59, // `;`
93913
- lessThan: 60, // `<`
93914
- equalsTo: 61, // `=`
93915
- greaterThan: 62, // `>`
93916
- questionMark: 63, // `?`
93917
- atSign: 64, // `@`
93918
- uppercaseA: 65, // `A`
93919
- uppercaseB: 66, // `B`
93920
- uppercaseC: 67, // `C`
93921
- uppercaseD: 68, // `D`
93922
- uppercaseE: 69, // `E`
93923
- uppercaseF: 70, // `F`
93924
- uppercaseG: 71, // `G`
93925
- uppercaseH: 72, // `H`
93926
- uppercaseI: 73, // `I`
93927
- uppercaseJ: 74, // `J`
93928
- uppercaseK: 75, // `K`
93929
- uppercaseL: 76, // `L`
93930
- uppercaseM: 77, // `M`
93931
- uppercaseN: 78, // `N`
93932
- uppercaseO: 79, // `O`
93933
- uppercaseP: 80, // `P`
93934
- uppercaseQ: 81, // `Q`
93935
- uppercaseR: 82, // `R`
93936
- uppercaseS: 83, // `S`
93937
- uppercaseT: 84, // `T`
93938
- uppercaseU: 85, // `U`
93939
- uppercaseV: 86, // `V`
93940
- uppercaseW: 87, // `W`
93941
- uppercaseX: 88, // `X`
93942
- uppercaseY: 89, // `Y`
93943
- uppercaseZ: 90, // `Z`
93944
- leftSquareBracket: 91, // `[`
93945
- backslash: 92, // `\`
93946
- rightSquareBracket: 93, // `]`
93947
- caret: 94, // `^`
93948
- underscore: 95, // `_`
93949
- graveAccent: 96, // `` ` ``
93950
- lowercaseA: 97, // `a`
93951
- lowercaseB: 98, // `b`
93952
- lowercaseC: 99, // `c`
93953
- lowercaseD: 100, // `d`
93954
- lowercaseE: 101, // `e`
93955
- lowercaseF: 102, // `f`
93956
- lowercaseG: 103, // `g`
93957
- lowercaseH: 104, // `h`
93958
- lowercaseI: 105, // `i`
93959
- lowercaseJ: 106, // `j`
93960
- lowercaseK: 107, // `k`
93961
- lowercaseL: 108, // `l`
93962
- lowercaseM: 109, // `m`
93963
- lowercaseN: 110, // `n`
93964
- lowercaseO: 111, // `o`
93965
- lowercaseP: 112, // `p`
93966
- lowercaseQ: 113, // `q`
93967
- lowercaseR: 114, // `r`
93968
- lowercaseS: 115, // `s`
93969
- lowercaseT: 116, // `t`
93970
- lowercaseU: 117, // `u`
93971
- lowercaseV: 118, // `v`
93972
- lowercaseW: 119, // `w`
93973
- lowercaseX: 120, // `x`
93974
- lowercaseY: 121, // `y`
93975
- lowercaseZ: 122, // `z`
93976
- leftCurlyBrace: 123, // `{`
93977
- verticalBar: 124, // `|`
93978
- rightCurlyBrace: 125, // `}`
93979
- tilde: 126, // `~`
93980
- del: 127,
93981
- // Unicode Specials block.
93982
- byteOrderMarker: 65_279,
93983
- // Unicode Specials block.
93984
- replacementCharacter: 65_533 // `�`
93985
- })
93986
-
93987
94061
  ;// ./lib/micromark/gemoji/syntax.ts
93988
94062
 
93989
94063
  // Matches the name pattern from the original regex: \+1 or [-\w]+
@@ -94071,6 +94145,9 @@ function syntax_gemoji() {
94071
94145
  };
94072
94146
  }
94073
94147
 
94148
+ ;// ./lib/micromark/heading-id/index.ts
94149
+
94150
+
94074
94151
  ;// ./node_modules/micromark-util-symbol/lib/types.js
94075
94152
  /**
94076
94153
  * This module is compiled away!
@@ -97520,6 +97597,8 @@ function mdxExpressionLenient() {
97520
97597
 
97521
97598
 
97522
97599
 
97600
+
97601
+
97523
97602
 
97524
97603
 
97525
97604
 
@@ -97559,6 +97638,8 @@ const REGISTRY = {
97559
97638
  mdxComponent: { syntax: mdxComponent, fromMarkdown: mdxComponentFromMarkdown },
97560
97639
  gemoji: { syntax: syntax_gemoji, fromMarkdown: gemojiFromMarkdown },
97561
97640
  legacyVariable: { syntax: legacyVariable, fromMarkdown: legacyVariableFromMarkdown },
97641
+ // Replaces the ATX heading construct in `flow`, so it never touches prose outside a heading.
97642
+ headingId: { syntax: headingId, fromMarkdown: headingIdFromMarkdown },
97562
97643
  looseHtmlEntity: { syntax: looseHtmlEntity, fromMarkdown: looseHtmlEntityFromMarkdown },
97563
97644
  htmlBlockComponent: { syntax: htmlBlockComponent, fromMarkdown: htmlBlockComponentFromMarkdown },
97564
97645
  // This is for in-document variable & function definitions
@@ -97589,18 +97670,13 @@ const EXPRESSIONS = ['jsxComment', 'mdxExpressionLenient', 'mdxjsEsm'];
97589
97670
  */
97590
97671
  const FEATURES = {
97591
97672
  /** `lib/mdxish.ts` — the document parser; the only site taking every group */
97592
- document: [...BLOCK_CLAIMS, ...INLINE, ...EXPRESSIONS, 'emptyTaskListItem'],
97673
+ document: [...BLOCK_CLAIMS, ...INLINE, ...EXPRESSIONS, 'emptyTaskListItem', 'headingId'],
97593
97674
  /**
97594
97675
  * `components/utils.ts` — re-parses a component body, which should tokenize
97595
97676
  * like the document around it: when the two drifted a `<Table>` in a
97596
97677
  * `<Callout>` lost every row (CX-3705).
97597
97678
  */
97598
- componentBody: [
97599
- ...BLOCK_CLAIMS,
97600
- ...INLINE,
97601
- 'mdxExpression',
97602
- 'emptyTaskListItem',
97603
- ],
97679
+ componentBody: [...BLOCK_CLAIMS, ...INLINE, 'mdxExpression', 'emptyTaskListItem', 'headingId'],
97604
97680
  /**
97605
97681
  * `lib/mdxishTags.ts` — collects component names, so nothing inline is needed.
97606
97682
  * Omits `htmlBlockComponent` deliberately since it's not a custom component,
@@ -122224,6 +122300,18 @@ const embed_embed = (node) => {
122224
122300
  };
122225
122301
  /* harmony default export */ const compile_embed = (embed_embed);
122226
122302
 
122303
+ ;// ./processor/compile/heading.ts
122304
+
122305
+
122306
+ const SETEXT_UNDERLINE_REGEX = /\n(?:=+|-+)$/;
122307
+ /** Writes an explicit heading id back as ` {#id}`. A setext heading, written for a line break, can't carry one. */
122308
+ const compile_heading_heading = ((node, parent, state, info) => {
122309
+ const markdown = handle.heading(node, parent, state, info);
122310
+ const id = explicitHeadingId(node);
122311
+ return id && !SETEXT_UNDERLINE_REGEX.test(markdown) ? `${markdown} {#${id}}` : markdown;
122312
+ });
122313
+ /* harmony default export */ const compile_heading = (compile_heading_heading);
122314
+
122227
122315
  ;// ./processor/compile/html-block.ts
122228
122316
 
122229
122317
  const htmlBlock = (node) => {
@@ -122369,6 +122457,7 @@ const mdxishText = (node, parent, state, info) => compile_text_text(node, parent
122369
122457
 
122370
122458
 
122371
122459
 
122460
+
122372
122461
  function compilers(mdxish = false) {
122373
122462
  const data = this.data();
122374
122463
  const toMarkdownExtensions = data.toMarkdownExtensions || (data.toMarkdownExtensions = []);
@@ -122389,6 +122478,7 @@ function compilers(mdxish = false) {
122389
122478
  text: compile_text_text,
122390
122479
  yaml: compile_compatibility,
122391
122480
  // needed only for mdxish
122481
+ ...(mdxish && { heading: compile_heading }),
122392
122482
  ...(mdxish && { list: compile_list }),
122393
122483
  ...(mdxish && { listItem: list_item }),
122394
122484
  ...(mdxish && { text: compile_text }),
@@ -125938,6 +126028,7 @@ function reactElementToHast(node) {
125938
126028
 
125939
126029
 
125940
126030
 
126031
+
125941
126032
  /**
125942
126033
  * Bind the components a given expression actually uses as tags. Scoped per expression on purpose:
125943
126034
  * binding the whole hash would shadow same-named globals (a `math` component would break
@@ -125988,14 +126079,6 @@ const wrapInParagraph = (child) => ({
125988
126079
  position: child.position,
125989
126080
  });
125990
126081
  const placeText = (text, needsBlock) => (needsBlock ? wrapInParagraph(text) : text);
125991
- /** Turn a non-renderable evaluation result into a text node. */
125992
- const createTextNode = (result, position) => {
125993
- if (result === null || result === undefined)
125994
- return { type: 'text', value: '', position };
125995
- if (typeof result === 'object')
125996
- return { type: 'text', value: JSON.stringify(result), position };
125997
- return { type: 'text', value: String(result), position };
125998
- };
125999
126082
  /**
126000
126083
  * AST transformer to evaluate MDX expressions.
126001
126084
  * Replaces mdxFlowExpression and mdxTextExpression nodes with their evaluated values.
@@ -126115,6 +126198,26 @@ const evaluateStyleBlockExpressions = () => (tree, file) => {
126115
126198
  };
126116
126199
  /* harmony default export */ const evaluate_style_block_expressions = (evaluateStyleBlockExpressions);
126117
126200
 
126201
+ ;// ./processor/transform/mdxish/heading-ids.ts
126202
+
126203
+ /**
126204
+ * Records every heading id set by `{#id}`, so the slug pass never gives one to another heading.
126205
+ * Warns when two headings share an id, since links can only reach the first.
126206
+ */
126207
+ const headingIdsTransformer = () => (tree, file) => {
126208
+ visit(tree, 'heading', (node) => {
126209
+ const id = node.data?.hProperties?.id;
126210
+ if (typeof id !== 'string')
126211
+ return;
126212
+ const ids = file.data.explicitHeadingIds ?? new Set();
126213
+ file.data.explicitHeadingIds = ids;
126214
+ if (ids.has(id))
126215
+ console.warn(`[mdxish] Heading id "${id}" is used more than once; links reach only the first.`);
126216
+ ids.add(id);
126217
+ });
126218
+ };
126219
+ /* harmony default export */ const heading_ids = (headingIdsTransformer);
126220
+
126118
126221
  ;// ./processor/transform/mdxish/heading-slugs.ts
126119
126222
 
126120
126223
 
@@ -126140,12 +126243,17 @@ function textContent(node) {
126140
126243
  * Id's are used to construct slug anchor links & Table of Contents during rendering
126141
126244
  * Use the text / nodes that make up the heading to generate the id
126142
126245
  */
126143
- const generateSlugForHeadings = () => (tree) => {
126246
+ const generateSlugForHeadings = () => (tree, file) => {
126144
126247
  const slugger = new BananaSlug();
126248
+ // The slugger only counts the ids it generates, so `{#id}` ones are skipped past by hand.
126249
+ const explicitIds = file.data.explicitHeadingIds ?? new Set();
126145
126250
  visit(tree, 'element', (node) => {
126146
126251
  if (isHeading(node) && !node.properties.id) {
126147
126252
  const text = node.children.map(textContent).join('');
126148
- node.properties.id = slugger.slug(text);
126253
+ let id = slugger.slug(text);
126254
+ while (explicitIds.has(id))
126255
+ id = slugger.slug(text);
126256
+ node.properties.id = id;
126149
126257
  }
126150
126258
  });
126151
126259
  return tree;
@@ -128660,6 +128768,7 @@ function loadComponents() {
128660
128768
 
128661
128769
 
128662
128770
 
128771
+
128663
128772
 
128664
128773
 
128665
128774
  const defaultTransformers = [
@@ -128779,24 +128888,15 @@ function mdxishMdastToMd(mdast) {
128779
128888
  .use(remarkStringify, stringifyOptions);
128780
128889
  return processor.stringify(processor.runSync(mdast));
128781
128890
  }
128782
- /**
128783
- * Processes markdown content with MDX syntax support and returns a HAST.
128784
- * Detects and renders custom component tags from the components hash.
128785
- *
128786
- * @see .claude/context/MDXish/Processor Overview.md
128787
- */
128788
- function mdxish(mdContent, opts = {}) {
128891
+ /** The steps `mdxish()` runs after parsing; run it on the parse's VFile, since steps read `file.data`. */
128892
+ function mdxishRenderProcessor(opts = {}) {
128789
128893
  const { components: userComponents = {}, hardBreaks: enableHardBreaks = true, safeMode = false, sanitize = false, variables, } = opts;
128790
128894
  const components = {
128791
128895
  ...loadComponents(),
128792
128896
  ...userComponents,
128793
128897
  };
128794
- // Remove JSX comments before processing (protect code blocks first)
128795
- const { protectedCode, protectedContent } = protectCodeBlocks(mdContent);
128796
- const withoutComments = removeJSXComments(protectedContent);
128797
- const contentWithoutComments = restoreCodeBlocks(withoutComments, protectedCode);
128798
- const { processor, parserReadyContent } = mdxishAstProcessor(contentWithoutComments, opts);
128799
- processor
128898
+ return unified()
128899
+ .use(heading_ids)
128800
128900
  .use(safeMode ? undefined : evaluate_exports, { sanitize }) // Evaluate `export const/function` and stash scope on file.data.mdxishScope
128801
128901
  .use(enableHardBreaks ? hard_breaks : undefined) // Must precede evaluateExpressions to avoid splitting the \n in an evaluated template literal into a <br> node
128802
128902
  .use(safeMode ? undefined : evaluate_expressions, { components, variables }) // Evaluate self-contained MDX expressions (e.g. `{1+1}`)
@@ -128814,11 +128914,25 @@ function mdxish(mdContent, opts = {}) {
128814
128914
  .use(heading_slugs)
128815
128915
  .use(rehypeMdxishComponents, {
128816
128916
  components,
128917
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define -- component bodies render through mdxish() again
128817
128918
  processMarkdown: (markdown) => mdxish(markdown, opts),
128818
128919
  });
128920
+ }
128921
+ /**
128922
+ * Processes markdown content with MDX syntax support and returns a HAST.
128923
+ * Detects and renders custom component tags from the components hash.
128924
+ *
128925
+ * @see .claude/context/MDXish/Processor Overview.md
128926
+ */
128927
+ function mdxish(mdContent, opts = {}) {
128928
+ // Remove JSX comments before processing (protect code blocks first)
128929
+ const { protectedCode, protectedContent } = protectCodeBlocks(mdContent);
128930
+ const withoutComments = removeJSXComments(protectedContent);
128931
+ const contentWithoutComments = restoreCodeBlocks(withoutComments, protectedCode);
128932
+ const { processor, parserReadyContent } = mdxishAstProcessor(contentWithoutComments, opts);
128819
128933
  const vfile = new VFile({ value: parserReadyContent });
128820
- const mdast = processor.parse(parserReadyContent);
128821
- const hast = processor.runSync(mdast, vfile);
128934
+ const mdast = processor.runSync(processor.parse(parserReadyContent), vfile);
128935
+ const hast = mdxishRenderProcessor(opts).runSync(mdast, vfile);
128822
128936
  if (!hast) {
128823
128937
  throw new Error('Markdown pipeline did not produce a HAST tree.');
128824
128938
  }
@@ -128843,6 +128957,134 @@ const mix = (text, opts = {}) => {
128843
128957
  };
128844
128958
  /* harmony default export */ const lib_mix = (mix);
128845
128959
 
128960
+ ;// ./lib/mdxishHeadingIds.ts
128961
+
128962
+
128963
+
128964
+
128965
+
128966
+
128967
+
128968
+
128969
+ const HEADING_INDEX = 'dataMdxishHeadingIndex';
128970
+ const HEADING_TAG_REGEX = /^h[1-6]$/;
128971
+ const JSX_COMMENT_ONLY_REGEX = new RegExp(`^${JSX_COMMENT_REGEX.source}$`);
128972
+ const isExpression = (node) => node.type === 'mdxFlowExpression' || node.type === 'mdxTextExpression';
128973
+ function collectHeadings(tree) {
128974
+ const headings = [];
128975
+ visit(tree, 'heading', (node) => {
128976
+ headings.push(node);
128977
+ });
128978
+ return headings;
128979
+ }
128980
+ function literalValue(source) {
128981
+ try {
128982
+ return { value: evaluateLiteralExpression(source) };
128983
+ }
128984
+ catch {
128985
+ return null;
128986
+ }
128987
+ }
128988
+ function trimHeadingText(heading) {
128989
+ const first = heading.children[0];
128990
+ if (first?.type === 'text')
128991
+ first.value = first.value.trimStart();
128992
+ const last = heading.children.at(-1);
128993
+ if (last?.type === 'text')
128994
+ last.value = last.value.trimEnd();
128995
+ }
128996
+ const isNamePath = (node) => node.type === 'Identifier' ||
128997
+ (node.type === 'MemberExpression' && !node.computed && !!node.object && isNamePath(node.object));
128998
+ // A name like `{price}` or `{plan.name}` can only read a value, never build an element. Code the parser
128999
+ // rejects can't run at all, so the hub shows it as text.
129000
+ function canBuildElements(source) {
129001
+ try {
129002
+ return !isNamePath(jsxAcornParser.parseExpressionAt(source, 0, { ecmaVersion: 'latest' }));
129003
+ }
129004
+ catch {
129005
+ return false;
129006
+ }
129007
+ }
129008
+ const isHeadingElement = (node) => isMDXElement(node) && HEADING_TAG_REGEX.test(node.name ?? '');
129009
+ // An expression the hub has to run changes a heading from inside one (Markdown or an HTML heading tag), by
129010
+ // building an element (a call or JSX), or as a block: alone in its paragraph, its result is lifted out as one.
129011
+ function canChangeHeadings(node, ancestors, heading) {
129012
+ if (heading || ancestors.some(isHeadingElement) || node.type === 'mdxFlowExpression' || canBuildElements(node.value))
129013
+ return true;
129014
+ const parent = ancestors[ancestors.length - 1];
129015
+ return parent.children.every(child => child === node || (child.type === 'text' && !child.value.trim()));
129016
+ }
129017
+ // Safe mode leaves `<h2 id={...}>` without the id the hub evaluates, which shifts the numbering.
129018
+ function hasEvaluatedHeadingAttribute(tree) {
129019
+ let found = false;
129020
+ visit(tree, isHeadingElement, (node) => {
129021
+ found = node.attributes.some(attribute => attribute.type === 'mdxJsxExpressionAttribute' || typeof attribute.value === 'object');
129022
+ return found ? (/* inlined export .EXIT */false) : undefined;
129023
+ });
129024
+ return found;
129025
+ }
129026
+ // Matches what the hub renders without running code: comments are stripped and plain literals become their
129027
+ // text. `false` when an expression that needs running could change the headings.
129028
+ function settleExpressions(tree) {
129029
+ const edits = [];
129030
+ let settled = true;
129031
+ visitParents(tree, isExpression, (node, ancestors) => {
129032
+ const heading = ancestors.find((ancestor) => ancestor.type === 'heading');
129033
+ const parent = ancestors[ancestors.length - 1];
129034
+ if (JSX_COMMENT_ONLY_REGEX.test(`{${node.value}}`)) {
129035
+ edits.push({ heading, node, parent, replacement: null });
129036
+ return;
129037
+ }
129038
+ const literal = literalValue(node.value);
129039
+ if (literal) {
129040
+ edits.push({ heading, node, parent, replacement: createTextNode(literal.value, node.position) });
129041
+ return;
129042
+ }
129043
+ if (canChangeHeadings(node, ancestors, heading))
129044
+ settled = false;
129045
+ });
129046
+ const apply = ({ node, parent, replacement }) => {
129047
+ parent.children.splice(parent.children.indexOf(node), 1, ...(replacement ? [replacement] : []));
129048
+ };
129049
+ // Comments go first: the hub strips them from the source, so the parser trims only the source
129050
+ // whitespace around them, never the spaces a literal adds.
129051
+ edits
129052
+ .filter(edit => !edit.replacement)
129053
+ .forEach(edit => {
129054
+ apply(edit);
129055
+ if (edit.heading)
129056
+ trimHeadingText(edit.heading);
129057
+ });
129058
+ edits.filter(edit => edit.replacement).forEach(apply);
129059
+ return settled;
129060
+ }
129061
+ /** Each heading's rendered anchor id, worked out without running code; `null` when code could change them. */
129062
+ function mdxishHeadingIds(tree, opts = {}) {
129063
+ const headings = collectHeadings(tree);
129064
+ if (headings.length === 0)
129065
+ return new Map();
129066
+ const copy = structuredClone(tree);
129067
+ let hasExport = false;
129068
+ visit(copy, 'mdxjsEsm', () => {
129069
+ hasExport = true;
129070
+ });
129071
+ // An `export` can define components that render headings.
129072
+ if (hasExport || hasEvaluatedHeadingAttribute(copy) || !settleExpressions(copy))
129073
+ return null;
129074
+ collectHeadings(copy).forEach((heading, index) => {
129075
+ heading.data = { ...heading.data, hProperties: { ...heading.data?.hProperties, [HEADING_INDEX]: index } };
129076
+ });
129077
+ const hast = mdxishRenderProcessor({ ...opts, safeMode: true }).runSync(copy, new VFile());
129078
+ const ids = new Map();
129079
+ visit(hast, 'element', (node) => {
129080
+ const index = node.properties[HEADING_INDEX];
129081
+ if (index === undefined || typeof node.properties.id !== 'string')
129082
+ return;
129083
+ ids.set(headings[Number(index)], node.properties.id);
129084
+ });
129085
+ return ids;
129086
+ }
129087
+
128846
129088
  ;// ./lib/extractToc.ts
128847
129089
 
128848
129090
  /* harmony default export */ const lib_extractToc = (extractToc);
@@ -129462,6 +129704,7 @@ async function stripComments(doc, { mdx, mdxish } = {}) {
129462
129704
 
129463
129705
 
129464
129706
 
129707
+
129465
129708
 
129466
129709
  ;// ./index.tsx
129467
129710
 
@@ -129817,7 +130060,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"*":["about","acceptCharset","accessK
129817
130060
  /******/ // startup
129818
130061
  /******/ // Load entry module and return exports
129819
130062
  /******/ // This entry module used 'module' so it can't be inlined
129820
- /******/ let __webpack_exports__ = __webpack_require__(3975);
130063
+ /******/ let __webpack_exports__ = __webpack_require__(5893);
129821
130064
  /******/ module.exports = __webpack_exports__;
129822
130065
  /******/
129823
130066
  /******/ })()