eslint-plugin-markdown-preferences 0.9.0 → 0.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/README.md CHANGED
@@ -50,7 +50,7 @@ Example **eslint.config.js**:
50
50
  ```js
51
51
  import { defineConfig } from "eslint/config";
52
52
  // import markdown from "@eslint/markdown";
53
- import markdownPreferences from 'eslint-plugin-markdown-preferences';
53
+ import markdownPreferences from "eslint-plugin-markdown-preferences";
54
54
  export default [
55
55
  // add more generic rule sets here, such as:
56
56
  // markdown.configs.recommended,
@@ -59,8 +59,8 @@ export default [
59
59
  rules: {
60
60
  // override/add rules settings here, such as:
61
61
  // 'markdown-preferences/prefer-linked-words': 'error'
62
- }
63
- }
62
+ },
63
+ },
64
64
  ];
65
65
  ```
66
66
 
@@ -86,6 +86,8 @@ The rules with the following star ⭐ are included in the configs.
86
86
 
87
87
  <!--RULES_TABLE_START-->
88
88
 
89
+ <!-- prettier-ignore-start -->
90
+
89
91
  ### Preference Rules
90
92
 
91
93
  | Rule ID | Description | Fixable | RECOMMENDED |
@@ -102,10 +104,14 @@ The rules with the following star ⭐ are included in the configs.
102
104
  | [markdown-preferences/definitions-last](https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/definitions-last.html) | require link definitions and footnote definitions to be placed at the end of the document | 🔧 | |
103
105
  | [markdown-preferences/hard-linebreak-style](https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/hard-linebreak-style.html) | enforce consistent hard linebreak style. | 🔧 | ⭐ |
104
106
  | [markdown-preferences/heading-casing](https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/heading-casing.html) | enforce consistent casing in headings. | 🔧 | |
107
+ | [markdown-preferences/no-laziness-blockquotes](https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/no-laziness-blockquotes.html) | disallow laziness in blockquotes | | ⭐ |
108
+ | [markdown-preferences/no-multiple-empty-lines](https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/no-multiple-empty-lines.html) | disallow multiple empty lines in Markdown files. | 🔧 | |
105
109
  | [markdown-preferences/no-trailing-spaces](https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/no-trailing-spaces.html) | disallow trailing whitespace at the end of lines in Markdown files. | 🔧 | |
106
110
  | [markdown-preferences/prefer-link-reference-definitions](https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/prefer-link-reference-definitions.html) | enforce using link reference definitions instead of inline links | 🔧 | |
107
111
  | [markdown-preferences/sort-definitions](https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/sort-definitions.html) | enforce a specific order for link definitions and footnote definitions | 🔧 | |
108
112
 
113
+ <!-- prettier-ignore-end -->
114
+
109
115
  <!--RULES_TABLE_END-->
110
116
  <!--RULES_SECTION_END-->
111
117
  <!--DOCS_IGNORE_START-->
package/lib/index.d.ts CHANGED
@@ -30,6 +30,16 @@ interface RuleOptions {
30
30
  * @see https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/heading-casing.html
31
31
  */
32
32
  'markdown-preferences/heading-casing'?: Linter.RuleEntry<MarkdownPreferencesHeadingCasing>;
33
+ /**
34
+ * disallow laziness in blockquotes
35
+ * @see https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/no-laziness-blockquotes.html
36
+ */
37
+ 'markdown-preferences/no-laziness-blockquotes'?: Linter.RuleEntry<[]>;
38
+ /**
39
+ * disallow multiple empty lines in Markdown files.
40
+ * @see https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/no-multiple-empty-lines.html
41
+ */
42
+ 'markdown-preferences/no-multiple-empty-lines'?: Linter.RuleEntry<MarkdownPreferencesNoMultipleEmptyLines>;
33
43
  /**
34
44
  * disallow text backslash at the end of a line.
35
45
  * @see https://ota-meshi.github.io/eslint-plugin-markdown-preferences/rules/no-text-backslash-linebreak.html
@@ -75,6 +85,11 @@ type MarkdownPreferencesHeadingCasing = [] | [{
75
85
  ignorePatterns?: string[];
76
86
  minorWords?: string[];
77
87
  }];
88
+ type MarkdownPreferencesNoMultipleEmptyLines = [] | [{
89
+ max?: number;
90
+ maxEOF?: number;
91
+ maxBOF?: number;
92
+ }];
78
93
  type MarkdownPreferencesNoTrailingSpaces = [] | [{
79
94
  skipBlankLines?: boolean;
80
95
  ignoreComments?: boolean;
@@ -128,7 +143,7 @@ declare namespace meta_d_exports {
128
143
  export { name, version };
129
144
  }
130
145
  declare const name: "eslint-plugin-markdown-preferences";
131
- declare const version: "0.9.0";
146
+ declare const version: "0.10.0";
132
147
  //#endregion
133
148
  //#region src/index.d.ts
134
149
  declare const configs: {
package/lib/index.js CHANGED
@@ -978,6 +978,333 @@ var heading_casing_default = createRule("heading-casing", {
978
978
  }
979
979
  });
980
980
 
981
+ //#endregion
982
+ //#region src/utils/lines.ts
983
+ const cache = /* @__PURE__ */ new WeakMap();
984
+ var ParsedLines = class {
985
+ lines;
986
+ constructor(codeText) {
987
+ let offset = 0;
988
+ this.lines = codeText.split(/(?<=\n)/u).map((lineText, index) => {
989
+ const start = offset;
990
+ offset += lineText.length;
991
+ const range = [start, offset];
992
+ let text = lineText;
993
+ let linebreak = "";
994
+ if (text.at(-1) === "\n") {
995
+ text = text.slice(0, -1);
996
+ linebreak = "\n";
997
+ }
998
+ if (text.at(-1) === "\r") {
999
+ text = text.slice(0, -1);
1000
+ linebreak = `\r${linebreak}`;
1001
+ }
1002
+ return {
1003
+ text,
1004
+ range,
1005
+ line: index + 1,
1006
+ linebreak
1007
+ };
1008
+ });
1009
+ }
1010
+ [Symbol.iterator]() {
1011
+ return this.lines[Symbol.iterator]();
1012
+ }
1013
+ get length() {
1014
+ return this.lines.length;
1015
+ }
1016
+ get(lineNumber) {
1017
+ return this.lines[lineNumber - 1];
1018
+ }
1019
+ };
1020
+ /**
1021
+ * Parse the lines of the source code.
1022
+ * @param sourceCode source code to parse
1023
+ * @returns parsed lines
1024
+ */
1025
+ function parseLines(sourceCode) {
1026
+ const cached = cache.get(sourceCode);
1027
+ if (cached) return cached;
1028
+ const parsedLines = new ParsedLines(sourceCode.text);
1029
+ cache.set(sourceCode, parsedLines);
1030
+ return parsedLines;
1031
+ }
1032
+
1033
+ //#endregion
1034
+ //#region src/rules/no-laziness-blockquotes.ts
1035
+ /**
1036
+ * Helper function to get blockquote line information.
1037
+ */
1038
+ function getBlockquoteLineInfo(line) {
1039
+ const regex = /^\s*(?:>\s*)*/u;
1040
+ const match = regex.exec(line.text);
1041
+ return {
1042
+ line,
1043
+ prefix: match[0],
1044
+ level: (match[0].match(/>/gu) || []).length
1045
+ };
1046
+ }
1047
+ var no_laziness_blockquotes_default = createRule("no-laziness-blockquotes", {
1048
+ meta: {
1049
+ type: "problem",
1050
+ docs: {
1051
+ description: "disallow laziness in blockquotes",
1052
+ categories: ["recommended"],
1053
+ listCategory: "Stylistic"
1054
+ },
1055
+ fixable: void 0,
1056
+ hasSuggestions: true,
1057
+ schema: [],
1058
+ messages: {
1059
+ lazyBlockquoteLine: "Expected {{level}} '>' marker(s), but found {{actualLevel}}. This line will be interpreted as part of level {{level}} blockquote.",
1060
+ addMarker: "Add {{missingMarkers}} '>' marker(s).",
1061
+ addLineBreak: "Add line break to separate from blockquote."
1062
+ }
1063
+ },
1064
+ create(context) {
1065
+ const sourceCode = context.sourceCode;
1066
+ const checkedLines = /* @__PURE__ */ new Set();
1067
+ const lines = parseLines(sourceCode);
1068
+ /**
1069
+ * Report invalid blockquote lines.
1070
+ */
1071
+ function reportInvalidLines(invalidLines, base) {
1072
+ const invalidGroups = [];
1073
+ for (const invalidLine of invalidLines) {
1074
+ const currentGroup = invalidGroups.at(-1);
1075
+ if (!currentGroup || currentGroup.level < invalidLine.level) {
1076
+ invalidGroups.push({
1077
+ level: invalidLine.level,
1078
+ lines: [invalidLine]
1079
+ });
1080
+ continue;
1081
+ }
1082
+ if (currentGroup.level === invalidLine.level) {
1083
+ currentGroup.lines.push(invalidLine);
1084
+ continue;
1085
+ }
1086
+ if (invalidLine.level < currentGroup.level) break;
1087
+ }
1088
+ for (const group of invalidGroups) {
1089
+ const first = group.lines[0];
1090
+ const last = group.lines.at(-1);
1091
+ context.report({
1092
+ loc: {
1093
+ start: {
1094
+ line: first.line.line,
1095
+ column: 1
1096
+ },
1097
+ end: {
1098
+ line: last.line.line,
1099
+ column: last.line.text.length + 1
1100
+ }
1101
+ },
1102
+ messageId: "lazyBlockquoteLine",
1103
+ data: {
1104
+ level: `${base.level}`,
1105
+ actualLevel: `${group.level}`
1106
+ },
1107
+ suggest: [{
1108
+ messageId: "addMarker",
1109
+ data: { missingMarkers: `${base.level - group.level}` },
1110
+ *fix(fixer) {
1111
+ for (const invalidLine of group.lines) yield fixer.replaceTextRange([invalidLine.line.range[0], invalidLine.line.range[0] + invalidLine.prefix.length], base.prefix);
1112
+ }
1113
+ }, {
1114
+ messageId: "addLineBreak",
1115
+ fix: (fixer) => {
1116
+ return fixer.insertTextBeforeRange([first.line.range[0], first.line.range[0]], `${first.prefix.trimEnd()}\n`);
1117
+ }
1118
+ }]
1119
+ });
1120
+ }
1121
+ }
1122
+ return { "blockquote:exit"(node) {
1123
+ const loc = sourceCode.getLoc(node);
1124
+ const startLine = loc.start.line;
1125
+ const endLine = loc.end.line;
1126
+ const base = getBlockquoteLineInfo(lines.get(startLine));
1127
+ const invalidLines = [];
1128
+ for (let lineNumber = startLine + 1; lineNumber <= endLine; lineNumber++) {
1129
+ if (checkedLines.has(lineNumber)) {
1130
+ reportInvalidLines(invalidLines, base);
1131
+ invalidLines.length = 0;
1132
+ continue;
1133
+ }
1134
+ checkedLines.add(lineNumber);
1135
+ const line = lines.get(lineNumber);
1136
+ const current = getBlockquoteLineInfo(line);
1137
+ if (base.level <= current.level) {
1138
+ reportInvalidLines(invalidLines, base);
1139
+ invalidLines.length = 0;
1140
+ continue;
1141
+ }
1142
+ invalidLines.push(current);
1143
+ }
1144
+ reportInvalidLines(invalidLines, base);
1145
+ } };
1146
+ }
1147
+ });
1148
+
1149
+ //#endregion
1150
+ //#region src/rules/no-multiple-empty-lines.ts
1151
+ var no_multiple_empty_lines_default = createRule("no-multiple-empty-lines", {
1152
+ meta: {
1153
+ type: "layout",
1154
+ docs: {
1155
+ description: "disallow multiple empty lines in Markdown files.",
1156
+ categories: null,
1157
+ listCategory: "Stylistic"
1158
+ },
1159
+ fixable: "whitespace",
1160
+ hasSuggestions: false,
1161
+ schema: [{
1162
+ type: "object",
1163
+ properties: {
1164
+ max: {
1165
+ type: "integer",
1166
+ minimum: 0,
1167
+ default: 1
1168
+ },
1169
+ maxEOF: {
1170
+ type: "integer",
1171
+ minimum: 0,
1172
+ default: 0
1173
+ },
1174
+ maxBOF: {
1175
+ type: "integer",
1176
+ minimum: 0,
1177
+ default: 0
1178
+ }
1179
+ },
1180
+ additionalProperties: false
1181
+ }],
1182
+ messages: {
1183
+ blankBeginningOfFile: "Too many blank lines at the beginning of file. Max of {{max}} allowed.",
1184
+ blankEndOfFile: "Too many blank lines at the end of file. Max of {{max}} allowed.",
1185
+ consecutiveBlank: "More than {{max}} blank {{pluralizedLines}} not allowed."
1186
+ }
1187
+ },
1188
+ create(context) {
1189
+ const sourceCode = context.sourceCode;
1190
+ const option = context.options[0] || {};
1191
+ const max = typeof option.max === "number" ? option.max : 1;
1192
+ const maxEOF = typeof option.maxEOF === "number" ? option.maxEOF : 0;
1193
+ const maxBOF = typeof option.maxBOF === "number" ? option.maxBOF : 0;
1194
+ const ignoreLocs = [];
1195
+ /**
1196
+ * Register the range of nodes to ignore (code, html, yaml, toml, json)
1197
+ * @param node mdast node
1198
+ */
1199
+ function addIgnoreLoc(node) {
1200
+ const loc = sourceCode.getLoc(node);
1201
+ ignoreLocs.push({
1202
+ startLine: loc.start.line,
1203
+ endLine: loc.end.line
1204
+ });
1205
+ }
1206
+ return {
1207
+ code: addIgnoreLoc,
1208
+ html: addIgnoreLoc,
1209
+ yaml: addIgnoreLoc,
1210
+ toml: addIgnoreLoc,
1211
+ json: addIgnoreLoc,
1212
+ "root:exit"() {
1213
+ const lines = [...parseLines(sourceCode)];
1214
+ const bofEmptyLines = [];
1215
+ while (lines.length) {
1216
+ if (lines[0].text.trim()) break;
1217
+ bofEmptyLines.push(lines.shift());
1218
+ }
1219
+ const invalidBOFEmptyLines = bofEmptyLines.slice(maxBOF);
1220
+ if (invalidBOFEmptyLines.length > 0) {
1221
+ const first = invalidBOFEmptyLines[0];
1222
+ const last = invalidBOFEmptyLines[invalidBOFEmptyLines.length - 1];
1223
+ context.report({
1224
+ loc: {
1225
+ start: {
1226
+ line: first.line,
1227
+ column: 1
1228
+ },
1229
+ end: {
1230
+ line: last.line,
1231
+ column: last.text.length + 1
1232
+ }
1233
+ },
1234
+ messageId: "blankBeginningOfFile",
1235
+ data: { max: maxBOF },
1236
+ fix(fixer) {
1237
+ return fixer.removeRange([first.range[0], last.range[1]]);
1238
+ }
1239
+ });
1240
+ }
1241
+ const eofEmptyLines = [];
1242
+ while (lines.length) {
1243
+ if (lines[lines.length - 1].text.trim()) break;
1244
+ eofEmptyLines.unshift(lines.pop());
1245
+ }
1246
+ const invalidEOFEmptyLines = eofEmptyLines.slice(maxEOF);
1247
+ if (invalidEOFEmptyLines.length > 0) {
1248
+ const first = invalidEOFEmptyLines[0];
1249
+ const last = invalidEOFEmptyLines[invalidEOFEmptyLines.length - 1];
1250
+ context.report({
1251
+ loc: {
1252
+ start: {
1253
+ line: first.line,
1254
+ column: 1
1255
+ },
1256
+ end: {
1257
+ line: last.line,
1258
+ column: last.text.length + 1
1259
+ }
1260
+ },
1261
+ messageId: "blankEndOfFile",
1262
+ data: { max: maxEOF },
1263
+ fix(fixer) {
1264
+ return fixer.removeRange([first.range[0], last.range[1]]);
1265
+ }
1266
+ });
1267
+ }
1268
+ const emptyLines = [];
1269
+ for (const lineInfo of lines) {
1270
+ if (!lineInfo.text.trim() && !ignoreLocs.some(({ startLine, endLine }) => {
1271
+ return lineInfo.line > startLine && lineInfo.line < endLine;
1272
+ })) {
1273
+ emptyLines.push(lineInfo);
1274
+ continue;
1275
+ }
1276
+ const invalidEmptyLines = emptyLines.slice(max);
1277
+ emptyLines.length = 0;
1278
+ if (invalidEmptyLines.length) {
1279
+ const first = invalidEmptyLines[0];
1280
+ const last = invalidEmptyLines[invalidEmptyLines.length - 1];
1281
+ context.report({
1282
+ loc: {
1283
+ start: {
1284
+ line: first.line,
1285
+ column: 1
1286
+ },
1287
+ end: {
1288
+ line: last.line,
1289
+ column: last.text.length + 1
1290
+ }
1291
+ },
1292
+ messageId: "consecutiveBlank",
1293
+ data: {
1294
+ max,
1295
+ pluralizedLines: max === 1 ? "line" : "lines"
1296
+ },
1297
+ fix(fixer) {
1298
+ return fixer.removeRange([first.range[0], last.range[1]]);
1299
+ }
1300
+ });
1301
+ }
1302
+ }
1303
+ }
1304
+ };
1305
+ }
1306
+ });
1307
+
981
1308
  //#endregion
982
1309
  //#region src/rules/no-text-backslash-linebreak.ts
983
1310
  var no_text_backslash_linebreak_default = createRule("no-text-backslash-linebreak", {
@@ -1109,45 +1436,28 @@ var no_trailing_spaces_default = createRule("no-trailing-spaces", {
1109
1436
  "root:exit"() {
1110
1437
  const re = /[^\S\n\r]+$/u;
1111
1438
  const skipMatch = /^[^\S\n\r]*$/u;
1112
- const lines = sourceCode.lines;
1113
- const linebreaks = sourceCode.text.match(/\r?\n/gu);
1439
+ const lines = parseLines(sourceCode);
1114
1440
  const commentLineNumbers = getCommentLineNumbers();
1115
- let totalLength = 0;
1116
- for (let i = 0, ii = lines.length; i < ii; i++) {
1117
- const lineNumber = i + 1;
1118
- const linebreakLength = linebreaks && linebreaks[i] ? linebreaks[i].length : 1;
1119
- const lineLength = lines[i].length + linebreakLength;
1120
- const matches = re.exec(lines[i]);
1121
- if (!matches) {
1122
- totalLength += lineLength;
1123
- continue;
1124
- }
1441
+ for (const lineInfo of lines) {
1442
+ const matches = re.exec(lineInfo.text);
1443
+ if (!matches) continue;
1125
1444
  const location = {
1126
1445
  start: {
1127
- line: lineNumber,
1446
+ line: lineInfo.line,
1128
1447
  column: matches.index + 1
1129
1448
  },
1130
1449
  end: {
1131
- line: lineNumber,
1132
- column: lineLength + 1 - linebreakLength
1450
+ line: lineInfo.line,
1451
+ column: matches.index + 1 + matches[0].length
1133
1452
  }
1134
1453
  };
1135
- const rangeStart = totalLength + location.start.column - 1;
1136
- const rangeEnd = totalLength + location.end.column - 1;
1454
+ const range = [lineInfo.range[0] + location.start.column - 1, lineInfo.range[0] + location.end.column - 1];
1137
1455
  if (ignoreNodes.some((node) => {
1138
- const range = sourceCode.getRange(node);
1139
- return range[0] <= rangeStart && rangeEnd <= range[1];
1140
- })) {
1141
- totalLength += lineLength;
1142
- continue;
1143
- }
1144
- if (skipBlankLines && skipMatch.test(lines[i])) {
1145
- totalLength += lineLength;
1146
- continue;
1147
- }
1148
- const fixRange = [rangeStart, rangeEnd];
1149
- if (!ignoreComments || !commentLineNumbers.has(lineNumber)) report(location, fixRange);
1150
- totalLength += lineLength;
1456
+ const nodeRange = sourceCode.getRange(node);
1457
+ return nodeRange[0] <= range[0] && range[1] <= nodeRange[1];
1458
+ })) continue;
1459
+ if (skipBlankLines && skipMatch.test(lineInfo.text)) continue;
1460
+ if (!ignoreComments || !commentLineNumbers.has(lineInfo.line)) report(location, range);
1151
1461
  }
1152
1462
  }
1153
1463
  };
@@ -1488,25 +1798,6 @@ var prefer_link_reference_definitions_default = createRule("prefer-link-referenc
1488
1798
  }
1489
1799
  });
1490
1800
 
1491
- //#endregion
1492
- //#region src/utils/url.ts
1493
- /**
1494
- * Utility function to check if a string is a valid URL.
1495
- */
1496
- function isValidURL(url) {
1497
- return Boolean(createURLSafe(url));
1498
- }
1499
- /**
1500
- * Utility function to create a URL object safely.
1501
- */
1502
- function createURLSafe(url) {
1503
- try {
1504
- return new URL(url);
1505
- } catch {
1506
- return null;
1507
- }
1508
- }
1509
-
1510
1801
  //#endregion
1511
1802
  //#region src/rules/prefer-linked-words.ts
1512
1803
  var prefer_linked_words_default = createRule("prefer-linked-words", {
@@ -1608,7 +1899,7 @@ var prefer_linked_words_default = createRule("prefer-linked-words", {
1608
1899
  * Adjust link to be relative to the file.
1609
1900
  */
1610
1901
  function adjustLink(link) {
1611
- if (isValidURL(link)) return link;
1902
+ if (URL.canParse(link)) return link;
1612
1903
  if (link.startsWith("#")) return link;
1613
1904
  const absoluteLink = path.isAbsolute(link) || path.posix.isAbsolute(link) ? link : path.join(context.cwd, link);
1614
1905
  return `./${path.relative(path.dirname(context.filename), absoluteLink)}`;
@@ -1789,14 +2080,14 @@ var sort_definitions_default = createRule("sort-definitions", {
1789
2080
  }
1790
2081
  /** Compile order option */
1791
2082
  function compileOption(orderOption) {
1792
- const cache = /* @__PURE__ */ new Map();
2083
+ const cache$1 = /* @__PURE__ */ new Map();
1793
2084
  const compiled = compileOptionWithoutCache(orderOption);
1794
2085
  return {
1795
2086
  match: (node) => {
1796
- const cached = cache.get(node);
2087
+ const cached = cache$1.get(node);
1797
2088
  if (cached != null) return cached;
1798
2089
  const result = compiled.match(node);
1799
- cache.set(node, result);
2090
+ cache$1.set(node, result);
1800
2091
  return result;
1801
2092
  },
1802
2093
  sort: compiled.sort
@@ -1847,7 +2138,7 @@ var sort_definitions_default = createRule("sort-definitions", {
1847
2138
  if (node.label === patternStr || node.identifier === patternStr) return true;
1848
2139
  if (node.type === "definition") {
1849
2140
  if (node.url === patternStr) return true;
1850
- if (isValidURL(patternStr)) {
2141
+ if (URL.canParse(patternStr) && URL.canParse(node.url)) {
1851
2142
  const normalizedPattern = normalizedURL(patternStr);
1852
2143
  const normalizedUrl = normalizedURL(node.url);
1853
2144
  if (normalizedUrl.startsWith(normalizedPattern)) return true;
@@ -1894,7 +2185,7 @@ function getQuote(text) {
1894
2185
  * Normalize a URL by ensuring it ends with a slash.
1895
2186
  */
1896
2187
  function normalizedURL(url) {
1897
- const urlObj = createURLSafe(url);
2188
+ const urlObj = new URL(url);
1898
2189
  if (!urlObj) return url;
1899
2190
  return urlObj.href.endsWith("/") ? urlObj.href : `${urlObj.href}/`;
1900
2191
  }
@@ -1906,6 +2197,8 @@ const rules$1 = [
1906
2197
  definitions_last_default,
1907
2198
  hard_linebreak_style_default,
1908
2199
  heading_casing_default,
2200
+ no_laziness_blockquotes_default,
2201
+ no_multiple_empty_lines_default,
1909
2202
  no_text_backslash_linebreak_default,
1910
2203
  no_trailing_spaces_default,
1911
2204
  prefer_inline_code_words_default,
@@ -1935,6 +2228,7 @@ const plugins = {
1935
2228
  };
1936
2229
  const rules$2 = {
1937
2230
  "markdown-preferences/hard-linebreak-style": "error",
2231
+ "markdown-preferences/no-laziness-blockquotes": "error",
1938
2232
  "markdown-preferences/no-text-backslash-linebreak": "error"
1939
2233
  };
1940
2234
 
@@ -1946,7 +2240,7 @@ __export(meta_exports, {
1946
2240
  version: () => version
1947
2241
  });
1948
2242
  const name = "eslint-plugin-markdown-preferences";
1949
- const version = "0.9.0";
2243
+ const version = "0.10.0";
1950
2244
 
1951
2245
  //#endregion
1952
2246
  //#region src/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-markdown-preferences",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "ESLint plugin that enforces our markdown preferences",
5
5
  "type": "module",
6
6
  "exports": {