mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-09-22 05:40:48 +02:00
Update MD013/line-length with heading_line_length parameter (fixes #170).
This commit is contained in:
parent
fa04d29485
commit
d7c0d195d7
9 changed files with 110 additions and 40 deletions
|
@ -443,13 +443,14 @@ Tags: line_length
|
||||||
|
|
||||||
Aliases: line-length
|
Aliases: line-length
|
||||||
|
|
||||||
Parameters: line_length, code_blocks, tables, headings, headers (number; default 80, boolean; default true)
|
Parameters: line_length, heading_line_length, code_blocks, tables, headings, headers (number; default 80, boolean; default true)
|
||||||
|
|
||||||
> If `headings` is not provided, `headers` (deprecated) will be used.
|
> If `headings` is not provided, `headers` (deprecated) will be used.
|
||||||
|
|
||||||
This rule is triggered when there are lines that are longer than the
|
This rule is triggered when there are lines that are longer than the
|
||||||
configured line length (default: 80 characters). To fix this, split the line
|
configured `line_length` (default: 80 characters). To fix this, split the line
|
||||||
up into multiple lines.
|
up into multiple lines. To set a different maximum length for headings, use
|
||||||
|
`heading_line_length`.
|
||||||
|
|
||||||
This rule has an exception where there is no whitespace beyond the configured
|
This rule has an exception where there is no whitespace beyond the configured
|
||||||
line length. This allows you to still include items such as long URLs without
|
line length. This allows you to still include items such as long URLs without
|
||||||
|
|
72
lib/md013.js
72
lib/md013.js
|
@ -3,8 +3,23 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const shared = require("./shared");
|
const shared = require("./shared");
|
||||||
|
const {
|
||||||
|
addErrorDetailIf, filterTokens, forEachHeading, forEachLine, rangeFromRegExp
|
||||||
|
} = shared;
|
||||||
|
|
||||||
|
const longLineRePrefix = "^(.{";
|
||||||
|
const longLineRePostfix = "})(.*\\s.*)$";
|
||||||
const labelRe = /^\s*\[.*[^\\]]:/;
|
const labelRe = /^\s*\[.*[^\\]]:/;
|
||||||
|
const linkOnlyLineRe = /^[es]*lT?L[ES]*$/;
|
||||||
|
const tokenTypeMap = {
|
||||||
|
"em_open": "e",
|
||||||
|
"em_close": "E",
|
||||||
|
"link_open": "l",
|
||||||
|
"link_close": "L",
|
||||||
|
"strong_open": "s",
|
||||||
|
"strong_close": "S",
|
||||||
|
"text": "T"
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
"names": [ "MD013", "line-length" ],
|
"names": [ "MD013", "line-length" ],
|
||||||
|
@ -12,6 +27,11 @@ module.exports = {
|
||||||
"tags": [ "line_length" ],
|
"tags": [ "line_length" ],
|
||||||
"function": function MD013(params, onError) {
|
"function": function MD013(params, onError) {
|
||||||
const lineLength = params.config.line_length || 80;
|
const lineLength = params.config.line_length || 80;
|
||||||
|
const headingLineLength = params.config.heading_line_length || lineLength;
|
||||||
|
const longLineRe =
|
||||||
|
new RegExp(longLineRePrefix + lineLength + longLineRePostfix);
|
||||||
|
const longHeadingLineRe =
|
||||||
|
new RegExp(longLineRePrefix + headingLineLength + longLineRePostfix);
|
||||||
const codeBlocks = params.config.code_blocks;
|
const codeBlocks = params.config.code_blocks;
|
||||||
const includeCodeBlocks = (codeBlocks === undefined) ? true : !!codeBlocks;
|
const includeCodeBlocks = (codeBlocks === undefined) ? true : !!codeBlocks;
|
||||||
const tables = params.config.tables;
|
const tables = params.config.tables;
|
||||||
|
@ -22,45 +42,35 @@ module.exports = {
|
||||||
}
|
}
|
||||||
const includeHeadings = (headings === undefined) ? true : !!headings;
|
const includeHeadings = (headings === undefined) ? true : !!headings;
|
||||||
const headingLineNumbers = [];
|
const headingLineNumbers = [];
|
||||||
if (!includeHeadings) {
|
forEachHeading(params, (heading) => {
|
||||||
shared.forEachHeading(params, function forHeading(heading) {
|
headingLineNumbers.push(heading.lineNumber);
|
||||||
headingLineNumbers.push(heading.lineNumber);
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
const tokenTypeMap = {
|
|
||||||
"em_open": "e",
|
|
||||||
"em_close": "E",
|
|
||||||
"link_open": "l",
|
|
||||||
"link_close": "L",
|
|
||||||
"strong_open": "s",
|
|
||||||
"strong_close": "S",
|
|
||||||
"text": "T"
|
|
||||||
};
|
|
||||||
const linkOnlyLineNumbers = [];
|
const linkOnlyLineNumbers = [];
|
||||||
shared.filterTokens(params, "inline", function forToken(token) {
|
filterTokens(params, "inline", (token) => {
|
||||||
let childTokenTypes = "";
|
let childTokenTypes = "";
|
||||||
token.children.forEach(function forChild(child) {
|
token.children.forEach((child) => {
|
||||||
if (child.type !== "text" || child.content !== "") {
|
if (child.type !== "text" || child.content !== "") {
|
||||||
childTokenTypes += tokenTypeMap[child.type] || "x";
|
childTokenTypes += tokenTypeMap[child.type] || "x";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (/^[es]*lT?L[ES]*$/.test(childTokenTypes)) {
|
if (linkOnlyLineRe.test(childTokenTypes)) {
|
||||||
linkOnlyLineNumbers.push(token.lineNumber);
|
linkOnlyLineNumbers.push(token.lineNumber);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const longLineRe = new RegExp("^(.{" + lineLength + "})(.*\\s.*)$");
|
forEachLine((line, lineIndex, inCode, onFence, inTable) => {
|
||||||
shared.forEachLine(
|
const lineNumber = lineIndex + 1;
|
||||||
function forLine(line, lineIndex, inCode, onFence, inTable) {
|
const isHeading = headingLineNumbers.indexOf(lineNumber) >= 0;
|
||||||
const lineNumber = lineIndex + 1;
|
const length = isHeading ? headingLineLength : lineLength;
|
||||||
if ((includeCodeBlocks || !inCode) &&
|
const lengthRe = isHeading ? longHeadingLineRe : longLineRe;
|
||||||
(includeTables || !inTable) &&
|
if ((includeCodeBlocks || !inCode) &&
|
||||||
(includeHeadings || (headingLineNumbers.indexOf(lineNumber)) < 0) &&
|
(includeTables || !inTable) &&
|
||||||
(linkOnlyLineNumbers.indexOf(lineNumber) < 0) &&
|
(includeHeadings || !isHeading) &&
|
||||||
longLineRe.test(line) &&
|
(linkOnlyLineNumbers.indexOf(lineNumber) < 0) &&
|
||||||
!labelRe.test(line)) {
|
lengthRe.test(line) &&
|
||||||
shared.addErrorDetailIf(onError, lineNumber, lineLength,
|
!labelRe.test(line)) {
|
||||||
line.length, null, null, shared.rangeFromRegExp(line, longLineRe));
|
addErrorDetailIf(onError, lineNumber, length, line.length,
|
||||||
}
|
null, null, rangeFromRegExp(line, lengthRe));
|
||||||
});
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -129,6 +129,11 @@ rules.forEach(function forRule(rule) {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"default": 80
|
"default": 80
|
||||||
},
|
},
|
||||||
|
"heading_line_length": {
|
||||||
|
"description": "Number of characters for headings",
|
||||||
|
"type": "integer",
|
||||||
|
"default": 80
|
||||||
|
},
|
||||||
"code_blocks": {
|
"code_blocks": {
|
||||||
"description": "Include code blocks",
|
"description": "Include code blocks",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
|
|
@ -374,6 +374,11 @@
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"default": 80
|
"default": 80
|
||||||
},
|
},
|
||||||
|
"heading_line_length": {
|
||||||
|
"description": "Number of characters for headings",
|
||||||
|
"type": "integer",
|
||||||
|
"default": 80
|
||||||
|
},
|
||||||
"code_blocks": {
|
"code_blocks": {
|
||||||
"description": "Include code blocks",
|
"description": "Include code blocks",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
@ -410,6 +415,11 @@
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"default": 80
|
"default": 80
|
||||||
},
|
},
|
||||||
|
"heading_line_length": {
|
||||||
|
"description": "Number of characters for headings",
|
||||||
|
"type": "integer",
|
||||||
|
"default": 80
|
||||||
|
},
|
||||||
"code_blocks": {
|
"code_blocks": {
|
||||||
"description": "Include code blocks",
|
"description": "Include code blocks",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
|
6
test/detailed-results-MD011-MD021.json
Normal file
6
test/detailed-results-MD011-MD021.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"default": true,
|
||||||
|
"MD013": {
|
||||||
|
"heading_line_length": 40
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,8 @@ A (reversed)[link] example.
|
||||||
|
|
||||||
123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
|
123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
|
||||||
|
|
||||||
|
## 123456789 123456789 123456789 123456789 123456789 123456789
|
||||||
|
|
||||||
$ command with no output
|
$ command with no output
|
||||||
|
|
||||||
##No space A
|
##No space A
|
||||||
|
|
|
@ -28,6 +28,15 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"lineNumber": 10,
|
"lineNumber": 10,
|
||||||
|
"ruleNames": [ "MD013", "line-length" ],
|
||||||
|
"ruleDescription": "Line length",
|
||||||
|
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md013",
|
||||||
|
"errorDetail": "Expected: 40; Actual: 62",
|
||||||
|
"errorContext": null,
|
||||||
|
"errorRange": [41, 22]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lineNumber": 12,
|
||||||
"ruleNames": [ "MD014", "commands-show-output" ],
|
"ruleNames": [ "MD014", "commands-show-output" ],
|
||||||
"ruleDescription": "Dollar signs used before commands without showing output",
|
"ruleDescription": "Dollar signs used before commands without showing output",
|
||||||
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md014",
|
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md014",
|
||||||
|
@ -36,7 +45,7 @@
|
||||||
"errorRange": [5, 2]
|
"errorRange": [5, 2]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"lineNumber": 12,
|
"lineNumber": 14,
|
||||||
"ruleNames": [ "MD018", "no-missing-space-atx" ],
|
"ruleNames": [ "MD018", "no-missing-space-atx" ],
|
||||||
"ruleDescription": "No space after hash on atx style heading",
|
"ruleDescription": "No space after hash on atx style heading",
|
||||||
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md018",
|
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md018",
|
||||||
|
@ -45,7 +54,7 @@
|
||||||
"errorRange": [1, 3]
|
"errorRange": [1, 3]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"lineNumber": 14,
|
"lineNumber": 16,
|
||||||
"ruleNames": [ "MD019", "no-multiple-space-atx" ],
|
"ruleNames": [ "MD019", "no-multiple-space-atx" ],
|
||||||
"ruleDescription": "Multiple spaces after hash on atx style heading",
|
"ruleDescription": "Multiple spaces after hash on atx style heading",
|
||||||
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md019",
|
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md019",
|
||||||
|
@ -54,7 +63,7 @@
|
||||||
"errorRange": [1, 5]
|
"errorRange": [1, 5]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"lineNumber": 16,
|
"lineNumber": 18,
|
||||||
"ruleNames": [ "MD020", "no-missing-space-closed-atx" ],
|
"ruleNames": [ "MD020", "no-missing-space-closed-atx" ],
|
||||||
"ruleDescription": "No space inside hashes on closed atx style heading",
|
"ruleDescription": "No space inside hashes on closed atx style heading",
|
||||||
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md020",
|
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md020",
|
||||||
|
@ -63,7 +72,7 @@
|
||||||
"errorRange": [1, 3]
|
"errorRange": [1, 3]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"lineNumber": 18,
|
"lineNumber": 20,
|
||||||
"ruleNames": [ "MD020", "no-missing-space-closed-atx" ],
|
"ruleNames": [ "MD020", "no-missing-space-closed-atx" ],
|
||||||
"ruleDescription": "No space inside hashes on closed atx style heading",
|
"ruleDescription": "No space inside hashes on closed atx style heading",
|
||||||
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md020",
|
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md020",
|
||||||
|
@ -72,7 +81,7 @@
|
||||||
"errorRange": [13, 3]
|
"errorRange": [13, 3]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"lineNumber": 20,
|
"lineNumber": 22,
|
||||||
"ruleNames": [ "MD021", "no-multiple-space-closed-atx" ],
|
"ruleNames": [ "MD021", "no-multiple-space-closed-atx" ],
|
||||||
"ruleDescription": "Multiple spaces inside hashes on closed atx style heading",
|
"ruleDescription": "Multiple spaces inside hashes on closed atx style heading",
|
||||||
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md021",
|
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md021",
|
||||||
|
@ -81,7 +90,7 @@
|
||||||
"errorRange": [1, 5]
|
"errorRange": [1, 5]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"lineNumber": 22,
|
"lineNumber": 24,
|
||||||
"ruleNames": [ "MD021", "no-multiple-space-closed-atx" ],
|
"ruleNames": [ "MD021", "no-multiple-space-closed-atx" ],
|
||||||
"ruleDescription": "Multiple spaces inside hashes on closed atx style heading",
|
"ruleDescription": "Multiple spaces inside hashes on closed atx style heading",
|
||||||
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md021",
|
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md021",
|
||||||
|
|
7
test/long-lines-short-headings.json
Normal file
7
test/long-lines-short-headings.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"default": true,
|
||||||
|
"MD003": false,
|
||||||
|
"MD013": {
|
||||||
|
"heading_line_length": 30
|
||||||
|
}
|
||||||
|
}
|
20
test/long-lines-short-headings.md
Normal file
20
test/long-lines-short-headings.md
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# Long Lines, Short Headings
|
||||||
|
|
||||||
|
Text text text text text text text text text text text text text text text text text {MD013}
|
||||||
|
|
||||||
|
## Short heading text text text
|
||||||
|
|
||||||
|
Text
|
||||||
|
|
||||||
|
## Long heading text text text {MD013}
|
||||||
|
|
||||||
|
Text
|
||||||
|
|
||||||
|
## Long heading text text {MD013} ##
|
||||||
|
|
||||||
|
Text
|
||||||
|
|
||||||
|
Long heading of text text text text text text {MD013}
|
||||||
|
-----------------------------------------------------
|
||||||
|
|
||||||
|
Text
|
Loading…
Add table
Add a link
Reference in a new issue