eslint-plugin-markdown-preferences 0.27.0 → 0.28.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
@@ -175,6 +175,7 @@ The rules with the following 💄 are included in the `standard` config.
175
175
  | [markdown-preferences/level2-heading-style](https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/level2-heading-style.html) | enforce consistent style for level 2 headings | 🔧 | 💄 |
176
176
  | [markdown-preferences/link-destination-style](https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/link-destination-style.html) | enforce a consistent style for link destinations | 🔧 | 💄 |
177
177
  | [markdown-preferences/link-title-style](https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/link-title-style.html) | enforce a consistent style for link titles | 🔧 | 💄 |
178
+ | [markdown-preferences/no-implicit-block-closing](https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/no-implicit-block-closing.html) | disallow implicit block closing for fenced code blocks, math blocks, and custom blocks | 🔧 | ⭐💄 |
178
179
  | [markdown-preferences/no-text-backslash-linebreak](https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/no-text-backslash-linebreak.html) | disallow text backslash at the end of a line. | | ⭐💄 |
179
180
  | [markdown-preferences/ordered-list-marker-style](https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/ordered-list-marker-style.html) | enforce consistent ordered list marker style | 🔧 | 💄 |
180
181
  | [markdown-preferences/prefer-autolinks](https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/prefer-autolinks.html) | enforce the use of autolinks for URLs | 🔧 | ⭐💄 |
package/lib/index.d.ts CHANGED
@@ -125,6 +125,11 @@ interface RuleOptions {
125
125
  * @see https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/list-marker-alignment.html
126
126
  */
127
127
  'markdown-preferences/list-marker-alignment'?: Linter.RuleEntry<MarkdownPreferencesListMarkerAlignment>;
128
+ /**
129
+ * disallow implicit block closing for fenced code blocks, math blocks, and custom blocks
130
+ * @see https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/no-implicit-block-closing.html
131
+ */
132
+ 'markdown-preferences/no-implicit-block-closing'?: Linter.RuleEntry<[]>;
128
133
  /**
129
134
  * disallow laziness in blockquotes
130
135
  * @see https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/no-laziness-blockquotes.html
@@ -503,7 +508,7 @@ declare namespace meta_d_exports {
503
508
  export { name, version };
504
509
  }
505
510
  declare const name: "eslint-plugin-markdown-preferences";
506
- declare const version: "0.27.0";
511
+ declare const version: "0.28.0";
507
512
  //#endregion
508
513
  //#region src/language/ast-types.d.ts
509
514
  type Node = mdast.Node;
@@ -600,7 +605,7 @@ interface RootContentMap {
600
605
  importCodeSnippet: ImportCodeSnippet;
601
606
  }
602
607
  //#endregion
603
- //#region src/language/extended-markdown-ianguage.d.ts
608
+ //#region src/language/extended-markdown-language.d.ts
604
609
  type ExtendedMarkdownSourceCode = TextSourceCodeBase<{
605
610
  LangOptions: MarkdownLanguageOptions;
606
611
  RootNode: Root;
package/lib/index.js CHANGED
@@ -989,28 +989,14 @@ const RE_LANGUAGE = /^(\w*)/u;
989
989
  * Parse the fenced code block.
990
990
  */
991
991
  function parseFencedCodeBlock(sourceCode, node) {
992
+ if (getCodeBlockKind(sourceCode, node) === "indented") return null;
992
993
  const loc = sourceCode.getLoc(node);
993
994
  const range = sourceCode.getRange(node);
994
995
  const text = sourceCode.text.slice(...range);
995
996
  const match = RE_OPENING_FENCE.exec(text);
996
997
  if (!match) return null;
997
998
  const [, fenceText] = match;
998
- const fenceChar = fenceText[0];
999
- let closingFenceText = "";
1000
- const trimmed = text.trimEnd();
1001
- const trailingSpacesLength = text.length - trimmed.length;
1002
- for (let index = trimmed.length - 1; index >= 0; index--) {
1003
- const c = trimmed[index];
1004
- if (c === fenceChar || isSpaceOrTab(c)) {
1005
- closingFenceText = c + closingFenceText;
1006
- continue;
1007
- }
1008
- if (c === "\n") break;
1009
- return null;
1010
- }
1011
- closingFenceText = closingFenceText.trimStart();
1012
- if (!closingFenceText || !closingFenceText.startsWith(fenceText)) return null;
1013
- const afterOpeningFence = getParsedLines(sourceCode).get(loc.start.line).text.slice(fenceText.length);
999
+ const afterOpeningFence = sourceCode.lines[loc.start.line - 1].slice(loc.start.column - 1 + fenceText.length);
1014
1000
  const trimmedAfterOpeningFence = afterOpeningFence.trimStart();
1015
1001
  const spaceAfterOpeningFenceLength = afterOpeningFence.length - trimmedAfterOpeningFence.length;
1016
1002
  let languageText = "";
@@ -1019,45 +1005,49 @@ function parseFencedCodeBlock(sourceCode, node) {
1019
1005
  const trimmedAfterLanguage = afterLanguage.trimStart();
1020
1006
  const spaceAfterLanguageLength = afterLanguage.length - trimmedAfterLanguage.length;
1021
1007
  const metaText = trimmedAfterLanguage.trimEnd();
1008
+ const openingFenceRange = [range[0], range[0] + fenceText.length];
1022
1009
  const openingFence = {
1023
1010
  text: fenceText,
1024
- range: [range[0], range[0] + fenceText.length],
1025
- loc: {
1026
- start: loc.start,
1027
- end: {
1028
- line: loc.start.line,
1029
- column: loc.start.column + fenceText.length
1030
- }
1031
- }
1011
+ range: openingFenceRange,
1012
+ loc: getSourceLocationFromRange(sourceCode, node, openingFenceRange)
1032
1013
  };
1033
- const language$2 = languageText ? {
1014
+ const languageRange = languageText ? [openingFence.range[1] + spaceAfterOpeningFenceLength, openingFence.range[1] + spaceAfterOpeningFenceLength + languageText.length] : null;
1015
+ const language$2 = languageText && languageRange ? {
1034
1016
  text: languageText,
1035
- range: [openingFence.range[1] + spaceAfterOpeningFenceLength, openingFence.range[1] + spaceAfterOpeningFenceLength + languageText.length],
1036
- loc: {
1037
- start: {
1038
- line: openingFence.loc.end.line,
1039
- column: openingFence.loc.end.column + spaceAfterOpeningFenceLength
1040
- },
1041
- end: {
1042
- line: openingFence.loc.end.line,
1043
- column: openingFence.loc.end.column + spaceAfterOpeningFenceLength + languageText.length
1044
- }
1045
- }
1017
+ range: languageRange,
1018
+ loc: getSourceLocationFromRange(sourceCode, node, languageRange)
1046
1019
  } : null;
1047
- const meta = language$2 && metaText ? {
1020
+ const metaRange = language$2 && metaText ? [language$2.range[1] + spaceAfterLanguageLength, language$2.range[1] + spaceAfterLanguageLength + metaText.length] : null;
1021
+ const meta = language$2 && metaText && metaRange ? {
1048
1022
  text: metaText,
1049
- range: [language$2.range[1] + spaceAfterLanguageLength, language$2.range[1] + spaceAfterLanguageLength + metaText.length],
1050
- loc: {
1051
- start: {
1052
- line: language$2.loc.end.line,
1053
- column: language$2.loc.end.column + spaceAfterLanguageLength
1054
- },
1055
- end: {
1056
- line: language$2.loc.end.line,
1057
- column: language$2.loc.end.column + spaceAfterLanguageLength + metaText.length
1058
- }
1059
- }
1023
+ range: metaRange,
1024
+ loc: getSourceLocationFromRange(sourceCode, node, metaRange)
1060
1025
  } : null;
1026
+ const fenceChar = fenceText[0];
1027
+ let closingFenceText = "";
1028
+ const trimmed = text.trimEnd();
1029
+ const trailingSpacesLength = text.length - trimmed.length;
1030
+ for (let index = trimmed.length - 1; index >= 0; index--) {
1031
+ const c = trimmed[index];
1032
+ if (c === fenceChar || isSpaceOrTab(c)) {
1033
+ closingFenceText = c + closingFenceText;
1034
+ continue;
1035
+ }
1036
+ if (c === ">") {
1037
+ closingFenceText = ` ${closingFenceText}`;
1038
+ continue;
1039
+ }
1040
+ if (c === "\n") break;
1041
+ closingFenceText = "";
1042
+ break;
1043
+ }
1044
+ closingFenceText = closingFenceText.trimStart();
1045
+ if (!closingFenceText || !closingFenceText.startsWith(fenceText)) return {
1046
+ openingFence,
1047
+ language: language$2,
1048
+ meta,
1049
+ closingFence: null
1050
+ };
1061
1051
  return {
1062
1052
  openingFence,
1063
1053
  language: language$2,
@@ -1227,8 +1217,9 @@ var code_fence_length_default = createRule("code-fence-length", {
1227
1217
  actual: parsed.openingFence.text
1228
1218
  },
1229
1219
  messageId: "notPreferred",
1230
- fix(fixer) {
1231
- return [fixer.replaceTextRange(parsed.openingFence.range, expectedFence), fixer.replaceTextRange(parsed.closingFence.range, expectedFence)];
1220
+ *fix(fixer) {
1221
+ yield fixer.replaceTextRange(parsed.openingFence.range, expectedFence);
1222
+ if (parsed.closingFence) yield fixer.replaceTextRange(parsed.closingFence.range, expectedFence);
1232
1223
  }
1233
1224
  });
1234
1225
  }
@@ -1267,14 +1258,14 @@ var code_fence_length_default = createRule("code-fence-length", {
1267
1258
  /**
1268
1259
  * Verify that the opening and closing fence lengths match.
1269
1260
  */
1270
- function verifyClosingFenceLength(node, parsed) {
1271
- if (parsed.openingFence.text.length === parsed.closingFence.text.length) return true;
1261
+ function verifyClosingFenceLength(node, { openingFence, closingFence }) {
1262
+ if (!closingFence || openingFence.text.length === closingFence.text.length) return true;
1272
1263
  context.report({
1273
1264
  node,
1274
- loc: parsed.closingFence.loc,
1265
+ loc: closingFence.loc,
1275
1266
  messageId: "notMatch",
1276
1267
  fix(fixer) {
1277
- return [fixer.replaceTextRange(parsed.closingFence.range, parsed.openingFence.text)];
1268
+ return [fixer.replaceTextRange(closingFence.range, openingFence.text)];
1278
1269
  }
1279
1270
  });
1280
1271
  return false;
@@ -1327,8 +1318,9 @@ var code_fence_style_default = createRule("code-fence-style", {
1327
1318
  actual: parsed.openingFence.text
1328
1319
  },
1329
1320
  messageId: "useCodeFenceStyle",
1330
- fix(fixer) {
1331
- return [fixer.replaceTextRange(parsed.openingFence.range, expectedOpeningFence), fixer.replaceTextRange(parsed.closingFence.range, expectedChar.repeat(Math.max(3, parsed.closingFence.text.length)))];
1321
+ *fix(fixer) {
1322
+ yield fixer.replaceTextRange(parsed.openingFence.range, expectedOpeningFence);
1323
+ if (parsed.closingFence) yield fixer.replaceTextRange(parsed.closingFence.range, expectedChar.repeat(Math.max(3, parsed.closingFence.text.length)));
1332
1324
  }
1333
1325
  });
1334
1326
  } };
@@ -5323,7 +5315,19 @@ function parseMathBlock(sourceCode, node) {
5323
5315
  loc: getSourceLocationFromRange(sourceCode, node, openingSequenceRange)
5324
5316
  };
5325
5317
  const parsedClosing = parseMathClosingSequenceFromText(text);
5326
- if (parsedClosing == null) return null;
5318
+ if (parsedClosing == null || parsedClosing.closingSequence !== parsedOpening.openingSequence) {
5319
+ const contentRange$1 = [openingSequence.range[1] + parsedOpening.after.length, range[1]];
5320
+ return {
5321
+ openingSequence,
5322
+ content: {
5323
+ text: text.slice(parsedOpening.after.length),
5324
+ range: contentRange$1,
5325
+ loc: getSourceLocationFromRange(sourceCode, node, contentRange$1)
5326
+ },
5327
+ closingSequence: null,
5328
+ after: null
5329
+ };
5330
+ }
5327
5331
  const spaceAfterClosingRange = [range[1] - parsedClosing.after.length, range[1]];
5328
5332
  const spaceAfterClosing = {
5329
5333
  text: parsedClosing.after,
@@ -5891,7 +5895,7 @@ var indent_default = createRule("indent", {
5891
5895
  const parsed = parseMathBlock(sourceCode, node);
5892
5896
  if (!parsed) return;
5893
5897
  const loc = sourceCode.getLoc(node);
5894
- const endLineToBeChecked = inlineToBeChecked(parsed.closingSequence.loc.start);
5898
+ const endLineToBeChecked = parsed.closingSequence && inlineToBeChecked(parsed.closingSequence.loc.start);
5895
5899
  verifyLinesIndent(endLineToBeChecked ? [loc.start.line, loc.end.line] : [loc.start.line], (lineNumber) => blockStack.getExpectedIndent({
5896
5900
  lineNumber,
5897
5901
  block: true
@@ -7541,6 +7545,143 @@ var list_marker_alignment_default = createRule("list-marker-alignment", {
7541
7545
  }
7542
7546
  });
7543
7547
 
7548
+ //#endregion
7549
+ //#region src/utils/custom-container.ts
7550
+ const RE_OPENING_SEQUENCE = /^(:{3,})/u;
7551
+ /**
7552
+ * Parse the custom container.
7553
+ */
7554
+ function parseCustomContainer(sourceCode, node) {
7555
+ const loc = sourceCode.getLoc(node);
7556
+ const range = sourceCode.getRange(node);
7557
+ const text = sourceCode.text.slice(...range);
7558
+ const match = RE_OPENING_SEQUENCE.exec(text);
7559
+ if (!match) return null;
7560
+ const [, sequenceText] = match;
7561
+ const afterOpeningSequence = sourceCode.lines[loc.start.line - 1].slice(loc.start.column - 1 + sequenceText.length);
7562
+ const trimmedAfterOpeningSequence = afterOpeningSequence.trimStart();
7563
+ const spaceAfterOpeningSequenceLength = afterOpeningSequence.length - trimmedAfterOpeningSequence.length;
7564
+ const infoText = trimmedAfterOpeningSequence.trimEnd();
7565
+ if (!infoText) return null;
7566
+ const openingSequenceRange = [range[0], range[0] + sequenceText.length];
7567
+ const openingSequence = {
7568
+ text: sequenceText,
7569
+ range: openingSequenceRange,
7570
+ loc: getSourceLocationFromRange(sourceCode, node, openingSequenceRange)
7571
+ };
7572
+ const infoRange = [openingSequence.range[1] + spaceAfterOpeningSequenceLength, openingSequence.range[1] + spaceAfterOpeningSequenceLength + infoText.length];
7573
+ const info = {
7574
+ text: infoText,
7575
+ range: infoRange,
7576
+ loc: getSourceLocationFromRange(sourceCode, node, infoRange)
7577
+ };
7578
+ const sequenceChar = sequenceText[0];
7579
+ let closingSequenceText = "";
7580
+ const trimmed = text.trimEnd();
7581
+ const trailingSpacesLength = text.length - trimmed.length;
7582
+ for (let index = trimmed.length - 1; index >= 0; index--) {
7583
+ const c = trimmed[index];
7584
+ if (c === sequenceChar || isSpaceOrTab(c)) {
7585
+ closingSequenceText = c + closingSequenceText;
7586
+ continue;
7587
+ }
7588
+ if (c === ">") {
7589
+ closingSequenceText = ` ${closingSequenceText}`;
7590
+ continue;
7591
+ }
7592
+ if (c === "\n") break;
7593
+ closingSequenceText = "";
7594
+ break;
7595
+ }
7596
+ closingSequenceText = closingSequenceText.trimStart();
7597
+ if (!closingSequenceText || !closingSequenceText.startsWith(sequenceText)) return {
7598
+ openingSequence,
7599
+ info,
7600
+ closingSequence: null
7601
+ };
7602
+ const closingSequenceRange = [range[1] - trailingSpacesLength - closingSequenceText.length, range[1] - trailingSpacesLength];
7603
+ return {
7604
+ openingSequence,
7605
+ info,
7606
+ closingSequence: {
7607
+ text: closingSequenceText,
7608
+ range: closingSequenceRange,
7609
+ loc: getSourceLocationFromRange(sourceCode, node, closingSequenceRange)
7610
+ }
7611
+ };
7612
+ }
7613
+
7614
+ //#endregion
7615
+ //#region src/rules/no-implicit-block-closing.ts
7616
+ var no_implicit_block_closing_default = createRule("no-implicit-block-closing", {
7617
+ meta: {
7618
+ type: "suggestion",
7619
+ docs: {
7620
+ description: "disallow implicit block closing for fenced code blocks, math blocks, and custom blocks",
7621
+ categories: ["recommended", "standard"],
7622
+ listCategory: "Notation"
7623
+ },
7624
+ fixable: "code",
7625
+ hasSuggestions: false,
7626
+ schema: [],
7627
+ messages: {
7628
+ missingClosingFence: "Missing closing fence for fenced code block.",
7629
+ missingClosingMath: "Missing closing sequence for math block.",
7630
+ missingClosingContainer: "Missing closing sequence for custom container."
7631
+ }
7632
+ },
7633
+ create(context) {
7634
+ const sourceCode = context.sourceCode;
7635
+ return {
7636
+ code(node) {
7637
+ const parsed = parseFencedCodeBlock(sourceCode, node);
7638
+ if (!parsed) return;
7639
+ if (!parsed.closingFence) context.report({
7640
+ node,
7641
+ loc: parsed.openingFence.loc,
7642
+ messageId: "missingClosingFence",
7643
+ fix(fixer) {
7644
+ const openingLoc = parsed.openingFence.loc;
7645
+ const prefix = sourceCode.lines[openingLoc.start.line - 1].slice(0, openingLoc.start.column - 1).replace(/[^\s>]/gu, " ");
7646
+ const closingFence = parsed.openingFence.text;
7647
+ return fixer.insertTextAfter(node, `\n${prefix}${closingFence}`);
7648
+ }
7649
+ });
7650
+ },
7651
+ math(node) {
7652
+ const parsed = parseMathBlock(sourceCode, node);
7653
+ if (!parsed) return;
7654
+ if (!parsed.closingSequence) context.report({
7655
+ node,
7656
+ loc: parsed.openingSequence.loc,
7657
+ messageId: "missingClosingMath",
7658
+ fix(fixer) {
7659
+ const openingLoc = parsed.openingSequence.loc;
7660
+ const prefix = sourceCode.lines[openingLoc.start.line - 1].slice(0, openingLoc.start.column - 1).replace(/[^\s>]/gu, " ");
7661
+ const closingSequence = parsed.openingSequence.text;
7662
+ return fixer.insertTextAfter(node, `\n${prefix}${closingSequence}`);
7663
+ }
7664
+ });
7665
+ },
7666
+ customContainer(node) {
7667
+ const parsed = parseCustomContainer(sourceCode, node);
7668
+ if (!parsed) return;
7669
+ if (!parsed.closingSequence) context.report({
7670
+ node,
7671
+ loc: parsed.openingSequence.loc,
7672
+ messageId: "missingClosingContainer",
7673
+ fix(fixer) {
7674
+ const openingLoc = parsed.openingSequence.loc;
7675
+ const prefix = sourceCode.lines[openingLoc.start.line - 1].slice(0, openingLoc.start.column - 1).replace(/[^\s>]/gu, " ");
7676
+ const closingSequence = parsed.openingSequence.text;
7677
+ return fixer.insertTextAfter(node, `\n${prefix}${closingSequence}`);
7678
+ }
7679
+ });
7680
+ }
7681
+ };
7682
+ }
7683
+ });
7684
+
7544
7685
  //#endregion
7545
7686
  //#region src/rules/no-laziness-blockquotes.ts
7546
7687
  var no_laziness_blockquotes_default = createRule("no-laziness-blockquotes", {
@@ -7854,31 +7995,37 @@ var no_multi_spaces_default = createRule("no-multi-spaces", {
7854
7995
  const sourceCode = context.sourceCode;
7855
7996
  let codeText = sourceCode.text;
7856
7997
  return {
7998
+ customContainer: verifyCustomContainer,
7999
+ code: verifyCodeBlock,
7857
8000
  definition: verifyLinkDefinition,
7858
8001
  footnoteDefinition: verifyFootnoteDefinition,
7859
8002
  heading: verifyHeading,
7860
8003
  image: verifyImage,
7861
8004
  imageReference: verifyImageReference,
8005
+ inlineMath: verifyInlineMath,
7862
8006
  link: verifyLink,
7863
8007
  linkReference: verifyLinkReference,
7864
8008
  listItem: verifyListItem,
7865
- blockquote: processBlockquote,
8009
+ table: verifyTable,
7866
8010
  text: verifyText,
7867
- table: verifyTable
8011
+ math: verifyMathBlock,
8012
+ blockquote: processBlockquote
7868
8013
  };
7869
8014
  /**
7870
- * Verify a text node.
8015
+ * Verify a code block node.
7871
8016
  */
7872
- function verifyText(node) {
7873
- verifyTextInNode(node);
8017
+ function verifyCustomContainer(node) {
8018
+ const parsed = parseCustomContainer(sourceCode, node);
8019
+ if (!parsed) return;
8020
+ verifyTextInRange(node, [parsed.openingSequence.range[0], parsed.info.range[1]]);
7874
8021
  }
7875
8022
  /**
7876
- * Verify a table node.
8023
+ * Verify a code block node.
7877
8024
  */
7878
- function verifyTable(node) {
7879
- const parsedDelimiterRow = parseTableDelimiterRow(sourceCode, node);
7880
- if (!parsedDelimiterRow) return;
7881
- verifyTextInRange(node, parsedDelimiterRow.range);
8025
+ function verifyCodeBlock(node) {
8026
+ const parsed = parseFencedCodeBlock(sourceCode, node);
8027
+ if (!parsed) return;
8028
+ verifyTextInRange(node, [parsed.openingFence.range[0], (parsed.meta ?? parsed.language ?? parsed.openingFence).range[1]]);
7882
8029
  }
7883
8030
  /**
7884
8031
  * Verify a definition node.
@@ -7919,6 +8066,12 @@ var no_multi_spaces_default = createRule("no-multi-spaces", {
7919
8066
  verifyTextInNode(node);
7920
8067
  }
7921
8068
  /**
8069
+ * Verify an inline math node
8070
+ */
8071
+ function verifyInlineMath(node) {
8072
+ verifyTextInNode(node);
8073
+ }
8074
+ /**
7922
8075
  * Verify a link node
7923
8076
  */
7924
8077
  function verifyLink(node) {
@@ -7954,6 +8107,26 @@ var no_multi_spaces_default = createRule("no-multi-spaces", {
7954
8107
  codeText = newCodeText;
7955
8108
  }
7956
8109
  /**
8110
+ * Verify a table node.
8111
+ */
8112
+ function verifyTable(node) {
8113
+ const parsedDelimiterRow = parseTableDelimiterRow(sourceCode, node);
8114
+ if (!parsedDelimiterRow) return;
8115
+ verifyTextInRange(node, parsedDelimiterRow.range);
8116
+ }
8117
+ /**
8118
+ * Verify a text node.
8119
+ */
8120
+ function verifyText(node) {
8121
+ verifyTextInNode(node);
8122
+ }
8123
+ /**
8124
+ * Verify a math block node
8125
+ */
8126
+ function verifyMathBlock(node) {
8127
+ verifyTextInNode(node);
8128
+ }
8129
+ /**
7957
8130
  * Verify spaces in a node
7958
8131
  */
7959
8132
  function verifyTextInNode(node) {
@@ -11260,6 +11433,7 @@ const rules$1 = [
11260
11433
  link_paren_spacing_default,
11261
11434
  link_title_style_default,
11262
11435
  list_marker_alignment_default,
11436
+ no_implicit_block_closing_default,
11263
11437
  no_laziness_blockquotes_default,
11264
11438
  no_multi_spaces_default,
11265
11439
  no_multiple_empty_lines_default,
@@ -11310,6 +11484,7 @@ const rules$3 = {
11310
11484
  "markdown-preferences/blockquote-marker-alignment": "error",
11311
11485
  "markdown-preferences/hard-linebreak-style": "error",
11312
11486
  "markdown-preferences/list-marker-alignment": "error",
11487
+ "markdown-preferences/no-implicit-block-closing": "error",
11313
11488
  "markdown-preferences/no-laziness-blockquotes": "error",
11314
11489
  "markdown-preferences/no-text-backslash-linebreak": "error",
11315
11490
  "markdown-preferences/prefer-autolinks": "error",
@@ -11355,6 +11530,7 @@ const rules$2 = {
11355
11530
  "markdown-preferences/link-paren-spacing": "error",
11356
11531
  "markdown-preferences/link-title-style": "error",
11357
11532
  "markdown-preferences/list-marker-alignment": "error",
11533
+ "markdown-preferences/no-implicit-block-closing": "error",
11358
11534
  "markdown-preferences/no-laziness-blockquotes": "error",
11359
11535
  "markdown-preferences/no-multi-spaces": "error",
11360
11536
  "markdown-preferences/no-multiple-empty-lines": "error",
@@ -11384,7 +11560,7 @@ var meta_exports = /* @__PURE__ */ __export({
11384
11560
  version: () => version
11385
11561
  });
11386
11562
  const name = "eslint-plugin-markdown-preferences";
11387
- const version = "0.27.0";
11563
+ const version = "0.28.0";
11388
11564
 
11389
11565
  //#endregion
11390
11566
  //#region src/language/extensions/micromark-custom-container.ts
@@ -11752,7 +11928,7 @@ function parseExtendedMarkdown(code) {
11752
11928
  }
11753
11929
 
11754
11930
  //#endregion
11755
- //#region src/language/extended-markdown-ianguage.ts
11931
+ //#region src/language/extended-markdown-language.ts
11756
11932
  var ExtendedMarkdownLanguage = class {
11757
11933
  /**
11758
11934
  * The type of file to read.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-markdown-preferences",
3
- "version": "0.27.0",
3
+ "version": "0.28.0",
4
4
  "description": "ESLint plugin that enforces our markdown preferences",
5
5
  "type": "module",
6
6
  "exports": {