markdownlint
Advanced tools
Comparing version 0.34.0 to 0.35.0
# Changelog | ||
## 0.35.0 | ||
- Add MD058/blanks-around-tables | ||
- Use `micromark` in MD001/MD003/MD009/MD010/MD013/MD014/MD019/MD021/MD023/ | ||
MD024/MD025/MD039/MD042/MD043 | ||
- Improve MD018/MD020/MD031/MD034/MD044 | ||
- `markdown-it` parser no longer invoked by default | ||
- Add strict version of JSON schema | ||
- Improve performance | ||
- Update dependencies | ||
## 0.34.0 | ||
@@ -4,0 +15,0 @@ |
# Custom Rules | ||
In addition to its built-in rules, `markdownlint` lets you enhance the linting | ||
experience by passing a list of custom rules using the [`options.customRules` | ||
experience by passing an array of custom rules using the [`options.customRules` | ||
property][options-custom-rules]. Custom rules can do everything the built-in | ||
rules can and are defined inline or imported from another package ([keyword | ||
`markdownlint-rule` on npm][markdownlint-rule]). Custom rules can be disabled, | ||
enabled, and customized using the same syntax as built-in rules. | ||
`markdownlint-rule` on npm][markdownlint-rule]). When defined by a file or | ||
package, the export can be a single rule object (see below) or an array of them. | ||
Custom rules can be disabled, enabled, and customized using the same syntax as | ||
built-in rules. | ||
@@ -132,4 +134,5 @@ ## Implementing Simple Rules | ||
- [Code for all `markdownlint` built-in rules][lib] | ||
- [Package configuration for publishing to npm][test-rules-npm] | ||
- Packages should export a single rule object or an `Array` of rule objects | ||
- [Complete example rule including npm configuration][extended-ascii] | ||
- [Custom rules from the github/docs repository][github-docs] | ||
- [Custom rules from the electron/lint-roller repository][electron] | ||
- [Custom rules from the webhintio/hint repository][hint] | ||
@@ -376,2 +379,5 @@ | ||
[commonmark]: https://commonmark.org/ | ||
[electron]: https://github.com/electron/lint-roller/tree/main/markdownlint-rules | ||
[extended-ascii]: https://github.com/DavidAnson/markdownlint-rule-extended-ascii | ||
[github-docs]: https://github.com/github/docs/tree/main/src/content-linter/lib/linting-rules | ||
[hint]: https://github.com/webhintio/hint/blob/main/scripts/lint-markdown.js | ||
@@ -385,2 +391,1 @@ [lib]: ../lib | ||
[test-rules]: ../test/rules | ||
[test-rules-npm]: ../test/rules/npm |
@@ -22,2 +22,7 @@ # `MD034` - Bare URL used | ||
If a URL or email address contains non-ASCII characters, it may be not be | ||
handled as intended even when angle brackets are present. In such cases, | ||
[percent-encoding](https://en.m.wikipedia.org/wiki/Percent-encoding) can be used | ||
to comply with the required syntax for URL and email. | ||
Note: To include a bare URL or email without it being converted into a link, | ||
@@ -24,0 +29,0 @@ wrap it in a code span: |
@@ -30,2 +30,12 @@ # `MD044` - Proper names should have the correct capitalization | ||
Sometimes a proper name is capitalized differently in certain contexts. In such | ||
cases, add both forms to the `names` array: | ||
```json | ||
[ | ||
"GitHub", | ||
"github.com" | ||
] | ||
``` | ||
Set the `code_blocks` parameter to `false` to disable this rule for code blocks | ||
@@ -32,0 +42,0 @@ and spans. Set the `html_elements` parameter to `false` to disable this rule |
@@ -1357,2 +1357,7 @@ # Rules | ||
If a URL or email address contains non-ASCII characters, it may be not be | ||
handled as intended even when angle brackets are present. In such cases, | ||
[percent-encoding](https://en.m.wikipedia.org/wiki/Percent-encoding) can be used | ||
to comply with the required syntax for URL and email. | ||
Note: To include a bare URL or email without it being converted into a link, | ||
@@ -1833,2 +1838,12 @@ wrap it in a code span: | ||
Sometimes a proper name is capitalized differently in certain contexts. In such | ||
cases, add both forms to the `names` array: | ||
```json | ||
[ | ||
"GitHub", | ||
"github.com" | ||
] | ||
``` | ||
Set the `code_blocks` parameter to `false` to disable this rule for code blocks | ||
@@ -2458,2 +2473,53 @@ and spans. Set the `html_elements` parameter to `false` to disable this rule | ||
<a name="md058"></a> | ||
## `MD058` - Tables should be surrounded by blank lines | ||
Tags: `table` | ||
Aliases: `blanks-around-tables` | ||
Fixable: Some violations can be fixed by tooling | ||
This rule is triggered when tables are either not preceded or not followed by a | ||
blank line: | ||
```markdown | ||
Some text | ||
| Header | Header | | ||
| ------ | ------ | | ||
| Cell | Cell | | ||
> Blockquote | ||
``` | ||
To fix violations of this rule, ensure that all tables have a blank line both | ||
before and after (except when the table is at the very beginning or end of the | ||
document): | ||
```markdown | ||
Some text | ||
| Header | Header | | ||
| ------ | ------ | | ||
| Cell | Cell | | ||
> Blockquote | ||
``` | ||
Note that text immediately following a table (i.e., not separated by an empty | ||
line) is treated as part of the table (per the specification) and will not | ||
trigger this rule: | ||
```markdown | ||
| Header | Header | | ||
| ------ | ------ | | ||
| Cell | Cell | | ||
This text is part of the table and the next line is blank | ||
Some text | ||
``` | ||
Rationale: In addition to aesthetic reasons, some parsers will incorrectly parse | ||
tables that don't have blank lines before and after them. | ||
<!-- markdownlint-configure-file { | ||
@@ -2460,0 +2526,0 @@ "no-inline-html": { |
@@ -21,6 +21,2 @@ // @ts-check | ||
// Regular expressions for range matching | ||
module.exports.listItemMarkerRe = /^([\s>]*)(?:[*+-]|\d+[.)])\s+/; | ||
module.exports.orderedListItemMarkerRe = /^[\s>]*0*(\d+)[.)]/; | ||
// Regular expression for blockquote prefixes | ||
@@ -147,3 +143,2 @@ const blockquotePrefixRe = /^[>\s]*/; | ||
const removeComments = (s) => { | ||
// eslint-disable-next-line no-constant-condition | ||
while (true) { | ||
@@ -175,31 +170,2 @@ const start = s.indexOf(startComment); | ||
/** | ||
* Compare function for Array.prototype.sort for ascending order of numbers. | ||
* | ||
* @param {number} a First number. | ||
* @param {number} b Second number. | ||
* @returns {number} Positive value if a>b, negative value if b<a, 0 otherwise. | ||
*/ | ||
module.exports.numericSortAscending = function numericSortAscending(a, b) { | ||
return a - b; | ||
}; | ||
// Returns true iff the sorted array contains the specified element | ||
module.exports.includesSorted = function includesSorted(array, element) { | ||
let left = 0; | ||
let right = array.length - 1; | ||
while (left <= right) { | ||
// eslint-disable-next-line no-bitwise | ||
const mid = (left + right) >> 1; | ||
if (array[mid] < element) { | ||
left = mid + 1; | ||
} else if (array[mid] > element) { | ||
right = mid - 1; | ||
} else { | ||
return true; | ||
} | ||
} | ||
return false; | ||
}; | ||
// Replaces the content of properly-formatted CommonMark comments with "." | ||
@@ -296,204 +262,2 @@ // This preserves the line/column information for the rest of the document | ||
/** | ||
* Return the number of characters of indent for a token. | ||
* | ||
* @param {Object} token MarkdownItToken instance. | ||
* @returns {number} Characters of indent. | ||
*/ | ||
function indentFor(token) { | ||
const line = token.line.replace(/^[\s>]*(> |>)/, ""); | ||
return line.length - line.trimStart().length; | ||
} | ||
module.exports.indentFor = indentFor; | ||
// Returns the heading style for a heading token | ||
module.exports.headingStyleFor = function headingStyleFor(token) { | ||
if ((token.map[1] - token.map[0]) === 1) { | ||
if (/[^\\]#\s*$/.test(token.line)) { | ||
return "atx_closed"; | ||
} | ||
return "atx"; | ||
} | ||
return "setext"; | ||
}; | ||
/** | ||
* Return the string representation of an unordered list marker. | ||
* | ||
* @param {Object} token MarkdownItToken instance. | ||
* @returns {"asterisk" | "dash" | "plus"} String representation. | ||
*/ | ||
module.exports.unorderedListStyleFor = function unorderedListStyleFor(token) { | ||
switch (token.markup) { | ||
case "-": | ||
return "dash"; | ||
case "+": | ||
return "plus"; | ||
// case "*": | ||
default: | ||
return "asterisk"; | ||
} | ||
}; | ||
/** | ||
* @callback TokenCallback | ||
* @param {MarkdownItToken} token Current token. | ||
* @returns {void} | ||
*/ | ||
/** | ||
* Calls the provided function for each matching token. | ||
* | ||
* @param {Object} params RuleParams instance. | ||
* @param {string} type Token type identifier. | ||
* @param {TokenCallback} handler Callback function. | ||
* @returns {void} | ||
*/ | ||
function filterTokens(params, type, handler) { | ||
for (const token of params.parsers.markdownit.tokens) { | ||
if (token.type === type) { | ||
handler(token); | ||
} | ||
} | ||
} | ||
module.exports.filterTokens = filterTokens; | ||
/** | ||
* @typedef {Array} LineMetadata | ||
*/ | ||
/** | ||
* Gets a line metadata array. | ||
* | ||
* @param {Object} params RuleParams instance. | ||
* @returns {LineMetadata} Line metadata. | ||
*/ | ||
function getLineMetadata(params) { | ||
const lineMetadata = params.lines.map( | ||
(line, index) => [ line, index, false, 0, false, false, false ] | ||
); | ||
filterTokens(params, "fence", (token) => { | ||
lineMetadata[token.map[0]][3] = 1; | ||
lineMetadata[token.map[1] - 1][3] = -1; | ||
for (let i = token.map[0] + 1; i < token.map[1] - 1; i++) { | ||
lineMetadata[i][2] = true; | ||
} | ||
}); | ||
filterTokens(params, "code_block", (token) => { | ||
for (let i = token.map[0]; i < token.map[1]; i++) { | ||
lineMetadata[i][2] = true; | ||
} | ||
}); | ||
filterTokens(params, "table_open", (token) => { | ||
for (let i = token.map[0]; i < token.map[1]; i++) { | ||
lineMetadata[i][4] = true; | ||
} | ||
}); | ||
filterTokens(params, "list_item_open", (token) => { | ||
let count = 1; | ||
for (let i = token.map[0]; i < token.map[1]; i++) { | ||
lineMetadata[i][5] = count; | ||
count++; | ||
} | ||
}); | ||
filterTokens(params, "hr", (token) => { | ||
lineMetadata[token.map[0]][6] = true; | ||
}); | ||
return lineMetadata; | ||
} | ||
module.exports.getLineMetadata = getLineMetadata; | ||
/** | ||
* @callback EachLineCallback | ||
* @param {string} line Line content. | ||
* @param {number} lineIndex Line index (0-based). | ||
* @param {boolean} inCode Iff in a code block. | ||
* @param {number} onFence + if open, - if closed, 0 otherwise. | ||
* @param {boolean} inTable Iff in a table. | ||
* @param {boolean} inItem Iff in a list item. | ||
* @param {boolean} inBreak Iff in semantic break. | ||
* @returns {void} | ||
*/ | ||
/** | ||
* Calls the provided function for each line. | ||
* | ||
* @param {LineMetadata} lineMetadata Line metadata object. | ||
* @param {EachLineCallback} handler Function taking (line, lineIndex, inCode, | ||
* onFence, inTable, inItem, inBreak). | ||
* @returns {void} | ||
*/ | ||
function forEachLine(lineMetadata, handler) { | ||
for (const metadata of lineMetadata) { | ||
// @ts-ignore | ||
handler(...metadata); | ||
} | ||
} | ||
module.exports.forEachLine = forEachLine; | ||
// Returns (nested) lists as a flat array (in order) | ||
module.exports.flattenLists = function flattenLists(tokens) { | ||
const flattenedLists = []; | ||
const stack = []; | ||
let current = null; | ||
let nesting = 0; | ||
const nestingStack = []; | ||
let lastWithMap = { "map": [ 0, 1 ] }; | ||
for (const token of tokens) { | ||
if ((token.type === "bullet_list_open") || | ||
(token.type === "ordered_list_open")) { | ||
// Save current context and start a new one | ||
stack.push(current); | ||
current = { | ||
"unordered": (token.type === "bullet_list_open"), | ||
"parentsUnordered": !current || | ||
(current.unordered && current.parentsUnordered), | ||
"open": token, | ||
"indent": indentFor(token), | ||
"parentIndent": (current && current.indent) || 0, | ||
"items": [], | ||
"nesting": nesting, | ||
"lastLineIndex": -1, | ||
"insert": flattenedLists.length | ||
}; | ||
nesting++; | ||
} else if ((token.type === "bullet_list_close") || | ||
(token.type === "ordered_list_close")) { | ||
// Finalize current context and restore previous | ||
current.lastLineIndex = lastWithMap.map[1]; | ||
flattenedLists.splice(current.insert, 0, current); | ||
delete current.insert; | ||
current = stack.pop(); | ||
nesting--; | ||
} else if (token.type === "list_item_open") { | ||
// Add list item | ||
current.items.push(token); | ||
} else if (token.type === "blockquote_open") { | ||
nestingStack.push(nesting); | ||
nesting = 0; | ||
} else if (token.type === "blockquote_close") { | ||
nesting = nestingStack.pop() || 0; | ||
} | ||
if (token.map) { | ||
// Track last token with map | ||
lastWithMap = token; | ||
} | ||
} | ||
return flattenedLists; | ||
}; | ||
// Calls the provided function for each heading's content | ||
module.exports.forEachHeading = function forEachHeading(params, handler) { | ||
let heading = null; | ||
for (const token of params.parsers.markdownit.tokens) { | ||
if (token.type === "heading_open") { | ||
heading = token; | ||
} else if (token.type === "heading_close") { | ||
heading = null; | ||
} else if ((token.type === "inline") && heading) { | ||
handler(heading, token.content, token); | ||
} | ||
} | ||
}; | ||
/** | ||
* @callback InlineCodeSpanCallback | ||
@@ -603,4 +367,16 @@ * @param {string} code Code content. | ||
// Adds an error object with details conditionally via the onError callback | ||
module.exports.addErrorDetailIf = function addErrorDetailIf( | ||
/** | ||
* Adds an error object with details conditionally via the onError callback. | ||
* | ||
* @param {Object} onError RuleOnError instance. | ||
* @param {number} lineNumber Line number. | ||
* @param {Object} expected Expected value. | ||
* @param {Object} actual Actual value. | ||
* @param {string} [detail] Error details. | ||
* @param {string} [context] Error context. | ||
* @param {number[]} [range] Column and length of error. | ||
* @param {Object} [fixInfo] RuleOnErrorFixInfo instance. | ||
* @returns {void} | ||
*/ | ||
function addErrorDetailIf( | ||
onError, lineNumber, expected, actual, detail, context, range, fixInfo) { | ||
@@ -617,47 +393,51 @@ if (expected !== actual) { | ||
} | ||
}; | ||
} | ||
module.exports.addErrorDetailIf = addErrorDetailIf; | ||
// Adds an error object with context via the onError callback | ||
module.exports.addErrorContext = function addErrorContext( | ||
onError, lineNumber, context, left, right, range, fixInfo) { | ||
context = ellipsify(context, left, right); | ||
/** | ||
* Adds an error object with context via the onError callback. | ||
* | ||
* @param {Object} onError RuleOnError instance. | ||
* @param {number} lineNumber Line number. | ||
* @param {string} context Error context. | ||
* @param {boolean} [start] True iff the start of the text is important. | ||
* @param {boolean} [end] True iff the end of the text is important. | ||
* @param {number[]} [range] Column and length of error. | ||
* @param {Object} [fixInfo] RuleOnErrorFixInfo instance. | ||
* @returns {void} | ||
*/ | ||
function addErrorContext( | ||
onError, lineNumber, context, start, end, range, fixInfo) { | ||
context = ellipsify(context, start, end); | ||
addError(onError, lineNumber, undefined, context, range, fixInfo); | ||
}; | ||
} | ||
module.exports.addErrorContext = addErrorContext; | ||
/** | ||
* Returns an array of code block and span content ranges. | ||
* Adds an error object with context for a construct missing a blank line. | ||
* | ||
* @param {Object} params RuleParams instance. | ||
* @param {Object} lineMetadata Line metadata object. | ||
* @returns {number[][]} Array of ranges (lineIndex, columnIndex, length). | ||
* @param {Object} onError RuleOnError instance. | ||
* @param {string[]} lines Lines of Markdown content. | ||
* @param {number} lineIndex Line index of line. | ||
* @param {number} [lineNumber] Line number for override. | ||
* @returns {void} | ||
*/ | ||
module.exports.codeBlockAndSpanRanges = (params, lineMetadata) => { | ||
const exclusions = []; | ||
// Add code block ranges (excludes fences) | ||
forEachLine(lineMetadata, (line, lineIndex, inCode, onFence) => { | ||
if (inCode && !onFence) { | ||
exclusions.push([ lineIndex, 0, line.length ]); | ||
function addErrorContextForLine(onError, lines, lineIndex, lineNumber) { | ||
const line = lines[lineIndex]; | ||
// @ts-ignore | ||
const quotePrefix = line.match(blockquotePrefixRe)[0].trimEnd(); | ||
addErrorContext( | ||
onError, | ||
lineIndex + 1, | ||
line.trim(), | ||
undefined, | ||
undefined, | ||
undefined, | ||
{ | ||
lineNumber, | ||
"insertText": `${quotePrefix}\n` | ||
} | ||
}); | ||
// Add code span ranges (excludes ticks) | ||
filterTokens(params, "inline", (token) => { | ||
if (token.children.some((child) => child.type === "code_inline")) { | ||
const tokenLines = params.lines.slice(token.map[0], token.map[1]); | ||
forEachInlineCodeSpan( | ||
tokenLines.join("\n"), | ||
(code, lineIndex, columnIndex) => { | ||
const codeLines = code.split(newLineRe); | ||
for (const [ i, line ] of codeLines.entries()) { | ||
exclusions.push([ | ||
token.lineNumber - 1 + lineIndex + i, | ||
i ? 0 : columnIndex, | ||
line.length | ||
]); | ||
} | ||
} | ||
); | ||
} | ||
}); | ||
return exclusions; | ||
}; | ||
); | ||
} | ||
module.exports.addErrorContextForLine = addErrorContextForLine; | ||
@@ -682,14 +462,2 @@ /** | ||
// Returns a range object for a line by applying a RegExp | ||
module.exports.rangeFromRegExp = function rangeFromRegExp(line, regexp) { | ||
let range = null; | ||
const match = line.match(regexp); | ||
if (match) { | ||
const column = match.index + 1; | ||
const length = match[0].length; | ||
range = [ column, length ]; | ||
} | ||
return range; | ||
}; | ||
// Determines if the front matter includes a title | ||
@@ -696,0 +464,0 @@ module.exports.frontMatterHasTitle = |
{ | ||
"name": "markdownlint-rule-helpers", | ||
"version": "0.25.0", | ||
"version": "0.26.0", | ||
"description": "A collection of markdownlint helper functions for custom rules", | ||
@@ -5,0 +5,0 @@ "main": "./helpers.js", |
@@ -22,28 +22,2 @@ # markdownlint-rule-helpers | ||
### Using Helpers from a Custom Rule | ||
```javascript | ||
const { forEachLine, getLineMetadata } = require("markdownlint-rule-helpers"); | ||
/** @type import("markdownlint").Rule */ | ||
module.exports = { | ||
"names": [ "every-n-lines" ], | ||
"description": "Rule that reports an error every N lines", | ||
"tags": [ "test" ], | ||
"parser": "none", | ||
"function": (params, onError) => { | ||
const n = params.config.n || 2; | ||
forEachLine(getLineMetadata(params), (line, lineIndex) => { | ||
const lineNumber = lineIndex + 1; | ||
if ((lineNumber % n) === 0) { | ||
onError({ | ||
"lineNumber": lineNumber, | ||
"detail": "Line number " + lineNumber | ||
}); | ||
} | ||
}); | ||
} | ||
}; | ||
``` | ||
### Applying Recommended Fixes | ||
@@ -68,7 +42,7 @@ | ||
[custom-rules]: https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/CustomRules.md | ||
[custom-rules]: https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/CustomRules.md | ||
[jsdoc]: https://en.m.wikipedia.org/wiki/JSDoc | ||
[lib]: https://github.com/DavidAnson/markdownlint/tree/v0.34.0/lib | ||
[lib]: https://github.com/DavidAnson/markdownlint/tree/v0.35.0/lib | ||
[markdown]: https://en.wikipedia.org/wiki/Markdown | ||
[markdownlint]: https://github.com/DavidAnson/markdownlint | ||
[rules]: https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/Rules.md | ||
[rules]: https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/Rules.md |
@@ -5,18 +5,67 @@ // @ts-check | ||
const helpers = require("../helpers"); | ||
const { filterByTypes } = require("../helpers/micromark.cjs"); | ||
/** @type {Map<string, object>} */ | ||
const map = new Map(); | ||
// eslint-disable-next-line no-undef-init | ||
let params = undefined; | ||
module.exports.set = (keyValuePairs) => { | ||
for (const [ key, value ] of Object.entries(keyValuePairs)) { | ||
map.set(key, value); | ||
/** | ||
* Initializes (resets) the cache. | ||
* | ||
* @param {import("./markdownlint").RuleParams} [p] Rule parameters object. | ||
* @returns {void} | ||
*/ | ||
function initialize(p) { | ||
map.clear(); | ||
params = p; | ||
} | ||
/** | ||
* Gets a cached object value - computes it and caches it. | ||
* | ||
* @param {string} name Cache object name. | ||
* @param {Function} getValue Getter for object value. | ||
* @returns {Object} Object value. | ||
*/ | ||
function getCached(name, getValue) { | ||
if (map.has(name)) { | ||
return map.get(name); | ||
} | ||
const value = getValue(); | ||
map.set(name, value); | ||
return value; | ||
} | ||
/** | ||
* Filters a list of Micromark tokens by type and caches the result. | ||
* | ||
* @param {import("./markdownlint").MicromarkTokenType[]} types Types to allow. | ||
* @param {boolean} [htmlFlow] Whether to include htmlFlow content. | ||
* @returns {import("./markdownlint").MicromarkToken[]} Filtered tokens. | ||
*/ | ||
function filterByTypesCached(types, htmlFlow) { | ||
return getCached( | ||
types.join("|"), | ||
() => filterByTypes(params.parsers.micromark.tokens, types, htmlFlow) | ||
); | ||
} | ||
/** | ||
* Gets a reference link and image data object. | ||
* | ||
* @returns {Object} Reference link and image data object. | ||
*/ | ||
function getReferenceLinkImageData() { | ||
return getCached( | ||
getReferenceLinkImageData.name, | ||
() => helpers.getReferenceLinkImageData(params.parsers.micromark.tokens) | ||
); | ||
} | ||
module.exports = { | ||
initialize, | ||
filterByTypesCached, | ||
getReferenceLinkImageData | ||
}; | ||
module.exports.clear = () => map.clear(); | ||
module.exports.codeBlockAndSpanRanges = | ||
() => map.get("codeBlockAndSpanRanges"); | ||
module.exports.flattenedLists = | ||
() => map.get("flattenedLists"); | ||
module.exports.lineMetadata = | ||
() => map.get("lineMetadata"); | ||
module.exports.referenceLinkImageData = | ||
() => map.get("referenceLinkImageData"); |
@@ -1,1178 +0,8 @@ | ||
/* eslint-disable */ | ||
/** | ||
* This file was automatically generated by json-schema-to-typescript. | ||
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, | ||
* and run json-schema-to-typescript to regenerate this file. | ||
*/ | ||
import { ConfigurationStrict } from "./configuration-strict"; | ||
export interface Configuration { | ||
export interface Configuration extends ConfigurationStrict { | ||
/** | ||
* JSON Schema URI (expected by some editors) | ||
* Index signature for arbitrary custom rules. | ||
*/ | ||
$schema?: string; | ||
/** | ||
* Default state for all rules | ||
*/ | ||
default?: boolean; | ||
/** | ||
* Path to configuration file to extend | ||
*/ | ||
extends?: string | null; | ||
/** | ||
* MD001/heading-increment : Heading levels should only increment by one level at a time : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md001.md | ||
*/ | ||
MD001?: boolean; | ||
/** | ||
* MD001/heading-increment : Heading levels should only increment by one level at a time : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md001.md | ||
*/ | ||
"heading-increment"?: boolean; | ||
/** | ||
* MD003/heading-style : Heading style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md003.md | ||
*/ | ||
MD003?: | ||
| boolean | ||
| { | ||
/** | ||
* Heading style | ||
*/ | ||
style?: "consistent" | "atx" | "atx_closed" | "setext" | "setext_with_atx" | "setext_with_atx_closed"; | ||
}; | ||
/** | ||
* MD003/heading-style : Heading style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md003.md | ||
*/ | ||
"heading-style"?: | ||
| boolean | ||
| { | ||
/** | ||
* Heading style | ||
*/ | ||
style?: "consistent" | "atx" | "atx_closed" | "setext" | "setext_with_atx" | "setext_with_atx_closed"; | ||
}; | ||
/** | ||
* MD004/ul-style : Unordered list style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md004.md | ||
*/ | ||
MD004?: | ||
| boolean | ||
| { | ||
/** | ||
* List style | ||
*/ | ||
style?: "consistent" | "asterisk" | "plus" | "dash" | "sublist"; | ||
}; | ||
/** | ||
* MD004/ul-style : Unordered list style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md004.md | ||
*/ | ||
"ul-style"?: | ||
| boolean | ||
| { | ||
/** | ||
* List style | ||
*/ | ||
style?: "consistent" | "asterisk" | "plus" | "dash" | "sublist"; | ||
}; | ||
/** | ||
* MD005/list-indent : Inconsistent indentation for list items at the same level : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md005.md | ||
*/ | ||
MD005?: boolean; | ||
/** | ||
* MD005/list-indent : Inconsistent indentation for list items at the same level : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md005.md | ||
*/ | ||
"list-indent"?: boolean; | ||
/** | ||
* MD007/ul-indent : Unordered list indentation : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md007.md | ||
*/ | ||
MD007?: | ||
| boolean | ||
| { | ||
/** | ||
* Spaces for indent | ||
*/ | ||
indent?: number; | ||
/** | ||
* Whether to indent the first level of the list | ||
*/ | ||
start_indented?: boolean; | ||
/** | ||
* Spaces for first level indent (when start_indented is set) | ||
*/ | ||
start_indent?: number; | ||
}; | ||
/** | ||
* MD007/ul-indent : Unordered list indentation : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md007.md | ||
*/ | ||
"ul-indent"?: | ||
| boolean | ||
| { | ||
/** | ||
* Spaces for indent | ||
*/ | ||
indent?: number; | ||
/** | ||
* Whether to indent the first level of the list | ||
*/ | ||
start_indented?: boolean; | ||
/** | ||
* Spaces for first level indent (when start_indented is set) | ||
*/ | ||
start_indent?: number; | ||
}; | ||
/** | ||
* MD009/no-trailing-spaces : Trailing spaces : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md009.md | ||
*/ | ||
MD009?: | ||
| boolean | ||
| { | ||
/** | ||
* Spaces for line break | ||
*/ | ||
br_spaces?: number; | ||
/** | ||
* Allow spaces for empty lines in list items | ||
*/ | ||
list_item_empty_lines?: boolean; | ||
/** | ||
* Include unnecessary breaks | ||
*/ | ||
strict?: boolean; | ||
}; | ||
/** | ||
* MD009/no-trailing-spaces : Trailing spaces : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md009.md | ||
*/ | ||
"no-trailing-spaces"?: | ||
| boolean | ||
| { | ||
/** | ||
* Spaces for line break | ||
*/ | ||
br_spaces?: number; | ||
/** | ||
* Allow spaces for empty lines in list items | ||
*/ | ||
list_item_empty_lines?: boolean; | ||
/** | ||
* Include unnecessary breaks | ||
*/ | ||
strict?: boolean; | ||
}; | ||
/** | ||
* MD010/no-hard-tabs : Hard tabs : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md010.md | ||
*/ | ||
MD010?: | ||
| boolean | ||
| { | ||
/** | ||
* Include code blocks | ||
*/ | ||
code_blocks?: boolean; | ||
/** | ||
* Fenced code languages to ignore | ||
*/ | ||
ignore_code_languages?: string[]; | ||
/** | ||
* Number of spaces for each hard tab | ||
*/ | ||
spaces_per_tab?: number; | ||
}; | ||
/** | ||
* MD010/no-hard-tabs : Hard tabs : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md010.md | ||
*/ | ||
"no-hard-tabs"?: | ||
| boolean | ||
| { | ||
/** | ||
* Include code blocks | ||
*/ | ||
code_blocks?: boolean; | ||
/** | ||
* Fenced code languages to ignore | ||
*/ | ||
ignore_code_languages?: string[]; | ||
/** | ||
* Number of spaces for each hard tab | ||
*/ | ||
spaces_per_tab?: number; | ||
}; | ||
/** | ||
* MD011/no-reversed-links : Reversed link syntax : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md011.md | ||
*/ | ||
MD011?: boolean; | ||
/** | ||
* MD011/no-reversed-links : Reversed link syntax : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md011.md | ||
*/ | ||
"no-reversed-links"?: boolean; | ||
/** | ||
* MD012/no-multiple-blanks : Multiple consecutive blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md012.md | ||
*/ | ||
MD012?: | ||
| boolean | ||
| { | ||
/** | ||
* Consecutive blank lines | ||
*/ | ||
maximum?: number; | ||
}; | ||
/** | ||
* MD012/no-multiple-blanks : Multiple consecutive blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md012.md | ||
*/ | ||
"no-multiple-blanks"?: | ||
| boolean | ||
| { | ||
/** | ||
* Consecutive blank lines | ||
*/ | ||
maximum?: number; | ||
}; | ||
/** | ||
* MD013/line-length : Line length : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md | ||
*/ | ||
MD013?: | ||
| boolean | ||
| { | ||
/** | ||
* Number of characters | ||
*/ | ||
line_length?: number; | ||
/** | ||
* Number of characters for headings | ||
*/ | ||
heading_line_length?: number; | ||
/** | ||
* Number of characters for code blocks | ||
*/ | ||
code_block_line_length?: number; | ||
/** | ||
* Include code blocks | ||
*/ | ||
code_blocks?: boolean; | ||
/** | ||
* Include tables | ||
*/ | ||
tables?: boolean; | ||
/** | ||
* Include headings | ||
*/ | ||
headings?: boolean; | ||
/** | ||
* Strict length checking | ||
*/ | ||
strict?: boolean; | ||
/** | ||
* Stern length checking | ||
*/ | ||
stern?: boolean; | ||
}; | ||
/** | ||
* MD013/line-length : Line length : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md | ||
*/ | ||
"line-length"?: | ||
| boolean | ||
| { | ||
/** | ||
* Number of characters | ||
*/ | ||
line_length?: number; | ||
/** | ||
* Number of characters for headings | ||
*/ | ||
heading_line_length?: number; | ||
/** | ||
* Number of characters for code blocks | ||
*/ | ||
code_block_line_length?: number; | ||
/** | ||
* Include code blocks | ||
*/ | ||
code_blocks?: boolean; | ||
/** | ||
* Include tables | ||
*/ | ||
tables?: boolean; | ||
/** | ||
* Include headings | ||
*/ | ||
headings?: boolean; | ||
/** | ||
* Strict length checking | ||
*/ | ||
strict?: boolean; | ||
/** | ||
* Stern length checking | ||
*/ | ||
stern?: boolean; | ||
}; | ||
/** | ||
* MD014/commands-show-output : Dollar signs used before commands without showing output : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md014.md | ||
*/ | ||
MD014?: boolean; | ||
/** | ||
* MD014/commands-show-output : Dollar signs used before commands without showing output : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md014.md | ||
*/ | ||
"commands-show-output"?: boolean; | ||
/** | ||
* MD018/no-missing-space-atx : No space after hash on atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md018.md | ||
*/ | ||
MD018?: boolean; | ||
/** | ||
* MD018/no-missing-space-atx : No space after hash on atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md018.md | ||
*/ | ||
"no-missing-space-atx"?: boolean; | ||
/** | ||
* MD019/no-multiple-space-atx : Multiple spaces after hash on atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md019.md | ||
*/ | ||
MD019?: boolean; | ||
/** | ||
* MD019/no-multiple-space-atx : Multiple spaces after hash on atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md019.md | ||
*/ | ||
"no-multiple-space-atx"?: boolean; | ||
/** | ||
* MD020/no-missing-space-closed-atx : No space inside hashes on closed atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md020.md | ||
*/ | ||
MD020?: boolean; | ||
/** | ||
* MD020/no-missing-space-closed-atx : No space inside hashes on closed atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md020.md | ||
*/ | ||
"no-missing-space-closed-atx"?: boolean; | ||
/** | ||
* MD021/no-multiple-space-closed-atx : Multiple spaces inside hashes on closed atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md021.md | ||
*/ | ||
MD021?: boolean; | ||
/** | ||
* MD021/no-multiple-space-closed-atx : Multiple spaces inside hashes on closed atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md021.md | ||
*/ | ||
"no-multiple-space-closed-atx"?: boolean; | ||
/** | ||
* MD022/blanks-around-headings : Headings should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md022.md | ||
*/ | ||
MD022?: | ||
| boolean | ||
| { | ||
/** | ||
* Blank lines above heading | ||
*/ | ||
lines_above?: number | number[]; | ||
/** | ||
* Blank lines below heading | ||
*/ | ||
lines_below?: number | number[]; | ||
}; | ||
/** | ||
* MD022/blanks-around-headings : Headings should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md022.md | ||
*/ | ||
"blanks-around-headings"?: | ||
| boolean | ||
| { | ||
/** | ||
* Blank lines above heading | ||
*/ | ||
lines_above?: number | number[]; | ||
/** | ||
* Blank lines below heading | ||
*/ | ||
lines_below?: number | number[]; | ||
}; | ||
/** | ||
* MD023/heading-start-left : Headings must start at the beginning of the line : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md023.md | ||
*/ | ||
MD023?: boolean; | ||
/** | ||
* MD023/heading-start-left : Headings must start at the beginning of the line : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md023.md | ||
*/ | ||
"heading-start-left"?: boolean; | ||
/** | ||
* MD024/no-duplicate-heading : Multiple headings with the same content : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md024.md | ||
*/ | ||
MD024?: | ||
| boolean | ||
| { | ||
/** | ||
* Only check sibling headings | ||
*/ | ||
siblings_only?: boolean; | ||
}; | ||
/** | ||
* MD024/no-duplicate-heading : Multiple headings with the same content : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md024.md | ||
*/ | ||
"no-duplicate-heading"?: | ||
| boolean | ||
| { | ||
/** | ||
* Only check sibling headings | ||
*/ | ||
siblings_only?: boolean; | ||
}; | ||
/** | ||
* MD025/single-title/single-h1 : Multiple top-level headings in the same document : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md025.md | ||
*/ | ||
MD025?: | ||
| boolean | ||
| { | ||
/** | ||
* Heading level | ||
*/ | ||
level?: number; | ||
/** | ||
* RegExp for matching title in front matter | ||
*/ | ||
front_matter_title?: string; | ||
}; | ||
/** | ||
* MD025/single-title/single-h1 : Multiple top-level headings in the same document : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md025.md | ||
*/ | ||
"single-title"?: | ||
| boolean | ||
| { | ||
/** | ||
* Heading level | ||
*/ | ||
level?: number; | ||
/** | ||
* RegExp for matching title in front matter | ||
*/ | ||
front_matter_title?: string; | ||
}; | ||
/** | ||
* MD025/single-title/single-h1 : Multiple top-level headings in the same document : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md025.md | ||
*/ | ||
"single-h1"?: | ||
| boolean | ||
| { | ||
/** | ||
* Heading level | ||
*/ | ||
level?: number; | ||
/** | ||
* RegExp for matching title in front matter | ||
*/ | ||
front_matter_title?: string; | ||
}; | ||
/** | ||
* MD026/no-trailing-punctuation : Trailing punctuation in heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md026.md | ||
*/ | ||
MD026?: | ||
| boolean | ||
| { | ||
/** | ||
* Punctuation characters | ||
*/ | ||
punctuation?: string; | ||
}; | ||
/** | ||
* MD026/no-trailing-punctuation : Trailing punctuation in heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md026.md | ||
*/ | ||
"no-trailing-punctuation"?: | ||
| boolean | ||
| { | ||
/** | ||
* Punctuation characters | ||
*/ | ||
punctuation?: string; | ||
}; | ||
/** | ||
* MD027/no-multiple-space-blockquote : Multiple spaces after blockquote symbol : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md027.md | ||
*/ | ||
MD027?: boolean; | ||
/** | ||
* MD027/no-multiple-space-blockquote : Multiple spaces after blockquote symbol : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md027.md | ||
*/ | ||
"no-multiple-space-blockquote"?: boolean; | ||
/** | ||
* MD028/no-blanks-blockquote : Blank line inside blockquote : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md028.md | ||
*/ | ||
MD028?: boolean; | ||
/** | ||
* MD028/no-blanks-blockquote : Blank line inside blockquote : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md028.md | ||
*/ | ||
"no-blanks-blockquote"?: boolean; | ||
/** | ||
* MD029/ol-prefix : Ordered list item prefix : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md029.md | ||
*/ | ||
MD029?: | ||
| boolean | ||
| { | ||
/** | ||
* List style | ||
*/ | ||
style?: "one" | "ordered" | "one_or_ordered" | "zero"; | ||
}; | ||
/** | ||
* MD029/ol-prefix : Ordered list item prefix : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md029.md | ||
*/ | ||
"ol-prefix"?: | ||
| boolean | ||
| { | ||
/** | ||
* List style | ||
*/ | ||
style?: "one" | "ordered" | "one_or_ordered" | "zero"; | ||
}; | ||
/** | ||
* MD030/list-marker-space : Spaces after list markers : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md030.md | ||
*/ | ||
MD030?: | ||
| boolean | ||
| { | ||
/** | ||
* Spaces for single-line unordered list items | ||
*/ | ||
ul_single?: number; | ||
/** | ||
* Spaces for single-line ordered list items | ||
*/ | ||
ol_single?: number; | ||
/** | ||
* Spaces for multi-line unordered list items | ||
*/ | ||
ul_multi?: number; | ||
/** | ||
* Spaces for multi-line ordered list items | ||
*/ | ||
ol_multi?: number; | ||
}; | ||
/** | ||
* MD030/list-marker-space : Spaces after list markers : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md030.md | ||
*/ | ||
"list-marker-space"?: | ||
| boolean | ||
| { | ||
/** | ||
* Spaces for single-line unordered list items | ||
*/ | ||
ul_single?: number; | ||
/** | ||
* Spaces for single-line ordered list items | ||
*/ | ||
ol_single?: number; | ||
/** | ||
* Spaces for multi-line unordered list items | ||
*/ | ||
ul_multi?: number; | ||
/** | ||
* Spaces for multi-line ordered list items | ||
*/ | ||
ol_multi?: number; | ||
}; | ||
/** | ||
* MD031/blanks-around-fences : Fenced code blocks should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md031.md | ||
*/ | ||
MD031?: | ||
| boolean | ||
| { | ||
/** | ||
* Include list items | ||
*/ | ||
list_items?: boolean; | ||
}; | ||
/** | ||
* MD031/blanks-around-fences : Fenced code blocks should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md031.md | ||
*/ | ||
"blanks-around-fences"?: | ||
| boolean | ||
| { | ||
/** | ||
* Include list items | ||
*/ | ||
list_items?: boolean; | ||
}; | ||
/** | ||
* MD032/blanks-around-lists : Lists should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md032.md | ||
*/ | ||
MD032?: boolean; | ||
/** | ||
* MD032/blanks-around-lists : Lists should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md032.md | ||
*/ | ||
"blanks-around-lists"?: boolean; | ||
/** | ||
* MD033/no-inline-html : Inline HTML : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md033.md | ||
*/ | ||
MD033?: | ||
| boolean | ||
| { | ||
/** | ||
* Allowed elements | ||
*/ | ||
allowed_elements?: string[]; | ||
}; | ||
/** | ||
* MD033/no-inline-html : Inline HTML : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md033.md | ||
*/ | ||
"no-inline-html"?: | ||
| boolean | ||
| { | ||
/** | ||
* Allowed elements | ||
*/ | ||
allowed_elements?: string[]; | ||
}; | ||
/** | ||
* MD034/no-bare-urls : Bare URL used : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md034.md | ||
*/ | ||
MD034?: boolean; | ||
/** | ||
* MD034/no-bare-urls : Bare URL used : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md034.md | ||
*/ | ||
"no-bare-urls"?: boolean; | ||
/** | ||
* MD035/hr-style : Horizontal rule style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md035.md | ||
*/ | ||
MD035?: | ||
| boolean | ||
| { | ||
/** | ||
* Horizontal rule style | ||
*/ | ||
style?: string; | ||
}; | ||
/** | ||
* MD035/hr-style : Horizontal rule style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md035.md | ||
*/ | ||
"hr-style"?: | ||
| boolean | ||
| { | ||
/** | ||
* Horizontal rule style | ||
*/ | ||
style?: string; | ||
}; | ||
/** | ||
* MD036/no-emphasis-as-heading : Emphasis used instead of a heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md036.md | ||
*/ | ||
MD036?: | ||
| boolean | ||
| { | ||
/** | ||
* Punctuation characters | ||
*/ | ||
punctuation?: string; | ||
}; | ||
/** | ||
* MD036/no-emphasis-as-heading : Emphasis used instead of a heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md036.md | ||
*/ | ||
"no-emphasis-as-heading"?: | ||
| boolean | ||
| { | ||
/** | ||
* Punctuation characters | ||
*/ | ||
punctuation?: string; | ||
}; | ||
/** | ||
* MD037/no-space-in-emphasis : Spaces inside emphasis markers : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md037.md | ||
*/ | ||
MD037?: boolean; | ||
/** | ||
* MD037/no-space-in-emphasis : Spaces inside emphasis markers : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md037.md | ||
*/ | ||
"no-space-in-emphasis"?: boolean; | ||
/** | ||
* MD038/no-space-in-code : Spaces inside code span elements : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md038.md | ||
*/ | ||
MD038?: boolean; | ||
/** | ||
* MD038/no-space-in-code : Spaces inside code span elements : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md038.md | ||
*/ | ||
"no-space-in-code"?: boolean; | ||
/** | ||
* MD039/no-space-in-links : Spaces inside link text : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md039.md | ||
*/ | ||
MD039?: boolean; | ||
/** | ||
* MD039/no-space-in-links : Spaces inside link text : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md039.md | ||
*/ | ||
"no-space-in-links"?: boolean; | ||
/** | ||
* MD040/fenced-code-language : Fenced code blocks should have a language specified : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md040.md | ||
*/ | ||
MD040?: | ||
| boolean | ||
| { | ||
/** | ||
* List of languages | ||
*/ | ||
allowed_languages?: string[]; | ||
/** | ||
* Require language only | ||
*/ | ||
language_only?: boolean; | ||
}; | ||
/** | ||
* MD040/fenced-code-language : Fenced code blocks should have a language specified : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md040.md | ||
*/ | ||
"fenced-code-language"?: | ||
| boolean | ||
| { | ||
/** | ||
* List of languages | ||
*/ | ||
allowed_languages?: string[]; | ||
/** | ||
* Require language only | ||
*/ | ||
language_only?: boolean; | ||
}; | ||
/** | ||
* MD041/first-line-heading/first-line-h1 : First line in a file should be a top-level heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md041.md | ||
*/ | ||
MD041?: | ||
| boolean | ||
| { | ||
/** | ||
* Heading level | ||
*/ | ||
level?: number; | ||
/** | ||
* RegExp for matching title in front matter | ||
*/ | ||
front_matter_title?: string; | ||
}; | ||
/** | ||
* MD041/first-line-heading/first-line-h1 : First line in a file should be a top-level heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md041.md | ||
*/ | ||
"first-line-heading"?: | ||
| boolean | ||
| { | ||
/** | ||
* Heading level | ||
*/ | ||
level?: number; | ||
/** | ||
* RegExp for matching title in front matter | ||
*/ | ||
front_matter_title?: string; | ||
}; | ||
/** | ||
* MD041/first-line-heading/first-line-h1 : First line in a file should be a top-level heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md041.md | ||
*/ | ||
"first-line-h1"?: | ||
| boolean | ||
| { | ||
/** | ||
* Heading level | ||
*/ | ||
level?: number; | ||
/** | ||
* RegExp for matching title in front matter | ||
*/ | ||
front_matter_title?: string; | ||
}; | ||
/** | ||
* MD042/no-empty-links : No empty links : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md042.md | ||
*/ | ||
MD042?: boolean; | ||
/** | ||
* MD042/no-empty-links : No empty links : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md042.md | ||
*/ | ||
"no-empty-links"?: boolean; | ||
/** | ||
* MD043/required-headings : Required heading structure : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md043.md | ||
*/ | ||
MD043?: | ||
| boolean | ||
| { | ||
/** | ||
* List of headings | ||
*/ | ||
headings?: string[]; | ||
/** | ||
* Match case of headings | ||
*/ | ||
match_case?: boolean; | ||
}; | ||
/** | ||
* MD043/required-headings : Required heading structure : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md043.md | ||
*/ | ||
"required-headings"?: | ||
| boolean | ||
| { | ||
/** | ||
* List of headings | ||
*/ | ||
headings?: string[]; | ||
/** | ||
* Match case of headings | ||
*/ | ||
match_case?: boolean; | ||
}; | ||
/** | ||
* MD044/proper-names : Proper names should have the correct capitalization : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md044.md | ||
*/ | ||
MD044?: | ||
| boolean | ||
| { | ||
/** | ||
* List of proper names | ||
*/ | ||
names?: string[]; | ||
/** | ||
* Include code blocks | ||
*/ | ||
code_blocks?: boolean; | ||
/** | ||
* Include HTML elements | ||
*/ | ||
html_elements?: boolean; | ||
}; | ||
/** | ||
* MD044/proper-names : Proper names should have the correct capitalization : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md044.md | ||
*/ | ||
"proper-names"?: | ||
| boolean | ||
| { | ||
/** | ||
* List of proper names | ||
*/ | ||
names?: string[]; | ||
/** | ||
* Include code blocks | ||
*/ | ||
code_blocks?: boolean; | ||
/** | ||
* Include HTML elements | ||
*/ | ||
html_elements?: boolean; | ||
}; | ||
/** | ||
* MD045/no-alt-text : Images should have alternate text (alt text) : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md045.md | ||
*/ | ||
MD045?: boolean; | ||
/** | ||
* MD045/no-alt-text : Images should have alternate text (alt text) : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md045.md | ||
*/ | ||
"no-alt-text"?: boolean; | ||
/** | ||
* MD046/code-block-style : Code block style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md046.md | ||
*/ | ||
MD046?: | ||
| boolean | ||
| { | ||
/** | ||
* Block style | ||
*/ | ||
style?: "consistent" | "fenced" | "indented"; | ||
}; | ||
/** | ||
* MD046/code-block-style : Code block style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md046.md | ||
*/ | ||
"code-block-style"?: | ||
| boolean | ||
| { | ||
/** | ||
* Block style | ||
*/ | ||
style?: "consistent" | "fenced" | "indented"; | ||
}; | ||
/** | ||
* MD047/single-trailing-newline : Files should end with a single newline character : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md047.md | ||
*/ | ||
MD047?: boolean; | ||
/** | ||
* MD047/single-trailing-newline : Files should end with a single newline character : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md047.md | ||
*/ | ||
"single-trailing-newline"?: boolean; | ||
/** | ||
* MD048/code-fence-style : Code fence style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md048.md | ||
*/ | ||
MD048?: | ||
| boolean | ||
| { | ||
/** | ||
* Code fence style | ||
*/ | ||
style?: "consistent" | "backtick" | "tilde"; | ||
}; | ||
/** | ||
* MD048/code-fence-style : Code fence style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md048.md | ||
*/ | ||
"code-fence-style"?: | ||
| boolean | ||
| { | ||
/** | ||
* Code fence style | ||
*/ | ||
style?: "consistent" | "backtick" | "tilde"; | ||
}; | ||
/** | ||
* MD049/emphasis-style : Emphasis style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md049.md | ||
*/ | ||
MD049?: | ||
| boolean | ||
| { | ||
/** | ||
* Emphasis style | ||
*/ | ||
style?: "consistent" | "asterisk" | "underscore"; | ||
}; | ||
/** | ||
* MD049/emphasis-style : Emphasis style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md049.md | ||
*/ | ||
"emphasis-style"?: | ||
| boolean | ||
| { | ||
/** | ||
* Emphasis style | ||
*/ | ||
style?: "consistent" | "asterisk" | "underscore"; | ||
}; | ||
/** | ||
* MD050/strong-style : Strong style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md050.md | ||
*/ | ||
MD050?: | ||
| boolean | ||
| { | ||
/** | ||
* Strong style | ||
*/ | ||
style?: "consistent" | "asterisk" | "underscore"; | ||
}; | ||
/** | ||
* MD050/strong-style : Strong style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md050.md | ||
*/ | ||
"strong-style"?: | ||
| boolean | ||
| { | ||
/** | ||
* Strong style | ||
*/ | ||
style?: "consistent" | "asterisk" | "underscore"; | ||
}; | ||
/** | ||
* MD051/link-fragments : Link fragments should be valid : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md051.md | ||
*/ | ||
MD051?: boolean; | ||
/** | ||
* MD051/link-fragments : Link fragments should be valid : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md051.md | ||
*/ | ||
"link-fragments"?: boolean; | ||
/** | ||
* MD052/reference-links-images : Reference links and images should use a label that is defined : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md052.md | ||
*/ | ||
MD052?: | ||
| boolean | ||
| { | ||
/** | ||
* Include shortcut syntax | ||
*/ | ||
shortcut_syntax?: boolean; | ||
}; | ||
/** | ||
* MD052/reference-links-images : Reference links and images should use a label that is defined : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md052.md | ||
*/ | ||
"reference-links-images"?: | ||
| boolean | ||
| { | ||
/** | ||
* Include shortcut syntax | ||
*/ | ||
shortcut_syntax?: boolean; | ||
}; | ||
/** | ||
* MD053/link-image-reference-definitions : Link and image reference definitions should be needed : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md053.md | ||
*/ | ||
MD053?: | ||
| boolean | ||
| { | ||
/** | ||
* Ignored definitions | ||
*/ | ||
ignored_definitions?: string[]; | ||
}; | ||
/** | ||
* MD053/link-image-reference-definitions : Link and image reference definitions should be needed : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md053.md | ||
*/ | ||
"link-image-reference-definitions"?: | ||
| boolean | ||
| { | ||
/** | ||
* Ignored definitions | ||
*/ | ||
ignored_definitions?: string[]; | ||
}; | ||
/** | ||
* MD054/link-image-style : Link and image style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md054.md | ||
*/ | ||
MD054?: | ||
| boolean | ||
| { | ||
/** | ||
* Allow autolinks | ||
*/ | ||
autolink?: boolean; | ||
/** | ||
* Allow inline links and images | ||
*/ | ||
inline?: boolean; | ||
/** | ||
* Allow full reference links and images | ||
*/ | ||
full?: boolean; | ||
/** | ||
* Allow collapsed reference links and images | ||
*/ | ||
collapsed?: boolean; | ||
/** | ||
* Allow shortcut reference links and images | ||
*/ | ||
shortcut?: boolean; | ||
/** | ||
* Allow URLs as inline links | ||
*/ | ||
url_inline?: boolean; | ||
}; | ||
/** | ||
* MD054/link-image-style : Link and image style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md054.md | ||
*/ | ||
"link-image-style"?: | ||
| boolean | ||
| { | ||
/** | ||
* Allow autolinks | ||
*/ | ||
autolink?: boolean; | ||
/** | ||
* Allow inline links and images | ||
*/ | ||
inline?: boolean; | ||
/** | ||
* Allow full reference links and images | ||
*/ | ||
full?: boolean; | ||
/** | ||
* Allow collapsed reference links and images | ||
*/ | ||
collapsed?: boolean; | ||
/** | ||
* Allow shortcut reference links and images | ||
*/ | ||
shortcut?: boolean; | ||
/** | ||
* Allow URLs as inline links | ||
*/ | ||
url_inline?: boolean; | ||
}; | ||
/** | ||
* MD055/table-pipe-style : Table pipe style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md055.md | ||
*/ | ||
MD055?: | ||
| boolean | ||
| { | ||
/** | ||
* Table pipe style | ||
*/ | ||
style?: "consistent" | "leading_only" | "trailing_only" | "leading_and_trailing" | "no_leading_or_trailing"; | ||
}; | ||
/** | ||
* MD055/table-pipe-style : Table pipe style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md055.md | ||
*/ | ||
"table-pipe-style"?: | ||
| boolean | ||
| { | ||
/** | ||
* Table pipe style | ||
*/ | ||
style?: "consistent" | "leading_only" | "trailing_only" | "leading_and_trailing" | "no_leading_or_trailing"; | ||
}; | ||
/** | ||
* MD056/table-column-count : Table column count : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md056.md | ||
*/ | ||
MD056?: boolean; | ||
/** | ||
* MD056/table-column-count : Table column count : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md056.md | ||
*/ | ||
"table-column-count"?: boolean; | ||
/** | ||
* headings : MD001, MD003, MD018, MD019, MD020, MD021, MD022, MD023, MD024, MD025, MD026, MD036, MD041, MD043 | ||
*/ | ||
headings?: boolean; | ||
/** | ||
* bullet : MD004, MD005, MD007, MD032 | ||
*/ | ||
bullet?: boolean; | ||
/** | ||
* ul : MD004, MD005, MD007, MD030, MD032 | ||
*/ | ||
ul?: boolean; | ||
/** | ||
* indentation : MD005, MD007, MD027 | ||
*/ | ||
indentation?: boolean; | ||
/** | ||
* whitespace : MD009, MD010, MD012, MD027, MD028, MD030, MD037, MD038, MD039 | ||
*/ | ||
whitespace?: boolean; | ||
/** | ||
* hard_tab : MD010 | ||
*/ | ||
hard_tab?: boolean; | ||
/** | ||
* links : MD011, MD034, MD039, MD042, MD051, MD052, MD053, MD054 | ||
*/ | ||
links?: boolean; | ||
/** | ||
* blank_lines : MD012, MD022, MD031, MD032, MD047 | ||
*/ | ||
blank_lines?: boolean; | ||
/** | ||
* line_length : MD013 | ||
*/ | ||
line_length?: boolean; | ||
/** | ||
* code : MD014, MD031, MD038, MD040, MD046, MD048 | ||
*/ | ||
code?: boolean; | ||
/** | ||
* atx : MD018, MD019 | ||
*/ | ||
atx?: boolean; | ||
/** | ||
* spaces : MD018, MD019, MD020, MD021, MD023 | ||
*/ | ||
spaces?: boolean; | ||
/** | ||
* atx_closed : MD020, MD021 | ||
*/ | ||
atx_closed?: boolean; | ||
/** | ||
* blockquote : MD027, MD028 | ||
*/ | ||
blockquote?: boolean; | ||
/** | ||
* ol : MD029, MD030, MD032 | ||
*/ | ||
ol?: boolean; | ||
/** | ||
* html : MD033 | ||
*/ | ||
html?: boolean; | ||
/** | ||
* url : MD034 | ||
*/ | ||
url?: boolean; | ||
/** | ||
* hr : MD035 | ||
*/ | ||
hr?: boolean; | ||
/** | ||
* emphasis : MD036, MD037, MD049, MD050 | ||
*/ | ||
emphasis?: boolean; | ||
/** | ||
* language : MD040 | ||
*/ | ||
language?: boolean; | ||
/** | ||
* spelling : MD044 | ||
*/ | ||
spelling?: boolean; | ||
/** | ||
* accessibility : MD045 | ||
*/ | ||
accessibility?: boolean; | ||
/** | ||
* images : MD045, MD052, MD053, MD054 | ||
*/ | ||
images?: boolean; | ||
/** | ||
* table : MD055, MD056 | ||
*/ | ||
table?: boolean; | ||
[k: string]: unknown; | ||
} |
@@ -11,5 +11,6 @@ // @ts-check | ||
"MD032", "MD034", "MD037", "MD038", "MD039", "MD044", | ||
"MD047", "MD049", "MD050", "MD051", "MD053", "MD054" | ||
"MD047", "MD049", "MD050", "MD051", "MD053", "MD054", | ||
"MD058" | ||
]; | ||
module.exports.homepage = "https://github.com/DavidAnson/markdownlint"; | ||
module.exports.version = "0.34.0"; | ||
module.exports.version = "0.35.0"; |
@@ -11,60 +11,5 @@ export = markdownlint; | ||
declare namespace markdownlint { | ||
export { markdownlintSync as sync, readConfig, readConfigSync, getVersion, promises, RuleFunction, RuleParams, MarkdownParsers, ParserMarkdownIt, ParserMicromark, MarkdownItToken, MicromarkTokenType, MicromarkToken, RuleOnError, RuleOnErrorInfo, RuleOnErrorFixInfo, Rule, Options, Plugin, ToStringCallback, LintResults, LintError, FixInfo, LintContentCallback, LintCallback, Configuration, RuleConfiguration, ConfigurationParser, ReadConfigCallback, ResolveConfigExtendsCallback }; | ||
export { markdownlintSync as sync, readConfig, readConfigSync, getVersion, promises, GetMarkdownIt, RuleFunction, RuleParams, MarkdownParsers, ParserMarkdownIt, ParserMicromark, MarkdownItToken, MicromarkTokenType, MicromarkToken, RuleOnError, RuleOnErrorInfo, RuleOnErrorFixInfo, Rule, Options, Plugin, ToStringCallback, LintResults, LintError, FixInfo, LintContentCallback, LintCallback, Configuration, ConfigurationStrict, RuleConfiguration, ConfigurationParser, ReadConfigCallback, ResolveConfigExtendsCallback }; | ||
} | ||
/** | ||
* Configuration options. | ||
*/ | ||
type Options = { | ||
/** | ||
* Configuration object. | ||
*/ | ||
config?: Configuration; | ||
/** | ||
* Configuration parsers. | ||
*/ | ||
configParsers?: ConfigurationParser[]; | ||
/** | ||
* Custom rules. | ||
*/ | ||
customRules?: Rule[] | Rule; | ||
/** | ||
* Files to lint. | ||
*/ | ||
files?: string[] | string; | ||
/** | ||
* Front matter pattern. | ||
*/ | ||
frontMatter?: RegExp | null; | ||
/** | ||
* File system implementation. | ||
*/ | ||
fs?: any; | ||
/** | ||
* True to catch exceptions. | ||
*/ | ||
handleRuleFailures?: boolean; | ||
/** | ||
* Additional plugins. | ||
*/ | ||
markdownItPlugins?: Plugin[]; | ||
/** | ||
* True to ignore HTML directives. | ||
*/ | ||
noInlineConfig?: boolean; | ||
/** | ||
* Results object version. | ||
*/ | ||
resultVersion?: number; | ||
/** | ||
* Strings to lint. | ||
*/ | ||
strings?: { | ||
[x: string]: string; | ||
}; | ||
}; | ||
/** | ||
* Called with the result of the lint function. | ||
*/ | ||
type LintCallback = (error: Error | null, results?: LintResults) => void; | ||
/** | ||
* Lint specified Markdown files synchronously. | ||
@@ -109,2 +54,6 @@ * | ||
/** | ||
* Function to get an instance of the markdown-it parser. | ||
*/ | ||
type GetMarkdownIt = () => any; | ||
/** | ||
* Function to implement rule logic. | ||
@@ -360,2 +309,53 @@ */ | ||
/** | ||
* Configuration options. | ||
*/ | ||
type Options = { | ||
/** | ||
* Configuration object. | ||
*/ | ||
config?: Configuration; | ||
/** | ||
* Configuration parsers. | ||
*/ | ||
configParsers?: ConfigurationParser[]; | ||
/** | ||
* Custom rules. | ||
*/ | ||
customRules?: Rule[] | Rule; | ||
/** | ||
* Files to lint. | ||
*/ | ||
files?: string[] | string; | ||
/** | ||
* Front matter pattern. | ||
*/ | ||
frontMatter?: RegExp | null; | ||
/** | ||
* File system implementation. | ||
*/ | ||
fs?: any; | ||
/** | ||
* True to catch exceptions. | ||
*/ | ||
handleRuleFailures?: boolean; | ||
/** | ||
* Additional plugins. | ||
*/ | ||
markdownItPlugins?: Plugin[]; | ||
/** | ||
* True to ignore HTML directives. | ||
*/ | ||
noInlineConfig?: boolean; | ||
/** | ||
* Results object version. | ||
*/ | ||
resultVersion?: number; | ||
/** | ||
* Strings to lint. | ||
*/ | ||
strings?: { | ||
[x: string]: string; | ||
}; | ||
}; | ||
/** | ||
* A markdown-it plugin. | ||
@@ -437,2 +437,6 @@ */ | ||
/** | ||
* Called with the result of the lint function. | ||
*/ | ||
type LintCallback = (error: Error | null, results?: LintResults) => void; | ||
/** | ||
* Configuration object for linting rules. For the JSON schema, see | ||
@@ -443,2 +447,7 @@ * {@link ../schema/markdownlint-config-schema.json}. | ||
/** | ||
* Configuration object for linting rules strictly. For the JSON schema, see | ||
* {@link ../schema/markdownlint-config-schema-strict.json}. | ||
*/ | ||
type ConfigurationStrict = import("./configuration-strict").ConfigurationStrict; | ||
/** | ||
* Rule configuration. | ||
@@ -445,0 +454,0 @@ */ |
@@ -7,3 +7,2 @@ // @ts-check | ||
const { promisify } = require("node:util"); | ||
const markdownit = require("markdown-it"); | ||
const micromark = require("../helpers/micromark.cjs"); | ||
@@ -36,3 +35,3 @@ // const { deprecatedRuleNames } = require("./constants"); | ||
const customIndex = index - rules.length; | ||
// eslint-disable-next-line no-inner-declarations, jsdoc/require-jsdoc | ||
// eslint-disable-next-line jsdoc/require-jsdoc | ||
function newError(property, value) { | ||
@@ -231,3 +230,3 @@ return new Error( | ||
* | ||
* @param {MarkdownItToken[]} tokens Array of markdown-it tokens. | ||
* @param {import("markdown-it").Token[]} tokens Array of markdown-it tokens. | ||
* @param {string[]} lines Lines of Markdown content. | ||
@@ -238,3 +237,7 @@ * @returns {void} | ||
let trMap = null; | ||
for (const token of tokens) { | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type MarkdownItToken[] */ | ||
// @ts-ignore | ||
const markdownItTokens = tokens; | ||
for (const token of markdownItTokens) { | ||
// Provide missing maps for table content | ||
@@ -514,6 +517,14 @@ if (token.type === "tr_open") { | ||
handleInlineConfig(lines, disableLineNextLine); | ||
// Create the list of rules that are used at least once | ||
const enabledRuleList = []; | ||
for (const [ index, ruleName ] of allRuleNames.entries()) { | ||
if (enabledRulesPerLineNumber.some((enabledRulesForLine) => enabledRulesForLine[ruleName])) { | ||
enabledRuleList.push(ruleList[index]); | ||
} | ||
} | ||
// Return results | ||
return { | ||
effectiveConfig, | ||
enabledRulesPerLineNumber | ||
enabledRulesPerLineNumber, | ||
enabledRuleList | ||
}; | ||
@@ -530,3 +541,3 @@ } | ||
* @param {string} content Markdown content. | ||
* @param {Object} md Instance of markdown-it. | ||
* @param {GetMarkdownIt} getMarkdownIt Getter for instance of markdown-it. | ||
* @param {Configuration} config Configuration object. | ||
@@ -546,3 +557,3 @@ * @param {ConfigurationParser[] | null} configParsers Configuration parsers. | ||
content, | ||
md, | ||
getMarkdownIt, | ||
config, | ||
@@ -562,3 +573,3 @@ configParsers, | ||
// Get enabled rules per line (with HTML comments present) | ||
const { effectiveConfig, enabledRulesPerLineNumber } = | ||
const { effectiveConfig, enabledRulesPerLineNumber, enabledRuleList } = | ||
getEnabledRulesPerLineNumber( | ||
@@ -573,4 +584,7 @@ ruleList, | ||
); | ||
const needMarkdownItTokens = enabledRuleList.some( | ||
(rule) => (rule.parser === "markdownit") || (rule.parser === undefined) | ||
); | ||
// Parse content into parser tokens | ||
const markdownitTokens = md.parse(content, {}); | ||
const markdownitTokens = needMarkdownItTokens ? getMarkdownIt().parse(content, {}) : []; | ||
const micromarkTokens = micromark.parse(content); | ||
@@ -602,19 +616,9 @@ // Hide the content of HTML comments from rules | ||
name, | ||
"parsers": parsersMarkdownIt, | ||
"lines": Object.freeze(lines), | ||
"frontMatterLines": Object.freeze(frontMatterLines) | ||
}; | ||
const lineMetadata = | ||
helpers.getLineMetadata(paramsBase); | ||
const codeBlockAndSpanRanges = | ||
helpers.codeBlockAndSpanRanges(paramsBase, lineMetadata); | ||
const flattenedLists = | ||
helpers.flattenLists(markdownitTokens); | ||
const referenceLinkImageData = | ||
helpers.getReferenceLinkImageData(micromarkTokens); | ||
cache.set({ | ||
codeBlockAndSpanRanges, | ||
flattenedLists, | ||
lineMetadata, | ||
referenceLinkImageData | ||
cache.initialize({ | ||
...paramsBase, | ||
"parsers": parsersMicromark, | ||
"config": null | ||
}); | ||
@@ -813,4 +817,4 @@ // Function to run for each rule | ||
// Run all rules | ||
const ruleListAsync = ruleList.filter((rule) => rule.asynchronous); | ||
const ruleListSync = ruleList.filter((rule) => !rule.asynchronous); | ||
const ruleListAsync = enabledRuleList.filter((rule) => rule.asynchronous); | ||
const ruleListSync = enabledRuleList.filter((rule) => !rule.asynchronous); | ||
const ruleListAsyncFirst = [ | ||
@@ -835,3 +839,3 @@ ...ruleListAsync, | ||
} finally { | ||
cache.clear(); | ||
cache.initialize(); | ||
} | ||
@@ -847,3 +851,3 @@ } | ||
* @param {string} file Path of file to lint. | ||
* @param {Object} md Instance of markdown-it. | ||
* @param {GetMarkdownIt} getMarkdownIt Getter for instance of markdown-it. | ||
* @param {Configuration} config Configuration object. | ||
@@ -864,3 +868,3 @@ * @param {ConfigurationParser[] | null} configParsers Configuration parsers. | ||
file, | ||
md, | ||
getMarkdownIt, | ||
config, | ||
@@ -885,3 +889,3 @@ configParsers, | ||
content, | ||
md, | ||
getMarkdownIt, | ||
config, | ||
@@ -951,8 +955,12 @@ configParsers, | ||
3 : options.resultVersion; | ||
const md = markdownit({ "html": true }); | ||
const markdownItPlugins = options.markdownItPlugins || []; | ||
for (const plugin of markdownItPlugins) { | ||
// @ts-ignore | ||
md.use(...plugin); | ||
} | ||
const getMarkdownIt = () => { | ||
const markdownit = require("markdown-it"); | ||
const md = markdownit({ "html": true }); | ||
const markdownItPlugins = options.markdownItPlugins || []; | ||
for (const plugin of markdownItPlugins) { | ||
// @ts-ignore | ||
md.use(...plugin); | ||
} | ||
return md; | ||
}; | ||
const fs = options.fs || require("node:fs"); | ||
@@ -989,3 +997,3 @@ const aliasToRuleNames = mapAliasToRuleNames(ruleList); | ||
currentItem, | ||
md, | ||
getMarkdownIt, | ||
config, | ||
@@ -1009,3 +1017,3 @@ configParsers, | ||
strings[currentItem] || "", | ||
md, | ||
getMarkdownIt, | ||
config, | ||
@@ -1326,2 +1334,9 @@ configParsers, | ||
/** | ||
* Function to get an instance of the markdown-it parser. | ||
* | ||
* @callback GetMarkdownIt | ||
* @returns {import("markdown-it")} | ||
*/ | ||
/** | ||
* Function to implement rule logic. | ||
@@ -1540,2 +1555,9 @@ * | ||
/** | ||
* Configuration object for linting rules strictly. For the JSON schema, see | ||
* {@link ../schema/markdownlint-config-schema-strict.json}. | ||
* | ||
* @typedef {import("./configuration-strict").ConfigurationStrict} ConfigurationStrict | ||
*/ | ||
/** | ||
* Rule configuration object. | ||
@@ -1542,0 +1564,0 @@ * |
@@ -5,3 +5,5 @@ // @ts-check | ||
const { addErrorDetailIf, filterTokens } = require("../helpers"); | ||
const { addErrorDetailIf } = require("../helpers"); | ||
const { getHeadingLevel } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -14,14 +16,18 @@ // eslint-disable-next-line jsdoc/valid-types | ||
"tags": [ "headings" ], | ||
"parser": "markdownit", | ||
"parser": "micromark", | ||
"function": function MD001(params, onError) { | ||
let prevLevel = 0; | ||
filterTokens(params, "heading_open", function forToken(token) { | ||
const level = Number.parseInt(token.tag.slice(1), 10); | ||
if (prevLevel && (level > prevLevel)) { | ||
addErrorDetailIf(onError, token.lineNumber, | ||
"h" + (prevLevel + 1), "h" + level); | ||
let prevLevel = Number.MAX_SAFE_INTEGER; | ||
for (const heading of filterByTypesCached([ "atxHeading", "setextHeading" ])) { | ||
const level = getHeadingLevel(heading); | ||
if (level > prevLevel) { | ||
addErrorDetailIf( | ||
onError, | ||
heading.startLine, | ||
`h${prevLevel + 1}`, | ||
`h${level}` | ||
); | ||
} | ||
prevLevel = level; | ||
}); | ||
} | ||
} | ||
}; |
@@ -5,4 +5,5 @@ // @ts-check | ||
const { addErrorDetailIf, filterTokens, headingStyleFor } = | ||
require("../helpers"); | ||
const { addErrorDetailIf } = require("../helpers"); | ||
const { getHeadingLevel, getHeadingStyle } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -15,7 +16,7 @@ // eslint-disable-next-line jsdoc/valid-types | ||
"tags": [ "headings" ], | ||
"parser": "markdownit", | ||
"parser": "micromark", | ||
"function": function MD003(params, onError) { | ||
let style = String(params.config.style || "consistent"); | ||
filterTokens(params, "heading_open", function forToken(token) { | ||
const styleForToken = headingStyleFor(token); | ||
for (const heading of filterByTypesCached([ "atxHeading", "setextHeading" ])) { | ||
const styleForToken = getHeadingStyle(heading); | ||
if (style === "consistent") { | ||
@@ -25,3 +26,3 @@ style = styleForToken; | ||
if (styleForToken !== style) { | ||
const h12 = /h[12]/.test(token.tag); | ||
const h12 = getHeadingLevel(heading) <= 2; | ||
const setextWithAtx = | ||
@@ -42,8 +43,12 @@ (style === "setext_with_atx") && | ||
} | ||
addErrorDetailIf(onError, token.lineNumber, | ||
expected, styleForToken); | ||
addErrorDetailIf( | ||
onError, | ||
heading.startLine, | ||
expected, | ||
styleForToken | ||
); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
}; |
103
lib/md004.js
@@ -5,7 +5,12 @@ // @ts-check | ||
const { addErrorDetailIf, listItemMarkerRe, unorderedListStyleFor } = | ||
require("../helpers"); | ||
const { flattenedLists } = require("./cache"); | ||
const { addErrorDetailIf } = require("../helpers"); | ||
const { getDescendantsByType, getTokenParentOfType } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
const expectedStyleToMarker = { | ||
const markerToStyle = { | ||
"-": "dash", | ||
"+": "plus", | ||
"*": "asterisk" | ||
}; | ||
const styleToMarker = { | ||
"dash": "-", | ||
@@ -20,3 +25,9 @@ "plus": "+", | ||
}; | ||
const validStyles = Object.keys(expectedStyleToMarker); | ||
const validStyles = new Set([ | ||
"asterisk", | ||
"consistent", | ||
"dash", | ||
"plus", | ||
"sublist" | ||
]); | ||
@@ -29,51 +40,47 @@ // eslint-disable-next-line jsdoc/valid-types | ||
"tags": [ "bullet", "ul" ], | ||
"parser": "none", | ||
"parser": "micromark", | ||
"function": function MD004(params, onError) { | ||
const style = String(params.config.style || "consistent"); | ||
let expectedStyle = style; | ||
let expectedStyle = validStyles.has(style) ? style : "dash"; | ||
const nestingStyles = []; | ||
for (const list of flattenedLists()) { | ||
if (list.unordered) { | ||
if (expectedStyle === "consistent") { | ||
expectedStyle = unorderedListStyleFor(list.items[0]); | ||
for (const listUnordered of filterByTypesCached([ "listUnordered" ])) { | ||
let nesting = 0; | ||
if (style === "sublist") { | ||
/** @type {import("../helpers/micromark.cjs").Token | null} */ | ||
let parent = listUnordered; | ||
// @ts-ignore | ||
while ((parent = getTokenParentOfType(parent, [ "listOrdered", "listUnordered" ]))) { | ||
nesting++; | ||
} | ||
for (const item of list.items) { | ||
const itemStyle = unorderedListStyleFor(item); | ||
if (style === "sublist") { | ||
const nesting = list.nesting; | ||
if (!nestingStyles[nesting]) { | ||
nestingStyles[nesting] = | ||
(itemStyle === nestingStyles[nesting - 1]) ? | ||
differentItemStyle[itemStyle] : | ||
itemStyle; | ||
} | ||
expectedStyle = nestingStyles[nesting]; | ||
} | ||
const listItemMarkers = getDescendantsByType(listUnordered, [ "listItemPrefix", "listItemMarker" ]); | ||
for (const listItemMarker of listItemMarkers) { | ||
const itemStyle = markerToStyle[listItemMarker.text]; | ||
if (style === "sublist") { | ||
if (!nestingStyles[nesting]) { | ||
nestingStyles[nesting] = | ||
(itemStyle === nestingStyles[nesting - 1]) ? | ||
differentItemStyle[itemStyle] : | ||
itemStyle; | ||
} | ||
if (!validStyles.includes(expectedStyle)) { | ||
expectedStyle = validStyles[0]; | ||
expectedStyle = nestingStyles[nesting]; | ||
} else if (expectedStyle === "consistent") { | ||
expectedStyle = itemStyle; | ||
} | ||
const column = listItemMarker.startColumn; | ||
const length = listItemMarker.endColumn - listItemMarker.startColumn; | ||
addErrorDetailIf( | ||
onError, | ||
listItemMarker.startLine, | ||
expectedStyle, | ||
itemStyle, | ||
undefined, | ||
undefined, | ||
[ column, length ], | ||
{ | ||
"editColumn": column, | ||
"deleteCount": length, | ||
"insertText": styleToMarker[expectedStyle] | ||
} | ||
let range = null; | ||
let fixInfo = null; | ||
const match = item.line.match(listItemMarkerRe); | ||
if (match) { | ||
const column = match.index + 1; | ||
const length = match[0].length; | ||
range = [ column, length ]; | ||
fixInfo = { | ||
"editColumn": match[1].length + 1, | ||
"deleteCount": 1, | ||
"insertText": expectedStyleToMarker[expectedStyle] | ||
}; | ||
} | ||
addErrorDetailIf( | ||
onError, | ||
item.lineNumber, | ||
expectedStyle, | ||
itemStyle, | ||
null, | ||
null, | ||
range, | ||
fixInfo | ||
); | ||
} | ||
); | ||
} | ||
@@ -80,0 +87,0 @@ } |
@@ -6,3 +6,3 @@ // @ts-check | ||
const { addError, addErrorDetailIf } = require("../helpers"); | ||
const { filterByTypes, inHtmlFlow } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -17,12 +17,3 @@ // eslint-disable-next-line jsdoc/valid-types | ||
"function": function MD005(params, onError) { | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
const lists = filterByTypes( | ||
micromarkTokens, | ||
[ "listOrdered", "listUnordered" ] | ||
).filter((list) => !inHtmlFlow(list)); | ||
for (const list of lists) { | ||
for (const list of filterByTypesCached([ "listOrdered", "listUnordered" ])) { | ||
const expectedIndent = list.startColumn - 1; | ||
@@ -43,4 +34,4 @@ let expectedEnd = 0; | ||
actualIndent, | ||
null, | ||
null, | ||
undefined, | ||
undefined, | ||
range | ||
@@ -47,0 +38,0 @@ // No fixInfo; MD007 handles this scenario better |
@@ -6,4 +6,4 @@ // @ts-check | ||
const { addErrorDetailIf } = require("../helpers"); | ||
const { filterByTypes, getTokenParentOfType, inHtmlFlow } = | ||
require("../helpers/micromark.cjs"); | ||
const { getTokenParentOfType } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -30,10 +30,5 @@ // eslint-disable-next-line jsdoc/valid-types | ||
const startIndent = Number(params.config.start_indent || indent); | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
const unorderedListNesting = new Map(); | ||
let lastBlockQuotePrefix = null; | ||
const tokens = filterByTypes(micromarkTokens, unorderedListTypes); | ||
const tokens = filterByTypesCached(unorderedListTypes); | ||
for (const token of tokens) { | ||
@@ -48,2 +43,3 @@ const { endColumn, parent, startColumn, startLine, type } = token; | ||
while ( | ||
// @ts-ignore | ||
(current = getTokenParentOfType(current, unorderedParentTypes)) | ||
@@ -63,3 +59,3 @@ ) { | ||
} | ||
} else if (!inHtmlFlow(token)) { | ||
} else { | ||
// listItemPrefix | ||
@@ -66,0 +62,0 @@ const nesting = unorderedListNesting.get(parent); |
@@ -5,5 +5,5 @@ // @ts-check | ||
const { addError, filterTokens, forEachLine, includesSorted, | ||
numericSortAscending } = require("../helpers"); | ||
const { lineMetadata } = require("./cache"); | ||
const { addError } = require("../helpers"); | ||
const { addRangeToSet } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -16,3 +16,3 @@ // eslint-disable-next-line jsdoc/valid-types | ||
"tags": [ "whitespace" ], | ||
"parser": "markdownit", | ||
"parser": "micromark", | ||
"function": function MD009(params, onError) { | ||
@@ -23,42 +23,47 @@ let brSpaces = params.config.br_spaces; | ||
const strict = !!params.config.strict; | ||
const listItemLineNumbers = []; | ||
const codeBlockLineNumbers = new Set(); | ||
for (const codeBlock of filterByTypesCached([ "codeFenced" ])) { | ||
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine + 1, codeBlock.endLine - 1); | ||
} | ||
for (const codeBlock of filterByTypesCached([ "codeIndented" ])) { | ||
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine, codeBlock.endLine); | ||
} | ||
const listItemLineNumbers = new Set(); | ||
if (listItemEmptyLines) { | ||
filterTokens(params, "list_item_open", (token) => { | ||
for (let i = token.map[0]; i < token.map[1]; i++) { | ||
listItemLineNumbers.push(i + 1); | ||
for (const listBlock of filterByTypesCached([ "listOrdered", "listUnordered" ])) { | ||
addRangeToSet(listItemLineNumbers, listBlock.startLine, listBlock.endLine); | ||
let trailingIndent = true; | ||
for (let i = listBlock.children.length - 1; i >= 0; i--) { | ||
const child = listBlock.children[i]; | ||
switch (child.type) { | ||
case "content": | ||
trailingIndent = false; | ||
break; | ||
case "listItemIndent": | ||
if (trailingIndent) { | ||
listItemLineNumbers.delete(child.startLine); | ||
} | ||
break; | ||
case "listItemPrefix": | ||
trailingIndent = true; | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
}); | ||
listItemLineNumbers.sort(numericSortAscending); | ||
} | ||
} | ||
const paragraphLineNumbers = []; | ||
const codeInlineLineNumbers = []; | ||
const paragraphLineNumbers = new Set(); | ||
const codeInlineLineNumbers = new Set(); | ||
if (strict) { | ||
filterTokens(params, "paragraph_open", (token) => { | ||
for (let i = token.map[0]; i < token.map[1] - 1; i++) { | ||
paragraphLineNumbers.push(i + 1); | ||
} | ||
}); | ||
const addLineNumberRange = (start, end) => { | ||
for (let i = start; i < end; i++) { | ||
codeInlineLineNumbers.push(i); | ||
} | ||
}; | ||
filterTokens(params, "inline", (token) => { | ||
let start = 0; | ||
for (const child of token.children) { | ||
if (start > 0) { | ||
addLineNumberRange(start, child.lineNumber); | ||
start = 0; | ||
} | ||
if (child.type === "code_inline") { | ||
start = child.lineNumber; | ||
} | ||
} | ||
if (start > 0) { | ||
addLineNumberRange(start, token.map[1]); | ||
} | ||
}); | ||
for (const paragraph of filterByTypesCached([ "paragraph" ])) { | ||
addRangeToSet(paragraphLineNumbers, paragraph.startLine, paragraph.endLine - 1); | ||
} | ||
for (const codeText of filterByTypesCached([ "codeText" ])) { | ||
addRangeToSet(codeInlineLineNumbers, codeText.startLine, codeText.endLine - 1); | ||
} | ||
} | ||
const expected = (brSpaces < 2) ? 0 : brSpaces; | ||
forEachLine(lineMetadata(), (line, lineIndex, inCode) => { | ||
for (let lineIndex = 0; lineIndex < params.lines.length; lineIndex++) { | ||
const line = params.lines[lineIndex]; | ||
const lineNumber = lineIndex + 1; | ||
@@ -68,9 +73,9 @@ const trailingSpaces = line.length - line.trimEnd().length; | ||
trailingSpaces && | ||
!inCode && | ||
!includesSorted(listItemLineNumbers, lineNumber) && | ||
!codeBlockLineNumbers.has(lineNumber) && | ||
!listItemLineNumbers.has(lineNumber) && | ||
( | ||
(expected !== trailingSpaces) || | ||
(strict && | ||
(!includesSorted(paragraphLineNumbers, lineNumber) || | ||
includesSorted(codeInlineLineNumbers, lineNumber))) | ||
(!paragraphLineNumbers.has(lineNumber) || | ||
codeInlineLineNumbers.has(lineNumber))) | ||
) | ||
@@ -89,6 +94,7 @@ ) { | ||
"deleteCount": trailingSpaces | ||
}); | ||
} | ||
); | ||
} | ||
}); | ||
} | ||
} | ||
}; |
@@ -5,5 +5,5 @@ // @ts-check | ||
const { addError, filterTokens, forEachLine, withinAnyRange } = | ||
require("../helpers"); | ||
const { codeBlockAndSpanRanges, lineMetadata } = require("./cache"); | ||
const { addError, withinAnyRange } = require("../helpers"); | ||
const { getDescendantsByType, getExclusionsForToken } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -18,3 +18,3 @@ const tabRe = /\t+/g; | ||
"tags": [ "whitespace", "hard_tab" ], | ||
"parser": "markdownit", | ||
"parser": "micromark", | ||
"function": function MD010(params, onError) { | ||
@@ -31,36 +31,51 @@ const codeBlocks = params.config.code_blocks; | ||
Math.max(0, Number(spacesPerTab)); | ||
const exclusions = includeCode ? [] : codeBlockAndSpanRanges(); | ||
filterTokens(params, "fence", (token) => { | ||
const language = token.info.trim().toLowerCase(); | ||
if (ignoreCodeLanguages.has(language)) { | ||
for (let i = token.map[0] + 1; i < token.map[1] - 1; i++) { | ||
exclusions.push([ i, 0, params.lines[i].length ]); | ||
} | ||
const exclusions = []; | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").TokenType[] */ | ||
const exclusionTypes = []; | ||
if (includeCode) { | ||
if (ignoreCodeLanguages.size > 0) { | ||
exclusionTypes.push("codeFenced"); | ||
} | ||
} else { | ||
exclusionTypes.push("codeFenced", "codeIndented", "codeText"); | ||
} | ||
const codeTokens = filterByTypesCached(exclusionTypes).filter((token) => { | ||
if ((token.type === "codeFenced") && (ignoreCodeLanguages.size > 0)) { | ||
const fenceInfos = getDescendantsByType(token, [ "codeFencedFence", "codeFencedFenceInfo" ]); | ||
return fenceInfos.every((fenceInfo) => ignoreCodeLanguages.has(fenceInfo.text.toLowerCase())); | ||
} | ||
return true; | ||
}); | ||
forEachLine(lineMetadata(), (line, lineIndex, inCode) => { | ||
if (includeCode || !inCode) { | ||
let match = null; | ||
while ((match = tabRe.exec(line)) !== null) { | ||
const { index } = match; | ||
const column = index + 1; | ||
const length = match[0].length; | ||
if (!withinAnyRange(exclusions, lineIndex, index, length)) { | ||
addError( | ||
onError, | ||
lineIndex + 1, | ||
"Column: " + column, | ||
undefined, | ||
[ column, length ], | ||
{ | ||
"editColumn": column, | ||
"deleteCount": length, | ||
"insertText": "".padEnd(length * spaceMultiplier) | ||
} | ||
); | ||
} | ||
for (const codeToken of codeTokens) { | ||
const exclusionsForToken = getExclusionsForToken(params.lines, codeToken); | ||
if (codeToken.type === "codeFenced") { | ||
exclusionsForToken.pop(); | ||
exclusionsForToken.shift(); | ||
} | ||
exclusions.push(...exclusionsForToken); | ||
} | ||
for (let lineIndex = 0; lineIndex < params.lines.length; lineIndex++) { | ||
const line = params.lines[lineIndex]; | ||
let match = null; | ||
while ((match = tabRe.exec(line)) !== null) { | ||
const column = match.index + 1; | ||
const length = match[0].length; | ||
if (!withinAnyRange(exclusions, lineIndex + 1, column, length)) { | ||
addError( | ||
onError, | ||
lineIndex + 1, | ||
"Column: " + column, | ||
undefined, | ||
[ column, length ], | ||
{ | ||
"editColumn": column, | ||
"deleteCount": length, | ||
"insertText": "".padEnd(length * spaceMultiplier) | ||
} | ||
); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
}; |
@@ -5,4 +5,5 @@ // @ts-check | ||
const { addError, forEachLine, withinAnyRange } = require("../helpers"); | ||
const { codeBlockAndSpanRanges, lineMetadata } = require("./cache"); | ||
const { addError, withinAnyRange } = require("../helpers"); | ||
const { addRangeToSet, getExclusionsForToken } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -18,7 +19,14 @@ const reversedLinkRe = | ||
"tags": [ "links" ], | ||
"parser": "none", | ||
"parser": "micromark", | ||
"function": function MD011(params, onError) { | ||
const exclusions = codeBlockAndSpanRanges(); | ||
forEachLine(lineMetadata(), (line, lineIndex, inCode, onFence) => { | ||
if (!inCode && !onFence) { | ||
const codeBlockLineNumbers = new Set(); | ||
for (const codeBlock of filterByTypesCached([ "codeFenced", "codeIndented" ])) { | ||
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine, codeBlock.endLine); | ||
} | ||
const exclusions = []; | ||
for (const codeText of filterByTypesCached([ "codeText" ])) { | ||
exclusions.push(...getExclusionsForToken(params.lines, codeText)); | ||
} | ||
for (const [ lineIndex, line ] of params.lines.entries()) { | ||
if (!codeBlockLineNumbers.has(lineIndex + 1)) { | ||
let match = null; | ||
@@ -32,3 +40,3 @@ while ((match = reversedLinkRe.exec(line)) !== null) { | ||
!linkDestination.endsWith("\\") && | ||
!withinAnyRange(exclusions, lineIndex, index, length) | ||
!withinAnyRange(exclusions, lineIndex + 1, index, length) | ||
) { | ||
@@ -50,4 +58,4 @@ addError( | ||
} | ||
}); | ||
} | ||
} | ||
}; |
@@ -5,4 +5,5 @@ // @ts-check | ||
const { addErrorDetailIf, forEachLine } = require("../helpers"); | ||
const { lineMetadata } = require("./cache"); | ||
const { addErrorDetailIf } = require("../helpers"); | ||
const { addRangeToSet } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -15,7 +16,13 @@ // eslint-disable-next-line jsdoc/valid-types | ||
"tags": [ "whitespace", "blank_lines" ], | ||
"parser": "none", | ||
"parser": "micromark", | ||
"function": function MD012(params, onError) { | ||
const maximum = Number(params.config.maximum || 1); | ||
const { lines } = params; | ||
const codeBlockLineNumbers = new Set(); | ||
for (const codeBlock of filterByTypesCached([ "codeFenced", "codeIndented" ])) { | ||
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine, codeBlock.endLine); | ||
} | ||
let count = 0; | ||
forEachLine(lineMetadata(), (line, lineIndex, inCode) => { | ||
for (const [ lineIndex, line ] of lines.entries()) { | ||
const inCode = codeBlockLineNumbers.has(lineIndex + 1); | ||
count = (inCode || (line.trim().length > 0)) ? 0 : count + 1; | ||
@@ -28,11 +35,12 @@ if (maximum < count) { | ||
count, | ||
null, | ||
null, | ||
null, | ||
undefined, | ||
undefined, | ||
undefined, | ||
{ | ||
"deleteCount": -1 | ||
}); | ||
} | ||
); | ||
} | ||
}); | ||
} | ||
} | ||
}; |
@@ -5,5 +5,6 @@ // @ts-check | ||
const { addErrorDetailIf, filterTokens, forEachHeading, forEachLine, | ||
includesSorted } = require("../helpers"); | ||
const { lineMetadata, referenceLinkImageData } = require("./cache"); | ||
const { addErrorDetailIf } = require("../helpers"); | ||
const { getReferenceLinkImageData } = require("./cache"); | ||
const { addRangeToSet, getDescendantsByType } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -13,14 +14,3 @@ const longLineRePrefix = "^.{"; | ||
const longLineRePostfixStrict = "}.+$"; | ||
const linkOrImageOnlyLineRe = /^[es]*(?:lT?L|I)[ES]*$/; | ||
const sternModeRe = /^(?:[#>\s]*\s)?\S*$/; | ||
const tokenTypeMap = { | ||
"em_open": "e", | ||
"em_close": "E", | ||
"image": "I", | ||
"link_open": "l", | ||
"link_close": "L", | ||
"strong_open": "s", | ||
"strong_close": "S", | ||
"text": "T" | ||
}; | ||
@@ -33,3 +23,3 @@ // eslint-disable-next-line jsdoc/valid-types | ||
"tags": [ "line_length" ], | ||
"parser": "markdownit", | ||
"parser": "micromark", | ||
"function": function MD013(params, onError) { | ||
@@ -57,22 +47,37 @@ const lineLength = Number(params.config.line_length || 80); | ||
const includeHeadings = (headings === undefined) ? true : !!headings; | ||
const headingLineNumbers = []; | ||
forEachHeading(params, (heading) => { | ||
headingLineNumbers.push(heading.lineNumber); | ||
}); | ||
const linkOnlyLineNumbers = []; | ||
filterTokens(params, "inline", (token) => { | ||
let childTokenTypes = ""; | ||
for (const child of token.children) { | ||
if (child.type !== "text" || child.content !== "") { | ||
childTokenTypes += tokenTypeMap[child.type] || "x"; | ||
} | ||
const headingLineNumbers = new Set(); | ||
for (const heading of filterByTypesCached([ "atxHeading", "setextHeading" ])) { | ||
addRangeToSet(headingLineNumbers, heading.startLine, heading.endLine); | ||
} | ||
const codeBlockLineNumbers = new Set(); | ||
for (const codeBlock of filterByTypesCached([ "codeFenced", "codeIndented" ])) { | ||
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine, codeBlock.endLine); | ||
} | ||
const tableLineNumbers = new Set(); | ||
for (const table of filterByTypesCached([ "table" ])) { | ||
addRangeToSet(tableLineNumbers, table.startLine, table.endLine); | ||
} | ||
const linkLineNumbers = new Set(); | ||
for (const link of filterByTypesCached([ "autolink", "image", "link", "literalAutolink" ])) { | ||
addRangeToSet(linkLineNumbers, link.startLine, link.endLine); | ||
} | ||
const paragraphDataLineNumbers = new Set(); | ||
for (const paragraph of filterByTypesCached([ "paragraph" ])) { | ||
for (const data of getDescendantsByType(paragraph, [ "data" ])) { | ||
addRangeToSet(paragraphDataLineNumbers, data.startLine, data.endLine); | ||
} | ||
if (linkOrImageOnlyLineRe.test(childTokenTypes)) { | ||
linkOnlyLineNumbers.push(token.lineNumber); | ||
} | ||
const linkOnlyLineNumbers = new Set(); | ||
for (const lineNumber of linkLineNumbers) { | ||
if (!paragraphDataLineNumbers.has(lineNumber)) { | ||
linkOnlyLineNumbers.add(lineNumber); | ||
} | ||
}); | ||
const { definitionLineIndices } = referenceLinkImageData(); | ||
forEachLine(lineMetadata(), (line, lineIndex, inCode, onFence, inTable) => { | ||
} | ||
const definitionLineIndices = new Set(getReferenceLinkImageData().definitionLineIndices); | ||
for (let lineIndex = 0; lineIndex < params.lines.length; lineIndex++) { | ||
const line = params.lines[lineIndex]; | ||
const lineNumber = lineIndex + 1; | ||
const isHeading = includesSorted(headingLineNumbers, lineNumber); | ||
const isHeading = headingLineNumbers.has(lineNumber); | ||
const inCode = codeBlockLineNumbers.has(lineNumber); | ||
const inTable = tableLineNumbers.has(lineNumber); | ||
const length = inCode ? | ||
@@ -87,6 +92,6 @@ codeLineLength : | ||
(includeHeadings || !isHeading) && | ||
!includesSorted(definitionLineIndices, lineIndex) && | ||
!definitionLineIndices.has(lineIndex) && | ||
(strict || | ||
(!(stern && sternModeRe.test(line)) && | ||
!includesSorted(linkOnlyLineNumbers, lineNumber))) && | ||
!linkOnlyLineNumbers.has(lineNumber))) && | ||
lengthRe.test(line)) { | ||
@@ -98,8 +103,9 @@ addErrorDetailIf( | ||
line.length, | ||
null, | ||
null, | ||
[ length + 1, line.length - length ]); | ||
undefined, | ||
undefined, | ||
[ length + 1, line.length - length ] | ||
); | ||
} | ||
}); | ||
} | ||
} | ||
}; |
@@ -5,3 +5,5 @@ // @ts-check | ||
const { addErrorContext, filterTokens } = require("../helpers"); | ||
const { addErrorContext } = require("../helpers"); | ||
const { filterByTypes } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -16,44 +18,39 @@ const dollarCommandRe = /^(\s*)(\$\s+)/; | ||
"tags": [ "code" ], | ||
"parser": "markdownit", | ||
"parser": "micromark", | ||
"function": function MD014(params, onError) { | ||
for (const type of [ "code_block", "fence" ]) { | ||
filterTokens(params, type, (token) => { | ||
const margin = (token.type === "fence") ? 1 : 0; | ||
const dollarInstances = []; | ||
let allDollars = true; | ||
for (let i = token.map[0] + margin; i < token.map[1] - margin; i++) { | ||
const line = params.lines[i]; | ||
const lineTrim = line.trim(); | ||
if (lineTrim) { | ||
const match = dollarCommandRe.exec(line); | ||
if (match) { | ||
const column = match[1].length + 1; | ||
const length = match[2].length; | ||
dollarInstances.push([ i, lineTrim, column, length ]); | ||
} else { | ||
allDollars = false; | ||
for (const codeBlock of filterByTypesCached([ "codeFenced", "codeIndented" ])) { | ||
const codeFlowValues = filterByTypes( | ||
codeBlock.children, | ||
[ "codeFlowValue" ] | ||
); | ||
const dollarMatches = codeFlowValues. | ||
map((codeFlowValue) => ({ | ||
"result": codeFlowValue.text.match(dollarCommandRe), | ||
"startColumn": codeFlowValue.startColumn, | ||
"startLine": codeFlowValue.startLine, | ||
"text": codeFlowValue.text | ||
})). | ||
filter((dollarMatch) => dollarMatch.result); | ||
if (dollarMatches.length === codeFlowValues.length) { | ||
for (const dollarMatch of dollarMatches) { | ||
// @ts-ignore | ||
const column = dollarMatch.startColumn + dollarMatch.result[1].length; | ||
// @ts-ignore | ||
const length = dollarMatch.result[2].length; | ||
addErrorContext( | ||
onError, | ||
dollarMatch.startLine, | ||
dollarMatch.text, | ||
undefined, | ||
undefined, | ||
[ column, length ], | ||
{ | ||
"editColumn": column, | ||
"deleteCount": length | ||
} | ||
} | ||
); | ||
} | ||
if (allDollars) { | ||
for (const instance of dollarInstances) { | ||
const [ i, lineTrim, column, length ] = instance; | ||
addErrorContext( | ||
onError, | ||
// @ts-ignore | ||
i + 1, | ||
lineTrim, | ||
null, | ||
null, | ||
[ column, length ], | ||
{ | ||
"editColumn": column, | ||
"deleteCount": length | ||
} | ||
); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
} | ||
}; |
@@ -5,4 +5,5 @@ // @ts-check | ||
const { addErrorContext, forEachLine } = require("../helpers"); | ||
const { lineMetadata } = require("./cache"); | ||
const { addErrorContext } = require("../helpers"); | ||
const { addRangeToSet } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -15,9 +16,16 @@ // eslint-disable-next-line jsdoc/valid-types | ||
"tags": [ "headings", "atx", "spaces" ], | ||
"parser": "none", | ||
"parser": "micromark", | ||
"function": function MD018(params, onError) { | ||
forEachLine(lineMetadata(), (line, lineIndex, inCode) => { | ||
if (!inCode && | ||
const { lines } = params; | ||
const ignoreBlockLineNumbers = new Set(); | ||
for (const ignoreBlock of filterByTypesCached([ "codeFenced", "codeIndented", "htmlFlow" ])) { | ||
addRangeToSet(ignoreBlockLineNumbers, ignoreBlock.startLine, ignoreBlock.endLine); | ||
} | ||
for (const [ lineIndex, line ] of lines.entries()) { | ||
if ( | ||
!ignoreBlockLineNumbers.has(lineIndex + 1) && | ||
/^#+[^# \t]/.test(line) && | ||
!/#\s*$/.test(line) && | ||
!line.startsWith("#️⃣")) { | ||
!line.startsWith("#️⃣") | ||
) { | ||
// @ts-ignore | ||
@@ -29,4 +37,4 @@ const hashCount = /^#+/.exec(line)[0].length; | ||
line.trim(), | ||
null, | ||
null, | ||
undefined, | ||
undefined, | ||
[ 1, hashCount + 1 ], | ||
@@ -39,4 +47,4 @@ { | ||
} | ||
}); | ||
} | ||
} | ||
}; |
@@ -5,4 +5,5 @@ // @ts-check | ||
const { addErrorContext, forEachLine } = require("../helpers"); | ||
const { lineMetadata } = require("./cache"); | ||
const { addErrorContext } = require("../helpers"); | ||
const { addRangeToSet } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -15,6 +16,11 @@ // eslint-disable-next-line jsdoc/valid-types | ||
"tags": [ "headings", "atx_closed", "spaces" ], | ||
"parser": "none", | ||
"parser": "micromark", | ||
"function": function MD020(params, onError) { | ||
forEachLine(lineMetadata(), (line, lineIndex, inCode) => { | ||
if (!inCode) { | ||
const { lines } = params; | ||
const ignoreBlockLineNumbers = new Set(); | ||
for (const ignoreBlock of filterByTypesCached([ "codeFenced", "codeIndented", "htmlFlow" ])) { | ||
addRangeToSet(ignoreBlockLineNumbers, ignoreBlock.startLine, ignoreBlock.endLine); | ||
} | ||
for (const [ lineIndex, line ] of lines.entries()) { | ||
if (!ignoreBlockLineNumbers.has(lineIndex + 1)) { | ||
const match = | ||
@@ -36,3 +42,3 @@ /^(#+)([ \t]*)([^#]*?[^#\\])([ \t]*)((?:\\#)?)(#+)(\s*)$/.exec(line); | ||
const left = !leftSpaceLength; | ||
const right = !rightSpaceLength || rightEscape; | ||
const right = !rightSpaceLength || !!rightEscape; | ||
const rightEscapeReplacement = rightEscape ? `${rightEscape} ` : ""; | ||
@@ -66,4 +72,4 @@ if (left || right) { | ||
} | ||
}); | ||
} | ||
} | ||
}; |
@@ -5,6 +5,5 @@ // @ts-check | ||
const { addErrorDetailIf, blockquotePrefixRe, isBlankLine } = | ||
require("../helpers"); | ||
const { filterByTypes, getHeadingLevel, inHtmlFlow } = | ||
require("../helpers/micromark.cjs"); | ||
const { addErrorDetailIf, blockquotePrefixRe, isBlankLine } = require("../helpers"); | ||
const { getHeadingLevel } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -45,13 +44,4 @@ const defaultLines = 1; | ||
const getLinesBelow = getLinesFunction(params.config.lines_below); | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
const { lines } = params; | ||
const headings = filterByTypes( | ||
micromarkTokens, | ||
[ "atxHeading", "setextHeading" ] | ||
).filter((heading) => !inHtmlFlow(heading)); | ||
for (const heading of headings) { | ||
for (const heading of filterByTypesCached([ "atxHeading", "setextHeading" ])) { | ||
const { startLine, endLine } = heading; | ||
@@ -78,3 +68,3 @@ const line = lines[startLine - 1].trim(); | ||
line, | ||
null, | ||
undefined, | ||
{ | ||
@@ -107,3 +97,3 @@ "insertText": getBlockQuote( | ||
line, | ||
null, | ||
undefined, | ||
{ | ||
@@ -110,0 +100,0 @@ "lineNumber": endLine + 1, |
@@ -5,6 +5,5 @@ // @ts-check | ||
const { addErrorContext, filterTokens } = require("../helpers"); | ||
const { addErrorContext } = require("../helpers"); | ||
const { filterByTypesCached } = require("./cache"); | ||
const spaceBeforeHeadingRe = /^(\s+|[>\s]+\s\s)[^>\s]/; | ||
// eslint-disable-next-line jsdoc/valid-types | ||
@@ -16,28 +15,28 @@ /** @type import("./markdownlint").Rule */ | ||
"tags": [ "headings", "spaces" ], | ||
"parser": "markdownit", | ||
"parser": "micromark", | ||
"function": function MD023(params, onError) { | ||
filterTokens(params, "heading_open", function forToken(token) { | ||
const { lineNumber, line } = token; | ||
const match = line.match(spaceBeforeHeadingRe); | ||
if (match) { | ||
const [ prefixAndFirstChar, prefix ] = match; | ||
let deleteCount = prefix.length; | ||
const prefixLengthNoSpace = prefix.trimEnd().length; | ||
if (prefixLengthNoSpace) { | ||
deleteCount -= prefixLengthNoSpace - 1; | ||
} | ||
const headings = filterByTypesCached([ "atxHeading", "linePrefix", "setextHeading" ]); | ||
for (let i = 0; i < headings.length - 1; i++) { | ||
if ( | ||
(headings[i].type === "linePrefix") && | ||
(headings[i + 1].type !== "linePrefix") && | ||
(headings[i].startLine === headings[i + 1].startLine) | ||
) { | ||
const { endColumn, startColumn, startLine } = headings[i]; | ||
const length = endColumn - startColumn; | ||
addErrorContext( | ||
onError, | ||
lineNumber, | ||
line, | ||
null, | ||
null, | ||
[ 1, prefixAndFirstChar.length ], | ||
startLine, | ||
params.lines[startLine - 1], | ||
true, | ||
false, | ||
[ startColumn, length ], | ||
{ | ||
"editColumn": prefixLengthNoSpace + 1, | ||
"deleteCount": deleteCount | ||
}); | ||
"editColumn": startColumn, | ||
"deleteCount": length | ||
} | ||
); | ||
} | ||
}); | ||
} | ||
} | ||
}; |
@@ -5,3 +5,5 @@ // @ts-check | ||
const { addErrorContext, forEachHeading } = require("../helpers"); | ||
const { addErrorContext } = require("../helpers"); | ||
const { getHeadingLevel, getHeadingText } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -14,3 +16,3 @@ // eslint-disable-next-line jsdoc/valid-types | ||
"tags": [ "headings" ], | ||
"parser": "markdownit", | ||
"parser": "micromark", | ||
"function": function MD024(params, onError) { | ||
@@ -21,5 +23,6 @@ const siblingsOnly = !!params.config.siblings_only || false; | ||
let knownContent = knownContents[lastLevel]; | ||
forEachHeading(params, (heading, content) => { | ||
for (const heading of filterByTypesCached([ "atxHeading", "setextHeading" ])) { | ||
const headingText = getHeadingText(heading); | ||
if (siblingsOnly) { | ||
const newLevel = heading.tag.slice(1); | ||
const newLevel = getHeadingLevel(heading); | ||
while (lastLevel < newLevel) { | ||
@@ -36,14 +39,14 @@ lastLevel++; | ||
// @ts-ignore | ||
if (knownContent.includes(content)) { | ||
if (knownContent.includes(headingText)) { | ||
addErrorContext( | ||
onError, | ||
heading.lineNumber, | ||
heading.line.trim() | ||
heading.startLine, | ||
headingText.trim() | ||
); | ||
} else { | ||
// @ts-ignore | ||
knownContent.push(content); | ||
knownContent.push(headingText); | ||
} | ||
}); | ||
} | ||
} | ||
}; |
@@ -5,4 +5,5 @@ // @ts-check | ||
const { addErrorContext, filterTokens, frontMatterHasTitle } = | ||
require("../helpers"); | ||
const { addErrorContext, frontMatterHasTitle } = require("../helpers"); | ||
const { getHeadingLevel, getHeadingText } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -15,6 +16,5 @@ // eslint-disable-next-line jsdoc/valid-types | ||
"tags": [ "headings" ], | ||
"parser": "markdownit", | ||
"parser": "micromark", | ||
"function": function MD025(params, onError) { | ||
const level = Number(params.config.level || 1); | ||
const tag = "h" + level; | ||
const foundFrontMatterTitle = | ||
@@ -26,13 +26,18 @@ frontMatterHasTitle( | ||
let hasTopLevelHeading = false; | ||
filterTokens(params, "heading_open", function forToken(token) { | ||
if (token.tag === tag) { | ||
for (const heading of filterByTypesCached([ "atxHeading", "setextHeading" ])) { | ||
const headingLevel = getHeadingLevel(heading); | ||
if (headingLevel === level) { | ||
if (hasTopLevelHeading || foundFrontMatterTitle) { | ||
addErrorContext(onError, token.lineNumber, | ||
token.line.trim()); | ||
} else if (token.lineNumber === 1) { | ||
const headingText = getHeadingText(heading); | ||
addErrorContext( | ||
onError, | ||
heading.startLine, | ||
headingText | ||
); | ||
} else if (heading.startLine === 1) { | ||
hasTopLevelHeading = true; | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
}; |
@@ -7,3 +7,3 @@ // @ts-check | ||
endOfLineHtmlEntityRe, escapeForRegExp } = require("../helpers"); | ||
const { filterByTypes } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -24,8 +24,3 @@ // eslint-disable-next-line jsdoc/valid-types | ||
new RegExp("\\s*[" + escapeForRegExp(punctuation) + "]+$"); | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
const headings = filterByTypes(micromarkTokens, [ "atxHeadingText", "setextHeadingText" ]); | ||
const headings = filterByTypesCached([ "atxHeadingText", "setextHeadingText" ]); | ||
for (const heading of headings) { | ||
@@ -32,0 +27,0 @@ const { endColumn, endLine, text } = heading; |
@@ -6,3 +6,3 @@ // @ts-check | ||
const { addErrorContext } = require("../helpers"); | ||
const { filterByTypes } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -17,9 +17,4 @@ // eslint-disable-next-line jsdoc/valid-types | ||
"function": function MD027(params, onError) { | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
for (const token of filterByTypes(micromarkTokens, [ "linePrefix" ])) { | ||
const siblings = token.parent?.children || micromarkTokens; | ||
for (const token of filterByTypesCached([ "linePrefix" ])) { | ||
const siblings = token.parent?.children || params.parsers.micromark.tokens; | ||
if (siblings[siblings.indexOf(token) - 1]?.type === "blockQuotePrefix") { | ||
@@ -33,4 +28,4 @@ const { startColumn, startLine, text } = token; | ||
line, | ||
null, | ||
null, | ||
undefined, | ||
undefined, | ||
[ startColumn, length ], | ||
@@ -37,0 +32,0 @@ { |
@@ -6,3 +6,3 @@ // @ts-check | ||
const { addError } = require("../helpers"); | ||
const { filterByTypes } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -19,10 +19,5 @@ const ignoreTypes = new Set([ "lineEnding", "listItemIndent", "linePrefix" ]); | ||
"function": function MD028(params, onError) { | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
for (const token of filterByTypes(micromarkTokens, [ "blockQuote" ])) { | ||
for (const token of filterByTypesCached([ "blockQuote" ])) { | ||
const errorLineNumbers = []; | ||
const siblings = token.parent?.children || micromarkTokens; | ||
const siblings = token.parent?.children || params.parsers.micromark.tokens; | ||
for (let i = siblings.indexOf(token) + 1; i < siblings.length; i++) { | ||
@@ -29,0 +24,0 @@ const sibling = siblings[i]; |
@@ -5,5 +5,5 @@ // @ts-check | ||
const { addErrorDetailIf, listItemMarkerRe, orderedListItemMarkerRe, | ||
rangeFromRegExp } = require("../helpers"); | ||
const { flattenedLists } = require("./cache"); | ||
const { addErrorDetailIf } = require("../helpers"); | ||
const { getDescendantsByType, getTokenTextByType } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -16,2 +16,12 @@ const listStyleExamples = { | ||
/** | ||
* Gets the value of an ordered list item prefix token. | ||
* | ||
* @param {import("../helpers/micromark.cjs").Token} listItemPrefix List item prefix token. | ||
* @returns {number} List item value. | ||
*/ | ||
function getOrderedListItemValue(listItemPrefix) { | ||
return Number(getTokenTextByType(listItemPrefix.children, "listItemValue")); | ||
} | ||
// eslint-disable-next-line jsdoc/valid-types | ||
@@ -23,22 +33,17 @@ /** @type import("./markdownlint").Rule */ | ||
"tags": [ "ol" ], | ||
"parser": "none", | ||
"parser": "micromark", | ||
"function": function MD029(params, onError) { | ||
const style = String(params.config.style || "one_or_ordered"); | ||
const filteredLists = flattenedLists().filter((list) => !list.unordered); | ||
for (const list of filteredLists) { | ||
const { items } = list; | ||
let current = 1; | ||
for (const listOrdered of filterByTypesCached([ "listOrdered" ])) { | ||
const listItemPrefixes = getDescendantsByType(listOrdered, [ "listItemPrefix" ]); | ||
let expected = 1; | ||
let incrementing = false; | ||
// Check for incrementing number pattern 1/2/3 or 0/1/2 | ||
if (items.length >= 2) { | ||
const first = orderedListItemMarkerRe.exec(items[0].line); | ||
const second = orderedListItemMarkerRe.exec(items[1].line); | ||
if (first && second) { | ||
const [ , firstNumber ] = first; | ||
const [ , secondNumber ] = second; | ||
if ((secondNumber !== "1") || (firstNumber === "0")) { | ||
incrementing = true; | ||
if (firstNumber === "0") { | ||
current = 0; | ||
} | ||
if (listItemPrefixes.length >= 2) { | ||
const firstValue = getOrderedListItemValue(listItemPrefixes[0]); | ||
const secondValue = getOrderedListItemValue(listItemPrefixes[1]); | ||
if ((secondValue !== 1) || (firstValue === 0)) { | ||
incrementing = true; | ||
if (firstValue === 0) { | ||
expected = 0; | ||
} | ||
@@ -51,20 +56,21 @@ } | ||
listStyle = incrementing ? "ordered" : "one"; | ||
} | ||
// Force expected value for 0/0/0 and 1/1/1 patterns | ||
if (listStyle === "zero") { | ||
current = 0; | ||
} else if (listStyle === "zero") { | ||
expected = 0; | ||
} else if (listStyle === "one") { | ||
current = 1; | ||
expected = 1; | ||
} | ||
// Validate each list item marker | ||
for (const item of items) { | ||
const match = orderedListItemMarkerRe.exec(item.line); | ||
if (match) { | ||
addErrorDetailIf(onError, item.lineNumber, | ||
String(current), match[1], | ||
"Style: " + listStyleExamples[listStyle], null, | ||
rangeFromRegExp(item.line, listItemMarkerRe)); | ||
if (listStyle === "ordered") { | ||
current++; | ||
} | ||
for (const listItemPrefix of listItemPrefixes) { | ||
const actual = getOrderedListItemValue(listItemPrefix); | ||
addErrorDetailIf( | ||
onError, | ||
listItemPrefix.startLine, | ||
expected, | ||
actual, | ||
"Style: " + listStyleExamples[listStyle], | ||
undefined, | ||
[ listItemPrefix.startColumn, listItemPrefix.endColumn - listItemPrefix.startColumn ] | ||
); | ||
if (listStyle === "ordered") { | ||
expected++; | ||
} | ||
@@ -71,0 +77,0 @@ } |
@@ -6,3 +6,3 @@ // @ts-check | ||
const { addErrorDetailIf } = require("../helpers"); | ||
const { filterByTypes } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -21,9 +21,3 @@ // eslint-disable-next-line jsdoc/valid-types | ||
const olMulti = Number(params.config.ol_multi || 1); | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
const lists = filterByTypes(micromarkTokens, [ "listOrdered", "listUnordered" ]); | ||
for (const list of lists) { | ||
for (const list of filterByTypesCached([ "listOrdered", "listUnordered" ])) { | ||
const ordered = (list.type === "listOrdered"); | ||
@@ -59,4 +53,4 @@ const listItemPrefixes = | ||
actualSpaces, | ||
null, | ||
null, | ||
undefined, | ||
undefined, | ||
range, | ||
@@ -63,0 +57,0 @@ fixInfo |
@@ -5,4 +5,5 @@ // @ts-check | ||
const { addErrorContext, forEachLine, isBlankLine } = require("../helpers"); | ||
const { lineMetadata } = require("./cache"); | ||
const { addErrorContext, isBlankLine } = require("../helpers"); | ||
const { getTokenParentOfType } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -12,2 +13,32 @@ const codeFencePrefixRe = /^(.*?)[`~]/; | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @typedef {readonly string[]} ReadonlyStringArray */ | ||
/** | ||
* Adds an error for the top or bottom of a code fence. | ||
* | ||
* @param {import("./markdownlint").RuleOnError} onError Error-reporting callback. | ||
* @param {ReadonlyStringArray} lines Lines of Markdown content. | ||
* @param {number} lineNumber Line number. | ||
* @param {boolean} top True iff top fence. | ||
* @returns {void} | ||
*/ | ||
function addError(onError, lines, lineNumber, top) { | ||
const line = lines[lineNumber - 1]; | ||
const [ , prefix ] = line.match(codeFencePrefixRe) || []; | ||
const fixInfo = (prefix === undefined) ? null : { | ||
"lineNumber": lineNumber + (top ? 0 : 1), | ||
"insertText": `${prefix.replace(/[^>]/g, " ").trim()}\n` | ||
}; | ||
addErrorContext( | ||
onError, | ||
lineNumber, | ||
line.trim(), | ||
undefined, | ||
undefined, | ||
undefined, | ||
fixInfo | ||
); | ||
} | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("./markdownlint").Rule */ | ||
@@ -18,3 +49,3 @@ module.exports = { | ||
"tags": [ "code", "blank_lines" ], | ||
"parser": "none", | ||
"parser": "micromark", | ||
"function": function MD031(params, onError) { | ||
@@ -24,24 +55,13 @@ const listItems = params.config.list_items; | ||
const { lines } = params; | ||
forEachLine(lineMetadata(), (line, i, inCode, onFence, inTable, inItem) => { | ||
const onTopFence = (onFence > 0); | ||
const onBottomFence = (onFence < 0); | ||
if ((includeListItems || !inItem) && | ||
((onTopFence && !isBlankLine(lines[i - 1])) || | ||
(onBottomFence && !isBlankLine(lines[i + 1])))) { | ||
const [ , prefix ] = line.match(codeFencePrefixRe) || []; | ||
const fixInfo = (prefix === undefined) ? null : { | ||
"lineNumber": i + (onTopFence ? 1 : 2), | ||
"insertText": `${prefix.replace(/[^>]/g, " ").trim()}\n` | ||
}; | ||
addErrorContext( | ||
onError, | ||
i + 1, | ||
lines[i].trim(), | ||
null, | ||
null, | ||
null, | ||
fixInfo); | ||
for (const codeBlock of filterByTypesCached([ "codeFenced" ])) { | ||
if (includeListItems || !(getTokenParentOfType(codeBlock, [ "listOrdered", "listUnordered" ]))) { | ||
if (!isBlankLine(lines[codeBlock.startLine - 2])) { | ||
addError(onError, lines, codeBlock.startLine, true); | ||
} | ||
if (!isBlankLine(lines[codeBlock.endLine]) && !isBlankLine(lines[codeBlock.endLine - 1])) { | ||
addError(onError, lines, codeBlock.endLine, false); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
}; |
@@ -5,3 +5,3 @@ // @ts-check | ||
const { addErrorContext, blockquotePrefixRe, isBlankLine } = require("../helpers"); | ||
const { addErrorContextForLine, isBlankLine } = require("../helpers"); | ||
const { filterByPredicate, nonContentTokens } = require("../helpers/micromark.cjs"); | ||
@@ -12,18 +12,2 @@ | ||
); | ||
const addBlankLineError = (onError, lines, lineIndex, lineNumber) => { | ||
const line = lines[lineIndex]; | ||
const quotePrefix = line.match(blockquotePrefixRe)[0].trimEnd(); | ||
addErrorContext( | ||
onError, | ||
lineIndex + 1, | ||
line.trim(), | ||
null, | ||
null, | ||
null, | ||
{ | ||
lineNumber, | ||
"insertText": `${quotePrefix}\n` | ||
} | ||
); | ||
}; | ||
@@ -38,12 +22,7 @@ // eslint-disable-next-line jsdoc/valid-types | ||
"function": function MD032(params, onError) { | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
const { lines } = params; | ||
const { lines, parsers } = params; | ||
// For every top-level list... | ||
const topLevelLists = filterByPredicate( | ||
micromarkTokens, | ||
parsers.micromark.tokens, | ||
isList, | ||
@@ -59,3 +38,8 @@ (token) => ( | ||
if (!isBlankLine(lines[firstIndex - 1])) { | ||
addBlankLineError(onError, lines, firstIndex); | ||
addErrorContextForLine( | ||
onError, | ||
// @ts-ignore | ||
lines, | ||
firstIndex | ||
); | ||
} | ||
@@ -76,3 +60,9 @@ | ||
if (!isBlankLine(lines[lastIndex + 1])) { | ||
addBlankLineError(onError, lines, lastIndex, lastIndex + 2); | ||
addErrorContextForLine( | ||
onError, | ||
// @ts-ignore | ||
lines, | ||
lastIndex, | ||
lastIndex + 2 | ||
); | ||
} | ||
@@ -79,0 +69,0 @@ } |
@@ -6,4 +6,4 @@ // @ts-check | ||
const { addError, nextLinesRe } = require("../helpers"); | ||
const { filterByTypes, getHtmlTagInfo } = | ||
require("../helpers/micromark.cjs"); | ||
const { getHtmlTagInfo } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -21,8 +21,3 @@ // eslint-disable-next-line jsdoc/valid-types | ||
allowedElements = allowedElements.map((element) => element.toLowerCase()); | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
for (const token of filterByTypes(micromarkTokens, [ "htmlText" ])) { | ||
for (const token of filterByTypesCached([ "htmlText" ], true)) { | ||
const htmlTagInfo = getHtmlTagInfo(token); | ||
@@ -29,0 +24,0 @@ if ( |
@@ -6,4 +6,4 @@ // @ts-check | ||
const { addErrorContext } = require("../helpers"); | ||
const { filterByPredicate, filterByTypes, getHtmlTagInfo, inHtmlFlow, parse } = | ||
require("../helpers/micromark.cjs"); | ||
const { filterByPredicate, getHtmlTagInfo, inHtmlFlow, parse } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -18,7 +18,2 @@ // eslint-disable-next-line jsdoc/valid-types | ||
"function": function MD034(params, onError) { | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
const literalAutolinks = (tokens) => ( | ||
@@ -80,3 +75,3 @@ filterByPredicate( | ||
); | ||
const autoLinks = filterByTypes(micromarkTokens, [ "literalAutolink" ]); | ||
const autoLinks = filterByTypesCached([ "literalAutolink" ]); | ||
if (autoLinks.length > 0) { | ||
@@ -100,4 +95,4 @@ // Re-parse with correct link/image reference definition handling | ||
token.text, | ||
null, | ||
null, | ||
undefined, | ||
undefined, | ||
range, | ||
@@ -104,0 +99,0 @@ fixInfo |
@@ -6,3 +6,3 @@ // @ts-check | ||
const { addErrorDetailIf } = require("../helpers"); | ||
const { filterByTypes } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -18,8 +18,3 @@ // eslint-disable-next-line jsdoc/valid-types | ||
let style = String(params.config.style || "consistent").trim(); | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
const thematicBreaks = filterByTypes(micromarkTokens, [ "thematicBreak" ]); | ||
const thematicBreaks = filterByTypesCached([ "thematicBreak" ]); | ||
for (const token of thematicBreaks) { | ||
@@ -26,0 +21,0 @@ const { startLine, text } = token; |
@@ -6,3 +6,4 @@ // @ts-check | ||
const { addErrorContext, allPunctuation } = require("../helpers"); | ||
const { filterByTypes, matchAndGetTokensByType } = require("../helpers/micromark.cjs"); | ||
const { matchAndGetTokensByType } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -28,3 +29,3 @@ /** @typedef {import("../helpers/micromark.cjs").TokenType} TokenType */ | ||
const paragraphTokens = | ||
filterByTypes(params.parsers.micromark.tokens, [ "paragraph" ]). | ||
filterByTypesCached([ "paragraph" ]). | ||
filter((token) => | ||
@@ -31,0 +32,0 @@ (token.parent?.type === "content") && !token.parent?.parent && (token.children.length === 1) |
@@ -18,8 +18,3 @@ // @ts-check | ||
// Initialize variables | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
const { lines } = params; | ||
const { lines, parsers } = params; | ||
const emphasisTokensByMarker = new Map(); | ||
@@ -30,3 +25,3 @@ for (const marker of [ "_", "__", "___", "*", "**", "***" ]) { | ||
const tokens = filterByPredicate( | ||
micromarkTokens, | ||
parsers.micromark.tokens, | ||
(token) => token.children.some((child) => child.type === "data") | ||
@@ -33,0 +28,0 @@ ); |
@@ -6,4 +6,4 @@ // @ts-check | ||
const { addErrorContext } = require("../helpers"); | ||
const { filterByTypes, inHtmlFlow, tokenIfType } = | ||
require("../helpers/micromark.cjs"); | ||
const { tokenIfType } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -31,9 +31,3 @@ const leftSpaceRe = /^\s(?:[^`]|$)/; | ||
"function": function MD038(params, onError) { | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
const codeTexts = filterByTypes(micromarkTokens, [ "codeText" ]) | ||
.filter((codeText) => !inHtmlFlow(codeText)); | ||
const codeTexts = filterByTypesCached([ "codeText" ]); | ||
for (const codeText of codeTexts) { | ||
@@ -40,0 +34,0 @@ const { children } = codeText; |
120
lib/md039.js
@@ -5,7 +5,48 @@ // @ts-check | ||
const { addErrorContext, filterTokens } = require("../helpers"); | ||
const { addErrorContext } = require("../helpers"); | ||
const { filterByTypes } = require("../helpers/micromark.cjs"); | ||
const { getReferenceLinkImageData, filterByTypesCached } = require("./cache"); | ||
const spaceInLinkRe = | ||
/\[(?:\s[^\]]*|[^\]]*?\s)\](?=(\([^)]*\)|\[[^\]]*\]))/; | ||
/** | ||
* Adds an error for a label space issue. | ||
* | ||
* @param {import("./markdownlint").RuleOnError} onError Error-reporting callback. | ||
* @param {import("../helpers/micromark.cjs").Token} label Label token. | ||
* @param {import("../helpers/micromark.cjs").Token} labelText LabelText token. | ||
* @param {boolean} isStart True iff error is at the start of the link. | ||
*/ | ||
function addLabelSpaceError(onError, label, labelText, isStart) { | ||
const match = labelText.text.match(isStart ? /^[^\S\r\n]+/ : /[^\S\r\n]+$/); | ||
const range = match ? | ||
[ | ||
(isStart ? (labelText.startColumn) : (labelText.endColumn - match[0].length)), | ||
match[0].length | ||
] : | ||
undefined; | ||
addErrorContext( | ||
onError, | ||
isStart ? (labelText.startLine + (match ? 0 : 1)) : (labelText.endLine - (match ? 0 : 1)), | ||
label.text.replace(/\s+/g, " "), | ||
isStart, | ||
!isStart, | ||
range, | ||
range ? { | ||
"editColumn": range[0], | ||
"deleteCount": range[1] | ||
} : undefined | ||
); | ||
} | ||
/** | ||
* Determines if a link is a valid link (and not a fake shortcut link due to parser tricks). | ||
* | ||
* @param {import("../helpers/micromark.cjs").Token} label Label token. | ||
* @param {import("../helpers/micromark.cjs").Token} labelText LabelText token. | ||
* @param {Map<string, any>} definitions Map of link definitions. | ||
* @returns {boolean} True iff the link is valid. | ||
*/ | ||
function validLink(label, labelText, definitions) { | ||
return (label.parent?.children.length !== 1) || definitions.has(labelText.text.trim()); | ||
} | ||
// eslint-disable-next-line jsdoc/valid-types | ||
@@ -17,57 +58,28 @@ /** @type import("./markdownlint").Rule */ | ||
"tags": [ "whitespace", "links" ], | ||
"parser": "markdownit", | ||
"parser": "micromark", | ||
"function": function MD039(params, onError) { | ||
filterTokens(params, "inline", (token) => { | ||
const { children } = token; | ||
let { lineNumber } = token; | ||
let inLink = false; | ||
let linkText = ""; | ||
let lineIndex = 0; | ||
for (const child of children) { | ||
const { content, markup, type } = child; | ||
if (type === "link_open") { | ||
inLink = true; | ||
linkText = ""; | ||
} else if (type === "link_close") { | ||
inLink = false; | ||
const left = linkText.trimStart().length !== linkText.length; | ||
const right = linkText.trimEnd().length !== linkText.length; | ||
if (left || right) { | ||
const line = params.lines[lineNumber - 1]; | ||
let range = null; | ||
let fixInfo = null; | ||
const match = line.slice(lineIndex).match(spaceInLinkRe); | ||
if (match) { | ||
// @ts-ignore | ||
const column = match.index + lineIndex + 1; | ||
const length = match[0].length; | ||
range = [ column, length ]; | ||
fixInfo = { | ||
"editColumn": column + 1, | ||
"deleteCount": length - 2, | ||
"insertText": linkText.trim() | ||
}; | ||
lineIndex = column + length - 1; | ||
} | ||
addErrorContext( | ||
onError, | ||
lineNumber, | ||
`[${linkText}]`, | ||
left, | ||
right, | ||
range, | ||
fixInfo | ||
); | ||
} | ||
} else if ((type === "softbreak") || (type === "hardbreak")) { | ||
lineNumber++; | ||
lineIndex = 0; | ||
} else if (inLink) { | ||
linkText += type.endsWith("_inline") ? | ||
`${markup}${content}${markup}` : | ||
(content || markup); | ||
const { definitions } = getReferenceLinkImageData(); | ||
const labels = filterByTypesCached([ "label" ]). | ||
filter((label) => label.parent?.type === "link"); | ||
for (const label of labels) { | ||
const labelTexts = filterByTypes( | ||
label.children, | ||
[ "labelText" ] | ||
); | ||
for (const labelText of labelTexts) { | ||
if ( | ||
(labelText.text.trimStart().length !== labelText.text.length) && | ||
validLink(label, labelText, definitions) | ||
) { | ||
addLabelSpaceError(onError, label, labelText, true); | ||
} | ||
if ( | ||
(labelText.text.trimEnd().length !== labelText.text.length) && | ||
validLink(label, labelText, definitions) | ||
) { | ||
addLabelSpaceError(onError, label, labelText, false); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
}; |
@@ -6,4 +6,4 @@ // @ts-check | ||
const { addError, addErrorContext } = require("../helpers"); | ||
const { filterByTypes, getTokenTextByType, tokenIfType } = | ||
require("../helpers/micromark.cjs"); | ||
const { getTokenTextByType, tokenIfType } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -21,8 +21,3 @@ // eslint-disable-next-line jsdoc/valid-types | ||
const languageOnly = !!params.config.language_only; | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
const fencedCodes = filterByTypes(micromarkTokens, [ "codeFenced" ]); | ||
const fencedCodes = filterByTypesCached([ "codeFenced" ]); | ||
for (const fencedCode of fencedCodes) { | ||
@@ -29,0 +24,0 @@ const openingFence = tokenIfType(fencedCode.children[0], "codeFencedFence"); |
@@ -26,3 +26,3 @@ // @ts-check | ||
} else if (token.type === "htmlFlow") { | ||
const htmlTexts = filterByTypes(token.children, [ "htmlText" ]); | ||
const htmlTexts = filterByTypes(token.children, [ "htmlText" ], true); | ||
const tagInfo = (htmlTexts.length > 0) && getHtmlTagInfo(htmlTexts[0]); | ||
@@ -29,0 +29,0 @@ isError = !tagInfo || (tagInfo.name.toLowerCase() !== `h${level}`); |
@@ -5,4 +5,5 @@ // @ts-check | ||
const { addErrorContext, escapeForRegExp, filterTokens } = | ||
require("../helpers"); | ||
const { addErrorContext } = require("../helpers"); | ||
const { getDescendantsByType } = require("../helpers/micromark.cjs"); | ||
const { getReferenceLinkImageData, filterByTypesCached } = require("./cache"); | ||
@@ -15,41 +16,50 @@ // eslint-disable-next-line jsdoc/valid-types | ||
"tags": [ "links" ], | ||
"parser": "markdownit", | ||
"parser": "micromark", | ||
"function": function MD042(params, onError) { | ||
filterTokens(params, "inline", function forToken(token) { | ||
let inLink = false; | ||
let linkText = ""; | ||
let emptyLink = false; | ||
for (const child of token.children) { | ||
if (child.type === "link_open") { | ||
inLink = true; | ||
linkText = ""; | ||
for (const attr of child.attrs) { | ||
if (attr[0] === "href" && (!attr[1] || (attr[1] === "#"))) { | ||
emptyLink = true; | ||
} | ||
} | ||
} else if (child.type === "link_close") { | ||
inLink = false; | ||
if (emptyLink) { | ||
let context = `[${linkText}]`; | ||
let range = null; | ||
const match = child.line.match( | ||
new RegExp(`${escapeForRegExp(context)}\\((?:|#|<>)\\)`) | ||
); | ||
if (match) { | ||
context = match[0]; | ||
// @ts-ignore | ||
range = [ match.index + 1, match[0].length ]; | ||
} | ||
addErrorContext( | ||
onError, child.lineNumber, context, null, null, range | ||
); | ||
emptyLink = false; | ||
} | ||
} else if (inLink) { | ||
linkText += child.content; | ||
} | ||
const { definitions } = getReferenceLinkImageData(); | ||
const isReferenceDefinitionHash = (token) => { | ||
const definition = definitions.get(token.text.trim()); | ||
return (definition && (definition[1] === "#")); | ||
}; | ||
const links = filterByTypesCached([ "link" ]); | ||
for (const link of links) { | ||
const labelText = getDescendantsByType(link, [ "label", "labelText" ]); | ||
const reference = getDescendantsByType(link, [ "reference" ]); | ||
const resource = getDescendantsByType(link, [ "resource" ]); | ||
const referenceString = getDescendantsByType(reference, [ "referenceString" ]); | ||
const resourceDestination = getDescendantsByType(resource, [ "resourceDestination" ]); | ||
const resourceDestinationString = [ | ||
...getDescendantsByType(resourceDestination, [ "resourceDestinationRaw", "resourceDestinationString" ]), | ||
...getDescendantsByType(resourceDestination, [ "resourceDestinationLiteral", "resourceDestinationString" ]) | ||
]; | ||
const hasLabelText = labelText.length > 0; | ||
const hasReference = reference.length > 0; | ||
const hasResource = resource.length > 0; | ||
const hasReferenceString = referenceString.length > 0; | ||
const hasResourceDestinationString = resourceDestinationString.length > 0; | ||
let error = false; | ||
if ( | ||
hasLabelText && | ||
((!hasReference && !hasResource) || (hasReference && !hasReferenceString)) | ||
) { | ||
error = isReferenceDefinitionHash(labelText[0]); | ||
} else if (hasReferenceString && !hasResourceDestinationString) { | ||
error = isReferenceDefinitionHash(referenceString[0]); | ||
} else if (!hasReferenceString && hasResourceDestinationString) { | ||
error = (resourceDestinationString[0].text.trim() === "#"); | ||
} else if (!hasReferenceString && !hasResourceDestinationString) { | ||
error = true; | ||
} | ||
}); | ||
if (error) { | ||
addErrorContext( | ||
onError, | ||
link.startLine, | ||
link.text, | ||
undefined, | ||
undefined, | ||
[ link.startColumn, link.endColumn - link.startColumn ] | ||
); | ||
} | ||
} | ||
} | ||
}; |
@@ -5,4 +5,5 @@ // @ts-check | ||
const { addErrorContext, addErrorDetailIf, forEachHeading } = | ||
require("../helpers"); | ||
const { addErrorContext, addErrorDetailIf } = require("../helpers"); | ||
const { getHeadingLevel, getHeadingText } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -15,3 +16,3 @@ // eslint-disable-next-line jsdoc/valid-types | ||
"tags": [ "headings" ], | ||
"parser": "markdownit", | ||
"parser": "micromark", | ||
"function": function MD043(params, onError) { | ||
@@ -24,6 +25,2 @@ const requiredHeadings = params.config.headings; | ||
const matchCase = params.config.match_case || false; | ||
const levels = {}; | ||
for (const level of [ 1, 2, 3, 4, 5, 6 ]) { | ||
levels["h" + level] = "######".substr(-level); | ||
} | ||
let i = 0; | ||
@@ -35,6 +32,8 @@ let matchAny = false; | ||
const handleCase = (str) => (matchCase ? str : str.toLowerCase()); | ||
forEachHeading(params, (heading, content) => { | ||
for (const heading of filterByTypesCached([ "atxHeading", "setextHeading" ])) { | ||
if (!hasError) { | ||
const headingText = getHeadingText(heading); | ||
const headingLevel = getHeadingLevel(heading); | ||
anyHeadings = true; | ||
const actual = levels[heading.tag] + " " + content; | ||
const actual = `${"".padEnd(headingLevel, "#")} ${headingText}`; | ||
const expected = getExpected(); | ||
@@ -54,8 +53,12 @@ if (expected === "*") { | ||
} else { | ||
addErrorDetailIf(onError, heading.lineNumber, | ||
expected, actual); | ||
addErrorDetailIf( | ||
onError, | ||
heading.startLine, | ||
expected, | ||
actual | ||
); | ||
hasError = true; | ||
} | ||
} | ||
}); | ||
} | ||
const extraHeadings = requiredHeadings.length - i; | ||
@@ -68,6 +71,9 @@ if ( | ||
) { | ||
addErrorContext(onError, params.lines.length, | ||
requiredHeadings[i]); | ||
addErrorContext( | ||
onError, | ||
params.lines.length, | ||
requiredHeadings[i] | ||
); | ||
} | ||
} | ||
}; |
@@ -35,7 +35,2 @@ // @ts-check | ||
(htmlElements === undefined) ? true : !!htmlElements; | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
const scannedTypes = new Set([ "data" ]); | ||
@@ -52,3 +47,3 @@ if (includeCodeBlocks) { | ||
filterByPredicate( | ||
micromarkTokens, | ||
params.parsers.micromark.tokens, | ||
(token) => scannedTypes.has(token.type), | ||
@@ -101,4 +96,4 @@ (token) => ( | ||
nameMatch, | ||
null, | ||
null, | ||
undefined, | ||
undefined, | ||
[ column, length ], | ||
@@ -105,0 +100,0 @@ { |
@@ -7,2 +7,3 @@ // @ts-check | ||
const { filterByTypes, getHtmlTagInfo } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -19,10 +20,4 @@ const altRe = getHtmlAttributeRe("alt"); | ||
"function": function MD045(params, onError) { | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
// Process Markdown images | ||
const images = filterByTypes(micromarkTokens, [ "image" ]); | ||
const images = filterByTypesCached([ "image" ]); | ||
for (const image of images) { | ||
@@ -45,3 +40,3 @@ const labelTexts = filterByTypes(image.children, [ "labelText" ]); | ||
// Process HTML images | ||
const htmlTexts = filterByTypes(micromarkTokens, [ "htmlText" ]); | ||
const htmlTexts = filterByTypesCached([ "htmlText" ], true); | ||
for (const htmlText of htmlTexts) { | ||
@@ -48,0 +43,0 @@ const { startColumn, startLine, text } = htmlText; |
@@ -6,3 +6,3 @@ // @ts-check | ||
const { addErrorDetailIf } = require("../helpers"); | ||
const { filterByTypes } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -23,9 +23,3 @@ const tokenTypeToStyle = { | ||
let expectedStyle = String(params.config.style || "consistent"); | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
const codeBlocksAndFences = filterByTypes(micromarkTokens, [ "codeFenced", "codeIndented" ]); | ||
for (const token of codeBlocksAndFences) { | ||
for (const token of filterByTypesCached([ "codeFenced", "codeIndented" ])) { | ||
const { startLine, type } = token; | ||
@@ -32,0 +26,0 @@ if (expectedStyle === "consistent") { |
@@ -6,3 +6,4 @@ // @ts-check | ||
const { addErrorDetailIf, fencedCodeBlockStyleFor } = require("../helpers"); | ||
const { filterByTypes, tokenIfType } = require("../helpers/micromark.cjs"); | ||
const { tokenIfType } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -18,9 +19,4 @@ // eslint-disable-next-line jsdoc/valid-types | ||
const style = String(params.config.style || "consistent"); | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
let expectedStyle = style; | ||
const codeFenceds = filterByTypes(micromarkTokens, [ "codeFenced" ]); | ||
const codeFenceds = filterByTypesCached([ "codeFenced" ]); | ||
for (const codeFenced of codeFenceds) { | ||
@@ -27,0 +23,0 @@ const codeFencedFence = tokenIfType(codeFenced.children[0], "codeFencedFence"); |
@@ -21,10 +21,5 @@ // @ts-check | ||
(params, onError, type, typeSequence, asterisk, underline, style = "consistent") => { | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
const { lines } = params; | ||
const { lines, parsers } = params; | ||
const emphasisTokens = filterByPredicate( | ||
micromarkTokens, | ||
parsers.micromark.tokens, | ||
(token) => token.type === type, | ||
@@ -31,0 +26,0 @@ (token) => ((token.type === "htmlFlow") ? [] : token.children) |
@@ -5,6 +5,5 @@ // @ts-check | ||
const { addError, addErrorDetailIf, getHtmlAttributeRe } = | ||
require("../helpers"); | ||
const { filterByPredicate, filterByTypes, getHtmlTagInfo } = | ||
require("../helpers/micromark.cjs"); | ||
const { addError, addErrorDetailIf, getHtmlAttributeRe } = require("../helpers"); | ||
const { filterByPredicate, filterByTypes, getHtmlTagInfo } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -73,11 +72,6 @@ // Regular expression for identifying HTML anchor names | ||
"function": function MD051(params, onError) { | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
const fragments = new Map(); | ||
// Process headings | ||
const headingTexts = filterByTypes(micromarkTokens, [ "atxHeadingText", "setextHeadingText" ]); | ||
const headingTexts = filterByTypesCached([ "atxHeadingText", "setextHeadingText" ]); | ||
for (const headingText of headingTexts) { | ||
@@ -102,3 +96,3 @@ const fragment = convertHeadingToHTMLFragment(headingText); | ||
// Process HTML anchors | ||
for (const token of filterByTypes(micromarkTokens, [ "htmlText" ])) { | ||
for (const token of filterByTypesCached([ "htmlText" ], true)) { | ||
const htmlTagInfo = getHtmlTagInfo(token); | ||
@@ -122,3 +116,3 @@ if (htmlTagInfo && !htmlTagInfo.close) { | ||
for (const [ parentType, definitionType ] of parentChilds) { | ||
const links = filterByTypes(micromarkTokens, [ parentType ]); | ||
const links = filterByTypesCached([ parentType ]); | ||
for (const link of links) { | ||
@@ -125,0 +119,0 @@ const definitions = filterByTypes(link.children, [ definitionType ]); |
@@ -6,3 +6,3 @@ // @ts-check | ||
const { addError } = require("../helpers"); | ||
const { referenceLinkImageData } = require("./cache"); | ||
const { getReferenceLinkImageData } = require("./cache"); | ||
@@ -20,3 +20,3 @@ // eslint-disable-next-line jsdoc/valid-types | ||
const shortcutSyntax = config.shortcut_syntax || false; | ||
const { definitions, references, shortcuts } = referenceLinkImageData(); | ||
const { definitions, references, shortcuts } = getReferenceLinkImageData(); | ||
const entries = shortcutSyntax ? | ||
@@ -23,0 +23,0 @@ [ ...references.entries(), ...shortcuts.entries() ] : |
@@ -7,3 +7,3 @@ // @ts-check | ||
require("../helpers"); | ||
const { referenceLinkImageData } = require("./cache"); | ||
const { getReferenceLinkImageData } = require("./cache"); | ||
@@ -21,3 +21,3 @@ // eslint-disable-next-line jsdoc/valid-types | ||
const { references, shortcuts, definitions, duplicateDefinitions } = | ||
referenceLinkImageData(); | ||
getReferenceLinkImageData(); | ||
const singleLineDefinition = (line) => ( | ||
@@ -24,0 +24,0 @@ line.replace(linkReferenceDefinitionRe, "").trim().length > 0 |
@@ -6,5 +6,4 @@ // @ts-check | ||
const { addErrorContext, nextLinesRe } = require("../helpers"); | ||
const { filterByTypes, filterByPredicate, getTokenTextByType } = | ||
require("../helpers/micromark.cjs"); | ||
const { referenceLinkImageData } = require("./cache"); | ||
const { filterByPredicate, getTokenTextByType } = require("../helpers/micromark.cjs"); | ||
const { getReferenceLinkImageData, filterByTypesCached } = require("./cache"); | ||
@@ -44,9 +43,4 @@ const backslashEscapeRe = /\\([!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~])/g; | ||
} | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
const { definitions } = referenceLinkImageData(); | ||
const links = filterByTypes(micromarkTokens, [ "autolink", "image", "link" ]); | ||
const { definitions } = getReferenceLinkImageData(); | ||
const links = filterByTypesCached([ "autolink", "image", "link" ]); | ||
for (const link of links) { | ||
@@ -94,3 +88,4 @@ let label = null; | ||
if (isError) { | ||
let range = null; | ||
// eslint-disable-next-line no-undef-init | ||
let range = undefined; | ||
let fixInfo = null; | ||
@@ -125,4 +120,4 @@ if (startLine === endLine) { | ||
text.replace(nextLinesRe, ""), | ||
null, | ||
null, | ||
undefined, | ||
undefined, | ||
range, | ||
@@ -129,0 +124,0 @@ fixInfo |
@@ -7,2 +7,3 @@ // @ts-check | ||
const { filterByTypes } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -31,10 +32,8 @@ const whitespaceTypes = new Set([ "linePrefix", "whitespace" ]); | ||
((expectedStyle !== "no_leading_or_trailing") && (expectedStyle !== "leading_only")); | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
const tables = filterByTypes(micromarkTokens, [ "table" ]); | ||
const tables = filterByTypesCached([ "table" ]); | ||
for (const table of tables) { | ||
const rows = filterByTypes(table.children, [ "tableDelimiterRow", "tableRow" ]); | ||
const rows = filterByTypes( | ||
table.children, | ||
[ "tableDelimiterRow", "tableRow" ] | ||
); | ||
for (const row of rows) { | ||
@@ -82,2 +81,2 @@ // The following uses of first/lastOrNothing lack fallback handling | ||
} | ||
} | ||
}; |
@@ -7,2 +7,3 @@ // @ts-check | ||
const { filterByTypes } = require("../helpers/micromark.cjs"); | ||
const { filterByTypesCached } = require("./cache"); | ||
@@ -19,17 +20,20 @@ const makeRange = (start, end) => [ start, end - start + 1 ]; | ||
"function": function MD056(params, onError) { | ||
// eslint-disable-next-line jsdoc/valid-types | ||
/** @type import("../helpers/micromark.cjs").Token[] */ | ||
const micromarkTokens = | ||
// @ts-ignore | ||
params.parsers.micromark.tokens; | ||
const tables = filterByTypes(micromarkTokens, [ "table" ]); | ||
const tables = filterByTypesCached([ "table" ]); | ||
for (const table of tables) { | ||
const rows = filterByTypes(table.children, [ "tableDelimiterRow", "tableRow" ]); | ||
const rows = filterByTypes( | ||
table.children, | ||
[ "tableDelimiterRow", "tableRow" ] | ||
); | ||
let expectedCount = 0; | ||
for (const row of rows) { | ||
const cells = filterByTypes(row.children, [ "tableData", "tableDelimiter", "tableHeader" ]); | ||
const cells = filterByTypes( | ||
row.children, | ||
[ "tableData", "tableDelimiter", "tableHeader" ] | ||
); | ||
const actualCount = cells.length; | ||
expectedCount ||= actualCount; | ||
let detail = null; | ||
let range = null; | ||
// eslint-disable-next-line no-undef-init | ||
let detail = undefined; | ||
// eslint-disable-next-line no-undef-init | ||
let range = undefined; | ||
if (actualCount < expectedCount) { | ||
@@ -48,3 +52,3 @@ detail = "Too few cells, row will be missing data"; | ||
detail, | ||
null, | ||
undefined, | ||
range | ||
@@ -51,0 +55,0 @@ ); |
@@ -7,2 +7,7 @@ // @ts-check | ||
// @ts-ignore | ||
const [ md019, md021 ] = require("./md019-md021"); | ||
// @ts-ignore | ||
const [ md049, md050 ] = require("./md049-md050"); | ||
const rules = [ | ||
@@ -23,5 +28,5 @@ require("./md001"), | ||
require("./md018"), | ||
require("./md019"), | ||
md019, | ||
require("./md020"), | ||
require("./md021"), | ||
md021, | ||
require("./md022"), | ||
@@ -54,3 +59,4 @@ require("./md023"), | ||
require("./md048"), | ||
...require("./md049-md050"), | ||
md049, | ||
md050, | ||
require("./md051"), | ||
@@ -61,4 +67,5 @@ require("./md052"), | ||
require("./md055"), | ||
require("./md056") | ||
require("./md056"), | ||
// md057: See https://github.com/markdownlint/markdownlint | ||
require("./md058") | ||
]; | ||
@@ -65,0 +72,0 @@ for (const rule of rules) { |
{ | ||
"name": "markdownlint", | ||
"version": "0.34.0", | ||
"version": "0.35.0", | ||
"description": "A Node.js style checker and lint tool for Markdown/CommonMark files.", | ||
@@ -52,3 +52,3 @@ "type": "commonjs", | ||
"install-micromark": "cd micromark && npm install", | ||
"lint": "eslint --ext .js,.cjs,.mjs --max-warnings 0 .", | ||
"lint": "eslint --max-warnings 0", | ||
"lint-test-repos": "ava --timeout=10m test/markdownlint-test-repos-*.js", | ||
@@ -59,3 +59,3 @@ "serial-config-docs": "npm run build-config && npm run build-docs", | ||
"test-cover": "c8 --100 npm test", | ||
"test-declaration": "cd example/typescript && tsc && node type-check.js", | ||
"test-declaration": "cd example/typescript && tsc --module nodenext && tsc --module commonjs && node type-check.js", | ||
"test-extra": "ava --timeout=10m test/markdownlint-test-extra-parse.js test/markdownlint-test-extra-type.js", | ||
@@ -71,27 +71,29 @@ "update-snapshots": "ava --update-snapshots test/markdownlint-test-micromark.mjs test/markdownlint-test-scenarios.js", | ||
"markdown-it": "14.1.0", | ||
"markdownlint-micromark": "0.1.9" | ||
"markdownlint-micromark": "0.1.10" | ||
}, | ||
"devDependencies": { | ||
"ajv": "8.12.0", | ||
"ava": "6.1.2", | ||
"c8": "9.1.0", | ||
"@eslint/js": "9.9.1", | ||
"ajv": "8.17.1", | ||
"ava": "6.1.3", | ||
"c8": "10.1.2", | ||
"character-entities": "2.0.2", | ||
"eslint": "8.57.0", | ||
"eslint-plugin-jsdoc": "48.2.1", | ||
"eslint-plugin-n": "16.6.2", | ||
"eslint-plugin-regexp": "2.3.0", | ||
"eslint-plugin-unicorn": "51.0.1", | ||
"eslint": "9.9.1", | ||
"eslint-plugin-jsdoc": "50.2.2", | ||
"eslint-plugin-n": "17.10.2", | ||
"eslint-plugin-regexp": "2.6.0", | ||
"eslint-plugin-unicorn": "55.0.0", | ||
"gemoji": "8.1.0", | ||
"globby": "14.0.1", | ||
"globby": "14.0.2", | ||
"js-yaml": "4.1.0", | ||
"json-schema-to-typescript": "13.1.2", | ||
"jsonc-parser": "3.2.1", | ||
"json-schema-to-typescript": "15.0.1", | ||
"jsonc-parser": "3.3.1", | ||
"markdown-it-for-inline": "2.0.1", | ||
"markdown-it-sub": "2.0.0", | ||
"markdown-it-sup": "2.0.0", | ||
"markdownlint-rule-extended-ascii": "0.1.0", | ||
"npm-run-all": "4.1.5", | ||
"terser-webpack-plugin": "5.3.10", | ||
"toml": "3.0.0", | ||
"typescript": "5.4.3", | ||
"webpack": "5.91.0", | ||
"typescript": "5.5.4", | ||
"webpack": "5.94.0", | ||
"webpack-cli": "5.1.4" | ||
@@ -98,0 +100,0 @@ }, |
@@ -139,2 +139,3 @@ # markdownlint | ||
- **[MD056](doc/md056.md)** *table-column-count* - Table column count | ||
- **[MD058](doc/md058.md)** *blanks-around-tables* - Tables should be surrounded by blank lines | ||
@@ -181,3 +182,3 @@ <!-- markdownlint-restore --> | ||
- **`spelling`** - `MD044` | ||
- **`table`** - `MD055`, `MD056` | ||
- **`table`** - `MD055`, `MD056`, `MD058` | ||
- **`ul`** - `MD004`, `MD005`, `MD007`, `MD030`, `MD032` | ||
@@ -358,12 +359,12 @@ - **`url`** - `MD034` | ||
Object keys are rule names or aliases and values are the rule's configuration. | ||
Object keys are rule names/aliases; object values are the rule's configuration. | ||
The value `false` disables a rule, `true` enables its default configuration, | ||
and passing an object customizes its settings. Setting the special `default` | ||
rule to `true` or `false` includes/excludes all rules by default. Enabling | ||
or disabling a tag name (ex: `whitespace`) affects all rules having that | ||
tag. | ||
and passing an object value customizes that rule. Setting the special `default` | ||
rule to `true` or `false` includes/excludes all rules by default. In the absence | ||
of a configuration object, all rules are enabled. Enabling or disabling a tag | ||
name (ex: `whitespace`) affects all rules having that tag. | ||
The `default` rule is applied first, then keys are processed in order | ||
from top to bottom with later values overriding earlier ones. Keys | ||
(including rule names, aliases, tags, and `default`) are not case-sensitive. | ||
The `default` rule is applied first, then keys are processed in order from top | ||
to bottom with later values overriding earlier ones. Keys (including rule names, | ||
aliases, tags, and `default`) are not case-sensitive. | ||
@@ -568,3 +569,3 @@ Example: | ||
Specifies additional [markdown-it plugins][markdown-it-plugin] to use when | ||
Specifies additional [`markdown-it` plugins][markdown-it-plugin] to use when | ||
parsing input. Plugins can be used to support additional syntax and features for | ||
@@ -581,2 +582,9 @@ advanced scenarios. | ||
> Note that `markdown-it` plugins are only called when the `markdown-it` parser | ||
> is invoked. None of the built-in rules use the `markdown-it` parser, so | ||
> `markdown-it` plugins will only be invoked when one or more | ||
> [custom rules][custom-rules] that use the `markdown-it` parser are present. | ||
[custom-rules]: #custom-rules | ||
##### options.noInlineConfig | ||
@@ -987,2 +995,7 @@ | ||
For more advanced integration scenarios: | ||
- [GitHub Docs content linter][content-linter] | ||
- [GitHub's `markdownlint-github` repository][markdownlint-github] | ||
[ally-js]: https://allyjs.io/ | ||
@@ -996,2 +1009,3 @@ [ally-js-search]: https://github.com/medialize/ally.js/search?q=markdownlint | ||
[codimd-search]: https://github.com/hackmdio/codimd/search?q=markdownlint | ||
[content-linter]: https://docs.github.com/en/contributing/collaborating-on-github-docs/using-the-content-linter | ||
[dot-net-doc]: https://docs.microsoft.com/en-us/dotnet/ | ||
@@ -1005,2 +1019,3 @@ [dot-net-doc-search]: https://github.com/dotnet/docs/search?q=markdownlint | ||
[garden-search]: https://github.com/zendeskgarden/react-components/search?q=markdownlint | ||
[markdownlint-github]: https://github.com/github/markdownlint-github | ||
[mdn]: https://developer.mozilla.org/ | ||
@@ -1007,0 +1022,0 @@ [mdn-search]: https://github.com/mdn/content/search?q=markdownlint |
{ | ||
"$schema": "http://json-schema.org/draft-07/schema#", | ||
"$id": "https://raw.githubusercontent.com/DavidAnson/markdownlint/v0.34.0/schema/markdownlint-config-schema.json", | ||
"$id": "https://raw.githubusercontent.com/DavidAnson/markdownlint/v0.35.0/schema/markdownlint-config-schema.json", | ||
"title": "markdownlint configuration schema", | ||
@@ -10,3 +10,3 @@ "type": "object", | ||
"type": "string", | ||
"default": "https://raw.githubusercontent.com/DavidAnson/markdownlint/v0.34.0/schema/markdownlint-config-schema.json" | ||
"default": "https://raw.githubusercontent.com/DavidAnson/markdownlint/v0.35.0/schema/markdownlint-config-schema.json" | ||
}, | ||
@@ -27,3 +27,3 @@ "default": { | ||
"MD001": { | ||
"description": "MD001/heading-increment : Heading levels should only increment by one level at a time : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md001.md", | ||
"description": "MD001/heading-increment : Heading levels should only increment by one level at a time : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md001.md", | ||
"type": "boolean", | ||
@@ -33,3 +33,3 @@ "default": true | ||
"heading-increment": { | ||
"description": "MD001/heading-increment : Heading levels should only increment by one level at a time : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md001.md", | ||
"description": "MD001/heading-increment : Heading levels should only increment by one level at a time : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md001.md", | ||
"type": "boolean", | ||
@@ -39,3 +39,3 @@ "default": true | ||
"MD003": { | ||
"description": "MD003/heading-style : Heading style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md003.md", | ||
"description": "MD003/heading-style : Heading style : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md003.md", | ||
"type": [ | ||
@@ -64,3 +64,3 @@ "boolean", | ||
"heading-style": { | ||
"description": "MD003/heading-style : Heading style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md003.md", | ||
"description": "MD003/heading-style : Heading style : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md003.md", | ||
"type": [ | ||
@@ -89,3 +89,3 @@ "boolean", | ||
"MD004": { | ||
"description": "MD004/ul-style : Unordered list style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md004.md", | ||
"description": "MD004/ul-style : Unordered list style : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md004.md", | ||
"type": [ | ||
@@ -113,3 +113,3 @@ "boolean", | ||
"ul-style": { | ||
"description": "MD004/ul-style : Unordered list style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md004.md", | ||
"description": "MD004/ul-style : Unordered list style : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md004.md", | ||
"type": [ | ||
@@ -137,3 +137,3 @@ "boolean", | ||
"MD005": { | ||
"description": "MD005/list-indent : Inconsistent indentation for list items at the same level : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md005.md", | ||
"description": "MD005/list-indent : Inconsistent indentation for list items at the same level : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md005.md", | ||
"type": "boolean", | ||
@@ -143,3 +143,3 @@ "default": true | ||
"list-indent": { | ||
"description": "MD005/list-indent : Inconsistent indentation for list items at the same level : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md005.md", | ||
"description": "MD005/list-indent : Inconsistent indentation for list items at the same level : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md005.md", | ||
"type": "boolean", | ||
@@ -149,3 +149,3 @@ "default": true | ||
"MD007": { | ||
"description": "MD007/ul-indent : Unordered list indentation : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md007.md", | ||
"description": "MD007/ul-indent : Unordered list indentation : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md007.md", | ||
"type": [ | ||
@@ -178,3 +178,3 @@ "boolean", | ||
"ul-indent": { | ||
"description": "MD007/ul-indent : Unordered list indentation : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md007.md", | ||
"description": "MD007/ul-indent : Unordered list indentation : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md007.md", | ||
"type": [ | ||
@@ -207,3 +207,3 @@ "boolean", | ||
"MD009": { | ||
"description": "MD009/no-trailing-spaces : Trailing spaces : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md009.md", | ||
"description": "MD009/no-trailing-spaces : Trailing spaces : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md009.md", | ||
"type": [ | ||
@@ -235,3 +235,3 @@ "boolean", | ||
"no-trailing-spaces": { | ||
"description": "MD009/no-trailing-spaces : Trailing spaces : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md009.md", | ||
"description": "MD009/no-trailing-spaces : Trailing spaces : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md009.md", | ||
"type": [ | ||
@@ -263,3 +263,3 @@ "boolean", | ||
"MD010": { | ||
"description": "MD010/no-hard-tabs : Hard tabs : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md010.md", | ||
"description": "MD010/no-hard-tabs : Hard tabs : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md010.md", | ||
"type": [ | ||
@@ -294,3 +294,3 @@ "boolean", | ||
"no-hard-tabs": { | ||
"description": "MD010/no-hard-tabs : Hard tabs : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md010.md", | ||
"description": "MD010/no-hard-tabs : Hard tabs : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md010.md", | ||
"type": [ | ||
@@ -325,3 +325,3 @@ "boolean", | ||
"MD011": { | ||
"description": "MD011/no-reversed-links : Reversed link syntax : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md011.md", | ||
"description": "MD011/no-reversed-links : Reversed link syntax : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md011.md", | ||
"type": "boolean", | ||
@@ -331,3 +331,3 @@ "default": true | ||
"no-reversed-links": { | ||
"description": "MD011/no-reversed-links : Reversed link syntax : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md011.md", | ||
"description": "MD011/no-reversed-links : Reversed link syntax : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md011.md", | ||
"type": "boolean", | ||
@@ -337,3 +337,3 @@ "default": true | ||
"MD012": { | ||
"description": "MD012/no-multiple-blanks : Multiple consecutive blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md012.md", | ||
"description": "MD012/no-multiple-blanks : Multiple consecutive blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md012.md", | ||
"type": [ | ||
@@ -355,3 +355,3 @@ "boolean", | ||
"no-multiple-blanks": { | ||
"description": "MD012/no-multiple-blanks : Multiple consecutive blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md012.md", | ||
"description": "MD012/no-multiple-blanks : Multiple consecutive blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md012.md", | ||
"type": [ | ||
@@ -373,3 +373,3 @@ "boolean", | ||
"MD013": { | ||
"description": "MD013/line-length : Line length : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md", | ||
"description": "MD013/line-length : Line length : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md013.md", | ||
"type": [ | ||
@@ -428,3 +428,3 @@ "boolean", | ||
"line-length": { | ||
"description": "MD013/line-length : Line length : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md", | ||
"description": "MD013/line-length : Line length : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md013.md", | ||
"type": [ | ||
@@ -483,3 +483,3 @@ "boolean", | ||
"MD014": { | ||
"description": "MD014/commands-show-output : Dollar signs used before commands without showing output : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md014.md", | ||
"description": "MD014/commands-show-output : Dollar signs used before commands without showing output : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md014.md", | ||
"type": "boolean", | ||
@@ -489,3 +489,3 @@ "default": true | ||
"commands-show-output": { | ||
"description": "MD014/commands-show-output : Dollar signs used before commands without showing output : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md014.md", | ||
"description": "MD014/commands-show-output : Dollar signs used before commands without showing output : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md014.md", | ||
"type": "boolean", | ||
@@ -495,3 +495,3 @@ "default": true | ||
"MD018": { | ||
"description": "MD018/no-missing-space-atx : No space after hash on atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md018.md", | ||
"description": "MD018/no-missing-space-atx : No space after hash on atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md018.md", | ||
"type": "boolean", | ||
@@ -501,3 +501,3 @@ "default": true | ||
"no-missing-space-atx": { | ||
"description": "MD018/no-missing-space-atx : No space after hash on atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md018.md", | ||
"description": "MD018/no-missing-space-atx : No space after hash on atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md018.md", | ||
"type": "boolean", | ||
@@ -507,3 +507,3 @@ "default": true | ||
"MD019": { | ||
"description": "MD019/no-multiple-space-atx : Multiple spaces after hash on atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md019.md", | ||
"description": "MD019/no-multiple-space-atx : Multiple spaces after hash on atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md019.md", | ||
"type": "boolean", | ||
@@ -513,3 +513,3 @@ "default": true | ||
"no-multiple-space-atx": { | ||
"description": "MD019/no-multiple-space-atx : Multiple spaces after hash on atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md019.md", | ||
"description": "MD019/no-multiple-space-atx : Multiple spaces after hash on atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md019.md", | ||
"type": "boolean", | ||
@@ -519,3 +519,3 @@ "default": true | ||
"MD020": { | ||
"description": "MD020/no-missing-space-closed-atx : No space inside hashes on closed atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md020.md", | ||
"description": "MD020/no-missing-space-closed-atx : No space inside hashes on closed atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md020.md", | ||
"type": "boolean", | ||
@@ -525,3 +525,3 @@ "default": true | ||
"no-missing-space-closed-atx": { | ||
"description": "MD020/no-missing-space-closed-atx : No space inside hashes on closed atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md020.md", | ||
"description": "MD020/no-missing-space-closed-atx : No space inside hashes on closed atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md020.md", | ||
"type": "boolean", | ||
@@ -531,3 +531,3 @@ "default": true | ||
"MD021": { | ||
"description": "MD021/no-multiple-space-closed-atx : Multiple spaces inside hashes on closed atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md021.md", | ||
"description": "MD021/no-multiple-space-closed-atx : Multiple spaces inside hashes on closed atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md021.md", | ||
"type": "boolean", | ||
@@ -537,3 +537,3 @@ "default": true | ||
"no-multiple-space-closed-atx": { | ||
"description": "MD021/no-multiple-space-closed-atx : Multiple spaces inside hashes on closed atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md021.md", | ||
"description": "MD021/no-multiple-space-closed-atx : Multiple spaces inside hashes on closed atx style heading : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md021.md", | ||
"type": "boolean", | ||
@@ -543,3 +543,3 @@ "default": true | ||
"MD022": { | ||
"description": "MD022/blanks-around-headings : Headings should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md022.md", | ||
"description": "MD022/blanks-around-headings : Headings should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md022.md", | ||
"type": [ | ||
@@ -579,3 +579,3 @@ "boolean", | ||
"blanks-around-headings": { | ||
"description": "MD022/blanks-around-headings : Headings should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md022.md", | ||
"description": "MD022/blanks-around-headings : Headings should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md022.md", | ||
"type": [ | ||
@@ -615,3 +615,3 @@ "boolean", | ||
"MD023": { | ||
"description": "MD023/heading-start-left : Headings must start at the beginning of the line : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md023.md", | ||
"description": "MD023/heading-start-left : Headings must start at the beginning of the line : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md023.md", | ||
"type": "boolean", | ||
@@ -621,3 +621,3 @@ "default": true | ||
"heading-start-left": { | ||
"description": "MD023/heading-start-left : Headings must start at the beginning of the line : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md023.md", | ||
"description": "MD023/heading-start-left : Headings must start at the beginning of the line : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md023.md", | ||
"type": "boolean", | ||
@@ -627,3 +627,3 @@ "default": true | ||
"MD024": { | ||
"description": "MD024/no-duplicate-heading : Multiple headings with the same content : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md024.md", | ||
"description": "MD024/no-duplicate-heading : Multiple headings with the same content : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md024.md", | ||
"type": [ | ||
@@ -644,3 +644,3 @@ "boolean", | ||
"no-duplicate-heading": { | ||
"description": "MD024/no-duplicate-heading : Multiple headings with the same content : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md024.md", | ||
"description": "MD024/no-duplicate-heading : Multiple headings with the same content : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md024.md", | ||
"type": [ | ||
@@ -661,3 +661,3 @@ "boolean", | ||
"MD025": { | ||
"description": "MD025/single-title/single-h1 : Multiple top-level headings in the same document : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md025.md", | ||
"description": "MD025/single-title/single-h1 : Multiple top-level headings in the same document : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md025.md", | ||
"type": [ | ||
@@ -685,3 +685,3 @@ "boolean", | ||
"single-title": { | ||
"description": "MD025/single-title/single-h1 : Multiple top-level headings in the same document : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md025.md", | ||
"description": "MD025/single-title/single-h1 : Multiple top-level headings in the same document : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md025.md", | ||
"type": [ | ||
@@ -709,3 +709,3 @@ "boolean", | ||
"single-h1": { | ||
"description": "MD025/single-title/single-h1 : Multiple top-level headings in the same document : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md025.md", | ||
"description": "MD025/single-title/single-h1 : Multiple top-level headings in the same document : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md025.md", | ||
"type": [ | ||
@@ -733,3 +733,3 @@ "boolean", | ||
"MD026": { | ||
"description": "MD026/no-trailing-punctuation : Trailing punctuation in heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md026.md", | ||
"description": "MD026/no-trailing-punctuation : Trailing punctuation in heading : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md026.md", | ||
"type": [ | ||
@@ -750,3 +750,3 @@ "boolean", | ||
"no-trailing-punctuation": { | ||
"description": "MD026/no-trailing-punctuation : Trailing punctuation in heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md026.md", | ||
"description": "MD026/no-trailing-punctuation : Trailing punctuation in heading : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md026.md", | ||
"type": [ | ||
@@ -767,3 +767,3 @@ "boolean", | ||
"MD027": { | ||
"description": "MD027/no-multiple-space-blockquote : Multiple spaces after blockquote symbol : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md027.md", | ||
"description": "MD027/no-multiple-space-blockquote : Multiple spaces after blockquote symbol : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md027.md", | ||
"type": "boolean", | ||
@@ -773,3 +773,3 @@ "default": true | ||
"no-multiple-space-blockquote": { | ||
"description": "MD027/no-multiple-space-blockquote : Multiple spaces after blockquote symbol : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md027.md", | ||
"description": "MD027/no-multiple-space-blockquote : Multiple spaces after blockquote symbol : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md027.md", | ||
"type": "boolean", | ||
@@ -779,3 +779,3 @@ "default": true | ||
"MD028": { | ||
"description": "MD028/no-blanks-blockquote : Blank line inside blockquote : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md028.md", | ||
"description": "MD028/no-blanks-blockquote : Blank line inside blockquote : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md028.md", | ||
"type": "boolean", | ||
@@ -785,3 +785,3 @@ "default": true | ||
"no-blanks-blockquote": { | ||
"description": "MD028/no-blanks-blockquote : Blank line inside blockquote : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md028.md", | ||
"description": "MD028/no-blanks-blockquote : Blank line inside blockquote : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md028.md", | ||
"type": "boolean", | ||
@@ -791,3 +791,3 @@ "default": true | ||
"MD029": { | ||
"description": "MD029/ol-prefix : Ordered list item prefix : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md029.md", | ||
"description": "MD029/ol-prefix : Ordered list item prefix : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md029.md", | ||
"type": [ | ||
@@ -814,3 +814,3 @@ "boolean", | ||
"ol-prefix": { | ||
"description": "MD029/ol-prefix : Ordered list item prefix : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md029.md", | ||
"description": "MD029/ol-prefix : Ordered list item prefix : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md029.md", | ||
"type": [ | ||
@@ -837,3 +837,3 @@ "boolean", | ||
"MD030": { | ||
"description": "MD030/list-marker-space : Spaces after list markers : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md030.md", | ||
"description": "MD030/list-marker-space : Spaces after list markers : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md030.md", | ||
"type": [ | ||
@@ -873,3 +873,3 @@ "boolean", | ||
"list-marker-space": { | ||
"description": "MD030/list-marker-space : Spaces after list markers : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md030.md", | ||
"description": "MD030/list-marker-space : Spaces after list markers : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md030.md", | ||
"type": [ | ||
@@ -909,3 +909,3 @@ "boolean", | ||
"MD031": { | ||
"description": "MD031/blanks-around-fences : Fenced code blocks should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md031.md", | ||
"description": "MD031/blanks-around-fences : Fenced code blocks should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md031.md", | ||
"type": [ | ||
@@ -926,3 +926,3 @@ "boolean", | ||
"blanks-around-fences": { | ||
"description": "MD031/blanks-around-fences : Fenced code blocks should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md031.md", | ||
"description": "MD031/blanks-around-fences : Fenced code blocks should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md031.md", | ||
"type": [ | ||
@@ -943,3 +943,3 @@ "boolean", | ||
"MD032": { | ||
"description": "MD032/blanks-around-lists : Lists should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md032.md", | ||
"description": "MD032/blanks-around-lists : Lists should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md032.md", | ||
"type": "boolean", | ||
@@ -949,3 +949,3 @@ "default": true | ||
"blanks-around-lists": { | ||
"description": "MD032/blanks-around-lists : Lists should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md032.md", | ||
"description": "MD032/blanks-around-lists : Lists should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md032.md", | ||
"type": "boolean", | ||
@@ -955,3 +955,3 @@ "default": true | ||
"MD033": { | ||
"description": "MD033/no-inline-html : Inline HTML : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md033.md", | ||
"description": "MD033/no-inline-html : Inline HTML : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md033.md", | ||
"type": [ | ||
@@ -975,3 +975,3 @@ "boolean", | ||
"no-inline-html": { | ||
"description": "MD033/no-inline-html : Inline HTML : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md033.md", | ||
"description": "MD033/no-inline-html : Inline HTML : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md033.md", | ||
"type": [ | ||
@@ -995,3 +995,3 @@ "boolean", | ||
"MD034": { | ||
"description": "MD034/no-bare-urls : Bare URL used : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md034.md", | ||
"description": "MD034/no-bare-urls : Bare URL used : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md034.md", | ||
"type": "boolean", | ||
@@ -1001,3 +1001,3 @@ "default": true | ||
"no-bare-urls": { | ||
"description": "MD034/no-bare-urls : Bare URL used : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md034.md", | ||
"description": "MD034/no-bare-urls : Bare URL used : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md034.md", | ||
"type": "boolean", | ||
@@ -1007,3 +1007,3 @@ "default": true | ||
"MD035": { | ||
"description": "MD035/hr-style : Horizontal rule style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md035.md", | ||
"description": "MD035/hr-style : Horizontal rule style : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md035.md", | ||
"type": [ | ||
@@ -1024,3 +1024,3 @@ "boolean", | ||
"hr-style": { | ||
"description": "MD035/hr-style : Horizontal rule style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md035.md", | ||
"description": "MD035/hr-style : Horizontal rule style : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md035.md", | ||
"type": [ | ||
@@ -1041,3 +1041,3 @@ "boolean", | ||
"MD036": { | ||
"description": "MD036/no-emphasis-as-heading : Emphasis used instead of a heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md036.md", | ||
"description": "MD036/no-emphasis-as-heading : Emphasis used instead of a heading : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md036.md", | ||
"type": [ | ||
@@ -1058,3 +1058,3 @@ "boolean", | ||
"no-emphasis-as-heading": { | ||
"description": "MD036/no-emphasis-as-heading : Emphasis used instead of a heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md036.md", | ||
"description": "MD036/no-emphasis-as-heading : Emphasis used instead of a heading : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md036.md", | ||
"type": [ | ||
@@ -1075,3 +1075,3 @@ "boolean", | ||
"MD037": { | ||
"description": "MD037/no-space-in-emphasis : Spaces inside emphasis markers : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md037.md", | ||
"description": "MD037/no-space-in-emphasis : Spaces inside emphasis markers : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md037.md", | ||
"type": "boolean", | ||
@@ -1081,3 +1081,3 @@ "default": true | ||
"no-space-in-emphasis": { | ||
"description": "MD037/no-space-in-emphasis : Spaces inside emphasis markers : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md037.md", | ||
"description": "MD037/no-space-in-emphasis : Spaces inside emphasis markers : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md037.md", | ||
"type": "boolean", | ||
@@ -1087,3 +1087,3 @@ "default": true | ||
"MD038": { | ||
"description": "MD038/no-space-in-code : Spaces inside code span elements : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md038.md", | ||
"description": "MD038/no-space-in-code : Spaces inside code span elements : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md038.md", | ||
"type": "boolean", | ||
@@ -1093,3 +1093,3 @@ "default": true | ||
"no-space-in-code": { | ||
"description": "MD038/no-space-in-code : Spaces inside code span elements : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md038.md", | ||
"description": "MD038/no-space-in-code : Spaces inside code span elements : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md038.md", | ||
"type": "boolean", | ||
@@ -1099,3 +1099,3 @@ "default": true | ||
"MD039": { | ||
"description": "MD039/no-space-in-links : Spaces inside link text : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md039.md", | ||
"description": "MD039/no-space-in-links : Spaces inside link text : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md039.md", | ||
"type": "boolean", | ||
@@ -1105,3 +1105,3 @@ "default": true | ||
"no-space-in-links": { | ||
"description": "MD039/no-space-in-links : Spaces inside link text : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md039.md", | ||
"description": "MD039/no-space-in-links : Spaces inside link text : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md039.md", | ||
"type": "boolean", | ||
@@ -1111,3 +1111,3 @@ "default": true | ||
"MD040": { | ||
"description": "MD040/fenced-code-language : Fenced code blocks should have a language specified : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md040.md", | ||
"description": "MD040/fenced-code-language : Fenced code blocks should have a language specified : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md040.md", | ||
"type": [ | ||
@@ -1136,3 +1136,3 @@ "boolean", | ||
"fenced-code-language": { | ||
"description": "MD040/fenced-code-language : Fenced code blocks should have a language specified : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md040.md", | ||
"description": "MD040/fenced-code-language : Fenced code blocks should have a language specified : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md040.md", | ||
"type": [ | ||
@@ -1161,3 +1161,3 @@ "boolean", | ||
"MD041": { | ||
"description": "MD041/first-line-heading/first-line-h1 : First line in a file should be a top-level heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md041.md", | ||
"description": "MD041/first-line-heading/first-line-h1 : First line in a file should be a top-level heading : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md041.md", | ||
"type": [ | ||
@@ -1185,3 +1185,3 @@ "boolean", | ||
"first-line-heading": { | ||
"description": "MD041/first-line-heading/first-line-h1 : First line in a file should be a top-level heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md041.md", | ||
"description": "MD041/first-line-heading/first-line-h1 : First line in a file should be a top-level heading : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md041.md", | ||
"type": [ | ||
@@ -1209,3 +1209,3 @@ "boolean", | ||
"first-line-h1": { | ||
"description": "MD041/first-line-heading/first-line-h1 : First line in a file should be a top-level heading : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md041.md", | ||
"description": "MD041/first-line-heading/first-line-h1 : First line in a file should be a top-level heading : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md041.md", | ||
"type": [ | ||
@@ -1233,3 +1233,3 @@ "boolean", | ||
"MD042": { | ||
"description": "MD042/no-empty-links : No empty links : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md042.md", | ||
"description": "MD042/no-empty-links : No empty links : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md042.md", | ||
"type": "boolean", | ||
@@ -1239,3 +1239,3 @@ "default": true | ||
"no-empty-links": { | ||
"description": "MD042/no-empty-links : No empty links : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md042.md", | ||
"description": "MD042/no-empty-links : No empty links : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md042.md", | ||
"type": "boolean", | ||
@@ -1245,3 +1245,3 @@ "default": true | ||
"MD043": { | ||
"description": "MD043/required-headings : Required heading structure : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md043.md", | ||
"description": "MD043/required-headings : Required heading structure : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md043.md", | ||
"type": [ | ||
@@ -1271,3 +1271,3 @@ "boolean", | ||
"required-headings": { | ||
"description": "MD043/required-headings : Required heading structure : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md043.md", | ||
"description": "MD043/required-headings : Required heading structure : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md043.md", | ||
"type": [ | ||
@@ -1297,3 +1297,3 @@ "boolean", | ||
"MD044": { | ||
"description": "MD044/proper-names : Proper names should have the correct capitalization : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md044.md", | ||
"description": "MD044/proper-names : Proper names should have the correct capitalization : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md044.md", | ||
"type": [ | ||
@@ -1327,3 +1327,3 @@ "boolean", | ||
"proper-names": { | ||
"description": "MD044/proper-names : Proper names should have the correct capitalization : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md044.md", | ||
"description": "MD044/proper-names : Proper names should have the correct capitalization : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md044.md", | ||
"type": [ | ||
@@ -1357,3 +1357,3 @@ "boolean", | ||
"MD045": { | ||
"description": "MD045/no-alt-text : Images should have alternate text (alt text) : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md045.md", | ||
"description": "MD045/no-alt-text : Images should have alternate text (alt text) : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md045.md", | ||
"type": "boolean", | ||
@@ -1363,3 +1363,3 @@ "default": true | ||
"no-alt-text": { | ||
"description": "MD045/no-alt-text : Images should have alternate text (alt text) : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md045.md", | ||
"description": "MD045/no-alt-text : Images should have alternate text (alt text) : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md045.md", | ||
"type": "boolean", | ||
@@ -1369,3 +1369,3 @@ "default": true | ||
"MD046": { | ||
"description": "MD046/code-block-style : Code block style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md046.md", | ||
"description": "MD046/code-block-style : Code block style : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md046.md", | ||
"type": [ | ||
@@ -1391,3 +1391,3 @@ "boolean", | ||
"code-block-style": { | ||
"description": "MD046/code-block-style : Code block style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md046.md", | ||
"description": "MD046/code-block-style : Code block style : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md046.md", | ||
"type": [ | ||
@@ -1413,3 +1413,3 @@ "boolean", | ||
"MD047": { | ||
"description": "MD047/single-trailing-newline : Files should end with a single newline character : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md047.md", | ||
"description": "MD047/single-trailing-newline : Files should end with a single newline character : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md047.md", | ||
"type": "boolean", | ||
@@ -1419,3 +1419,3 @@ "default": true | ||
"single-trailing-newline": { | ||
"description": "MD047/single-trailing-newline : Files should end with a single newline character : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md047.md", | ||
"description": "MD047/single-trailing-newline : Files should end with a single newline character : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md047.md", | ||
"type": "boolean", | ||
@@ -1425,3 +1425,3 @@ "default": true | ||
"MD048": { | ||
"description": "MD048/code-fence-style : Code fence style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md048.md", | ||
"description": "MD048/code-fence-style : Code fence style : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md048.md", | ||
"type": [ | ||
@@ -1447,3 +1447,3 @@ "boolean", | ||
"code-fence-style": { | ||
"description": "MD048/code-fence-style : Code fence style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md048.md", | ||
"description": "MD048/code-fence-style : Code fence style : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md048.md", | ||
"type": [ | ||
@@ -1469,3 +1469,3 @@ "boolean", | ||
"MD049": { | ||
"description": "MD049/emphasis-style : Emphasis style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md049.md", | ||
"description": "MD049/emphasis-style : Emphasis style : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md049.md", | ||
"type": [ | ||
@@ -1491,3 +1491,3 @@ "boolean", | ||
"emphasis-style": { | ||
"description": "MD049/emphasis-style : Emphasis style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md049.md", | ||
"description": "MD049/emphasis-style : Emphasis style : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md049.md", | ||
"type": [ | ||
@@ -1513,3 +1513,3 @@ "boolean", | ||
"MD050": { | ||
"description": "MD050/strong-style : Strong style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md050.md", | ||
"description": "MD050/strong-style : Strong style : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md050.md", | ||
"type": [ | ||
@@ -1535,3 +1535,3 @@ "boolean", | ||
"strong-style": { | ||
"description": "MD050/strong-style : Strong style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md050.md", | ||
"description": "MD050/strong-style : Strong style : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md050.md", | ||
"type": [ | ||
@@ -1557,3 +1557,3 @@ "boolean", | ||
"MD051": { | ||
"description": "MD051/link-fragments : Link fragments should be valid : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md051.md", | ||
"description": "MD051/link-fragments : Link fragments should be valid : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md051.md", | ||
"type": "boolean", | ||
@@ -1563,3 +1563,3 @@ "default": true | ||
"link-fragments": { | ||
"description": "MD051/link-fragments : Link fragments should be valid : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md051.md", | ||
"description": "MD051/link-fragments : Link fragments should be valid : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md051.md", | ||
"type": "boolean", | ||
@@ -1569,3 +1569,3 @@ "default": true | ||
"MD052": { | ||
"description": "MD052/reference-links-images : Reference links and images should use a label that is defined : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md052.md", | ||
"description": "MD052/reference-links-images : Reference links and images should use a label that is defined : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md052.md", | ||
"type": [ | ||
@@ -1586,3 +1586,3 @@ "boolean", | ||
"reference-links-images": { | ||
"description": "MD052/reference-links-images : Reference links and images should use a label that is defined : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md052.md", | ||
"description": "MD052/reference-links-images : Reference links and images should use a label that is defined : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md052.md", | ||
"type": [ | ||
@@ -1603,3 +1603,3 @@ "boolean", | ||
"MD053": { | ||
"description": "MD053/link-image-reference-definitions : Link and image reference definitions should be needed : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md053.md", | ||
"description": "MD053/link-image-reference-definitions : Link and image reference definitions should be needed : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md053.md", | ||
"type": [ | ||
@@ -1625,3 +1625,3 @@ "boolean", | ||
"link-image-reference-definitions": { | ||
"description": "MD053/link-image-reference-definitions : Link and image reference definitions should be needed : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md053.md", | ||
"description": "MD053/link-image-reference-definitions : Link and image reference definitions should be needed : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md053.md", | ||
"type": [ | ||
@@ -1647,3 +1647,3 @@ "boolean", | ||
"MD054": { | ||
"description": "MD054/link-image-style : Link and image style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md054.md", | ||
"description": "MD054/link-image-style : Link and image style : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md054.md", | ||
"type": [ | ||
@@ -1689,3 +1689,3 @@ "boolean", | ||
"link-image-style": { | ||
"description": "MD054/link-image-style : Link and image style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md054.md", | ||
"description": "MD054/link-image-style : Link and image style : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md054.md", | ||
"type": [ | ||
@@ -1731,3 +1731,3 @@ "boolean", | ||
"MD055": { | ||
"description": "MD055/table-pipe-style : Table pipe style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md055.md", | ||
"description": "MD055/table-pipe-style : Table pipe style : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md055.md", | ||
"type": [ | ||
@@ -1755,3 +1755,3 @@ "boolean", | ||
"table-pipe-style": { | ||
"description": "MD055/table-pipe-style : Table pipe style : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md055.md", | ||
"description": "MD055/table-pipe-style : Table pipe style : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md055.md", | ||
"type": [ | ||
@@ -1779,3 +1779,3 @@ "boolean", | ||
"MD056": { | ||
"description": "MD056/table-column-count : Table column count : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md056.md", | ||
"description": "MD056/table-column-count : Table column count : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md056.md", | ||
"type": "boolean", | ||
@@ -1785,6 +1785,16 @@ "default": true | ||
"table-column-count": { | ||
"description": "MD056/table-column-count : Table column count : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md056.md", | ||
"description": "MD056/table-column-count : Table column count : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md056.md", | ||
"type": "boolean", | ||
"default": true | ||
}, | ||
"MD058": { | ||
"description": "MD058/blanks-around-tables : Tables should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md058.md", | ||
"type": "boolean", | ||
"default": true | ||
}, | ||
"blanks-around-tables": { | ||
"description": "MD058/blanks-around-tables : Tables should be surrounded by blank lines : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md058.md", | ||
"type": "boolean", | ||
"default": true | ||
}, | ||
"headings": { | ||
@@ -1906,3 +1916,3 @@ "description": "headings : MD001, MD003, MD018, MD019, MD020, MD021, MD022, MD023, MD024, MD025, MD026, MD036, MD041, MD043", | ||
"table": { | ||
"description": "table : MD055, MD056", | ||
"description": "table : MD055, MD056, MD058", | ||
"type": "boolean", | ||
@@ -1909,0 +1919,0 @@ "default": true |
# Validating Configuration | ||
A [JSON Schema][json-schema] is provided to enable validating configuration | ||
objects: [`markdownlint-config-schema.json`][markdownlint-config-schema] | ||
objects: [`markdownlint-config-schema.json`][markdownlint-config-schema]. | ||
@@ -19,11 +19,9 @@ Some editors automatically use a JSON Schema with files that reference it. For | ||
By default, any rule name is valid in order to allow for custom rules. To ensure | ||
that only built-in rules are used, change the value of `#/additionalProperties` | ||
(at the bottom of the schema file) to `false` before validating: | ||
By default, any rule name is valid because of custom rules. To allow only | ||
built-in rules, use the | ||
[`markdownlint-config-schema-strict.json`][markdownlint-config-schema-strict] | ||
JSON Schema instead. | ||
```json | ||
"additionalProperties": false | ||
``` | ||
[json-schema]: https://json-schema.org | ||
[markdownlint-config-schema]: markdownlint-config-schema.json | ||
[markdownlint-config-schema-strict]: markdownlint-config-schema-strict.json |
@@ -10,2 +10,3 @@ { | ||
"heading-start-left": false, | ||
"heading-style": false, | ||
"hr-style": false, | ||
@@ -12,0 +13,0 @@ "line-length": false, |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
810060
132
17796
1048
25
+ Addedmarkdownlint-micromark@0.1.10(transitive)
- Removedmarkdownlint-micromark@0.1.9(transitive)