markdownlint 0.35.0 → 0.36.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/CHANGELOG.md +10 -0
- package/README.md +72 -35
- package/demo/markdownlint-browser.js +1258 -1214
- package/doc/CustomRules.md +55 -249
- package/doc/Rules.md +36 -29
- package/doc/md003.md +2 -2
- package/doc/md004.md +4 -3
- package/doc/md035.md +3 -8
- package/doc/md046.md +2 -2
- package/doc/md048.md +3 -2
- package/doc/md049.md +4 -3
- package/doc/md050.md +4 -4
- package/doc/md051.md +11 -3
- package/doc/md055.md +3 -2
- package/helpers/README.md +2 -19
- package/helpers/helpers.js +87 -347
- package/helpers/micromark-helpers.cjs +296 -0
- package/helpers/micromark-parse.cjs +313 -0
- package/helpers/package.json +5 -2
- package/helpers/shared.js +6 -0
- package/helpers/test.cjs +28 -0
- package/lib/cache.js +3 -3
- package/lib/configuration-strict.d.ts +120 -106
- package/lib/constants.js +1 -1
- package/lib/markdownit.cjs +172 -0
- package/lib/markdownlint.d.ts +41 -3
- package/lib/markdownlint.js +153 -115
- package/lib/md001.js +1 -1
- package/lib/md003.js +1 -1
- package/lib/md004.js +3 -3
- package/lib/md007.js +3 -3
- package/lib/md009.js +1 -1
- package/lib/md010.js +18 -14
- package/lib/md011.js +24 -23
- package/lib/md012.js +1 -1
- package/lib/md013.js +1 -1
- package/lib/md014.js +5 -9
- package/lib/md018.js +1 -1
- package/lib/md019-md021.js +1 -1
- package/lib/md020.js +2 -2
- package/lib/md022.js +9 -15
- package/lib/md024.js +1 -1
- package/lib/md025.js +1 -1
- package/lib/md027.js +2 -2
- package/lib/md029.js +3 -3
- package/lib/md031.js +8 -6
- package/lib/md032.js +27 -15
- package/lib/md033.js +1 -1
- package/lib/md034.js +21 -29
- package/lib/md036.js +18 -24
- package/lib/md037.js +1 -1
- package/lib/md038.js +9 -14
- package/lib/md039.js +13 -15
- package/lib/md040.js +11 -13
- package/lib/md041.js +4 -4
- package/lib/md042.js +2 -6
- package/lib/md043.js +1 -1
- package/lib/md044.js +31 -28
- package/lib/md045.js +2 -2
- package/lib/md048.js +28 -17
- package/lib/md049-md050.js +20 -5
- package/lib/md051.js +16 -18
- package/lib/md053.js +5 -4
- package/lib/md054.js +10 -12
- package/lib/md055.js +39 -46
- package/lib/md056.js +31 -36
- package/lib/md058.js +29 -14
- package/package.json +14 -13
- package/schema/.markdownlint.jsonc +55 -52
- package/schema/.markdownlint.yaml +54 -52
- package/schema/markdownlint-config-schema-strict.json +132 -110
- package/schema/markdownlint-config-schema.json +132 -110
- package/helpers/micromark.cjs +0 -544
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! markdownlint 0.
|
|
1
|
+
/*! markdownlint 0.36.0 https://github.com/DavidAnson/markdownlint @license MIT */
|
|
2
2
|
var markdownlint;
|
|
3
3
|
/******/ (() => { // webpackBootstrap
|
|
4
4
|
/******/ var __webpack_modules__ = ({
|
|
@@ -14,30 +14,25 @@ var markdownlint;
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
const micromark = __webpack_require__(/*! ./micromark.cjs */ "../helpers/micromark.cjs");
|
|
17
|
+
const micromark = __webpack_require__(/*! ./micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
18
18
|
|
|
19
19
|
const { newLineRe, nextLinesRe } = __webpack_require__(/*! ./shared.js */ "../helpers/shared.js");
|
|
20
20
|
|
|
21
21
|
module.exports.newLineRe = newLineRe;
|
|
22
22
|
module.exports.nextLinesRe = nextLinesRe;
|
|
23
23
|
|
|
24
|
+
/** @typedef {import("../lib/markdownlint.js").RuleOnError} RuleOnError */
|
|
25
|
+
/** @typedef {import("../lib/markdownlint.js").RuleOnErrorFixInfo} RuleOnErrorFixInfo */
|
|
26
|
+
|
|
24
27
|
// Regular expression for matching common front matter (YAML and TOML)
|
|
25
28
|
module.exports.frontMatterRe =
|
|
26
|
-
/((
|
|
29
|
+
/((^---[^\S\r\n\u2028\u2029]*$[\s\S]+?^---\s*)|(^\+\+\+[^\S\r\n\u2028\u2029]*$[\s\S]+?^(\+\+\+|\.\.\.)\s*)|(^\{[^\S\r\n\u2028\u2029]*$[\s\S]+?^\}\s*))(\r\n|\r|\n|$)/m;
|
|
27
30
|
|
|
28
31
|
// Regular expression for matching the start of inline disable/enable comments
|
|
29
32
|
const inlineCommentStartRe =
|
|
30
33
|
/(<!--\s*markdownlint-(disable|enable|capture|restore|disable-file|enable-file|disable-line|disable-next-line|configure-file))(?:\s|-->)/gi;
|
|
31
34
|
module.exports.inlineCommentStartRe = inlineCommentStartRe;
|
|
32
35
|
|
|
33
|
-
// Regular expression for blockquote prefixes
|
|
34
|
-
const blockquotePrefixRe = /^[>\s]*/;
|
|
35
|
-
module.exports.blockquotePrefixRe = blockquotePrefixRe;
|
|
36
|
-
|
|
37
|
-
// Regular expression for link reference definitions
|
|
38
|
-
const linkReferenceDefinitionRe = /^ {0,3}\[([^\]]*[^\\])\]:/;
|
|
39
|
-
module.exports.linkReferenceDefinitionRe = linkReferenceDefinitionRe;
|
|
40
|
-
|
|
41
36
|
// Regular expression for identifying an HTML entity at the end of a line
|
|
42
37
|
module.exports.endOfLineHtmlEntityRe =
|
|
43
38
|
/&(?:#\d+|#[xX][\da-fA-F]+|[a-zA-Z]{2,31}|blk\d{2}|emsp1[34]|frac\d{2}|sup\d|there4);$/;
|
|
@@ -235,99 +230,6 @@ module.exports.escapeForRegExp = function escapeForRegExp(str) {
|
|
|
235
230
|
return str.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
236
231
|
};
|
|
237
232
|
|
|
238
|
-
/**
|
|
239
|
-
* Return the string representation of a fence markup character.
|
|
240
|
-
*
|
|
241
|
-
* @param {string} markup Fence string.
|
|
242
|
-
* @returns {string} String representation.
|
|
243
|
-
*/
|
|
244
|
-
module.exports.fencedCodeBlockStyleFor =
|
|
245
|
-
function fencedCodeBlockStyleFor(markup) {
|
|
246
|
-
switch (markup[0]) {
|
|
247
|
-
case "~":
|
|
248
|
-
return "tilde";
|
|
249
|
-
default:
|
|
250
|
-
return "backtick";
|
|
251
|
-
}
|
|
252
|
-
};
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Return the string representation of a emphasis or strong markup character.
|
|
256
|
-
*
|
|
257
|
-
* @param {string} markup Emphasis or strong string.
|
|
258
|
-
* @returns {"asterisk" | "underscore"} String representation.
|
|
259
|
-
*/
|
|
260
|
-
module.exports.emphasisOrStrongStyleFor =
|
|
261
|
-
function emphasisOrStrongStyleFor(markup) {
|
|
262
|
-
switch (markup[0]) {
|
|
263
|
-
case "*":
|
|
264
|
-
return "asterisk";
|
|
265
|
-
default:
|
|
266
|
-
return "underscore";
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* @callback InlineCodeSpanCallback
|
|
272
|
-
* @param {string} code Code content.
|
|
273
|
-
* @param {number} lineIndex Line index (0-based).
|
|
274
|
-
* @param {number} columnIndex Column index (0-based).
|
|
275
|
-
* @param {number} ticks Count of backticks.
|
|
276
|
-
* @returns {void}
|
|
277
|
-
*/
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* Calls the provided function for each inline code span's content.
|
|
281
|
-
*
|
|
282
|
-
* @param {string} input Markdown content.
|
|
283
|
-
* @param {InlineCodeSpanCallback} handler Callback function taking (code,
|
|
284
|
-
* lineIndex, columnIndex, ticks).
|
|
285
|
-
* @returns {void}
|
|
286
|
-
*/
|
|
287
|
-
function forEachInlineCodeSpan(input, handler) {
|
|
288
|
-
const backtickRe = /`+/g;
|
|
289
|
-
let match = null;
|
|
290
|
-
const backticksLengthAndIndex = [];
|
|
291
|
-
while ((match = backtickRe.exec(input)) !== null) {
|
|
292
|
-
backticksLengthAndIndex.push([ match[0].length, match.index ]);
|
|
293
|
-
}
|
|
294
|
-
const newLinesIndex = [];
|
|
295
|
-
while ((match = newLineRe.exec(input)) !== null) {
|
|
296
|
-
newLinesIndex.push(match.index);
|
|
297
|
-
}
|
|
298
|
-
let lineIndex = 0;
|
|
299
|
-
let lineStartIndex = 0;
|
|
300
|
-
let k = 0;
|
|
301
|
-
for (let i = 0; i < backticksLengthAndIndex.length - 1; i++) {
|
|
302
|
-
const [ startLength, startIndex ] = backticksLengthAndIndex[i];
|
|
303
|
-
if ((startIndex === 0) || (input[startIndex - 1] !== "\\")) {
|
|
304
|
-
for (let j = i + 1; j < backticksLengthAndIndex.length; j++) {
|
|
305
|
-
const [ endLength, endIndex ] = backticksLengthAndIndex[j];
|
|
306
|
-
if (startLength === endLength) {
|
|
307
|
-
for (; k < newLinesIndex.length; k++) {
|
|
308
|
-
const newLineIndex = newLinesIndex[k];
|
|
309
|
-
if (startIndex < newLineIndex) {
|
|
310
|
-
break;
|
|
311
|
-
}
|
|
312
|
-
lineIndex++;
|
|
313
|
-
lineStartIndex = newLineIndex + 1;
|
|
314
|
-
}
|
|
315
|
-
const columnIndex = startIndex - lineStartIndex + startLength;
|
|
316
|
-
handler(
|
|
317
|
-
input.slice(startIndex + startLength, endIndex),
|
|
318
|
-
lineIndex,
|
|
319
|
-
columnIndex,
|
|
320
|
-
startLength
|
|
321
|
-
);
|
|
322
|
-
i = j;
|
|
323
|
-
break;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
module.exports.forEachInlineCodeSpan = forEachInlineCodeSpan;
|
|
330
|
-
|
|
331
233
|
/**
|
|
332
234
|
* Adds ellipsis to the left/right/middle of the specified text.
|
|
333
235
|
*
|
|
@@ -353,12 +255,12 @@ module.exports.ellipsify = ellipsify;
|
|
|
353
255
|
/**
|
|
354
256
|
* Adds a generic error object via the onError callback.
|
|
355
257
|
*
|
|
356
|
-
* @param {
|
|
258
|
+
* @param {RuleOnError} onError RuleOnError instance.
|
|
357
259
|
* @param {number} lineNumber Line number.
|
|
358
260
|
* @param {string} [detail] Error details.
|
|
359
261
|
* @param {string} [context] Error context.
|
|
360
262
|
* @param {number[]} [range] Column and length of error.
|
|
361
|
-
* @param {
|
|
263
|
+
* @param {RuleOnErrorFixInfo} [fixInfo] RuleOnErrorFixInfo instance.
|
|
362
264
|
* @returns {void}
|
|
363
265
|
*/
|
|
364
266
|
function addError(onError, lineNumber, detail, context, range, fixInfo) {
|
|
@@ -375,14 +277,14 @@ module.exports.addError = addError;
|
|
|
375
277
|
/**
|
|
376
278
|
* Adds an error object with details conditionally via the onError callback.
|
|
377
279
|
*
|
|
378
|
-
* @param {
|
|
280
|
+
* @param {RuleOnError} onError RuleOnError instance.
|
|
379
281
|
* @param {number} lineNumber Line number.
|
|
380
282
|
* @param {Object} expected Expected value.
|
|
381
283
|
* @param {Object} actual Actual value.
|
|
382
284
|
* @param {string} [detail] Error details.
|
|
383
285
|
* @param {string} [context] Error context.
|
|
384
286
|
* @param {number[]} [range] Column and length of error.
|
|
385
|
-
* @param {
|
|
287
|
+
* @param {RuleOnErrorFixInfo} [fixInfo] RuleOnErrorFixInfo instance.
|
|
386
288
|
* @returns {void}
|
|
387
289
|
*/
|
|
388
290
|
function addErrorDetailIf(
|
|
@@ -403,13 +305,13 @@ module.exports.addErrorDetailIf = addErrorDetailIf;
|
|
|
403
305
|
/**
|
|
404
306
|
* Adds an error object with context via the onError callback.
|
|
405
307
|
*
|
|
406
|
-
* @param {
|
|
308
|
+
* @param {RuleOnError} onError RuleOnError instance.
|
|
407
309
|
* @param {number} lineNumber Line number.
|
|
408
310
|
* @param {string} context Error context.
|
|
409
311
|
* @param {boolean} [start] True iff the start of the text is important.
|
|
410
312
|
* @param {boolean} [end] True iff the end of the text is important.
|
|
411
313
|
* @param {number[]} [range] Column and length of error.
|
|
412
|
-
* @param {
|
|
314
|
+
* @param {RuleOnErrorFixInfo} [fixInfo] RuleOnErrorFixInfo instance.
|
|
413
315
|
* @returns {void}
|
|
414
316
|
*/
|
|
415
317
|
function addErrorContext(
|
|
@@ -420,50 +322,42 @@ function addErrorContext(
|
|
|
420
322
|
module.exports.addErrorContext = addErrorContext;
|
|
421
323
|
|
|
422
324
|
/**
|
|
423
|
-
*
|
|
325
|
+
* Defines a range within a file (start line/column to end line/column, subset of MicromarkToken).
|
|
424
326
|
*
|
|
425
|
-
* @
|
|
426
|
-
* @
|
|
427
|
-
* @
|
|
428
|
-
* @
|
|
429
|
-
* @
|
|
327
|
+
* @typedef {Object} FileRange
|
|
328
|
+
* @property {number} startLine Start line (1-based).
|
|
329
|
+
* @property {number} startColumn Start column (1-based).
|
|
330
|
+
* @property {number} endLine End line (1-based).
|
|
331
|
+
* @property {number} endColumn End column (1-based).
|
|
430
332
|
*/
|
|
431
|
-
function addErrorContextForLine(onError, lines, lineIndex, lineNumber) {
|
|
432
|
-
const line = lines[lineIndex];
|
|
433
|
-
// @ts-ignore
|
|
434
|
-
const quotePrefix = line.match(blockquotePrefixRe)[0].trimEnd();
|
|
435
|
-
addErrorContext(
|
|
436
|
-
onError,
|
|
437
|
-
lineIndex + 1,
|
|
438
|
-
line.trim(),
|
|
439
|
-
undefined,
|
|
440
|
-
undefined,
|
|
441
|
-
undefined,
|
|
442
|
-
{
|
|
443
|
-
lineNumber,
|
|
444
|
-
"insertText": `${quotePrefix}\n`
|
|
445
|
-
}
|
|
446
|
-
);
|
|
447
|
-
}
|
|
448
|
-
module.exports.addErrorContextForLine = addErrorContextForLine;
|
|
449
333
|
|
|
450
334
|
/**
|
|
451
|
-
*
|
|
335
|
+
* Returns whether line/column A is less than or equal to line/column B.
|
|
452
336
|
*
|
|
453
|
-
* @param {number
|
|
454
|
-
* @param {number}
|
|
455
|
-
* @param {number}
|
|
456
|
-
* @param {number}
|
|
457
|
-
* @returns {boolean} True iff
|
|
337
|
+
* @param {number} lineA Line A.
|
|
338
|
+
* @param {number} columnA Column A.
|
|
339
|
+
* @param {number} lineB Line B.
|
|
340
|
+
* @param {number} columnB Column B.
|
|
341
|
+
* @returns {boolean} True iff A is less than or equal to B.
|
|
458
342
|
*/
|
|
459
|
-
const
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
(index < span[1]) ||
|
|
463
|
-
(index + length > span[1] + span[2])
|
|
464
|
-
))
|
|
343
|
+
const positionLessThanOrEqual = (lineA, columnA, lineB, columnB) => (
|
|
344
|
+
(lineA < lineB) ||
|
|
345
|
+
((lineA === lineB) && (columnA <= columnB))
|
|
465
346
|
);
|
|
466
|
-
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Returns whether two ranges (or MicromarkTokens) overlap anywhere.
|
|
350
|
+
*
|
|
351
|
+
* @param {FileRange|import("../lib/markdownlint.js").MicromarkToken} rangeA Range A.
|
|
352
|
+
* @param {FileRange|import("../lib/markdownlint.js").MicromarkToken} rangeB Range B.
|
|
353
|
+
* @returns {boolean} True iff the two ranges overlap.
|
|
354
|
+
*/
|
|
355
|
+
module.exports.hasOverlap = function hasOverlap(rangeA, rangeB) {
|
|
356
|
+
const lte = positionLessThanOrEqual(rangeA.startLine, rangeA.startColumn, rangeB.startLine, rangeB.startColumn);
|
|
357
|
+
const first = lte ? rangeA : rangeB;
|
|
358
|
+
const second = lte ? rangeB : rangeA;
|
|
359
|
+
return positionLessThanOrEqual(second.startLine, second.startColumn, first.endLine, first.endColumn);
|
|
360
|
+
};
|
|
467
361
|
|
|
468
362
|
// Determines if the front matter includes a title
|
|
469
363
|
module.exports.frontMatterHasTitle =
|
|
@@ -482,16 +376,28 @@ module.exports.frontMatterHasTitle =
|
|
|
482
376
|
/**
|
|
483
377
|
* Returns an object with information about reference links and images.
|
|
484
378
|
*
|
|
485
|
-
* @param {import("../helpers/micromark.cjs").Token[]} tokens Micromark tokens.
|
|
379
|
+
* @param {import("../helpers/micromark-helpers.cjs").Token[]} tokens Micromark tokens.
|
|
486
380
|
* @returns {Object} Reference link/image data.
|
|
487
381
|
*/
|
|
488
382
|
function getReferenceLinkImageData(tokens) {
|
|
489
383
|
const normalizeReference = (s) => s.toLowerCase().trim().replace(/\s+/g, " ");
|
|
384
|
+
const references = new Map();
|
|
385
|
+
const shortcuts = new Map();
|
|
386
|
+
const addReferenceToDictionary = (token, label, isShortcut) => {
|
|
387
|
+
const referenceDatum = [
|
|
388
|
+
token.startLine - 1,
|
|
389
|
+
token.startColumn - 1,
|
|
390
|
+
token.text.length
|
|
391
|
+
];
|
|
392
|
+
const reference = normalizeReference(label);
|
|
393
|
+
const dictionary = isShortcut ? shortcuts : references;
|
|
394
|
+
const referenceData = dictionary.get(reference) || [];
|
|
395
|
+
referenceData.push(referenceDatum);
|
|
396
|
+
dictionary.set(reference, referenceData);
|
|
397
|
+
};
|
|
490
398
|
const definitions = new Map();
|
|
491
399
|
const definitionLineIndices = [];
|
|
492
400
|
const duplicateDefinitions = [];
|
|
493
|
-
const references = new Map();
|
|
494
|
-
const shortcuts = new Map();
|
|
495
401
|
const filteredTokens =
|
|
496
402
|
micromark.filterByTypes(
|
|
497
403
|
tokens,
|
|
@@ -501,7 +407,9 @@ function getReferenceLinkImageData(tokens) {
|
|
|
501
407
|
// definitions and definitionLineIndices
|
|
502
408
|
"definitionLabelString", "gfmFootnoteDefinitionLabelString",
|
|
503
409
|
// references and shortcuts
|
|
504
|
-
"gfmFootnoteCall", "image", "link"
|
|
410
|
+
"gfmFootnoteCall", "image", "link",
|
|
411
|
+
// undefined link labels
|
|
412
|
+
"undefinedReferenceCollapsed", "undefinedReferenceFull", "undefinedReferenceShortcut"
|
|
505
413
|
]
|
|
506
414
|
);
|
|
507
415
|
for (const token of filteredTokens) {
|
|
@@ -524,15 +432,10 @@ function getReferenceLinkImageData(tokens) {
|
|
|
524
432
|
if (definitions.has(reference)) {
|
|
525
433
|
duplicateDefinitions.push([ reference, token.startLine - 1 ]);
|
|
526
434
|
} else {
|
|
527
|
-
let destinationString = null;
|
|
528
435
|
const parent =
|
|
529
|
-
micromark.
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
micromark.filterByPredicate(parent.children),
|
|
533
|
-
"definitionDestinationString"
|
|
534
|
-
);
|
|
535
|
-
}
|
|
436
|
+
micromark.getParentOfType(token, [ "definition" ]);
|
|
437
|
+
const destinationString = parent &&
|
|
438
|
+
micromark.getDescendantsByType(parent, [ "definitionDestination", "definitionDestinationRaw", "definitionDestinationString" ])[0]?.text;
|
|
536
439
|
definitions.set(
|
|
537
440
|
reference,
|
|
538
441
|
[ token.startLine - 1, destinationString ]
|
|
@@ -544,67 +447,38 @@ function getReferenceLinkImageData(tokens) {
|
|
|
544
447
|
case "image":
|
|
545
448
|
case "link":
|
|
546
449
|
{
|
|
547
|
-
|
|
548
|
-
let
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
const
|
|
552
|
-
|
|
553
|
-
if
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
);
|
|
558
|
-
isShortcut = (labelText !== null);
|
|
559
|
-
}
|
|
560
|
-
const fullAndCollapsedCandidate =
|
|
561
|
-
micromark.matchAndGetTokensByType(
|
|
562
|
-
token.children, [ "label", "reference" ]
|
|
450
|
+
// Identify if shortcut or full/collapsed
|
|
451
|
+
let isShortcut = (token.children.length === 1);
|
|
452
|
+
const isFullOrCollapsed = (token.children.length === 2) && !token.children.some((t) => t.type === "resource");
|
|
453
|
+
const [ labelText ] = micromark.getDescendantsByType(token, [ "label", "labelText" ]);
|
|
454
|
+
const [ referenceString ] = micromark.getDescendantsByType(token, [ "reference", "referenceString" ]);
|
|
455
|
+
let label = labelText?.text;
|
|
456
|
+
// Identify if footnote
|
|
457
|
+
if (!isShortcut && !isFullOrCollapsed) {
|
|
458
|
+
const [ footnoteCallMarker, footnoteCallString ] = token.children.filter(
|
|
459
|
+
(t) => [ "gfmFootnoteCallMarker", "gfmFootnoteCallString" ].includes(t.type)
|
|
563
460
|
);
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
);
|
|
569
|
-
referenceStringText =
|
|
570
|
-
micromark.getTokenTextByType(
|
|
571
|
-
fullAndCollapsedCandidate[1].children, "referenceString"
|
|
572
|
-
);
|
|
573
|
-
isFullOrCollapsed = (labelText !== null);
|
|
574
|
-
}
|
|
575
|
-
const footnote = micromark.matchAndGetTokensByType(
|
|
576
|
-
token.children,
|
|
577
|
-
[
|
|
578
|
-
"gfmFootnoteCallLabelMarker", "gfmFootnoteCallMarker",
|
|
579
|
-
"gfmFootnoteCallString", "gfmFootnoteCallLabelMarker"
|
|
580
|
-
],
|
|
581
|
-
[ "gfmFootnoteCallMarker", "gfmFootnoteCallString" ]
|
|
582
|
-
);
|
|
583
|
-
if (footnote) {
|
|
584
|
-
const callMarkerText = footnote[0].text;
|
|
585
|
-
const callString = footnote[1].text;
|
|
586
|
-
labelText = `${callMarkerText}${callString}`;
|
|
587
|
-
isShortcut = true;
|
|
461
|
+
if (footnoteCallMarker && footnoteCallString) {
|
|
462
|
+
label = `${footnoteCallMarker.text}${footnoteCallString.text}`;
|
|
463
|
+
isShortcut = true;
|
|
464
|
+
}
|
|
588
465
|
}
|
|
589
|
-
// Track shortcuts separately due to ambiguity in "text [text] text"
|
|
466
|
+
// Track link (handle shortcuts separately due to ambiguity in "text [text] text")
|
|
590
467
|
if (isShortcut || isFullOrCollapsed) {
|
|
591
|
-
|
|
592
|
-
token.startLine - 1,
|
|
593
|
-
token.startColumn - 1,
|
|
594
|
-
token.text.length,
|
|
595
|
-
// @ts-ignore
|
|
596
|
-
labelText.length,
|
|
597
|
-
(referenceStringText || "").length
|
|
598
|
-
];
|
|
599
|
-
const reference =
|
|
600
|
-
normalizeReference(referenceStringText || labelText);
|
|
601
|
-
const dictionary = isShortcut ? shortcuts : references;
|
|
602
|
-
const referenceData = dictionary.get(reference) || [];
|
|
603
|
-
referenceData.push(referenceDatum);
|
|
604
|
-
dictionary.set(reference, referenceData);
|
|
468
|
+
addReferenceToDictionary(token, referenceString?.text || label, isShortcut);
|
|
605
469
|
}
|
|
606
470
|
}
|
|
607
471
|
break;
|
|
472
|
+
case "undefinedReferenceCollapsed":
|
|
473
|
+
case "undefinedReferenceFull":
|
|
474
|
+
case "undefinedReferenceShortcut":
|
|
475
|
+
{
|
|
476
|
+
const undefinedReference = micromark.getDescendantsByType(token, [ "undefinedReference" ])[0];
|
|
477
|
+
const label = undefinedReference.children.map((t) => t.text).join("");
|
|
478
|
+
const isShortcut = (token.type === "undefinedReferenceShortcut");
|
|
479
|
+
addReferenceToDictionary(token, label, isShortcut);
|
|
480
|
+
}
|
|
481
|
+
break;
|
|
608
482
|
}
|
|
609
483
|
}
|
|
610
484
|
return {
|
|
@@ -657,120 +531,6 @@ function getPreferredLineEnding(input, os) {
|
|
|
657
531
|
}
|
|
658
532
|
module.exports.getPreferredLineEnding = getPreferredLineEnding;
|
|
659
533
|
|
|
660
|
-
/**
|
|
661
|
-
* Normalizes the fields of a RuleOnErrorFixInfo instance.
|
|
662
|
-
*
|
|
663
|
-
* @param {Object} fixInfo RuleOnErrorFixInfo instance.
|
|
664
|
-
* @param {number} [lineNumber] Line number.
|
|
665
|
-
* @returns {Object} Normalized RuleOnErrorFixInfo instance.
|
|
666
|
-
*/
|
|
667
|
-
function normalizeFixInfo(fixInfo, lineNumber) {
|
|
668
|
-
return {
|
|
669
|
-
"lineNumber": fixInfo.lineNumber || lineNumber,
|
|
670
|
-
"editColumn": fixInfo.editColumn || 1,
|
|
671
|
-
"deleteCount": fixInfo.deleteCount || 0,
|
|
672
|
-
"insertText": fixInfo.insertText || ""
|
|
673
|
-
};
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
/**
|
|
677
|
-
* Fixes the specified error on a line of Markdown content.
|
|
678
|
-
*
|
|
679
|
-
* @param {string} line Line of Markdown content.
|
|
680
|
-
* @param {Object} fixInfo RuleOnErrorFixInfo instance.
|
|
681
|
-
* @param {string} [lineEnding] Line ending to use.
|
|
682
|
-
* @returns {string | null} Fixed content.
|
|
683
|
-
*/
|
|
684
|
-
function applyFix(line, fixInfo, lineEnding) {
|
|
685
|
-
const { editColumn, deleteCount, insertText } = normalizeFixInfo(fixInfo);
|
|
686
|
-
const editIndex = editColumn - 1;
|
|
687
|
-
return (deleteCount === -1) ?
|
|
688
|
-
null :
|
|
689
|
-
line.slice(0, editIndex) +
|
|
690
|
-
insertText.replace(/\n/g, lineEnding || "\n") +
|
|
691
|
-
line.slice(editIndex + deleteCount);
|
|
692
|
-
}
|
|
693
|
-
module.exports.applyFix = applyFix;
|
|
694
|
-
|
|
695
|
-
/**
|
|
696
|
-
* Applies as many fixes as possible to Markdown content.
|
|
697
|
-
*
|
|
698
|
-
* @param {string} input Lines of Markdown content.
|
|
699
|
-
* @param {Object[]} errors RuleOnErrorInfo instances.
|
|
700
|
-
* @returns {string} Corrected content.
|
|
701
|
-
*/
|
|
702
|
-
function applyFixes(input, errors) {
|
|
703
|
-
const lineEnding = getPreferredLineEnding(input, __webpack_require__(/*! node:os */ "?0176"));
|
|
704
|
-
const lines = input.split(newLineRe);
|
|
705
|
-
// Normalize fixInfo objects
|
|
706
|
-
let fixInfos = errors
|
|
707
|
-
.filter((error) => error.fixInfo)
|
|
708
|
-
.map((error) => normalizeFixInfo(error.fixInfo, error.lineNumber));
|
|
709
|
-
// Sort bottom-to-top, line-deletes last, right-to-left, long-to-short
|
|
710
|
-
fixInfos.sort((a, b) => {
|
|
711
|
-
const aDeletingLine = (a.deleteCount === -1);
|
|
712
|
-
const bDeletingLine = (b.deleteCount === -1);
|
|
713
|
-
return (
|
|
714
|
-
(b.lineNumber - a.lineNumber) ||
|
|
715
|
-
(aDeletingLine ? 1 : (bDeletingLine ? -1 : 0)) ||
|
|
716
|
-
(b.editColumn - a.editColumn) ||
|
|
717
|
-
(b.insertText.length - a.insertText.length)
|
|
718
|
-
);
|
|
719
|
-
});
|
|
720
|
-
// Remove duplicate entries (needed for following collapse step)
|
|
721
|
-
let lastFixInfo = {};
|
|
722
|
-
fixInfos = fixInfos.filter((fixInfo) => {
|
|
723
|
-
const unique = (
|
|
724
|
-
(fixInfo.lineNumber !== lastFixInfo.lineNumber) ||
|
|
725
|
-
(fixInfo.editColumn !== lastFixInfo.editColumn) ||
|
|
726
|
-
(fixInfo.deleteCount !== lastFixInfo.deleteCount) ||
|
|
727
|
-
(fixInfo.insertText !== lastFixInfo.insertText)
|
|
728
|
-
);
|
|
729
|
-
lastFixInfo = fixInfo;
|
|
730
|
-
return unique;
|
|
731
|
-
});
|
|
732
|
-
// Collapse insert/no-delete and no-insert/delete for same line/column
|
|
733
|
-
lastFixInfo = {
|
|
734
|
-
"lineNumber": -1
|
|
735
|
-
};
|
|
736
|
-
for (const fixInfo of fixInfos) {
|
|
737
|
-
if (
|
|
738
|
-
(fixInfo.lineNumber === lastFixInfo.lineNumber) &&
|
|
739
|
-
(fixInfo.editColumn === lastFixInfo.editColumn) &&
|
|
740
|
-
!fixInfo.insertText &&
|
|
741
|
-
(fixInfo.deleteCount > 0) &&
|
|
742
|
-
lastFixInfo.insertText &&
|
|
743
|
-
!lastFixInfo.deleteCount) {
|
|
744
|
-
fixInfo.insertText = lastFixInfo.insertText;
|
|
745
|
-
lastFixInfo.lineNumber = 0;
|
|
746
|
-
}
|
|
747
|
-
lastFixInfo = fixInfo;
|
|
748
|
-
}
|
|
749
|
-
fixInfos = fixInfos.filter((fixInfo) => fixInfo.lineNumber);
|
|
750
|
-
// Apply all (remaining/updated) fixes
|
|
751
|
-
let lastLineIndex = -1;
|
|
752
|
-
let lastEditIndex = -1;
|
|
753
|
-
for (const fixInfo of fixInfos) {
|
|
754
|
-
const { lineNumber, editColumn, deleteCount } = fixInfo;
|
|
755
|
-
const lineIndex = lineNumber - 1;
|
|
756
|
-
const editIndex = editColumn - 1;
|
|
757
|
-
if (
|
|
758
|
-
(lineIndex !== lastLineIndex) ||
|
|
759
|
-
(deleteCount === -1) ||
|
|
760
|
-
((editIndex + deleteCount) <=
|
|
761
|
-
(lastEditIndex - ((deleteCount > 0) ? 0 : 1)))
|
|
762
|
-
) {
|
|
763
|
-
// @ts-ignore
|
|
764
|
-
lines[lineIndex] = applyFix(lines[lineIndex], fixInfo, lineEnding);
|
|
765
|
-
}
|
|
766
|
-
lastLineIndex = lineIndex;
|
|
767
|
-
lastEditIndex = editIndex;
|
|
768
|
-
}
|
|
769
|
-
// Return corrected input
|
|
770
|
-
return lines.filter((line) => line !== null).join(lineEnding);
|
|
771
|
-
}
|
|
772
|
-
module.exports.applyFixes = applyFixes;
|
|
773
|
-
|
|
774
534
|
/**
|
|
775
535
|
* Expands a path with a tilde to an absolute path.
|
|
776
536
|
*
|
|
@@ -784,26 +544,6 @@ function expandTildePath(file, os) {
|
|
|
784
544
|
}
|
|
785
545
|
module.exports.expandTildePath = expandTildePath;
|
|
786
546
|
|
|
787
|
-
// Copied from markdownlint.js to avoid TypeScript compiler import() issue.
|
|
788
|
-
/**
|
|
789
|
-
* @typedef {Object} MarkdownItToken
|
|
790
|
-
* @property {string[][]} attrs HTML attributes.
|
|
791
|
-
* @property {boolean} block Block-level token.
|
|
792
|
-
* @property {MarkdownItToken[]} children Child nodes.
|
|
793
|
-
* @property {string} content Tag contents.
|
|
794
|
-
* @property {boolean} hidden Ignore element.
|
|
795
|
-
* @property {string} info Fence info.
|
|
796
|
-
* @property {number} level Nesting level.
|
|
797
|
-
* @property {number[]} map Beginning/ending line numbers.
|
|
798
|
-
* @property {string} markup Markup text.
|
|
799
|
-
* @property {Object} meta Arbitrary data.
|
|
800
|
-
* @property {number} nesting Level change.
|
|
801
|
-
* @property {string} tag HTML tag name.
|
|
802
|
-
* @property {string} type Token type.
|
|
803
|
-
* @property {number} lineNumber Line number (1-based).
|
|
804
|
-
* @property {string} line Line content.
|
|
805
|
-
*/
|
|
806
|
-
|
|
807
547
|
|
|
808
548
|
/***/ }),
|
|
809
549
|
|
|
@@ -818,6 +558,12 @@ module.exports.expandTildePath = expandTildePath;
|
|
|
818
558
|
|
|
819
559
|
|
|
820
560
|
|
|
561
|
+
// Symbol for identifing the flat tokens array from micromark parse
|
|
562
|
+
module.exports.flatTokensSymbol = Symbol("flat-tokens");
|
|
563
|
+
|
|
564
|
+
// Symbol for identifying the htmlFlow token from micromark parse
|
|
565
|
+
module.exports.htmlFlowSymbol = Symbol("html-flow");
|
|
566
|
+
|
|
821
567
|
// Regular expression for matching common newline characters
|
|
822
568
|
// See NEWLINES_RE in markdown-it/lib/rules_core/normalize.js
|
|
823
569
|
module.exports.newLineRe = /\r\n?|\n/g;
|
|
@@ -868,16 +614,6 @@ module.exports = micromarkBrowser;
|
|
|
868
614
|
|
|
869
615
|
/***/ }),
|
|
870
616
|
|
|
871
|
-
/***/ "?0176":
|
|
872
|
-
/*!*************************!*\
|
|
873
|
-
!*** node:os (ignored) ***!
|
|
874
|
-
\*************************/
|
|
875
|
-
/***/ (() => {
|
|
876
|
-
|
|
877
|
-
/* (ignored) */
|
|
878
|
-
|
|
879
|
-
/***/ }),
|
|
880
|
-
|
|
881
617
|
/***/ "?d0ee":
|
|
882
618
|
/*!*************************!*\
|
|
883
619
|
!*** node:fs (ignored) ***!
|
|
@@ -937,10 +673,10 @@ module.exports = {
|
|
|
937
673
|
|
|
938
674
|
/***/ }),
|
|
939
675
|
|
|
940
|
-
/***/ "../helpers/micromark.cjs":
|
|
941
|
-
|
|
942
|
-
!*** ../helpers/micromark.cjs ***!
|
|
943
|
-
|
|
676
|
+
/***/ "../helpers/micromark-helpers.cjs":
|
|
677
|
+
/*!****************************************!*\
|
|
678
|
+
!*** ../helpers/micromark-helpers.cjs ***!
|
|
679
|
+
\****************************************/
|
|
944
680
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
945
681
|
|
|
946
682
|
"use strict";
|
|
@@ -948,30 +684,19 @@ module.exports = {
|
|
|
948
684
|
|
|
949
685
|
|
|
950
686
|
|
|
951
|
-
|
|
952
|
-
const {
|
|
953
|
-
directive, gfmAutolinkLiteral, gfmFootnote, gfmTable, math,
|
|
954
|
-
parse, postprocess, preprocess
|
|
955
|
-
// @ts-ignore
|
|
956
|
-
} = __webpack_require__(/*! markdownlint-micromark */ "markdownlint-micromark");
|
|
957
|
-
const { newLineRe } = __webpack_require__(/*! ./shared.js */ "../helpers/shared.js");
|
|
958
|
-
|
|
959
|
-
const flatTokensSymbol = Symbol("flat-tokens");
|
|
960
|
-
const reparseSymbol = Symbol("reparse");
|
|
687
|
+
const { flatTokensSymbol, htmlFlowSymbol } = __webpack_require__(/*! ./shared.js */ "../helpers/shared.js");
|
|
961
688
|
|
|
962
|
-
/** @typedef {import("markdownlint-micromark").Event} Event */
|
|
963
|
-
/** @typedef {import("markdownlint-micromark").ParseOptions} ParseOptions */
|
|
964
689
|
/** @typedef {import("markdownlint-micromark").TokenType} TokenType */
|
|
965
690
|
/** @typedef {import("../lib/markdownlint.js").MicromarkToken} Token */
|
|
966
691
|
|
|
967
692
|
/**
|
|
968
|
-
* Determines if a Micromark token is within an htmlFlow.
|
|
693
|
+
* Determines if a Micromark token is within an htmlFlow type.
|
|
969
694
|
*
|
|
970
695
|
* @param {Token} token Micromark token.
|
|
971
|
-
* @returns {boolean} True iff the token is within an htmlFlow.
|
|
696
|
+
* @returns {boolean} True iff the token is within an htmlFlow type.
|
|
972
697
|
*/
|
|
973
698
|
function inHtmlFlow(token) {
|
|
974
|
-
return token[
|
|
699
|
+
return Boolean(token[htmlFlowSymbol]);
|
|
975
700
|
}
|
|
976
701
|
|
|
977
702
|
/**
|
|
@@ -1003,180 +728,6 @@ function isHtmlFlowComment(token) {
|
|
|
1003
728
|
return false;
|
|
1004
729
|
}
|
|
1005
730
|
|
|
1006
|
-
/**
|
|
1007
|
-
* Parses a Markdown document and returns Micromark events.
|
|
1008
|
-
*
|
|
1009
|
-
* @param {string} markdown Markdown document.
|
|
1010
|
-
* @param {ParseOptions} [micromarkOptions] Options for micromark.
|
|
1011
|
-
* @param {boolean} [referencesDefined] Treat references as defined.
|
|
1012
|
-
* @returns {Event[]} Micromark events.
|
|
1013
|
-
*/
|
|
1014
|
-
function getMicromarkEvents(
|
|
1015
|
-
markdown,
|
|
1016
|
-
micromarkOptions = {},
|
|
1017
|
-
referencesDefined = true
|
|
1018
|
-
) {
|
|
1019
|
-
|
|
1020
|
-
// Customize options object to add useful extensions
|
|
1021
|
-
micromarkOptions.extensions = micromarkOptions.extensions || [];
|
|
1022
|
-
micromarkOptions.extensions.push(
|
|
1023
|
-
directive(),
|
|
1024
|
-
gfmAutolinkLiteral(),
|
|
1025
|
-
gfmFootnote(),
|
|
1026
|
-
gfmTable(),
|
|
1027
|
-
math()
|
|
1028
|
-
);
|
|
1029
|
-
|
|
1030
|
-
// Use micromark to parse document into Events
|
|
1031
|
-
const encoding = undefined;
|
|
1032
|
-
const eol = true;
|
|
1033
|
-
const parseContext = parse(micromarkOptions);
|
|
1034
|
-
if (referencesDefined) {
|
|
1035
|
-
// Customize ParseContext to treat all references as defined
|
|
1036
|
-
parseContext.defined.includes = (searchElement) => searchElement.length > 0;
|
|
1037
|
-
}
|
|
1038
|
-
const chunks = preprocess()(markdown, encoding, eol);
|
|
1039
|
-
const events = postprocess(parseContext.document().write(chunks));
|
|
1040
|
-
return events;
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
|
-
/**
|
|
1044
|
-
* Parses a Markdown document and returns (frozen) tokens.
|
|
1045
|
-
*
|
|
1046
|
-
* @param {string} markdown Markdown document.
|
|
1047
|
-
* @param {ParseOptions} micromarkOptions Options for micromark.
|
|
1048
|
-
* @param {boolean} referencesDefined Treat references as defined.
|
|
1049
|
-
* @param {number} lineDelta Offset to apply to start/end line.
|
|
1050
|
-
* @param {Token} [ancestor] Parent of top-most tokens.
|
|
1051
|
-
* @returns {Token[]} Micromark tokens (frozen).
|
|
1052
|
-
*/
|
|
1053
|
-
function micromarkParseWithOffset(
|
|
1054
|
-
markdown,
|
|
1055
|
-
micromarkOptions,
|
|
1056
|
-
referencesDefined,
|
|
1057
|
-
lineDelta,
|
|
1058
|
-
ancestor
|
|
1059
|
-
) {
|
|
1060
|
-
// Use micromark to parse document into Events
|
|
1061
|
-
const events = getMicromarkEvents(
|
|
1062
|
-
markdown, micromarkOptions, referencesDefined
|
|
1063
|
-
);
|
|
1064
|
-
|
|
1065
|
-
// Create Token objects
|
|
1066
|
-
const document = [];
|
|
1067
|
-
let flatTokens = [];
|
|
1068
|
-
/** @type {Token} */
|
|
1069
|
-
const root = {
|
|
1070
|
-
"type": "data",
|
|
1071
|
-
"startLine": -1,
|
|
1072
|
-
"startColumn": -1,
|
|
1073
|
-
"endLine": -1,
|
|
1074
|
-
"endColumn": -1,
|
|
1075
|
-
"text": "ROOT",
|
|
1076
|
-
"children": document,
|
|
1077
|
-
"parent": null
|
|
1078
|
-
};
|
|
1079
|
-
const history = [ root ];
|
|
1080
|
-
let current = root;
|
|
1081
|
-
// eslint-disable-next-line jsdoc/valid-types
|
|
1082
|
-
/** @type ParseOptions | null */
|
|
1083
|
-
let reparseOptions = null;
|
|
1084
|
-
let lines = null;
|
|
1085
|
-
let skipHtmlFlowChildren = false;
|
|
1086
|
-
for (const event of events) {
|
|
1087
|
-
const [ kind, token, context ] = event;
|
|
1088
|
-
const { type, start, end } = token;
|
|
1089
|
-
const { "column": startColumn, "line": startLine } = start;
|
|
1090
|
-
const { "column": endColumn, "line": endLine } = end;
|
|
1091
|
-
const text = context.sliceSerialize(token);
|
|
1092
|
-
if ((kind === "enter") && !skipHtmlFlowChildren) {
|
|
1093
|
-
const previous = current;
|
|
1094
|
-
history.push(previous);
|
|
1095
|
-
current = {
|
|
1096
|
-
type,
|
|
1097
|
-
"startLine": startLine + lineDelta,
|
|
1098
|
-
startColumn,
|
|
1099
|
-
"endLine": endLine + lineDelta,
|
|
1100
|
-
endColumn,
|
|
1101
|
-
text,
|
|
1102
|
-
"children": [],
|
|
1103
|
-
"parent": ((previous === root) ? (ancestor || null) : previous)
|
|
1104
|
-
};
|
|
1105
|
-
if (ancestor) {
|
|
1106
|
-
Object.defineProperty(current, reparseSymbol, { "value": true });
|
|
1107
|
-
}
|
|
1108
|
-
previous.children.push(current);
|
|
1109
|
-
flatTokens.push(current);
|
|
1110
|
-
if ((current.type === "htmlFlow") && !isHtmlFlowComment(current)) {
|
|
1111
|
-
skipHtmlFlowChildren = true;
|
|
1112
|
-
if (!reparseOptions || !lines) {
|
|
1113
|
-
reparseOptions = {
|
|
1114
|
-
...micromarkOptions,
|
|
1115
|
-
"extensions": [
|
|
1116
|
-
{
|
|
1117
|
-
"disable": {
|
|
1118
|
-
"null": [ "codeIndented", "htmlFlow" ]
|
|
1119
|
-
}
|
|
1120
|
-
}
|
|
1121
|
-
]
|
|
1122
|
-
};
|
|
1123
|
-
lines = markdown.split(newLineRe);
|
|
1124
|
-
}
|
|
1125
|
-
const reparseMarkdown = lines
|
|
1126
|
-
.slice(current.startLine - 1, current.endLine)
|
|
1127
|
-
.join("\n");
|
|
1128
|
-
const tokens = micromarkParseWithOffset(
|
|
1129
|
-
reparseMarkdown,
|
|
1130
|
-
reparseOptions,
|
|
1131
|
-
referencesDefined,
|
|
1132
|
-
current.startLine - 1,
|
|
1133
|
-
current
|
|
1134
|
-
);
|
|
1135
|
-
current.children = tokens;
|
|
1136
|
-
// Avoid stack overflow of Array.push(...spread)
|
|
1137
|
-
// eslint-disable-next-line unicorn/prefer-spread
|
|
1138
|
-
flatTokens = flatTokens.concat(tokens[flatTokensSymbol]);
|
|
1139
|
-
}
|
|
1140
|
-
} else if (kind === "exit") {
|
|
1141
|
-
if (type === "htmlFlow") {
|
|
1142
|
-
skipHtmlFlowChildren = false;
|
|
1143
|
-
}
|
|
1144
|
-
if (!skipHtmlFlowChildren) {
|
|
1145
|
-
Object.freeze(current.children);
|
|
1146
|
-
Object.freeze(current);
|
|
1147
|
-
// @ts-ignore
|
|
1148
|
-
current = history.pop();
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1151
|
-
}
|
|
1152
|
-
|
|
1153
|
-
// Return document
|
|
1154
|
-
Object.defineProperty(document, flatTokensSymbol, { "value": flatTokens });
|
|
1155
|
-
Object.freeze(document);
|
|
1156
|
-
return document;
|
|
1157
|
-
}
|
|
1158
|
-
|
|
1159
|
-
/**
|
|
1160
|
-
* Parses a Markdown document and returns (frozen) tokens.
|
|
1161
|
-
*
|
|
1162
|
-
* @param {string} markdown Markdown document.
|
|
1163
|
-
* @param {ParseOptions} [micromarkOptions] Options for micromark.
|
|
1164
|
-
* @param {boolean} [referencesDefined] Treat references as defined.
|
|
1165
|
-
* @returns {Token[]} Micromark tokens (frozen).
|
|
1166
|
-
*/
|
|
1167
|
-
function micromarkParse(
|
|
1168
|
-
markdown,
|
|
1169
|
-
micromarkOptions = {},
|
|
1170
|
-
referencesDefined = true
|
|
1171
|
-
) {
|
|
1172
|
-
return micromarkParseWithOffset(
|
|
1173
|
-
markdown,
|
|
1174
|
-
micromarkOptions,
|
|
1175
|
-
referencesDefined,
|
|
1176
|
-
0
|
|
1177
|
-
);
|
|
1178
|
-
}
|
|
1179
|
-
|
|
1180
731
|
/**
|
|
1181
732
|
* Adds a range of numbers to a set.
|
|
1182
733
|
*
|
|
@@ -1255,8 +806,7 @@ function filterByPredicate(tokens, allowed, transformChildren) {
|
|
|
1255
806
|
* @returns {Token[]} Filtered tokens.
|
|
1256
807
|
*/
|
|
1257
808
|
function filterByTypes(tokens, types, htmlFlow) {
|
|
1258
|
-
const predicate = (token) =>
|
|
1259
|
-
(htmlFlow || !inHtmlFlow(token)) && types.includes(token.type);
|
|
809
|
+
const predicate = (token) => types.includes(token.type) && (htmlFlow || !inHtmlFlow(token));
|
|
1260
810
|
const flatTokens = tokens[flatTokensSymbol];
|
|
1261
811
|
if (flatTokens) {
|
|
1262
812
|
return flatTokens.filter(predicate);
|
|
@@ -1264,46 +814,41 @@ function filterByTypes(tokens, types, htmlFlow) {
|
|
|
1264
814
|
return filterByPredicate(tokens, predicate);
|
|
1265
815
|
}
|
|
1266
816
|
|
|
817
|
+
/**
|
|
818
|
+
* Gets the blockquote prefix text (if any) for the specified line number.
|
|
819
|
+
*
|
|
820
|
+
* @param {Token[]} tokens Micromark tokens.
|
|
821
|
+
* @param {number} lineNumber Line number to examine.
|
|
822
|
+
* @param {number} [count] Number of times to repeat.
|
|
823
|
+
* @returns {string} Blockquote prefix text.
|
|
824
|
+
*/
|
|
825
|
+
function getBlockQuotePrefixText(tokens, lineNumber, count = 1) {
|
|
826
|
+
return filterByTypes(tokens, [ "blockQuotePrefix", "linePrefix" ])
|
|
827
|
+
.filter((prefix) => prefix.startLine === lineNumber)
|
|
828
|
+
.map((prefix) => prefix.text)
|
|
829
|
+
.join("")
|
|
830
|
+
.trimEnd()
|
|
831
|
+
// eslint-disable-next-line unicorn/prefer-spread
|
|
832
|
+
.concat("\n")
|
|
833
|
+
.repeat(count);
|
|
834
|
+
};
|
|
835
|
+
|
|
1267
836
|
/**
|
|
1268
837
|
* Gets a list of nested Micromark token descendants by type path.
|
|
1269
838
|
*
|
|
1270
839
|
* @param {Token|Token[]} parent Micromark token parent or parents.
|
|
1271
|
-
* @param {TokenType[]} typePath Micromark token type path.
|
|
840
|
+
* @param {(TokenType|TokenType[])[]} typePath Micromark token type path.
|
|
1272
841
|
* @returns {Token[]} Micromark token descendants.
|
|
1273
842
|
*/
|
|
1274
843
|
function getDescendantsByType(parent, typePath) {
|
|
1275
844
|
let tokens = Array.isArray(parent) ? parent : [ parent ];
|
|
1276
845
|
for (const type of typePath) {
|
|
1277
|
-
|
|
846
|
+
const predicate = (token) => Array.isArray(type) ? type.includes(token.type) : (type === token.type);
|
|
847
|
+
tokens = tokens.flatMap((t) => t.children.filter(predicate));
|
|
1278
848
|
}
|
|
1279
849
|
return tokens;
|
|
1280
850
|
}
|
|
1281
851
|
|
|
1282
|
-
// eslint-disable-next-line jsdoc/valid-types
|
|
1283
|
-
/** @typedef {readonly string[]} ReadonlyStringArray */
|
|
1284
|
-
|
|
1285
|
-
/**
|
|
1286
|
-
* Gets the line/column/length exclusions for a Micromark token.
|
|
1287
|
-
*
|
|
1288
|
-
* @param {ReadonlyStringArray} lines File/string lines.
|
|
1289
|
-
* @param {Token} token Micromark token.
|
|
1290
|
-
* @returns {number[][]} Exclusions (line number, start column, length).
|
|
1291
|
-
*/
|
|
1292
|
-
function getExclusionsForToken(lines, token) {
|
|
1293
|
-
const exclusions = [];
|
|
1294
|
-
const { endColumn, endLine, startColumn, startLine } = token;
|
|
1295
|
-
for (let lineNumber = startLine; lineNumber <= endLine; lineNumber++) {
|
|
1296
|
-
const start = (lineNumber === startLine) ? startColumn : 1;
|
|
1297
|
-
const end = (lineNumber === endLine) ? endColumn : lines[lineNumber - 1].length;
|
|
1298
|
-
exclusions.push([
|
|
1299
|
-
lineNumber,
|
|
1300
|
-
start,
|
|
1301
|
-
end - start + 1
|
|
1302
|
-
]);
|
|
1303
|
-
}
|
|
1304
|
-
return exclusions;
|
|
1305
|
-
}
|
|
1306
|
-
|
|
1307
852
|
/**
|
|
1308
853
|
* Gets the heading level of a Micromark heading tokan.
|
|
1309
854
|
*
|
|
@@ -1311,12 +856,12 @@ function getExclusionsForToken(lines, token) {
|
|
|
1311
856
|
* @returns {number} Heading level.
|
|
1312
857
|
*/
|
|
1313
858
|
function getHeadingLevel(heading) {
|
|
1314
|
-
const headingSequence = filterByTypes(
|
|
1315
|
-
heading.children,
|
|
1316
|
-
[ "atxHeadingSequence", "setextHeadingLineSequence" ]
|
|
1317
|
-
);
|
|
1318
859
|
let level = 1;
|
|
1319
|
-
const
|
|
860
|
+
const headingSequence = heading.children.find(
|
|
861
|
+
(child) => [ "atxHeadingSequence", "setextHeadingLine" ].includes(child.type)
|
|
862
|
+
);
|
|
863
|
+
// @ts-ignore
|
|
864
|
+
const { text } = headingSequence;
|
|
1320
865
|
if (text[0] === "#") {
|
|
1321
866
|
level = Math.min(text.length, 6);
|
|
1322
867
|
} else if (text[0] === "-") {
|
|
@@ -1335,9 +880,8 @@ function getHeadingStyle(heading) {
|
|
|
1335
880
|
if (heading.type === "setextHeading") {
|
|
1336
881
|
return "setext";
|
|
1337
882
|
}
|
|
1338
|
-
const atxHeadingSequenceLength =
|
|
1339
|
-
|
|
1340
|
-
[ "atxHeadingSequence" ]
|
|
883
|
+
const atxHeadingSequenceLength = heading.children.filter(
|
|
884
|
+
(child) => child.type === "atxHeadingSequence"
|
|
1341
885
|
).length;
|
|
1342
886
|
if (atxHeadingSequenceLength === 1) {
|
|
1343
887
|
return "atx";
|
|
@@ -1352,10 +896,7 @@ function getHeadingStyle(heading) {
|
|
|
1352
896
|
* @returns {string} Heading text.
|
|
1353
897
|
*/
|
|
1354
898
|
function getHeadingText(heading) {
|
|
1355
|
-
const headingTexts =
|
|
1356
|
-
heading.children,
|
|
1357
|
-
[ "atxHeadingText", "setextHeadingText" ]
|
|
1358
|
-
);
|
|
899
|
+
const headingTexts = getDescendantsByType(heading, [ [ "atxHeadingText", "setextHeadingText" ] ]);
|
|
1359
900
|
return headingTexts[0]?.text.replace(/[\r\n]+/g, " ") || "";
|
|
1360
901
|
}
|
|
1361
902
|
|
|
@@ -1396,7 +937,7 @@ function getHtmlTagInfo(token) {
|
|
|
1396
937
|
* @param {TokenType[]} types Types to allow.
|
|
1397
938
|
* @returns {Token | null} Parent token.
|
|
1398
939
|
*/
|
|
1399
|
-
function
|
|
940
|
+
function getParentOfType(token, types) {
|
|
1400
941
|
/** @type {Token | null} */
|
|
1401
942
|
let current = token;
|
|
1402
943
|
while ((current = current.parent) && !types.includes(current.type)) {
|
|
@@ -1405,54 +946,6 @@ function getTokenParentOfType(token, types) {
|
|
|
1405
946
|
return current;
|
|
1406
947
|
}
|
|
1407
948
|
|
|
1408
|
-
/**
|
|
1409
|
-
* Get the text of the first match from a list of Micromark tokens by type.
|
|
1410
|
-
*
|
|
1411
|
-
* @param {Token[]} tokens Micromark tokens.
|
|
1412
|
-
* @param {TokenType} type Type to match.
|
|
1413
|
-
* @returns {string | null} Text of token.
|
|
1414
|
-
*/
|
|
1415
|
-
function getTokenTextByType(tokens, type) {
|
|
1416
|
-
const filtered = tokens.filter((token) => token.type === type);
|
|
1417
|
-
return (filtered.length > 0) ? filtered[0].text : null;
|
|
1418
|
-
}
|
|
1419
|
-
|
|
1420
|
-
/**
|
|
1421
|
-
* Determines a list of Micromark tokens matches and returns a subset.
|
|
1422
|
-
*
|
|
1423
|
-
* @param {Token[]} tokens Micromark tokens.
|
|
1424
|
-
* @param {TokenType[]} matchTypes Types to match.
|
|
1425
|
-
* @param {TokenType[]} [resultTypes] Types to return.
|
|
1426
|
-
* @returns {Token[] | null} Matching tokens.
|
|
1427
|
-
*/
|
|
1428
|
-
function matchAndGetTokensByType(tokens, matchTypes, resultTypes) {
|
|
1429
|
-
if (tokens.length !== matchTypes.length) {
|
|
1430
|
-
return null;
|
|
1431
|
-
}
|
|
1432
|
-
resultTypes = resultTypes || matchTypes;
|
|
1433
|
-
const result = [];
|
|
1434
|
-
// eslint-disable-next-line unicorn/no-for-loop
|
|
1435
|
-
for (let i = 0; i < matchTypes.length; i++) {
|
|
1436
|
-
if (tokens[i].type !== matchTypes[i]) {
|
|
1437
|
-
return null;
|
|
1438
|
-
} else if (resultTypes.includes(matchTypes[i])) {
|
|
1439
|
-
result.push(tokens[i]);
|
|
1440
|
-
}
|
|
1441
|
-
}
|
|
1442
|
-
return result;
|
|
1443
|
-
}
|
|
1444
|
-
|
|
1445
|
-
/**
|
|
1446
|
-
* Returns the specified token iff it is of the desired type.
|
|
1447
|
-
*
|
|
1448
|
-
* @param {Token} token Micromark token candidate.
|
|
1449
|
-
* @param {TokenType} type Desired type.
|
|
1450
|
-
* @returns {Token | null} Token instance.
|
|
1451
|
-
*/
|
|
1452
|
-
function tokenIfType(token, type) {
|
|
1453
|
-
return (token && (token.type === type)) ? token : null;
|
|
1454
|
-
}
|
|
1455
|
-
|
|
1456
949
|
/**
|
|
1457
950
|
* Set containing token types that do not contain content.
|
|
1458
951
|
*
|
|
@@ -1469,24 +962,343 @@ const nonContentTokens = new Set([
|
|
|
1469
962
|
]);
|
|
1470
963
|
|
|
1471
964
|
module.exports = {
|
|
1472
|
-
"parse": micromarkParse,
|
|
1473
965
|
addRangeToSet,
|
|
1474
966
|
filterByPredicate,
|
|
1475
967
|
filterByTypes,
|
|
968
|
+
getBlockQuotePrefixText,
|
|
1476
969
|
getDescendantsByType,
|
|
1477
|
-
getExclusionsForToken,
|
|
1478
970
|
getHeadingLevel,
|
|
1479
971
|
getHeadingStyle,
|
|
1480
972
|
getHeadingText,
|
|
1481
973
|
getHtmlTagInfo,
|
|
1482
|
-
|
|
1483
|
-
getTokenParentOfType,
|
|
1484
|
-
getTokenTextByType,
|
|
974
|
+
getParentOfType,
|
|
1485
975
|
inHtmlFlow,
|
|
1486
976
|
isHtmlFlowComment,
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
977
|
+
nonContentTokens
|
|
978
|
+
};
|
|
979
|
+
|
|
980
|
+
|
|
981
|
+
/***/ }),
|
|
982
|
+
|
|
983
|
+
/***/ "../helpers/micromark-parse.cjs":
|
|
984
|
+
/*!**************************************!*\
|
|
985
|
+
!*** ../helpers/micromark-parse.cjs ***!
|
|
986
|
+
\**************************************/
|
|
987
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
988
|
+
|
|
989
|
+
"use strict";
|
|
990
|
+
// @ts-check
|
|
991
|
+
|
|
992
|
+
|
|
993
|
+
|
|
994
|
+
const micromark = __webpack_require__(/*! markdownlint-micromark */ "markdownlint-micromark");
|
|
995
|
+
const { isHtmlFlowComment } = __webpack_require__(/*! ./micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
996
|
+
const { flatTokensSymbol, htmlFlowSymbol, newLineRe } = __webpack_require__(/*! ./shared.js */ "../helpers/shared.js");
|
|
997
|
+
|
|
998
|
+
/** @typedef {import("markdownlint-micromark").Construct} Construct */
|
|
999
|
+
/** @typedef {import("markdownlint-micromark").Event} Event */
|
|
1000
|
+
/** @typedef {import("markdownlint-micromark").ParseOptions} MicromarkParseOptions */
|
|
1001
|
+
/** @typedef {import("markdownlint-micromark").State} State */
|
|
1002
|
+
/** @typedef {import("markdownlint-micromark").Token} Token */
|
|
1003
|
+
/** @typedef {import("markdownlint-micromark").Tokenizer} Tokenizer */
|
|
1004
|
+
/** @typedef {import("../lib/markdownlint.js").MicromarkToken} MicromarkToken */
|
|
1005
|
+
|
|
1006
|
+
/**
|
|
1007
|
+
* Parse options.
|
|
1008
|
+
*
|
|
1009
|
+
* @typedef {Object} ParseOptions
|
|
1010
|
+
* @property {boolean} [freezeTokens] Whether to freeze output Tokens.
|
|
1011
|
+
*/
|
|
1012
|
+
|
|
1013
|
+
/**
|
|
1014
|
+
* Parses a Markdown document and returns Micromark events.
|
|
1015
|
+
*
|
|
1016
|
+
* @param {string} markdown Markdown document.
|
|
1017
|
+
* @param {MicromarkParseOptions} [micromarkParseOptions] Options for micromark.
|
|
1018
|
+
* @returns {Event[]} Micromark events.
|
|
1019
|
+
*/
|
|
1020
|
+
function getEvents(
|
|
1021
|
+
markdown,
|
|
1022
|
+
micromarkParseOptions = {}
|
|
1023
|
+
) {
|
|
1024
|
+
// Customize extensions list to add useful extensions
|
|
1025
|
+
const extensions = [
|
|
1026
|
+
micromark.directive(),
|
|
1027
|
+
micromark.gfmAutolinkLiteral(),
|
|
1028
|
+
micromark.gfmFootnote(),
|
|
1029
|
+
micromark.gfmTable(),
|
|
1030
|
+
micromark.math(),
|
|
1031
|
+
...(micromarkParseOptions.extensions || [])
|
|
1032
|
+
];
|
|
1033
|
+
|
|
1034
|
+
// // Shim labelEnd to identify undefined link labels
|
|
1035
|
+
/** @type {Event[][]} */
|
|
1036
|
+
const artificialEventLists = [];
|
|
1037
|
+
/** @type {Construct} */
|
|
1038
|
+
const labelEnd =
|
|
1039
|
+
// @ts-ignore
|
|
1040
|
+
micromark.labelEnd;
|
|
1041
|
+
const tokenizeOriginal = labelEnd.tokenize;
|
|
1042
|
+
|
|
1043
|
+
/** @type {Tokenizer} */
|
|
1044
|
+
function tokenizeShim(effects, okOriginal, nokOriginal) {
|
|
1045
|
+
// eslint-disable-next-line consistent-this, unicorn/no-this-assignment, no-invalid-this
|
|
1046
|
+
const tokenizeContext = this;
|
|
1047
|
+
const events = tokenizeContext.events;
|
|
1048
|
+
|
|
1049
|
+
/** @type {State} */
|
|
1050
|
+
const nokShim = (code) => {
|
|
1051
|
+
// Find start of label (image or link)
|
|
1052
|
+
let indexStart = events.length;
|
|
1053
|
+
while (--indexStart >= 0) {
|
|
1054
|
+
const event = events[indexStart];
|
|
1055
|
+
const [ kind, token ] = event;
|
|
1056
|
+
if (kind === "enter") {
|
|
1057
|
+
const { type } = token;
|
|
1058
|
+
if ((type === "labelImage") || (type === "labelLink")) {
|
|
1059
|
+
// Found it
|
|
1060
|
+
break;
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
// If found...
|
|
1066
|
+
if (indexStart >= 0) {
|
|
1067
|
+
// Create artificial enter/exit events and replicate all data/lineEnding events within
|
|
1068
|
+
const eventStart = events[indexStart];
|
|
1069
|
+
const [ , eventStartToken ] = eventStart;
|
|
1070
|
+
const eventEnd = events[events.length - 1];
|
|
1071
|
+
const [ , eventEndToken ] = eventEnd;
|
|
1072
|
+
/** @type {Token} */
|
|
1073
|
+
const undefinedReferenceType = {
|
|
1074
|
+
"type": "undefinedReferenceShortcut",
|
|
1075
|
+
"start": eventStartToken.start,
|
|
1076
|
+
"end": eventEndToken.end
|
|
1077
|
+
};
|
|
1078
|
+
/** @type {Token} */
|
|
1079
|
+
const undefinedReference = {
|
|
1080
|
+
"type": "undefinedReference",
|
|
1081
|
+
"start": eventStartToken.start,
|
|
1082
|
+
"end": eventEndToken.end
|
|
1083
|
+
};
|
|
1084
|
+
const eventsToReplicate = events
|
|
1085
|
+
.slice(indexStart)
|
|
1086
|
+
.filter((event) => {
|
|
1087
|
+
const [ , eventToken ] = event;
|
|
1088
|
+
const { type } = eventToken;
|
|
1089
|
+
return (type === "data") || (type === "lineEnding");
|
|
1090
|
+
});
|
|
1091
|
+
|
|
1092
|
+
// Determine the type of the undefined reference
|
|
1093
|
+
const previousUndefinedEvent = (artificialEventLists.length > 0) && artificialEventLists[artificialEventLists.length - 1][0];
|
|
1094
|
+
const previousUndefinedToken = previousUndefinedEvent && previousUndefinedEvent[1];
|
|
1095
|
+
if (
|
|
1096
|
+
previousUndefinedToken &&
|
|
1097
|
+
(previousUndefinedToken.end.line === undefinedReferenceType.start.line) &&
|
|
1098
|
+
(previousUndefinedToken.end.column === undefinedReferenceType.start.column)
|
|
1099
|
+
) {
|
|
1100
|
+
// Previous undefined reference event is immediately before this one
|
|
1101
|
+
if (eventsToReplicate.length === 0) {
|
|
1102
|
+
// The pair represent a collapsed reference (ex: [...][])
|
|
1103
|
+
previousUndefinedToken.type = "undefinedReferenceCollapsed";
|
|
1104
|
+
previousUndefinedToken.end = eventEndToken.end;
|
|
1105
|
+
} else {
|
|
1106
|
+
// The pair represent a full reference (ex: [...][...])
|
|
1107
|
+
undefinedReferenceType.type = "undefinedReferenceFull";
|
|
1108
|
+
undefinedReferenceType.start = previousUndefinedToken.start;
|
|
1109
|
+
artificialEventLists.pop();
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
// Create artificial event list and replicate content
|
|
1114
|
+
const text = eventsToReplicate
|
|
1115
|
+
.filter((event) => event[0] === "enter")
|
|
1116
|
+
.map((event) => tokenizeContext.sliceSerialize(event[1]))
|
|
1117
|
+
.join("")
|
|
1118
|
+
.trim();
|
|
1119
|
+
if ((text.length > 0) && !text.includes("]")) {
|
|
1120
|
+
/** @type {Event[]} */
|
|
1121
|
+
const artificialEvents = [];
|
|
1122
|
+
artificialEvents.push(
|
|
1123
|
+
[ "enter", undefinedReferenceType, tokenizeContext ],
|
|
1124
|
+
[ "enter", undefinedReference, tokenizeContext ]
|
|
1125
|
+
);
|
|
1126
|
+
for (const event of eventsToReplicate) {
|
|
1127
|
+
const [ kind, token ] = event;
|
|
1128
|
+
// Copy token because the current object will get modified by the parser
|
|
1129
|
+
artificialEvents.push([ kind, { ...token }, tokenizeContext ]);
|
|
1130
|
+
}
|
|
1131
|
+
artificialEvents.push(
|
|
1132
|
+
[ "exit", undefinedReference, tokenizeContext ],
|
|
1133
|
+
[ "exit", undefinedReferenceType, tokenizeContext ]
|
|
1134
|
+
);
|
|
1135
|
+
artificialEventLists.push(artificialEvents);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
// Continue with original behavior
|
|
1140
|
+
return nokOriginal(code);
|
|
1141
|
+
};
|
|
1142
|
+
|
|
1143
|
+
// Shim nok handler of labelEnd's tokenize
|
|
1144
|
+
return tokenizeOriginal.call(tokenizeContext, effects, okOriginal, nokShim);
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
try {
|
|
1148
|
+
// Shim labelEnd behavior to detect undefined references
|
|
1149
|
+
labelEnd.tokenize = tokenizeShim;
|
|
1150
|
+
|
|
1151
|
+
// Use micromark to parse document into Events
|
|
1152
|
+
const encoding = undefined;
|
|
1153
|
+
const eol = true;
|
|
1154
|
+
const parseContext = micromark.parse({ ...micromarkParseOptions, extensions });
|
|
1155
|
+
const chunks = micromark.preprocess()(markdown, encoding, eol);
|
|
1156
|
+
const events = micromark.postprocess(parseContext.document().write(chunks));
|
|
1157
|
+
|
|
1158
|
+
// Append artificial events and return all events
|
|
1159
|
+
// eslint-disable-next-line unicorn/prefer-spread
|
|
1160
|
+
return events.concat(...artificialEventLists);
|
|
1161
|
+
} finally {
|
|
1162
|
+
// Restore shimmed labelEnd behavior
|
|
1163
|
+
labelEnd.tokenize = tokenizeOriginal;
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
/**
|
|
1168
|
+
* Parses a Markdown document and returns micromark tokens (internal).
|
|
1169
|
+
*
|
|
1170
|
+
* @param {string} markdown Markdown document.
|
|
1171
|
+
* @param {ParseOptions} [parseOptions] Options.
|
|
1172
|
+
* @param {MicromarkParseOptions} [micromarkParseOptions] Options for micromark.
|
|
1173
|
+
* @param {number} [lineDelta] Offset for start/end line.
|
|
1174
|
+
* @param {MicromarkToken} [ancestor] Parent of top-most tokens.
|
|
1175
|
+
* @returns {MicromarkToken[]} Micromark tokens.
|
|
1176
|
+
*/
|
|
1177
|
+
function parseInternal(
|
|
1178
|
+
markdown,
|
|
1179
|
+
parseOptions = {},
|
|
1180
|
+
micromarkParseOptions = {},
|
|
1181
|
+
lineDelta = 0,
|
|
1182
|
+
ancestor = undefined
|
|
1183
|
+
) {
|
|
1184
|
+
// Get options
|
|
1185
|
+
const freezeTokens = Boolean(parseOptions.freezeTokens);
|
|
1186
|
+
|
|
1187
|
+
// Use micromark to parse document into Events
|
|
1188
|
+
const events = getEvents(markdown, micromarkParseOptions);
|
|
1189
|
+
|
|
1190
|
+
// Create Token objects
|
|
1191
|
+
const document = [];
|
|
1192
|
+
let flatTokens = [];
|
|
1193
|
+
/** @type {MicromarkToken} */
|
|
1194
|
+
const root = {
|
|
1195
|
+
"type": "data",
|
|
1196
|
+
"startLine": -1,
|
|
1197
|
+
"startColumn": -1,
|
|
1198
|
+
"endLine": -1,
|
|
1199
|
+
"endColumn": -1,
|
|
1200
|
+
"text": "ROOT",
|
|
1201
|
+
"children": document,
|
|
1202
|
+
"parent": null
|
|
1203
|
+
};
|
|
1204
|
+
const history = [ root ];
|
|
1205
|
+
let current = root;
|
|
1206
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
1207
|
+
/** @type MicromarkParseOptions | null */
|
|
1208
|
+
let reparseOptions = null;
|
|
1209
|
+
let lines = null;
|
|
1210
|
+
let skipHtmlFlowChildren = false;
|
|
1211
|
+
for (const event of events) {
|
|
1212
|
+
const [ kind, token, context ] = event;
|
|
1213
|
+
const { type, start, end } = token;
|
|
1214
|
+
const { "column": startColumn, "line": startLine } = start;
|
|
1215
|
+
const { "column": endColumn, "line": endLine } = end;
|
|
1216
|
+
const text = context.sliceSerialize(token);
|
|
1217
|
+
if ((kind === "enter") && !skipHtmlFlowChildren) {
|
|
1218
|
+
const previous = current;
|
|
1219
|
+
history.push(previous);
|
|
1220
|
+
current = {
|
|
1221
|
+
type,
|
|
1222
|
+
"startLine": startLine + lineDelta,
|
|
1223
|
+
startColumn,
|
|
1224
|
+
"endLine": endLine + lineDelta,
|
|
1225
|
+
endColumn,
|
|
1226
|
+
text,
|
|
1227
|
+
"children": [],
|
|
1228
|
+
"parent": ((previous === root) ? (ancestor || null) : previous)
|
|
1229
|
+
};
|
|
1230
|
+
if (ancestor) {
|
|
1231
|
+
Object.defineProperty(current, htmlFlowSymbol, { "value": true });
|
|
1232
|
+
}
|
|
1233
|
+
previous.children.push(current);
|
|
1234
|
+
flatTokens.push(current);
|
|
1235
|
+
if ((current.type === "htmlFlow") && !isHtmlFlowComment(current)) {
|
|
1236
|
+
skipHtmlFlowChildren = true;
|
|
1237
|
+
if (!reparseOptions || !lines) {
|
|
1238
|
+
reparseOptions = {
|
|
1239
|
+
...micromarkParseOptions,
|
|
1240
|
+
"extensions": [
|
|
1241
|
+
{
|
|
1242
|
+
"disable": {
|
|
1243
|
+
"null": [ "codeIndented", "htmlFlow" ]
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
]
|
|
1247
|
+
};
|
|
1248
|
+
lines = markdown.split(newLineRe);
|
|
1249
|
+
}
|
|
1250
|
+
const reparseMarkdown = lines
|
|
1251
|
+
.slice(current.startLine - 1, current.endLine)
|
|
1252
|
+
.join("\n");
|
|
1253
|
+
const tokens = parseInternal(
|
|
1254
|
+
reparseMarkdown,
|
|
1255
|
+
parseOptions,
|
|
1256
|
+
reparseOptions,
|
|
1257
|
+
current.startLine - 1,
|
|
1258
|
+
current
|
|
1259
|
+
);
|
|
1260
|
+
current.children = tokens;
|
|
1261
|
+
// Avoid stack overflow of Array.push(...spread)
|
|
1262
|
+
// eslint-disable-next-line unicorn/prefer-spread
|
|
1263
|
+
flatTokens = flatTokens.concat(tokens[flatTokensSymbol]);
|
|
1264
|
+
}
|
|
1265
|
+
} else if (kind === "exit") {
|
|
1266
|
+
if (type === "htmlFlow") {
|
|
1267
|
+
skipHtmlFlowChildren = false;
|
|
1268
|
+
}
|
|
1269
|
+
if (!skipHtmlFlowChildren) {
|
|
1270
|
+
if (freezeTokens) {
|
|
1271
|
+
Object.freeze(current.children);
|
|
1272
|
+
Object.freeze(current);
|
|
1273
|
+
}
|
|
1274
|
+
// @ts-ignore
|
|
1275
|
+
current = history.pop();
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
// Return document
|
|
1281
|
+
Object.defineProperty(document, flatTokensSymbol, { "value": flatTokens });
|
|
1282
|
+
if (freezeTokens) {
|
|
1283
|
+
Object.freeze(document);
|
|
1284
|
+
}
|
|
1285
|
+
return document;
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
/**
|
|
1289
|
+
* Parses a Markdown document and returns micromark tokens.
|
|
1290
|
+
*
|
|
1291
|
+
* @param {string} markdown Markdown document.
|
|
1292
|
+
* @param {ParseOptions} [parseOptions] Options.
|
|
1293
|
+
* @returns {MicromarkToken[]} Micromark tokens.
|
|
1294
|
+
*/
|
|
1295
|
+
function parse(markdown, parseOptions) {
|
|
1296
|
+
return parseInternal(markdown, parseOptions);
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
module.exports = {
|
|
1300
|
+
getEvents,
|
|
1301
|
+
parse
|
|
1490
1302
|
};
|
|
1491
1303
|
|
|
1492
1304
|
|
|
@@ -1504,11 +1316,10 @@ module.exports = {
|
|
|
1504
1316
|
|
|
1505
1317
|
|
|
1506
1318
|
const helpers = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
1507
|
-
const { filterByTypes } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
1319
|
+
const { filterByTypes } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
1508
1320
|
|
|
1509
1321
|
/** @type {Map<string, object>} */
|
|
1510
1322
|
const map = new Map();
|
|
1511
|
-
// eslint-disable-next-line no-undef-init
|
|
1512
1323
|
let params = undefined;
|
|
1513
1324
|
|
|
1514
1325
|
/**
|
|
@@ -1533,70 +1344,254 @@ function getCached(name, getValue) {
|
|
|
1533
1344
|
if (map.has(name)) {
|
|
1534
1345
|
return map.get(name);
|
|
1535
1346
|
}
|
|
1536
|
-
const value = getValue();
|
|
1537
|
-
map.set(name, value);
|
|
1538
|
-
return value;
|
|
1347
|
+
const value = getValue();
|
|
1348
|
+
map.set(name, value);
|
|
1349
|
+
return value;
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
/**
|
|
1353
|
+
* Filters a list of Micromark tokens by type and caches the result.
|
|
1354
|
+
*
|
|
1355
|
+
* @param {import("./markdownlint").MicromarkTokenType[]} types Types to allow.
|
|
1356
|
+
* @param {boolean} [htmlFlow] Whether to include htmlFlow content.
|
|
1357
|
+
* @returns {import("./markdownlint").MicromarkToken[]} Filtered tokens.
|
|
1358
|
+
*/
|
|
1359
|
+
function filterByTypesCached(types, htmlFlow) {
|
|
1360
|
+
return getCached(
|
|
1361
|
+
// eslint-disable-next-line prefer-rest-params
|
|
1362
|
+
JSON.stringify(arguments),
|
|
1363
|
+
() => filterByTypes(params.parsers.micromark.tokens, types, htmlFlow)
|
|
1364
|
+
);
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
/**
|
|
1368
|
+
* Gets a reference link and image data object.
|
|
1369
|
+
*
|
|
1370
|
+
* @returns {Object} Reference link and image data object.
|
|
1371
|
+
*/
|
|
1372
|
+
function getReferenceLinkImageData() {
|
|
1373
|
+
return getCached(
|
|
1374
|
+
getReferenceLinkImageData.name,
|
|
1375
|
+
() => helpers.getReferenceLinkImageData(params.parsers.micromark.tokens)
|
|
1376
|
+
);
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
module.exports = {
|
|
1380
|
+
initialize,
|
|
1381
|
+
filterByTypesCached,
|
|
1382
|
+
getReferenceLinkImageData
|
|
1383
|
+
};
|
|
1384
|
+
|
|
1385
|
+
|
|
1386
|
+
/***/ }),
|
|
1387
|
+
|
|
1388
|
+
/***/ "../lib/constants.js":
|
|
1389
|
+
/*!***************************!*\
|
|
1390
|
+
!*** ../lib/constants.js ***!
|
|
1391
|
+
\***************************/
|
|
1392
|
+
/***/ ((module) => {
|
|
1393
|
+
|
|
1394
|
+
"use strict";
|
|
1395
|
+
// @ts-check
|
|
1396
|
+
|
|
1397
|
+
|
|
1398
|
+
|
|
1399
|
+
module.exports.deprecatedRuleNames = [];
|
|
1400
|
+
module.exports.fixableRuleNames = [
|
|
1401
|
+
"MD004", "MD005", "MD007", "MD009", "MD010", "MD011",
|
|
1402
|
+
"MD012", "MD014", "MD018", "MD019", "MD020", "MD021",
|
|
1403
|
+
"MD022", "MD023", "MD026", "MD027", "MD030", "MD031",
|
|
1404
|
+
"MD032", "MD034", "MD037", "MD038", "MD039", "MD044",
|
|
1405
|
+
"MD047", "MD049", "MD050", "MD051", "MD053", "MD054",
|
|
1406
|
+
"MD058"
|
|
1407
|
+
];
|
|
1408
|
+
module.exports.homepage = "https://github.com/DavidAnson/markdownlint";
|
|
1409
|
+
module.exports.version = "0.36.0";
|
|
1410
|
+
|
|
1411
|
+
|
|
1412
|
+
/***/ }),
|
|
1413
|
+
|
|
1414
|
+
/***/ "../lib/markdownit.cjs":
|
|
1415
|
+
/*!*****************************!*\
|
|
1416
|
+
!*** ../lib/markdownit.cjs ***!
|
|
1417
|
+
\*****************************/
|
|
1418
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
1419
|
+
|
|
1420
|
+
"use strict";
|
|
1421
|
+
// @ts-check
|
|
1422
|
+
|
|
1423
|
+
|
|
1424
|
+
|
|
1425
|
+
const { newLineRe } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
1426
|
+
|
|
1427
|
+
/**
|
|
1428
|
+
* @callback InlineCodeSpanCallback
|
|
1429
|
+
* @param {string} code Code content.
|
|
1430
|
+
* @param {number} lineIndex Line index (0-based).
|
|
1431
|
+
* @param {number} columnIndex Column index (0-based).
|
|
1432
|
+
* @param {number} ticks Count of backticks.
|
|
1433
|
+
* @returns {void}
|
|
1434
|
+
*/
|
|
1435
|
+
|
|
1436
|
+
/**
|
|
1437
|
+
* Calls the provided function for each inline code span's content.
|
|
1438
|
+
*
|
|
1439
|
+
* @param {string} input Markdown content.
|
|
1440
|
+
* @param {InlineCodeSpanCallback} handler Callback function taking (code,
|
|
1441
|
+
* lineIndex, columnIndex, ticks).
|
|
1442
|
+
* @returns {void}
|
|
1443
|
+
*/
|
|
1444
|
+
function forEachInlineCodeSpan(input, handler) {
|
|
1445
|
+
const backtickRe = /`+/g;
|
|
1446
|
+
let match = null;
|
|
1447
|
+
const backticksLengthAndIndex = [];
|
|
1448
|
+
while ((match = backtickRe.exec(input)) !== null) {
|
|
1449
|
+
backticksLengthAndIndex.push([ match[0].length, match.index ]);
|
|
1450
|
+
}
|
|
1451
|
+
const newLinesIndex = [];
|
|
1452
|
+
while ((match = newLineRe.exec(input)) !== null) {
|
|
1453
|
+
newLinesIndex.push(match.index);
|
|
1454
|
+
}
|
|
1455
|
+
let lineIndex = 0;
|
|
1456
|
+
let lineStartIndex = 0;
|
|
1457
|
+
let k = 0;
|
|
1458
|
+
for (let i = 0; i < backticksLengthAndIndex.length - 1; i++) {
|
|
1459
|
+
const [ startLength, startIndex ] = backticksLengthAndIndex[i];
|
|
1460
|
+
if ((startIndex === 0) || (input[startIndex - 1] !== "\\")) {
|
|
1461
|
+
for (let j = i + 1; j < backticksLengthAndIndex.length; j++) {
|
|
1462
|
+
const [ endLength, endIndex ] = backticksLengthAndIndex[j];
|
|
1463
|
+
if (startLength === endLength) {
|
|
1464
|
+
for (; k < newLinesIndex.length; k++) {
|
|
1465
|
+
const newLineIndex = newLinesIndex[k];
|
|
1466
|
+
if (startIndex < newLineIndex) {
|
|
1467
|
+
break;
|
|
1468
|
+
}
|
|
1469
|
+
lineIndex++;
|
|
1470
|
+
lineStartIndex = newLineIndex + 1;
|
|
1471
|
+
}
|
|
1472
|
+
const columnIndex = startIndex - lineStartIndex + startLength;
|
|
1473
|
+
handler(
|
|
1474
|
+
input.slice(startIndex + startLength, endIndex),
|
|
1475
|
+
lineIndex,
|
|
1476
|
+
columnIndex,
|
|
1477
|
+
startLength
|
|
1478
|
+
);
|
|
1479
|
+
i = j;
|
|
1480
|
+
break;
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
/**
|
|
1488
|
+
* Freeze all freeze-able members of a token and its children.
|
|
1489
|
+
*
|
|
1490
|
+
* @param {import("./markdownlint").MarkdownItToken} token A markdown-it token.
|
|
1491
|
+
* @returns {void}
|
|
1492
|
+
*/
|
|
1493
|
+
function freezeToken(token) {
|
|
1494
|
+
if (token.attrs) {
|
|
1495
|
+
for (const attr of token.attrs) {
|
|
1496
|
+
Object.freeze(attr);
|
|
1497
|
+
}
|
|
1498
|
+
Object.freeze(token.attrs);
|
|
1499
|
+
}
|
|
1500
|
+
if (token.children) {
|
|
1501
|
+
for (const child of token.children) {
|
|
1502
|
+
freezeToken(child);
|
|
1503
|
+
}
|
|
1504
|
+
Object.freeze(token.children);
|
|
1505
|
+
}
|
|
1506
|
+
if (token.map) {
|
|
1507
|
+
Object.freeze(token.map);
|
|
1508
|
+
}
|
|
1509
|
+
Object.freeze(token);
|
|
1539
1510
|
}
|
|
1540
1511
|
|
|
1541
1512
|
/**
|
|
1542
|
-
*
|
|
1513
|
+
* Annotate tokens with line/lineNumber and freeze them.
|
|
1543
1514
|
*
|
|
1544
|
-
* @param {
|
|
1545
|
-
* @param {
|
|
1546
|
-
* @returns {
|
|
1515
|
+
* @param {Object[]} tokens Array of markdown-it tokens.
|
|
1516
|
+
* @param {string[]} lines Lines of Markdown content.
|
|
1517
|
+
* @returns {void}
|
|
1547
1518
|
*/
|
|
1548
|
-
function
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1519
|
+
function annotateAndFreezeTokens(tokens, lines) {
|
|
1520
|
+
let trMap = null;
|
|
1521
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
1522
|
+
/** @type import("./markdownlint").MarkdownItToken[] */
|
|
1523
|
+
// @ts-ignore
|
|
1524
|
+
const markdownItTokens = tokens;
|
|
1525
|
+
for (const token of markdownItTokens) {
|
|
1526
|
+
// Provide missing maps for table content
|
|
1527
|
+
if (token.type === "tr_open") {
|
|
1528
|
+
trMap = token.map;
|
|
1529
|
+
} else if (token.type === "tr_close") {
|
|
1530
|
+
trMap = null;
|
|
1531
|
+
}
|
|
1532
|
+
if (!token.map && trMap) {
|
|
1533
|
+
token.map = [ ...trMap ];
|
|
1534
|
+
}
|
|
1535
|
+
// Update token metadata
|
|
1536
|
+
if (token.map) {
|
|
1537
|
+
token.line = lines[token.map[0]];
|
|
1538
|
+
token.lineNumber = token.map[0] + 1;
|
|
1539
|
+
// Trim bottom of token to exclude whitespace lines
|
|
1540
|
+
while (token.map[1] && !((lines[token.map[1] - 1] || "").trim())) {
|
|
1541
|
+
token.map[1]--;
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
// Annotate children with lineNumber
|
|
1545
|
+
if (token.children) {
|
|
1546
|
+
const codeSpanExtraLines = [];
|
|
1547
|
+
if (token.children.some((child) => child.type === "code_inline")) {
|
|
1548
|
+
forEachInlineCodeSpan(token.content, (code) => {
|
|
1549
|
+
codeSpanExtraLines.push(code.split(newLineRe).length - 1);
|
|
1550
|
+
});
|
|
1551
|
+
}
|
|
1552
|
+
let lineNumber = token.lineNumber;
|
|
1553
|
+
for (const child of token.children) {
|
|
1554
|
+
child.lineNumber = lineNumber;
|
|
1555
|
+
child.line = lines[lineNumber - 1];
|
|
1556
|
+
if ((child.type === "softbreak") || (child.type === "hardbreak")) {
|
|
1557
|
+
lineNumber++;
|
|
1558
|
+
} else if (child.type === "code_inline") {
|
|
1559
|
+
lineNumber += codeSpanExtraLines.shift();
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
freezeToken(token);
|
|
1564
|
+
}
|
|
1565
|
+
Object.freeze(tokens);
|
|
1553
1566
|
}
|
|
1554
1567
|
|
|
1555
1568
|
/**
|
|
1556
|
-
* Gets
|
|
1569
|
+
* Gets an array of markdown-it tokens for the input.
|
|
1557
1570
|
*
|
|
1558
|
-
* @
|
|
1571
|
+
* @param {import("./markdownlint").Plugin[]} markdownItPlugins Additional plugins.
|
|
1572
|
+
* @param {string} content Markdown content.
|
|
1573
|
+
* @param {string[]} lines Lines of Markdown content.
|
|
1574
|
+
* @returns {import("../lib/markdownlint").MarkdownItToken} Array of markdown-it tokens.
|
|
1559
1575
|
*/
|
|
1560
|
-
function
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1576
|
+
function getMarkdownItTokens(markdownItPlugins, content, lines) {
|
|
1577
|
+
const markdownit = __webpack_require__(/*! markdown-it */ "markdown-it");
|
|
1578
|
+
const md = markdownit({ "html": true });
|
|
1579
|
+
for (const plugin of markdownItPlugins) {
|
|
1580
|
+
// @ts-ignore
|
|
1581
|
+
md.use(...plugin);
|
|
1582
|
+
}
|
|
1583
|
+
const tokens = md.parse(content, {});
|
|
1584
|
+
annotateAndFreezeTokens(tokens, lines);
|
|
1585
|
+
// @ts-ignore
|
|
1586
|
+
return tokens;
|
|
1587
|
+
};
|
|
1566
1588
|
|
|
1567
1589
|
module.exports = {
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
getReferenceLinkImageData
|
|
1590
|
+
forEachInlineCodeSpan,
|
|
1591
|
+
getMarkdownItTokens
|
|
1571
1592
|
};
|
|
1572
1593
|
|
|
1573
1594
|
|
|
1574
|
-
/***/ }),
|
|
1575
|
-
|
|
1576
|
-
/***/ "../lib/constants.js":
|
|
1577
|
-
/*!***************************!*\
|
|
1578
|
-
!*** ../lib/constants.js ***!
|
|
1579
|
-
\***************************/
|
|
1580
|
-
/***/ ((module) => {
|
|
1581
|
-
|
|
1582
|
-
"use strict";
|
|
1583
|
-
// @ts-check
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
module.exports.deprecatedRuleNames = [];
|
|
1588
|
-
module.exports.fixableRuleNames = [
|
|
1589
|
-
"MD004", "MD005", "MD007", "MD009", "MD010", "MD011",
|
|
1590
|
-
"MD012", "MD014", "MD018", "MD019", "MD020", "MD021",
|
|
1591
|
-
"MD022", "MD023", "MD026", "MD027", "MD030", "MD031",
|
|
1592
|
-
"MD032", "MD034", "MD037", "MD038", "MD039", "MD044",
|
|
1593
|
-
"MD047", "MD049", "MD050", "MD051", "MD053", "MD054",
|
|
1594
|
-
"MD058"
|
|
1595
|
-
];
|
|
1596
|
-
module.exports.homepage = "https://github.com/DavidAnson/markdownlint";
|
|
1597
|
-
module.exports.version = "0.35.0";
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
1595
|
/***/ }),
|
|
1601
1596
|
|
|
1602
1597
|
/***/ "../lib/markdownlint.js":
|
|
@@ -1612,8 +1607,8 @@ module.exports.version = "0.35.0";
|
|
|
1612
1607
|
|
|
1613
1608
|
const path = __webpack_require__(/*! node:path */ "?9a52");
|
|
1614
1609
|
const { promisify } = __webpack_require__(/*! node:util */ "?39e5");
|
|
1615
|
-
const micromark = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
1616
|
-
|
|
1610
|
+
const micromark = __webpack_require__(/*! ../helpers/micromark-parse.cjs */ "../helpers/micromark-parse.cjs");
|
|
1611
|
+
const { version } = __webpack_require__(/*! ./constants */ "../lib/constants.js");
|
|
1617
1612
|
const rules = __webpack_require__(/*! ./rules */ "../lib/rules.js");
|
|
1618
1613
|
const helpers = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
1619
1614
|
const cache = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
@@ -1666,7 +1661,7 @@ function validateRuleList(ruleList, synchronous) {
|
|
|
1666
1661
|
!result &&
|
|
1667
1662
|
(rule.parser !== undefined) &&
|
|
1668
1663
|
(rule.parser !== "markdownit") &&
|
|
1669
|
-
|
|
1664
|
+
(rule.parser !== "micromark") &&
|
|
1670
1665
|
(rule.parser !== "none")
|
|
1671
1666
|
) {
|
|
1672
1667
|
result = newError("parser", rule.parser);
|
|
@@ -1805,87 +1800,6 @@ function removeFrontMatter(content, frontMatter) {
|
|
|
1805
1800
|
};
|
|
1806
1801
|
}
|
|
1807
1802
|
|
|
1808
|
-
/**
|
|
1809
|
-
* Freeze all freeze-able members of a token and its children.
|
|
1810
|
-
*
|
|
1811
|
-
* @param {MarkdownItToken} token A markdown-it token.
|
|
1812
|
-
* @returns {void}
|
|
1813
|
-
*/
|
|
1814
|
-
function freezeToken(token) {
|
|
1815
|
-
if (token.attrs) {
|
|
1816
|
-
for (const attr of token.attrs) {
|
|
1817
|
-
Object.freeze(attr);
|
|
1818
|
-
}
|
|
1819
|
-
Object.freeze(token.attrs);
|
|
1820
|
-
}
|
|
1821
|
-
if (token.children) {
|
|
1822
|
-
for (const child of token.children) {
|
|
1823
|
-
freezeToken(child);
|
|
1824
|
-
}
|
|
1825
|
-
Object.freeze(token.children);
|
|
1826
|
-
}
|
|
1827
|
-
if (token.map) {
|
|
1828
|
-
Object.freeze(token.map);
|
|
1829
|
-
}
|
|
1830
|
-
Object.freeze(token);
|
|
1831
|
-
}
|
|
1832
|
-
|
|
1833
|
-
/**
|
|
1834
|
-
* Annotate tokens with line/lineNumber and freeze them.
|
|
1835
|
-
*
|
|
1836
|
-
* @param {import("markdown-it").Token[]} tokens Array of markdown-it tokens.
|
|
1837
|
-
* @param {string[]} lines Lines of Markdown content.
|
|
1838
|
-
* @returns {void}
|
|
1839
|
-
*/
|
|
1840
|
-
function annotateAndFreezeTokens(tokens, lines) {
|
|
1841
|
-
let trMap = null;
|
|
1842
|
-
// eslint-disable-next-line jsdoc/valid-types
|
|
1843
|
-
/** @type MarkdownItToken[] */
|
|
1844
|
-
// @ts-ignore
|
|
1845
|
-
const markdownItTokens = tokens;
|
|
1846
|
-
for (const token of markdownItTokens) {
|
|
1847
|
-
// Provide missing maps for table content
|
|
1848
|
-
if (token.type === "tr_open") {
|
|
1849
|
-
trMap = token.map;
|
|
1850
|
-
} else if (token.type === "tr_close") {
|
|
1851
|
-
trMap = null;
|
|
1852
|
-
}
|
|
1853
|
-
if (!token.map && trMap) {
|
|
1854
|
-
token.map = [ ...trMap ];
|
|
1855
|
-
}
|
|
1856
|
-
// Update token metadata
|
|
1857
|
-
if (token.map) {
|
|
1858
|
-
token.line = lines[token.map[0]];
|
|
1859
|
-
token.lineNumber = token.map[0] + 1;
|
|
1860
|
-
// Trim bottom of token to exclude whitespace lines
|
|
1861
|
-
while (token.map[1] && !((lines[token.map[1] - 1] || "").trim())) {
|
|
1862
|
-
token.map[1]--;
|
|
1863
|
-
}
|
|
1864
|
-
}
|
|
1865
|
-
// Annotate children with lineNumber
|
|
1866
|
-
if (token.children) {
|
|
1867
|
-
const codeSpanExtraLines = [];
|
|
1868
|
-
if (token.children.some((child) => child.type === "code_inline")) {
|
|
1869
|
-
helpers.forEachInlineCodeSpan(token.content, (code) => {
|
|
1870
|
-
codeSpanExtraLines.push(code.split(helpers.newLineRe).length - 1);
|
|
1871
|
-
});
|
|
1872
|
-
}
|
|
1873
|
-
let lineNumber = token.lineNumber;
|
|
1874
|
-
for (const child of token.children) {
|
|
1875
|
-
child.lineNumber = lineNumber;
|
|
1876
|
-
child.line = lines[lineNumber - 1];
|
|
1877
|
-
if ((child.type === "softbreak") || (child.type === "hardbreak")) {
|
|
1878
|
-
lineNumber++;
|
|
1879
|
-
} else if (child.type === "code_inline") {
|
|
1880
|
-
lineNumber += codeSpanExtraLines.shift();
|
|
1881
|
-
}
|
|
1882
|
-
}
|
|
1883
|
-
}
|
|
1884
|
-
freezeToken(token);
|
|
1885
|
-
}
|
|
1886
|
-
Object.freeze(tokens);
|
|
1887
|
-
}
|
|
1888
|
-
|
|
1889
1803
|
/**
|
|
1890
1804
|
* Map rule names/tags to canonical rule name.
|
|
1891
1805
|
*
|
|
@@ -2141,7 +2055,7 @@ function getEnabledRulesPerLineNumber(
|
|
|
2141
2055
|
* names.
|
|
2142
2056
|
* @param {string} name Identifier for the content.
|
|
2143
2057
|
* @param {string} content Markdown content.
|
|
2144
|
-
* @param {
|
|
2058
|
+
* @param {Plugin[]} markdownItPlugins Additional plugins.
|
|
2145
2059
|
* @param {Configuration} config Configuration object.
|
|
2146
2060
|
* @param {ConfigurationParser[] | null} configParsers Configuration parsers.
|
|
2147
2061
|
* @param {RegExp | null} frontMatter Regular expression for front matter.
|
|
@@ -2156,7 +2070,7 @@ function lintContent(
|
|
|
2156
2070
|
aliasToRuleNames,
|
|
2157
2071
|
name,
|
|
2158
2072
|
content,
|
|
2159
|
-
|
|
2073
|
+
markdownItPlugins,
|
|
2160
2074
|
config,
|
|
2161
2075
|
configParsers,
|
|
2162
2076
|
frontMatter,
|
|
@@ -2184,14 +2098,20 @@ function lintContent(
|
|
|
2184
2098
|
const needMarkdownItTokens = enabledRuleList.some(
|
|
2185
2099
|
(rule) => (rule.parser === "markdownit") || (rule.parser === undefined)
|
|
2186
2100
|
);
|
|
2101
|
+
const customRulesPresent = (ruleList.length !== rules.length);
|
|
2187
2102
|
// Parse content into parser tokens
|
|
2188
|
-
const
|
|
2189
|
-
|
|
2103
|
+
const micromarkTokens = micromark.parse(
|
|
2104
|
+
content,
|
|
2105
|
+
{ "freezeTokens": customRulesPresent }
|
|
2106
|
+
);
|
|
2190
2107
|
// Hide the content of HTML comments from rules
|
|
2108
|
+
const preClearedContent = content;
|
|
2191
2109
|
content = helpers.clearHtmlCommentText(content);
|
|
2192
|
-
// Parse content into lines and
|
|
2110
|
+
// Parse content into lines and get markdown-it tokens
|
|
2193
2111
|
const lines = content.split(helpers.newLineRe);
|
|
2194
|
-
|
|
2112
|
+
const markdownitTokens = needMarkdownItTokens ?
|
|
2113
|
+
(__webpack_require__(/*! ./markdownit.cjs */ "../lib/markdownit.cjs").getMarkdownItTokens)(markdownItPlugins, preClearedContent, lines) :
|
|
2114
|
+
[];
|
|
2195
2115
|
// Create (frozen) parameters for rules
|
|
2196
2116
|
/** @type {MarkdownParsers} */
|
|
2197
2117
|
// @ts-ignore
|
|
@@ -2212,6 +2132,7 @@ function lintContent(
|
|
|
2212
2132
|
const parsersNone = Object.freeze({});
|
|
2213
2133
|
const paramsBase = {
|
|
2214
2134
|
name,
|
|
2135
|
+
version,
|
|
2215
2136
|
"lines": Object.freeze(lines),
|
|
2216
2137
|
"frontMatterLines": Object.freeze(frontMatterLines)
|
|
2217
2138
|
};
|
|
@@ -2444,7 +2365,7 @@ function lintContent(
|
|
|
2444
2365
|
* @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule
|
|
2445
2366
|
* names.
|
|
2446
2367
|
* @param {string} file Path of file to lint.
|
|
2447
|
-
* @param {
|
|
2368
|
+
* @param {Plugin[]} markdownItPlugins Additional plugins.
|
|
2448
2369
|
* @param {Configuration} config Configuration object.
|
|
2449
2370
|
* @param {ConfigurationParser[] | null} configParsers Configuration parsers.
|
|
2450
2371
|
* @param {RegExp | null} frontMatter Regular expression for front matter.
|
|
@@ -2460,7 +2381,7 @@ function lintFile(
|
|
|
2460
2381
|
ruleList,
|
|
2461
2382
|
aliasToRuleNames,
|
|
2462
2383
|
file,
|
|
2463
|
-
|
|
2384
|
+
markdownItPlugins,
|
|
2464
2385
|
config,
|
|
2465
2386
|
configParsers,
|
|
2466
2387
|
frontMatter,
|
|
@@ -2480,7 +2401,7 @@ function lintFile(
|
|
|
2480
2401
|
aliasToRuleNames,
|
|
2481
2402
|
file,
|
|
2482
2403
|
content,
|
|
2483
|
-
|
|
2404
|
+
markdownItPlugins,
|
|
2484
2405
|
config,
|
|
2485
2406
|
configParsers,
|
|
2486
2407
|
frontMatter,
|
|
@@ -2540,21 +2461,14 @@ function lintInput(options, synchronous, callback) {
|
|
|
2540
2461
|
const config = options.config || { "default": true };
|
|
2541
2462
|
const configParsers = options.configParsers || null;
|
|
2542
2463
|
const frontMatter = (options.frontMatter === undefined) ?
|
|
2543
|
-
helpers.frontMatterRe :
|
|
2464
|
+
helpers.frontMatterRe :
|
|
2465
|
+
options.frontMatter;
|
|
2544
2466
|
const handleRuleFailures = !!options.handleRuleFailures;
|
|
2545
2467
|
const noInlineConfig = !!options.noInlineConfig;
|
|
2546
2468
|
const resultVersion = (options.resultVersion === undefined) ?
|
|
2547
|
-
3 :
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
const md = markdownit({ "html": true });
|
|
2551
|
-
const markdownItPlugins = options.markdownItPlugins || [];
|
|
2552
|
-
for (const plugin of markdownItPlugins) {
|
|
2553
|
-
// @ts-ignore
|
|
2554
|
-
md.use(...plugin);
|
|
2555
|
-
}
|
|
2556
|
-
return md;
|
|
2557
|
-
};
|
|
2469
|
+
3 :
|
|
2470
|
+
options.resultVersion;
|
|
2471
|
+
const markdownItPlugins = options.markdownItPlugins || [];
|
|
2558
2472
|
const fs = options.fs || __webpack_require__(/*! node:fs */ "?d0ee");
|
|
2559
2473
|
const aliasToRuleNames = mapAliasToRuleNames(ruleList);
|
|
2560
2474
|
const results = newResults(ruleList);
|
|
@@ -2586,7 +2500,7 @@ function lintInput(options, synchronous, callback) {
|
|
|
2586
2500
|
ruleList,
|
|
2587
2501
|
aliasToRuleNames,
|
|
2588
2502
|
currentItem,
|
|
2589
|
-
|
|
2503
|
+
markdownItPlugins,
|
|
2590
2504
|
config,
|
|
2591
2505
|
configParsers,
|
|
2592
2506
|
frontMatter,
|
|
@@ -2605,7 +2519,7 @@ function lintInput(options, synchronous, callback) {
|
|
|
2605
2519
|
aliasToRuleNames,
|
|
2606
2520
|
currentItem,
|
|
2607
2521
|
strings[currentItem] || "",
|
|
2608
|
-
|
|
2522
|
+
markdownItPlugins,
|
|
2609
2523
|
config,
|
|
2610
2524
|
configParsers,
|
|
2611
2525
|
frontMatter,
|
|
@@ -2889,12 +2803,125 @@ function readConfigSync(file, parsers, fs) {
|
|
|
2889
2803
|
helpers.expandTildePath(configExtends, os),
|
|
2890
2804
|
fs
|
|
2891
2805
|
);
|
|
2892
|
-
return {
|
|
2893
|
-
...readConfigSync(resolvedExtends, parsers, fs),
|
|
2894
|
-
...config
|
|
2895
|
-
};
|
|
2806
|
+
return {
|
|
2807
|
+
...readConfigSync(resolvedExtends, parsers, fs),
|
|
2808
|
+
...config
|
|
2809
|
+
};
|
|
2810
|
+
}
|
|
2811
|
+
return config;
|
|
2812
|
+
}
|
|
2813
|
+
|
|
2814
|
+
/**
|
|
2815
|
+
* Normalizes the fields of a RuleOnErrorFixInfo instance.
|
|
2816
|
+
*
|
|
2817
|
+
* @param {RuleOnErrorFixInfo} fixInfo RuleOnErrorFixInfo instance.
|
|
2818
|
+
* @param {number} [lineNumber] Line number.
|
|
2819
|
+
* @returns {RuleOnErrorFixInfoNormalized} Normalized RuleOnErrorFixInfo instance.
|
|
2820
|
+
*/
|
|
2821
|
+
function normalizeFixInfo(fixInfo, lineNumber = 0) {
|
|
2822
|
+
return {
|
|
2823
|
+
"lineNumber": fixInfo.lineNumber || lineNumber,
|
|
2824
|
+
"editColumn": fixInfo.editColumn || 1,
|
|
2825
|
+
"deleteCount": fixInfo.deleteCount || 0,
|
|
2826
|
+
"insertText": fixInfo.insertText || ""
|
|
2827
|
+
};
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
/**
|
|
2831
|
+
* Applies the specified fix to a Markdown content line.
|
|
2832
|
+
*
|
|
2833
|
+
* @param {string} line Line of Markdown content.
|
|
2834
|
+
* @param {RuleOnErrorFixInfo} fixInfo RuleOnErrorFixInfo instance.
|
|
2835
|
+
* @param {string} [lineEnding] Line ending to use.
|
|
2836
|
+
* @returns {string | null} Fixed content or null if deleted.
|
|
2837
|
+
*/
|
|
2838
|
+
function applyFix(line, fixInfo, lineEnding = "\n") {
|
|
2839
|
+
const { editColumn, deleteCount, insertText } = normalizeFixInfo(fixInfo);
|
|
2840
|
+
const editIndex = editColumn - 1;
|
|
2841
|
+
return (deleteCount === -1) ?
|
|
2842
|
+
null :
|
|
2843
|
+
line.slice(0, editIndex) + insertText.replace(/\n/g, lineEnding) + line.slice(editIndex + deleteCount);
|
|
2844
|
+
}
|
|
2845
|
+
|
|
2846
|
+
/**
|
|
2847
|
+
* Applies as many of the specified fixes as possible to Markdown content.
|
|
2848
|
+
*
|
|
2849
|
+
* @param {string} input Lines of Markdown content.
|
|
2850
|
+
* @param {RuleOnErrorInfo[]} errors RuleOnErrorInfo instances.
|
|
2851
|
+
* @returns {string} Fixed content.
|
|
2852
|
+
*/
|
|
2853
|
+
function applyFixes(input, errors) {
|
|
2854
|
+
const lineEnding = helpers.getPreferredLineEnding(input, __webpack_require__(/*! node:os */ "?e6c4"));
|
|
2855
|
+
const lines = input.split(helpers.newLineRe);
|
|
2856
|
+
// Normalize fixInfo objects
|
|
2857
|
+
let fixInfos = errors
|
|
2858
|
+
.filter((error) => error.fixInfo)
|
|
2859
|
+
// @ts-ignore
|
|
2860
|
+
.map((error) => normalizeFixInfo(error.fixInfo, error.lineNumber));
|
|
2861
|
+
// Sort bottom-to-top, line-deletes last, right-to-left, long-to-short
|
|
2862
|
+
fixInfos.sort((a, b) => {
|
|
2863
|
+
const aDeletingLine = (a.deleteCount === -1);
|
|
2864
|
+
const bDeletingLine = (b.deleteCount === -1);
|
|
2865
|
+
return (
|
|
2866
|
+
(b.lineNumber - a.lineNumber) ||
|
|
2867
|
+
(aDeletingLine ? 1 : (bDeletingLine ? -1 : 0)) ||
|
|
2868
|
+
(b.editColumn - a.editColumn) ||
|
|
2869
|
+
(b.insertText.length - a.insertText.length)
|
|
2870
|
+
);
|
|
2871
|
+
});
|
|
2872
|
+
// Remove duplicate entries (needed for following collapse step)
|
|
2873
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
2874
|
+
/** @type RuleOnErrorFixInfo */
|
|
2875
|
+
let lastFixInfo = {};
|
|
2876
|
+
fixInfos = fixInfos.filter((fixInfo) => {
|
|
2877
|
+
const unique = (
|
|
2878
|
+
(fixInfo.lineNumber !== lastFixInfo.lineNumber) ||
|
|
2879
|
+
(fixInfo.editColumn !== lastFixInfo.editColumn) ||
|
|
2880
|
+
(fixInfo.deleteCount !== lastFixInfo.deleteCount) ||
|
|
2881
|
+
(fixInfo.insertText !== lastFixInfo.insertText)
|
|
2882
|
+
);
|
|
2883
|
+
lastFixInfo = fixInfo;
|
|
2884
|
+
return unique;
|
|
2885
|
+
});
|
|
2886
|
+
// Collapse insert/no-delete and no-insert/delete for same line/column
|
|
2887
|
+
lastFixInfo = {
|
|
2888
|
+
"lineNumber": -1
|
|
2889
|
+
};
|
|
2890
|
+
for (const fixInfo of fixInfos) {
|
|
2891
|
+
if (
|
|
2892
|
+
(fixInfo.lineNumber === lastFixInfo.lineNumber) &&
|
|
2893
|
+
(fixInfo.editColumn === lastFixInfo.editColumn) &&
|
|
2894
|
+
!fixInfo.insertText &&
|
|
2895
|
+
(fixInfo.deleteCount > 0) &&
|
|
2896
|
+
lastFixInfo.insertText &&
|
|
2897
|
+
!lastFixInfo.deleteCount) {
|
|
2898
|
+
fixInfo.insertText = lastFixInfo.insertText;
|
|
2899
|
+
lastFixInfo.lineNumber = 0;
|
|
2900
|
+
}
|
|
2901
|
+
lastFixInfo = fixInfo;
|
|
2896
2902
|
}
|
|
2897
|
-
|
|
2903
|
+
fixInfos = fixInfos.filter((fixInfo) => fixInfo.lineNumber);
|
|
2904
|
+
// Apply all (remaining/updated) fixes
|
|
2905
|
+
let lastLineIndex = -1;
|
|
2906
|
+
let lastEditIndex = -1;
|
|
2907
|
+
for (const fixInfo of fixInfos) {
|
|
2908
|
+
const { lineNumber, editColumn, deleteCount } = fixInfo;
|
|
2909
|
+
const lineIndex = lineNumber - 1;
|
|
2910
|
+
const editIndex = editColumn - 1;
|
|
2911
|
+
if (
|
|
2912
|
+
(lineIndex !== lastLineIndex) ||
|
|
2913
|
+
(deleteCount === -1) ||
|
|
2914
|
+
((editIndex + deleteCount) <=
|
|
2915
|
+
(lastEditIndex - ((deleteCount > 0) ? 0 : 1)))
|
|
2916
|
+
) {
|
|
2917
|
+
// @ts-ignore
|
|
2918
|
+
lines[lineIndex] = applyFix(lines[lineIndex], fixInfo, lineEnding);
|
|
2919
|
+
}
|
|
2920
|
+
lastLineIndex = lineIndex;
|
|
2921
|
+
lastEditIndex = editIndex;
|
|
2922
|
+
}
|
|
2923
|
+
// Return corrected input
|
|
2924
|
+
return lines.filter((line) => line !== null).join(lineEnding);
|
|
2898
2925
|
}
|
|
2899
2926
|
|
|
2900
2927
|
/**
|
|
@@ -2903,7 +2930,7 @@ function readConfigSync(file, parsers, fs) {
|
|
|
2903
2930
|
* @returns {string} SemVer string.
|
|
2904
2931
|
*/
|
|
2905
2932
|
function getVersion() {
|
|
2906
|
-
return
|
|
2933
|
+
return version;
|
|
2907
2934
|
}
|
|
2908
2935
|
|
|
2909
2936
|
// Export a/synchronous/Promise APIs
|
|
@@ -2916,17 +2943,12 @@ markdownlint.promises = {
|
|
|
2916
2943
|
"extendConfig": extendConfigPromise,
|
|
2917
2944
|
"readConfig": readConfigPromise
|
|
2918
2945
|
};
|
|
2946
|
+
markdownlint.applyFix = applyFix;
|
|
2947
|
+
markdownlint.applyFixes = applyFixes;
|
|
2919
2948
|
module.exports = markdownlint;
|
|
2920
2949
|
|
|
2921
2950
|
// Type declarations
|
|
2922
2951
|
|
|
2923
|
-
/**
|
|
2924
|
-
* Function to get an instance of the markdown-it parser.
|
|
2925
|
-
*
|
|
2926
|
-
* @callback GetMarkdownIt
|
|
2927
|
-
* @returns {import("markdown-it")}
|
|
2928
|
-
*/
|
|
2929
|
-
|
|
2930
2952
|
/**
|
|
2931
2953
|
* Function to implement rule logic.
|
|
2932
2954
|
*
|
|
@@ -2947,6 +2969,7 @@ module.exports = markdownlint;
|
|
|
2947
2969
|
* @property {readonly string[]} lines File/string lines.
|
|
2948
2970
|
* @property {readonly string[]} frontMatterLines Front matter lines.
|
|
2949
2971
|
* @property {RuleConfiguration} config Rule configuration.
|
|
2972
|
+
* @property {string} version Version of the markdownlint library.
|
|
2950
2973
|
*/
|
|
2951
2974
|
|
|
2952
2975
|
/* eslint-enable jsdoc/valid-types */
|
|
@@ -3040,6 +3063,16 @@ module.exports = markdownlint;
|
|
|
3040
3063
|
* @property {string} [insertText] Text to insert (after deleting).
|
|
3041
3064
|
*/
|
|
3042
3065
|
|
|
3066
|
+
/**
|
|
3067
|
+
* RuleOnErrorInfo with all optional properties present.
|
|
3068
|
+
*
|
|
3069
|
+
* @typedef {Object} RuleOnErrorFixInfoNormalized
|
|
3070
|
+
* @property {number} lineNumber Line number (1-based).
|
|
3071
|
+
* @property {number} editColumn Column of the fix (1-based).
|
|
3072
|
+
* @property {number} deleteCount Count of characters to delete.
|
|
3073
|
+
* @property {string} insertText Text to insert (after deleting).
|
|
3074
|
+
*/
|
|
3075
|
+
|
|
3043
3076
|
/**
|
|
3044
3077
|
* Rule definition.
|
|
3045
3078
|
*
|
|
@@ -3194,7 +3227,7 @@ module.exports = markdownlint;
|
|
|
3194
3227
|
|
|
3195
3228
|
|
|
3196
3229
|
const { addErrorDetailIf } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
3197
|
-
const { getHeadingLevel } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
3230
|
+
const { getHeadingLevel } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
3198
3231
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
3199
3232
|
|
|
3200
3233
|
// eslint-disable-next-line jsdoc/valid-types
|
|
@@ -3236,7 +3269,7 @@ module.exports = {
|
|
|
3236
3269
|
|
|
3237
3270
|
|
|
3238
3271
|
const { addErrorDetailIf } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
3239
|
-
const { getHeadingLevel, getHeadingStyle } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
3272
|
+
const { getHeadingLevel, getHeadingStyle } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
3240
3273
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
3241
3274
|
|
|
3242
3275
|
// eslint-disable-next-line jsdoc/valid-types
|
|
@@ -3297,7 +3330,7 @@ module.exports = {
|
|
|
3297
3330
|
|
|
3298
3331
|
|
|
3299
3332
|
const { addErrorDetailIf } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
3300
|
-
const { getDescendantsByType,
|
|
3333
|
+
const { getDescendantsByType, getParentOfType } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
3301
3334
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
3302
3335
|
|
|
3303
3336
|
const markerToStyle = {
|
|
@@ -3337,10 +3370,10 @@ module.exports = {
|
|
|
3337
3370
|
for (const listUnordered of filterByTypesCached([ "listUnordered" ])) {
|
|
3338
3371
|
let nesting = 0;
|
|
3339
3372
|
if (style === "sublist") {
|
|
3340
|
-
/** @type {import("../helpers/micromark.cjs").Token | null} */
|
|
3373
|
+
/** @type {import("../helpers/micromark-helpers.cjs").Token | null} */
|
|
3341
3374
|
let parent = listUnordered;
|
|
3342
3375
|
// @ts-ignore
|
|
3343
|
-
while ((parent =
|
|
3376
|
+
while ((parent = getParentOfType(parent, [ "listOrdered", "listUnordered" ]))) {
|
|
3344
3377
|
nesting++;
|
|
3345
3378
|
}
|
|
3346
3379
|
}
|
|
@@ -3477,7 +3510,7 @@ module.exports = {
|
|
|
3477
3510
|
|
|
3478
3511
|
|
|
3479
3512
|
const { addErrorDetailIf } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
3480
|
-
const {
|
|
3513
|
+
const { getParentOfType } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
3481
3514
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
3482
3515
|
|
|
3483
3516
|
// eslint-disable-next-line jsdoc/valid-types
|
|
@@ -3509,11 +3542,11 @@ module.exports = {
|
|
|
3509
3542
|
lastBlockQuotePrefix = token;
|
|
3510
3543
|
} else if (type === "listUnordered") {
|
|
3511
3544
|
let nesting = 0;
|
|
3512
|
-
/** @type {import("../helpers/micromark.cjs").Token | null} */
|
|
3545
|
+
/** @type {import("../helpers/micromark-helpers.cjs").Token | null} */
|
|
3513
3546
|
let current = token;
|
|
3514
3547
|
while (
|
|
3515
3548
|
// @ts-ignore
|
|
3516
|
-
(current =
|
|
3549
|
+
(current = getParentOfType(current, unorderedParentTypes))
|
|
3517
3550
|
) {
|
|
3518
3551
|
if (current.type === "listUnordered") {
|
|
3519
3552
|
nesting++;
|
|
@@ -3576,7 +3609,7 @@ module.exports = {
|
|
|
3576
3609
|
|
|
3577
3610
|
|
|
3578
3611
|
const { addError } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
3579
|
-
const { addRangeToSet } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
3612
|
+
const { addRangeToSet } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
3580
3613
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
3581
3614
|
|
|
3582
3615
|
// eslint-disable-next-line jsdoc/valid-types
|
|
@@ -3681,8 +3714,8 @@ module.exports = {
|
|
|
3681
3714
|
|
|
3682
3715
|
|
|
3683
3716
|
|
|
3684
|
-
const { addError,
|
|
3685
|
-
const { getDescendantsByType
|
|
3717
|
+
const { addError, hasOverlap } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
3718
|
+
const { getDescendantsByType } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
3686
3719
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
3687
3720
|
|
|
3688
3721
|
const tabRe = /\t+/g;
|
|
@@ -3705,9 +3738,8 @@ module.exports = {
|
|
|
3705
3738
|
const spaceMultiplier = (spacesPerTab === undefined) ?
|
|
3706
3739
|
1 :
|
|
3707
3740
|
Math.max(0, Number(spacesPerTab));
|
|
3708
|
-
const exclusions = [];
|
|
3709
3741
|
// eslint-disable-next-line jsdoc/valid-types
|
|
3710
|
-
/** @type import("../helpers/micromark.cjs").TokenType[] */
|
|
3742
|
+
/** @type import("../helpers/micromark-helpers.cjs").TokenType[] */
|
|
3711
3743
|
const exclusionTypes = [];
|
|
3712
3744
|
if (includeCode) {
|
|
3713
3745
|
if (ignoreCodeLanguages.size > 0) {
|
|
@@ -3723,24 +3755,29 @@ module.exports = {
|
|
|
3723
3755
|
}
|
|
3724
3756
|
return true;
|
|
3725
3757
|
});
|
|
3726
|
-
|
|
3727
|
-
const
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3758
|
+
const codeRanges = codeTokens.map((token) => {
|
|
3759
|
+
const { type, startLine, startColumn, endLine, endColumn } = token;
|
|
3760
|
+
const codeFenced = (type === "codeFenced");
|
|
3761
|
+
return {
|
|
3762
|
+
"startLine": startLine + (codeFenced ? 1 : 0),
|
|
3763
|
+
"startColumn": codeFenced ? 0 : startColumn,
|
|
3764
|
+
"endLine": endLine - (codeFenced ? 1 : 0),
|
|
3765
|
+
"endColumn": codeFenced ? Number.MAX_SAFE_INTEGER : endColumn
|
|
3766
|
+
};
|
|
3767
|
+
});
|
|
3734
3768
|
for (let lineIndex = 0; lineIndex < params.lines.length; lineIndex++) {
|
|
3735
3769
|
const line = params.lines[lineIndex];
|
|
3736
3770
|
let match = null;
|
|
3737
3771
|
while ((match = tabRe.exec(line)) !== null) {
|
|
3772
|
+
const lineNumber = lineIndex + 1;
|
|
3738
3773
|
const column = match.index + 1;
|
|
3739
3774
|
const length = match[0].length;
|
|
3740
|
-
|
|
3775
|
+
/** @type {import("../helpers").FileRange} */
|
|
3776
|
+
const range = { "startLine": lineNumber, "startColumn": column, "endLine": lineNumber, "endColumn": column + length - 1 };
|
|
3777
|
+
if (!codeRanges.some((codeRange) => hasOverlap(codeRange, range))) {
|
|
3741
3778
|
addError(
|
|
3742
3779
|
onError,
|
|
3743
|
-
|
|
3780
|
+
lineNumber,
|
|
3744
3781
|
"Column: " + column,
|
|
3745
3782
|
undefined,
|
|
3746
3783
|
[ column, length ],
|
|
@@ -3770,8 +3807,8 @@ module.exports = {
|
|
|
3770
3807
|
|
|
3771
3808
|
|
|
3772
3809
|
|
|
3773
|
-
const { addError,
|
|
3774
|
-
const { addRangeToSet
|
|
3810
|
+
const { addError, hasOverlap } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
3811
|
+
const { addRangeToSet } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
3775
3812
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
3776
3813
|
|
|
3777
3814
|
const reversedLinkRe =
|
|
@@ -3789,34 +3826,35 @@ module.exports = {
|
|
|
3789
3826
|
for (const codeBlock of filterByTypesCached([ "codeFenced", "codeIndented" ])) {
|
|
3790
3827
|
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine, codeBlock.endLine);
|
|
3791
3828
|
}
|
|
3792
|
-
const
|
|
3793
|
-
for (const codeText of filterByTypesCached([ "codeText" ])) {
|
|
3794
|
-
exclusions.push(...getExclusionsForToken(params.lines, codeText));
|
|
3795
|
-
}
|
|
3829
|
+
const codeTexts = filterByTypesCached([ "codeText" ]);
|
|
3796
3830
|
for (const [ lineIndex, line ] of params.lines.entries()) {
|
|
3797
|
-
|
|
3831
|
+
const lineNumber = lineIndex + 1;
|
|
3832
|
+
if (!codeBlockLineNumbers.has(lineNumber)) {
|
|
3798
3833
|
let match = null;
|
|
3799
3834
|
while ((match = reversedLinkRe.exec(line)) !== null) {
|
|
3800
3835
|
const [ reversedLink, preChar, linkText, linkDestination ] = match;
|
|
3801
|
-
const index = match.index + preChar.length;
|
|
3802
|
-
const length = match[0].length - preChar.length;
|
|
3803
3836
|
if (
|
|
3804
3837
|
!linkText.endsWith("\\") &&
|
|
3805
|
-
!linkDestination.endsWith("\\")
|
|
3806
|
-
!withinAnyRange(exclusions, lineIndex + 1, index, length)
|
|
3838
|
+
!linkDestination.endsWith("\\")
|
|
3807
3839
|
) {
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3840
|
+
const column = match.index + preChar.length + 1;
|
|
3841
|
+
const length = match[0].length - preChar.length;
|
|
3842
|
+
/** @type {import("../helpers").FileRange} */
|
|
3843
|
+
const range = { "startLine": lineNumber, "startColumn": column, "endLine": lineNumber, "endColumn": column + length - 1 };
|
|
3844
|
+
if (!codeTexts.some((codeText) => hasOverlap(codeText, range))) {
|
|
3845
|
+
addError(
|
|
3846
|
+
onError,
|
|
3847
|
+
lineNumber,
|
|
3848
|
+
reversedLink.slice(preChar.length),
|
|
3849
|
+
undefined,
|
|
3850
|
+
[ column, length ],
|
|
3851
|
+
{
|
|
3852
|
+
"editColumn": column,
|
|
3853
|
+
"deleteCount": length,
|
|
3854
|
+
"insertText": `[${linkText}](${linkDestination})`
|
|
3855
|
+
}
|
|
3856
|
+
);
|
|
3857
|
+
}
|
|
3820
3858
|
}
|
|
3821
3859
|
}
|
|
3822
3860
|
}
|
|
@@ -3839,7 +3877,7 @@ module.exports = {
|
|
|
3839
3877
|
|
|
3840
3878
|
|
|
3841
3879
|
const { addErrorDetailIf } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
3842
|
-
const { addRangeToSet } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
3880
|
+
const { addRangeToSet } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
3843
3881
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
3844
3882
|
|
|
3845
3883
|
// eslint-disable-next-line jsdoc/valid-types
|
|
@@ -3894,7 +3932,7 @@ module.exports = {
|
|
|
3894
3932
|
|
|
3895
3933
|
const { addErrorDetailIf } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
3896
3934
|
const { getReferenceLinkImageData } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
3897
|
-
const { addRangeToSet, getDescendantsByType } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
3935
|
+
const { addRangeToSet, getDescendantsByType } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
3898
3936
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
3899
3937
|
|
|
3900
3938
|
const longLineRePrefix = "^.{";
|
|
@@ -4009,7 +4047,6 @@ module.exports = {
|
|
|
4009
4047
|
|
|
4010
4048
|
|
|
4011
4049
|
const { addErrorContext } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
4012
|
-
const { filterByTypes } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
4013
4050
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
4014
4051
|
|
|
4015
4052
|
const dollarCommandRe = /^(\s*)(\$\s+)/;
|
|
@@ -4023,18 +4060,15 @@ module.exports = {
|
|
|
4023
4060
|
"parser": "micromark",
|
|
4024
4061
|
"function": function MD014(params, onError) {
|
|
4025
4062
|
for (const codeBlock of filterByTypesCached([ "codeFenced", "codeIndented" ])) {
|
|
4026
|
-
const codeFlowValues =
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
);
|
|
4030
|
-
const dollarMatches = codeFlowValues.
|
|
4031
|
-
map((codeFlowValue) => ({
|
|
4063
|
+
const codeFlowValues = codeBlock.children.filter((child) => child.type === "codeFlowValue");
|
|
4064
|
+
const dollarMatches = codeFlowValues
|
|
4065
|
+
.map((codeFlowValue) => ({
|
|
4032
4066
|
"result": codeFlowValue.text.match(dollarCommandRe),
|
|
4033
4067
|
"startColumn": codeFlowValue.startColumn,
|
|
4034
4068
|
"startLine": codeFlowValue.startLine,
|
|
4035
4069
|
"text": codeFlowValue.text
|
|
4036
|
-
}))
|
|
4037
|
-
filter((dollarMatch) => dollarMatch.result);
|
|
4070
|
+
}))
|
|
4071
|
+
.filter((dollarMatch) => dollarMatch.result);
|
|
4038
4072
|
if (dollarMatches.length === codeFlowValues.length) {
|
|
4039
4073
|
for (const dollarMatch of dollarMatches) {
|
|
4040
4074
|
// @ts-ignore
|
|
@@ -4074,7 +4108,7 @@ module.exports = {
|
|
|
4074
4108
|
|
|
4075
4109
|
|
|
4076
4110
|
const { addErrorContext } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
4077
|
-
const { addRangeToSet } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
4111
|
+
const { addRangeToSet } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
4078
4112
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
4079
4113
|
|
|
4080
4114
|
// eslint-disable-next-line jsdoc/valid-types
|
|
@@ -4131,7 +4165,7 @@ module.exports = {
|
|
|
4131
4165
|
|
|
4132
4166
|
|
|
4133
4167
|
const { addErrorContext } = __webpack_require__(/*! ../helpers/helpers */ "../helpers/helpers.js");
|
|
4134
|
-
const { getHeadingStyle } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
4168
|
+
const { getHeadingStyle } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
4135
4169
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
4136
4170
|
|
|
4137
4171
|
/**
|
|
@@ -4222,7 +4256,7 @@ module.exports = [
|
|
|
4222
4256
|
|
|
4223
4257
|
|
|
4224
4258
|
const { addErrorContext } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
4225
|
-
const { addRangeToSet } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
4259
|
+
const { addRangeToSet } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
4226
4260
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
4227
4261
|
|
|
4228
4262
|
// eslint-disable-next-line jsdoc/valid-types
|
|
@@ -4241,7 +4275,7 @@ module.exports = {
|
|
|
4241
4275
|
for (const [ lineIndex, line ] of lines.entries()) {
|
|
4242
4276
|
if (!ignoreBlockLineNumbers.has(lineIndex + 1)) {
|
|
4243
4277
|
const match =
|
|
4244
|
-
/^(#+)([ \t]*)([^#]*?[
|
|
4278
|
+
/^(#+)([ \t]*)([^# \t\\]|[^# \t][^#]*?[^# \t\\])([ \t]*)((?:\\#)?)(#+)(\s*)$/.exec(line);
|
|
4245
4279
|
if (match) {
|
|
4246
4280
|
const [
|
|
4247
4281
|
,
|
|
@@ -4303,8 +4337,8 @@ module.exports = {
|
|
|
4303
4337
|
|
|
4304
4338
|
|
|
4305
4339
|
|
|
4306
|
-
const { addErrorDetailIf,
|
|
4307
|
-
const { getHeadingLevel } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
4340
|
+
const { addErrorDetailIf, isBlankLine } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
4341
|
+
const { getBlockQuotePrefixText, getHeadingLevel } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
4308
4342
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
4309
4343
|
|
|
4310
4344
|
const defaultLines = 1;
|
|
@@ -4322,15 +4356,6 @@ const getLinesFunction = (linesParam) => {
|
|
|
4322
4356
|
return () => lines;
|
|
4323
4357
|
};
|
|
4324
4358
|
|
|
4325
|
-
const getBlockQuote = (str, count) => (
|
|
4326
|
-
(str || "")
|
|
4327
|
-
.match(blockquotePrefixRe)[0]
|
|
4328
|
-
.trimEnd()
|
|
4329
|
-
// eslint-disable-next-line unicorn/prefer-spread
|
|
4330
|
-
.concat("\n")
|
|
4331
|
-
.repeat(count)
|
|
4332
|
-
);
|
|
4333
|
-
|
|
4334
4359
|
// eslint-disable-next-line jsdoc/valid-types
|
|
4335
4360
|
/** @type import("./markdownlint").Rule */
|
|
4336
4361
|
module.exports = {
|
|
@@ -4342,6 +4367,7 @@ module.exports = {
|
|
|
4342
4367
|
const getLinesAbove = getLinesFunction(params.config.lines_above);
|
|
4343
4368
|
const getLinesBelow = getLinesFunction(params.config.lines_below);
|
|
4344
4369
|
const { lines } = params;
|
|
4370
|
+
const blockQuotePrefixes = filterByTypesCached([ "blockQuotePrefix", "linePrefix" ]);
|
|
4345
4371
|
for (const heading of filterByTypesCached([ "atxHeading", "setextHeading" ])) {
|
|
4346
4372
|
const { startLine, endLine } = heading;
|
|
4347
4373
|
const line = lines[startLine - 1].trim();
|
|
@@ -4366,8 +4392,9 @@ module.exports = {
|
|
|
4366
4392
|
line,
|
|
4367
4393
|
undefined,
|
|
4368
4394
|
{
|
|
4369
|
-
"insertText":
|
|
4370
|
-
|
|
4395
|
+
"insertText": getBlockQuotePrefixText(
|
|
4396
|
+
blockQuotePrefixes,
|
|
4397
|
+
startLine - 1,
|
|
4371
4398
|
linesAbove - actualAbove
|
|
4372
4399
|
)
|
|
4373
4400
|
}
|
|
@@ -4395,8 +4422,9 @@ module.exports = {
|
|
|
4395
4422
|
undefined,
|
|
4396
4423
|
{
|
|
4397
4424
|
"lineNumber": endLine + 1,
|
|
4398
|
-
"insertText":
|
|
4399
|
-
|
|
4425
|
+
"insertText": getBlockQuotePrefixText(
|
|
4426
|
+
blockQuotePrefixes,
|
|
4427
|
+
endLine + 1,
|
|
4400
4428
|
linesBelow - actualBelow
|
|
4401
4429
|
)
|
|
4402
4430
|
}
|
|
@@ -4472,7 +4500,7 @@ module.exports = {
|
|
|
4472
4500
|
|
|
4473
4501
|
|
|
4474
4502
|
const { addErrorContext } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
4475
|
-
const { getHeadingLevel, getHeadingText } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
4503
|
+
const { getHeadingLevel, getHeadingText } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
4476
4504
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
4477
4505
|
|
|
4478
4506
|
// eslint-disable-next-line jsdoc/valid-types
|
|
@@ -4531,7 +4559,7 @@ module.exports = {
|
|
|
4531
4559
|
|
|
4532
4560
|
|
|
4533
4561
|
const { addErrorContext, frontMatterHasTitle } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
4534
|
-
const { getHeadingLevel, getHeadingText } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
4562
|
+
const { getHeadingLevel, getHeadingText } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
4535
4563
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
4536
4564
|
|
|
4537
4565
|
// eslint-disable-next-line jsdoc/valid-types
|
|
@@ -4647,9 +4675,9 @@ const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache
|
|
|
4647
4675
|
// eslint-disable-next-line jsdoc/valid-types
|
|
4648
4676
|
/** @type import("./markdownlint").Rule */
|
|
4649
4677
|
module.exports = {
|
|
4650
|
-
"names": ["MD027", "no-multiple-space-blockquote"],
|
|
4678
|
+
"names": [ "MD027", "no-multiple-space-blockquote" ],
|
|
4651
4679
|
"description": "Multiple spaces after blockquote symbol",
|
|
4652
|
-
"tags": ["blockquote", "whitespace", "indentation"],
|
|
4680
|
+
"tags": [ "blockquote", "whitespace", "indentation" ],
|
|
4653
4681
|
"parser": "micromark",
|
|
4654
4682
|
"function": function MD027(params, onError) {
|
|
4655
4683
|
for (const token of filterByTypesCached([ "linePrefix" ])) {
|
|
@@ -4743,7 +4771,7 @@ module.exports = {
|
|
|
4743
4771
|
|
|
4744
4772
|
|
|
4745
4773
|
const { addErrorDetailIf } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
4746
|
-
const { getDescendantsByType
|
|
4774
|
+
const { getDescendantsByType } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
4747
4775
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
4748
4776
|
|
|
4749
4777
|
const listStyleExamples = {
|
|
@@ -4755,11 +4783,11 @@ const listStyleExamples = {
|
|
|
4755
4783
|
/**
|
|
4756
4784
|
* Gets the value of an ordered list item prefix token.
|
|
4757
4785
|
*
|
|
4758
|
-
* @param {import("../helpers/micromark.cjs").Token} listItemPrefix List item prefix token.
|
|
4786
|
+
* @param {import("../helpers/micromark-helpers.cjs").Token} listItemPrefix List item prefix token.
|
|
4759
4787
|
* @returns {number} List item value.
|
|
4760
4788
|
*/
|
|
4761
4789
|
function getOrderedListItemValue(listItemPrefix) {
|
|
4762
|
-
return Number(
|
|
4790
|
+
return Number(getDescendantsByType(listItemPrefix, [ "listItemValue" ])[0].text);
|
|
4763
4791
|
}
|
|
4764
4792
|
|
|
4765
4793
|
// eslint-disable-next-line jsdoc/valid-types
|
|
@@ -4901,7 +4929,7 @@ module.exports = {
|
|
|
4901
4929
|
|
|
4902
4930
|
|
|
4903
4931
|
const { addErrorContext, isBlankLine } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
4904
|
-
const {
|
|
4932
|
+
const { getParentOfType } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
4905
4933
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
4906
4934
|
|
|
4907
4935
|
const codeFencePrefixRe = /^(.*?)[`~]/;
|
|
@@ -4921,10 +4949,12 @@ const codeFencePrefixRe = /^(.*?)[`~]/;
|
|
|
4921
4949
|
function addError(onError, lines, lineNumber, top) {
|
|
4922
4950
|
const line = lines[lineNumber - 1];
|
|
4923
4951
|
const [ , prefix ] = line.match(codeFencePrefixRe) || [];
|
|
4924
|
-
const fixInfo = (prefix === undefined) ?
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4952
|
+
const fixInfo = (prefix === undefined) ?
|
|
4953
|
+
null :
|
|
4954
|
+
{
|
|
4955
|
+
"lineNumber": lineNumber + (top ? 0 : 1),
|
|
4956
|
+
"insertText": `${prefix.replace(/[^>]/g, " ").trim()}\n`
|
|
4957
|
+
};
|
|
4928
4958
|
addErrorContext(
|
|
4929
4959
|
onError,
|
|
4930
4960
|
lineNumber,
|
|
@@ -4948,7 +4978,7 @@ module.exports = {
|
|
|
4948
4978
|
const includeListItems = (listItems === undefined) ? true : !!listItems;
|
|
4949
4979
|
const { lines } = params;
|
|
4950
4980
|
for (const codeBlock of filterByTypesCached([ "codeFenced" ])) {
|
|
4951
|
-
if (includeListItems || !(
|
|
4981
|
+
if (includeListItems || !(getParentOfType(codeBlock, [ "listOrdered", "listUnordered" ]))) {
|
|
4952
4982
|
if (!isBlankLine(lines[codeBlock.startLine - 2])) {
|
|
4953
4983
|
addError(onError, lines, codeBlock.startLine, true);
|
|
4954
4984
|
}
|
|
@@ -4974,8 +5004,9 @@ module.exports = {
|
|
|
4974
5004
|
|
|
4975
5005
|
|
|
4976
5006
|
|
|
4977
|
-
const {
|
|
4978
|
-
const { filterByPredicate, nonContentTokens } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
5007
|
+
const { addErrorContext, isBlankLine } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
5008
|
+
const { filterByPredicate, getBlockQuotePrefixText, nonContentTokens } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
5009
|
+
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
4979
5010
|
|
|
4980
5011
|
const isList = (token) => (
|
|
4981
5012
|
(token.type === "listOrdered") || (token.type === "listUnordered")
|
|
@@ -4990,6 +5021,7 @@ module.exports = {
|
|
|
4990
5021
|
"parser": "micromark",
|
|
4991
5022
|
"function": function MD032(params, onError) {
|
|
4992
5023
|
const { lines, parsers } = params;
|
|
5024
|
+
const blockQuotePrefixes = filterByTypesCached([ "blockQuotePrefix", "linePrefix" ]);
|
|
4993
5025
|
|
|
4994
5026
|
// For every top-level list...
|
|
4995
5027
|
const topLevelLists = filterByPredicate(
|
|
@@ -5002,13 +5034,18 @@ module.exports = {
|
|
|
5002
5034
|
for (const list of topLevelLists) {
|
|
5003
5035
|
|
|
5004
5036
|
// Look for a blank line above the list
|
|
5005
|
-
const
|
|
5006
|
-
if (!isBlankLine(lines[
|
|
5007
|
-
|
|
5037
|
+
const firstLineNumber = list.startLine;
|
|
5038
|
+
if (!isBlankLine(lines[firstLineNumber - 2])) {
|
|
5039
|
+
addErrorContext(
|
|
5008
5040
|
onError,
|
|
5009
|
-
|
|
5010
|
-
lines,
|
|
5011
|
-
|
|
5041
|
+
firstLineNumber,
|
|
5042
|
+
lines[firstLineNumber - 1].trim(),
|
|
5043
|
+
undefined,
|
|
5044
|
+
undefined,
|
|
5045
|
+
undefined,
|
|
5046
|
+
{
|
|
5047
|
+
"insertText": getBlockQuotePrefixText(blockQuotePrefixes, firstLineNumber)
|
|
5048
|
+
}
|
|
5012
5049
|
);
|
|
5013
5050
|
}
|
|
5014
5051
|
|
|
@@ -5023,14 +5060,19 @@ module.exports = {
|
|
|
5023
5060
|
}
|
|
5024
5061
|
|
|
5025
5062
|
// Look for a blank line below the list
|
|
5026
|
-
const
|
|
5027
|
-
if (!isBlankLine(lines[
|
|
5028
|
-
|
|
5063
|
+
const lastLineNumber = endLine;
|
|
5064
|
+
if (!isBlankLine(lines[lastLineNumber])) {
|
|
5065
|
+
addErrorContext(
|
|
5029
5066
|
onError,
|
|
5030
|
-
|
|
5031
|
-
lines,
|
|
5032
|
-
|
|
5033
|
-
|
|
5067
|
+
lastLineNumber,
|
|
5068
|
+
lines[lastLineNumber - 1].trim(),
|
|
5069
|
+
undefined,
|
|
5070
|
+
undefined,
|
|
5071
|
+
undefined,
|
|
5072
|
+
{
|
|
5073
|
+
"lineNumber": lastLineNumber + 1,
|
|
5074
|
+
"insertText": getBlockQuotePrefixText(blockQuotePrefixes, lastLineNumber)
|
|
5075
|
+
}
|
|
5034
5076
|
);
|
|
5035
5077
|
}
|
|
5036
5078
|
}
|
|
@@ -5052,7 +5094,7 @@ module.exports = {
|
|
|
5052
5094
|
|
|
5053
5095
|
|
|
5054
5096
|
const { addError, nextLinesRe } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
5055
|
-
const { getHtmlTagInfo } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
5097
|
+
const { getHtmlTagInfo } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
5056
5098
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
5057
5099
|
|
|
5058
5100
|
// eslint-disable-next-line jsdoc/valid-types
|
|
@@ -5104,8 +5146,7 @@ module.exports = {
|
|
|
5104
5146
|
|
|
5105
5147
|
|
|
5106
5148
|
const { addErrorContext } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
5107
|
-
const { filterByPredicate, getHtmlTagInfo, inHtmlFlow
|
|
5108
|
-
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
5149
|
+
const { filterByPredicate, getHtmlTagInfo, inHtmlFlow } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
5109
5150
|
|
|
5110
5151
|
// eslint-disable-next-line jsdoc/valid-types
|
|
5111
5152
|
/** @type import("./markdownlint").Rule */
|
|
@@ -5122,8 +5163,6 @@ module.exports = {
|
|
|
5122
5163
|
if ((token.type === "literalAutolink") && !inHtmlFlow(token)) {
|
|
5123
5164
|
// Detect and ignore https://github.com/micromark/micromark/issues/164
|
|
5124
5165
|
const siblings = token.parent?.children;
|
|
5125
|
-
// Commented-out due to not being able to exercise in test/code coverage
|
|
5126
|
-
// || micromarkTokens;
|
|
5127
5166
|
const index = siblings?.indexOf(token);
|
|
5128
5167
|
// @ts-ignore
|
|
5129
5168
|
const prev = siblings?.at(index - 1);
|
|
@@ -5141,6 +5180,7 @@ module.exports = {
|
|
|
5141
5180
|
return false;
|
|
5142
5181
|
},
|
|
5143
5182
|
(token) => {
|
|
5183
|
+
// Ignore content of inline HTML tags
|
|
5144
5184
|
const { children } = token;
|
|
5145
5185
|
const result = [];
|
|
5146
5186
|
for (let i = 0; i < children.length; i++) {
|
|
@@ -5171,31 +5211,25 @@ module.exports = {
|
|
|
5171
5211
|
}
|
|
5172
5212
|
)
|
|
5173
5213
|
);
|
|
5174
|
-
const
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
undefined,
|
|
5194
|
-
undefined,
|
|
5195
|
-
range,
|
|
5196
|
-
fixInfo
|
|
5197
|
-
);
|
|
5198
|
-
}
|
|
5214
|
+
for (const token of literalAutolinks(params.parsers.micromark.tokens)) {
|
|
5215
|
+
const range = [
|
|
5216
|
+
token.startColumn,
|
|
5217
|
+
token.endColumn - token.startColumn
|
|
5218
|
+
];
|
|
5219
|
+
const fixInfo = {
|
|
5220
|
+
"editColumn": range[0],
|
|
5221
|
+
"deleteCount": range[1],
|
|
5222
|
+
"insertText": `<${token.text}>`
|
|
5223
|
+
};
|
|
5224
|
+
addErrorContext(
|
|
5225
|
+
onError,
|
|
5226
|
+
token.startLine,
|
|
5227
|
+
token.text,
|
|
5228
|
+
undefined,
|
|
5229
|
+
undefined,
|
|
5230
|
+
range,
|
|
5231
|
+
fixInfo
|
|
5232
|
+
);
|
|
5199
5233
|
}
|
|
5200
5234
|
}
|
|
5201
5235
|
};
|
|
@@ -5252,15 +5286,15 @@ module.exports = {
|
|
|
5252
5286
|
|
|
5253
5287
|
|
|
5254
5288
|
const { addErrorContext, allPunctuation } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
5255
|
-
const {
|
|
5289
|
+
const { getDescendantsByType } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
5256
5290
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
5257
5291
|
|
|
5258
|
-
/** @typedef {import("../helpers/micromark.cjs").TokenType} TokenType */
|
|
5259
|
-
/** @type {
|
|
5260
|
-
const
|
|
5261
|
-
[ "emphasis",
|
|
5262
|
-
[ "strong",
|
|
5263
|
-
]
|
|
5292
|
+
/** @typedef {import("../helpers/micromark-helpers.cjs").TokenType} TokenType */
|
|
5293
|
+
/** @type {TokenType[][]} */
|
|
5294
|
+
const emphasisTypes = [
|
|
5295
|
+
[ "emphasis", "emphasisText" ],
|
|
5296
|
+
[ "strong", "strongText" ]
|
|
5297
|
+
];
|
|
5264
5298
|
|
|
5265
5299
|
// eslint-disable-next-line jsdoc/valid-types
|
|
5266
5300
|
/** @type import("./markdownlint").Rule */
|
|
@@ -5274,25 +5308,19 @@ module.exports = {
|
|
|
5274
5308
|
punctuation = String((punctuation === undefined) ? allPunctuation : punctuation);
|
|
5275
5309
|
const punctuationRe = new RegExp("[" + punctuation + "]$");
|
|
5276
5310
|
const paragraphTokens =
|
|
5277
|
-
filterByTypesCached([ "paragraph" ])
|
|
5278
|
-
filter((token) =>
|
|
5311
|
+
filterByTypesCached([ "paragraph" ])
|
|
5312
|
+
.filter((token) =>
|
|
5279
5313
|
(token.parent?.type === "content") && !token.parent?.parent && (token.children.length === 1)
|
|
5280
5314
|
);
|
|
5281
|
-
for (const
|
|
5282
|
-
const
|
|
5283
|
-
for (const
|
|
5284
|
-
if (
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
(textToken.children[0].type === "data") &&
|
|
5291
|
-
!punctuationRe.test(textToken.text)
|
|
5292
|
-
) {
|
|
5293
|
-
addErrorContext(onError, textToken.startLine, textToken.text);
|
|
5294
|
-
}
|
|
5295
|
-
}
|
|
5315
|
+
for (const emphasisType of emphasisTypes) {
|
|
5316
|
+
const textTokens = getDescendantsByType(paragraphTokens, emphasisType);
|
|
5317
|
+
for (const textToken of textTokens) {
|
|
5318
|
+
if (
|
|
5319
|
+
(textToken.children.length === 1) &&
|
|
5320
|
+
(textToken.children[0].type === "data") &&
|
|
5321
|
+
!punctuationRe.test(textToken.text)
|
|
5322
|
+
) {
|
|
5323
|
+
addErrorContext(onError, textToken.startLine, textToken.text);
|
|
5296
5324
|
}
|
|
5297
5325
|
}
|
|
5298
5326
|
}
|
|
@@ -5314,7 +5342,7 @@ module.exports = {
|
|
|
5314
5342
|
|
|
5315
5343
|
|
|
5316
5344
|
const { addError } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
5317
|
-
const { filterByPredicate, inHtmlFlow } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
5345
|
+
const { filterByPredicate, inHtmlFlow } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
5318
5346
|
|
|
5319
5347
|
// eslint-disable-next-line jsdoc/valid-types
|
|
5320
5348
|
/** @type import("./markdownlint").Rule */
|
|
@@ -5419,7 +5447,7 @@ module.exports = {
|
|
|
5419
5447
|
|
|
5420
5448
|
|
|
5421
5449
|
const { addErrorContext } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
5422
|
-
const {
|
|
5450
|
+
const { getDescendantsByType } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
5423
5451
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
5424
5452
|
|
|
5425
5453
|
const leftSpaceRe = /^\s(?:[^`]|$)/;
|
|
@@ -5445,24 +5473,19 @@ module.exports = {
|
|
|
5445
5473
|
"function": function MD038(params, onError) {
|
|
5446
5474
|
const codeTexts = filterByTypesCached([ "codeText" ]);
|
|
5447
5475
|
for (const codeText of codeTexts) {
|
|
5448
|
-
const
|
|
5449
|
-
const
|
|
5450
|
-
const
|
|
5451
|
-
const
|
|
5452
|
-
const
|
|
5453
|
-
const
|
|
5454
|
-
tokenIfType(children[first + 1], "codeTextData") ||
|
|
5455
|
-
tokenIfType(children[first + 2], "codeTextData");
|
|
5456
|
-
const endData =
|
|
5457
|
-
tokenIfType(children[last - 1], "codeTextData") ||
|
|
5458
|
-
tokenIfType(children[last - 2], "codeTextData");
|
|
5476
|
+
const sequences = getDescendantsByType(codeText, [ "codeTextSequence" ]);
|
|
5477
|
+
const startSequence = sequences[0];
|
|
5478
|
+
const endSequence = sequences[sequences.length - 1];
|
|
5479
|
+
const datas = getDescendantsByType(codeText, [ "codeTextData" ]);
|
|
5480
|
+
const startData = datas[0];
|
|
5481
|
+
const endData = datas[datas.length - 1];
|
|
5459
5482
|
if (startSequence && endSequence && startData && endData) {
|
|
5460
5483
|
const spaceLeft = leftSpaceRe.test(startData.text);
|
|
5461
5484
|
const spaceRight = rightSpaceRe.test(endData.text);
|
|
5462
5485
|
if (spaceLeft || spaceRight) {
|
|
5463
5486
|
let lineNumber = startSequence.startLine;
|
|
5464
|
-
let range =
|
|
5465
|
-
let fixInfo =
|
|
5487
|
+
let range = undefined;
|
|
5488
|
+
let fixInfo = undefined;
|
|
5466
5489
|
if (startSequence.startLine === endSequence.endLine) {
|
|
5467
5490
|
range = [
|
|
5468
5491
|
startSequence.startColumn,
|
|
@@ -5530,15 +5553,14 @@ module.exports = {
|
|
|
5530
5553
|
|
|
5531
5554
|
|
|
5532
5555
|
const { addErrorContext } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
5533
|
-
const { filterByTypes } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
5534
5556
|
const { getReferenceLinkImageData, filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
5535
5557
|
|
|
5536
5558
|
/**
|
|
5537
5559
|
* Adds an error for a label space issue.
|
|
5538
5560
|
*
|
|
5539
5561
|
* @param {import("./markdownlint").RuleOnError} onError Error-reporting callback.
|
|
5540
|
-
* @param {import("../helpers/micromark.cjs").Token} label Label token.
|
|
5541
|
-
* @param {import("../helpers/micromark.cjs").Token} labelText LabelText token.
|
|
5562
|
+
* @param {import("../helpers/micromark-helpers.cjs").Token} label Label token.
|
|
5563
|
+
* @param {import("../helpers/micromark-helpers.cjs").Token} labelText LabelText token.
|
|
5542
5564
|
* @param {boolean} isStart True iff error is at the start of the link.
|
|
5543
5565
|
*/
|
|
5544
5566
|
function addLabelSpaceError(onError, label, labelText, isStart) {
|
|
@@ -5556,18 +5578,20 @@ function addLabelSpaceError(onError, label, labelText, isStart) {
|
|
|
5556
5578
|
isStart,
|
|
5557
5579
|
!isStart,
|
|
5558
5580
|
range,
|
|
5559
|
-
range ?
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
|
|
5581
|
+
range ?
|
|
5582
|
+
{
|
|
5583
|
+
"editColumn": range[0],
|
|
5584
|
+
"deleteCount": range[1]
|
|
5585
|
+
} :
|
|
5586
|
+
undefined
|
|
5563
5587
|
);
|
|
5564
5588
|
}
|
|
5565
5589
|
|
|
5566
5590
|
/**
|
|
5567
5591
|
* Determines if a link is a valid link (and not a fake shortcut link due to parser tricks).
|
|
5568
5592
|
*
|
|
5569
|
-
* @param {import("../helpers/micromark.cjs").Token} label Label token.
|
|
5570
|
-
* @param {import("../helpers/micromark.cjs").Token} labelText LabelText token.
|
|
5593
|
+
* @param {import("../helpers/micromark-helpers.cjs").Token} label Label token.
|
|
5594
|
+
* @param {import("../helpers/micromark-helpers.cjs").Token} labelText LabelText token.
|
|
5571
5595
|
* @param {Map<string, any>} definitions Map of link definitions.
|
|
5572
5596
|
* @returns {boolean} True iff the link is valid.
|
|
5573
5597
|
*/
|
|
@@ -5584,13 +5608,10 @@ module.exports = {
|
|
|
5584
5608
|
"parser": "micromark",
|
|
5585
5609
|
"function": function MD039(params, onError) {
|
|
5586
5610
|
const { definitions } = getReferenceLinkImageData();
|
|
5587
|
-
const labels = filterByTypesCached([ "label" ])
|
|
5588
|
-
filter((label) => label.parent?.type === "link");
|
|
5611
|
+
const labels = filterByTypesCached([ "label" ])
|
|
5612
|
+
.filter((label) => label.parent?.type === "link");
|
|
5589
5613
|
for (const label of labels) {
|
|
5590
|
-
const labelTexts =
|
|
5591
|
-
label.children,
|
|
5592
|
-
[ "labelText" ]
|
|
5593
|
-
);
|
|
5614
|
+
const labelTexts = label.children.filter((child) => child.type === "labelText");
|
|
5594
5615
|
for (const labelText of labelTexts) {
|
|
5595
5616
|
if (
|
|
5596
5617
|
(labelText.text.trimStart().length !== labelText.text.length) &&
|
|
@@ -5624,7 +5645,7 @@ module.exports = {
|
|
|
5624
5645
|
|
|
5625
5646
|
|
|
5626
5647
|
const { addError, addErrorContext } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
5627
|
-
const {
|
|
5648
|
+
const { getDescendantsByType } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
5628
5649
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
5629
5650
|
|
|
5630
5651
|
// eslint-disable-next-line jsdoc/valid-types
|
|
@@ -5640,18 +5661,16 @@ module.exports = {
|
|
|
5640
5661
|
const languageOnly = !!params.config.language_only;
|
|
5641
5662
|
const fencedCodes = filterByTypesCached([ "codeFenced" ]);
|
|
5642
5663
|
for (const fencedCode of fencedCodes) {
|
|
5643
|
-
const openingFence =
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
addError(onError, startLine, `Info string contains more than language: "${text}"`);
|
|
5654
|
-
}
|
|
5664
|
+
const openingFence = getDescendantsByType(fencedCode, [ "codeFencedFence" ])[0];
|
|
5665
|
+
const { startLine, text } = openingFence;
|
|
5666
|
+
const info = getDescendantsByType(openingFence, [ "codeFencedFenceInfo" ])[0]?.text;
|
|
5667
|
+
if (!info) {
|
|
5668
|
+
addErrorContext(onError, startLine, text);
|
|
5669
|
+
} else if ((allowed.length > 0) && !allowed.includes(info)) {
|
|
5670
|
+
addError(onError, startLine, `"${info}" is not allowed`);
|
|
5671
|
+
}
|
|
5672
|
+
if (languageOnly && getDescendantsByType(openingFence, [ "codeFencedFenceMeta" ]).length > 0) {
|
|
5673
|
+
addError(onError, startLine, `Info string contains more than language: "${text}"`);
|
|
5655
5674
|
}
|
|
5656
5675
|
}
|
|
5657
5676
|
}
|
|
@@ -5673,7 +5692,7 @@ module.exports = {
|
|
|
5673
5692
|
|
|
5674
5693
|
const { addErrorContext, frontMatterHasTitle } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
5675
5694
|
const { filterByTypes, getHeadingLevel, getHtmlTagInfo, isHtmlFlowComment, nonContentTokens } =
|
|
5676
|
-
__webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
5695
|
+
__webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
5677
5696
|
|
|
5678
5697
|
// eslint-disable-next-line jsdoc/valid-types
|
|
5679
5698
|
/** @type import("./markdownlint").Rule */
|
|
@@ -5685,9 +5704,9 @@ module.exports = {
|
|
|
5685
5704
|
"function": function MD041(params, onError) {
|
|
5686
5705
|
const level = Number(params.config.level || 1);
|
|
5687
5706
|
if (!frontMatterHasTitle(params.frontMatterLines, params.config.front_matter_title)) {
|
|
5688
|
-
params.parsers.micromark.tokens
|
|
5689
|
-
filter((token) => !nonContentTokens.has(token.type) && !isHtmlFlowComment(token))
|
|
5690
|
-
every((token) => {
|
|
5707
|
+
params.parsers.micromark.tokens
|
|
5708
|
+
.filter((token) => !nonContentTokens.has(token.type) && !isHtmlFlowComment(token))
|
|
5709
|
+
.every((token) => {
|
|
5691
5710
|
let isError = true;
|
|
5692
5711
|
if ((token.type === "atxHeading") || (token.type === "setextHeading")) {
|
|
5693
5712
|
isError = (getHeadingLevel(token) !== level);
|
|
@@ -5720,7 +5739,7 @@ module.exports = {
|
|
|
5720
5739
|
|
|
5721
5740
|
|
|
5722
5741
|
const { addErrorContext } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
5723
|
-
const { getDescendantsByType } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
5742
|
+
const { getDescendantsByType } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
5724
5743
|
const { getReferenceLinkImageData, filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
5725
5744
|
|
|
5726
5745
|
// eslint-disable-next-line jsdoc/valid-types
|
|
@@ -5742,11 +5761,7 @@ module.exports = {
|
|
|
5742
5761
|
const reference = getDescendantsByType(link, [ "reference" ]);
|
|
5743
5762
|
const resource = getDescendantsByType(link, [ "resource" ]);
|
|
5744
5763
|
const referenceString = getDescendantsByType(reference, [ "referenceString" ]);
|
|
5745
|
-
const
|
|
5746
|
-
const resourceDestinationString = [
|
|
5747
|
-
...getDescendantsByType(resourceDestination, [ "resourceDestinationRaw", "resourceDestinationString" ]),
|
|
5748
|
-
...getDescendantsByType(resourceDestination, [ "resourceDestinationLiteral", "resourceDestinationString" ])
|
|
5749
|
-
];
|
|
5764
|
+
const resourceDestinationString = getDescendantsByType(resource, [ "resourceDestination", [ "resourceDestinationLiteral", "resourceDestinationRaw" ], "resourceDestinationString" ]);
|
|
5750
5765
|
const hasLabelText = labelText.length > 0;
|
|
5751
5766
|
const hasReference = reference.length > 0;
|
|
5752
5767
|
const hasResource = resource.length > 0;
|
|
@@ -5794,7 +5809,7 @@ module.exports = {
|
|
|
5794
5809
|
|
|
5795
5810
|
|
|
5796
5811
|
const { addErrorContext, addErrorDetailIf } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
5797
|
-
const { getHeadingLevel, getHeadingText } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
5812
|
+
const { getHeadingLevel, getHeadingText } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
5798
5813
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
5799
5814
|
|
|
5800
5815
|
// eslint-disable-next-line jsdoc/valid-types
|
|
@@ -5877,10 +5892,9 @@ module.exports = {
|
|
|
5877
5892
|
|
|
5878
5893
|
|
|
5879
5894
|
|
|
5880
|
-
const { addErrorDetailIf, escapeForRegExp,
|
|
5881
|
-
|
|
5882
|
-
const {
|
|
5883
|
-
__webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
5895
|
+
const { addErrorDetailIf, escapeForRegExp, hasOverlap } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
5896
|
+
const { filterByPredicate, filterByTypes } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
5897
|
+
const { parse } = __webpack_require__(/*! ../helpers/micromark-parse.cjs */ "../helpers/micromark-parse.cjs");
|
|
5884
5898
|
|
|
5885
5899
|
const ignoredChildTypes = new Set(
|
|
5886
5900
|
[ "codeFencedFence", "definition", "reference", "resource" ]
|
|
@@ -5924,43 +5938,47 @@ module.exports = {
|
|
|
5924
5938
|
token.children.filter((t) => !ignoredChildTypes.has(t.type))
|
|
5925
5939
|
)
|
|
5926
5940
|
);
|
|
5941
|
+
/** @type {import("../helpers").FileRange[]} */
|
|
5927
5942
|
const exclusions = [];
|
|
5928
|
-
const
|
|
5943
|
+
const scannedTokens = new Set();
|
|
5929
5944
|
for (const name of names) {
|
|
5930
5945
|
const escapedName = escapeForRegExp(name);
|
|
5931
5946
|
const startNamePattern = /^\W/.test(name) ? "" : "\\b_*";
|
|
5932
5947
|
const endNamePattern = /\W$/.test(name) ? "" : "_*\\b";
|
|
5933
|
-
const namePattern =
|
|
5934
|
-
`(${startNamePattern})(${escapedName})${endNamePattern}`;
|
|
5948
|
+
const namePattern = `(${startNamePattern})(${escapedName})${endNamePattern}`;
|
|
5935
5949
|
const nameRe = new RegExp(namePattern, "gi");
|
|
5936
5950
|
for (const token of contentTokens) {
|
|
5937
5951
|
let match = null;
|
|
5938
5952
|
while ((match = nameRe.exec(token.text)) !== null) {
|
|
5939
5953
|
const [ , leftMatch, nameMatch ] = match;
|
|
5940
|
-
const
|
|
5954
|
+
const column = token.startColumn + match.index + leftMatch.length;
|
|
5941
5955
|
const length = nameMatch.length;
|
|
5942
|
-
const
|
|
5956
|
+
const lineNumber = token.startLine;
|
|
5957
|
+
/** @type {import("../helpers").FileRange} */
|
|
5958
|
+
const nameRange = {
|
|
5959
|
+
"startLine": lineNumber,
|
|
5960
|
+
"startColumn": column,
|
|
5961
|
+
"endLine": lineNumber,
|
|
5962
|
+
"endColumn": column + length - 1
|
|
5963
|
+
};
|
|
5943
5964
|
if (
|
|
5944
|
-
!
|
|
5945
|
-
!
|
|
5965
|
+
!names.includes(nameMatch) &&
|
|
5966
|
+
!exclusions.some((exclusion) => hasOverlap(exclusion, nameRange))
|
|
5946
5967
|
) {
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
token.
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
);
|
|
5959
|
-
exclusions.push(...urlRanges);
|
|
5960
|
-
autoLinked.add(token);
|
|
5968
|
+
/** @type {import("../helpers").FileRange[]} */
|
|
5969
|
+
let autolinkRanges = [];
|
|
5970
|
+
if (!scannedTokens.has(token)) {
|
|
5971
|
+
autolinkRanges = filterByTypes(parse(token.text), [ "literalAutolink" ])
|
|
5972
|
+
.map((tok) => ({
|
|
5973
|
+
"startLine": lineNumber,
|
|
5974
|
+
"startColumn": token.startColumn + tok.startColumn - 1,
|
|
5975
|
+
"endLine": lineNumber,
|
|
5976
|
+
"endColumn": token.endColumn + tok.endColumn - 1
|
|
5977
|
+
}));
|
|
5978
|
+
exclusions.push(...autolinkRanges);
|
|
5979
|
+
scannedTokens.add(token);
|
|
5961
5980
|
}
|
|
5962
|
-
if (!
|
|
5963
|
-
const column = index + 1;
|
|
5981
|
+
if (!autolinkRanges.some((autolinkRange) => hasOverlap(autolinkRange, nameRange))) {
|
|
5964
5982
|
addErrorDetailIf(
|
|
5965
5983
|
onError,
|
|
5966
5984
|
token.startLine,
|
|
@@ -5977,7 +5995,7 @@ module.exports = {
|
|
|
5977
5995
|
);
|
|
5978
5996
|
}
|
|
5979
5997
|
}
|
|
5980
|
-
exclusions.push(
|
|
5998
|
+
exclusions.push(nameRange);
|
|
5981
5999
|
}
|
|
5982
6000
|
}
|
|
5983
6001
|
}
|
|
@@ -5999,7 +6017,7 @@ module.exports = {
|
|
|
5999
6017
|
|
|
6000
6018
|
|
|
6001
6019
|
const { addError, getHtmlAttributeRe, nextLinesRe } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
6002
|
-
const {
|
|
6020
|
+
const { getHtmlTagInfo, getDescendantsByType } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
6003
6021
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
6004
6022
|
|
|
6005
6023
|
const altRe = getHtmlAttributeRe("alt");
|
|
@@ -6015,7 +6033,7 @@ module.exports = {
|
|
|
6015
6033
|
// Process Markdown images
|
|
6016
6034
|
const images = filterByTypesCached([ "image" ]);
|
|
6017
6035
|
for (const image of images) {
|
|
6018
|
-
const labelTexts =
|
|
6036
|
+
const labelTexts = getDescendantsByType(image, [ "label", "labelText" ]);
|
|
6019
6037
|
if (labelTexts.some((labelText) => labelText.text.length === 0)) {
|
|
6020
6038
|
const range = (image.startLine === image.endLine) ?
|
|
6021
6039
|
[ image.startColumn, image.endColumn - image.startColumn ] :
|
|
@@ -6158,10 +6176,25 @@ module.exports = {
|
|
|
6158
6176
|
|
|
6159
6177
|
|
|
6160
6178
|
|
|
6161
|
-
const { addErrorDetailIf
|
|
6162
|
-
const {
|
|
6179
|
+
const { addErrorDetailIf } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
6180
|
+
const { getDescendantsByType } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
6163
6181
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
6164
6182
|
|
|
6183
|
+
/**
|
|
6184
|
+
* Return the string representation of a fence markup character.
|
|
6185
|
+
*
|
|
6186
|
+
* @param {string} markup Fence string.
|
|
6187
|
+
* @returns {"tilde" | "backtick"} String representation.
|
|
6188
|
+
*/
|
|
6189
|
+
function fencedCodeBlockStyleFor(markup) {
|
|
6190
|
+
switch (markup[0]) {
|
|
6191
|
+
case "~":
|
|
6192
|
+
return "tilde";
|
|
6193
|
+
default:
|
|
6194
|
+
return "backtick";
|
|
6195
|
+
}
|
|
6196
|
+
};
|
|
6197
|
+
|
|
6165
6198
|
// eslint-disable-next-line jsdoc/valid-types
|
|
6166
6199
|
/** @type import("./markdownlint").Rule */
|
|
6167
6200
|
module.exports = {
|
|
@@ -6174,22 +6207,18 @@ module.exports = {
|
|
|
6174
6207
|
let expectedStyle = style;
|
|
6175
6208
|
const codeFenceds = filterByTypesCached([ "codeFenced" ]);
|
|
6176
6209
|
for (const codeFenced of codeFenceds) {
|
|
6177
|
-
const
|
|
6178
|
-
|
|
6179
|
-
|
|
6180
|
-
|
|
6181
|
-
|
|
6182
|
-
if (expectedStyle === "consistent") {
|
|
6183
|
-
expectedStyle = fencedCodeBlockStyleFor(text);
|
|
6184
|
-
}
|
|
6185
|
-
addErrorDetailIf(
|
|
6186
|
-
onError,
|
|
6187
|
-
startLine,
|
|
6188
|
-
expectedStyle,
|
|
6189
|
-
fencedCodeBlockStyleFor(text)
|
|
6190
|
-
);
|
|
6191
|
-
}
|
|
6210
|
+
const codeFencedFenceSequence =
|
|
6211
|
+
getDescendantsByType(codeFenced, [ "codeFencedFence", "codeFencedFenceSequence" ])[0];
|
|
6212
|
+
const { startLine, text } = codeFencedFenceSequence;
|
|
6213
|
+
if (expectedStyle === "consistent") {
|
|
6214
|
+
expectedStyle = fencedCodeBlockStyleFor(text);
|
|
6192
6215
|
}
|
|
6216
|
+
addErrorDetailIf(
|
|
6217
|
+
onError,
|
|
6218
|
+
startLine,
|
|
6219
|
+
expectedStyle,
|
|
6220
|
+
fencedCodeBlockStyleFor(text)
|
|
6221
|
+
);
|
|
6193
6222
|
}
|
|
6194
6223
|
}
|
|
6195
6224
|
};
|
|
@@ -6208,11 +6237,26 @@ module.exports = {
|
|
|
6208
6237
|
|
|
6209
6238
|
|
|
6210
6239
|
|
|
6211
|
-
const { addError
|
|
6212
|
-
const { filterByPredicate,
|
|
6240
|
+
const { addError } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
6241
|
+
const { filterByPredicate, getDescendantsByType } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
6213
6242
|
|
|
6214
6243
|
const intrawordRe = /^\w$/;
|
|
6215
6244
|
|
|
6245
|
+
/**
|
|
6246
|
+
* Return the string representation of a emphasis or strong markup character.
|
|
6247
|
+
*
|
|
6248
|
+
* @param {string} markup Emphasis or strong string.
|
|
6249
|
+
* @returns {"asterisk" | "underscore"} String representation.
|
|
6250
|
+
*/
|
|
6251
|
+
function emphasisOrStrongStyleFor(markup) {
|
|
6252
|
+
switch (markup[0]) {
|
|
6253
|
+
case "*":
|
|
6254
|
+
return "asterisk";
|
|
6255
|
+
default:
|
|
6256
|
+
return "underscore";
|
|
6257
|
+
}
|
|
6258
|
+
};
|
|
6259
|
+
|
|
6216
6260
|
/**
|
|
6217
6261
|
* @param {import("./markdownlint").RuleParams} params Rule parameters.
|
|
6218
6262
|
* @param {import("./markdownlint").RuleOnError} onError Error-reporting callback.
|
|
@@ -6231,9 +6275,9 @@ const impl =
|
|
|
6231
6275
|
(token) => ((token.type === "htmlFlow") ? [] : token.children)
|
|
6232
6276
|
);
|
|
6233
6277
|
for (const token of emphasisTokens) {
|
|
6234
|
-
const
|
|
6235
|
-
const startSequence =
|
|
6236
|
-
const endSequence =
|
|
6278
|
+
const sequences = getDescendantsByType(token, [ typeSequence ]);
|
|
6279
|
+
const startSequence = sequences[0];
|
|
6280
|
+
const endSequence = sequences[sequences.length - 1];
|
|
6237
6281
|
if (startSequence && endSequence) {
|
|
6238
6282
|
const markupStyle = emphasisOrStrongStyleFor(startSequence.text);
|
|
6239
6283
|
if (style === "consistent") {
|
|
@@ -6322,8 +6366,8 @@ module.exports = [
|
|
|
6322
6366
|
|
|
6323
6367
|
|
|
6324
6368
|
|
|
6325
|
-
const { addError,
|
|
6326
|
-
const { filterByPredicate, filterByTypes, getHtmlTagInfo } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
6369
|
+
const { addError, getHtmlAttributeRe } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
6370
|
+
const { filterByPredicate, filterByTypes, getHtmlTagInfo } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
6327
6371
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
6328
6372
|
|
|
6329
6373
|
// Regular expression for identifying HTML anchor names
|
|
@@ -6342,7 +6386,7 @@ const tokensInclude = new Set(
|
|
|
6342
6386
|
* Converts a Markdown heading into an HTML fragment according to the rules
|
|
6343
6387
|
* used by GitHub.
|
|
6344
6388
|
*
|
|
6345
|
-
* @param {import("../helpers/micromark.cjs").Token} headingText Heading text token.
|
|
6389
|
+
* @param {import("../helpers/micromark-helpers.cjs").Token} headingText Heading text token.
|
|
6346
6390
|
* @returns {string} Fragment string for heading.
|
|
6347
6391
|
*/
|
|
6348
6392
|
function convertHeadingToHTMLFragment(headingText) {
|
|
@@ -6371,7 +6415,7 @@ function convertHeadingToHTMLFragment(headingText) {
|
|
|
6371
6415
|
/**
|
|
6372
6416
|
* Unescapes the text of a String-type micromark Token.
|
|
6373
6417
|
*
|
|
6374
|
-
* @param {import("../helpers/micromark.cjs").Token} token String-type micromark Token.
|
|
6418
|
+
* @param {import("../helpers/micromark-helpers.cjs").Token} token String-type micromark Token.
|
|
6375
6419
|
* @returns {string} Unescaped token text.
|
|
6376
6420
|
*/
|
|
6377
6421
|
function unescapeStringTokenText(token) {
|
|
@@ -6388,6 +6432,7 @@ module.exports = {
|
|
|
6388
6432
|
"tags": [ "links" ],
|
|
6389
6433
|
"parser": "micromark",
|
|
6390
6434
|
"function": function MD051(params, onError) {
|
|
6435
|
+
const ignoreCase = params.config.ignore_case || false;
|
|
6391
6436
|
const fragments = new Map();
|
|
6392
6437
|
|
|
6393
6438
|
// Process headings
|
|
@@ -6424,7 +6469,7 @@ module.exports = {
|
|
|
6424
6469
|
|
|
6425
6470
|
// Process link and definition fragments
|
|
6426
6471
|
// eslint-disable-next-line jsdoc/valid-types
|
|
6427
|
-
/** @type import("../helpers/micromark.cjs").TokenType[][] */
|
|
6472
|
+
/** @type import("../helpers/micromark-helpers.cjs").TokenType[][] */
|
|
6428
6473
|
const parentChilds = [
|
|
6429
6474
|
[ "link", "resourceDestinationString" ],
|
|
6430
6475
|
[ "definition", "definitionDestinationString" ]
|
|
@@ -6443,11 +6488,8 @@ module.exports = {
|
|
|
6443
6488
|
!fragments.has(encodedText) &&
|
|
6444
6489
|
!lineFragmentRe.test(encodedText)
|
|
6445
6490
|
) {
|
|
6446
|
-
// eslint-disable-next-line no-undef-init
|
|
6447
6491
|
let context = undefined;
|
|
6448
|
-
// eslint-disable-next-line no-undef-init
|
|
6449
6492
|
let range = undefined;
|
|
6450
|
-
// eslint-disable-next-line no-undef-init
|
|
6451
6493
|
let fixInfo = undefined;
|
|
6452
6494
|
if (link.startLine === link.endLine) {
|
|
6453
6495
|
context = link.text;
|
|
@@ -6463,16 +6505,16 @@ module.exports = {
|
|
|
6463
6505
|
if (mixedCaseKey) {
|
|
6464
6506
|
// @ts-ignore
|
|
6465
6507
|
(fixInfo || {}).insertText = mixedCaseKey;
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6508
|
+
if (!ignoreCase && (mixedCaseKey !== text)) {
|
|
6509
|
+
addError(
|
|
6510
|
+
onError,
|
|
6511
|
+
link.startLine,
|
|
6512
|
+
`Expected: ${mixedCaseKey}; Actual: ${text}`,
|
|
6513
|
+
context,
|
|
6514
|
+
range,
|
|
6515
|
+
fixInfo
|
|
6516
|
+
);
|
|
6517
|
+
}
|
|
6476
6518
|
} else {
|
|
6477
6519
|
addError(
|
|
6478
6520
|
onError,
|
|
@@ -6556,10 +6598,11 @@ module.exports = {
|
|
|
6556
6598
|
|
|
6557
6599
|
|
|
6558
6600
|
|
|
6559
|
-
const { addError, ellipsify
|
|
6560
|
-
__webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
6601
|
+
const { addError, ellipsify } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
6561
6602
|
const { getReferenceLinkImageData } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
6562
6603
|
|
|
6604
|
+
const linkReferenceDefinitionRe = /^ {0,3}\[([^\]]*[^\\])\]:/;
|
|
6605
|
+
|
|
6563
6606
|
// eslint-disable-next-line jsdoc/valid-types
|
|
6564
6607
|
/** @type import("./markdownlint").Rule */
|
|
6565
6608
|
module.exports = {
|
|
@@ -6593,7 +6636,7 @@ module.exports = {
|
|
|
6593
6636
|
`Unused link or image reference definition: "${label}"`,
|
|
6594
6637
|
ellipsify(line),
|
|
6595
6638
|
[ 1, line.length ],
|
|
6596
|
-
singleLineDefinition(line) ? deleteFixInfo :
|
|
6639
|
+
singleLineDefinition(line) ? deleteFixInfo : undefined
|
|
6597
6640
|
);
|
|
6598
6641
|
}
|
|
6599
6642
|
}
|
|
@@ -6608,7 +6651,7 @@ module.exports = {
|
|
|
6608
6651
|
`Duplicate link or image reference definition: "${label}"`,
|
|
6609
6652
|
ellipsify(line),
|
|
6610
6653
|
[ 1, line.length ],
|
|
6611
|
-
singleLineDefinition(line) ? deleteFixInfo :
|
|
6654
|
+
singleLineDefinition(line) ? deleteFixInfo : undefined
|
|
6612
6655
|
);
|
|
6613
6656
|
}
|
|
6614
6657
|
}
|
|
@@ -6630,7 +6673,7 @@ module.exports = {
|
|
|
6630
6673
|
|
|
6631
6674
|
|
|
6632
6675
|
const { addErrorContext, nextLinesRe } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
6633
|
-
const {
|
|
6676
|
+
const { getDescendantsByType } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
6634
6677
|
const { getReferenceLinkImageData, filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
6635
6678
|
|
|
6636
6679
|
const backslashEscapeRe = /\\([!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~])/g;
|
|
@@ -6672,24 +6715,23 @@ module.exports = {
|
|
|
6672
6715
|
let label = null;
|
|
6673
6716
|
let destination = null;
|
|
6674
6717
|
const {
|
|
6675
|
-
|
|
6718
|
+
endColumn, endLine, startColumn, startLine, text, type
|
|
6676
6719
|
} = link;
|
|
6677
6720
|
const image = (type === "image");
|
|
6678
6721
|
let isError = false;
|
|
6679
6722
|
if (type === "autolink") {
|
|
6680
6723
|
// link kind is an autolink
|
|
6681
|
-
destination =
|
|
6724
|
+
destination = getDescendantsByType(link, [ "autolinkProtocol" ])[0].text;
|
|
6682
6725
|
label = destination;
|
|
6683
6726
|
isError = !autolink;
|
|
6684
6727
|
} else {
|
|
6685
6728
|
// link type is "image" or "link"
|
|
6686
|
-
|
|
6687
|
-
label = getTokenTextByType(descendents, "labelText");
|
|
6729
|
+
label = getDescendantsByType(link, [ "label", "labelText" ])[0].text;
|
|
6688
6730
|
destination =
|
|
6689
|
-
|
|
6731
|
+
getDescendantsByType(link, [ "resource", "resourceDestination", [ "resourceDestinationLiteral", "resourceDestinationRaw" ], "resourceDestinationString" ])[0]?.text;
|
|
6690
6732
|
if (destination) {
|
|
6691
6733
|
// link kind is an inline link
|
|
6692
|
-
const title =
|
|
6734
|
+
const title = getDescendantsByType(link, [ "resource", "resourceTitle", "resourceTitleString" ])[0]?.text;
|
|
6693
6735
|
isError = !inline || (
|
|
6694
6736
|
!urlInline &&
|
|
6695
6737
|
autolink &&
|
|
@@ -6700,9 +6742,9 @@ module.exports = {
|
|
|
6700
6742
|
);
|
|
6701
6743
|
} else {
|
|
6702
6744
|
// link kind is a full/collapsed/shortcut reference link
|
|
6703
|
-
const isShortcut =
|
|
6704
|
-
const referenceString =
|
|
6705
|
-
const isCollapsed = (referenceString ===
|
|
6745
|
+
const isShortcut = getDescendantsByType(link, [ "reference" ]).length === 0;
|
|
6746
|
+
const referenceString = getDescendantsByType(link, [ "reference", "referenceString" ])[0]?.text;
|
|
6747
|
+
const isCollapsed = (referenceString === undefined);
|
|
6706
6748
|
const definition = definitions.get(referenceString || label);
|
|
6707
6749
|
destination = definition && definition[1];
|
|
6708
6750
|
isError = destination &&
|
|
@@ -6710,9 +6752,8 @@ module.exports = {
|
|
|
6710
6752
|
}
|
|
6711
6753
|
}
|
|
6712
6754
|
if (isError) {
|
|
6713
|
-
// eslint-disable-next-line no-undef-init
|
|
6714
6755
|
let range = undefined;
|
|
6715
|
-
let fixInfo =
|
|
6756
|
+
let fixInfo = undefined;
|
|
6716
6757
|
if (startLine === endLine) {
|
|
6717
6758
|
range = [ startColumn, endColumn - startColumn ];
|
|
6718
6759
|
let insertText = null;
|
|
@@ -6766,7 +6807,6 @@ module.exports = {
|
|
|
6766
6807
|
|
|
6767
6808
|
|
|
6768
6809
|
const { addErrorDetailIf } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
6769
|
-
const { filterByTypes } = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs");
|
|
6770
6810
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
6771
6811
|
|
|
6772
6812
|
const whitespaceTypes = new Set([ "linePrefix", "whitespace" ]);
|
|
@@ -6791,51 +6831,45 @@ module.exports = {
|
|
|
6791
6831
|
((expectedStyle !== "no_leading_or_trailing") && (expectedStyle !== "trailing_only"));
|
|
6792
6832
|
let expectedTrailingPipe =
|
|
6793
6833
|
((expectedStyle !== "no_leading_or_trailing") && (expectedStyle !== "leading_only"));
|
|
6794
|
-
const
|
|
6795
|
-
for (const
|
|
6796
|
-
|
|
6797
|
-
|
|
6798
|
-
|
|
6799
|
-
);
|
|
6800
|
-
|
|
6801
|
-
|
|
6802
|
-
|
|
6803
|
-
|
|
6804
|
-
|
|
6805
|
-
|
|
6806
|
-
|
|
6807
|
-
|
|
6808
|
-
|
|
6809
|
-
|
|
6810
|
-
|
|
6811
|
-
|
|
6812
|
-
|
|
6813
|
-
|
|
6814
|
-
|
|
6815
|
-
|
|
6816
|
-
|
|
6817
|
-
|
|
6818
|
-
|
|
6819
|
-
|
|
6820
|
-
|
|
6821
|
-
|
|
6822
|
-
|
|
6823
|
-
|
|
6824
|
-
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
|
|
6830
|
-
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
actualStyle,
|
|
6834
|
-
`${expectedTrailingPipe ? "Missing" : "Unexpected"} trailing pipe`,
|
|
6835
|
-
undefined,
|
|
6836
|
-
makeRange(lastCell.endColumn - 1, row.endColumn - 1)
|
|
6837
|
-
);
|
|
6838
|
-
}
|
|
6834
|
+
const rows = filterByTypesCached([ "tableDelimiterRow", "tableRow" ]);
|
|
6835
|
+
for (const row of rows) {
|
|
6836
|
+
// The following uses of first/lastOrNothing lack fallback handling
|
|
6837
|
+
// because it seems not to be possible (i.e., 0% coverage)
|
|
6838
|
+
const firstCell = firstOrNothing(row.children);
|
|
6839
|
+
const leadingToken = firstOrNothing(ignoreWhitespace(firstCell.children));
|
|
6840
|
+
const actualLeadingPipe = (leadingToken.type === "tableCellDivider");
|
|
6841
|
+
const lastCell = lastOrNothing(row.children);
|
|
6842
|
+
const trailingToken = lastOrNothing(ignoreWhitespace(lastCell.children));
|
|
6843
|
+
const actualTrailingPipe = (trailingToken.type === "tableCellDivider");
|
|
6844
|
+
const actualStyle = actualLeadingPipe ?
|
|
6845
|
+
(actualTrailingPipe ? "leading_and_trailing" : "leading_only") :
|
|
6846
|
+
(actualTrailingPipe ? "trailing_only" : "no_leading_or_trailing");
|
|
6847
|
+
if (expectedStyle === "consistent") {
|
|
6848
|
+
expectedStyle = actualStyle;
|
|
6849
|
+
expectedLeadingPipe = actualLeadingPipe;
|
|
6850
|
+
expectedTrailingPipe = actualTrailingPipe;
|
|
6851
|
+
}
|
|
6852
|
+
if (actualLeadingPipe !== expectedLeadingPipe) {
|
|
6853
|
+
addErrorDetailIf(
|
|
6854
|
+
onError,
|
|
6855
|
+
firstCell.startLine,
|
|
6856
|
+
expectedStyle,
|
|
6857
|
+
actualStyle,
|
|
6858
|
+
`${expectedLeadingPipe ? "Missing" : "Unexpected"} leading pipe`,
|
|
6859
|
+
undefined,
|
|
6860
|
+
makeRange(row.startColumn, firstCell.startColumn)
|
|
6861
|
+
);
|
|
6862
|
+
}
|
|
6863
|
+
if (actualTrailingPipe !== expectedTrailingPipe) {
|
|
6864
|
+
addErrorDetailIf(
|
|
6865
|
+
onError,
|
|
6866
|
+
lastCell.endLine,
|
|
6867
|
+
expectedStyle,
|
|
6868
|
+
actualStyle,
|
|
6869
|
+
`${expectedTrailingPipe ? "Missing" : "Unexpected"} trailing pipe`,
|
|
6870
|
+
undefined,
|
|
6871
|
+
makeRange(lastCell.endColumn - 1, row.endColumn - 1)
|
|
6872
|
+
);
|
|
6839
6873
|
}
|
|
6840
6874
|
}
|
|
6841
6875
|
}
|
|
@@ -6856,7 +6890,7 @@ module.exports = {
|
|
|
6856
6890
|
|
|
6857
6891
|
|
|
6858
6892
|
const { addErrorDetailIf } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
6859
|
-
const {
|
|
6893
|
+
const { getParentOfType } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
6860
6894
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
6861
6895
|
|
|
6862
6896
|
const makeRange = (start, end) => [ start, end - start + 1 ];
|
|
@@ -6869,44 +6903,39 @@ module.exports = {
|
|
|
6869
6903
|
"tags": [ "table" ],
|
|
6870
6904
|
"parser": "micromark",
|
|
6871
6905
|
"function": function MD056(params, onError) {
|
|
6872
|
-
const
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
)
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
range = [ row.endColumn - 1, 1 ];
|
|
6893
|
-
} else if (expectedCount < actualCount) {
|
|
6894
|
-
detail = "Too many cells, extra data will be missing";
|
|
6895
|
-
range = makeRange(cells[expectedCount].startColumn, row.endColumn - 1);
|
|
6896
|
-
}
|
|
6897
|
-
addErrorDetailIf(
|
|
6898
|
-
onError,
|
|
6899
|
-
row.endLine,
|
|
6900
|
-
expectedCount,
|
|
6901
|
-
actualCount,
|
|
6902
|
-
detail,
|
|
6903
|
-
undefined,
|
|
6904
|
-
range
|
|
6905
|
-
);
|
|
6906
|
+
const rows = filterByTypesCached([ "tableDelimiterRow", "tableRow" ]);
|
|
6907
|
+
let expectedCount = 0;
|
|
6908
|
+
let currentTable = null;
|
|
6909
|
+
for (const row of rows) {
|
|
6910
|
+
const table = getParentOfType(row, [ "table" ]);
|
|
6911
|
+
if (currentTable !== table) {
|
|
6912
|
+
expectedCount = 0;
|
|
6913
|
+
currentTable = table;
|
|
6914
|
+
}
|
|
6915
|
+
const cells = row.children.filter((child) => [ "tableData", "tableDelimiter", "tableHeader" ].includes(child.type));
|
|
6916
|
+
const actualCount = cells.length;
|
|
6917
|
+
expectedCount ||= actualCount;
|
|
6918
|
+
let detail = undefined;
|
|
6919
|
+
let range = undefined;
|
|
6920
|
+
if (actualCount < expectedCount) {
|
|
6921
|
+
detail = "Too few cells, row will be missing data";
|
|
6922
|
+
range = [ row.endColumn - 1, 1 ];
|
|
6923
|
+
} else if (expectedCount < actualCount) {
|
|
6924
|
+
detail = "Too many cells, extra data will be missing";
|
|
6925
|
+
range = makeRange(cells[expectedCount].startColumn, row.endColumn - 1);
|
|
6906
6926
|
}
|
|
6927
|
+
addErrorDetailIf(
|
|
6928
|
+
onError,
|
|
6929
|
+
row.endLine,
|
|
6930
|
+
expectedCount,
|
|
6931
|
+
actualCount,
|
|
6932
|
+
detail,
|
|
6933
|
+
undefined,
|
|
6934
|
+
range
|
|
6935
|
+
);
|
|
6907
6936
|
}
|
|
6908
6937
|
}
|
|
6909
|
-
}
|
|
6938
|
+
};
|
|
6910
6939
|
|
|
6911
6940
|
|
|
6912
6941
|
/***/ }),
|
|
@@ -6922,7 +6951,8 @@ module.exports = {
|
|
|
6922
6951
|
|
|
6923
6952
|
|
|
6924
6953
|
|
|
6925
|
-
const {
|
|
6954
|
+
const { addErrorContext, isBlankLine } = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js");
|
|
6955
|
+
const { getBlockQuotePrefixText } = __webpack_require__(/*! ../helpers/micromark-helpers.cjs */ "../helpers/micromark-helpers.cjs");
|
|
6926
6956
|
const { filterByTypesCached } = __webpack_require__(/*! ./cache */ "../lib/cache.js");
|
|
6927
6957
|
|
|
6928
6958
|
// eslint-disable-next-line jsdoc/valid-types
|
|
@@ -6934,28 +6964,42 @@ module.exports = {
|
|
|
6934
6964
|
"parser": "micromark",
|
|
6935
6965
|
"function": function MD058(params, onError) {
|
|
6936
6966
|
const { lines } = params;
|
|
6967
|
+
const blockQuotePrefixes = filterByTypesCached([ "blockQuotePrefix", "linePrefix" ]);
|
|
6968
|
+
|
|
6937
6969
|
// For every table...
|
|
6938
6970
|
const tables = filterByTypesCached([ "table" ]);
|
|
6939
6971
|
for (const table of tables) {
|
|
6972
|
+
|
|
6940
6973
|
// Look for a blank line above the table
|
|
6941
|
-
const
|
|
6942
|
-
if (!isBlankLine(lines[
|
|
6943
|
-
|
|
6974
|
+
const firstLineNumber = table.startLine;
|
|
6975
|
+
if (!isBlankLine(lines[firstLineNumber - 2])) {
|
|
6976
|
+
addErrorContext(
|
|
6944
6977
|
onError,
|
|
6945
|
-
|
|
6946
|
-
lines,
|
|
6947
|
-
|
|
6978
|
+
firstLineNumber,
|
|
6979
|
+
lines[firstLineNumber - 1].trim(),
|
|
6980
|
+
undefined,
|
|
6981
|
+
undefined,
|
|
6982
|
+
undefined,
|
|
6983
|
+
{
|
|
6984
|
+
"insertText": getBlockQuotePrefixText(blockQuotePrefixes, firstLineNumber)
|
|
6985
|
+
}
|
|
6948
6986
|
);
|
|
6949
6987
|
}
|
|
6988
|
+
|
|
6950
6989
|
// Look for a blank line below the table
|
|
6951
|
-
const
|
|
6952
|
-
if (!isBlankLine(lines[
|
|
6953
|
-
|
|
6990
|
+
const lastLineNumber = table.endLine;
|
|
6991
|
+
if (!isBlankLine(lines[lastLineNumber])) {
|
|
6992
|
+
addErrorContext(
|
|
6954
6993
|
onError,
|
|
6955
|
-
|
|
6956
|
-
lines,
|
|
6957
|
-
|
|
6958
|
-
|
|
6994
|
+
lastLineNumber,
|
|
6995
|
+
lines[lastLineNumber - 1].trim(),
|
|
6996
|
+
undefined,
|
|
6997
|
+
undefined,
|
|
6998
|
+
undefined,
|
|
6999
|
+
{
|
|
7000
|
+
"lineNumber": lastLineNumber + 1,
|
|
7001
|
+
"insertText": getBlockQuotePrefixText(blockQuotePrefixes, lastLineNumber)
|
|
7002
|
+
}
|
|
6959
7003
|
);
|
|
6960
7004
|
}
|
|
6961
7005
|
}
|