@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.js CHANGED
@@ -11423,7 +11423,7 @@ module.exports = function () {
11423
11423
 
11424
11424
  /***/ },
11425
11425
 
11426
- /***/ 714
11426
+ /***/ 9477
11427
11427
  (module, __webpack_exports__, __webpack_require__) {
11428
11428
 
11429
11429
  "use strict";
@@ -11448,6 +11448,7 @@ __webpack_require__.d(__webpack_exports__, {
11448
11448
  mdx: () => (/* reexport */ lib_mdx),
11449
11449
  mdxish: () => (/* reexport */ lib_mdxish),
11450
11450
  mdxishAstProcessor: () => (/* reexport */ mdxishAstProcessor),
11451
+ mdxishHeadingIds: () => (/* reexport */ mdxishHeadingIds),
11451
11452
  mdxishMdastToMd: () => (/* reexport */ mdxishMdastToMd),
11452
11453
  mdxishTags: () => (/* reexport */ mdxishTags),
11453
11454
  migrate: () => (/* reexport */ lib_migrate),
@@ -54835,6 +54836,209 @@ const mdast = (text, opts = {}) => {
54835
54836
  };
54836
54837
  /* harmony default export */ const lib_mdast = (mdast);
54837
54838
 
54839
+ ;// ./node_modules/micromark-util-symbol/lib/codes.js
54840
+ /**
54841
+ * Character codes.
54842
+ *
54843
+ * This module is compiled away!
54844
+ *
54845
+ * micromark works based on character codes.
54846
+ * This module contains constants for the ASCII block and the replacement
54847
+ * character.
54848
+ * A couple of them are handled in a special way, such as the line endings
54849
+ * (CR, LF, and CR+LF, commonly known as end-of-line: EOLs), the tab (horizontal
54850
+ * tab) and its expansion based on what column it’s at (virtual space),
54851
+ * and the end-of-file (eof) character.
54852
+ * As values are preprocessed before handling them, the actual characters LF,
54853
+ * CR, HT, and NUL (which is present as the replacement character), are
54854
+ * guaranteed to not exist.
54855
+ *
54856
+ * Unicode basic latin block.
54857
+ */
54858
+ const codes = /** @type {const} */ ({
54859
+ carriageReturn: -5,
54860
+ lineFeed: -4,
54861
+ carriageReturnLineFeed: -3,
54862
+ horizontalTab: -2,
54863
+ virtualSpace: -1,
54864
+ eof: null,
54865
+ nul: 0,
54866
+ soh: 1,
54867
+ stx: 2,
54868
+ etx: 3,
54869
+ eot: 4,
54870
+ enq: 5,
54871
+ ack: 6,
54872
+ bel: 7,
54873
+ bs: 8,
54874
+ ht: 9, // `\t`
54875
+ lf: 10, // `\n`
54876
+ vt: 11, // `\v`
54877
+ ff: 12, // `\f`
54878
+ cr: 13, // `\r`
54879
+ so: 14,
54880
+ si: 15,
54881
+ dle: 16,
54882
+ dc1: 17,
54883
+ dc2: 18,
54884
+ dc3: 19,
54885
+ dc4: 20,
54886
+ nak: 21,
54887
+ syn: 22,
54888
+ etb: 23,
54889
+ can: 24,
54890
+ em: 25,
54891
+ sub: 26,
54892
+ esc: 27,
54893
+ fs: 28,
54894
+ gs: 29,
54895
+ rs: 30,
54896
+ us: 31,
54897
+ space: 32,
54898
+ exclamationMark: 33, // `!`
54899
+ quotationMark: 34, // `"`
54900
+ numberSign: 35, // `#`
54901
+ dollarSign: 36, // `$`
54902
+ percentSign: 37, // `%`
54903
+ ampersand: 38, // `&`
54904
+ apostrophe: 39, // `'`
54905
+ leftParenthesis: 40, // `(`
54906
+ rightParenthesis: 41, // `)`
54907
+ asterisk: 42, // `*`
54908
+ plusSign: 43, // `+`
54909
+ comma: 44, // `,`
54910
+ dash: 45, // `-`
54911
+ dot: 46, // `.`
54912
+ slash: 47, // `/`
54913
+ digit0: 48, // `0`
54914
+ digit1: 49, // `1`
54915
+ digit2: 50, // `2`
54916
+ digit3: 51, // `3`
54917
+ digit4: 52, // `4`
54918
+ digit5: 53, // `5`
54919
+ digit6: 54, // `6`
54920
+ digit7: 55, // `7`
54921
+ digit8: 56, // `8`
54922
+ digit9: 57, // `9`
54923
+ colon: 58, // `:`
54924
+ semicolon: 59, // `;`
54925
+ lessThan: 60, // `<`
54926
+ equalsTo: 61, // `=`
54927
+ greaterThan: 62, // `>`
54928
+ questionMark: 63, // `?`
54929
+ atSign: 64, // `@`
54930
+ uppercaseA: 65, // `A`
54931
+ uppercaseB: 66, // `B`
54932
+ uppercaseC: 67, // `C`
54933
+ uppercaseD: 68, // `D`
54934
+ uppercaseE: 69, // `E`
54935
+ uppercaseF: 70, // `F`
54936
+ uppercaseG: 71, // `G`
54937
+ uppercaseH: 72, // `H`
54938
+ uppercaseI: 73, // `I`
54939
+ uppercaseJ: 74, // `J`
54940
+ uppercaseK: 75, // `K`
54941
+ uppercaseL: 76, // `L`
54942
+ uppercaseM: 77, // `M`
54943
+ uppercaseN: 78, // `N`
54944
+ uppercaseO: 79, // `O`
54945
+ uppercaseP: 80, // `P`
54946
+ uppercaseQ: 81, // `Q`
54947
+ uppercaseR: 82, // `R`
54948
+ uppercaseS: 83, // `S`
54949
+ uppercaseT: 84, // `T`
54950
+ uppercaseU: 85, // `U`
54951
+ uppercaseV: 86, // `V`
54952
+ uppercaseW: 87, // `W`
54953
+ uppercaseX: 88, // `X`
54954
+ uppercaseY: 89, // `Y`
54955
+ uppercaseZ: 90, // `Z`
54956
+ leftSquareBracket: 91, // `[`
54957
+ backslash: 92, // `\`
54958
+ rightSquareBracket: 93, // `]`
54959
+ caret: 94, // `^`
54960
+ underscore: 95, // `_`
54961
+ graveAccent: 96, // `` ` ``
54962
+ lowercaseA: 97, // `a`
54963
+ lowercaseB: 98, // `b`
54964
+ lowercaseC: 99, // `c`
54965
+ lowercaseD: 100, // `d`
54966
+ lowercaseE: 101, // `e`
54967
+ lowercaseF: 102, // `f`
54968
+ lowercaseG: 103, // `g`
54969
+ lowercaseH: 104, // `h`
54970
+ lowercaseI: 105, // `i`
54971
+ lowercaseJ: 106, // `j`
54972
+ lowercaseK: 107, // `k`
54973
+ lowercaseL: 108, // `l`
54974
+ lowercaseM: 109, // `m`
54975
+ lowercaseN: 110, // `n`
54976
+ lowercaseO: 111, // `o`
54977
+ lowercaseP: 112, // `p`
54978
+ lowercaseQ: 113, // `q`
54979
+ lowercaseR: 114, // `r`
54980
+ lowercaseS: 115, // `s`
54981
+ lowercaseT: 116, // `t`
54982
+ lowercaseU: 117, // `u`
54983
+ lowercaseV: 118, // `v`
54984
+ lowercaseW: 119, // `w`
54985
+ lowercaseX: 120, // `x`
54986
+ lowercaseY: 121, // `y`
54987
+ lowercaseZ: 122, // `z`
54988
+ leftCurlyBrace: 123, // `{`
54989
+ verticalBar: 124, // `|`
54990
+ rightCurlyBrace: 125, // `}`
54991
+ tilde: 126, // `~`
54992
+ del: 127,
54993
+ // Unicode Specials block.
54994
+ byteOrderMarker: 65_279,
54995
+ // Unicode Specials block.
54996
+ replacementCharacter: 65_533 // `�`
54997
+ })
54998
+
54999
+ ;// ./lib/micromark/heading-id/syntax.ts
55000
+
55001
+
55002
+ /** One character a `{#id}` heading id may use: the ones github-slugger keeps, plus `.` and `:`. */
55003
+ const HEADING_ID_CHAR = '[\\p{L}\\p{M}\\p{N}_.:-]';
55004
+ const ID_CLOSE_REGEX = new RegExp(`^${HEADING_ID_CHAR}+\\}$`, 'u');
55005
+ const typeAt = (events, index) => events[index]?.[1].type;
55006
+ function isIdToken(events, index, context, type, value) {
55007
+ return typeAt(events, index) === type && value.test(context.sliceSerialize(events[index][1]));
55008
+ }
55009
+ /** The exit index of the heading's last content token, past any trailing space and closing `##`. */
55010
+ function contentEnd(events) {
55011
+ let end = events.length - 2;
55012
+ if (typeAt(events, end) === 'whitespace')
55013
+ end -= 2;
55014
+ if (typeAt(events, end) === 'atxHeadingSequence' && typeAt(events, end - 2) === 'whitespace')
55015
+ end -= 4;
55016
+ return end;
55017
+ }
55018
+ const resolveHeadingId = (events, context) => {
55019
+ // Each token is an enter and an exit event; these indexes point at the exits.
55020
+ const close = contentEnd(events);
55021
+ const hash = close - 2;
55022
+ const open = close - 4;
55023
+ const space = close - 6;
55024
+ const endsWithId = isIdToken(events, close, context, 'atxHeadingText', ID_CLOSE_REGEX) &&
55025
+ isIdToken(events, hash, context, 'atxHeadingSequence', /^#$/) &&
55026
+ isIdToken(events, open, context, 'atxHeadingText', /^\{$/) &&
55027
+ typeAt(events, space) === 'whitespace';
55028
+ if (!endsWithId)
55029
+ return headingAtx.resolve?.(events, context) ?? events;
55030
+ const id = { type: 'headingId', start: events[open][1].start, end: events[close][1].end };
55031
+ events.splice(space - 1, close - space + 2);
55032
+ const resolved = headingAtx.resolve?.(events, context) ?? events;
55033
+ resolved.splice(resolved.length - 1, 0, ['enter', id, context], ['exit', id, context]);
55034
+ return resolved;
55035
+ };
55036
+ const headingIdConstruct = { ...headingAtx, resolve: resolveHeadingId };
55037
+ /** The ATX heading construct, with a line-final ` {#id}` split off as a `headingId` token. */
55038
+ function headingId() {
55039
+ return { flow: { [codes.numberSign]: headingIdConstruct } };
55040
+ }
55041
+
54838
55042
  ;// ./lib/utils/jsx-acorn-parser.ts
54839
55043
 
54840
55044
 
@@ -54946,6 +55150,7 @@ const evaluateLiteralExpression = (source) => {
54946
55150
 
54947
55151
 
54948
55152
 
55153
+
54949
55154
  /**
54950
55155
  * Evaluate a JavaScript expression source and return its value.
54951
55156
  *
@@ -55062,6 +55267,24 @@ const getHPropKeys = (node) => {
55062
55267
  const hProps = getHProps(node);
55063
55268
  return Object.keys(hProps) || [];
55064
55269
  };
55270
+ /** Turn a non-renderable evaluation result into a text node. */
55271
+ const createTextNode = (result, position) => {
55272
+ if (result === null || result === undefined)
55273
+ return { type: 'text', value: '', position };
55274
+ if (typeof result === 'object')
55275
+ return { type: 'text', value: JSON.stringify(result), position };
55276
+ return { type: 'text', value: String(result), position };
55277
+ };
55278
+ const HEADING_ID_REGEX = new RegExp(`^${HEADING_ID_CHAR}+$`, 'u');
55279
+ /**
55280
+ * The id a heading's trailing `{#id}` set, when it is one the `{#id}` syntax can spell.
55281
+ *
55282
+ * Ids may use letters, numbers, `-`, `_`, `.` and `:`; anything else, like `x y`, is dropped.
55283
+ */
55284
+ const explicitHeadingId = (node) => {
55285
+ const id = node.data?.hProperties?.id;
55286
+ return typeof id === 'string' && HEADING_ID_REGEX.test(id) ? id : undefined;
55287
+ };
55065
55288
  /**
55066
55289
  * Gets the attributes of an MDX element and returns them as an object of hProperties.
55067
55290
  *
@@ -73197,6 +73420,17 @@ function gemojiFromMarkdown() {
73197
73420
  };
73198
73421
  }
73199
73422
 
73423
+ ;// ./lib/mdast-util/heading-id/index.ts
73424
+ function exitHeadingId(token) {
73425
+ const heading = this.stack[this.stack.length - 1];
73426
+ const id = this.sliceSerialize(token).slice('{#'.length, -'}'.length);
73427
+ heading.data = { ...heading.data, hProperties: { ...heading.data?.hProperties, id } };
73428
+ }
73429
+ /** Sets a heading's id from its `headingId` token. */
73430
+ function headingIdFromMarkdown() {
73431
+ return { exit: { headingId: exitHeadingId } };
73432
+ }
73433
+
73200
73434
  ;// ./lib/mdast-util/html-block-component/index.ts
73201
73435
  const contextMap = new WeakMap();
73202
73436
  function findHtmlBlockComponentToken() {
@@ -73575,166 +73809,6 @@ function mdxComponentFromMarkdown() {
73575
73809
  };
73576
73810
  }
73577
73811
 
73578
- ;// ./node_modules/micromark-util-symbol/lib/codes.js
73579
- /**
73580
- * Character codes.
73581
- *
73582
- * This module is compiled away!
73583
- *
73584
- * micromark works based on character codes.
73585
- * This module contains constants for the ASCII block and the replacement
73586
- * character.
73587
- * A couple of them are handled in a special way, such as the line endings
73588
- * (CR, LF, and CR+LF, commonly known as end-of-line: EOLs), the tab (horizontal
73589
- * tab) and its expansion based on what column it’s at (virtual space),
73590
- * and the end-of-file (eof) character.
73591
- * As values are preprocessed before handling them, the actual characters LF,
73592
- * CR, HT, and NUL (which is present as the replacement character), are
73593
- * guaranteed to not exist.
73594
- *
73595
- * Unicode basic latin block.
73596
- */
73597
- const codes = /** @type {const} */ ({
73598
- carriageReturn: -5,
73599
- lineFeed: -4,
73600
- carriageReturnLineFeed: -3,
73601
- horizontalTab: -2,
73602
- virtualSpace: -1,
73603
- eof: null,
73604
- nul: 0,
73605
- soh: 1,
73606
- stx: 2,
73607
- etx: 3,
73608
- eot: 4,
73609
- enq: 5,
73610
- ack: 6,
73611
- bel: 7,
73612
- bs: 8,
73613
- ht: 9, // `\t`
73614
- lf: 10, // `\n`
73615
- vt: 11, // `\v`
73616
- ff: 12, // `\f`
73617
- cr: 13, // `\r`
73618
- so: 14,
73619
- si: 15,
73620
- dle: 16,
73621
- dc1: 17,
73622
- dc2: 18,
73623
- dc3: 19,
73624
- dc4: 20,
73625
- nak: 21,
73626
- syn: 22,
73627
- etb: 23,
73628
- can: 24,
73629
- em: 25,
73630
- sub: 26,
73631
- esc: 27,
73632
- fs: 28,
73633
- gs: 29,
73634
- rs: 30,
73635
- us: 31,
73636
- space: 32,
73637
- exclamationMark: 33, // `!`
73638
- quotationMark: 34, // `"`
73639
- numberSign: 35, // `#`
73640
- dollarSign: 36, // `$`
73641
- percentSign: 37, // `%`
73642
- ampersand: 38, // `&`
73643
- apostrophe: 39, // `'`
73644
- leftParenthesis: 40, // `(`
73645
- rightParenthesis: 41, // `)`
73646
- asterisk: 42, // `*`
73647
- plusSign: 43, // `+`
73648
- comma: 44, // `,`
73649
- dash: 45, // `-`
73650
- dot: 46, // `.`
73651
- slash: 47, // `/`
73652
- digit0: 48, // `0`
73653
- digit1: 49, // `1`
73654
- digit2: 50, // `2`
73655
- digit3: 51, // `3`
73656
- digit4: 52, // `4`
73657
- digit5: 53, // `5`
73658
- digit6: 54, // `6`
73659
- digit7: 55, // `7`
73660
- digit8: 56, // `8`
73661
- digit9: 57, // `9`
73662
- colon: 58, // `:`
73663
- semicolon: 59, // `;`
73664
- lessThan: 60, // `<`
73665
- equalsTo: 61, // `=`
73666
- greaterThan: 62, // `>`
73667
- questionMark: 63, // `?`
73668
- atSign: 64, // `@`
73669
- uppercaseA: 65, // `A`
73670
- uppercaseB: 66, // `B`
73671
- uppercaseC: 67, // `C`
73672
- uppercaseD: 68, // `D`
73673
- uppercaseE: 69, // `E`
73674
- uppercaseF: 70, // `F`
73675
- uppercaseG: 71, // `G`
73676
- uppercaseH: 72, // `H`
73677
- uppercaseI: 73, // `I`
73678
- uppercaseJ: 74, // `J`
73679
- uppercaseK: 75, // `K`
73680
- uppercaseL: 76, // `L`
73681
- uppercaseM: 77, // `M`
73682
- uppercaseN: 78, // `N`
73683
- uppercaseO: 79, // `O`
73684
- uppercaseP: 80, // `P`
73685
- uppercaseQ: 81, // `Q`
73686
- uppercaseR: 82, // `R`
73687
- uppercaseS: 83, // `S`
73688
- uppercaseT: 84, // `T`
73689
- uppercaseU: 85, // `U`
73690
- uppercaseV: 86, // `V`
73691
- uppercaseW: 87, // `W`
73692
- uppercaseX: 88, // `X`
73693
- uppercaseY: 89, // `Y`
73694
- uppercaseZ: 90, // `Z`
73695
- leftSquareBracket: 91, // `[`
73696
- backslash: 92, // `\`
73697
- rightSquareBracket: 93, // `]`
73698
- caret: 94, // `^`
73699
- underscore: 95, // `_`
73700
- graveAccent: 96, // `` ` ``
73701
- lowercaseA: 97, // `a`
73702
- lowercaseB: 98, // `b`
73703
- lowercaseC: 99, // `c`
73704
- lowercaseD: 100, // `d`
73705
- lowercaseE: 101, // `e`
73706
- lowercaseF: 102, // `f`
73707
- lowercaseG: 103, // `g`
73708
- lowercaseH: 104, // `h`
73709
- lowercaseI: 105, // `i`
73710
- lowercaseJ: 106, // `j`
73711
- lowercaseK: 107, // `k`
73712
- lowercaseL: 108, // `l`
73713
- lowercaseM: 109, // `m`
73714
- lowercaseN: 110, // `n`
73715
- lowercaseO: 111, // `o`
73716
- lowercaseP: 112, // `p`
73717
- lowercaseQ: 113, // `q`
73718
- lowercaseR: 114, // `r`
73719
- lowercaseS: 115, // `s`
73720
- lowercaseT: 116, // `t`
73721
- lowercaseU: 117, // `u`
73722
- lowercaseV: 118, // `v`
73723
- lowercaseW: 119, // `w`
73724
- lowercaseX: 120, // `x`
73725
- lowercaseY: 121, // `y`
73726
- lowercaseZ: 122, // `z`
73727
- leftCurlyBrace: 123, // `{`
73728
- verticalBar: 124, // `|`
73729
- rightCurlyBrace: 125, // `}`
73730
- tilde: 126, // `~`
73731
- del: 127,
73732
- // Unicode Specials block.
73733
- byteOrderMarker: 65_279,
73734
- // Unicode Specials block.
73735
- replacementCharacter: 65_533 // `�`
73736
- })
73737
-
73738
73812
  ;// ./lib/micromark/gemoji/syntax.ts
73739
73813
 
73740
73814
  // Matches the name pattern from the original regex: \+1 or [-\w]+
@@ -73822,6 +73896,9 @@ function syntax_gemoji() {
73822
73896
  };
73823
73897
  }
73824
73898
 
73899
+ ;// ./lib/micromark/heading-id/index.ts
73900
+
73901
+
73825
73902
  ;// ./node_modules/micromark-util-symbol/lib/types.js
73826
73903
  /**
73827
73904
  * This module is compiled away!
@@ -77271,6 +77348,8 @@ function mdxExpressionLenient() {
77271
77348
 
77272
77349
 
77273
77350
 
77351
+
77352
+
77274
77353
 
77275
77354
 
77276
77355
 
@@ -77310,6 +77389,8 @@ const REGISTRY = {
77310
77389
  mdxComponent: { syntax: mdxComponent, fromMarkdown: mdxComponentFromMarkdown },
77311
77390
  gemoji: { syntax: syntax_gemoji, fromMarkdown: gemojiFromMarkdown },
77312
77391
  legacyVariable: { syntax: legacyVariable, fromMarkdown: legacyVariableFromMarkdown },
77392
+ // Replaces the ATX heading construct in `flow`, so it never touches prose outside a heading.
77393
+ headingId: { syntax: headingId, fromMarkdown: headingIdFromMarkdown },
77313
77394
  looseHtmlEntity: { syntax: looseHtmlEntity, fromMarkdown: looseHtmlEntityFromMarkdown },
77314
77395
  htmlBlockComponent: { syntax: htmlBlockComponent, fromMarkdown: htmlBlockComponentFromMarkdown },
77315
77396
  // This is for in-document variable & function definitions
@@ -77340,18 +77421,13 @@ const EXPRESSIONS = ['jsxComment', 'mdxExpressionLenient', 'mdxjsEsm'];
77340
77421
  */
77341
77422
  const FEATURES = {
77342
77423
  /** `lib/mdxish.ts` — the document parser; the only site taking every group */
77343
- document: [...BLOCK_CLAIMS, ...INLINE, ...EXPRESSIONS, 'emptyTaskListItem'],
77424
+ document: [...BLOCK_CLAIMS, ...INLINE, ...EXPRESSIONS, 'emptyTaskListItem', 'headingId'],
77344
77425
  /**
77345
77426
  * `components/utils.ts` — re-parses a component body, which should tokenize
77346
77427
  * like the document around it: when the two drifted a `<Table>` in a
77347
77428
  * `<Callout>` lost every row (CX-3705).
77348
77429
  */
77349
- componentBody: [
77350
- ...BLOCK_CLAIMS,
77351
- ...INLINE,
77352
- 'mdxExpression',
77353
- 'emptyTaskListItem',
77354
- ],
77430
+ componentBody: [...BLOCK_CLAIMS, ...INLINE, 'mdxExpression', 'emptyTaskListItem', 'headingId'],
77355
77431
  /**
77356
77432
  * `lib/mdxishTags.ts` — collects component names, so nothing inline is needed.
77357
77433
  * Omits `htmlBlockComponent` deliberately since it's not a custom component,
@@ -101975,6 +102051,18 @@ const embed_embed = (node) => {
101975
102051
  };
101976
102052
  /* harmony default export */ const compile_embed = (embed_embed);
101977
102053
 
102054
+ ;// ./processor/compile/heading.ts
102055
+
102056
+
102057
+ const SETEXT_UNDERLINE_REGEX = /\n(?:=+|-+)$/;
102058
+ /** Writes an explicit heading id back as ` {#id}`. A setext heading, written for a line break, can't carry one. */
102059
+ const compile_heading_heading = ((node, parent, state, info) => {
102060
+ const markdown = handle.heading(node, parent, state, info);
102061
+ const id = explicitHeadingId(node);
102062
+ return id && !SETEXT_UNDERLINE_REGEX.test(markdown) ? `${markdown} {#${id}}` : markdown;
102063
+ });
102064
+ /* harmony default export */ const compile_heading = (compile_heading_heading);
102065
+
101978
102066
  ;// ./processor/compile/html-block.ts
101979
102067
 
101980
102068
  const htmlBlock = (node) => {
@@ -102120,6 +102208,7 @@ const mdxishText = (node, parent, state, info) => compile_text_text(node, parent
102120
102208
 
102121
102209
 
102122
102210
 
102211
+
102123
102212
  function compilers(mdxish = false) {
102124
102213
  const data = this.data();
102125
102214
  const toMarkdownExtensions = data.toMarkdownExtensions || (data.toMarkdownExtensions = []);
@@ -102140,6 +102229,7 @@ function compilers(mdxish = false) {
102140
102229
  text: compile_text_text,
102141
102230
  yaml: compile_compatibility,
102142
102231
  // needed only for mdxish
102232
+ ...(mdxish && { heading: compile_heading }),
102143
102233
  ...(mdxish && { list: compile_list }),
102144
102234
  ...(mdxish && { listItem: list_item }),
102145
102235
  ...(mdxish && { text: compile_text }),
@@ -105689,6 +105779,7 @@ function reactElementToHast(node) {
105689
105779
 
105690
105780
 
105691
105781
 
105782
+
105692
105783
  /**
105693
105784
  * Bind the components a given expression actually uses as tags. Scoped per expression on purpose:
105694
105785
  * binding the whole hash would shadow same-named globals (a `math` component would break
@@ -105739,14 +105830,6 @@ const wrapInParagraph = (child) => ({
105739
105830
  position: child.position,
105740
105831
  });
105741
105832
  const placeText = (text, needsBlock) => (needsBlock ? wrapInParagraph(text) : text);
105742
- /** Turn a non-renderable evaluation result into a text node. */
105743
- const createTextNode = (result, position) => {
105744
- if (result === null || result === undefined)
105745
- return { type: 'text', value: '', position };
105746
- if (typeof result === 'object')
105747
- return { type: 'text', value: JSON.stringify(result), position };
105748
- return { type: 'text', value: String(result), position };
105749
- };
105750
105833
  /**
105751
105834
  * AST transformer to evaluate MDX expressions.
105752
105835
  * Replaces mdxFlowExpression and mdxTextExpression nodes with their evaluated values.
@@ -105866,6 +105949,26 @@ const evaluateStyleBlockExpressions = () => (tree, file) => {
105866
105949
  };
105867
105950
  /* harmony default export */ const evaluate_style_block_expressions = (evaluateStyleBlockExpressions);
105868
105951
 
105952
+ ;// ./processor/transform/mdxish/heading-ids.ts
105953
+
105954
+ /**
105955
+ * Records every heading id set by `{#id}`, so the slug pass never gives one to another heading.
105956
+ * Warns when two headings share an id, since links can only reach the first.
105957
+ */
105958
+ const headingIdsTransformer = () => (tree, file) => {
105959
+ visit(tree, 'heading', (node) => {
105960
+ const id = node.data?.hProperties?.id;
105961
+ if (typeof id !== 'string')
105962
+ return;
105963
+ const ids = file.data.explicitHeadingIds ?? new Set();
105964
+ file.data.explicitHeadingIds = ids;
105965
+ if (ids.has(id))
105966
+ console.warn(`[mdxish] Heading id "${id}" is used more than once; links reach only the first.`);
105967
+ ids.add(id);
105968
+ });
105969
+ };
105970
+ /* harmony default export */ const heading_ids = (headingIdsTransformer);
105971
+
105869
105972
  ;// ./processor/transform/mdxish/heading-slugs.ts
105870
105973
 
105871
105974
 
@@ -105891,12 +105994,17 @@ function textContent(node) {
105891
105994
  * Id's are used to construct slug anchor links & Table of Contents during rendering
105892
105995
  * Use the text / nodes that make up the heading to generate the id
105893
105996
  */
105894
- const generateSlugForHeadings = () => (tree) => {
105997
+ const generateSlugForHeadings = () => (tree, file) => {
105895
105998
  const slugger = new BananaSlug();
105999
+ // The slugger only counts the ids it generates, so `{#id}` ones are skipped past by hand.
106000
+ const explicitIds = file.data.explicitHeadingIds ?? new Set();
105896
106001
  visit(tree, 'element', (node) => {
105897
106002
  if (isHeading(node) && !node.properties.id) {
105898
106003
  const text = node.children.map(textContent).join('');
105899
- node.properties.id = slugger.slug(text);
106004
+ let id = slugger.slug(text);
106005
+ while (explicitIds.has(id))
106006
+ id = slugger.slug(text);
106007
+ node.properties.id = id;
105900
106008
  }
105901
106009
  });
105902
106010
  return tree;
@@ -108411,6 +108519,7 @@ function loadComponents() {
108411
108519
 
108412
108520
 
108413
108521
 
108522
+
108414
108523
 
108415
108524
 
108416
108525
  const defaultTransformers = [
@@ -108530,24 +108639,15 @@ function mdxishMdastToMd(mdast) {
108530
108639
  .use(remarkStringify, stringifyOptions);
108531
108640
  return processor.stringify(processor.runSync(mdast));
108532
108641
  }
108533
- /**
108534
- * Processes markdown content with MDX syntax support and returns a HAST.
108535
- * Detects and renders custom component tags from the components hash.
108536
- *
108537
- * @see .claude/context/MDXish/Processor Overview.md
108538
- */
108539
- function mdxish(mdContent, opts = {}) {
108642
+ /** The steps `mdxish()` runs after parsing; run it on the parse's VFile, since steps read `file.data`. */
108643
+ function mdxishRenderProcessor(opts = {}) {
108540
108644
  const { components: userComponents = {}, hardBreaks: enableHardBreaks = true, safeMode = false, sanitize = false, variables, } = opts;
108541
108645
  const components = {
108542
108646
  ...loadComponents(),
108543
108647
  ...userComponents,
108544
108648
  };
108545
- // Remove JSX comments before processing (protect code blocks first)
108546
- const { protectedCode, protectedContent } = protectCodeBlocks(mdContent);
108547
- const withoutComments = removeJSXComments(protectedContent);
108548
- const contentWithoutComments = restoreCodeBlocks(withoutComments, protectedCode);
108549
- const { processor, parserReadyContent } = mdxishAstProcessor(contentWithoutComments, opts);
108550
- processor
108649
+ return unified()
108650
+ .use(heading_ids)
108551
108651
  .use(safeMode ? undefined : evaluate_exports, { sanitize }) // Evaluate `export const/function` and stash scope on file.data.mdxishScope
108552
108652
  .use(enableHardBreaks ? hard_breaks : undefined) // Must precede evaluateExpressions to avoid splitting the \n in an evaluated template literal into a <br> node
108553
108653
  .use(safeMode ? undefined : evaluate_expressions, { components, variables }) // Evaluate self-contained MDX expressions (e.g. `{1+1}`)
@@ -108565,11 +108665,25 @@ function mdxish(mdContent, opts = {}) {
108565
108665
  .use(heading_slugs)
108566
108666
  .use(rehypeMdxishComponents, {
108567
108667
  components,
108668
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define -- component bodies render through mdxish() again
108568
108669
  processMarkdown: (markdown) => mdxish(markdown, opts),
108569
108670
  });
108671
+ }
108672
+ /**
108673
+ * Processes markdown content with MDX syntax support and returns a HAST.
108674
+ * Detects and renders custom component tags from the components hash.
108675
+ *
108676
+ * @see .claude/context/MDXish/Processor Overview.md
108677
+ */
108678
+ function mdxish(mdContent, opts = {}) {
108679
+ // Remove JSX comments before processing (protect code blocks first)
108680
+ const { protectedCode, protectedContent } = protectCodeBlocks(mdContent);
108681
+ const withoutComments = removeJSXComments(protectedContent);
108682
+ const contentWithoutComments = restoreCodeBlocks(withoutComments, protectedCode);
108683
+ const { processor, parserReadyContent } = mdxishAstProcessor(contentWithoutComments, opts);
108570
108684
  const vfile = new VFile({ value: parserReadyContent });
108571
- const mdast = processor.parse(parserReadyContent);
108572
- const hast = processor.runSync(mdast, vfile);
108685
+ const mdast = processor.runSync(processor.parse(parserReadyContent), vfile);
108686
+ const hast = mdxishRenderProcessor(opts).runSync(mdast, vfile);
108573
108687
  if (!hast) {
108574
108688
  throw new Error('Markdown pipeline did not produce a HAST tree.');
108575
108689
  }
@@ -108594,6 +108708,134 @@ const mix = (text, opts = {}) => {
108594
108708
  };
108595
108709
  /* harmony default export */ const lib_mix = (mix);
108596
108710
 
108711
+ ;// ./lib/mdxishHeadingIds.ts
108712
+
108713
+
108714
+
108715
+
108716
+
108717
+
108718
+
108719
+
108720
+ const HEADING_INDEX = 'dataMdxishHeadingIndex';
108721
+ const HEADING_TAG_REGEX = /^h[1-6]$/;
108722
+ const JSX_COMMENT_ONLY_REGEX = new RegExp(`^${JSX_COMMENT_REGEX.source}$`);
108723
+ const isExpression = (node) => node.type === 'mdxFlowExpression' || node.type === 'mdxTextExpression';
108724
+ function collectHeadings(tree) {
108725
+ const headings = [];
108726
+ visit(tree, 'heading', (node) => {
108727
+ headings.push(node);
108728
+ });
108729
+ return headings;
108730
+ }
108731
+ function literalValue(source) {
108732
+ try {
108733
+ return { value: evaluateLiteralExpression(source) };
108734
+ }
108735
+ catch {
108736
+ return null;
108737
+ }
108738
+ }
108739
+ function trimHeadingText(heading) {
108740
+ const first = heading.children[0];
108741
+ if (first?.type === 'text')
108742
+ first.value = first.value.trimStart();
108743
+ const last = heading.children.at(-1);
108744
+ if (last?.type === 'text')
108745
+ last.value = last.value.trimEnd();
108746
+ }
108747
+ const isNamePath = (node) => node.type === 'Identifier' ||
108748
+ (node.type === 'MemberExpression' && !node.computed && !!node.object && isNamePath(node.object));
108749
+ // A name like `{price}` or `{plan.name}` can only read a value, never build an element. Code the parser
108750
+ // rejects can't run at all, so the hub shows it as text.
108751
+ function canBuildElements(source) {
108752
+ try {
108753
+ return !isNamePath(jsxAcornParser.parseExpressionAt(source, 0, { ecmaVersion: 'latest' }));
108754
+ }
108755
+ catch {
108756
+ return false;
108757
+ }
108758
+ }
108759
+ const isHeadingElement = (node) => isMDXElement(node) && HEADING_TAG_REGEX.test(node.name ?? '');
108760
+ // An expression the hub has to run changes a heading from inside one (Markdown or an HTML heading tag), by
108761
+ // building an element (a call or JSX), or as a block: alone in its paragraph, its result is lifted out as one.
108762
+ function canChangeHeadings(node, ancestors, heading) {
108763
+ if (heading || ancestors.some(isHeadingElement) || node.type === 'mdxFlowExpression' || canBuildElements(node.value))
108764
+ return true;
108765
+ const parent = ancestors[ancestors.length - 1];
108766
+ return parent.children.every(child => child === node || (child.type === 'text' && !child.value.trim()));
108767
+ }
108768
+ // Safe mode leaves `<h2 id={...}>` without the id the hub evaluates, which shifts the numbering.
108769
+ function hasEvaluatedHeadingAttribute(tree) {
108770
+ let found = false;
108771
+ visit(tree, isHeadingElement, (node) => {
108772
+ found = node.attributes.some(attribute => attribute.type === 'mdxJsxExpressionAttribute' || typeof attribute.value === 'object');
108773
+ return found ? (/* inlined export .EXIT */false) : undefined;
108774
+ });
108775
+ return found;
108776
+ }
108777
+ // Matches what the hub renders without running code: comments are stripped and plain literals become their
108778
+ // text. `false` when an expression that needs running could change the headings.
108779
+ function settleExpressions(tree) {
108780
+ const edits = [];
108781
+ let settled = true;
108782
+ visitParents(tree, isExpression, (node, ancestors) => {
108783
+ const heading = ancestors.find((ancestor) => ancestor.type === 'heading');
108784
+ const parent = ancestors[ancestors.length - 1];
108785
+ if (JSX_COMMENT_ONLY_REGEX.test(`{${node.value}}`)) {
108786
+ edits.push({ heading, node, parent, replacement: null });
108787
+ return;
108788
+ }
108789
+ const literal = literalValue(node.value);
108790
+ if (literal) {
108791
+ edits.push({ heading, node, parent, replacement: createTextNode(literal.value, node.position) });
108792
+ return;
108793
+ }
108794
+ if (canChangeHeadings(node, ancestors, heading))
108795
+ settled = false;
108796
+ });
108797
+ const apply = ({ node, parent, replacement }) => {
108798
+ parent.children.splice(parent.children.indexOf(node), 1, ...(replacement ? [replacement] : []));
108799
+ };
108800
+ // Comments go first: the hub strips them from the source, so the parser trims only the source
108801
+ // whitespace around them, never the spaces a literal adds.
108802
+ edits
108803
+ .filter(edit => !edit.replacement)
108804
+ .forEach(edit => {
108805
+ apply(edit);
108806
+ if (edit.heading)
108807
+ trimHeadingText(edit.heading);
108808
+ });
108809
+ edits.filter(edit => edit.replacement).forEach(apply);
108810
+ return settled;
108811
+ }
108812
+ /** Each heading's rendered anchor id, worked out without running code; `null` when code could change them. */
108813
+ function mdxishHeadingIds(tree, opts = {}) {
108814
+ const headings = collectHeadings(tree);
108815
+ if (headings.length === 0)
108816
+ return new Map();
108817
+ const copy = structuredClone(tree);
108818
+ let hasExport = false;
108819
+ visit(copy, 'mdxjsEsm', () => {
108820
+ hasExport = true;
108821
+ });
108822
+ // An `export` can define components that render headings.
108823
+ if (hasExport || hasEvaluatedHeadingAttribute(copy) || !settleExpressions(copy))
108824
+ return null;
108825
+ collectHeadings(copy).forEach((heading, index) => {
108826
+ heading.data = { ...heading.data, hProperties: { ...heading.data?.hProperties, [HEADING_INDEX]: index } };
108827
+ });
108828
+ const hast = mdxishRenderProcessor({ ...opts, safeMode: true }).runSync(copy, new VFile());
108829
+ const ids = new Map();
108830
+ visit(hast, 'element', (node) => {
108831
+ const index = node.properties[HEADING_INDEX];
108832
+ if (index === undefined || typeof node.properties.id !== 'string')
108833
+ return;
108834
+ ids.set(headings[Number(index)], node.properties.id);
108835
+ });
108836
+ return ids;
108837
+ }
108838
+
108597
108839
  ;// ./lib/extractToc.ts
108598
108840
 
108599
108841
  /* harmony default export */ const lib_extractToc = (extractToc);
@@ -109213,6 +109455,7 @@ async function stripComments(doc, { mdx, mdxish } = {}) {
109213
109455
 
109214
109456
 
109215
109457
 
109458
+
109216
109459
 
109217
109460
  ;// ./index.tsx
109218
109461
 
@@ -109509,7 +109752,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"*":["about","acceptCharset","accessK
109509
109752
  /******/ // startup
109510
109753
  /******/ // Load entry module and return exports
109511
109754
  /******/ // This entry module used 'module' so it can't be inlined
109512
- /******/ let __webpack_exports__ = __webpack_require__(714);
109755
+ /******/ let __webpack_exports__ = __webpack_require__(9477);
109513
109756
  /******/
109514
109757
  /******/ return __webpack_exports__;
109515
109758
  /******/ })()