@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.
@@ -19111,7 +19111,7 @@ module.exports = function () {
19111
19111
 
19112
19112
  /***/ },
19113
19113
 
19114
- /***/ 7905
19114
+ /***/ 5919
19115
19115
  (module, __webpack_exports__, __webpack_require__) {
19116
19116
 
19117
19117
  "use strict";
@@ -68716,6 +68716,209 @@ const mdast = (text, opts = {}) => {
68716
68716
  };
68717
68717
  /* harmony default export */ const lib_mdast = (mdast);
68718
68718
 
68719
+ ;// ./node_modules/micromark-util-symbol/lib/codes.js
68720
+ /**
68721
+ * Character codes.
68722
+ *
68723
+ * This module is compiled away!
68724
+ *
68725
+ * micromark works based on character codes.
68726
+ * This module contains constants for the ASCII block and the replacement
68727
+ * character.
68728
+ * A couple of them are handled in a special way, such as the line endings
68729
+ * (CR, LF, and CR+LF, commonly known as end-of-line: EOLs), the tab (horizontal
68730
+ * tab) and its expansion based on what column it’s at (virtual space),
68731
+ * and the end-of-file (eof) character.
68732
+ * As values are preprocessed before handling them, the actual characters LF,
68733
+ * CR, HT, and NUL (which is present as the replacement character), are
68734
+ * guaranteed to not exist.
68735
+ *
68736
+ * Unicode basic latin block.
68737
+ */
68738
+ const codes = /** @type {const} */ ({
68739
+ carriageReturn: -5,
68740
+ lineFeed: -4,
68741
+ carriageReturnLineFeed: -3,
68742
+ horizontalTab: -2,
68743
+ virtualSpace: -1,
68744
+ eof: null,
68745
+ nul: 0,
68746
+ soh: 1,
68747
+ stx: 2,
68748
+ etx: 3,
68749
+ eot: 4,
68750
+ enq: 5,
68751
+ ack: 6,
68752
+ bel: 7,
68753
+ bs: 8,
68754
+ ht: 9, // `\t`
68755
+ lf: 10, // `\n`
68756
+ vt: 11, // `\v`
68757
+ ff: 12, // `\f`
68758
+ cr: 13, // `\r`
68759
+ so: 14,
68760
+ si: 15,
68761
+ dle: 16,
68762
+ dc1: 17,
68763
+ dc2: 18,
68764
+ dc3: 19,
68765
+ dc4: 20,
68766
+ nak: 21,
68767
+ syn: 22,
68768
+ etb: 23,
68769
+ can: 24,
68770
+ em: 25,
68771
+ sub: 26,
68772
+ esc: 27,
68773
+ fs: 28,
68774
+ gs: 29,
68775
+ rs: 30,
68776
+ us: 31,
68777
+ space: 32,
68778
+ exclamationMark: 33, // `!`
68779
+ quotationMark: 34, // `"`
68780
+ numberSign: 35, // `#`
68781
+ dollarSign: 36, // `$`
68782
+ percentSign: 37, // `%`
68783
+ ampersand: 38, // `&`
68784
+ apostrophe: 39, // `'`
68785
+ leftParenthesis: 40, // `(`
68786
+ rightParenthesis: 41, // `)`
68787
+ asterisk: 42, // `*`
68788
+ plusSign: 43, // `+`
68789
+ comma: 44, // `,`
68790
+ dash: 45, // `-`
68791
+ dot: 46, // `.`
68792
+ slash: 47, // `/`
68793
+ digit0: 48, // `0`
68794
+ digit1: 49, // `1`
68795
+ digit2: 50, // `2`
68796
+ digit3: 51, // `3`
68797
+ digit4: 52, // `4`
68798
+ digit5: 53, // `5`
68799
+ digit6: 54, // `6`
68800
+ digit7: 55, // `7`
68801
+ digit8: 56, // `8`
68802
+ digit9: 57, // `9`
68803
+ colon: 58, // `:`
68804
+ semicolon: 59, // `;`
68805
+ lessThan: 60, // `<`
68806
+ equalsTo: 61, // `=`
68807
+ greaterThan: 62, // `>`
68808
+ questionMark: 63, // `?`
68809
+ atSign: 64, // `@`
68810
+ uppercaseA: 65, // `A`
68811
+ uppercaseB: 66, // `B`
68812
+ uppercaseC: 67, // `C`
68813
+ uppercaseD: 68, // `D`
68814
+ uppercaseE: 69, // `E`
68815
+ uppercaseF: 70, // `F`
68816
+ uppercaseG: 71, // `G`
68817
+ uppercaseH: 72, // `H`
68818
+ uppercaseI: 73, // `I`
68819
+ uppercaseJ: 74, // `J`
68820
+ uppercaseK: 75, // `K`
68821
+ uppercaseL: 76, // `L`
68822
+ uppercaseM: 77, // `M`
68823
+ uppercaseN: 78, // `N`
68824
+ uppercaseO: 79, // `O`
68825
+ uppercaseP: 80, // `P`
68826
+ uppercaseQ: 81, // `Q`
68827
+ uppercaseR: 82, // `R`
68828
+ uppercaseS: 83, // `S`
68829
+ uppercaseT: 84, // `T`
68830
+ uppercaseU: 85, // `U`
68831
+ uppercaseV: 86, // `V`
68832
+ uppercaseW: 87, // `W`
68833
+ uppercaseX: 88, // `X`
68834
+ uppercaseY: 89, // `Y`
68835
+ uppercaseZ: 90, // `Z`
68836
+ leftSquareBracket: 91, // `[`
68837
+ backslash: 92, // `\`
68838
+ rightSquareBracket: 93, // `]`
68839
+ caret: 94, // `^`
68840
+ underscore: 95, // `_`
68841
+ graveAccent: 96, // `` ` ``
68842
+ lowercaseA: 97, // `a`
68843
+ lowercaseB: 98, // `b`
68844
+ lowercaseC: 99, // `c`
68845
+ lowercaseD: 100, // `d`
68846
+ lowercaseE: 101, // `e`
68847
+ lowercaseF: 102, // `f`
68848
+ lowercaseG: 103, // `g`
68849
+ lowercaseH: 104, // `h`
68850
+ lowercaseI: 105, // `i`
68851
+ lowercaseJ: 106, // `j`
68852
+ lowercaseK: 107, // `k`
68853
+ lowercaseL: 108, // `l`
68854
+ lowercaseM: 109, // `m`
68855
+ lowercaseN: 110, // `n`
68856
+ lowercaseO: 111, // `o`
68857
+ lowercaseP: 112, // `p`
68858
+ lowercaseQ: 113, // `q`
68859
+ lowercaseR: 114, // `r`
68860
+ lowercaseS: 115, // `s`
68861
+ lowercaseT: 116, // `t`
68862
+ lowercaseU: 117, // `u`
68863
+ lowercaseV: 118, // `v`
68864
+ lowercaseW: 119, // `w`
68865
+ lowercaseX: 120, // `x`
68866
+ lowercaseY: 121, // `y`
68867
+ lowercaseZ: 122, // `z`
68868
+ leftCurlyBrace: 123, // `{`
68869
+ verticalBar: 124, // `|`
68870
+ rightCurlyBrace: 125, // `}`
68871
+ tilde: 126, // `~`
68872
+ del: 127,
68873
+ // Unicode Specials block.
68874
+ byteOrderMarker: 65_279,
68875
+ // Unicode Specials block.
68876
+ replacementCharacter: 65_533 // `�`
68877
+ })
68878
+
68879
+ ;// ./lib/micromark/heading-id/syntax.ts
68880
+
68881
+
68882
+ /** One character a `{#id}` heading id may use: the ones github-slugger keeps, plus `.` and `:`. */
68883
+ const HEADING_ID_CHAR = '[\\p{L}\\p{M}\\p{N}_.:-]';
68884
+ const ID_CLOSE_REGEX = new RegExp(`^${HEADING_ID_CHAR}+\\}$`, 'u');
68885
+ const typeAt = (events, index) => events[index]?.[1].type;
68886
+ function isIdToken(events, index, context, type, value) {
68887
+ return typeAt(events, index) === type && value.test(context.sliceSerialize(events[index][1]));
68888
+ }
68889
+ /** The exit index of the heading's last content token, past any trailing space and closing `##`. */
68890
+ function contentEnd(events) {
68891
+ let end = events.length - 2;
68892
+ if (typeAt(events, end) === 'whitespace')
68893
+ end -= 2;
68894
+ if (typeAt(events, end) === 'atxHeadingSequence' && typeAt(events, end - 2) === 'whitespace')
68895
+ end -= 4;
68896
+ return end;
68897
+ }
68898
+ const resolveHeadingId = (events, context) => {
68899
+ // Each token is an enter and an exit event; these indexes point at the exits.
68900
+ const close = contentEnd(events);
68901
+ const hash = close - 2;
68902
+ const open = close - 4;
68903
+ const space = close - 6;
68904
+ const endsWithId = isIdToken(events, close, context, 'atxHeadingText', ID_CLOSE_REGEX) &&
68905
+ isIdToken(events, hash, context, 'atxHeadingSequence', /^#$/) &&
68906
+ isIdToken(events, open, context, 'atxHeadingText', /^\{$/) &&
68907
+ typeAt(events, space) === 'whitespace';
68908
+ if (!endsWithId)
68909
+ return headingAtx.resolve?.(events, context) ?? events;
68910
+ const id = { type: 'headingId', start: events[open][1].start, end: events[close][1].end };
68911
+ events.splice(space - 1, close - space + 2);
68912
+ const resolved = headingAtx.resolve?.(events, context) ?? events;
68913
+ resolved.splice(resolved.length - 1, 0, ['enter', id, context], ['exit', id, context]);
68914
+ return resolved;
68915
+ };
68916
+ const headingIdConstruct = { ...headingAtx, resolve: resolveHeadingId };
68917
+ /** The ATX heading construct, with a line-final ` {#id}` split off as a `headingId` token. */
68918
+ function headingId() {
68919
+ return { flow: { [codes.numberSign]: headingIdConstruct } };
68920
+ }
68921
+
68719
68922
  ;// ./lib/utils/jsx-acorn-parser.ts
68720
68923
 
68721
68924
 
@@ -68827,6 +69030,7 @@ const evaluateLiteralExpression = (source) => {
68827
69030
 
68828
69031
 
68829
69032
 
69033
+
68830
69034
  /**
68831
69035
  * Evaluate a JavaScript expression source and return its value.
68832
69036
  *
@@ -68943,6 +69147,24 @@ const getHPropKeys = (node) => {
68943
69147
  const hProps = getHProps(node);
68944
69148
  return Object.keys(hProps) || [];
68945
69149
  };
69150
+ /** Turn a non-renderable evaluation result into a text node. */
69151
+ const createTextNode = (result, position) => {
69152
+ if (result === null || result === undefined)
69153
+ return { type: 'text', value: '', position };
69154
+ if (typeof result === 'object')
69155
+ return { type: 'text', value: JSON.stringify(result), position };
69156
+ return { type: 'text', value: String(result), position };
69157
+ };
69158
+ const HEADING_ID_REGEX = new RegExp(`^${HEADING_ID_CHAR}+$`, 'u');
69159
+ /**
69160
+ * The id a heading's trailing `{#id}` set, when it is one the `{#id}` syntax can spell.
69161
+ *
69162
+ * Ids may use letters, numbers, `-`, `_`, `.` and `:`; anything else, like `x y`, is dropped.
69163
+ */
69164
+ const explicitHeadingId = (node) => {
69165
+ const id = node.data?.hProperties?.id;
69166
+ return typeof id === 'string' && HEADING_ID_REGEX.test(id) ? id : undefined;
69167
+ };
68946
69168
  /**
68947
69169
  * Gets the attributes of an MDX element and returns them as an object of hProperties.
68948
69170
  *
@@ -93392,6 +93614,17 @@ function gemojiFromMarkdown() {
93392
93614
  };
93393
93615
  }
93394
93616
 
93617
+ ;// ./lib/mdast-util/heading-id/index.ts
93618
+ function exitHeadingId(token) {
93619
+ const heading = this.stack[this.stack.length - 1];
93620
+ const id = this.sliceSerialize(token).slice('{#'.length, -'}'.length);
93621
+ heading.data = { ...heading.data, hProperties: { ...heading.data?.hProperties, id } };
93622
+ }
93623
+ /** Sets a heading's id from its `headingId` token. */
93624
+ function headingIdFromMarkdown() {
93625
+ return { exit: { headingId: exitHeadingId } };
93626
+ }
93627
+
93395
93628
  ;// ./lib/mdast-util/html-block-component/index.ts
93396
93629
  const contextMap = new WeakMap();
93397
93630
  function findHtmlBlockComponentToken() {
@@ -93770,166 +94003,6 @@ function mdxComponentFromMarkdown() {
93770
94003
  };
93771
94004
  }
93772
94005
 
93773
- ;// ./node_modules/micromark-util-symbol/lib/codes.js
93774
- /**
93775
- * Character codes.
93776
- *
93777
- * This module is compiled away!
93778
- *
93779
- * micromark works based on character codes.
93780
- * This module contains constants for the ASCII block and the replacement
93781
- * character.
93782
- * A couple of them are handled in a special way, such as the line endings
93783
- * (CR, LF, and CR+LF, commonly known as end-of-line: EOLs), the tab (horizontal
93784
- * tab) and its expansion based on what column it’s at (virtual space),
93785
- * and the end-of-file (eof) character.
93786
- * As values are preprocessed before handling them, the actual characters LF,
93787
- * CR, HT, and NUL (which is present as the replacement character), are
93788
- * guaranteed to not exist.
93789
- *
93790
- * Unicode basic latin block.
93791
- */
93792
- const codes = /** @type {const} */ ({
93793
- carriageReturn: -5,
93794
- lineFeed: -4,
93795
- carriageReturnLineFeed: -3,
93796
- horizontalTab: -2,
93797
- virtualSpace: -1,
93798
- eof: null,
93799
- nul: 0,
93800
- soh: 1,
93801
- stx: 2,
93802
- etx: 3,
93803
- eot: 4,
93804
- enq: 5,
93805
- ack: 6,
93806
- bel: 7,
93807
- bs: 8,
93808
- ht: 9, // `\t`
93809
- lf: 10, // `\n`
93810
- vt: 11, // `\v`
93811
- ff: 12, // `\f`
93812
- cr: 13, // `\r`
93813
- so: 14,
93814
- si: 15,
93815
- dle: 16,
93816
- dc1: 17,
93817
- dc2: 18,
93818
- dc3: 19,
93819
- dc4: 20,
93820
- nak: 21,
93821
- syn: 22,
93822
- etb: 23,
93823
- can: 24,
93824
- em: 25,
93825
- sub: 26,
93826
- esc: 27,
93827
- fs: 28,
93828
- gs: 29,
93829
- rs: 30,
93830
- us: 31,
93831
- space: 32,
93832
- exclamationMark: 33, // `!`
93833
- quotationMark: 34, // `"`
93834
- numberSign: 35, // `#`
93835
- dollarSign: 36, // `$`
93836
- percentSign: 37, // `%`
93837
- ampersand: 38, // `&`
93838
- apostrophe: 39, // `'`
93839
- leftParenthesis: 40, // `(`
93840
- rightParenthesis: 41, // `)`
93841
- asterisk: 42, // `*`
93842
- plusSign: 43, // `+`
93843
- comma: 44, // `,`
93844
- dash: 45, // `-`
93845
- dot: 46, // `.`
93846
- slash: 47, // `/`
93847
- digit0: 48, // `0`
93848
- digit1: 49, // `1`
93849
- digit2: 50, // `2`
93850
- digit3: 51, // `3`
93851
- digit4: 52, // `4`
93852
- digit5: 53, // `5`
93853
- digit6: 54, // `6`
93854
- digit7: 55, // `7`
93855
- digit8: 56, // `8`
93856
- digit9: 57, // `9`
93857
- colon: 58, // `:`
93858
- semicolon: 59, // `;`
93859
- lessThan: 60, // `<`
93860
- equalsTo: 61, // `=`
93861
- greaterThan: 62, // `>`
93862
- questionMark: 63, // `?`
93863
- atSign: 64, // `@`
93864
- uppercaseA: 65, // `A`
93865
- uppercaseB: 66, // `B`
93866
- uppercaseC: 67, // `C`
93867
- uppercaseD: 68, // `D`
93868
- uppercaseE: 69, // `E`
93869
- uppercaseF: 70, // `F`
93870
- uppercaseG: 71, // `G`
93871
- uppercaseH: 72, // `H`
93872
- uppercaseI: 73, // `I`
93873
- uppercaseJ: 74, // `J`
93874
- uppercaseK: 75, // `K`
93875
- uppercaseL: 76, // `L`
93876
- uppercaseM: 77, // `M`
93877
- uppercaseN: 78, // `N`
93878
- uppercaseO: 79, // `O`
93879
- uppercaseP: 80, // `P`
93880
- uppercaseQ: 81, // `Q`
93881
- uppercaseR: 82, // `R`
93882
- uppercaseS: 83, // `S`
93883
- uppercaseT: 84, // `T`
93884
- uppercaseU: 85, // `U`
93885
- uppercaseV: 86, // `V`
93886
- uppercaseW: 87, // `W`
93887
- uppercaseX: 88, // `X`
93888
- uppercaseY: 89, // `Y`
93889
- uppercaseZ: 90, // `Z`
93890
- leftSquareBracket: 91, // `[`
93891
- backslash: 92, // `\`
93892
- rightSquareBracket: 93, // `]`
93893
- caret: 94, // `^`
93894
- underscore: 95, // `_`
93895
- graveAccent: 96, // `` ` ``
93896
- lowercaseA: 97, // `a`
93897
- lowercaseB: 98, // `b`
93898
- lowercaseC: 99, // `c`
93899
- lowercaseD: 100, // `d`
93900
- lowercaseE: 101, // `e`
93901
- lowercaseF: 102, // `f`
93902
- lowercaseG: 103, // `g`
93903
- lowercaseH: 104, // `h`
93904
- lowercaseI: 105, // `i`
93905
- lowercaseJ: 106, // `j`
93906
- lowercaseK: 107, // `k`
93907
- lowercaseL: 108, // `l`
93908
- lowercaseM: 109, // `m`
93909
- lowercaseN: 110, // `n`
93910
- lowercaseO: 111, // `o`
93911
- lowercaseP: 112, // `p`
93912
- lowercaseQ: 113, // `q`
93913
- lowercaseR: 114, // `r`
93914
- lowercaseS: 115, // `s`
93915
- lowercaseT: 116, // `t`
93916
- lowercaseU: 117, // `u`
93917
- lowercaseV: 118, // `v`
93918
- lowercaseW: 119, // `w`
93919
- lowercaseX: 120, // `x`
93920
- lowercaseY: 121, // `y`
93921
- lowercaseZ: 122, // `z`
93922
- leftCurlyBrace: 123, // `{`
93923
- verticalBar: 124, // `|`
93924
- rightCurlyBrace: 125, // `}`
93925
- tilde: 126, // `~`
93926
- del: 127,
93927
- // Unicode Specials block.
93928
- byteOrderMarker: 65_279,
93929
- // Unicode Specials block.
93930
- replacementCharacter: 65_533 // `�`
93931
- })
93932
-
93933
94006
  ;// ./lib/micromark/gemoji/syntax.ts
93934
94007
 
93935
94008
  // Matches the name pattern from the original regex: \+1 or [-\w]+
@@ -94017,6 +94090,9 @@ function syntax_gemoji() {
94017
94090
  };
94018
94091
  }
94019
94092
 
94093
+ ;// ./lib/micromark/heading-id/index.ts
94094
+
94095
+
94020
94096
  ;// ./node_modules/micromark-util-symbol/lib/types.js
94021
94097
  /**
94022
94098
  * This module is compiled away!
@@ -97466,6 +97542,8 @@ function mdxExpressionLenient() {
97466
97542
 
97467
97543
 
97468
97544
 
97545
+
97546
+
97469
97547
 
97470
97548
 
97471
97549
 
@@ -97505,6 +97583,8 @@ const REGISTRY = {
97505
97583
  mdxComponent: { syntax: mdxComponent, fromMarkdown: mdxComponentFromMarkdown },
97506
97584
  gemoji: { syntax: syntax_gemoji, fromMarkdown: gemojiFromMarkdown },
97507
97585
  legacyVariable: { syntax: legacyVariable, fromMarkdown: legacyVariableFromMarkdown },
97586
+ // Replaces the ATX heading construct in `flow`, so it never touches prose outside a heading.
97587
+ headingId: { syntax: headingId, fromMarkdown: headingIdFromMarkdown },
97508
97588
  looseHtmlEntity: { syntax: looseHtmlEntity, fromMarkdown: looseHtmlEntityFromMarkdown },
97509
97589
  htmlBlockComponent: { syntax: htmlBlockComponent, fromMarkdown: htmlBlockComponentFromMarkdown },
97510
97590
  // This is for in-document variable & function definitions
@@ -97535,18 +97615,13 @@ const EXPRESSIONS = ['jsxComment', 'mdxExpressionLenient', 'mdxjsEsm'];
97535
97615
  */
97536
97616
  const FEATURES = {
97537
97617
  /** `lib/mdxish.ts` — the document parser; the only site taking every group */
97538
- document: [...BLOCK_CLAIMS, ...INLINE, ...EXPRESSIONS, 'emptyTaskListItem'],
97618
+ document: [...BLOCK_CLAIMS, ...INLINE, ...EXPRESSIONS, 'emptyTaskListItem', 'headingId'],
97539
97619
  /**
97540
97620
  * `components/utils.ts` — re-parses a component body, which should tokenize
97541
97621
  * like the document around it: when the two drifted a `<Table>` in a
97542
97622
  * `<Callout>` lost every row (CX-3705).
97543
97623
  */
97544
- componentBody: [
97545
- ...BLOCK_CLAIMS,
97546
- ...INLINE,
97547
- 'mdxExpression',
97548
- 'emptyTaskListItem',
97549
- ],
97624
+ componentBody: [...BLOCK_CLAIMS, ...INLINE, 'mdxExpression', 'emptyTaskListItem', 'headingId'],
97550
97625
  /**
97551
97626
  * `lib/mdxishTags.ts` — collects component names, so nothing inline is needed.
97552
97627
  * Omits `htmlBlockComponent` deliberately since it's not a custom component,
@@ -121998,6 +122073,18 @@ const embed_embed = (node) => {
121998
122073
  };
121999
122074
  /* harmony default export */ const compile_embed = (embed_embed);
122000
122075
 
122076
+ ;// ./processor/compile/heading.ts
122077
+
122078
+
122079
+ const SETEXT_UNDERLINE_REGEX = /\n(?:=+|-+)$/;
122080
+ /** Writes an explicit heading id back as ` {#id}`. A setext heading, written for a line break, can't carry one. */
122081
+ const compile_heading_heading = ((node, parent, state, info) => {
122082
+ const markdown = handle.heading(node, parent, state, info);
122083
+ const id = explicitHeadingId(node);
122084
+ return id && !SETEXT_UNDERLINE_REGEX.test(markdown) ? `${markdown} {#${id}}` : markdown;
122085
+ });
122086
+ /* harmony default export */ const compile_heading = (compile_heading_heading);
122087
+
122001
122088
  ;// ./processor/compile/html-block.ts
122002
122089
 
122003
122090
  const htmlBlock = (node) => {
@@ -122143,6 +122230,7 @@ const mdxishText = (node, parent, state, info) => compile_text_text(node, parent
122143
122230
 
122144
122231
 
122145
122232
 
122233
+
122146
122234
  function compilers(mdxish = false) {
122147
122235
  const data = this.data();
122148
122236
  const toMarkdownExtensions = data.toMarkdownExtensions || (data.toMarkdownExtensions = []);
@@ -122163,6 +122251,7 @@ function compilers(mdxish = false) {
122163
122251
  text: compile_text_text,
122164
122252
  yaml: compile_compatibility,
122165
122253
  // needed only for mdxish
122254
+ ...(mdxish && { heading: compile_heading }),
122166
122255
  ...(mdxish && { list: compile_list }),
122167
122256
  ...(mdxish && { listItem: list_item }),
122168
122257
  ...(mdxish && { text: compile_text }),
@@ -124281,6 +124370,7 @@ function reactElementToHast(node) {
124281
124370
 
124282
124371
 
124283
124372
 
124373
+
124284
124374
  /**
124285
124375
  * Bind the components a given expression actually uses as tags. Scoped per expression on purpose:
124286
124376
  * binding the whole hash would shadow same-named globals (a `math` component would break
@@ -124331,14 +124421,6 @@ const wrapInParagraph = (child) => ({
124331
124421
  position: child.position,
124332
124422
  });
124333
124423
  const placeText = (text, needsBlock) => (needsBlock ? wrapInParagraph(text) : text);
124334
- /** Turn a non-renderable evaluation result into a text node. */
124335
- const createTextNode = (result, position) => {
124336
- if (result === null || result === undefined)
124337
- return { type: 'text', value: '', position };
124338
- if (typeof result === 'object')
124339
- return { type: 'text', value: JSON.stringify(result), position };
124340
- return { type: 'text', value: String(result), position };
124341
- };
124342
124424
  /**
124343
124425
  * AST transformer to evaluate MDX expressions.
124344
124426
  * Replaces mdxFlowExpression and mdxTextExpression nodes with their evaluated values.
@@ -124458,6 +124540,26 @@ const evaluateStyleBlockExpressions = () => (tree, file) => {
124458
124540
  };
124459
124541
  /* harmony default export */ const evaluate_style_block_expressions = (evaluateStyleBlockExpressions);
124460
124542
 
124543
+ ;// ./processor/transform/mdxish/heading-ids.ts
124544
+
124545
+ /**
124546
+ * Records every heading id set by `{#id}`, so the slug pass never gives one to another heading.
124547
+ * Warns when two headings share an id, since links can only reach the first.
124548
+ */
124549
+ const headingIdsTransformer = () => (tree, file) => {
124550
+ visit(tree, 'heading', (node) => {
124551
+ const id = node.data?.hProperties?.id;
124552
+ if (typeof id !== 'string')
124553
+ return;
124554
+ const ids = file.data.explicitHeadingIds ?? new Set();
124555
+ file.data.explicitHeadingIds = ids;
124556
+ if (ids.has(id))
124557
+ console.warn(`[mdxish] Heading id "${id}" is used more than once; links reach only the first.`);
124558
+ ids.add(id);
124559
+ });
124560
+ };
124561
+ /* harmony default export */ const heading_ids = (headingIdsTransformer);
124562
+
124461
124563
  ;// ./processor/transform/mdxish/heading-slugs.ts
124462
124564
 
124463
124565
 
@@ -124483,12 +124585,17 @@ function textContent(node) {
124483
124585
  * Id's are used to construct slug anchor links & Table of Contents during rendering
124484
124586
  * Use the text / nodes that make up the heading to generate the id
124485
124587
  */
124486
- const generateSlugForHeadings = () => (tree) => {
124588
+ const generateSlugForHeadings = () => (tree, file) => {
124487
124589
  const slugger = new BananaSlug();
124590
+ // The slugger only counts the ids it generates, so `{#id}` ones are skipped past by hand.
124591
+ const explicitIds = file.data.explicitHeadingIds ?? new Set();
124488
124592
  visit(tree, 'element', (node) => {
124489
124593
  if (isHeading(node) && !node.properties.id) {
124490
124594
  const text = node.children.map(textContent).join('');
124491
- node.properties.id = slugger.slug(text);
124595
+ let id = slugger.slug(text);
124596
+ while (explicitIds.has(id))
124597
+ id = slugger.slug(text);
124598
+ node.properties.id = id;
124492
124599
  }
124493
124600
  });
124494
124601
  return tree;
@@ -128374,6 +128481,7 @@ function loadComponents() {
128374
128481
 
128375
128482
 
128376
128483
 
128484
+
128377
128485
 
128378
128486
 
128379
128487
  const defaultTransformers = [
@@ -128493,24 +128601,15 @@ function mdxishMdastToMd(mdast) {
128493
128601
  .use(mdxish_remarkStringify, stringifyOptions);
128494
128602
  return processor.stringify(processor.runSync(mdast));
128495
128603
  }
128496
- /**
128497
- * Processes markdown content with MDX syntax support and returns a HAST.
128498
- * Detects and renders custom component tags from the components hash.
128499
- *
128500
- * @see .claude/context/MDXish/Processor Overview.md
128501
- */
128502
- function mdxish(mdContent, opts = {}) {
128604
+ /** The steps `mdxish()` runs after parsing; run it on the parse's VFile, since steps read `file.data`. */
128605
+ function mdxishRenderProcessor(opts = {}) {
128503
128606
  const { components: userComponents = {}, hardBreaks: enableHardBreaks = true, safeMode = false, sanitize = false, variables, } = opts;
128504
128607
  const components = {
128505
128608
  ...loadComponents(),
128506
128609
  ...userComponents,
128507
128610
  };
128508
- // Remove JSX comments before processing (protect code blocks first)
128509
- const { protectedCode, protectedContent } = protectCodeBlocks(mdContent);
128510
- const withoutComments = removeJSXComments(protectedContent);
128511
- const contentWithoutComments = restoreCodeBlocks(withoutComments, protectedCode);
128512
- const { processor, parserReadyContent } = mdxishAstProcessor(contentWithoutComments, opts);
128513
- processor
128611
+ return unified()
128612
+ .use(heading_ids)
128514
128613
  .use(safeMode ? undefined : evaluate_exports, { sanitize }) // Evaluate `export const/function` and stash scope on file.data.mdxishScope
128515
128614
  .use(enableHardBreaks ? hard_breaks : undefined) // Must precede evaluateExpressions to avoid splitting the \n in an evaluated template literal into a <br> node
128516
128615
  .use(safeMode ? undefined : evaluate_expressions, { components, variables }) // Evaluate self-contained MDX expressions (e.g. `{1+1}`)
@@ -128528,11 +128627,25 @@ function mdxish(mdContent, opts = {}) {
128528
128627
  .use(heading_slugs)
128529
128628
  .use(rehypeMdxishComponents, {
128530
128629
  components,
128630
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define -- component bodies render through mdxish() again
128531
128631
  processMarkdown: (markdown) => mdxish(markdown, opts),
128532
128632
  });
128633
+ }
128634
+ /**
128635
+ * Processes markdown content with MDX syntax support and returns a HAST.
128636
+ * Detects and renders custom component tags from the components hash.
128637
+ *
128638
+ * @see .claude/context/MDXish/Processor Overview.md
128639
+ */
128640
+ function mdxish(mdContent, opts = {}) {
128641
+ // Remove JSX comments before processing (protect code blocks first)
128642
+ const { protectedCode, protectedContent } = protectCodeBlocks(mdContent);
128643
+ const withoutComments = removeJSXComments(protectedContent);
128644
+ const contentWithoutComments = restoreCodeBlocks(withoutComments, protectedCode);
128645
+ const { processor, parserReadyContent } = mdxishAstProcessor(contentWithoutComments, opts);
128533
128646
  const vfile = new VFile({ value: parserReadyContent });
128534
- const mdast = processor.parse(parserReadyContent);
128535
- const hast = processor.runSync(mdast, vfile);
128647
+ const mdast = processor.runSync(processor.parse(parserReadyContent), vfile);
128648
+ const hast = mdxishRenderProcessor(opts).runSync(mdast, vfile);
128536
128649
  if (!hast) {
128537
128650
  throw new Error('Markdown pipeline did not produce a HAST tree.');
128538
128651
  }
@@ -128560,6 +128673,142 @@ const mix = (text, opts = {}) => {
128560
128673
  };
128561
128674
  /* harmony default export */ const lib_mix = ((/* unused pure expression or super */ null && (mix)));
128562
128675
 
128676
+ ;// ./lib/mdxishHeadingIds.ts
128677
+ /* unused harmony import specifier */ var mdxishHeadingIds_visit;
128678
+ /* unused harmony import specifier */ var mdxishHeadingIds_visitParents;
128679
+ /* unused harmony import specifier */ var mdxishHeadingIds_VFile;
128680
+ /* unused harmony import specifier */ var mdxishHeadingIds_isMDXElement;
128681
+ /* unused harmony import specifier */ var mdxishHeadingIds_createTextNode;
128682
+ /* unused harmony import specifier */ var mdxishHeadingIds_mdxishRenderProcessor;
128683
+ /* unused harmony import specifier */ var mdxishHeadingIds_jsxAcornParser;
128684
+ /* unused harmony import specifier */ var mdxishHeadingIds_evaluateLiteralExpression;
128685
+
128686
+
128687
+
128688
+
128689
+
128690
+
128691
+
128692
+
128693
+ const HEADING_INDEX = 'dataMdxishHeadingIndex';
128694
+ const HEADING_TAG_REGEX = /^h[1-6]$/;
128695
+ const JSX_COMMENT_ONLY_REGEX = new RegExp(`^${JSX_COMMENT_REGEX.source}$`);
128696
+ const isExpression = (node) => node.type === 'mdxFlowExpression' || node.type === 'mdxTextExpression';
128697
+ function collectHeadings(tree) {
128698
+ const headings = [];
128699
+ mdxishHeadingIds_visit(tree, 'heading', (node) => {
128700
+ headings.push(node);
128701
+ });
128702
+ return headings;
128703
+ }
128704
+ function literalValue(source) {
128705
+ try {
128706
+ return { value: mdxishHeadingIds_evaluateLiteralExpression(source) };
128707
+ }
128708
+ catch {
128709
+ return null;
128710
+ }
128711
+ }
128712
+ function trimHeadingText(heading) {
128713
+ const first = heading.children[0];
128714
+ if (first?.type === 'text')
128715
+ first.value = first.value.trimStart();
128716
+ const last = heading.children.at(-1);
128717
+ if (last?.type === 'text')
128718
+ last.value = last.value.trimEnd();
128719
+ }
128720
+ const isNamePath = (node) => node.type === 'Identifier' ||
128721
+ (node.type === 'MemberExpression' && !node.computed && !!node.object && isNamePath(node.object));
128722
+ // A name like `{price}` or `{plan.name}` can only read a value, never build an element. Code the parser
128723
+ // rejects can't run at all, so the hub shows it as text.
128724
+ function canBuildElements(source) {
128725
+ try {
128726
+ return !isNamePath(mdxishHeadingIds_jsxAcornParser.parseExpressionAt(source, 0, { ecmaVersion: 'latest' }));
128727
+ }
128728
+ catch {
128729
+ return false;
128730
+ }
128731
+ }
128732
+ const isHeadingElement = (node) => mdxishHeadingIds_isMDXElement(node) && HEADING_TAG_REGEX.test(node.name ?? '');
128733
+ // An expression the hub has to run changes a heading from inside one (Markdown or an HTML heading tag), by
128734
+ // building an element (a call or JSX), or as a block: alone in its paragraph, its result is lifted out as one.
128735
+ function canChangeHeadings(node, ancestors, heading) {
128736
+ if (heading || ancestors.some(isHeadingElement) || node.type === 'mdxFlowExpression' || canBuildElements(node.value))
128737
+ return true;
128738
+ const parent = ancestors[ancestors.length - 1];
128739
+ return parent.children.every(child => child === node || (child.type === 'text' && !child.value.trim()));
128740
+ }
128741
+ // Safe mode leaves `<h2 id={...}>` without the id the hub evaluates, which shifts the numbering.
128742
+ function hasEvaluatedHeadingAttribute(tree) {
128743
+ let found = false;
128744
+ mdxishHeadingIds_visit(tree, isHeadingElement, (node) => {
128745
+ found = node.attributes.some(attribute => attribute.type === 'mdxJsxExpressionAttribute' || typeof attribute.value === 'object');
128746
+ return found ? (/* inlined export .EXIT */false) : undefined;
128747
+ });
128748
+ return found;
128749
+ }
128750
+ // Matches what the hub renders without running code: comments are stripped and plain literals become their
128751
+ // text. `false` when an expression that needs running could change the headings.
128752
+ function settleExpressions(tree) {
128753
+ const edits = [];
128754
+ let settled = true;
128755
+ mdxishHeadingIds_visitParents(tree, isExpression, (node, ancestors) => {
128756
+ const heading = ancestors.find((ancestor) => ancestor.type === 'heading');
128757
+ const parent = ancestors[ancestors.length - 1];
128758
+ if (JSX_COMMENT_ONLY_REGEX.test(`{${node.value}}`)) {
128759
+ edits.push({ heading, node, parent, replacement: null });
128760
+ return;
128761
+ }
128762
+ const literal = literalValue(node.value);
128763
+ if (literal) {
128764
+ edits.push({ heading, node, parent, replacement: mdxishHeadingIds_createTextNode(literal.value, node.position) });
128765
+ return;
128766
+ }
128767
+ if (canChangeHeadings(node, ancestors, heading))
128768
+ settled = false;
128769
+ });
128770
+ const apply = ({ node, parent, replacement }) => {
128771
+ parent.children.splice(parent.children.indexOf(node), 1, ...(replacement ? [replacement] : []));
128772
+ };
128773
+ // Comments go first: the hub strips them from the source, so the parser trims only the source
128774
+ // whitespace around them, never the spaces a literal adds.
128775
+ edits
128776
+ .filter(edit => !edit.replacement)
128777
+ .forEach(edit => {
128778
+ apply(edit);
128779
+ if (edit.heading)
128780
+ trimHeadingText(edit.heading);
128781
+ });
128782
+ edits.filter(edit => edit.replacement).forEach(apply);
128783
+ return settled;
128784
+ }
128785
+ /** Each heading's rendered anchor id, worked out without running code; `null` when code could change them. */
128786
+ function mdxishHeadingIds(tree, opts = {}) {
128787
+ const headings = collectHeadings(tree);
128788
+ if (headings.length === 0)
128789
+ return new Map();
128790
+ const copy = structuredClone(tree);
128791
+ let hasExport = false;
128792
+ mdxishHeadingIds_visit(copy, 'mdxjsEsm', () => {
128793
+ hasExport = true;
128794
+ });
128795
+ // An `export` can define components that render headings.
128796
+ if (hasExport || hasEvaluatedHeadingAttribute(copy) || !settleExpressions(copy))
128797
+ return null;
128798
+ collectHeadings(copy).forEach((heading, index) => {
128799
+ heading.data = { ...heading.data, hProperties: { ...heading.data?.hProperties, [HEADING_INDEX]: index } };
128800
+ });
128801
+ const hast = mdxishHeadingIds_mdxishRenderProcessor({ ...opts, safeMode: true }).runSync(copy, new mdxishHeadingIds_VFile());
128802
+ const ids = new Map();
128803
+ mdxishHeadingIds_visit(hast, 'element', (node) => {
128804
+ const index = node.properties[HEADING_INDEX];
128805
+ if (index === undefined || typeof node.properties.id !== 'string')
128806
+ return;
128807
+ ids.set(headings[Number(index)], node.properties.id);
128808
+ });
128809
+ return ids;
128810
+ }
128811
+
128563
128812
  ;// ./lib/extractToc.ts
128564
128813
  /* unused harmony import specifier */ var extractToc_extractToc;
128565
128814
 
@@ -129104,6 +129353,7 @@ async function stripComments(doc, { mdx, mdxish } = {}) {
129104
129353
 
129105
129354
 
129106
129355
 
129356
+
129107
129357
 
129108
129358
  ;// ./lib/render-fixture/renderFixture.ts
129109
129359
 
@@ -129576,7 +129826,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"*":["about","acceptCharset","accessK
129576
129826
  /******/ // startup
129577
129827
  /******/ // Load entry module and return exports
129578
129828
  /******/ // This entry module used 'module' so it can't be inlined
129579
- /******/ let __webpack_exports__ = __webpack_require__(7905);
129829
+ /******/ let __webpack_exports__ = __webpack_require__(5919);
129580
129830
  /******/ module.exports = __webpack_exports__;
129581
129831
  /******/
129582
129832
  /******/ })()