Add "enabled" and "severity"/"warning" to rule in Configuration object, add corresponding documentation and tests, update demo web app (fixes #254)”.

This commit is contained in:
David Anson 2025-09-22 21:39:09 -07:00
parent c6f248321e
commit 607be34b5d
20 changed files with 3792 additions and 867 deletions

View file

@ -362,54 +362,111 @@ of `files` or `strings` should be set to provide input.
##### options.config ##### options.config
Type: `Object` mapping `String` to `Boolean | "error" | Object` Type: `Object` mapping `String` to `Boolean | "error" | "warning" | Object`
Configures the rules to use. Configures the rules to use.
Object keys are rule names/aliases; object 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. The values `true` or `"error"` enable a rule The value `false` disables a rule. The values `true` or `"error"` enable a rule
in its default configuration and report violations as errors. Passing an object in its default configuration and report violations as errors. The value
enables and customizes the rule. The special `default` rule assigns the default `"warning"` enables a rule in its default configuration and reports violations
for all rules. Using a tag name (e.g., `whitespace`) and a setting of `false`, as warnings. Passing an object enables *and* customizes the rule; the properties
`true`, or `"error"` applies that setting to all rules with that tag. When no `severity` (`"error" | "warning"`) and `enabled` (`false | true`) can be used in
configuration object is passed or the optional `default` setting is not present, this context. The special `default` rule assigns the default for all rules.
all rules are enabled. Using a tag name (e.g., `whitespace`) and a setting of `false`, `true`,
`"error"`, or `"warning"` applies that setting to all rules with that tag. When
no configuration object is passed or the optional `default` setting is not
present, all rules are enabled.
The following syntax disables the specified rule, tag, or `default`: The following syntax disables the specified rule, tag, or `default`:
```javascript ```javascript
{ {
"rule_name": false "rule_tag_or_default": false
} }
``` ```
The following syntax enables the specified rule, tag, or `default`: The following syntax enables the specified rule, tag, or `default` to report
violations as errors:
```javascript ```javascript
{ {
"rule_name": true "rule_tag_or_default": true
// OR // OR
"rule_name": "error" "rule_tag_or_default": "error"
} }
``` ```
The following syntax enables and configures the specified rule: The following syntax enables the specified rule, tag, or `default` to report
violations as warnings:
```javascript ```javascript
{ {
"rule_name": { "rule_tag_or_default": "warning"
"parameter": "value" }
} ```
// OR
"rule_name": { The following syntax enables and configures the specified rule to report
"parameter": "value", violations as errors:
```javascript
{
"rule": {
"severity": "error" "severity": "error"
} }
// OR
"rule": {
"rule_parameter": "value"
}
// OR
"rule": {
"severity": "error",
"rule_parameter": "value"
}
} }
``` ```
> Note that `error` and `severity` are not supported by library versions earlier The following syntax enables and configures the specified rule to report
> than `0.39.0`. However, all examples above behave the same. violations as warnings:
```javascript
{
"rule": {
"severity": "warning"
}
// OR
"rule": {
"severity": "warning",
"rule_parameter": "value"
}
}
```
> Note that values `"error"` and `"warning"` and the property `severity` are not
> supported by library versions earlier than `0.39.0`. However, the examples
> above behave the same there, with warnings being reported as errors.
The following syntax disables and configures the specified rule:
```javascript
{
"rule": {
"enabled": false,
"rule_parameter": "value"
}
// OR
"rule": {
"enabled": false,
"severity": "warning",
"rule_parameter": "value"
}
}
```
> Note that this example behaves **differently** with library versions earlier
> than `0.39.0` because the property `enabled` is not supported: it **enables**
> the rule instead of **disabling** it. As such, this syntax is discouraged when
> interoperability is important.
To evaluate a configuration object, the `default` setting is applied first, then To evaluate a configuration object, the `default` setting is applied first, then
keys are processed in order from top to bottom. If multiple values apply to a keys are processed in order from top to bottom. If multiple values apply to a

View file

@ -47,6 +47,9 @@ textarea {
font-style: italic; font-style: italic;
white-space: pre-wrap; white-space: pre-wrap;
} }
.warning {
background: rgb(255, 255, 0, 0.5);
}
.error { .error {
background: rgb(255, 0, 0, 0.3); background: rgb(255, 0, 0, 0.3);
} }
@ -67,7 +70,7 @@ textarea {
min-height: 0; min-height: 0;
} }
.highlight { .highlight {
background: rgb(255, 0, 0, 0.8); background: rgb(0, 255, 255, 0.8);
} }
.inset { .inset {
box-sizing: border-box; box-sizing: border-box;

View file

@ -86,8 +86,8 @@
return `[Unsupported renderer "${renderer}"]`; return `[Unsupported renderer "${renderer}"]`;
} }
// Highlight error ranges // Highlight ranges
function highlightErrors(results, className) { function highlightRanges(results, className) {
for (const result of results) { for (const result of results) {
const { errorRange, lineNumber } = result; const { errorRange, lineNumber } = result;
const line = document.getElementById(`l${lineNumber}`); const line = document.getElementById(`l${lineNumber}`);
@ -150,14 +150,18 @@
sanitize(result.errorContext) + sanitize(result.errorContext) +
"\"</span>]" : "\"</span>]" :
"") + "") +
" [<span class='detail'>" +
result.severity +
"</span>]" +
(result.fixInfo ? (result.fixInfo ?
" [<a href='#fix' target='" + " [<a href='#fix' target='" +
resultJson + resultJson +
"' class='detail'>Fix</a>]" : "' class='detail'>Fix</a>]" :
""); "");
}).join("<br/>"); }).join("<br/>");
// Highlight errors // Highlight errors and warnings
highlightErrors(allLintErrors, "error"); highlightRanges(allLintErrors.filter((error) => error.severity === "warning"), "warning");
highlightRanges(allLintErrors.filter((error) => error.severity === "error"), "error");
} }
// Load from a string or File object // Load from a string or File object
@ -216,7 +220,7 @@
for (const element of [ ...document.getElementsByClassName("highlight") ]) { for (const element of [ ...document.getElementsByClassName("highlight") ]) {
element.classList.remove("highlight"); element.classList.remove("highlight");
} }
highlightErrors([ resultJson ], "highlight"); highlightRanges([ resultJson ], "highlight");
var line = document.getElementById(`l${resultJson.lineNumber}`); var line = document.getElementById(`l${resultJson.lineNumber}`);
line.scrollIntoView(); line.scrollIntoView();
e.preventDefault(); e.preventDefault();

View file

@ -64,7 +64,7 @@ for (const rule of rules) {
const ruleProperties = Object.fromEntries( const ruleProperties = Object.fromEntries(
Object.entries( Object.entries(
ruleData.oneOf.at(-1).properties ruleData.oneOf.at(-1).properties
).filter(([ key ]) => key !== "severity") ).filter(([ key ]) => ((key !== "enabled") && (key !== "severity")))
); );
if (Object.keys(ruleProperties).length > 0) { if (Object.keys(ruleProperties).length > 0) {
section.push( section.push(

File diff suppressed because it is too large Load diff

View file

@ -82,6 +82,23 @@ export function applyFixes(input: string, errors: LintError[]): string;
* @returns {string} SemVer string. * @returns {string} SemVer string.
*/ */
export function getVersion(): string; export function getVersion(): string;
/**
* Result object for getEffectiveConfig.
*/
export type GetEffectiveConfigResult = {
/**
* Effective configuration.
*/
effectiveConfig: Configuration;
/**
* Rules enabled.
*/
rulesEnabled: Map<string, boolean>;
/**
* Rules severity.
*/
rulesSeverity: Map<string, "error" | "warning">;
};
/** /**
* Result object for getEnabledRulesPerLineNumber. * Result object for getEnabledRulesPerLineNumber.
*/ */
@ -93,11 +110,15 @@ export type EnabledRulesPerLineNumberResult = {
/** /**
* Enabled rules per line number. * Enabled rules per line number.
*/ */
enabledRulesPerLineNumber: any[]; enabledRulesPerLineNumber: Map<string, boolean>[];
/** /**
* Enabled rule list. * Enabled rule list.
*/ */
enabledRuleList: Rule[]; enabledRuleList: Rule[];
/**
* Rules severity.
*/
rulesSeverity: Map<string, "error" | "warning">;
}; };
/** /**
* Function to implement rule logic. * Function to implement rule logic.

View file

@ -236,44 +236,87 @@ function mapAliasToRuleNames(ruleList) {
return aliasToRuleNames; return aliasToRuleNames;
} }
/**
* Result object for getEffectiveConfig.
*
* @typedef {Object} GetEffectiveConfigResult
* @property {Configuration} effectiveConfig Effective configuration.
* @property {Map<string, boolean>} rulesEnabled Rules enabled.
* @property {Map<string, "error" | "warning">} rulesSeverity Rules severity.
*/
/** /**
* Apply (and normalize) configuration object. * Apply (and normalize) configuration object.
* *
* @param {Rule[]} ruleList List of rules. * @param {Rule[]} ruleList List of rules.
* @param {Configuration} config Configuration object. * @param {Configuration} config Configuration object.
* @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule * @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule names.
* names. * @returns {GetEffectiveConfigResult} Effective configuration and rule severities.
* @returns {Configuration} Effective configuration.
*/ */
function getEffectiveConfig(ruleList, config, aliasToRuleNames) { function getEffectiveConfig(ruleList, config, aliasToRuleNames) {
const defaultKey = Object.keys(config).filter( let ruleDefaultEnable = true;
(key) => key.toUpperCase() === "DEFAULT" /** @type {"error" | "warning"} */
); let ruleDefaultSeverity = "error";
const ruleDefault = (defaultKey.length === 0) || !!config[defaultKey[0]]; Object.entries(config).every(([ key, value ]) => {
if (key.toUpperCase() === "DEFAULT") {
ruleDefaultEnable = !!value;
if (value === "warning") {
ruleDefaultSeverity = "warning";
}
return false;
}
return true;
});
/** @type {Configuration} */ /** @type {Configuration} */
const effectiveConfig = {}; const effectiveConfig = {};
for (const rule of ruleList) { /** @type {Map<string, boolean>} */
const ruleName = rule.names[0].toUpperCase(); const rulesEnabled = new Map();
effectiveConfig[ruleName] = ruleDefault; /** @type {Map<string, "error" | "warning">} */
const rulesSeverity = new Map();
const emptyObject = Object.freeze({});
for (const ruleName of ruleList.map((rule) => rule.names[0].toUpperCase())) {
effectiveConfig[ruleName] = emptyObject;
rulesEnabled.set(ruleName, ruleDefaultEnable);
rulesSeverity.set(ruleName, ruleDefaultSeverity);
} }
// for (const ruleName of deprecatedRuleNames) { // for (const ruleName of deprecatedRuleNames) {
// effectiveConfig[ruleName] = false; // effectiveConfig[ruleName] = false;
// } // }
for (const key of Object.keys(config)) { for (const [ key, value ] of Object.entries(config)) {
let value = config[key];
if (value) {
value = (value instanceof Object) ?
Object.fromEntries(Object.entries(value).filter(([ k ]) => k !== "severity")) :
{};
} else {
value = false;
}
const keyUpper = key.toUpperCase(); const keyUpper = key.toUpperCase();
/** @type {boolean} */
let enabled = false;
/** @type {"error" | "warning"} */
let severity = "error";
let effectiveValue = {};
if (value) {
if (value instanceof Object) {
/** @type {{ enabled?: boolean, severity?: "error" | "warning" }} */
const valueObject = value;
enabled = (valueObject.enabled === undefined) ? true : !!valueObject.enabled;
severity = (valueObject.severity === "warning") ? "warning" : "error";
effectiveValue = Object.fromEntries(
Object.entries(value).filter(
([ k ]) => (k !== "enabled") && (k !== "severity")
)
);
} else {
enabled = true;
severity = (value === "warning") ? "warning" : "error";
}
}
for (const ruleName of (aliasToRuleNames[keyUpper] || [])) { for (const ruleName of (aliasToRuleNames[keyUpper] || [])) {
effectiveConfig[ruleName] = value; Object.freeze(effectiveValue);
effectiveConfig[ruleName] = effectiveValue;
rulesEnabled.set(ruleName, enabled);
rulesSeverity.set(ruleName, severity);
} }
} }
return effectiveConfig; return {
effectiveConfig,
rulesEnabled,
rulesSeverity
};
} }
/** /**
@ -281,8 +324,9 @@ function getEffectiveConfig(ruleList, config, aliasToRuleNames) {
* *
* @typedef {Object} EnabledRulesPerLineNumberResult * @typedef {Object} EnabledRulesPerLineNumberResult
* @property {Configuration} effectiveConfig Effective configuration. * @property {Configuration} effectiveConfig Effective configuration.
* @property {any[]} enabledRulesPerLineNumber Enabled rules per line number. * @property {Map<string, boolean>[]} enabledRulesPerLineNumber Enabled rules per line number.
* @property {Rule[]} enabledRuleList Enabled rule list. * @property {Rule[]} enabledRuleList Enabled rule list.
* @property {Map<string, "error" | "warning">} rulesSeverity Rules severity.
*/ */
/** /**
@ -294,8 +338,7 @@ function getEffectiveConfig(ruleList, config, aliasToRuleNames) {
* @param {boolean} noInlineConfig Whether to allow inline configuration. * @param {boolean} noInlineConfig Whether to allow inline configuration.
* @param {Configuration} config Configuration object. * @param {Configuration} config Configuration object.
* @param {ConfigurationParser[] | undefined} configParsers Configuration parsers. * @param {ConfigurationParser[] | undefined} configParsers Configuration parsers.
* @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule * @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule names.
* names.
* @returns {EnabledRulesPerLineNumberResult} Effective configuration and enabled rules per line number. * @returns {EnabledRulesPerLineNumberResult} Effective configuration and enabled rules per line number.
*/ */
function getEnabledRulesPerLineNumber( function getEnabledRulesPerLineNumber(
@ -307,9 +350,10 @@ function getEnabledRulesPerLineNumber(
configParsers, configParsers,
aliasToRuleNames) { aliasToRuleNames) {
// Shared variables // Shared variables
let enabledRules = {}; /** @type {Map<string, boolean>} */
let capturedRules = {}; let enabledRules = new Map();
const allRuleNames = []; /** @type {Map<string, boolean>} */
let capturedRules = enabledRules;
const enabledRulesPerLineNumber = new Array(1 + frontMatterLines.length); const enabledRulesPerLineNumber = new Array(1 + frontMatterLines.length);
// Helper functions // Helper functions
// eslint-disable-next-line jsdoc/require-jsdoc // eslint-disable-next-line jsdoc/require-jsdoc
@ -349,13 +393,14 @@ function getEnabledRulesPerLineNumber(
} }
// eslint-disable-next-line jsdoc/require-jsdoc // eslint-disable-next-line jsdoc/require-jsdoc
function applyEnableDisable(action, parameter, state) { function applyEnableDisable(action, parameter, state) {
state = { ...state }; state = new Map(state);
const enabled = (action.startsWith("ENABLE")); const enabled = (action.startsWith("ENABLE"));
const trimmed = parameter && parameter.trim(); const trimmed = parameter && parameter.trim();
// eslint-disable-next-line no-use-before-define
const items = trimmed ? trimmed.toUpperCase().split(/\s+/) : allRuleNames; const items = trimmed ? trimmed.toUpperCase().split(/\s+/) : allRuleNames;
for (const nameUpper of items) { for (const nameUpper of items) {
for (const ruleName of (aliasToRuleNames[nameUpper] || [])) { for (const ruleName of (aliasToRuleNames[nameUpper] || [])) {
state[ruleName] = enabled; state.set(ruleName, enabled);
} }
} }
return state; return state;
@ -397,29 +442,24 @@ function getEnabledRulesPerLineNumber(
} }
// Handle inline comments // Handle inline comments
handleInlineConfig([ lines.join("\n") ], configureFile); handleInlineConfig([ lines.join("\n") ], configureFile);
const effectiveConfig = getEffectiveConfig( const { effectiveConfig, rulesEnabled, rulesSeverity } = getEffectiveConfig(ruleList, config, aliasToRuleNames);
ruleList, config, aliasToRuleNames); const allRuleNames = [ ...rulesEnabled.keys() ];
for (const rule of ruleList) { enabledRules = new Map(rulesEnabled);
const ruleName = rule.names[0].toUpperCase();
allRuleNames.push(ruleName);
enabledRules[ruleName] = !!effectiveConfig[ruleName];
}
capturedRules = enabledRules; capturedRules = enabledRules;
handleInlineConfig(lines, enableDisableFile); handleInlineConfig(lines, enableDisableFile);
handleInlineConfig(lines, captureRestoreEnableDisable, updateLineState); handleInlineConfig(lines, captureRestoreEnableDisable, updateLineState);
handleInlineConfig(lines, disableLineNextLine); handleInlineConfig(lines, disableLineNextLine);
// Create the list of rules that are used at least once // Create the list of rules that are used at least once
const enabledRuleList = []; const enabledRuleList = ruleList.filter((rule) => {
for (const [ index, ruleName ] of allRuleNames.entries()) { const ruleName = rule.names[0].toUpperCase();
if (enabledRulesPerLineNumber.some((enabledRulesForLine) => enabledRulesForLine[ruleName])) { return enabledRulesPerLineNumber.some((enabledRulesForLine) => enabledRulesForLine.get(ruleName));
enabledRuleList.push(ruleList[index]); });
}
}
// Return results // Return results
return { return {
effectiveConfig, effectiveConfig,
enabledRulesPerLineNumber, enabledRulesPerLineNumber,
enabledRuleList enabledRuleList,
rulesSeverity
}; };
} }
@ -464,7 +504,7 @@ function lintContent(
const { frontMatterLines } = removeFrontMatterResult; const { frontMatterLines } = removeFrontMatterResult;
content = removeFrontMatterResult.content; content = removeFrontMatterResult.content;
// Get enabled rules per line (with HTML comments present) // Get enabled rules per line (with HTML comments present)
const { effectiveConfig, enabledRulesPerLineNumber, enabledRuleList } = const { effectiveConfig, enabledRulesPerLineNumber, enabledRuleList, rulesSeverity } =
getEnabledRulesPerLineNumber( getEnabledRulesPerLineNumber(
ruleList, ruleList,
content.split(helpers.newLineRe), content.split(helpers.newLineRe),
@ -541,12 +581,12 @@ function lintContent(
} else if (rule.parser === "micromark") { } else if (rule.parser === "micromark") {
parsers = parsersMicromark; parsers = parsersMicromark;
} }
const params = { const params = Object.freeze({
...paramsBase, ...paramsBase,
...tokens, ...tokens,
parsers, parsers,
"config": (typeof effectiveConfig[ruleName] === "object") ? { ...effectiveConfig[ruleName] } : effectiveConfig[ruleName] "config": effectiveConfig[ruleName]
}; });
// eslint-disable-next-line jsdoc/require-jsdoc // eslint-disable-next-line jsdoc/require-jsdoc
function throwError(property) { function throwError(property) {
throw new Error( throw new Error(
@ -561,7 +601,7 @@ function lintContent(
throwError("lineNumber"); throwError("lineNumber");
} }
const lineNumber = errorInfo.lineNumber + frontMatterLines.length; const lineNumber = errorInfo.lineNumber + frontMatterLines.length;
if (!enabledRulesPerLineNumber[lineNumber][ruleName]) { if (!enabledRulesPerLineNumber[lineNumber].get(ruleName)) {
return; return;
} }
if (errorInfo.detail && if (errorInfo.detail &&
@ -638,7 +678,8 @@ function lintContent(
"errorContext": errorInfo.context?.replace(helpers.newLineRe, " ") || null, "errorContext": errorInfo.context?.replace(helpers.newLineRe, " ") || null,
"errorRange": errorInfo.range ? [ ...errorInfo.range ] : null, "errorRange": errorInfo.range ? [ ...errorInfo.range ] : null,
"fixInfo": fixInfo ? cleanFixInfo : null, "fixInfo": fixInfo ? cleanFixInfo : null,
"severity": "error" // @ts-ignore
"severity": rulesSeverity.get(ruleName)
}); });
} }
// Call (possibly external) rule function to report errors // Call (possibly external) rule function to report errors

View file

@ -16,7 +16,7 @@ for (const rule in configSchema.properties) {
const subproperties = Object.fromEntries( const subproperties = Object.fromEntries(
Object.entries( Object.entries(
properties.oneOf?.at(-1).properties || [] properties.oneOf?.at(-1).properties || []
).filter(([ key ]) => key !== "severity") ).filter(([ key ]) => ((key !== "enabled") && (key !== "severity")))
); );
if (Object.keys(subproperties).length > 0) { if (Object.keys(subproperties).length > 0) {
/** @type {Object<string, any>} */ /** @type {Object<string, any>} */

View file

@ -30,7 +30,7 @@ const schema = {
"description": "Default state for all rules", "description": "Default state for all rules",
"oneOf": [ "oneOf": [
{ "type": "boolean" }, { "type": "boolean" },
{ "enum": [ "error" ] } { "enum": [ "error", "warning" ] }
], ],
"default": true "default": true
}, },
@ -66,7 +66,7 @@ for (const rule of rules) {
`${rule.names.join("/")} : ${rule.description} : ${rule.information}`, `${rule.names.join("/")} : ${rule.description} : ${rule.information}`,
"oneOf": [ "oneOf": [
{ "type": "boolean" }, { "type": "boolean" },
{ "enum": [ "error" ] } { "enum": [ "error", "warning" ] }
], ],
"default": true "default": true
}; };
@ -74,12 +74,15 @@ for (const rule of rules) {
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,
"properties": { "properties": {
"enabled": {
"description": "Whether to enable the rule",
"type": "boolean",
"default": true
},
"severity": { "severity": {
"description": "Rule severity", "description": "Rule severity",
"type": "string", "type": "string",
"enum": [ "enum": [ "error", "warning" ],
"error"
],
"default": "error" "default": "error"
} }
} }
@ -656,7 +659,7 @@ for (const [ tag, tagTags ] of Object.entries(tags)) {
"description": `${tag} : ${tagTags.join(", ")}`, "description": `${tag} : ${tagTags.join(", ")}`,
"oneOf": [ "oneOf": [
{ "type": "boolean" }, { "type": "boolean" },
{ "enum": [ "error" ] } { "enum": [ "error", "warning" ] }
], ],
"default": true "default": true
}; };

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,47 @@
# Configure File Off Enable Inline
+ List item
Text (text)[.]
<!-- markdownlint-disable -->
+ List item
Text (text)[.]
<!-- markdownlint-restore -->
+ List item
Text (text)[.]
<!-- markdownlint-enable MD004 MD011 -->
+ List item {MD004}
Text (text)[.] {MD011}
<!-- markdownlint-disable -->
+ List item
Text (text)[.]
<!-- markdownlint-enable MD004 MD011 -->
+ List item {MD004}
Text (text)[.] {MD011}
<!-- markdownlint-configure-file {
"MD004": {
"enabled": false,
"severity": "warning",
"style": "dash"
},
"MD011": {
"enabled": false,
"severity": "error"
}
} -->

View file

@ -0,0 +1,58 @@
# Configure File With Severity Alias
Text * text* {MD037}
Text ` text` {MD038}
Text [ text](.)
+ List item {MD004}
Text (text)[.] {MD011}
2. List item
<!-- markdownlint-disable -->
Text * text*
Text ` text`
Text [ text](.)
+ List item
Text (text)[.]
2. List item
<!-- markdownlint-restore -->
Text * text* {MD037}
Text ` text` {MD038}
Text [ text](.)
+ List item {MD004}
Text (text)[.] {MD011}
2. List item
<!-- markdownlint-configure-file {
"default": false,
"no-space-in-emphasis": "error",
"no-space-in-code": "warning",
"no-space-in-links": false,
"ul-style": {
"severity": "error",
"style": "dash"
},
"no-reversed-links": {
"severity": "warning"
},
"ol-prefix": {
"enabled": false
}
} -->

View file

@ -1,16 +1,16 @@
# Configure File With Severity # Configure File With Severity Name
Text * text* {MD037} Text * text* {MD037}
Text ` text` {MD038} Text ` text` {MD038}
Text [ text](.) {MD039} Text [ text](.)
+ List item {MD004} + List item {MD004}
Text (text)[.] {MD011} Text (text)[.] {MD011}
2. List item {MD029} 2. List item
<!-- markdownlint-disable --> <!-- markdownlint-disable -->
@ -32,27 +32,27 @@ Text * text* {MD037}
Text ` text` {MD038} Text ` text` {MD038}
Text [ text](.) {MD039} Text [ text](.)
+ List item {MD004} + List item {MD004}
Text (text)[.] {MD011} Text (text)[.] {MD011}
2. List item {MD029} 2. List item
<!-- markdownlint-configure-file { <!-- markdownlint-configure-file {
"default": false, "default": false,
"MD037": "error", "MD037": "error",
"MD038": "error", "MD038": "warning",
"MD039": "error", "MD039": false,
"MD004": { "MD004": {
"severity": "error", "severity": "error",
"style": "dash" "style": "dash"
}, },
"MD011": { "MD011": {
"severity": "error" "severity": "warning"
}, },
"MD029": { "MD029": {
"severity": "error" "enabled": false
} }
} --> } -->

View file

@ -0,0 +1,50 @@
# Configure File With Severity Tag
Text * text* {MD037}
Text ` text` {MD038}
Text [ text](.) {MD039}
+ List item
Text (text)[.] {MD011}
2. List item {MD029}
<!-- markdownlint-disable -->
Text * text*
Text ` text`
Text [ text](.)
+ List item
Text (text)[.]
2. List item
<!-- markdownlint-restore -->
Text * text* {MD037}
Text ` text` {MD038}
Text [ text](.) {MD039}
+ List item
Text (text)[.] {MD011}
2. List item {MD029}
<!-- markdownlint-configure-file {
"default": false,
"emphasis": "error",
"code": "warning",
"bullet": false,
"links": "warning",
"ol": "error"
} -->

View file

@ -2037,7 +2037,7 @@ test("customRulesParamsAreFrozen", (t) => {
const pending = [ params ]; const pending = [ params ];
let current = null; let current = null;
while ((current = pending.shift())) { while ((current = pending.shift())) {
t.true(Object.isFrozen(current) || (current === params)); t.true(Object.isFrozen(current));
for (const name of Object.getOwnPropertyNames(current)) { for (const name of Object.getOwnPropertyNames(current)) {
// @ts-ignore // @ts-ignore
const value = current[name]; const value = current[name];
@ -2083,7 +2083,7 @@ test("customRulesParamsAreFrozen", (t) => {
}); });
test("customRulesParamsAreStable", (t) => { test("customRulesParamsAreStable", (t) => {
t.plan(6); t.plan(4);
const config1 = { "value1": 10 }; const config1 = { "value1": 10 };
const config2 = { "value2": 20 }; const config2 = { "value2": 20 };
/** @type {import("markdownlint").Options} */ /** @type {import("markdownlint").Options} */
@ -2108,7 +2108,6 @@ test("customRulesParamsAreStable", (t) => {
t.deepEqual(config, config1, `Unexpected config in sync path: ${config}.`); t.deepEqual(config, config1, `Unexpected config in sync path: ${config}.`);
return Promise.resolve().then(() => { return Promise.resolve().then(() => {
t.deepEqual(config, config1, `Unexpected config in async path: ${config}.`); t.deepEqual(config, config1, `Unexpected config in async path: ${config}.`);
config.extra = 1;
}); });
} }
}, },
@ -2124,7 +2123,6 @@ test("customRulesParamsAreStable", (t) => {
t.deepEqual(config, config2, `Unexpected config in sync path: ${config}.`); t.deepEqual(config, config2, `Unexpected config in sync path: ${config}.`);
return Promise.resolve().then(() => { return Promise.resolve().then(() => {
t.deepEqual(config, config2, `Unexpected config in async path: ${config}.`); t.deepEqual(config, config2, `Unexpected config in async path: ${config}.`);
config.extra = 2;
}); });
} }
} }
@ -2133,10 +2131,7 @@ test("customRulesParamsAreStable", (t) => {
"string": "# Heading" "string": "# Heading"
} }
}; };
return lintPromise(options).then(() => { return lintPromise(options);
t.deepEqual(config1, { "value1": 10 });
t.deepEqual(config2, { "value2": 20 });
});
}); });
test("customRulesParamsAreExpected", (t) => { test("customRulesParamsAreExpected", (t) => {
@ -2155,7 +2150,7 @@ test("customRulesParamsAreExpected", (t) => {
"description": "description", "description": "description",
"tags": [ "tag" ], "tags": [ "tag" ],
"parser": "none", "parser": "none",
"function": (params) => t.deepEqual(params.config, true) "function": (params) => t.deepEqual(params.config, {})
}, },
{ {
"names": [ "name2" ], "names": [ "name2" ],

View file

@ -347,6 +347,7 @@ test("getPreferredLineEnding", (t) => {
const actual = helpers.getPreferredLineEnding(input); const actual = helpers.getPreferredLineEnding(input);
t.is(actual, expected, "Incorrect line ending returned."); t.is(actual, expected, "Incorrect line ending returned.");
} }
// @ts-ignore
t.is(helpers.getPreferredLineEnding("", null), "\n"); t.is(helpers.getPreferredLineEnding("", null), "\n");
t.is(helpers.getPreferredLineEnding("", { "EOL": "\n" }), "\n"); t.is(helpers.getPreferredLineEnding("", { "EOL": "\n" }), "\n");
t.is(helpers.getPreferredLineEnding("", { "EOL": "\r\n" }), "\r\n"); t.is(helpers.getPreferredLineEnding("", { "EOL": "\r\n" }), "\r\n");
@ -358,29 +359,37 @@ test("expandTildePath", (t) => {
const homedir = os.homedir(); const homedir = os.homedir();
t.is(helpers.expandTildePath("", os), ""); t.is(helpers.expandTildePath("", os), "");
t.is(helpers.expandTildePath("", {}), ""); t.is(helpers.expandTildePath("", {}), "");
// @ts-ignore
t.is(helpers.expandTildePath("", null), ""); t.is(helpers.expandTildePath("", null), "");
t.is( t.is(
path.resolve(helpers.expandTildePath("~", os)), path.resolve(helpers.expandTildePath("~", os)),
homedir homedir
); );
// @ts-ignore
t.is(helpers.expandTildePath("~", null), "~"); t.is(helpers.expandTildePath("~", null), "~");
t.is(helpers.expandTildePath("file", os), "file"); t.is(helpers.expandTildePath("file", os), "file");
// @ts-ignore
t.is(helpers.expandTildePath("file", null), "file"); t.is(helpers.expandTildePath("file", null), "file");
t.is(helpers.expandTildePath("/file", os), "/file"); t.is(helpers.expandTildePath("/file", os), "/file");
// @ts-ignore
t.is(helpers.expandTildePath("/file", null), "/file"); t.is(helpers.expandTildePath("/file", null), "/file");
t.is( t.is(
path.resolve(helpers.expandTildePath("~/file", os)), path.resolve(helpers.expandTildePath("~/file", os)),
path.join(homedir, "/file") path.join(homedir, "/file")
); );
// @ts-ignore
t.is(helpers.expandTildePath("~/file", null), "~/file"); t.is(helpers.expandTildePath("~/file", null), "~/file");
t.is(helpers.expandTildePath("dir/file", os), "dir/file"); t.is(helpers.expandTildePath("dir/file", os), "dir/file");
// @ts-ignore
t.is(helpers.expandTildePath("dir/file", null), "dir/file"); t.is(helpers.expandTildePath("dir/file", null), "dir/file");
t.is(helpers.expandTildePath("/dir/file", os), "/dir/file"); t.is(helpers.expandTildePath("/dir/file", os), "/dir/file");
// @ts-ignore
t.is(helpers.expandTildePath("/dir/file", null), "/dir/file"); t.is(helpers.expandTildePath("/dir/file", null), "/dir/file");
t.is( t.is(
path.resolve(helpers.expandTildePath("~/dir/file", os)), path.resolve(helpers.expandTildePath("~/dir/file", os)),
path.join(homedir, "/dir/file") path.join(homedir, "/dir/file")
); );
// @ts-ignore
t.is(helpers.expandTildePath("~/dir/file", null), "~/dir/file"); t.is(helpers.expandTildePath("~/dir/file", null), "~/dir/file");
}); });
@ -396,6 +405,7 @@ test("getReferenceLinkImageData().shortcuts", (t) => {
"parser": "none", "parser": "none",
"function": "function":
() => { () => {
// @ts-ignore
const { shortcuts } = getReferenceLinkImageData(); const { shortcuts } = getReferenceLinkImageData();
t.is(shortcuts.size, 0, [ ...shortcuts.keys() ].join(", ")); t.is(shortcuts.size, 0, [ ...shortcuts.keys() ].join(", "));
} }
@ -533,14 +543,14 @@ test("hasOverlap", (t) => {
test("formatLintResults", async(t) => { test("formatLintResults", async(t) => {
t.plan(2); t.plan(2);
t.deepEqual(formatLintResults(undefined), []); t.deepEqual(formatLintResults(undefined), []);
const lintResults = await lint({ "strings": { "content": "# Heading\n<br/>" } }); const lintResults = await lint({ "strings": { "content": "# Heading\n<br/><!-- markdownlint-configure-file { \"MD033\": \"warning\" } -->" } });
t.deepEqual( t.deepEqual(
formatLintResults(lintResults), formatLintResults(lintResults),
[ [
"content:1:3 error MD019/no-multiple-space-atx Multiple spaces after hash on atx style heading [Context: \"# Heading\"]", "content:1:3 error MD019/no-multiple-space-atx Multiple spaces after hash on atx style heading [Context: \"# Heading\"]",
"content:1 error MD022/blanks-around-headings Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: \"# Heading\"]", "content:1 error MD022/blanks-around-headings Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: \"# Heading\"]",
"content:2:1 error MD033/no-inline-html Inline HTML [Element: br]", "content:2:1 warning MD033/no-inline-html Inline HTML [Element: br]",
"content:2:5 error MD047/single-trailing-newline Files should end with a single newline character" "content:2:64 error MD047/single-trailing-newline Files should end with a single newline character"
] ]
); );
}); });

View file

@ -190,6 +190,16 @@ function getConfigTestImplementation(config, expected) {
}; };
} }
/**
* Converts a config test scenario from errors to warnings.
*
* @param {Object.<string, string[]>} configTest Config test scenario.
* @returns {Object.<string, string[]>} Converted scenario.
*/
function configTestAsWarnings(configTest) {
return JSON.parse(JSON.stringify(configTest).replaceAll("error", "warning"));
}
const configTestExpected = { const configTestExpected = {
"./test/atx_heading_spacing.md": [], "./test/atx_heading_spacing.md": [],
"./test/first_heading_bad_atx.md": [] "./test/first_heading_bad_atx.md": []
@ -273,13 +283,23 @@ test("defaultError", getConfigTestImplementation(
test("defaultWarning", getConfigTestImplementation( test("defaultWarning", getConfigTestImplementation(
// @ts-ignore // @ts-ignore
{ "default": "warning" }, { "default": "warning" },
configTestAsWarnings(configTestExpected13511)
));
test("defaultMultipleTrue", getConfigTestImplementation(
{
"default": true,
"DEFAULT": false
},
configTestExpected13511 configTestExpected13511
)); ));
test("defaultOff", getConfigTestImplementation( test("defaultMultipleFalse", getConfigTestImplementation(
// @ts-ignore {
{ "default": "off" }, "DEFAULT": false,
configTestExpected13511 "default": true
},
configTestExpected
)); ));
test("disableRules", getConfigTestImplementation( test("disableRules", getConfigTestImplementation(
@ -336,7 +356,7 @@ test("enableRulesTruthy", getConfigTestImplementation(
configTestExpected3511 configTestExpected3511
)); ));
test("enableRulesString", getConfigTestImplementation( test("enableRulesError", getConfigTestImplementation(
{ {
"MD041": "error", "MD041": "error",
"default": false, "default": false,
@ -346,6 +366,16 @@ test("enableRulesString", getConfigTestImplementation(
configTestExpected3511 configTestExpected3511
)); ));
test("enableRulesWarning", getConfigTestImplementation(
{
"MD041": "warning",
"default": false,
"no-multiple-space-atx": "warning",
"extra": "warning"
},
configTestAsWarnings(configTestExpected3511)
));
test("enableRulesObjectEmpty", getConfigTestImplementation( test("enableRulesObjectEmpty", getConfigTestImplementation(
{ {
"MD041": {}, "MD041": {},
@ -356,7 +386,7 @@ test("enableRulesObjectEmpty", getConfigTestImplementation(
configTestExpected3511 configTestExpected3511
)); ));
test("enableRulesObjectTruthy", getConfigTestImplementation( test("enableRulesObjectSeverityTruthy", getConfigTestImplementation(
{ {
"MD041": { "MD041": {
// @ts-ignore // @ts-ignore
@ -374,7 +404,7 @@ test("enableRulesObjectTruthy", getConfigTestImplementation(
configTestExpected3511 configTestExpected3511
)); ));
test("enableRulesObjectFalsy", getConfigTestImplementation( test("enableRulesObjectSeverityFalsy", getConfigTestImplementation(
{ {
"MD041": { "MD041": {
// @ts-ignore // @ts-ignore
@ -392,7 +422,7 @@ test("enableRulesObjectFalsy", getConfigTestImplementation(
configTestExpected3511 configTestExpected3511
)); ));
test("enableRulesObjectError", getConfigTestImplementation( test("enableRulesObjectSeverityError", getConfigTestImplementation(
{ {
"MD041": { "MD041": {
"severity": "error" "severity": "error"
@ -408,42 +438,90 @@ test("enableRulesObjectError", getConfigTestImplementation(
configTestExpected3511 configTestExpected3511
)); ));
test("enableRulesObjectWarning", getConfigTestImplementation( test("enableRulesObjectSeverityWarning", getConfigTestImplementation(
{ {
"MD041": { "MD041": {
// @ts-ignore
"severity": "warning" "severity": "warning"
}, },
"default": false, "default": false,
"no-multiple-space-atx": { "no-multiple-space-atx": {
// @ts-ignore
"severity": "warning" "severity": "warning"
}, },
"extra": { "extra": {
"severity": "warning" "severity": "warning"
} }
}, },
configTestAsWarnings(configTestExpected3511)
));
test("enableRulesObjectEnabledTrue", getConfigTestImplementation(
{
"MD041": {
"enabled": true
},
"default": false,
"no-multiple-space-atx": {
"enabled": true
},
"extra": {
"enabled": true
}
},
configTestExpected3511 configTestExpected3511
)); ));
test("enableRulesObjectOff", getConfigTestImplementation( test("enableRulesObjectEnabledFalse", getConfigTestImplementation(
{
"MD041": {
"enabled": false
},
"default": true,
"no-multiple-space-atx": {
"enabled": false
},
"extra": {
"enabled": false
}
},
configTestExpected1
));
test("enableRulesObjectEnabledTruthy", getConfigTestImplementation(
{ {
"MD041": { "MD041": {
// @ts-ignore // @ts-ignore
"severity": "off" "enabled": 1
}, },
"default": false, "default": false,
"no-multiple-space-atx": { "no-multiple-space-atx": {
// @ts-ignore // @ts-ignore
"severity": "off" "enabled": 1
}, },
"extra": { "extra": {
"severity": "off" "enabled": 1
} }
}, },
configTestExpected3511 configTestExpected3511
)); ));
test("enableRulesObjectEnabledFalsy", getConfigTestImplementation(
{
"MD041": {
// @ts-ignore
"enabled": 0
},
"default": true,
"no-multiple-space-atx": {
// @ts-ignore
"enabled": 0
},
"extra": {
"enabled": 0
}
},
configTestExpected1
));
test("disableTag", getConfigTestImplementation( test("disableTag", getConfigTestImplementation(
{ {
"default": true, "default": true,
@ -491,7 +569,7 @@ test("enableTagTruthy", getConfigTestImplementation(
configTestExpected135 configTestExpected135
)); ));
test("enableTagString", getConfigTestImplementation( test("enableTagError", getConfigTestImplementation(
{ {
"default": false, "default": false,
"spaces": "error", "spaces": "error",
@ -500,6 +578,15 @@ test("enableTagString", getConfigTestImplementation(
configTestExpected135 configTestExpected135
)); ));
test("enableTagWarning", getConfigTestImplementation(
{
"default": false,
"spaces": "warning",
"extra": "warning"
},
configTestAsWarnings(configTestExpected135)
));
test("styleFiles", async(t) => { test("styleFiles", async(t) => {
t.plan(8); t.plan(8);
const files = await fs.promises.readdir("./style"); const files = await fs.promises.readdir("./style");
@ -1008,7 +1095,7 @@ test("readme", async(t) => {
}); });
test("validateJsonUsingConfigSchemaStrict", async(t) => { test("validateJsonUsingConfigSchemaStrict", async(t) => {
t.plan(212); t.plan(215);
// @ts-ignore // @ts-ignore
const ajv = new Ajv(ajvOptions); const ajv = new Ajv(ajvOptions);
const validateSchemaStrict = ajv.compile(configSchemaStrict); const validateSchemaStrict = ajv.compile(configSchemaStrict);

View file

@ -11203,7 +11203,148 @@ Generated by [AVA](https://avajs.dev).
`, `,
} }
## configure-file-with-severity.md ## configure-file-off-enable-inline.md
> Snapshot 1
{
errors: [
{
errorContext: null,
errorDetail: 'Expected: dash; Actual: plus',
errorRange: [
1,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 1,
insertText: '-',
},
lineNumber: 21,
ruleDescription: 'Unordered list style',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md004.md',
ruleNames: [
'MD004',
'ul-style',
],
severity: 'warning',
},
{
errorContext: null,
errorDetail: 'Expected: dash; Actual: plus',
errorRange: [
1,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 1,
insertText: '-',
},
lineNumber: 33,
ruleDescription: 'Unordered list style',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md004.md',
ruleNames: [
'MD004',
'ul-style',
],
severity: 'warning',
},
{
errorContext: null,
errorDetail: '(text)[.]',
errorRange: [
6,
9,
],
fixInfo: {
deleteCount: 9,
editColumn: 6,
insertText: '[text](.)',
},
lineNumber: 23,
ruleDescription: 'Reversed link syntax',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md011.md',
ruleNames: [
'MD011',
'no-reversed-links',
],
severity: 'error',
},
{
errorContext: null,
errorDetail: '(text)[.]',
errorRange: [
6,
9,
],
fixInfo: {
deleteCount: 9,
editColumn: 6,
insertText: '[text](.)',
},
lineNumber: 35,
ruleDescription: 'Reversed link syntax',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md011.md',
ruleNames: [
'MD011',
'no-reversed-links',
],
severity: 'error',
},
],
fixed: `# Configure File Off Enable Inline␊
+ List item␊
Text (text)[.]␊
<!-- markdownlint-disable -->
+ List item␊
Text (text)[.]␊
<!-- markdownlint-restore -->
+ List item␊
Text (text)[.]␊
<!-- markdownlint-enable MD004 MD011 -->
- List item {MD004}␊
Text [text](.) {MD011}␊
<!-- markdownlint-disable -->
+ List item␊
Text (text)[.]␊
<!-- markdownlint-enable MD004 MD011 -->
- List item {MD004}␊
Text [text](.) {MD011}␊
<!-- markdownlint-configure-file {␊
"MD004": {␊
"enabled": false,␊
"severity": "warning",␊
"style": "dash"␊
},␊
"MD011": {␊
"enabled": false,␊
"severity": "error"␊
}␊
} -->␊
`,
}
## configure-file-with-severity-alias.md
> Snapshot 1 > Snapshot 1
@ -11270,7 +11411,7 @@ Generated by [AVA](https://avajs.dev).
'MD011', 'MD011',
'no-reversed-links', 'no-reversed-links',
], ],
severity: 'error', severity: 'warning',
}, },
{ {
errorContext: null, errorContext: null,
@ -11291,8 +11432,430 @@ Generated by [AVA](https://avajs.dev).
'MD011', 'MD011',
'no-reversed-links', 'no-reversed-links',
], ],
severity: 'warning',
},
{
errorContext: '* t',
errorDetail: null,
errorRange: [
7,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 7,
},
lineNumber: 3,
ruleDescription: 'Spaces inside emphasis markers',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md037.md',
ruleNames: [
'MD037',
'no-space-in-emphasis',
],
severity: 'error', severity: 'error',
}, },
{
errorContext: '* t',
errorDetail: null,
errorRange: [
7,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 7,
},
lineNumber: 31,
ruleDescription: 'Spaces inside emphasis markers',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md037.md',
ruleNames: [
'MD037',
'no-space-in-emphasis',
],
severity: 'error',
},
{
errorContext: '` text`',
errorDetail: null,
errorRange: [
7,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 7,
},
lineNumber: 5,
ruleDescription: 'Spaces inside code span elements',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md038.md',
ruleNames: [
'MD038',
'no-space-in-code',
],
severity: 'warning',
},
{
errorContext: '` text`',
errorDetail: null,
errorRange: [
7,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 7,
},
lineNumber: 33,
ruleDescription: 'Spaces inside code span elements',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md038.md',
ruleNames: [
'MD038',
'no-space-in-code',
],
severity: 'warning',
},
],
fixed: `# Configure File With Severity Alias␊
Text *text* {MD037}␊
Text \`text\` {MD038}␊
Text [ text](.)␊
- List item {MD004}␊
Text [text](.) {MD011}␊
2. List item␊
<!-- markdownlint-disable -->
Text * text*
Text \` text\`␊
Text [ text](.)␊
+ List item␊
Text (text)[.]␊
2. List item␊
<!-- markdownlint-restore -->
Text *text* {MD037}␊
Text \`text\` {MD038}␊
Text [ text](.)␊
- List item {MD004}␊
Text [text](.) {MD011}␊
2. List item␊
<!-- markdownlint-configure-file {␊
"default": false,␊
"no-space-in-emphasis": "error",␊
"no-space-in-code": "warning",␊
"no-space-in-links": false,␊
"ul-style": {␊
"severity": "error",␊
"style": "dash"␊
},␊
"no-reversed-links": {␊
"severity": "warning"␊
},␊
"ol-prefix": {␊
"enabled": false␊
}␊
} -->␊
`,
}
## configure-file-with-severity-name.md
> Snapshot 1
{
errors: [
{
errorContext: null,
errorDetail: 'Expected: dash; Actual: plus',
errorRange: [
1,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 1,
insertText: '-',
},
lineNumber: 9,
ruleDescription: 'Unordered list style',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md004.md',
ruleNames: [
'MD004',
'ul-style',
],
severity: 'error',
},
{
errorContext: null,
errorDetail: 'Expected: dash; Actual: plus',
errorRange: [
1,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 1,
insertText: '-',
},
lineNumber: 37,
ruleDescription: 'Unordered list style',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md004.md',
ruleNames: [
'MD004',
'ul-style',
],
severity: 'error',
},
{
errorContext: null,
errorDetail: '(text)[.]',
errorRange: [
6,
9,
],
fixInfo: {
deleteCount: 9,
editColumn: 6,
insertText: '[text](.)',
},
lineNumber: 11,
ruleDescription: 'Reversed link syntax',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md011.md',
ruleNames: [
'MD011',
'no-reversed-links',
],
severity: 'warning',
},
{
errorContext: null,
errorDetail: '(text)[.]',
errorRange: [
6,
9,
],
fixInfo: {
deleteCount: 9,
editColumn: 6,
insertText: '[text](.)',
},
lineNumber: 39,
ruleDescription: 'Reversed link syntax',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md011.md',
ruleNames: [
'MD011',
'no-reversed-links',
],
severity: 'warning',
},
{
errorContext: '* t',
errorDetail: null,
errorRange: [
7,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 7,
},
lineNumber: 3,
ruleDescription: 'Spaces inside emphasis markers',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md037.md',
ruleNames: [
'MD037',
'no-space-in-emphasis',
],
severity: 'error',
},
{
errorContext: '* t',
errorDetail: null,
errorRange: [
7,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 7,
},
lineNumber: 31,
ruleDescription: 'Spaces inside emphasis markers',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md037.md',
ruleNames: [
'MD037',
'no-space-in-emphasis',
],
severity: 'error',
},
{
errorContext: '` text`',
errorDetail: null,
errorRange: [
7,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 7,
},
lineNumber: 5,
ruleDescription: 'Spaces inside code span elements',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md038.md',
ruleNames: [
'MD038',
'no-space-in-code',
],
severity: 'warning',
},
{
errorContext: '` text`',
errorDetail: null,
errorRange: [
7,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 7,
},
lineNumber: 33,
ruleDescription: 'Spaces inside code span elements',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md038.md',
ruleNames: [
'MD038',
'no-space-in-code',
],
severity: 'warning',
},
],
fixed: `# Configure File With Severity Name␊
Text *text* {MD037}␊
Text \`text\` {MD038}␊
Text [ text](.)␊
- List item {MD004}␊
Text [text](.) {MD011}␊
2. List item␊
<!-- markdownlint-disable -->
Text * text*
Text \` text\`␊
Text [ text](.)␊
+ List item␊
Text (text)[.]␊
2. List item␊
<!-- markdownlint-restore -->
Text *text* {MD037}␊
Text \`text\` {MD038}␊
Text [ text](.)␊
- List item {MD004}␊
Text [text](.) {MD011}␊
2. List item␊
<!-- markdownlint-configure-file {␊
"default": false,␊
"MD037": "error",␊
"MD038": "warning",␊
"MD039": false,␊
"MD004": {␊
"severity": "error",␊
"style": "dash"␊
},␊
"MD011": {␊
"severity": "warning"␊
},␊
"MD029": {␊
"enabled": false␊
}␊
} -->␊
`,
}
## configure-file-with-severity-tag.md
> Snapshot 1
{
errors: [
{
errorContext: null,
errorDetail: '(text)[.]',
errorRange: [
6,
9,
],
fixInfo: {
deleteCount: 9,
editColumn: 6,
insertText: '[text](.)',
},
lineNumber: 11,
ruleDescription: 'Reversed link syntax',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md011.md',
ruleNames: [
'MD011',
'no-reversed-links',
],
severity: 'warning',
},
{
errorContext: null,
errorDetail: '(text)[.]',
errorRange: [
6,
9,
],
fixInfo: {
deleteCount: 9,
editColumn: 6,
insertText: '[text](.)',
},
lineNumber: 39,
ruleDescription: 'Reversed link syntax',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md011.md',
ruleNames: [
'MD011',
'no-reversed-links',
],
severity: 'warning',
},
{ {
errorContext: null, errorContext: null,
errorDetail: 'Expected: 1; Actual: 2; Style: 1/1/1', errorDetail: 'Expected: 1; Actual: 2; Style: 1/1/1',
@ -11393,7 +11956,7 @@ Generated by [AVA](https://avajs.dev).
'MD038', 'MD038',
'no-space-in-code', 'no-space-in-code',
], ],
severity: 'error', severity: 'warning',
}, },
{ {
errorContext: '` text`', errorContext: '` text`',
@ -11413,7 +11976,7 @@ Generated by [AVA](https://avajs.dev).
'MD038', 'MD038',
'no-space-in-code', 'no-space-in-code',
], ],
severity: 'error', severity: 'warning',
}, },
{ {
errorContext: '[ text]', errorContext: '[ text]',
@ -11433,7 +11996,7 @@ Generated by [AVA](https://avajs.dev).
'MD039', 'MD039',
'no-space-in-links', 'no-space-in-links',
], ],
severity: 'error', severity: 'warning',
}, },
{ {
errorContext: '[ text]', errorContext: '[ text]',
@ -11453,10 +12016,10 @@ Generated by [AVA](https://avajs.dev).
'MD039', 'MD039',
'no-space-in-links', 'no-space-in-links',
], ],
severity: 'error', severity: 'warning',
}, },
], ],
fixed: `# Configure File With Severity␊ fixed: `# Configure File With Severity Tag
Text *text* {MD037}␊ Text *text* {MD037}␊
@ -11464,7 +12027,7 @@ Generated by [AVA](https://avajs.dev).
Text [text](.) {MD039}␊ Text [text](.) {MD039}␊
- List item {MD004} + List item
Text [text](.) {MD011}␊ Text [text](.) {MD011}␊
@ -11492,7 +12055,7 @@ Generated by [AVA](https://avajs.dev).
Text [text](.) {MD039}␊ Text [text](.) {MD039}␊
- List item {MD004} + List item
Text [text](.) {MD011}␊ Text [text](.) {MD011}␊
@ -11500,19 +12063,11 @@ Generated by [AVA](https://avajs.dev).
<!-- markdownlint-configure-file {␊ <!-- markdownlint-configure-file {␊
"default": false,␊ "default": false,␊
"MD037": "error",␊ "emphasis": "error",␊
"MD038": "error",␊ "code": "warning",␊
"MD039": "error",␊ "bullet": false,␊
"MD004": {␊ "links": "warning",␊
"severity": "error",␊ "ol": "error"␊
"style": "dash"␊
},␊
"MD011": {␊
"severity": "error"␊
},␊
"MD029": {␊
"severity": "error"␊
}␊
} -->␊ } -->␊
`, `,
} }