diff --git a/doc/Rules.md b/doc/Rules.md
index d77a0e38..4c47f9dc 100644
--- a/doc/Rules.md
+++ b/doc/Rules.md
@@ -51,25 +51,28 @@ Aliases: first-heading-h1, first-header-h1
Parameters: level (number; default 1)
-This rule is triggered when the first heading in the document isn't a h1 heading:
+This rule is intended to ensure document headings start at the top level and
+is triggered when the first heading in the document isn't an h1 heading:
```markdown
-## This isn't a H1 heading
+## This isn't an H1 heading
### Another heading
```
-The first heading in the document should be a h1 heading:
+The first heading in the document should be an h1 heading:
```markdown
-# Start with a H1 heading
+# Start with an H1 heading
-## Then use a H2 for subsections
+## Then use an H2 for subsections
```
Note: The `level` parameter can be used to change the top level (ex: to h2) in
cases where an h1 is added externally.
+See also: [MD041](#md041) for an improved version of this rule.
+
## MD003 - Heading style
@@ -215,7 +218,6 @@ the same ending column:
...
```
-
## MD006 - Consider starting bulleted lists at the beginning of the line
@@ -732,7 +734,7 @@ Aliases: single-h1
Parameters: level (number; default 1)
This rule is triggered when a top level heading is in use (the first line of
-the file is a h1 heading), and more than one h1 heading is in use in the
+the file is an h1 heading), and more than one h1 heading is in use in the
document:
```markdown
@@ -753,7 +755,7 @@ headings:
## Another heading
```
-Rationale: A top level heading is a h1 on the first line of the file, and
+Rationale: A top level heading is an h1 on the first line of the file, and
serves as the title for the document. If this convention is in use, then there
can not be more than one title for the document, and the entire document
should be contained within this heading.
@@ -1349,14 +1351,14 @@ Aliases: first-line-h1
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)
-heading:
+This rule is intended to ensure documents have a title and is triggered when
+the first line in the file isn't a top level (h1) heading:
```markdown
This is a file without a heading
```
-To fix this, add a heading to the top of your file:
+To fix this, add a top level heading to the beginning of the file:
```markdown
# File with heading
@@ -1364,10 +1366,10 @@ To fix this, add a heading to the top of your file:
This is a file with a top level heading
```
-The `level` parameter can be used to change the top level (ex: to h2) in cases
+Note: The `level` parameter can be used to change the top level (ex: to h2) in cases
where an h1 is added externally.
-If front matter is present and contains a [YAML](https://en.wikipedia.org/wiki/YAML)
+If [YAML](https://en.wikipedia.org/wiki/YAML) front matter is present and contains a
`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
diff --git a/lib/md041.js b/lib/md041.js
index c34b4950..484755ee 100644
--- a/lib/md041.js
+++ b/lib/md041.js
@@ -10,24 +10,24 @@ module.exports = {
"tags": [ "headings", "headers" ],
"function": function MD041(params, onError) {
const level = params.config.level || 1;
- const frontMatterTitle = params.config.front_matter_title;
const tag = "h" + level;
+ const frontMatterTitle = params.config.front_matter_title;
+ const ignoreFrontMatter =
+ (frontMatterTitle !== undefined) && !frontMatterTitle;
const frontMatterTitleRe =
new RegExp(frontMatterTitle || "^\\s*title\\s*[:=]", "i");
- params.tokens.every(function forToken(token) {
- if (token.type === "html_block") {
- return true;
- } else if (token.type === "heading_open") {
- if (token.tag !== tag) {
+ const foundFrontMatterTitle = !ignoreFrontMatter &&
+ params.frontMatterLines.some((line) => frontMatterTitleRe.test(line));
+ if (!foundFrontMatterTitle) {
+ params.tokens.every((token) => {
+ if (token.type === "html_block") {
+ return true;
+ }
+ if ((token.type !== "heading_open") || (token.tag !== tag)) {
shared.addErrorContext(onError, token.lineNumber, token.line);
}
- } else if (((frontMatterTitle !== undefined) && !frontMatterTitle) ||
- !params.frontMatterLines.some(function forLine(line) {
- return frontMatterTitleRe.test(line);
- })) {
- shared.addErrorContext(onError, token.lineNumber, token.line);
- }
- return false;
- });
+ return false;
+ });
+ }
}
};
diff --git a/test/front-matter-title-h2.json b/test/front-matter-title-h2.json
new file mode 100644
index 00000000..54223302
--- /dev/null
+++ b/test/front-matter-title-h2.json
@@ -0,0 +1,8 @@
+{
+ "default": true,
+ "MD002": {
+ "level": 2
+ },
+ "MD013": false,
+ "MD041": true
+}
diff --git a/test/front-matter-title-h2.md b/test/front-matter-title-h2.md
new file mode 100644
index 00000000..001b750c
--- /dev/null
+++ b/test/front-matter-title-h2.md
@@ -0,0 +1,9 @@
+---
+layout: post
+title: "Welcome to Jekyll!"
+date: 2015-11-17 16:16:01 -0600
+categories: jekyll update
+---
+## Secondary heading
+
+Front matter from [Jekyll documentation](https://jekyllrb.com/docs/posts/#a-typical-post).