eslint-plugin-markdown-preferences 0.26.1 → 0.27.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/README.md CHANGED
@@ -58,17 +58,18 @@ Example **eslint.config.js**:
58
58
  import { defineConfig } from "eslint/config";
59
59
  // import markdown from "@eslint/markdown";
60
60
  import markdownPreferences from "eslint-plugin-markdown-preferences";
61
- export default [
61
+ export default defineConfig([
62
62
  // add more generic rule sets here, such as:
63
63
  // markdown.configs.recommended,
64
64
  markdownPreferences.configs.recommended,
65
65
  {
66
+ files: ["**/*.md", "*.md"],
66
67
  rules: {
67
68
  // override/add rules settings here, such as:
68
69
  // 'markdown-preferences/prefer-linked-words': 'error'
69
70
  },
70
71
  },
71
- ];
72
+ ]);
72
73
  ```
73
74
 
74
75
  This plugin provides configs:
@@ -78,6 +79,49 @@ This plugin provides configs:
78
79
 
79
80
  See [the rule list](https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/) to get the `rules` that this plugin provides.
80
81
 
82
+ ##### Using Extended Syntax
83
+
84
+ This plugin experimentally supports some extended Markdown syntax.\
85
+ To use these extended syntaxes, set the `markdown-preferences/extended-syntax` language option.
86
+
87
+ ```js
88
+ import { defineConfig } from "eslint/config";
89
+ import markdownPreferences from "eslint-plugin-markdown-preferences";
90
+ export default defineConfig([
91
+ {
92
+ extends: [markdownPreferences.configs.recommended],
93
+ language: "markdown-preferences/extended-syntax",
94
+ },
95
+ ]);
96
+ ```
97
+
98
+ The following syntaxes are supported:
99
+
100
+ - [Custom Containers](https://vitepress.dev/guide/markdown#custom-containers)\
101
+ Example:
102
+
103
+ ```md
104
+ ::: warning
105
+ This is a warning box.
106
+ :::
107
+ ```
108
+
109
+ - [Mathematical Expressions](https://docs.github.com/get-started/writing-on-github/working-with-advanced-formatting/writing-mathematical-expressions)\
110
+ Example:
111
+
112
+ ```md
113
+ $$
114
+ E = mc^2
115
+ $$
116
+ ```
117
+
118
+ - [VitePress-style Import Code Snippets](https://vitepress.dev/guide/markdown#import-code-snippets) syntax using triple left angle brackets\
119
+ Example:
120
+
121
+ ```md
122
+ <<< @/filepath
123
+ ```
124
+
81
125
  #### Legacy Config (`.eslintrc`)
82
126
 
83
127
  Is not supported.
package/lib/index.d.ts CHANGED
@@ -1,7 +1,12 @@
1
1
  import markdown from "@eslint/markdown";
2
+ import * as math from "mdast-util-math";
2
3
  import * as _eslint_core0 from "@eslint/core";
3
- import { RuleDefinition } from "@eslint/core";
4
+ import { File, Language, OkParseResult, ParseResult, RuleDefinition, SourceLocation } from "@eslint/core";
4
5
  import { ESLint, Linter } from "eslint";
6
+ import * as eslint from "@eslint/markdown/types";
7
+ import { MarkdownLanguageContext, MarkdownLanguageOptions } from "@eslint/markdown/types";
8
+ import * as mdast from "mdast";
9
+ import { TextSourceCodeBase } from "@eslint/plugin-kit";
5
10
 
6
11
  //#region src/rule-types.d.ts
7
12
  declare module 'eslint' {
@@ -380,12 +385,12 @@ type MarkdownPreferencesOrderedListMarkerStyle = [] | [{
380
385
  }[];
381
386
  }];
382
387
  type MarkdownPreferencesPaddingLineBetweenBlocks = {
383
- prev: (("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "*") | [("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "*"), ...(("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "*"))[]] | {
384
- type: (("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "*") | [("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "*"), ...(("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "*"))[]]);
388
+ prev: (("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "custom-container" | "math" | "import-code-snippet" | "*") | [("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "custom-container" | "math" | "import-code-snippet" | "*"), ...(("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "custom-container" | "math" | "import-code-snippet" | "*"))[]] | {
389
+ type: (("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "custom-container" | "math" | "import-code-snippet" | "*") | [("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "custom-container" | "math" | "import-code-snippet" | "*"), ...(("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "custom-container" | "math" | "import-code-snippet" | "*"))[]]);
385
390
  in?: ("list" | "blockquote" | "footnote-definition");
386
391
  });
387
- next: (("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "*") | [("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "*"), ...(("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "*"))[]] | {
388
- type: (("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "*") | [("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "*"), ...(("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "*"))[]]);
392
+ next: (("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "custom-container" | "math" | "import-code-snippet" | "*") | [("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "custom-container" | "math" | "import-code-snippet" | "*"), ...(("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "custom-container" | "math" | "import-code-snippet" | "*"))[]] | {
393
+ type: (("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "custom-container" | "math" | "import-code-snippet" | "*") | [("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "custom-container" | "math" | "import-code-snippet" | "*"), ...(("blockquote" | "code" | "heading" | "html" | "list" | "paragraph" | "thematic-break" | "table" | "link-definition" | "footnote-definition" | "frontmatter" | "custom-container" | "math" | "import-code-snippet" | "*"))[]]);
389
394
  in?: ("list" | "blockquote" | "footnote-definition");
390
395
  });
391
396
  blankLine: ("any" | "never" | "always");
@@ -498,7 +503,161 @@ declare namespace meta_d_exports {
498
503
  export { name, version };
499
504
  }
500
505
  declare const name: "eslint-plugin-markdown-preferences";
501
- declare const version: "0.26.1";
506
+ declare const version: "0.27.0";
507
+ //#endregion
508
+ //#region src/language/ast-types.d.ts
509
+ type Node = mdast.Node;
510
+ type Root = ExtendChildren<mdast.Root, RootContent>;
511
+ type Blockquote = ExtendChildren<mdast.Blockquote, CustomContainer>;
512
+ type Break = mdast.Break;
513
+ type Code = mdast.Code;
514
+ type Definition = mdast.Definition;
515
+ type Delete = mdast.Delete;
516
+ type Emphasis = mdast.Emphasis;
517
+ type FootnoteDefinition = ExtendChildren<mdast.FootnoteDefinition, CustomContainer>;
518
+ type FootnoteReference = mdast.FootnoteReference;
519
+ type Heading = mdast.Heading;
520
+ type Html = mdast.Html;
521
+ type Image = mdast.Image;
522
+ type ImageReference = mdast.ImageReference;
523
+ type InlineCode = mdast.InlineCode;
524
+ type Link = mdast.Link;
525
+ type LinkReference = mdast.LinkReference;
526
+ type List = mdast.List;
527
+ type ListItem = ExtendChildren<mdast.ListItem, CustomContainer>;
528
+ type Paragraph = mdast.Paragraph;
529
+ type Strong = mdast.Strong;
530
+ type Table = mdast.Table;
531
+ type TableCell = mdast.TableCell;
532
+ type TableRow = mdast.TableRow;
533
+ type Text = mdast.Text;
534
+ type ThematicBreak = mdast.ThematicBreak;
535
+ type Yaml = mdast.Yaml;
536
+ type Math = math.Math;
537
+ type InlineMath = math.InlineMath;
538
+ type Toml = eslint.Toml;
539
+ type Json = eslint.Json;
540
+ interface CustomContainer extends ExtendChildren<mdast.Parent, CustomContainer | ImportCodeSnippet> {
541
+ /**
542
+ * Node type of mdast custom container.
543
+ */
544
+ type: "customContainer";
545
+ /**
546
+ * Info string (e.g., "warning" in ::: warning ... :::).
547
+ */
548
+ info: string | null;
549
+ /**
550
+ * Children of custom container.
551
+ */
552
+ children: (CustomContainer | BlockContent | DefinitionContent)[];
553
+ }
554
+ interface ImportCodeSnippet extends mdast.Literal {
555
+ /**
556
+ * Node type of mdast import code snippet.
557
+ */
558
+ type: "importCodeSnippet";
559
+ }
560
+ type RootContent = RootContentMap[keyof RootContentMap];
561
+ type BlockContent = RootContentMap[keyof mdast.BlockContentMap] | ImportCodeSnippet;
562
+ type DefinitionContent = RootContentMap[keyof mdast.DefinitionContentMap];
563
+ type ExtendChildren<N extends mdast.Node & {
564
+ children: mdast.Node[];
565
+ }, C extends mdast.Node> = Omit<N, "children"> & {
566
+ children: (MapChild<N["children"][number]> | C)[];
567
+ };
568
+ type MapChild<N extends mdast.Node> = N["type"] extends RootContent["type"] ? RootContentMap[N["type"]] : N;
569
+ interface RootContentMap {
570
+ blockquote: Blockquote;
571
+ break: Break;
572
+ code: Code;
573
+ definition: Definition;
574
+ delete: Delete;
575
+ emphasis: Emphasis;
576
+ footnoteDefinition: FootnoteDefinition;
577
+ footnoteReference: FootnoteReference;
578
+ heading: Heading;
579
+ html: Html;
580
+ image: Image;
581
+ imageReference: ImageReference;
582
+ inlineCode: InlineCode;
583
+ link: Link;
584
+ linkReference: LinkReference;
585
+ list: List;
586
+ listItem: ListItem;
587
+ paragraph: Paragraph;
588
+ strong: Strong;
589
+ table: Table;
590
+ tableCell: TableCell;
591
+ tableRow: TableRow;
592
+ text: Text;
593
+ thematicBreak: ThematicBreak;
594
+ yaml: Yaml;
595
+ toml: Toml;
596
+ json: Json;
597
+ customContainer: CustomContainer;
598
+ inlineMath: InlineMath;
599
+ math: Math;
600
+ importCodeSnippet: ImportCodeSnippet;
601
+ }
602
+ //#endregion
603
+ //#region src/language/extended-markdown-ianguage.d.ts
604
+ type ExtendedMarkdownSourceCode = TextSourceCodeBase<{
605
+ LangOptions: MarkdownLanguageOptions;
606
+ RootNode: Root;
607
+ SyntaxElementWithLoc: Node;
608
+ ConfigNode: {
609
+ value: string;
610
+ position: SourceLocation;
611
+ };
612
+ }>;
613
+ declare class ExtendedMarkdownLanguage implements Language {
614
+ /**
615
+ * The type of file to read.
616
+ * @type {"text"}
617
+ */
618
+ readonly fileType: "text";
619
+ /**
620
+ * The line number at which the parser starts counting.
621
+ * @type {0|1}
622
+ */
623
+ readonly lineStart: 0 | 1;
624
+ /**
625
+ * The column number at which the parser starts counting.
626
+ * @type {0|1}
627
+ */
628
+ readonly columnStart: 0 | 1;
629
+ /**
630
+ * The name of the key that holds the type of the node.
631
+ * @type {string}
632
+ */
633
+ readonly nodeTypeKey: string;
634
+ /**
635
+ * Default language options. User-defined options are merged with this object.
636
+ * @type {MarkdownLanguageOptions}
637
+ */
638
+ readonly defaultLanguageOptions: MarkdownLanguageOptions;
639
+ /**
640
+ * Validates the language options.
641
+ * @param {MarkdownLanguageOptions} languageOptions The language options to validate.
642
+ * @returns {void}
643
+ * @throws {Error} When the language options are invalid.
644
+ */
645
+ validateLanguageOptions(languageOptions: MarkdownLanguageOptions): void;
646
+ /**
647
+ * Parses the given file into an AST.
648
+ * @param {File} file The virtual file to parse.
649
+ * @param {MarkdownLanguageContext} _context The options to use for parsing.
650
+ * @returns {ParseResult<Root>} The result of parsing.
651
+ */
652
+ parse(file: File, _context: MarkdownLanguageContext): ParseResult<Root>;
653
+ /**
654
+ * Creates a new `MarkdownSourceCode` object from the given information.
655
+ * @param {File} file The virtual file to create a `MarkdownSourceCode` object from.
656
+ * @param {OkParseResult<Root>} parseResult The result returned from `parse()`.
657
+ * @returns {MarkdownSourceCode} The new `MarkdownSourceCode` object.
658
+ */
659
+ createSourceCode(file: File, parseResult: OkParseResult<Root>): ExtendedMarkdownSourceCode;
660
+ }
502
661
  //#endregion
503
662
  //#region src/index.d.ts
504
663
  declare const configs: {
@@ -510,8 +669,14 @@ declare const resources: {
510
669
  defaultPreserveWords: string[];
511
670
  defaultMinorWords: string[];
512
671
  };
672
+ declare const languages: {
673
+ "extended-syntax": ExtendedMarkdownLanguage;
674
+ };
513
675
  declare const _default: {
514
676
  meta: typeof meta_d_exports;
677
+ languages: {
678
+ "extended-syntax": ExtendedMarkdownLanguage;
679
+ };
515
680
  configs: {
516
681
  recommended: typeof recommended_d_exports;
517
682
  standard: typeof standard_d_exports;
@@ -523,4 +688,4 @@ declare const _default: {
523
688
  };
524
689
  };
525
690
  //#endregion
526
- export { RuleOptions, configs, _default as default, meta_d_exports as meta, resources, rules };
691
+ export { RuleOptions, configs, _default as default, languages, meta_d_exports as meta, resources, rules };
package/lib/index.js CHANGED
@@ -3,6 +3,16 @@ import stringWidth from "string-width";
3
3
  import emojiRegex from "emoji-regex-xs";
4
4
  import path from "node:path";
5
5
  import markdown from "@eslint/markdown";
6
+ import { fromMarkdown } from "mdast-util-from-markdown";
7
+ import { frontmatterFromMarkdown } from "mdast-util-frontmatter";
8
+ import { gfmFromMarkdown } from "mdast-util-gfm";
9
+ import { frontmatter } from "micromark-extension-frontmatter";
10
+ import { gfm } from "micromark-extension-gfm";
11
+ import { math } from "micromark-extension-math";
12
+ import { mathFromMarkdown } from "mdast-util-math";
13
+ import { markdownLineEnding, markdownSpace } from "micromark-util-character";
14
+ import { codes, constants, types } from "micromark-util-symbol";
15
+ import { factorySpace } from "micromark-factory-space";
6
16
 
7
17
  //#region src/utils/index.ts
8
18
  /**
@@ -957,14 +967,14 @@ var bullet_list_marker_style_default = createRule("bullet-list-marker-style", {
957
967
  if (node.ordered) return;
958
968
  checkBulletList(node);
959
969
  },
960
- "root, blockquote, listItem, footnoteDefinition"(node) {
970
+ "root, blockquote, listItem, footnoteDefinition, customContainer"(node) {
961
971
  containerStack = {
962
972
  node,
963
973
  level: node.type === "listItem" ? containerStack.level + 1 : 1,
964
974
  upper: containerStack
965
975
  };
966
976
  },
967
- "root, blockquote, listItem, footnoteDefinition:exit"() {
977
+ "root, blockquote, listItem, footnoteDefinition, customContainer:exit"() {
968
978
  containerStack = containerStack.upper;
969
979
  }
970
980
  };
@@ -1117,10 +1127,10 @@ var canonical_code_block_language_default = createRule("canonical-code-block-lan
1117
1127
  },
1118
1128
  create(context) {
1119
1129
  const sourceCode = context.sourceCode;
1120
- const languages = context.options[0]?.languages || DEFAULT_LANGUAGES;
1130
+ const languages$1 = context.options[0]?.languages || DEFAULT_LANGUAGES;
1121
1131
  return { code(node) {
1122
- if (!node.lang || !languages[node.lang]) return;
1123
- const canonical = languages[node.lang];
1132
+ if (!node.lang || !languages$1[node.lang]) return;
1133
+ const canonical = languages$1[node.lang];
1124
1134
  const current = node.lang;
1125
1135
  if (current === canonical) return;
1126
1136
  const parsed = parseFencedCodeBlock(sourceCode, node);
@@ -5296,6 +5306,108 @@ function parseListItem(sourceCode, node) {
5296
5306
  };
5297
5307
  }
5298
5308
 
5309
+ //#endregion
5310
+ //#region src/utils/math-block.ts
5311
+ /**
5312
+ * Parse the math block.
5313
+ */
5314
+ function parseMathBlock(sourceCode, node) {
5315
+ const range = sourceCode.getRange(node);
5316
+ const text = sourceCode.text.slice(...range);
5317
+ const parsedOpening = parseMathOpeningSequenceFromText(text);
5318
+ if (parsedOpening === null) return null;
5319
+ const openingSequenceRange = [range[0], range[0] + parsedOpening.openingSequence.length];
5320
+ const openingSequence = {
5321
+ text: parsedOpening.openingSequence,
5322
+ range: openingSequenceRange,
5323
+ loc: getSourceLocationFromRange(sourceCode, node, openingSequenceRange)
5324
+ };
5325
+ const parsedClosing = parseMathClosingSequenceFromText(text);
5326
+ if (parsedClosing == null) return null;
5327
+ const spaceAfterClosingRange = [range[1] - parsedClosing.after.length, range[1]];
5328
+ const spaceAfterClosing = {
5329
+ text: parsedClosing.after,
5330
+ range: spaceAfterClosingRange,
5331
+ loc: getSourceLocationFromRange(sourceCode, node, spaceAfterClosingRange)
5332
+ };
5333
+ const closingSequenceRange = [spaceAfterClosing.range[0] - parsedClosing.closingSequence.length, spaceAfterClosing.range[0]];
5334
+ const closingSequence = {
5335
+ text: parsedClosing.closingSequence,
5336
+ range: closingSequenceRange,
5337
+ loc: getSourceLocationFromRange(sourceCode, node, closingSequenceRange)
5338
+ };
5339
+ const contentRange = [openingSequence.range[1] + parsedOpening.after.length, closingSequence.range[0] - parsedClosing.before.length];
5340
+ const contentText = sourceCode.text.slice(...contentRange);
5341
+ return {
5342
+ openingSequence,
5343
+ content: {
5344
+ text: contentText,
5345
+ range: contentRange,
5346
+ loc: getSourceLocationFromRange(sourceCode, node, contentRange)
5347
+ },
5348
+ closingSequence,
5349
+ after: spaceAfterClosing.range[0] < spaceAfterClosing.range[1] ? spaceAfterClosing : null
5350
+ };
5351
+ }
5352
+ /**
5353
+ * Parse the opening sequence from a text string.
5354
+ */
5355
+ function parseMathOpeningSequenceFromText(text) {
5356
+ if (!text.startsWith("$")) return null;
5357
+ let openingSequenceAfterOffset = 1;
5358
+ while (openingSequenceAfterOffset < text.length && text[openingSequenceAfterOffset] === "$") openingSequenceAfterOffset++;
5359
+ const afterOffset = skipWhitespace(openingSequenceAfterOffset);
5360
+ if (afterOffset === openingSequenceAfterOffset || afterOffset >= text.length) return null;
5361
+ return {
5362
+ openingSequence: text.slice(0, openingSequenceAfterOffset),
5363
+ after: text.slice(openingSequenceAfterOffset, afterOffset)
5364
+ };
5365
+ /**
5366
+ * Skip whitespace characters at the start of the text.
5367
+ */
5368
+ function skipWhitespace(index) {
5369
+ let inIndent = false;
5370
+ let result = index;
5371
+ let c;
5372
+ while (result < text.length && (c = text[result]) && (isWhitespace(c) || inIndent && c === ">")) {
5373
+ result++;
5374
+ if (c === "\n") inIndent = true;
5375
+ else if (inIndent) inIndent = isWhitespace(c) || c === ">";
5376
+ }
5377
+ return result;
5378
+ }
5379
+ }
5380
+ /**
5381
+ * Parse the closing sequence from a text string.
5382
+ */
5383
+ function parseMathClosingSequenceFromText(text) {
5384
+ const trimmedEndOffset = skipEndWhitespace(text.length - 1) + 1;
5385
+ if (trimmedEndOffset <= 0 || text[trimmedEndOffset - 1] !== "$") return null;
5386
+ let closingSequenceBeforeOffset = trimmedEndOffset - 2;
5387
+ while (closingSequenceBeforeOffset >= 0 && text[closingSequenceBeforeOffset] === "$") closingSequenceBeforeOffset--;
5388
+ const beforeOffset = skipEndWhitespace(closingSequenceBeforeOffset);
5389
+ if (beforeOffset === closingSequenceBeforeOffset || beforeOffset < 0) return null;
5390
+ return {
5391
+ before: text.slice(beforeOffset + 1, closingSequenceBeforeOffset + 1),
5392
+ closingSequence: text.slice(closingSequenceBeforeOffset + 1, trimmedEndOffset),
5393
+ after: text.slice(trimmedEndOffset)
5394
+ };
5395
+ /**
5396
+ * Skip whitespace characters at the end of the text.
5397
+ */
5398
+ function skipEndWhitespace(index) {
5399
+ let result = index;
5400
+ let c;
5401
+ while (result >= 0 && (c = text[result]) && isWhitespace(c)) result--;
5402
+ if (c === ">") {
5403
+ let index2 = result - 1;
5404
+ while (index2 >= 0 && (c = text[index2]) && (isSpaceOrTab(c) || c === ">")) index2--;
5405
+ if (c === "\n") return skipEndWhitespace(index2);
5406
+ }
5407
+ return result;
5408
+ }
5409
+ }
5410
+
5299
5411
  //#endregion
5300
5412
  //#region src/rules/indent.ts
5301
5413
  /**
@@ -5575,7 +5687,10 @@ var indent_default = createRule("indent", {
5575
5687
  definition: verifyLinkDefinition,
5576
5688
  table: verifyTable,
5577
5689
  list: verifyList,
5578
- inlineCode: verifyInlineCode,
5690
+ customContainer: verifyCustomContainer,
5691
+ math: verifyMathBlock,
5692
+ importCodeSnippet: verifyImportCodeSnippet,
5693
+ inlineCode: verifyInlineCodeOrInlineMath,
5579
5694
  emphasis: verifyEmphasisOrStrongOrDelete,
5580
5695
  strong: verifyEmphasisOrStrongOrDelete,
5581
5696
  delete: verifyEmphasisOrStrongOrDelete,
@@ -5584,6 +5699,7 @@ var indent_default = createRule("indent", {
5584
5699
  footnoteReference: verifyInline,
5585
5700
  break: verifyInline,
5586
5701
  text: verifyText,
5702
+ inlineMath: verifyInlineCodeOrInlineMath,
5587
5703
  blockquote(node) {
5588
5704
  verifyBlockquote(node);
5589
5705
  blockStack = new BlockquoteStack(node);
@@ -5640,32 +5756,9 @@ var indent_default = createRule("indent", {
5640
5756
  verifyLinesIndent([loc.start.line, loc.end.line], (lineNumber) => blockStack.getExpectedIndent({
5641
5757
  lineNumber,
5642
5758
  block: true
5643
- }), additionalFixes);
5644
- /**
5645
- * Additional fixes for code block content lines.
5646
- */
5647
- function* additionalFixes(fixer, info) {
5648
- if (info.loc.start.line !== loc.start.line) return;
5649
- for (let lineNumber = loc.start.line + 1; lineNumber < loc.end.line; lineNumber++) {
5650
- const line = getParsedLines(sourceCode).get(lineNumber);
5651
- if (!line) continue;
5652
- if (info.expectedIndentWidth > info.actualIndentWidth) {
5653
- const before = sliceWidth(line.text, 0, info.actualIndentWidth);
5654
- const after = sliceWidth(line.text, info.actualIndentWidth);
5655
- const diffWidth = info.expectedIndentWidth - info.actualIndentWidth;
5656
- yield fixer.replaceTextRange([line.range[0], line.range[0] + line.text.length], before + " ".repeat(diffWidth) + after);
5657
- } else {
5658
- let before = sliceWidth(line.text, 0, info.expectedIndentWidth);
5659
- let between = sliceWidth(line.text, info.expectedIndentWidth, info.actualIndentWidth);
5660
- const after = sliceWidth(line.text, info.actualIndentWidth);
5661
- while (between && !isSpaceOrTab(between)) {
5662
- before += between[0];
5663
- between = between.slice(1);
5664
- }
5665
- yield fixer.replaceTextRange([line.range[0], line.range[0] + line.text.length], before + after);
5666
- }
5667
- }
5668
- }
5759
+ }), (fixer, info) => {
5760
+ return additionalFixesForCodeBlock(node, fixer, info, loc.start.line + 1, loc.end.line - 1);
5761
+ });
5669
5762
  }
5670
5763
  /**
5671
5764
  * Verify an HTML node.
@@ -5782,6 +5875,41 @@ var indent_default = createRule("indent", {
5782
5875
  }
5783
5876
  }
5784
5877
  /**
5878
+ * Verify a custom container node.
5879
+ */
5880
+ function verifyCustomContainer(node) {
5881
+ const loc = sourceCode.getLoc(node);
5882
+ verifyLinesIndent([loc.start.line, loc.end.line], (lineNumber) => blockStack.getExpectedIndent({
5883
+ lineNumber,
5884
+ block: true
5885
+ }));
5886
+ }
5887
+ /**
5888
+ * Verify a math node.
5889
+ */
5890
+ function verifyMathBlock(node) {
5891
+ const parsed = parseMathBlock(sourceCode, node);
5892
+ if (!parsed) return;
5893
+ const loc = sourceCode.getLoc(node);
5894
+ const endLineToBeChecked = inlineToBeChecked(parsed.closingSequence.loc.start);
5895
+ verifyLinesIndent(endLineToBeChecked ? [loc.start.line, loc.end.line] : [loc.start.line], (lineNumber) => blockStack.getExpectedIndent({
5896
+ lineNumber,
5897
+ block: true
5898
+ }), (fixer, info) => {
5899
+ return additionalFixesForCodeBlock(node, fixer, info, loc.start.line + 1, endLineToBeChecked ? loc.end.line - 1 : loc.end.line);
5900
+ });
5901
+ }
5902
+ /**
5903
+ * Verify an import code snippet node.
5904
+ */
5905
+ function verifyImportCodeSnippet(node) {
5906
+ const loc = sourceCode.getLoc(node);
5907
+ verifyLinesIndent(lineNumbersFromRange(loc.start.line, loc.end.line), (lineNumber) => blockStack.getExpectedIndent({
5908
+ lineNumber,
5909
+ block: true
5910
+ }));
5911
+ }
5912
+ /**
5785
5913
  * Verify a footnote definition node.
5786
5914
  */
5787
5915
  function verifyFootnoteDefinition(node) {
@@ -5792,9 +5920,9 @@ var indent_default = createRule("indent", {
5792
5920
  }));
5793
5921
  }
5794
5922
  /**
5795
- * Verify an inline code node.
5923
+ * Verify an inline code/math node.
5796
5924
  */
5797
- function verifyInlineCode(node) {
5925
+ function verifyInlineCodeOrInlineMath(node) {
5798
5926
  const loc = sourceCode.getLoc(node);
5799
5927
  if (!inlineToBeChecked(loc.start)) return;
5800
5928
  verifyLinesIndent([loc.start.line], (lineNumber) => blockStack.getExpectedIndent({
@@ -6176,6 +6304,32 @@ var indent_default = createRule("indent", {
6176
6304
  actualIndentWidth
6177
6305
  };
6178
6306
  }
6307
+ /**
6308
+ * Additional fixes for code/math block content lines.
6309
+ */
6310
+ function* additionalFixesForCodeBlock(node, fixer, info, fixStartLine, fixEndLine) {
6311
+ const loc = sourceCode.getLoc(node);
6312
+ if (info.loc.start.line !== loc.start.line) return;
6313
+ for (let lineNumber = fixStartLine; lineNumber <= fixEndLine; lineNumber++) {
6314
+ const line = getParsedLines(sourceCode).get(lineNumber);
6315
+ if (!line) continue;
6316
+ if (info.expectedIndentWidth > info.actualIndentWidth) {
6317
+ const before = sliceWidth(line.text, 0, info.actualIndentWidth);
6318
+ const after = sliceWidth(line.text, info.actualIndentWidth);
6319
+ const diffWidth = info.expectedIndentWidth - info.actualIndentWidth;
6320
+ yield fixer.replaceTextRange([line.range[0], line.range[0] + line.text.length], before + " ".repeat(diffWidth) + after);
6321
+ } else {
6322
+ let before = sliceWidth(line.text, 0, info.expectedIndentWidth);
6323
+ let between = sliceWidth(line.text, info.expectedIndentWidth, info.actualIndentWidth);
6324
+ const after = sliceWidth(line.text, info.actualIndentWidth);
6325
+ while (between && !isSpaceOrTab(between)) {
6326
+ before += between[0];
6327
+ between = between.slice(1);
6328
+ }
6329
+ yield fixer.replaceTextRange([line.range[0], line.range[0] + line.text.length], before + after);
6330
+ }
6331
+ }
6332
+ }
6179
6333
  }
6180
6334
  });
6181
6335
 
@@ -8312,14 +8466,14 @@ var ordered_list_marker_sequence_default = createRule("ordered-list-marker-seque
8312
8466
  }
8313
8467
  }
8314
8468
  return {
8315
- "blockquote, listItem, footnoteDefinition"(node) {
8469
+ "blockquote, listItem, footnoteDefinition, customContainer"(node) {
8316
8470
  scope = {
8317
8471
  node,
8318
8472
  upper: scope,
8319
8473
  last: null
8320
8474
  };
8321
8475
  },
8322
- "blockquote, listItem, footnoteDefinition:exit"(node) {
8476
+ "blockquote, listItem, footnoteDefinition, customContainer:exit"(node) {
8323
8477
  if (scope.node === node) scope = scope.upper;
8324
8478
  },
8325
8479
  heading() {
@@ -8401,14 +8555,14 @@ var ordered_list_marker_start_default = createRule("ordered-list-marker-start",
8401
8555
  });
8402
8556
  }
8403
8557
  return {
8404
- "blockquote, listItem, footnoteDefinition"(node) {
8558
+ "blockquote, listItem, footnoteDefinition, customContainer"(node) {
8405
8559
  scope = {
8406
8560
  node,
8407
8561
  upper: scope,
8408
8562
  last: null
8409
8563
  };
8410
8564
  },
8411
- "blockquote, listItem, footnoteDefinition:exit"(node) {
8565
+ "blockquote, listItem, footnoteDefinition, customContainer:exit"(node) {
8412
8566
  if (scope.node === node) scope = scope.upper;
8413
8567
  },
8414
8568
  heading() {
@@ -8581,14 +8735,14 @@ var ordered_list_marker_style_default = createRule("ordered-list-marker-style",
8581
8735
  if (!node.ordered) return;
8582
8736
  checkOrderedList(node);
8583
8737
  },
8584
- "root, blockquote, listItem, footnoteDefinition"(node) {
8738
+ "root, blockquote, listItem, footnoteDefinition, customContainer"(node) {
8585
8739
  containerStack = {
8586
8740
  node,
8587
8741
  level: node.type === "listItem" ? containerStack.level + 1 : 1,
8588
8742
  upper: containerStack
8589
8743
  };
8590
8744
  },
8591
- "root, blockquote, listItem, footnoteDefinition:exit"() {
8745
+ "root, blockquote, listItem, footnoteDefinition, customContainer:exit"() {
8592
8746
  containerStack = containerStack.upper;
8593
8747
  }
8594
8748
  };
@@ -8636,6 +8790,9 @@ const BLOCK_TYPES = [
8636
8790
  "link-definition",
8637
8791
  "footnote-definition",
8638
8792
  "frontmatter",
8793
+ "custom-container",
8794
+ "math",
8795
+ "import-code-snippet",
8639
8796
  "*"
8640
8797
  ];
8641
8798
  const BLOCK_TYPE_SCHEMAS = [{
@@ -8675,7 +8832,10 @@ const BLOCK_TYPE_MAP = {
8675
8832
  footnoteDefinition: "footnote-definition",
8676
8833
  json: "frontmatter",
8677
8834
  toml: "frontmatter",
8678
- yaml: "frontmatter"
8835
+ yaml: "frontmatter",
8836
+ customContainer: "custom-container",
8837
+ math: "math",
8838
+ importCodeSnippet: "import-code-snippet"
8679
8839
  };
8680
8840
  /**
8681
8841
  * Get the block type of a node
@@ -8871,10 +9031,10 @@ var padding_line_between_blocks_default = createRule("padding-line-between-block
8871
9031
  }
8872
9032
  }
8873
9033
  return {
8874
- "root, blockquote, listItem, footnoteDefinition"(node) {
9034
+ "root, blockquote, listItem, footnoteDefinition, customContainer"(node) {
8875
9035
  containerStack.unshift(node);
8876
9036
  },
8877
- "root, blockquote, listItem, footnoteDefinition:exit"(node) {
9037
+ "root, blockquote, listItem, footnoteDefinition, customContainer:exit"(node) {
8878
9038
  checkBlockPadding(node);
8879
9039
  containerStack.shift();
8880
9040
  }
@@ -11224,7 +11384,440 @@ var meta_exports = /* @__PURE__ */ __export({
11224
11384
  version: () => version
11225
11385
  });
11226
11386
  const name = "eslint-plugin-markdown-preferences";
11227
- const version = "0.26.1";
11387
+ const version = "0.27.0";
11388
+
11389
+ //#endregion
11390
+ //#region src/language/extensions/micromark-custom-container.ts
11391
+ /**
11392
+ * Micromark extension to support custom containers (e.g., ::: warning ... :::).
11393
+ */
11394
+ function customContainer() {
11395
+ const customContainerOpenConstruct = {
11396
+ name: "customContainer",
11397
+ continuation: {
11398
+ name: "customContainerContinuation",
11399
+ tokenize(effects, ok, nok) {
11400
+ return tokenizeCustomContainerContinuation(this, effects, ok, nok);
11401
+ }
11402
+ },
11403
+ exit(effects) {
11404
+ effects.exit("customContainer");
11405
+ },
11406
+ tokenize(effects, ok, nok) {
11407
+ return tokenizeCustomContainerOpen(this, effects, ok, nok);
11408
+ }
11409
+ };
11410
+ const customContainerCloseConstruct = {
11411
+ name: "customContainerCloseConstruct",
11412
+ tokenize(effects, ok, nok) {
11413
+ return tokenizeCustomContainerClose(this, effects, ok, nok);
11414
+ }
11415
+ };
11416
+ return { document: { [codes.colon]: customContainerOpenConstruct } };
11417
+ /**
11418
+ * Continuation tokenizer for the opening marker of the custom container.
11419
+ */
11420
+ function tokenizeCustomContainerOpen(self, effects, ok, nok) {
11421
+ let size = 0;
11422
+ let openToken;
11423
+ const infoCodes = [];
11424
+ return start;
11425
+ /**
11426
+ * Process start for the opening marker of the custom container.
11427
+ */
11428
+ function start(code) {
11429
+ if (code !== codes.colon) return nok(code);
11430
+ size = 0;
11431
+ openToken = effects.enter("customContainer", { _container: true });
11432
+ effects.enter("customContainerFence");
11433
+ effects.enter("customContainerFenceSequence");
11434
+ return sequence;
11435
+ }
11436
+ /**
11437
+ * Process sequence for the opening marker of the custom container.
11438
+ *
11439
+ * ```markdown
11440
+ * > | ::: info
11441
+ * ^
11442
+ * ```
11443
+ */
11444
+ function sequence(code) {
11445
+ if (code === codes.colon) {
11446
+ size++;
11447
+ effects.consume(code);
11448
+ return sequence;
11449
+ }
11450
+ if (size < 3) return nok(code);
11451
+ effects.exit("customContainerFenceSequence");
11452
+ return markdownSpace(code) ? factorySpace(effects, infoBefore, types.whitespace)(code) : infoBefore(code);
11453
+ }
11454
+ /**
11455
+ * Process before info for the opening marker of the custom container.
11456
+ *
11457
+ * ```markdown
11458
+ * > | ::: info
11459
+ * ^
11460
+ * ```
11461
+ */
11462
+ function infoBefore(code) {
11463
+ if (code === codes.eof || markdownLineEnding(code)) return nok(code);
11464
+ openToken._customContainer = { size };
11465
+ self.containerState._customContainer = { open: openToken };
11466
+ effects.enter("customContainerFenceInfo");
11467
+ effects.enter(types.chunkString, { contentType: constants.contentTypeString });
11468
+ infoCodes.length = 0;
11469
+ return info(code);
11470
+ }
11471
+ /**
11472
+ * Process info for the opening marker of the custom container.
11473
+ *
11474
+ * ```markdown
11475
+ * > | ::: info
11476
+ * ^
11477
+ * ```
11478
+ *
11479
+ * @type {State}
11480
+ */
11481
+ function info(code) {
11482
+ if (code === codes.eof || markdownLineEnding(code)) {
11483
+ effects.exit(types.chunkString);
11484
+ effects.exit("customContainerFenceInfo");
11485
+ effects.exit("customContainerFence");
11486
+ openToken._customContainer.info = String.fromCharCode(...infoCodes);
11487
+ return ok(code);
11488
+ }
11489
+ infoCodes.push(code);
11490
+ effects.consume(code);
11491
+ return info;
11492
+ }
11493
+ }
11494
+ /**
11495
+ * Continuation tokenizer for the closing marker of the custom container.
11496
+ */
11497
+ function tokenizeCustomContainerClose(self, effects, ok, nok) {
11498
+ let size = 0;
11499
+ return start;
11500
+ /**
11501
+ * Process start for the closing marker of the custom container.
11502
+ */
11503
+ function start(code) {
11504
+ if (code !== codes.colon) return nok(code);
11505
+ size = 0;
11506
+ effects.enter("customContainerFence");
11507
+ effects.enter("customContainerFenceSequence");
11508
+ return sequence;
11509
+ }
11510
+ /**
11511
+ * Process sequence for the closing marker of the custom container.
11512
+ *
11513
+ * ```markdown
11514
+ * > | :::
11515
+ * ```
11516
+ */
11517
+ function sequence(code) {
11518
+ if (code === codes.colon) {
11519
+ size++;
11520
+ effects.consume(code);
11521
+ return sequence;
11522
+ }
11523
+ if (size < 3) return nok(code);
11524
+ effects.exit("customContainerFenceSequence");
11525
+ return markdownSpace(code) ? factorySpace(effects, after, types.whitespace)(code) : after(code);
11526
+ }
11527
+ /**
11528
+ * Process after for the closing marker of the custom container.
11529
+ *
11530
+ * ```markdown
11531
+ * > | :::
11532
+ * ^
11533
+ * ```
11534
+ */
11535
+ function after(code) {
11536
+ if (code === codes.eof || markdownLineEnding(code)) {
11537
+ if (!self.containerState) throw new Error("containerState is undefined");
11538
+ const openToken = self.containerState._customContainer?.open;
11539
+ if (openToken?._customContainer?.size === size) {
11540
+ openToken._customContainer.closed = true;
11541
+ self.containerState._closeFlow = true;
11542
+ effects.exit("customContainerFence");
11543
+ return ok(code);
11544
+ }
11545
+ }
11546
+ return nok(code);
11547
+ }
11548
+ }
11549
+ /**
11550
+ * Continuation tokenizer for the custom container.
11551
+ */
11552
+ function tokenizeCustomContainerContinuation(self, effects, ok, nok) {
11553
+ if (self.containerState?._customContainer?.open?._customContainer?.closed) {
11554
+ self.containerState._closeFlow = true;
11555
+ return nok;
11556
+ }
11557
+ return start;
11558
+ /**
11559
+ * Process start for the custom container.
11560
+ */
11561
+ function start(code) {
11562
+ if (code !== codes.colon) return ok(code);
11563
+ return effects.attempt(customContainerCloseConstruct, () => {
11564
+ self.containerState._closeFlow = true;
11565
+ return ok;
11566
+ }, ok);
11567
+ }
11568
+ }
11569
+ }
11570
+
11571
+ //#endregion
11572
+ //#region src/language/extensions/mdast-custom-container.ts
11573
+ /**
11574
+ * Mdast extension to support custom containers (e.g., ::: warning ... :::).
11575
+ */
11576
+ function customContainerFromMarkdown() {
11577
+ return {
11578
+ enter: {
11579
+ customContainer(token) {
11580
+ this.enter({
11581
+ type: "customContainer",
11582
+ children: [],
11583
+ info: null
11584
+ }, token);
11585
+ },
11586
+ customContainerFenceInfo() {
11587
+ this.buffer();
11588
+ }
11589
+ },
11590
+ exit: {
11591
+ customContainer(token) {
11592
+ this.exit(token);
11593
+ },
11594
+ customContainerFenceInfo() {
11595
+ const data = this.resume();
11596
+ const node = this.stack[this.stack.length - 1];
11597
+ node.info = data;
11598
+ }
11599
+ }
11600
+ };
11601
+ }
11602
+
11603
+ //#endregion
11604
+ //#region src/language/extensions/micromark-import-code-snippet.ts
11605
+ /**
11606
+ * Micromark extension to support [VitePress-style Import Code Snippets](https://vitepress.dev/guide/markdown#import-code-snippets) syntax using triple left angle brackets.
11607
+ */
11608
+ function importCodeSnippet() {
11609
+ const importCodeSnippetConstruct = {
11610
+ name: "importCodeSnippet",
11611
+ tokenize(effects, ok, nok) {
11612
+ return tokenizeImportCodeSnippet(this, effects, ok, nok);
11613
+ }
11614
+ };
11615
+ return { flow: { [codes.lessThan]: importCodeSnippetConstruct } };
11616
+ /**
11617
+ * Tokenizer for the import code snippet.
11618
+ */
11619
+ function tokenizeImportCodeSnippet(_self, effects, ok, nok) {
11620
+ let size = 0;
11621
+ return start;
11622
+ /**
11623
+ * Process start for the opening marker of the import code snippet.
11624
+ */
11625
+ function start(code) {
11626
+ if (code !== codes.lessThan) return nok(code);
11627
+ size = 0;
11628
+ effects.enter("importCodeSnippet");
11629
+ effects.enter("importCodeSnippetMarkerSequence");
11630
+ return sequence(code);
11631
+ }
11632
+ /**
11633
+ * Process the sequence of opening markers for the import code snippet.
11634
+ *
11635
+ * ```markdown
11636
+ * > | <<< ./path/to/code.ts
11637
+ * ^^^
11638
+ * ```
11639
+ */
11640
+ function sequence(code) {
11641
+ if (code === codes.lessThan) {
11642
+ size++;
11643
+ effects.consume(code);
11644
+ return sequence;
11645
+ }
11646
+ if (size < 3) return nok(code);
11647
+ effects.exit("importCodeSnippetMarkerSequence");
11648
+ return markdownSpace(code) ? factorySpace(effects, afterMarker, types.whitespace)(code) : afterMarker(code);
11649
+ }
11650
+ /**
11651
+ * Process after the opening marker of the import code snippet.
11652
+ *
11653
+ * ```markdown
11654
+ * > | <<< ./path/to/code.ts
11655
+ * ^
11656
+ * ```
11657
+ */
11658
+ function afterMarker(code) {
11659
+ if (code === codes.eof || markdownLineEnding(code)) return nok(code);
11660
+ effects.enter("importCodeSnippetPath");
11661
+ effects.enter(types.chunkString, { contentType: constants.contentTypeString });
11662
+ return importPath(code);
11663
+ }
11664
+ /**
11665
+ * Process the path of the import code snippet.
11666
+ *
11667
+ * ```markdown
11668
+ * > | <<< ./path/to/code.ts
11669
+ * ^^^^^^^^^^^^^^^^^
11670
+ * ```
11671
+ */
11672
+ function importPath(code) {
11673
+ if (code === codes.eof || markdownLineEnding(code) || markdownSpace(code)) {
11674
+ effects.exit(types.chunkString);
11675
+ effects.exit("importCodeSnippetPath");
11676
+ effects.exit("importCodeSnippet");
11677
+ return afterPath(code);
11678
+ }
11679
+ effects.consume(code);
11680
+ return importPath;
11681
+ }
11682
+ /**
11683
+ * Process after the path of the import code snippet.
11684
+ *
11685
+ * ```markdown
11686
+ * > | <<< ./path/to/code.ts
11687
+ * ^
11688
+ * ```
11689
+ */
11690
+ function afterPath(code) {
11691
+ if (code === codes.eof || markdownLineEnding(code)) return ok(code);
11692
+ if (markdownSpace(code)) return factorySpace(effects, afterPath, types.whitespace)(code);
11693
+ return nok(code);
11694
+ }
11695
+ }
11696
+ }
11697
+
11698
+ //#endregion
11699
+ //#region src/language/extensions/mdast-import-code-snippet.ts
11700
+ /**
11701
+ * Mdast extension to support [VitePress-style Import Code Snippets](https://vitepress.dev/guide/markdown#import-code-snippets) syntax using triple left angle brackets.
11702
+ */
11703
+ function importCodeSnippetFromMarkdown() {
11704
+ return {
11705
+ enter: {
11706
+ importCodeSnippet(token) {
11707
+ this.enter({
11708
+ type: "importCodeSnippet",
11709
+ value: ""
11710
+ }, token);
11711
+ },
11712
+ importCodeSnippetPath() {
11713
+ this.buffer();
11714
+ }
11715
+ },
11716
+ exit: {
11717
+ importCodeSnippet(token) {
11718
+ this.exit(token);
11719
+ },
11720
+ importCodeSnippetPath() {
11721
+ const data = this.resume();
11722
+ const node = this.stack[this.stack.length - 1];
11723
+ node.value = data;
11724
+ }
11725
+ }
11726
+ };
11727
+ }
11728
+
11729
+ //#endregion
11730
+ //#region src/language/parser.ts
11731
+ /**
11732
+ * Parse Extended Markdown to MDAST.
11733
+ */
11734
+ function parseExtendedMarkdown(code) {
11735
+ const options = {
11736
+ extensions: [
11737
+ gfm(),
11738
+ frontmatter(["yaml", "toml"]),
11739
+ math(),
11740
+ customContainer(),
11741
+ importCodeSnippet()
11742
+ ],
11743
+ mdastExtensions: [
11744
+ gfmFromMarkdown(),
11745
+ frontmatterFromMarkdown(["yaml", "toml"]),
11746
+ mathFromMarkdown(),
11747
+ customContainerFromMarkdown(),
11748
+ importCodeSnippetFromMarkdown()
11749
+ ]
11750
+ };
11751
+ return fromMarkdown(code, options);
11752
+ }
11753
+
11754
+ //#endregion
11755
+ //#region src/language/extended-markdown-ianguage.ts
11756
+ var ExtendedMarkdownLanguage = class {
11757
+ /**
11758
+ * The type of file to read.
11759
+ * @type {"text"}
11760
+ */
11761
+ fileType = markdown.languages.gfm.fileType;
11762
+ /**
11763
+ * The line number at which the parser starts counting.
11764
+ * @type {0|1}
11765
+ */
11766
+ lineStart = markdown.languages.gfm.lineStart;
11767
+ /**
11768
+ * The column number at which the parser starts counting.
11769
+ * @type {0|1}
11770
+ */
11771
+ columnStart = markdown.languages.gfm.columnStart;
11772
+ /**
11773
+ * The name of the key that holds the type of the node.
11774
+ * @type {string}
11775
+ */
11776
+ nodeTypeKey = markdown.languages.gfm.nodeTypeKey;
11777
+ /**
11778
+ * Default language options. User-defined options are merged with this object.
11779
+ * @type {MarkdownLanguageOptions}
11780
+ */
11781
+ defaultLanguageOptions = markdown.languages.gfm.defaultLanguageOptions;
11782
+ /**
11783
+ * Validates the language options.
11784
+ * @param {MarkdownLanguageOptions} languageOptions The language options to validate.
11785
+ * @returns {void}
11786
+ * @throws {Error} When the language options are invalid.
11787
+ */
11788
+ validateLanguageOptions(languageOptions$2) {
11789
+ return markdown.languages.gfm.validateLanguageOptions(languageOptions$2);
11790
+ }
11791
+ /**
11792
+ * Parses the given file into an AST.
11793
+ * @param {File} file The virtual file to parse.
11794
+ * @param {MarkdownLanguageContext} _context The options to use for parsing.
11795
+ * @returns {ParseResult<Root>} The result of parsing.
11796
+ */
11797
+ parse(file, _context) {
11798
+ const text = file.body;
11799
+ try {
11800
+ return {
11801
+ ok: true,
11802
+ ast: parseExtendedMarkdown(text)
11803
+ };
11804
+ } catch (ex) {
11805
+ return {
11806
+ ok: false,
11807
+ errors: [ex]
11808
+ };
11809
+ }
11810
+ }
11811
+ /**
11812
+ * Creates a new `MarkdownSourceCode` object from the given information.
11813
+ * @param {File} file The virtual file to create a `MarkdownSourceCode` object from.
11814
+ * @param {OkParseResult<Root>} parseResult The result returned from `parse()`.
11815
+ * @returns {MarkdownSourceCode} The new `MarkdownSourceCode` object.
11816
+ */
11817
+ createSourceCode(file, parseResult) {
11818
+ return markdown.languages.gfm.createSourceCode(file, parseResult);
11819
+ }
11820
+ };
11228
11821
 
11229
11822
  //#endregion
11230
11823
  //#region src/index.ts
@@ -11240,12 +11833,14 @@ const resources = {
11240
11833
  defaultPreserveWords,
11241
11834
  defaultMinorWords
11242
11835
  };
11836
+ const languages = { "extended-syntax": new ExtendedMarkdownLanguage() };
11243
11837
  var src_default = {
11244
11838
  meta: meta_exports,
11839
+ languages,
11245
11840
  configs,
11246
11841
  rules,
11247
11842
  resources
11248
11843
  };
11249
11844
 
11250
11845
  //#endregion
11251
- export { configs, src_default as default, meta_exports as meta, resources, rules };
11846
+ export { configs, src_default as default, languages, meta_exports as meta, resources, rules };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-markdown-preferences",
3
- "version": "0.26.1",
3
+ "version": "0.27.0",
4
4
  "description": "ESLint plugin that enforces our markdown preferences",
5
5
  "type": "module",
6
6
  "exports": {
@@ -63,6 +63,16 @@
63
63
  },
64
64
  "dependencies": {
65
65
  "emoji-regex-xs": "^2.0.1",
66
+ "mdast-util-from-markdown": "^2.0.2",
67
+ "mdast-util-frontmatter": "^2.0.1",
68
+ "mdast-util-gfm": "^3.1.0",
69
+ "mdast-util-math": "^3.0.0",
70
+ "micromark-extension-frontmatter": "^2.0.0",
71
+ "micromark-extension-gfm": "^3.0.0",
72
+ "micromark-extension-math": "^3.1.0",
73
+ "micromark-factory-space": "^2.0.1",
74
+ "micromark-util-character": "^2.1.1",
75
+ "micromark-util-symbol": "^2.0.1",
66
76
  "string-width": "^8.0.0"
67
77
  },
68
78
  "devDependencies": {