markdownlint 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/CONTRIBUTING.md +81 -59
- package/README.md +424 -301
- package/demo/markdownlint-browser.js +445 -210
- package/doc/CustomRules.md +101 -50
- package/doc/Prettier.md +14 -10
- package/doc/ReleaseProcess.md +20 -0
- package/doc/Rules.md +464 -296
- package/doc/md001.md +37 -0
- package/doc/md002.md +37 -0
- package/doc/md003.md +59 -0
- package/doc/md004.md +49 -0
- package/doc/md005.md +53 -0
- package/doc/md006.md +46 -0
- package/doc/md007.md +55 -0
- package/doc/md009.md +51 -0
- package/doc/md010.md +56 -0
- package/doc/md011.md +30 -0
- package/doc/md012.md +38 -0
- package/doc/md013.md +60 -0
- package/doc/md014.md +54 -0
- package/doc/md018.md +27 -0
- package/doc/md019.md +28 -0
- package/doc/md020.md +29 -0
- package/doc/md021.md +31 -0
- package/doc/md022.md +46 -0
- package/doc/md023.md +26 -0
- package/doc/md024.md +47 -0
- package/doc/md025.md +49 -0
- package/doc/md026.md +41 -0
- package/doc/md027.md +24 -0
- package/doc/md028.md +40 -0
- package/doc/md029.md +98 -0
- package/doc/md030.md +82 -0
- package/doc/md031.md +50 -0
- package/doc/md032.md +38 -0
- package/doc/md033.md +27 -0
- package/doc/md034.md +44 -0
- package/doc/md035.md +42 -0
- package/doc/md036.md +45 -0
- package/doc/md037.md +37 -0
- package/doc/md038.md +40 -0
- package/doc/md039.md +21 -0
- package/doc/md040.md +52 -0
- package/doc/md041.md +49 -0
- package/doc/md042.md +32 -0
- package/doc/md043.md +72 -0
- package/doc/md044.md +35 -0
- package/doc/md045.md +34 -0
- package/doc/md046.md +40 -0
- package/doc/md047.md +34 -0
- package/doc/md048.md +41 -0
- package/doc/md049.md +32 -0
- package/doc/md050.md +32 -0
- package/doc/md051.md +50 -0
- package/doc/md052.md +33 -0
- package/doc/md053.md +38 -0
- package/helpers/README.md +35 -15
- package/helpers/helpers.js +234 -70
- package/helpers/package.json +2 -2
- package/lib/constants.js +8 -1
- package/lib/markdownlint.js +7 -12
- package/lib/md011.js +2 -2
- package/lib/md013.js +7 -6
- package/lib/md019.js +1 -1
- package/lib/md022.js +15 -3
- package/lib/md023.js +1 -1
- package/lib/md026.js +1 -1
- package/lib/md032.js +4 -5
- package/lib/md033.js +16 -5
- package/lib/md034.js +70 -45
- package/lib/md035.js +1 -1
- package/lib/md037.js +25 -22
- package/lib/md038.js +1 -1
- package/lib/md039.js +1 -1
- package/lib/md040.js +21 -2
- package/lib/md043.js +4 -2
- package/lib/md044.js +4 -3
- package/lib/md051.js +43 -11
- package/lib/md053.js +18 -11
- package/lib/rules.js +1 -1
- package/package.json +31 -21
- package/schema/.markdownlint.jsonc +16 -4
- package/schema/.markdownlint.yaml +13 -3
- package/schema/markdownlint-config-schema.json +45 -5
- package/style/prettier.json +26 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! markdownlint 0.
|
|
1
|
+
/*! markdownlint 0.27.0 https://github.com/DavidAnson/markdownlint @license MIT */
|
|
2
2
|
var markdownlint;
|
|
3
3
|
/******/ (() => { // webpackBootstrap
|
|
4
4
|
/******/ var __webpack_modules__ = ({
|
|
@@ -37,25 +37,27 @@ module.exports.newLineRe = newLineRe;
|
|
|
37
37
|
// Regular expression for matching common front matter (YAML and TOML)
|
|
38
38
|
module.exports.frontMatterRe =
|
|
39
39
|
// eslint-disable-next-line max-len
|
|
40
|
-
/((^---\s*$[
|
|
40
|
+
/((^---\s*$[\s\S]*?^---\s*)|(^\+\+\+\s*$[\s\S]*?^(\+\+\+|\.\.\.)\s*)|(^\{\s*$[\s\S]*?^\}\s*))(\r\n|\r|\n|$)/m;
|
|
41
41
|
// Regular expression for matching the start of inline disable/enable comments
|
|
42
42
|
const inlineCommentStartRe =
|
|
43
43
|
// eslint-disable-next-line max-len
|
|
44
|
-
/(<!--\s*markdownlint-(disable|enable|capture|restore|disable-file|enable-file|disable-line|disable-next-line|configure-file))(?:\s|-->)/
|
|
44
|
+
/(<!--\s*markdownlint-(disable|enable|capture|restore|disable-file|enable-file|disable-line|disable-next-line|configure-file))(?:\s|-->)/gi;
|
|
45
45
|
module.exports.inlineCommentStartRe = inlineCommentStartRe;
|
|
46
46
|
// Regular expression for matching HTML elements
|
|
47
|
-
const htmlElementRe = /<(([A-Za-z][A-Za-
|
|
47
|
+
const htmlElementRe = /<(([A-Za-z][A-Za-z\d-]*)(?:\s[^`>]*)?)\/?>/g;
|
|
48
48
|
module.exports.htmlElementRe = htmlElementRe;
|
|
49
49
|
// Regular expressions for range matching
|
|
50
|
-
module.exports.bareUrlRe = /(?:http|ftp)s?:\/\/[^\s\]"']*(?:\/|[^\s\]"'\W])/ig;
|
|
51
50
|
module.exports.listItemMarkerRe = /^([\s>]*)(?:[*+-]|\d+[.)])\s+/;
|
|
52
51
|
module.exports.orderedListItemMarkerRe = /^[\s>]*0*(\d+)[.)]/;
|
|
53
52
|
// Regular expression for all instances of emphasis markers
|
|
54
53
|
const emphasisMarkersRe = /[_*]/g;
|
|
55
|
-
// Regular expression for
|
|
56
|
-
const
|
|
54
|
+
// Regular expression for blockquote prefixes
|
|
55
|
+
const blockquotePrefixRe = /^[>\s]*/;
|
|
56
|
+
module.exports.blockquotePrefixRe = blockquotePrefixRe;
|
|
57
|
+
// Regular expression for reference links (full, collapsed, and shortcut)
|
|
58
|
+
const referenceLinkRe = /!?\\?\[((?:\[[^\]\0]*\]|[^[\]\0])*)\](?:\[([^\]\0]*)\]|([^(])|$)/g;
|
|
57
59
|
// Regular expression for link reference definitions
|
|
58
|
-
const linkReferenceDefinitionRe = /^ {0,3}\[([^\]]*[^\\])]:/;
|
|
60
|
+
const linkReferenceDefinitionRe = /^ {0,3}\[([^\]]*[^\\])\]:/;
|
|
59
61
|
module.exports.linkReferenceDefinitionRe = linkReferenceDefinitionRe;
|
|
60
62
|
// All punctuation characters (normal and full-width)
|
|
61
63
|
const allPunctuation = ".,;:!?。,;:!?";
|
|
@@ -151,6 +153,12 @@ module.exports.includesSorted = function includesSorted(array, element) {
|
|
|
151
153
|
// https://spec.commonmark.org/0.29/#html-comment
|
|
152
154
|
const htmlCommentBegin = "<!--";
|
|
153
155
|
const htmlCommentEnd = "-->";
|
|
156
|
+
const safeCommentCharacter = ".";
|
|
157
|
+
const startsWithPipeRe = /^ *\|/;
|
|
158
|
+
const notCrLfRe = /[^\r\n]/g;
|
|
159
|
+
const notSpaceCrLfRe = /[^ \r\n]/g;
|
|
160
|
+
const trailingSpaceRe = / +[\r\n]/g;
|
|
161
|
+
const replaceTrailingSpace = (s) => s.replace(notCrLfRe, safeCommentCharacter);
|
|
154
162
|
module.exports.clearHtmlCommentText = function clearHtmlCommentText(text) {
|
|
155
163
|
let i = 0;
|
|
156
164
|
while ((i = text.indexOf(htmlCommentBegin, i)) !== -1) {
|
|
@@ -161,24 +169,27 @@ module.exports.clearHtmlCommentText = function clearHtmlCommentText(text) {
|
|
|
161
169
|
}
|
|
162
170
|
// If the comment has content...
|
|
163
171
|
if (j > i + htmlCommentBegin.length) {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
172
|
+
const content = text.slice(i + htmlCommentBegin.length, j);
|
|
173
|
+
const lastLf = text.lastIndexOf("\n", i) + 1;
|
|
174
|
+
const preText = text.slice(lastLf, i);
|
|
175
|
+
const isBlock = preText.trim().length === 0;
|
|
176
|
+
const couldBeTable = startsWithPipeRe.test(preText);
|
|
177
|
+
const spansTableCells = couldBeTable && content.includes("\n");
|
|
178
|
+
const isValid = isBlock ||
|
|
179
|
+
!(spansTableCells ||
|
|
180
|
+
content.startsWith(">") ||
|
|
181
|
+
content.startsWith("->") ||
|
|
182
|
+
content.endsWith("-") ||
|
|
183
|
+
content.includes("--"));
|
|
184
|
+
// If a valid block/inline comment...
|
|
185
|
+
if (isValid) {
|
|
186
|
+
const clearedContent = content
|
|
187
|
+
.replace(notSpaceCrLfRe, safeCommentCharacter)
|
|
188
|
+
.replace(trailingSpaceRe, replaceTrailingSpace);
|
|
189
|
+
text =
|
|
190
|
+
text.slice(0, i + htmlCommentBegin.length) +
|
|
191
|
+
clearedContent +
|
|
192
|
+
text.slice(j);
|
|
182
193
|
}
|
|
183
194
|
}
|
|
184
195
|
i = j + htmlCommentEnd.length;
|
|
@@ -402,17 +413,22 @@ module.exports.flattenLists = function flattenLists(tokens) {
|
|
|
402
413
|
}
|
|
403
414
|
return flattenedLists;
|
|
404
415
|
};
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
+
/**
|
|
417
|
+
* Calls the provided function for each specified inline child token.
|
|
418
|
+
*
|
|
419
|
+
* @param {Object} params RuleParams instance.
|
|
420
|
+
* @param {string} type Token type identifier.
|
|
421
|
+
* @param {Function} handler Callback function.
|
|
422
|
+
* @returns {void}
|
|
423
|
+
*/
|
|
424
|
+
function forEachInlineChild(params, type, handler) {
|
|
425
|
+
filterTokens(params, "inline", (token) => {
|
|
426
|
+
for (const child of token.children.filter((c) => c.type === type)) {
|
|
427
|
+
handler(child, token);
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
module.exports.forEachInlineChild = forEachInlineChild;
|
|
416
432
|
// Calls the provided function for each heading's content
|
|
417
433
|
module.exports.forEachHeading = function forEachHeading(params, handler) {
|
|
418
434
|
let heading = null;
|
|
@@ -573,6 +589,7 @@ module.exports.codeBlockAndSpanRanges = (params, lineMetadata) => {
|
|
|
573
589
|
*/
|
|
574
590
|
module.exports.htmlElementRanges = (params, lineMetadata) => {
|
|
575
591
|
const exclusions = [];
|
|
592
|
+
// Match with htmlElementRe
|
|
576
593
|
forEachLine(lineMetadata, (line, lineIndex, inCode) => {
|
|
577
594
|
let match = null;
|
|
578
595
|
// eslint-disable-next-line no-unmodified-loop-condition
|
|
@@ -580,6 +597,32 @@ module.exports.htmlElementRanges = (params, lineMetadata) => {
|
|
|
580
597
|
exclusions.push([lineIndex, match.index, match[0].length]);
|
|
581
598
|
}
|
|
582
599
|
});
|
|
600
|
+
// Match with html_inline
|
|
601
|
+
forEachInlineChild(params, "html_inline", (token, parent) => {
|
|
602
|
+
const parentContent = parent.content;
|
|
603
|
+
let tokenContent = token.content;
|
|
604
|
+
const parentIndex = parentContent.indexOf(tokenContent);
|
|
605
|
+
let deltaLines = 0;
|
|
606
|
+
let indent = 0;
|
|
607
|
+
for (let i = parentIndex - 1; i >= 0; i--) {
|
|
608
|
+
if (parentContent[i] === "\n") {
|
|
609
|
+
deltaLines++;
|
|
610
|
+
}
|
|
611
|
+
else if (deltaLines === 0) {
|
|
612
|
+
indent++;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
let lineIndex = token.lineNumber - 1 + deltaLines;
|
|
616
|
+
do {
|
|
617
|
+
const index = tokenContent.indexOf("\n");
|
|
618
|
+
const length = (index === -1) ? tokenContent.length : index;
|
|
619
|
+
exclusions.push([lineIndex, indent, length]);
|
|
620
|
+
tokenContent = tokenContent.slice(length + 1);
|
|
621
|
+
lineIndex++;
|
|
622
|
+
indent = 0;
|
|
623
|
+
} while (tokenContent.length > 0);
|
|
624
|
+
});
|
|
625
|
+
// Return results
|
|
583
626
|
return exclusions;
|
|
584
627
|
};
|
|
585
628
|
/**
|
|
@@ -749,13 +792,14 @@ module.exports.emphasisMarkersInContent = emphasisMarkersInContent;
|
|
|
749
792
|
function getReferenceLinkImageData(lineMetadata) {
|
|
750
793
|
// Initialize return values
|
|
751
794
|
const references = new Map();
|
|
752
|
-
const shortcuts = new
|
|
795
|
+
const shortcuts = new Map();
|
|
753
796
|
const definitions = new Map();
|
|
754
797
|
const duplicateDefinitions = [];
|
|
798
|
+
const definitionLineIndices = [];
|
|
755
799
|
// Define helper functions
|
|
756
800
|
const normalizeLabel = (s) => s.toLowerCase().trim().replace(/\s+/g, " ");
|
|
757
801
|
const exclusions = [];
|
|
758
|
-
const excluded = (match) => withinAnyRange(exclusions, 0, match.index, match[0].length);
|
|
802
|
+
const excluded = (match) => withinAnyRange(exclusions, 0, match.index, match[0].length - (match[3] || "").length);
|
|
759
803
|
// Convert input to single-line so multi-line links/images are easier
|
|
760
804
|
const lineOffsets = [];
|
|
761
805
|
let currentOffset = 0;
|
|
@@ -763,6 +807,7 @@ function getReferenceLinkImageData(lineMetadata) {
|
|
|
763
807
|
forEachLine(lineMetadata, (line, lineIndex, inCode) => {
|
|
764
808
|
lineOffsets[lineIndex] = currentOffset;
|
|
765
809
|
if (!inCode) {
|
|
810
|
+
line = line.replace(blockquotePrefixRe, "");
|
|
766
811
|
if (line.trim().length === 0) {
|
|
767
812
|
// Allow RegExp to detect the end of a block
|
|
768
813
|
line = "\0";
|
|
@@ -789,7 +834,13 @@ function getReferenceLinkImageData(lineMetadata) {
|
|
|
789
834
|
else {
|
|
790
835
|
definitions.set(label, lineIndex);
|
|
791
836
|
}
|
|
792
|
-
|
|
837
|
+
const labelLength = linkReferenceDefinitionMatch[0].length;
|
|
838
|
+
exclusions.push([0, lineOffsets[lineIndex], labelLength]);
|
|
839
|
+
const hasDefinition = line.slice(labelLength).trim().length > 0;
|
|
840
|
+
definitionLineIndices.push(lineIndex);
|
|
841
|
+
if (!hasDefinition) {
|
|
842
|
+
definitionLineIndices.push(lineIndex + 1);
|
|
843
|
+
}
|
|
793
844
|
}
|
|
794
845
|
}
|
|
795
846
|
});
|
|
@@ -813,47 +864,51 @@ function getReferenceLinkImageData(lineMetadata) {
|
|
|
813
864
|
!matchString.startsWith("!\\") &&
|
|
814
865
|
!matchText.endsWith("\\") &&
|
|
815
866
|
!(matchLabel || "").endsWith("\\") &&
|
|
816
|
-
(topLevel
|
|
817
|
-
!excluded(referenceLinkMatch)) {
|
|
867
|
+
!(topLevel && excluded(referenceLinkMatch))) {
|
|
818
868
|
const shortcutLink = (matchLabel === undefined);
|
|
819
869
|
const collapsedLink = (!shortcutLink && (matchLabel.length === 0));
|
|
820
870
|
const label = normalizeLabel((shortcutLink || collapsedLink) ? matchText : matchLabel);
|
|
821
871
|
if (label.length > 0) {
|
|
872
|
+
const referenceindex = referenceLinkMatch.index;
|
|
873
|
+
if (topLevel) {
|
|
874
|
+
// Calculate line index
|
|
875
|
+
while (lineOffsets[lineIndex + 1] <= referenceindex) {
|
|
876
|
+
lineIndex++;
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
else {
|
|
880
|
+
// Use provided line index
|
|
881
|
+
lineIndex = contentLineIndex;
|
|
882
|
+
}
|
|
883
|
+
const referenceIndex = referenceindex +
|
|
884
|
+
(topLevel ? -lineOffsets[lineIndex] : contentIndex);
|
|
885
|
+
const referenceDatum = [
|
|
886
|
+
lineIndex,
|
|
887
|
+
referenceIndex,
|
|
888
|
+
matchString.length,
|
|
889
|
+
matchText.length,
|
|
890
|
+
(matchLabel || "").length
|
|
891
|
+
];
|
|
822
892
|
if (shortcutLink) {
|
|
823
|
-
// Track
|
|
824
|
-
shortcuts.
|
|
893
|
+
// Track separately due to ambiguity in "text [text] text"
|
|
894
|
+
const shortcutData = shortcuts.get(label) || [];
|
|
895
|
+
shortcutData.push(referenceDatum);
|
|
896
|
+
shortcuts.set(label, shortcutData);
|
|
825
897
|
}
|
|
826
898
|
else {
|
|
827
|
-
const referenceindex = referenceLinkMatch.index;
|
|
828
|
-
if (topLevel) {
|
|
829
|
-
// Calculate line index
|
|
830
|
-
while (lineOffsets[lineIndex + 1] <= referenceindex) {
|
|
831
|
-
lineIndex++;
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
else {
|
|
835
|
-
// Use provided line index
|
|
836
|
-
lineIndex = contentLineIndex;
|
|
837
|
-
}
|
|
838
|
-
const referenceIndex = referenceindex +
|
|
839
|
-
(topLevel ? -lineOffsets[lineIndex] : contentIndex);
|
|
840
899
|
// Track reference and location
|
|
841
900
|
const referenceData = references.get(label) || [];
|
|
842
|
-
referenceData.push(
|
|
843
|
-
lineIndex,
|
|
844
|
-
referenceIndex,
|
|
845
|
-
matchString.length
|
|
846
|
-
]);
|
|
901
|
+
referenceData.push(referenceDatum);
|
|
847
902
|
references.set(label, referenceData);
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
}
|
|
903
|
+
}
|
|
904
|
+
// Check for links embedded in brackets
|
|
905
|
+
if (!matchString.startsWith("!")) {
|
|
906
|
+
pendingContents.push({
|
|
907
|
+
"content": matchText,
|
|
908
|
+
"contentLineIndex": lineIndex,
|
|
909
|
+
"contentIndex": referenceIndex + 1,
|
|
910
|
+
"topLevel": false
|
|
911
|
+
});
|
|
857
912
|
}
|
|
858
913
|
}
|
|
859
914
|
}
|
|
@@ -863,7 +918,8 @@ function getReferenceLinkImageData(lineMetadata) {
|
|
|
863
918
|
references,
|
|
864
919
|
shortcuts,
|
|
865
920
|
definitions,
|
|
866
|
-
duplicateDefinitions
|
|
921
|
+
duplicateDefinitions,
|
|
922
|
+
definitionLineIndices
|
|
867
923
|
};
|
|
868
924
|
}
|
|
869
925
|
module.exports.getReferenceLinkImageData = getReferenceLinkImageData;
|
|
@@ -950,7 +1006,7 @@ module.exports.applyFix = applyFix;
|
|
|
950
1006
|
* @returns {string} Corrected content.
|
|
951
1007
|
*/
|
|
952
1008
|
function applyFixes(input, errors) {
|
|
953
|
-
const lineEnding = getPreferredLineEnding(input, __webpack_require__(/*! os */ "?
|
|
1009
|
+
const lineEnding = getPreferredLineEnding(input, __webpack_require__(/*! node:os */ "?0176"));
|
|
954
1010
|
const lines = input.split(newLineRe);
|
|
955
1011
|
// Normalize fixInfo objects
|
|
956
1012
|
let fixInfos = errors
|
|
@@ -1081,6 +1137,109 @@ function expandTildePath(file, os) {
|
|
|
1081
1137
|
return homedir ? file.replace(/^~($|\/|\\)/, `${homedir}$1`) : file;
|
|
1082
1138
|
}
|
|
1083
1139
|
module.exports.expandTildePath = expandTildePath;
|
|
1140
|
+
/**
|
|
1141
|
+
* RegExp.exec-style implementation of function expressions.
|
|
1142
|
+
*
|
|
1143
|
+
* @param {Function} funcExp Function that takes string and returns
|
|
1144
|
+
* [index, length] or null.
|
|
1145
|
+
* @param {string} input String to search.
|
|
1146
|
+
* @returns {string[] | null} RegExp.exec-style [match] with an index property.
|
|
1147
|
+
*/
|
|
1148
|
+
function funcExpExec(funcExp, input) {
|
|
1149
|
+
// Start or resume match
|
|
1150
|
+
// @ts-ignore
|
|
1151
|
+
const lastIndex = funcExp.lastIndex || 0;
|
|
1152
|
+
const result = funcExp(input.slice(lastIndex));
|
|
1153
|
+
if (result) {
|
|
1154
|
+
// Update lastIndex and return match
|
|
1155
|
+
const [subIndex, length] = result;
|
|
1156
|
+
const index = lastIndex + subIndex;
|
|
1157
|
+
// @ts-ignore
|
|
1158
|
+
funcExp.lastIndex = index + length;
|
|
1159
|
+
const match = [input.slice(index, index + length)];
|
|
1160
|
+
// @ts-ignore
|
|
1161
|
+
match.index = index;
|
|
1162
|
+
return match;
|
|
1163
|
+
}
|
|
1164
|
+
// Reset lastIndex and return no match
|
|
1165
|
+
// @ts-ignore
|
|
1166
|
+
funcExp.lastIndex = 0;
|
|
1167
|
+
return null;
|
|
1168
|
+
}
|
|
1169
|
+
module.exports.funcExpExec = funcExpExec;
|
|
1170
|
+
const urlFeProtocolRe = /(?:http|ftp)s?:\/\//i;
|
|
1171
|
+
const urlFeAutolinkTerminalsRe = / |$/;
|
|
1172
|
+
const urlFeBareTerminalsRe = /[ ,!`'"\]]|$/;
|
|
1173
|
+
const urlFeNonTerminalsRe = "-#/";
|
|
1174
|
+
const urlFePunctuationRe = /\p{Punctuation}/u;
|
|
1175
|
+
const urlFePrefixToPostfix = new Map([
|
|
1176
|
+
[" ", " "],
|
|
1177
|
+
["`", "`"],
|
|
1178
|
+
["'", "'"],
|
|
1179
|
+
["\"", "\""],
|
|
1180
|
+
["‘", "’"],
|
|
1181
|
+
["“", "”"],
|
|
1182
|
+
["«", "»"],
|
|
1183
|
+
["*", "*"],
|
|
1184
|
+
["_", "_"],
|
|
1185
|
+
["(", ")"],
|
|
1186
|
+
["[", "]"],
|
|
1187
|
+
["{", "}"],
|
|
1188
|
+
["<", ">"],
|
|
1189
|
+
[">", "<"]
|
|
1190
|
+
]);
|
|
1191
|
+
/**
|
|
1192
|
+
* Function expression that matches URLs.
|
|
1193
|
+
*
|
|
1194
|
+
* @param {string} input Substring to search for a URL.
|
|
1195
|
+
* @returns {Array | null} [index, length] of URL or null.
|
|
1196
|
+
*/
|
|
1197
|
+
function urlFe(input) {
|
|
1198
|
+
// Find start of URL by searching for protocol
|
|
1199
|
+
const match = input.match(urlFeProtocolRe);
|
|
1200
|
+
if (match) {
|
|
1201
|
+
// Look for matching pre/postfix characters (ex: <...>)
|
|
1202
|
+
const start = match.index || 0;
|
|
1203
|
+
const length = match[0].length;
|
|
1204
|
+
const prefix = input[start - 1] || " ";
|
|
1205
|
+
const postfix = urlFePrefixToPostfix.get(prefix);
|
|
1206
|
+
// @ts-ignore
|
|
1207
|
+
let endPostfix = input.indexOf(postfix, start + length);
|
|
1208
|
+
if (endPostfix === -1) {
|
|
1209
|
+
endPostfix = input.length;
|
|
1210
|
+
}
|
|
1211
|
+
// Look for characters that terminate a URL
|
|
1212
|
+
const terminalsRe = (prefix === "<") ? urlFeAutolinkTerminalsRe : urlFeBareTerminalsRe;
|
|
1213
|
+
const endTerminal = start + input.slice(start).search(terminalsRe);
|
|
1214
|
+
// Determine tentative end of URL
|
|
1215
|
+
let end = Math.min(endPostfix, endTerminal);
|
|
1216
|
+
if (prefix === " ") {
|
|
1217
|
+
// If the URL used " " as pre/postfix characters, trim the end
|
|
1218
|
+
if (input[end - 1] === ")") {
|
|
1219
|
+
// Trim any ")" beyond the last "(...)" pair
|
|
1220
|
+
const lastOpenParen = input.lastIndexOf("(", end - 2);
|
|
1221
|
+
if (lastOpenParen <= start) {
|
|
1222
|
+
end--;
|
|
1223
|
+
}
|
|
1224
|
+
else {
|
|
1225
|
+
const nextCloseParen = input.indexOf(")", lastOpenParen + 1);
|
|
1226
|
+
end = nextCloseParen + 1;
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
else {
|
|
1230
|
+
// Trim unwanted punctuation
|
|
1231
|
+
while (!urlFeNonTerminalsRe.includes(input[end - 1]) &&
|
|
1232
|
+
urlFePunctuationRe.test(input[end - 1])) {
|
|
1233
|
+
end--;
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
return [start, end - start];
|
|
1238
|
+
}
|
|
1239
|
+
// No match
|
|
1240
|
+
return null;
|
|
1241
|
+
}
|
|
1242
|
+
module.exports.urlFe = urlFe;
|
|
1084
1243
|
|
|
1085
1244
|
|
|
1086
1245
|
/***/ }),
|
|
@@ -1096,50 +1255,50 @@ module.exports = markdownit;
|
|
|
1096
1255
|
|
|
1097
1256
|
/***/ }),
|
|
1098
1257
|
|
|
1099
|
-
/***/ "?
|
|
1100
|
-
|
|
1101
|
-
!*** os (ignored) ***!
|
|
1102
|
-
|
|
1258
|
+
/***/ "?0176":
|
|
1259
|
+
/*!*************************!*\
|
|
1260
|
+
!*** node:os (ignored) ***!
|
|
1261
|
+
\*************************/
|
|
1103
1262
|
/***/ (() => {
|
|
1104
1263
|
|
|
1105
1264
|
/* (ignored) */
|
|
1106
1265
|
|
|
1107
1266
|
/***/ }),
|
|
1108
1267
|
|
|
1109
|
-
/***/ "?
|
|
1110
|
-
|
|
1111
|
-
!*** fs (ignored) ***!
|
|
1112
|
-
|
|
1268
|
+
/***/ "?d0ee":
|
|
1269
|
+
/*!*************************!*\
|
|
1270
|
+
!*** node:fs (ignored) ***!
|
|
1271
|
+
\*************************/
|
|
1113
1272
|
/***/ (() => {
|
|
1114
1273
|
|
|
1115
1274
|
/* (ignored) */
|
|
1116
1275
|
|
|
1117
1276
|
/***/ }),
|
|
1118
1277
|
|
|
1119
|
-
/***/ "?
|
|
1120
|
-
|
|
1121
|
-
!*** os (ignored) ***!
|
|
1122
|
-
|
|
1278
|
+
/***/ "?e6c4":
|
|
1279
|
+
/*!*************************!*\
|
|
1280
|
+
!*** node:os (ignored) ***!
|
|
1281
|
+
\*************************/
|
|
1123
1282
|
/***/ (() => {
|
|
1124
1283
|
|
|
1125
1284
|
/* (ignored) */
|
|
1126
1285
|
|
|
1127
1286
|
/***/ }),
|
|
1128
1287
|
|
|
1129
|
-
/***/ "?
|
|
1130
|
-
|
|
1131
|
-
!*** path (ignored) ***!
|
|
1132
|
-
|
|
1288
|
+
/***/ "?9a52":
|
|
1289
|
+
/*!***************************!*\
|
|
1290
|
+
!*** node:path (ignored) ***!
|
|
1291
|
+
\***************************/
|
|
1133
1292
|
/***/ (() => {
|
|
1134
1293
|
|
|
1135
1294
|
/* (ignored) */
|
|
1136
1295
|
|
|
1137
1296
|
/***/ }),
|
|
1138
1297
|
|
|
1139
|
-
/***/ "?
|
|
1140
|
-
|
|
1141
|
-
!*** util (ignored) ***!
|
|
1142
|
-
|
|
1298
|
+
/***/ "?39e5":
|
|
1299
|
+
/*!***************************!*\
|
|
1300
|
+
!*** node:util (ignored) ***!
|
|
1301
|
+
\***************************/
|
|
1143
1302
|
/***/ (() => {
|
|
1144
1303
|
|
|
1145
1304
|
/* (ignored) */
|
|
@@ -1186,8 +1345,15 @@ module.exports.referenceLinkImageData =
|
|
|
1186
1345
|
// @ts-check
|
|
1187
1346
|
|
|
1188
1347
|
module.exports.deprecatedRuleNames = ["MD002", "MD006"];
|
|
1348
|
+
module.exports.fixableRuleNames = [
|
|
1349
|
+
"MD004", "MD005", "MD006", "MD007", "MD009", "MD010",
|
|
1350
|
+
"MD011", "MD012", "MD014", "MD018", "MD019", "MD020",
|
|
1351
|
+
"MD021", "MD022", "MD023", "MD026", "MD027", "MD030",
|
|
1352
|
+
"MD031", "MD032", "MD034", "MD037", "MD038", "MD039",
|
|
1353
|
+
"MD044", "MD047", "MD049", "MD050", "MD051", "MD053"
|
|
1354
|
+
];
|
|
1189
1355
|
module.exports.homepage = "https://github.com/DavidAnson/markdownlint";
|
|
1190
|
-
module.exports.version = "0.
|
|
1356
|
+
module.exports.version = "0.27.0";
|
|
1191
1357
|
|
|
1192
1358
|
|
|
1193
1359
|
/***/ }),
|
|
@@ -1201,8 +1367,8 @@ module.exports.version = "0.26.1";
|
|
|
1201
1367
|
"use strict";
|
|
1202
1368
|
// @ts-check
|
|
1203
1369
|
|
|
1204
|
-
const path = __webpack_require__(/*! path */ "?
|
|
1205
|
-
const { promisify } = __webpack_require__(/*! util */ "?
|
|
1370
|
+
const path = __webpack_require__(/*! node:path */ "?9a52");
|
|
1371
|
+
const { promisify } = __webpack_require__(/*! node:util */ "?39e5");
|
|
1206
1372
|
const markdownIt = __webpack_require__(/*! markdown-it */ "markdown-it");
|
|
1207
1373
|
const { deprecatedRuleNames } = __webpack_require__(/*! ./constants */ "../lib/constants.js");
|
|
1208
1374
|
const rules = __webpack_require__(/*! ./rules */ "../lib/rules.js");
|
|
@@ -1419,11 +1585,6 @@ function annotateAndFreezeTokens(tokens, lines) {
|
|
|
1419
1585
|
if (!token.map && trMap) {
|
|
1420
1586
|
token.map = [...trMap];
|
|
1421
1587
|
}
|
|
1422
|
-
// Adjust maps for math blocks
|
|
1423
|
-
if (helpers.isMathBlock(token) && token.map[1]) {
|
|
1424
|
-
// markdown-it-texmath plugin does not account for math_block_end
|
|
1425
|
-
token.map[1]++;
|
|
1426
|
-
}
|
|
1427
1588
|
// Update token metadata
|
|
1428
1589
|
if (token.map) {
|
|
1429
1590
|
token.line = lines[token.map[0]];
|
|
@@ -1993,7 +2154,7 @@ function lintInput(options, synchronous, callback) {
|
|
|
1993
2154
|
// @ts-ignore
|
|
1994
2155
|
md.use(...plugin);
|
|
1995
2156
|
}
|
|
1996
|
-
const fs = options.fs || __webpack_require__(/*! fs */ "?
|
|
2157
|
+
const fs = options.fs || __webpack_require__(/*! node:fs */ "?d0ee");
|
|
1997
2158
|
const results = newResults(ruleList);
|
|
1998
2159
|
let done = false;
|
|
1999
2160
|
let concurrency = 0;
|
|
@@ -2169,10 +2330,10 @@ function readConfig(file, parsers, fs, callback) {
|
|
|
2169
2330
|
}
|
|
2170
2331
|
}
|
|
2171
2332
|
if (!fs) {
|
|
2172
|
-
fs = __webpack_require__(/*! fs */ "?
|
|
2333
|
+
fs = __webpack_require__(/*! node:fs */ "?d0ee");
|
|
2173
2334
|
}
|
|
2174
2335
|
// Read file
|
|
2175
|
-
const os = __webpack_require__(/*! os */ "?
|
|
2336
|
+
const os = __webpack_require__(/*! node:os */ "?e6c4");
|
|
2176
2337
|
file = helpers.expandTildePath(file, os);
|
|
2177
2338
|
fs.readFile(file, "utf8", (err, content) => {
|
|
2178
2339
|
if (err) {
|
|
@@ -2229,10 +2390,10 @@ function readConfigPromise(file, parsers, fs) {
|
|
|
2229
2390
|
*/
|
|
2230
2391
|
function readConfigSync(file, parsers, fs) {
|
|
2231
2392
|
if (!fs) {
|
|
2232
|
-
fs = __webpack_require__(/*! fs */ "?
|
|
2393
|
+
fs = __webpack_require__(/*! node:fs */ "?d0ee");
|
|
2233
2394
|
}
|
|
2234
2395
|
// Read file
|
|
2235
|
-
const os = __webpack_require__(/*! os */ "?
|
|
2396
|
+
const os = __webpack_require__(/*! node:os */ "?e6c4");
|
|
2236
2397
|
file = helpers.expandTildePath(file, os);
|
|
2237
2398
|
const content = fs.readFileSync(file, "utf8");
|
|
2238
2399
|
// Try to parse file
|
|
@@ -2744,7 +2905,7 @@ module.exports = {
|
|
|
2744
2905
|
|
|
2745
2906
|
const { addError, forEachLine, withinAnyRange } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
2746
2907
|
const { codeBlockAndSpanRanges, lineMetadata } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
2747
|
-
const reversedLinkRe = /(^|[^\\])\(([^)]+)\)\[([^\]^][^\]]*)](?!\()/g;
|
|
2908
|
+
const reversedLinkRe = /(^|[^\\])\(([^()]+)\)\[([^\]^][^\]]*)\](?!\()/g;
|
|
2748
2909
|
module.exports = {
|
|
2749
2910
|
"names": ["MD011", "no-reversed-links"],
|
|
2750
2911
|
"description": "Reversed link syntax",
|
|
@@ -2761,7 +2922,7 @@ module.exports = {
|
|
|
2761
2922
|
if (!linkText.endsWith("\\") &&
|
|
2762
2923
|
!linkDestination.endsWith("\\") &&
|
|
2763
2924
|
!withinAnyRange(exclusions, lineIndex, index, length)) {
|
|
2764
|
-
addError(onError, lineIndex + 1, reversedLink.slice(preChar.length),
|
|
2925
|
+
addError(onError, lineIndex + 1, reversedLink.slice(preChar.length), undefined, [index + 1, length], {
|
|
2765
2926
|
"editColumn": index + 1,
|
|
2766
2927
|
"deleteCount": length,
|
|
2767
2928
|
"insertText": `[${linkText}](${linkDestination})`
|
|
@@ -2817,13 +2978,13 @@ module.exports = {
|
|
|
2817
2978
|
"use strict";
|
|
2818
2979
|
// @ts-check
|
|
2819
2980
|
|
|
2820
|
-
const { addErrorDetailIf, filterTokens, forEachHeading, forEachLine, includesSorted
|
|
2821
|
-
const { lineMetadata } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
2981
|
+
const { addErrorDetailIf, filterTokens, forEachHeading, forEachLine, includesSorted } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
2982
|
+
const { lineMetadata, referenceLinkImageData } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
2822
2983
|
const longLineRePrefix = "^.{";
|
|
2823
2984
|
const longLineRePostfixRelaxed = "}.*\\s.*$";
|
|
2824
2985
|
const longLineRePostfixStrict = "}.+$";
|
|
2825
|
-
const linkOrImageOnlyLineRe = /^[es]*(lT?L|I)[ES]*$/;
|
|
2826
|
-
const sternModeRe = /^([#>\s]*\s)?\S*$/;
|
|
2986
|
+
const linkOrImageOnlyLineRe = /^[es]*(?:lT?L|I)[ES]*$/;
|
|
2987
|
+
const sternModeRe = /^(?:[#>\s]*\s)?\S*$/;
|
|
2827
2988
|
const tokenTypeMap = {
|
|
2828
2989
|
"em_open": "e",
|
|
2829
2990
|
"em_close": "E",
|
|
@@ -2873,6 +3034,7 @@ module.exports = {
|
|
|
2873
3034
|
linkOnlyLineNumbers.push(token.lineNumber);
|
|
2874
3035
|
}
|
|
2875
3036
|
});
|
|
3037
|
+
const { definitionLineIndices } = referenceLinkImageData();
|
|
2876
3038
|
forEachLine(lineMetadata(), (line, lineIndex, inCode, onFence, inTable) => {
|
|
2877
3039
|
const lineNumber = lineIndex + 1;
|
|
2878
3040
|
const isHeading = includesSorted(headingLineNumbers, lineNumber);
|
|
@@ -2885,10 +3047,10 @@ module.exports = {
|
|
|
2885
3047
|
if ((includeCodeBlocks || !inCode) &&
|
|
2886
3048
|
(includeTables || !inTable) &&
|
|
2887
3049
|
(includeHeadings || !isHeading) &&
|
|
3050
|
+
!includesSorted(definitionLineIndices, lineIndex) &&
|
|
2888
3051
|
(strict ||
|
|
2889
3052
|
(!(stern && sternModeRe.test(line)) &&
|
|
2890
|
-
!includesSorted(linkOnlyLineNumbers, lineNumber) &&
|
|
2891
|
-
!linkReferenceDefinitionRe.test(line))) &&
|
|
3053
|
+
!includesSorted(linkOnlyLineNumbers, lineNumber))) &&
|
|
2892
3054
|
lengthRe.test(line)) {
|
|
2893
3055
|
addErrorDetailIf(onError, lineNumber, length, line.length, null, null, [length + 1, line.length - length]);
|
|
2894
3056
|
}
|
|
@@ -3004,7 +3166,7 @@ module.exports = {
|
|
|
3004
3166
|
filterTokens(params, "heading_open", (token) => {
|
|
3005
3167
|
if (headingStyleFor(token) === "atx") {
|
|
3006
3168
|
const { line, lineNumber } = token;
|
|
3007
|
-
const match = /^(#+)([ \t]{2,})
|
|
3169
|
+
const match = /^(#+)([ \t]{2,})\S/.exec(line);
|
|
3008
3170
|
if (match) {
|
|
3009
3171
|
const [, { "length": hashLength }, { "length": spacesLength }] = match;
|
|
3010
3172
|
addErrorContext(onError, lineNumber, line.trim(), null, null, [1, hashLength + spacesLength + 1], {
|
|
@@ -3132,7 +3294,13 @@ module.exports = {
|
|
|
3132
3294
|
"use strict";
|
|
3133
3295
|
// @ts-check
|
|
3134
3296
|
|
|
3135
|
-
const { addErrorDetailIf, filterTokens, isBlankLine } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
3297
|
+
const { addErrorDetailIf, blockquotePrefixRe, filterTokens, isBlankLine } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
3298
|
+
const getBlockQuote = (str, count) => ((str || "")
|
|
3299
|
+
.match(blockquotePrefixRe)[0]
|
|
3300
|
+
.trimEnd()
|
|
3301
|
+
// eslint-disable-next-line unicorn/prefer-spread
|
|
3302
|
+
.concat("\n")
|
|
3303
|
+
.repeat(count));
|
|
3136
3304
|
module.exports = {
|
|
3137
3305
|
"names": ["MD022", "blanks-around-headings", "blanks-around-headers"],
|
|
3138
3306
|
"description": "Headings should be surrounded by blank lines",
|
|
@@ -3152,7 +3320,7 @@ module.exports = {
|
|
|
3152
3320
|
}
|
|
3153
3321
|
}
|
|
3154
3322
|
addErrorDetailIf(onError, topIndex + 1, linesAbove, actualAbove, "Above", lines[topIndex].trim(), null, {
|
|
3155
|
-
"insertText":
|
|
3323
|
+
"insertText": getBlockQuote(lines[topIndex - 1], linesAbove - actualAbove)
|
|
3156
3324
|
});
|
|
3157
3325
|
let actualBelow = 0;
|
|
3158
3326
|
for (let i = 0; i < linesBelow; i++) {
|
|
@@ -3162,7 +3330,7 @@ module.exports = {
|
|
|
3162
3330
|
}
|
|
3163
3331
|
addErrorDetailIf(onError, topIndex + 1, linesBelow, actualBelow, "Below", lines[topIndex].trim(), null, {
|
|
3164
3332
|
"lineNumber": nextIndex + 1,
|
|
3165
|
-
"insertText":
|
|
3333
|
+
"insertText": getBlockQuote(lines[nextIndex], linesBelow - actualBelow)
|
|
3166
3334
|
});
|
|
3167
3335
|
});
|
|
3168
3336
|
}
|
|
@@ -3181,7 +3349,7 @@ module.exports = {
|
|
|
3181
3349
|
// @ts-check
|
|
3182
3350
|
|
|
3183
3351
|
const { addErrorContext, filterTokens } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
3184
|
-
const spaceBeforeHeadingRe = /^(
|
|
3352
|
+
const spaceBeforeHeadingRe = /^(\s+|[>\s]+\s\s)[^>\s]/;
|
|
3185
3353
|
module.exports = {
|
|
3186
3354
|
"names": ["MD023", "heading-start-left", "header-start-left"],
|
|
3187
3355
|
"description": "Headings must start at the beginning of the line",
|
|
@@ -3300,7 +3468,7 @@ module.exports = {
|
|
|
3300
3468
|
// @ts-check
|
|
3301
3469
|
|
|
3302
3470
|
const { addError, allPunctuationNoQuestion, escapeForRegExp, forEachHeading } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
3303
|
-
const endOfLineHtmlEntityRe = /&#?[
|
|
3471
|
+
const endOfLineHtmlEntityRe = /&#?[\da-zA-Z]+;$/;
|
|
3304
3472
|
module.exports = {
|
|
3305
3473
|
"names": ["MD026", "no-trailing-punctuation"],
|
|
3306
3474
|
"description": "Trailing punctuation in heading",
|
|
@@ -3588,9 +3756,8 @@ module.exports = {
|
|
|
3588
3756
|
"use strict";
|
|
3589
3757
|
// @ts-check
|
|
3590
3758
|
|
|
3591
|
-
const { addErrorContext, isBlankLine } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
3759
|
+
const { addErrorContext, blockquotePrefixRe, isBlankLine } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
3592
3760
|
const { flattenedLists } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
3593
|
-
const quotePrefixRe = /^[>\s]*/;
|
|
3594
3761
|
module.exports = {
|
|
3595
3762
|
"names": ["MD032", "blanks-around-lists"],
|
|
3596
3763
|
"description": "Lists should be surrounded by blank lines",
|
|
@@ -3602,7 +3769,7 @@ module.exports = {
|
|
|
3602
3769
|
const firstIndex = list.open.map[0];
|
|
3603
3770
|
if (!isBlankLine(lines[firstIndex - 1])) {
|
|
3604
3771
|
const line = lines[firstIndex];
|
|
3605
|
-
const quotePrefix = line.match(
|
|
3772
|
+
const quotePrefix = line.match(blockquotePrefixRe)[0].trimEnd();
|
|
3606
3773
|
addErrorContext(onError, firstIndex + 1, line.trim(), null, null, null, {
|
|
3607
3774
|
"insertText": `${quotePrefix}\n`
|
|
3608
3775
|
});
|
|
@@ -3610,7 +3777,7 @@ module.exports = {
|
|
|
3610
3777
|
const lastIndex = list.lastLineIndex - 1;
|
|
3611
3778
|
if (!isBlankLine(lines[lastIndex + 1])) {
|
|
3612
3779
|
const line = lines[lastIndex];
|
|
3613
|
-
const quotePrefix = line.match(
|
|
3780
|
+
const quotePrefix = line.match(blockquotePrefixRe)[0].trimEnd();
|
|
3614
3781
|
addErrorContext(onError, lastIndex + 1, line.trim(), null, null, null, {
|
|
3615
3782
|
"lineNumber": lastIndex + 2,
|
|
3616
3783
|
"insertText": `${quotePrefix}\n`
|
|
@@ -3633,12 +3800,12 @@ module.exports = {
|
|
|
3633
3800
|
// @ts-check
|
|
3634
3801
|
|
|
3635
3802
|
const { addError, forEachLine, htmlElementRe, withinAnyRange, unescapeMarkdown } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
3636
|
-
const { codeBlockAndSpanRanges, lineMetadata } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
3637
|
-
const linkDestinationRe =
|
|
3803
|
+
const { codeBlockAndSpanRanges, lineMetadata, referenceLinkImageData } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
3804
|
+
const linkDestinationRe = /\]\(\s*$/;
|
|
3638
3805
|
// See https://spec.commonmark.org/0.29/#autolinks
|
|
3639
3806
|
const emailAddressRe =
|
|
3640
3807
|
// eslint-disable-next-line max-len
|
|
3641
|
-
/^[
|
|
3808
|
+
/^[\w.!#$%&'*+/=?^`{|}~-]+@[a-zA-Z\d](?:[a-zA-Z\d-]{0,61}[a-zA-Z\d])?(?:\.[a-zA-Z\d](?:[a-zA-Z\d-]{0,61}[a-zA-Z\d])?)*$/;
|
|
3642
3809
|
module.exports = {
|
|
3643
3810
|
"names": ["MD033", "no-inline-html"],
|
|
3644
3811
|
"description": "Inline HTML",
|
|
@@ -3648,6 +3815,15 @@ module.exports = {
|
|
|
3648
3815
|
allowedElements = Array.isArray(allowedElements) ? allowedElements : [];
|
|
3649
3816
|
allowedElements = allowedElements.map((element) => element.toLowerCase());
|
|
3650
3817
|
const exclusions = codeBlockAndSpanRanges();
|
|
3818
|
+
const { references, definitionLineIndices } = referenceLinkImageData();
|
|
3819
|
+
for (const datas of references.values()) {
|
|
3820
|
+
for (const data of datas) {
|
|
3821
|
+
const [lineIndex, index, , textLength, labelLength] = data;
|
|
3822
|
+
if (labelLength > 0) {
|
|
3823
|
+
exclusions.push([lineIndex, index + 3 + textLength, labelLength]);
|
|
3824
|
+
}
|
|
3825
|
+
}
|
|
3826
|
+
}
|
|
3651
3827
|
forEachLine(lineMetadata(), (line, lineIndex, inCode) => {
|
|
3652
3828
|
let match = null;
|
|
3653
3829
|
// eslint-disable-next-line no-unmodified-loop-condition
|
|
@@ -3656,12 +3832,13 @@ module.exports = {
|
|
|
3656
3832
|
if (!allowedElements.includes(element.toLowerCase()) &&
|
|
3657
3833
|
!tag.endsWith("\\>") &&
|
|
3658
3834
|
!emailAddressRe.test(content) &&
|
|
3659
|
-
!withinAnyRange(exclusions, lineIndex, match.index,
|
|
3835
|
+
!withinAnyRange(exclusions, lineIndex, match.index, tag.length) &&
|
|
3836
|
+
!definitionLineIndices.includes(lineIndex)) {
|
|
3660
3837
|
const prefix = line.substring(0, match.index);
|
|
3661
3838
|
if (!linkDestinationRe.test(prefix)) {
|
|
3662
3839
|
const unescaped = unescapeMarkdown(prefix + "<", "_");
|
|
3663
3840
|
if (!unescaped.endsWith("_")) {
|
|
3664
|
-
addError(onError, lineIndex + 1, "Element: " + element,
|
|
3841
|
+
addError(onError, lineIndex + 1, "Element: " + element, undefined, [match.index + 1, tag.length]);
|
|
3665
3842
|
}
|
|
3666
3843
|
}
|
|
3667
3844
|
}
|
|
@@ -3682,52 +3859,70 @@ module.exports = {
|
|
|
3682
3859
|
"use strict";
|
|
3683
3860
|
// @ts-check
|
|
3684
3861
|
|
|
3685
|
-
const { addErrorContext,
|
|
3862
|
+
const { addErrorContext, filterTokens, funcExpExec, urlFe, withinAnyRange } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
3863
|
+
const { codeBlockAndSpanRanges, htmlElementRanges, referenceLinkImageData } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
3864
|
+
const htmlLinkRe = /<a(?:\s[^>]*)?>[^<>]*<\/a\s*>/gi;
|
|
3686
3865
|
module.exports = {
|
|
3687
3866
|
"names": ["MD034", "no-bare-urls"],
|
|
3688
3867
|
"description": "Bare URL used",
|
|
3689
3868
|
"tags": ["links", "url"],
|
|
3690
3869
|
"function": function MD034(params, onError) {
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3870
|
+
const { lines } = params;
|
|
3871
|
+
const codeExclusions = [
|
|
3872
|
+
...codeBlockAndSpanRanges(),
|
|
3873
|
+
...htmlElementRanges()
|
|
3874
|
+
];
|
|
3875
|
+
filterTokens(params, "html_block", (token) => {
|
|
3876
|
+
for (let i = token.map[0]; i < token.map[1]; i++) {
|
|
3877
|
+
codeExclusions.push([i, 0, lines[i].length]);
|
|
3878
|
+
}
|
|
3879
|
+
});
|
|
3880
|
+
const { definitionLineIndices } = referenceLinkImageData();
|
|
3881
|
+
for (const [lineIndex, line] of lines.entries()) {
|
|
3882
|
+
if (definitionLineIndices[0] === lineIndex) {
|
|
3883
|
+
definitionLineIndices.shift();
|
|
3884
|
+
}
|
|
3885
|
+
else {
|
|
3695
3886
|
let match = null;
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
else if (type === "link_close") {
|
|
3700
|
-
inLink = false;
|
|
3887
|
+
const lineExclusions = [];
|
|
3888
|
+
while ((match = htmlLinkRe.exec(line)) !== null) {
|
|
3889
|
+
lineExclusions.push([lineIndex, match.index, match[0].length]);
|
|
3701
3890
|
}
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3891
|
+
while ((match = funcExpExec(urlFe, line)) !== null) {
|
|
3892
|
+
const [bareUrl] = match;
|
|
3893
|
+
// @ts-ignore
|
|
3894
|
+
const matchIndex = match.index;
|
|
3895
|
+
const bareUrlLength = bareUrl.length;
|
|
3896
|
+
const prefix = line.slice(0, matchIndex);
|
|
3897
|
+
const postfix = line.slice(matchIndex + bareUrlLength);
|
|
3898
|
+
if (
|
|
3899
|
+
// Allow <...> to avoid reporting non-bare links
|
|
3900
|
+
!(prefix.endsWith("<") && postfix.startsWith(">")) &&
|
|
3901
|
+
// Allow >...</ to avoid reporting <code>...</code>
|
|
3902
|
+
!(prefix.endsWith(">") && postfix.startsWith("</")) &&
|
|
3903
|
+
// Allow "..." and '...' to allow quoting a bare link
|
|
3904
|
+
!(prefix.endsWith("\"") && postfix.startsWith("\"")) &&
|
|
3905
|
+
!(prefix.endsWith("'") && postfix.startsWith("'")) &&
|
|
3906
|
+
// Allow ](... to avoid reporting Markdown-style links
|
|
3907
|
+
!(/\]\(\s*$/.test(prefix)) &&
|
|
3908
|
+
// Allow [...] to avoid MD011/no-reversed-links and nested links
|
|
3909
|
+
!(/\[[^\]]*$/.test(prefix) && /^[^[]*\]/.test(postfix)) &&
|
|
3910
|
+
!withinAnyRange(lineExclusions, lineIndex, matchIndex, bareUrlLength) &&
|
|
3911
|
+
!withinAnyRange(codeExclusions, lineIndex, matchIndex, bareUrlLength)) {
|
|
3912
|
+
const range = [
|
|
3913
|
+
matchIndex + 1,
|
|
3914
|
+
bareUrlLength
|
|
3915
|
+
];
|
|
3916
|
+
const fixInfo = {
|
|
3917
|
+
"editColumn": range[0],
|
|
3918
|
+
"deleteCount": range[1],
|
|
3919
|
+
"insertText": `<${bareUrl}>`
|
|
3920
|
+
};
|
|
3921
|
+
addErrorContext(onError, lineIndex + 1, bareUrl, null, null, range, fixInfo);
|
|
3727
3922
|
}
|
|
3728
3923
|
}
|
|
3729
3924
|
}
|
|
3730
|
-
}
|
|
3925
|
+
}
|
|
3731
3926
|
}
|
|
3732
3927
|
};
|
|
3733
3928
|
|
|
@@ -3753,7 +3948,7 @@ module.exports = {
|
|
|
3753
3948
|
filterTokens(params, "hr", (token) => {
|
|
3754
3949
|
const { line, lineNumber } = token;
|
|
3755
3950
|
let { markup } = token;
|
|
3756
|
-
const match = line.match(/[_*\-\s
|
|
3951
|
+
const match = line.match(/[_*\-\s]+$/);
|
|
3757
3952
|
if (match) {
|
|
3758
3953
|
markup = match[0].trim();
|
|
3759
3954
|
}
|
|
@@ -3842,10 +4037,10 @@ module.exports = {
|
|
|
3842
4037
|
"use strict";
|
|
3843
4038
|
// @ts-check
|
|
3844
4039
|
|
|
3845
|
-
const { addErrorContext, emphasisMarkersInContent, forEachLine, isBlankLine } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
3846
|
-
const { lineMetadata } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
3847
|
-
const emphasisRe = /(^|[^\\]|\\\\)(?:(
|
|
3848
|
-
const embeddedUnderscoreRe = /([A-Za-
|
|
4040
|
+
const { addErrorContext, emphasisMarkersInContent, forEachLine, isBlankLine, withinAnyRange } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
4041
|
+
const { htmlElementRanges, lineMetadata } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
4042
|
+
const emphasisRe = /(^|[^\\]|\\\\)(?:(\*{1,3})|(_{1,3}))/g;
|
|
4043
|
+
const embeddedUnderscoreRe = /([A-Za-z\d])_([A-Za-z\d])/g;
|
|
3849
4044
|
const asteriskListItemMarkerRe = /^([\s>]*)\*(\s+)/;
|
|
3850
4045
|
const leftSpaceRe = /^\s+/;
|
|
3851
4046
|
const rightSpaceRe = /\s+$/;
|
|
@@ -3855,6 +4050,7 @@ module.exports = {
|
|
|
3855
4050
|
"description": "Spaces inside emphasis markers",
|
|
3856
4051
|
"tags": ["whitespace", "emphasis"],
|
|
3857
4052
|
"function": function MD037(params, onError) {
|
|
4053
|
+
const exclusions = htmlElementRanges();
|
|
3858
4054
|
// eslint-disable-next-line init-declarations
|
|
3859
4055
|
let effectiveEmphasisLength, emphasisIndex, emphasisKind, emphasisLength, pendingError = null;
|
|
3860
4056
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
@@ -3882,25 +4078,27 @@ module.exports = {
|
|
|
3882
4078
|
// Report the violation
|
|
3883
4079
|
const contextStart = emphasisIndex - emphasisLength;
|
|
3884
4080
|
const contextEnd = matchIndex + contextLength;
|
|
3885
|
-
const context = line.substring(contextStart, contextEnd);
|
|
3886
4081
|
const column = contextStart + 1;
|
|
3887
4082
|
const length = contextEnd - contextStart;
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
4083
|
+
if (!withinAnyRange(exclusions, lineIndex, column, length)) {
|
|
4084
|
+
const context = line.substring(contextStart, contextEnd);
|
|
4085
|
+
const leftMarker = line.substring(contextStart, emphasisIndex);
|
|
4086
|
+
const rightMarker = match ? (match[2] || match[3]) : "";
|
|
4087
|
+
const fixedText = `${leftMarker}${content.trim()}${rightMarker}`;
|
|
4088
|
+
return [
|
|
4089
|
+
onError,
|
|
4090
|
+
lineIndex + 1,
|
|
4091
|
+
context,
|
|
4092
|
+
leftSpace,
|
|
4093
|
+
rightSpace,
|
|
4094
|
+
[column, length],
|
|
4095
|
+
{
|
|
4096
|
+
"editColumn": column,
|
|
4097
|
+
"deleteCount": length,
|
|
4098
|
+
"insertText": fixedText
|
|
4099
|
+
}
|
|
4100
|
+
];
|
|
4101
|
+
}
|
|
3904
4102
|
}
|
|
3905
4103
|
return null;
|
|
3906
4104
|
}
|
|
@@ -4013,7 +4211,7 @@ module.exports = {
|
|
|
4013
4211
|
// @ts-check
|
|
4014
4212
|
|
|
4015
4213
|
const { addErrorContext, filterTokens, forEachInlineCodeSpan, newLineRe } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
4016
|
-
const leftSpaceRe = /^\s([^`]|$)/;
|
|
4214
|
+
const leftSpaceRe = /^\s(?:[^`]|$)/;
|
|
4017
4215
|
const rightSpaceRe = /[^`]\s$/;
|
|
4018
4216
|
const spaceInsideCodeInline = (token) => ((token.type === "code_inline") &&
|
|
4019
4217
|
(leftSpaceRe.test(token.content) || rightSpaceRe.test(token.content)));
|
|
@@ -4076,7 +4274,7 @@ module.exports = {
|
|
|
4076
4274
|
// @ts-check
|
|
4077
4275
|
|
|
4078
4276
|
const { addErrorContext, filterTokens } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
4079
|
-
const spaceInLinkRe = /\[(?:\s
|
|
4277
|
+
const spaceInLinkRe = /\[(?:\s[^\]]*|[^\]]*?\s)\](?=(\([^)]*\)|\[[^\]]*\]))/;
|
|
4080
4278
|
module.exports = {
|
|
4081
4279
|
"names": ["MD039", "no-space-in-links"],
|
|
4082
4280
|
"description": "Spaces inside link text",
|
|
@@ -4143,16 +4341,26 @@ module.exports = {
|
|
|
4143
4341
|
"use strict";
|
|
4144
4342
|
// @ts-check
|
|
4145
4343
|
|
|
4146
|
-
const { addErrorContext, filterTokens } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
4344
|
+
const { addError, addErrorContext, filterTokens } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
4147
4345
|
module.exports = {
|
|
4148
4346
|
"names": ["MD040", "fenced-code-language"],
|
|
4149
4347
|
"description": "Fenced code blocks should have a language specified",
|
|
4150
4348
|
"tags": ["code", "language"],
|
|
4151
4349
|
"function": function MD040(params, onError) {
|
|
4350
|
+
let allowed = params.config.allowed_languages;
|
|
4351
|
+
allowed = Array.isArray(allowed) ? allowed : [];
|
|
4352
|
+
const languageOnly = !!params.config.language_only;
|
|
4152
4353
|
filterTokens(params, "fence", function forToken(token) {
|
|
4153
|
-
|
|
4354
|
+
const lang = token.info.trim().split(/\s+/u).shift();
|
|
4355
|
+
if (lang === "") {
|
|
4154
4356
|
addErrorContext(onError, token.lineNumber, token.line);
|
|
4155
4357
|
}
|
|
4358
|
+
else if ((allowed.length > 0) && !allowed.includes(lang)) {
|
|
4359
|
+
addError(onError, token.lineNumber, `"${lang}" is not allowed`);
|
|
4360
|
+
}
|
|
4361
|
+
if (languageOnly && (token.info !== lang)) {
|
|
4362
|
+
addError(onError, token.lineNumber, `Info string contains more than language: "${token.info}"`);
|
|
4363
|
+
}
|
|
4156
4364
|
});
|
|
4157
4365
|
}
|
|
4158
4366
|
};
|
|
@@ -4278,6 +4486,7 @@ module.exports = {
|
|
|
4278
4486
|
"tags": ["headings", "headers"],
|
|
4279
4487
|
"function": function MD043(params, onError) {
|
|
4280
4488
|
const requiredHeadings = params.config.headings || params.config.headers;
|
|
4489
|
+
const matchCase = params.config.match_case || false;
|
|
4281
4490
|
if (Array.isArray(requiredHeadings)) {
|
|
4282
4491
|
const levels = {};
|
|
4283
4492
|
for (const level of [1, 2, 3, 4, 5, 6]) {
|
|
@@ -4288,6 +4497,7 @@ module.exports = {
|
|
|
4288
4497
|
let hasError = false;
|
|
4289
4498
|
let anyHeadings = false;
|
|
4290
4499
|
const getExpected = () => requiredHeadings[i++] || "[None]";
|
|
4500
|
+
const handleCase = (str) => (matchCase ? str : str.toLowerCase());
|
|
4291
4501
|
forEachHeading(params, (heading, content) => {
|
|
4292
4502
|
if (!hasError) {
|
|
4293
4503
|
anyHeadings = true;
|
|
@@ -4295,7 +4505,7 @@ module.exports = {
|
|
|
4295
4505
|
const expected = getExpected();
|
|
4296
4506
|
if (expected === "*") {
|
|
4297
4507
|
const nextExpected = getExpected();
|
|
4298
|
-
if (nextExpected
|
|
4508
|
+
if (handleCase(nextExpected) !== handleCase(actual)) {
|
|
4299
4509
|
matchAny = true;
|
|
4300
4510
|
i--;
|
|
4301
4511
|
}
|
|
@@ -4303,7 +4513,7 @@ module.exports = {
|
|
|
4303
4513
|
else if (expected === "+") {
|
|
4304
4514
|
matchAny = true;
|
|
4305
4515
|
}
|
|
4306
|
-
else if (expected
|
|
4516
|
+
else if (handleCase(expected) === handleCase(actual)) {
|
|
4307
4517
|
matchAny = false;
|
|
4308
4518
|
}
|
|
4309
4519
|
else if (matchAny) {
|
|
@@ -4338,7 +4548,7 @@ module.exports = {
|
|
|
4338
4548
|
"use strict";
|
|
4339
4549
|
// @ts-check
|
|
4340
4550
|
|
|
4341
|
-
const { addErrorDetailIf,
|
|
4551
|
+
const { addErrorDetailIf, escapeForRegExp, forEachLine, forEachLink, funcExpExec, linkReferenceDefinitionRe, urlFe, withinAnyRange } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
4342
4552
|
const { codeBlockAndSpanRanges, htmlElementRanges, lineMetadata } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
4343
4553
|
module.exports = {
|
|
4344
4554
|
"names": ["MD044", "proper-names"],
|
|
@@ -4359,7 +4569,8 @@ module.exports = {
|
|
|
4359
4569
|
}
|
|
4360
4570
|
else {
|
|
4361
4571
|
let match = null;
|
|
4362
|
-
while ((match =
|
|
4572
|
+
while ((match = funcExpExec(urlFe, line)) !== null) {
|
|
4573
|
+
// @ts-ignore
|
|
4363
4574
|
exclusions.push([lineIndex, match.index, match[0].length]);
|
|
4364
4575
|
}
|
|
4365
4576
|
forEachLink(line, (index, _, text, destination) => {
|
|
@@ -4599,9 +4810,10 @@ module.exports = [
|
|
|
4599
4810
|
"use strict";
|
|
4600
4811
|
// @ts-check
|
|
4601
4812
|
|
|
4602
|
-
const { addError, escapeForRegExp, filterTokens, forEachInlineChild, forEachHeading, htmlElementRe } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
4813
|
+
const { addError, addErrorDetailIf, escapeForRegExp, filterTokens, forEachInlineChild, forEachHeading, htmlElementRe } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
4603
4814
|
// Regular expression for identifying HTML anchor names
|
|
4604
|
-
const
|
|
4815
|
+
const idRe = /\sid\s*=\s*['"]?([^'"\s>]+)/iu;
|
|
4816
|
+
const nameRe = /\sname\s*=\s*['"]?([^'"\s>]+)/iu;
|
|
4605
4817
|
/**
|
|
4606
4818
|
* Converts a Markdown heading into an HTML fragment according to the rules
|
|
4607
4819
|
* used by GitHub.
|
|
@@ -4643,11 +4855,10 @@ module.exports = {
|
|
|
4643
4855
|
let match = null;
|
|
4644
4856
|
while ((match = htmlElementRe.exec(token.content)) !== null) {
|
|
4645
4857
|
const [tag, , element] = match;
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
}
|
|
4858
|
+
const anchorMatch = idRe.exec(tag) ||
|
|
4859
|
+
(element.toLowerCase() === "a" && nameRe.exec(tag));
|
|
4860
|
+
if (anchorMatch) {
|
|
4861
|
+
fragments.set(`#${anchorMatch[1]}`, 0);
|
|
4651
4862
|
}
|
|
4652
4863
|
}
|
|
4653
4864
|
};
|
|
@@ -4661,12 +4872,31 @@ module.exports = {
|
|
|
4661
4872
|
if (id && (id.length > 1) && (id[0] === "#") && !fragments.has(id)) {
|
|
4662
4873
|
let context = id;
|
|
4663
4874
|
let range = null;
|
|
4875
|
+
let fixInfo = null;
|
|
4664
4876
|
const match = line.match(new RegExp(`\\[.*?\\]\\(${escapeForRegExp(context)}\\)`));
|
|
4665
4877
|
if (match) {
|
|
4666
|
-
context = match
|
|
4667
|
-
|
|
4878
|
+
[context] = match;
|
|
4879
|
+
const index = match.index;
|
|
4880
|
+
const length = context.length;
|
|
4881
|
+
range = [index + 1, length];
|
|
4882
|
+
fixInfo = {
|
|
4883
|
+
"editColumn": index + (length - id.length),
|
|
4884
|
+
"deleteCount": id.length,
|
|
4885
|
+
"insertText": null
|
|
4886
|
+
};
|
|
4887
|
+
}
|
|
4888
|
+
const idLower = id.toLowerCase();
|
|
4889
|
+
const mixedCaseKey = [...fragments.keys()]
|
|
4890
|
+
.find((key) => idLower === key.toLowerCase());
|
|
4891
|
+
if (mixedCaseKey) {
|
|
4892
|
+
(fixInfo || {}).insertText = mixedCaseKey;
|
|
4893
|
+
addErrorDetailIf(onError, lineNumber, mixedCaseKey, id, undefined, context, range, fixInfo);
|
|
4894
|
+
}
|
|
4895
|
+
else {
|
|
4896
|
+
addError(onError, lineNumber, undefined, context,
|
|
4897
|
+
// @ts-ignore
|
|
4898
|
+
range);
|
|
4668
4899
|
}
|
|
4669
|
-
addError(onError, lineNumber, undefined, context, range);
|
|
4670
4900
|
}
|
|
4671
4901
|
});
|
|
4672
4902
|
}
|
|
@@ -4727,7 +4957,8 @@ module.exports = {
|
|
|
4727
4957
|
"description": "Link and image reference definitions should be needed",
|
|
4728
4958
|
"tags": ["images", "links"],
|
|
4729
4959
|
"function": function MD053(params, onError) {
|
|
4730
|
-
const
|
|
4960
|
+
const ignored = new Set(params.config.ignored_definitions || ["//"]);
|
|
4961
|
+
const lines = params.lines;
|
|
4731
4962
|
const { references, shortcuts, definitions, duplicateDefinitions } = referenceLinkImageData();
|
|
4732
4963
|
const singleLineDefinition = (line) => (line.replace(linkReferenceDefinitionRe, "").trim().length > 0);
|
|
4733
4964
|
const deleteFixInfo = {
|
|
@@ -4736,7 +4967,9 @@ module.exports = {
|
|
|
4736
4967
|
// Look for unused link references (unreferenced by any link/image)
|
|
4737
4968
|
for (const definition of definitions.entries()) {
|
|
4738
4969
|
const [label, lineIndex] = definition;
|
|
4739
|
-
if (!
|
|
4970
|
+
if (!ignored.has(label) &&
|
|
4971
|
+
!references.has(label) &&
|
|
4972
|
+
!shortcuts.has(label)) {
|
|
4740
4973
|
const line = lines[lineIndex];
|
|
4741
4974
|
addError(onError, lineIndex + 1, `Unused link or image reference definition: "${label}"`, ellipsify(line), [1, line.length], singleLineDefinition(line) ? deleteFixInfo : 0);
|
|
4742
4975
|
}
|
|
@@ -4744,8 +4977,10 @@ module.exports = {
|
|
|
4744
4977
|
// Look for duplicate link references (defined more than once)
|
|
4745
4978
|
for (const duplicateDefinition of duplicateDefinitions) {
|
|
4746
4979
|
const [label, lineIndex] = duplicateDefinition;
|
|
4747
|
-
|
|
4748
|
-
|
|
4980
|
+
if (!ignored.has(label)) {
|
|
4981
|
+
const line = lines[lineIndex];
|
|
4982
|
+
addError(onError, lineIndex + 1, `Duplicate link or image reference definition: "${label}"`, ellipsify(line), [1, line.length], singleLineDefinition(line) ? deleteFixInfo : 0);
|
|
4983
|
+
}
|
|
4749
4984
|
}
|
|
4750
4985
|
}
|
|
4751
4986
|
};
|
|
@@ -4817,7 +5052,7 @@ for (const rule of rules) {
|
|
|
4817
5052
|
const name = rule.names[0].toLowerCase();
|
|
4818
5053
|
// eslint-disable-next-line dot-notation
|
|
4819
5054
|
rule["information"] =
|
|
4820
|
-
new URL(`${homepage}/blob/v${version}/doc
|
|
5055
|
+
new URL(`${homepage}/blob/v${version}/doc/${name}.md`);
|
|
4821
5056
|
}
|
|
4822
5057
|
module.exports = rules;
|
|
4823
5058
|
|