@readme/markdown 14.11.2 → 14.11.3

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
@@ -96019,6 +96019,32 @@ const applyInserts = (html, inserts) => {
96019
96019
  return { value: out + html.slice(cursor), inserts: sorted };
96020
96020
  };
96021
96021
 
96022
+ ;// ./processor/transform/mdxish/tables/escape-stray-less-than.ts
96023
+
96024
+
96025
+ // A `<` only starts a JSX/HTML construct when followed by a tag-name start
96026
+ // (letter, `_`, `$`), a closer `/`, a fragment `>`, or a comment/declaration
96027
+ // `!`. Anything else (whitespace, EOL, a digit, …) is a literal `<` that acorn
96028
+ // rejects with "before name, expected a character that can start a name".
96029
+ const STRAY_LESS_THAN_RE = /<(?![a-zA-Z_$/>!])/g;
96030
+ /**
96031
+ * Escapes stray `<` characters that don't begin a valid tag so the strict mdxjs
96032
+ * parse treats them as literal text instead of throwing (`word <`, `a <1>`).
96033
+ *
96034
+ * Runs against the masked source so `<` inside code spans, legacy `<<var>>`
96035
+ * syntax, or already-escaped `\<` are left untouched.
96036
+ */
96037
+ const escapeStrayLessThan = (html) => {
96038
+ const masked = maskNonTagRegions(html);
96039
+ const inserts = [];
96040
+ STRAY_LESS_THAN_RE.lastIndex = 0;
96041
+ let match;
96042
+ while ((match = STRAY_LESS_THAN_RE.exec(masked)) !== null) {
96043
+ inserts.push({ offset: match.index, text: '\\' });
96044
+ }
96045
+ return applyInserts(html, inserts);
96046
+ };
96047
+
96022
96048
  ;// ./processor/transform/mdxish/tables/normalize-tag-spacing.ts
96023
96049
 
96024
96050
 
@@ -96518,6 +96544,7 @@ const repairUnclosedTags = (html) => {
96518
96544
 
96519
96545
 
96520
96546
 
96547
+
96521
96548
 
96522
96549
 
96523
96550
  const isTableCell = (node) => isMDXElement(node) && ['th', 'td'].includes(node.name);
@@ -96804,11 +96831,14 @@ const mdxishTables = () => tree => {
96804
96831
  // - normalizeTagSpacing: a line mixing text and an opening tag
96805
96832
  // (e.g. `text <div> \n <div> text`)
96806
96833
  // - repairExpressionEscapes: backslash escapes inside a `{…}` expression
96834
+ // - escapeStrayLessThan: a `<` that doesn't begin a valid tag
96835
+ // (e.g. `word <`, `a <1>`)
96807
96836
  // These repairs are created after seeing real customer content that has failed to parse
96808
96837
  const repairs = [
96809
96838
  repairUnclosedTags,
96810
96839
  normalizeTagSpacing,
96811
96840
  repairExpressionEscapes,
96841
+ escapeStrayLessThan,
96812
96842
  ];
96813
96843
  // Stops at the first repair that yields a parseable tree
96814
96844
  repairs.some(repair => {
@@ -118967,6 +118997,21 @@ function isActualHtmlTag(tagName, originalExcerpt) {
118967
118997
  return true;
118968
118998
  return false;
118969
118999
  }
119000
+ /**
119001
+ * Re-parsing a component's text child treats it as a standalone document, so
119002
+ * content that happens to start with the literal word `export`/`import`
119003
+ * (e.g. link text like "export Lorem Ipsum") sits at true column 1 and
119004
+ * gets mistaken for an MDX ESM statement, which then fails to parse as JS.
119005
+ * Fall back to `undefined` rather than letting one such child crash the page.
119006
+ */
119007
+ function tryProcessMarkdown(processMarkdown, content) {
119008
+ try {
119009
+ return processMarkdown(content);
119010
+ }
119011
+ catch {
119012
+ return undefined;
119013
+ }
119014
+ }
118970
119015
  /** Parse and replace text children with processed markdown */
118971
119016
  function parseTextChildren(node, processMarkdown, components) {
118972
119017
  if (!node.children?.length)
@@ -118981,7 +119026,9 @@ function parseTextChildren(node, processMarkdown, components) {
118981
119026
  node.properties = { ...node.properties, children: child.value };
118982
119027
  return [];
118983
119028
  }
118984
- const hast = processMarkdown(child.value.trim());
119029
+ const hast = tryProcessMarkdown(processMarkdown, child.value.trim());
119030
+ if (!hast)
119031
+ return [child];
118985
119032
  const children = (hast.children ?? []).filter(isElementContentNode);
118986
119033
  // For inline components, preserve plain text instead of wrapping in <p>
118987
119034
  if (INLINE_COMPONENT_TAGS_LOWER.has(node.tagName.toLowerCase()) && isSingleParagraphTextNode(children)) {
@@ -119055,8 +119102,9 @@ const rehypeMdxishComponents = ({ components, processMarkdown }) => {
119055
119102
  // rehypeRaw strips children from <img> (void element), so we must
119056
119103
  // re-process the caption here, after rehypeRaw.
119057
119104
  if (node.tagName === 'img' && typeof node.properties?.caption === 'string' && !node.children?.length) {
119058
- const captionHast = processMarkdown(node.properties.caption);
119059
- node.children = (captionHast.children ?? []).filter(isElementContentNode);
119105
+ const caption = node.properties.caption;
119106
+ const captionHast = tryProcessMarkdown(processMarkdown, caption);
119107
+ node.children = captionHast ? (captionHast.children ?? []).filter(isElementContentNode) : [{ type: 'text', value: caption }];
119060
119108
  }
119061
119109
  // Skip runtime components and standard HTML tags
119062
119110
  if (RUNTIME_COMPONENT_TAGS.has(node.tagName))
@@ -126607,6 +126655,332 @@ const mdxishTags_tags = (doc) => {
126607
126655
  };
126608
126656
  /* harmony default export */ const mdxishTags = (mdxishTags_tags);
126609
126657
 
126658
+ ;// ./lib/mdast-util/html-block-component/index.ts
126659
+ const html_block_component_contextMap = new WeakMap();
126660
+ function findHtmlBlockComponentToken() {
126661
+ const events = this.tokenStack;
126662
+ for (let i = events.length - 1; i >= 0; i -= 1) {
126663
+ if (events[i][0].type === 'htmlBlockComponent')
126664
+ return events[i][0];
126665
+ }
126666
+ return undefined;
126667
+ }
126668
+ function enterHtmlBlockComponent(token) {
126669
+ html_block_component_contextMap.set(token, { chunks: [], lastEndLine: token.start.line });
126670
+ this.enter({ type: 'html', value: '' }, token);
126671
+ }
126672
+ function exitHtmlBlockComponentData(token) {
126673
+ const componentToken = findHtmlBlockComponentToken.call(this);
126674
+ if (!componentToken)
126675
+ return;
126676
+ const ctx = html_block_component_contextMap.get(componentToken);
126677
+ if (ctx) {
126678
+ const gap = token.start.line - ctx.lastEndLine;
126679
+ if (ctx.chunks.length > 0 && gap > 0) {
126680
+ ctx.chunks.push('\n'.repeat(gap));
126681
+ }
126682
+ ctx.chunks.push(this.sliceSerialize(token));
126683
+ ctx.lastEndLine = token.end.line;
126684
+ }
126685
+ }
126686
+ function exitHtmlBlockComponent(token) {
126687
+ const ctx = html_block_component_contextMap.get(token);
126688
+ const node = this.stack[this.stack.length - 1];
126689
+ if (ctx) {
126690
+ node.value = ctx.chunks.join('');
126691
+ html_block_component_contextMap.delete(token);
126692
+ }
126693
+ this.exit(token);
126694
+ }
126695
+ function htmlBlockComponentFromMarkdown() {
126696
+ return {
126697
+ enter: {
126698
+ htmlBlockComponent: enterHtmlBlockComponent,
126699
+ },
126700
+ exit: {
126701
+ htmlBlockComponentData: exitHtmlBlockComponentData,
126702
+ htmlBlockComponent: exitHtmlBlockComponent,
126703
+ },
126704
+ };
126705
+ }
126706
+
126707
+ ;// ./lib/micromark/html-block-component/syntax.ts
126708
+
126709
+
126710
+ const TAG_SUFFIX = [
126711
+ codes.uppercaseT,
126712
+ codes.uppercaseM,
126713
+ codes.uppercaseL,
126714
+ codes.uppercaseB,
126715
+ codes.lowercaseL,
126716
+ codes.lowercaseO,
126717
+ codes.lowercaseC,
126718
+ codes.lowercaseK,
126719
+ ];
126720
+ // ---------------------------------------------------------------------------
126721
+ // Shared tokenizer factory
126722
+ // ---------------------------------------------------------------------------
126723
+ /**
126724
+ * Creates a tokenize function for `<HTMLBlock>...</HTMLBlock>`.
126725
+ *
126726
+ * - **flow** (block-level): supports multiline content via line continuations,
126727
+ * consumes trailing whitespace after the closing tag.
126728
+ * - **text** (inline): single-line only, exits immediately after the closing tag.
126729
+ */
126730
+ function syntax_createTokenize(mode) {
126731
+ return function tokenize(effects, ok, nok) {
126732
+ let depth = 1;
126733
+ function matchChars(chars, onMatch, onFail) {
126734
+ if (chars.length === 0)
126735
+ return onMatch;
126736
+ const next = (code) => {
126737
+ if (code === chars[0]) {
126738
+ effects.consume(code);
126739
+ return matchChars(chars.slice(1), onMatch, onFail);
126740
+ }
126741
+ return onFail(code);
126742
+ };
126743
+ return next;
126744
+ }
126745
+ function matchTagName(onMatch, onFail) {
126746
+ const next = (code) => {
126747
+ if (code === codes.uppercaseH) {
126748
+ effects.consume(code);
126749
+ return matchChars(TAG_SUFFIX, onMatch, onFail);
126750
+ }
126751
+ return onFail(code);
126752
+ };
126753
+ return next;
126754
+ }
126755
+ return start;
126756
+ function start(code) {
126757
+ if (code !== codes.lessThan)
126758
+ return nok(code);
126759
+ effects.enter('htmlBlockComponent');
126760
+ effects.enter('htmlBlockComponentData');
126761
+ effects.consume(code);
126762
+ return matchTagName(afterTagName, nok);
126763
+ }
126764
+ function afterTagName(code) {
126765
+ if (code === codes.greaterThan) {
126766
+ effects.consume(code);
126767
+ return body;
126768
+ }
126769
+ if (code === codes.space || code === codes.horizontalTab) {
126770
+ effects.consume(code);
126771
+ return inAttributes;
126772
+ }
126773
+ if (mode === 'flow' && markdownLineEnding(code)) {
126774
+ effects.exit('htmlBlockComponentData');
126775
+ return attributeContinuationStart(code);
126776
+ }
126777
+ if (code === codes.slash) {
126778
+ effects.consume(code);
126779
+ return selfClose;
126780
+ }
126781
+ return nok(code);
126782
+ }
126783
+ function inAttributes(code) {
126784
+ if (code === codes.greaterThan) {
126785
+ effects.consume(code);
126786
+ return body;
126787
+ }
126788
+ if (code === null) {
126789
+ return nok(code);
126790
+ }
126791
+ if (markdownLineEnding(code)) {
126792
+ if (mode === 'text')
126793
+ return nok(code);
126794
+ effects.exit('htmlBlockComponentData');
126795
+ return attributeContinuationStart(code);
126796
+ }
126797
+ effects.consume(code);
126798
+ return inAttributes;
126799
+ }
126800
+ function attributeContinuationStart(code) {
126801
+ return effects.check(html_block_component_syntax_nonLazyContinuationStart, attributeContinuationNonLazy, continuationAfter)(code);
126802
+ }
126803
+ function attributeContinuationNonLazy(code) {
126804
+ effects.enter(types_types.lineEnding);
126805
+ effects.consume(code);
126806
+ effects.exit(types_types.lineEnding);
126807
+ return attributeContinuationBefore;
126808
+ }
126809
+ function attributeContinuationBefore(code) {
126810
+ if (code === null || markdownLineEnding(code)) {
126811
+ return attributeContinuationStart(code);
126812
+ }
126813
+ effects.enter('htmlBlockComponentData');
126814
+ return inAttributes(code);
126815
+ }
126816
+ function selfClose(code) {
126817
+ if (code === codes.greaterThan) {
126818
+ effects.consume(code);
126819
+ return mode === 'flow' ? afterClose : done(code);
126820
+ }
126821
+ return nok(code);
126822
+ }
126823
+ function body(code) {
126824
+ if (code === null)
126825
+ return nok(code);
126826
+ if (markdownLineEnding(code)) {
126827
+ if (mode === 'text') {
126828
+ // Text constructs operate on paragraph content which spans lines
126829
+ effects.consume(code);
126830
+ return body;
126831
+ }
126832
+ effects.exit('htmlBlockComponentData');
126833
+ return continuationStart(code);
126834
+ }
126835
+ if (code === codes.lessThan) {
126836
+ effects.consume(code);
126837
+ return closeSlash;
126838
+ }
126839
+ effects.consume(code);
126840
+ return body;
126841
+ }
126842
+ function closeSlash(code) {
126843
+ if (code === codes.slash) {
126844
+ effects.consume(code);
126845
+ return matchTagName(closeGt, body);
126846
+ }
126847
+ return matchTagName(openAfterTagName, body)(code);
126848
+ }
126849
+ function openAfterTagName(code) {
126850
+ if (code === codes.greaterThan || code === codes.space || code === codes.horizontalTab) {
126851
+ depth += 1;
126852
+ effects.consume(code);
126853
+ return body;
126854
+ }
126855
+ return body(code);
126856
+ }
126857
+ function closeGt(code) {
126858
+ if (code === codes.greaterThan) {
126859
+ depth -= 1;
126860
+ effects.consume(code);
126861
+ if (depth === 0) {
126862
+ return mode === 'flow' ? afterClose : done(code);
126863
+ }
126864
+ return body;
126865
+ }
126866
+ return body(code);
126867
+ }
126868
+ // -- flow-only states ---------------------------------------------------
126869
+ function afterClose(code) {
126870
+ if (code === null || markdownLineEnding(code)) {
126871
+ return done(code);
126872
+ }
126873
+ if (code === codes.space || code === codes.horizontalTab) {
126874
+ effects.consume(code);
126875
+ return afterClose;
126876
+ }
126877
+ // Reject so the block re-parses as a paragraph, deferring to the
126878
+ // text tokenizer which preserves trailing content in the same line.
126879
+ return nok(code);
126880
+ }
126881
+ // -- flow-only: line continuation ---------------------------------------
126882
+ function continuationStart(code) {
126883
+ return effects.check(html_block_component_syntax_nonLazyContinuationStart, continuationStartNonLazy, continuationAfter)(code);
126884
+ }
126885
+ function continuationStartNonLazy(code) {
126886
+ effects.enter(types_types.lineEnding);
126887
+ effects.consume(code);
126888
+ effects.exit(types_types.lineEnding);
126889
+ return continuationBefore;
126890
+ }
126891
+ function continuationBefore(code) {
126892
+ if (code === null || markdownLineEnding(code)) {
126893
+ return continuationStart(code);
126894
+ }
126895
+ effects.enter('htmlBlockComponentData');
126896
+ return body(code);
126897
+ }
126898
+ function continuationAfter(code) {
126899
+ if (code === null)
126900
+ return nok(code);
126901
+ effects.exit('htmlBlockComponent');
126902
+ return ok(code);
126903
+ }
126904
+ // -- shared exit --------------------------------------------------------
126905
+ function done(_code) {
126906
+ effects.exit('htmlBlockComponentData');
126907
+ effects.exit('htmlBlockComponent');
126908
+ return ok(_code);
126909
+ }
126910
+ };
126911
+ }
126912
+ // ---------------------------------------------------------------------------
126913
+ // Flow construct (block-level)
126914
+ // ---------------------------------------------------------------------------
126915
+ const html_block_component_syntax_nonLazyContinuationStart = {
126916
+ tokenize: html_block_component_syntax_tokenizeNonLazyContinuationStart,
126917
+ partial: true,
126918
+ };
126919
+ function resolveToHtmlBlockComponent(events) {
126920
+ let index = events.length;
126921
+ while (index > 0) {
126922
+ index -= 1;
126923
+ if (events[index][0] === 'enter' && events[index][1].type === 'htmlBlockComponent') {
126924
+ break;
126925
+ }
126926
+ }
126927
+ if (index > 1 && events[index - 2][1].type === types_types.linePrefix) {
126928
+ events[index][1].start = events[index - 2][1].start;
126929
+ events[index + 1][1].start = events[index - 2][1].start;
126930
+ events.splice(index - 2, 2);
126931
+ }
126932
+ return events;
126933
+ }
126934
+ const htmlBlockComponentFlowConstruct = {
126935
+ name: 'htmlBlockComponent',
126936
+ tokenize: syntax_createTokenize('flow'),
126937
+ resolveTo: resolveToHtmlBlockComponent,
126938
+ concrete: true,
126939
+ };
126940
+ function html_block_component_syntax_tokenizeNonLazyContinuationStart(effects, ok, nok) {
126941
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
126942
+ const self = this;
126943
+ return start;
126944
+ function start(code) {
126945
+ if (markdownLineEnding(code)) {
126946
+ effects.enter(types_types.lineEnding);
126947
+ effects.consume(code);
126948
+ effects.exit(types_types.lineEnding);
126949
+ return after;
126950
+ }
126951
+ return nok(code);
126952
+ }
126953
+ function after(code) {
126954
+ if (self.parser.lazy[self.now().line]) {
126955
+ return nok(code);
126956
+ }
126957
+ return ok(code);
126958
+ }
126959
+ }
126960
+ // ---------------------------------------------------------------------------
126961
+ // Text construct (inline)
126962
+ // ---------------------------------------------------------------------------
126963
+ const htmlBlockComponentTextConstruct = {
126964
+ name: 'htmlBlockComponent',
126965
+ tokenize: syntax_createTokenize('text'),
126966
+ };
126967
+ // ---------------------------------------------------------------------------
126968
+ // Extension
126969
+ // ---------------------------------------------------------------------------
126970
+ function htmlBlockComponent() {
126971
+ return {
126972
+ flow: {
126973
+ [codes.lessThan]: [htmlBlockComponentFlowConstruct],
126974
+ },
126975
+ text: {
126976
+ [codes.lessThan]: [htmlBlockComponentTextConstruct],
126977
+ },
126978
+ };
126979
+ }
126980
+
126981
+ ;// ./lib/micromark/html-block-component/index.ts
126982
+
126983
+
126610
126984
  ;// ./lib/utils/extractMagicBlocks.ts
126611
126985
  /**
126612
126986
  * The content matching in this regex captures everything between `[block:TYPE]`
@@ -126673,19 +127047,22 @@ function restoreMagicBlocks(replaced, blocks) {
126673
127047
 
126674
127048
 
126675
127049
 
127050
+
127051
+
126676
127052
  /**
126677
127053
  * Removes Markdown and MDX comments.
126678
127054
  */
126679
127055
  async function stripComments(doc, { mdx, mdxish } = {}) {
126680
127056
  const { replaced, blocks } = extractMagicBlocks(doc);
126681
127057
  const processor = unified();
126682
- // we still require these two extensions because:
127058
+ // we still require these extensions because:
126683
127059
  // 1. we can rely on remarkMdx to parse MDXish
126684
127060
  // 2. we need to parse JSX comments into mdxTextExpression nodes so that the transformers can pick them up
127061
+ // 3. we need to claim <HTMLBlock> before htmlFlow intercepts its inner HTML tags
126685
127062
  if (mdxish) {
126686
127063
  processor
126687
- .data('micromarkExtensions', [jsxTable(), mdxExpression({ allowEmpty: true })])
126688
- .data('fromMarkdownExtensions', [jsxTableFromMarkdown(), mdxExpressionFromMarkdown()])
127064
+ .data('micromarkExtensions', [htmlBlockComponent(), jsxTable(), mdxExpression({ allowEmpty: true })])
127065
+ .data('fromMarkdownExtensions', [htmlBlockComponentFromMarkdown(), jsxTableFromMarkdown(), mdxExpressionFromMarkdown()])
126689
127066
  .data('toMarkdownExtensions', [mdxExpressionToMarkdown()]);
126690
127067
  }
126691
127068
  processor