mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-09-22 05:40:48 +02:00
Support front matter title property override for MD041/first-line-h1 (fixes #53).
This commit is contained in:
parent
4ae649c462
commit
942f0600d2
18 changed files with 131 additions and 12 deletions
|
@ -57,7 +57,7 @@
|
||||||
"max-lines": "off",
|
"max-lines": "off",
|
||||||
"max-nested-callbacks": "error",
|
"max-nested-callbacks": "error",
|
||||||
"max-params": ["error", 6],
|
"max-params": ["error", 6],
|
||||||
"max-statements": ["error", 28],
|
"max-statements": ["error", 30],
|
||||||
"max-statements-per-line": "error",
|
"max-statements-per-line": "error",
|
||||||
"multiline-ternary": "off",
|
"multiline-ternary": "off",
|
||||||
"new-cap": "error",
|
"new-cap": "error",
|
||||||
|
|
12
doc/Rules.md
12
doc/Rules.md
|
@ -1032,7 +1032,7 @@ Tags: headers
|
||||||
|
|
||||||
Aliases: first-line-h1
|
Aliases: first-line-h1
|
||||||
|
|
||||||
Parameters: level (number; default 1)
|
Parameters: level, front_matter_title (number; default 1, string; default "^\s*title:")
|
||||||
|
|
||||||
This rule is triggered when the first line in the file isn't a top level (h1)
|
This rule is triggered when the first line in the file isn't a top level (h1)
|
||||||
header:
|
header:
|
||||||
|
@ -1045,8 +1045,14 @@ To fix this, add a header to the top of your file:
|
||||||
|
|
||||||
This is a file with a top level header
|
This is a file with a top level header
|
||||||
|
|
||||||
Note: The `level` parameter can be used to change the top level (ex: to h2) in
|
The `level` parameter can be used to change the top level (ex: to h2) in cases
|
||||||
cases where an h1 is added externally.
|
where an h1 is added externally.
|
||||||
|
|
||||||
|
If front matter is present and contains a [YAML](https://en.wikipedia.org/wiki/YAML)
|
||||||
|
`title` property (commonly used with blog posts), this rule will not report a
|
||||||
|
violation. To use a different property name in front matter, specify the text
|
||||||
|
of a regular expression via the `front_matter_title` parameter. To disable the
|
||||||
|
use of front matter by this rule, specify `""` for `front_matter_title`.
|
||||||
|
|
||||||
## MD042 - No empty links
|
## MD042 - No empty links
|
||||||
|
|
||||||
|
|
|
@ -88,13 +88,17 @@ function lintContent(content, config, frontMatter, resultVersion) {
|
||||||
content = content.slice(1);
|
content = content.slice(1);
|
||||||
}
|
}
|
||||||
// Remove front matter (if present at beginning of content)
|
// Remove front matter (if present at beginning of content)
|
||||||
var frontMatterLines = 0;
|
var frontMatterLines = [];
|
||||||
if (frontMatter) {
|
if (frontMatter) {
|
||||||
var frontMatterMatch = content.match(frontMatter);
|
var frontMatterMatch = content.match(frontMatter);
|
||||||
if (frontMatterMatch && !frontMatterMatch.index) {
|
if (frontMatterMatch && !frontMatterMatch.index) {
|
||||||
var contentMatched = frontMatterMatch[0];
|
var contentMatched = frontMatterMatch[0];
|
||||||
content = content.slice(contentMatched.length);
|
content = content.slice(contentMatched.length);
|
||||||
frontMatterLines = contentMatched.split(shared.newLineRe).length - 1;
|
frontMatterLines = contentMatched.split(shared.newLineRe);
|
||||||
|
if (frontMatterLines.length &&
|
||||||
|
(frontMatterLines[frontMatterLines.length - 1] === "")) {
|
||||||
|
frontMatterLines.length--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Parse content into tokens and lines
|
// Parse content into tokens and lines
|
||||||
|
@ -184,7 +188,7 @@ function lintContent(content, config, frontMatter, resultVersion) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
var enabledRulesPerLineNumber = new Array(1 + frontMatterLines);
|
var enabledRulesPerLineNumber = new Array(1 + frontMatterLines.length);
|
||||||
lines.forEach(function forLine(line) {
|
lines.forEach(function forLine(line) {
|
||||||
var match = shared.inlineCommentRe.exec(line);
|
var match = shared.inlineCommentRe.exec(line);
|
||||||
if (match) {
|
if (match) {
|
||||||
|
@ -200,7 +204,8 @@ function lintContent(content, config, frontMatter, resultVersion) {
|
||||||
var params = {
|
var params = {
|
||||||
"tokens": tokens,
|
"tokens": tokens,
|
||||||
"tokenLists": tokenLists,
|
"tokenLists": tokenLists,
|
||||||
"lines": lines
|
"lines": lines,
|
||||||
|
"frontMatterLines": frontMatterLines
|
||||||
};
|
};
|
||||||
// Run each rule
|
// Run each rule
|
||||||
var result = (resultVersion === 1) ? [] : {};
|
var result = (resultVersion === 1) ? [] : {};
|
||||||
|
@ -210,7 +215,7 @@ function lintContent(content, config, frontMatter, resultVersion) {
|
||||||
var errors = [];
|
var errors = [];
|
||||||
function addError(lineNumber, detail, context) {
|
function addError(lineNumber, detail, context) {
|
||||||
errors.push({
|
errors.push({
|
||||||
"lineNumber": lineNumber + frontMatterLines,
|
"lineNumber": lineNumber + frontMatterLines.length,
|
||||||
"detail": detail || null,
|
"detail": detail || null,
|
||||||
"context": context || null
|
"context": context || null
|
||||||
});
|
});
|
||||||
|
@ -255,7 +260,7 @@ function lintContent(content, config, frontMatter, resultVersion) {
|
||||||
if (typeof regexp === "function") {
|
if (typeof regexp === "function") {
|
||||||
regexp = regexp(params.options);
|
regexp = regexp(params.options);
|
||||||
}
|
}
|
||||||
var lineIndex = error.lineNumber - frontMatterLines - 1;
|
var lineIndex = error.lineNumber - frontMatterLines.length - 1;
|
||||||
var match = lines[lineIndex].match(regexp);
|
var match = lines[lineIndex].match(regexp);
|
||||||
if (match) {
|
if (match) {
|
||||||
var column = match.index + 1;
|
var column = match.index + 1;
|
||||||
|
|
10
lib/rules.js
10
lib/rules.js
|
@ -1029,7 +1029,10 @@ module.exports = [
|
||||||
"regexp": null,
|
"regexp": null,
|
||||||
"func": function MD041(params, errors) {
|
"func": function MD041(params, errors) {
|
||||||
var level = params.options.level || 1;
|
var level = params.options.level || 1;
|
||||||
|
var frontMatterTitle = params.options.front_matter_title;
|
||||||
var tag = "h" + level;
|
var tag = "h" + level;
|
||||||
|
var frontMatterTitleRe =
|
||||||
|
new RegExp(frontMatterTitle || "^\\s*title:", "i");
|
||||||
params.tokens.every(function forToken(token, index) {
|
params.tokens.every(function forToken(token, index) {
|
||||||
if (token.type === "heading_open") {
|
if (token.type === "heading_open") {
|
||||||
if (!((token.lineNumber === 1) || (index > 0)) ||
|
if (!((token.lineNumber === 1) || (index > 0)) ||
|
||||||
|
@ -1040,7 +1043,12 @@ module.exports = [
|
||||||
} else if (token.type === "html_block") {
|
} else if (token.type === "html_block") {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
errors.addContext(token.lineNumber, token.line);
|
if (((frontMatterTitle !== undefined) && !frontMatterTitle) ||
|
||||||
|
!params.frontMatterLines.some(function forLine(line) {
|
||||||
|
return frontMatterTitleRe.test(line);
|
||||||
|
})) {
|
||||||
|
errors.addContext(token.lineNumber, token.line);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,6 @@ rules.forEach(function forRule(rule) {
|
||||||
switch (rule.name) {
|
switch (rule.name) {
|
||||||
case "MD002":
|
case "MD002":
|
||||||
case "MD025":
|
case "MD025":
|
||||||
case "MD041":
|
|
||||||
scheme.properties = {
|
scheme.properties = {
|
||||||
"level": {
|
"level": {
|
||||||
"description": "Header level",
|
"description": "Header level",
|
||||||
|
@ -205,6 +204,20 @@ rules.forEach(function forRule(rule) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
case "MD041":
|
||||||
|
scheme.properties = {
|
||||||
|
"level": {
|
||||||
|
"description": "Header level",
|
||||||
|
"type": "integer",
|
||||||
|
"default": 1
|
||||||
|
},
|
||||||
|
"front_matter_title": {
|
||||||
|
"description": "RegExp for matching title in front matter",
|
||||||
|
"type": "string",
|
||||||
|
"default": "^\\s*title:"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
break;
|
||||||
case "MD043":
|
case "MD043":
|
||||||
scheme.properties = {
|
scheme.properties = {
|
||||||
"headers": {
|
"headers": {
|
||||||
|
|
|
@ -813,6 +813,11 @@
|
||||||
"description": "Header level",
|
"description": "Header level",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"default": 1
|
"default": 1
|
||||||
|
},
|
||||||
|
"front_matter_title": {
|
||||||
|
"description": "RegExp for matching title in front matter",
|
||||||
|
"type": "string",
|
||||||
|
"default": "^\\s*title:"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
|
@ -829,6 +834,11 @@
|
||||||
"description": "Header level",
|
"description": "Header level",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"default": 1
|
"default": 1
|
||||||
|
},
|
||||||
|
"front_matter_title": {
|
||||||
|
"description": "RegExp for matching title in front matter",
|
||||||
|
"type": "string",
|
||||||
|
"default": "^\\s*title:"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
|
|
7
test/front-matter-alt-title-no-h1.json
Normal file
7
test/front-matter-alt-title-no-h1.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"default": true,
|
||||||
|
"MD013": false,
|
||||||
|
"MD041": {
|
||||||
|
"front_matter_title": "^\\s*alternate="
|
||||||
|
}
|
||||||
|
}
|
4
test/front-matter-alt-title-no-h1.md
Normal file
4
test/front-matter-alt-title-no-h1.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
alternate="Welcome to Jekyll!"
|
||||||
|
---
|
||||||
|
Front matter from [Jekyll documentation](https://jekyllrb.com/docs/posts/#a-typical-post).
|
7
test/front-matter-empty-title-no-h1.json
Normal file
7
test/front-matter-empty-title-no-h1.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"default": true,
|
||||||
|
"MD013": false,
|
||||||
|
"MD041": {
|
||||||
|
"front_matter_title": ""
|
||||||
|
}
|
||||||
|
}
|
7
test/front-matter-empty-title-no-h1.md
Normal file
7
test/front-matter-empty-title-no-h1.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: "Welcome to Jekyll!"
|
||||||
|
date: 2015-11-17 16:16:01 -0600
|
||||||
|
categories: jekyll update
|
||||||
|
---
|
||||||
|
Front matter from [Jekyll documentation](https://jekyllrb.com/docs/posts/#a-typical-post). {MD041}
|
5
test/front-matter-no-title-h1.json
Normal file
5
test/front-matter-no-title-h1.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"default": true,
|
||||||
|
"MD013": false,
|
||||||
|
"MD041": true
|
||||||
|
}
|
9
test/front-matter-no-title-h1.md
Normal file
9
test/front-matter-no-title-h1.md
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
notitle: "Welcome to Jekyll!"
|
||||||
|
date: 2015-11-17 16:16:01 -0600
|
||||||
|
categories: jekyll update
|
||||||
|
---
|
||||||
|
# Top level header
|
||||||
|
|
||||||
|
Front matter from [Jekyll documentation](https://jekyllrb.com/docs/posts/#a-typical-post).
|
5
test/front-matter-no-title-no-h1.json
Normal file
5
test/front-matter-no-title-no-h1.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"default": true,
|
||||||
|
"MD013": false,
|
||||||
|
"MD041": true
|
||||||
|
}
|
7
test/front-matter-no-title-no-h1.md
Normal file
7
test/front-matter-no-title-no-h1.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
notitle: "Welcome to Jekyll!"
|
||||||
|
date: 2015-11-17 16:16:01 -0600
|
||||||
|
categories: jekyll update
|
||||||
|
---
|
||||||
|
Front matter from [Jekyll documentation](https://jekyllrb.com/docs/posts/#a-typical-post). {MD041}
|
5
test/front-matter-title-h1.json
Normal file
5
test/front-matter-title-h1.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"default": true,
|
||||||
|
"MD013": false,
|
||||||
|
"MD041": true
|
||||||
|
}
|
9
test/front-matter-title-h1.md
Normal file
9
test/front-matter-title-h1.md
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: "Welcome to Jekyll!"
|
||||||
|
date: 2015-11-17 16:16:01 -0600
|
||||||
|
categories: jekyll update
|
||||||
|
---
|
||||||
|
# Top level header
|
||||||
|
|
||||||
|
Front matter from [Jekyll documentation](https://jekyllrb.com/docs/posts/#a-typical-post).
|
5
test/front-matter-title-no-h1.json
Normal file
5
test/front-matter-title-no-h1.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"default": true,
|
||||||
|
"MD013": false,
|
||||||
|
"MD041": true
|
||||||
|
}
|
7
test/front-matter-title-no-h1.md
Normal file
7
test/front-matter-title-no-h1.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: "Welcome to Jekyll!"
|
||||||
|
date: 2015-11-17 16:16:01 -0600
|
||||||
|
categories: jekyll update
|
||||||
|
---
|
||||||
|
Front matter from [Jekyll documentation](https://jekyllrb.com/docs/posts/#a-typical-post).
|
Loading…
Add table
Add a link
Reference in a new issue