diff --git a/.markdownlint-cli2.cjs b/.markdownlint-cli2.cjs index 2fad76ea77860a..4c32c4753903e0 100644 --- a/.markdownlint-cli2.cjs +++ b/.markdownlint-cli2.cjs @@ -2,6 +2,7 @@ const straightQuotes = require('./packages/markdownlint-rule-mui/straight-quotes const gitDiff = require('./packages/markdownlint-rule-mui/git-diff'); const tableAlignment = require('./packages/markdownlint-rule-mui/table-alignment'); const terminalLanguage = require('./packages/markdownlint-rule-mui/terminal-language'); +const duplicateH1 = require('./packages/markdownlint-rule-mui/duplicate-h1'); // https://github.com/DavidAnson/markdownlint#rules--aliases module.exports = { @@ -35,8 +36,9 @@ module.exports = { gitDiff: true, tableAlignment: true, terminalLanguage: true, + duplicateH1: true, }, - customRules: [straightQuotes, gitDiff, tableAlignment, terminalLanguage], + customRules: [straightQuotes, gitDiff, tableAlignment, terminalLanguage, duplicateH1], ignores: [ 'CHANGELOG.old.md', '**/node_modules/**', diff --git a/packages/markdownlint-rule-mui/duplicate-h1.js b/packages/markdownlint-rule-mui/duplicate-h1.js new file mode 100644 index 00000000000000..86a2ec5ce00e62 --- /dev/null +++ b/packages/markdownlint-rule-mui/duplicate-h1.js @@ -0,0 +1,31 @@ +// This rule is an extension of MD025/no-multiple-top-level-headings. +// The rule is buggy https://github.com/DavidAnson/markdownlint/pull/1109 +// but also blog headers don't tell you that h1 is already injected. +module.exports = { + names: ['duplicateH1'], + description: 'Multiple top-level headings in the same document.', + tags: ['headings'], + function: (params, onError) => { + let hasTopLevelHeading = false; + params.tokens.forEach((token) => { + if (token.type === 'heading_open' && token.tag === 'h1') { + // Avoid duplicate errors with MD025. + if (hasTopLevelHeading !== false && hasTopLevelHeading !== 1) { + onError({ + lineNumber: token.lineNumber, + }); + } else if (params.name.includes('/docs/pages/blog/')) { + onError({ + lineNumber: token.lineNumber, + details: 'In the blog, the h1 is already added using the markdown header.title value.', + }); + } + + // Store the first h1 of the page. + if (hasTopLevelHeading === false) { + hasTopLevelHeading = token.lineNumber; + } + } + }); + }, +};