From 37baddcf27bd3c17d12b440e8a102aa04007aaed Mon Sep 17 00:00:00 2001 From: David Anson Date: Sat, 29 Oct 2022 23:21:45 -0700 Subject: [PATCH] Generate Rules.md and md###.md files from metadata, improve Parameters documentation by referencing schema. --- .github/dictionary.txt | 1 + README.md | 2 +- demo/markdownlint-browser.js | 7 + doc-build/.markdownlint.jsonc | 3 + doc-build/build-rules.mjs | 96 ++++++++++++ doc-build/footing.md | 7 + doc-build/heading.md | 6 + doc-build/md001.md | 31 ++++ doc-build/md002.md | 25 ++++ doc-build/md003.md | 38 +++++ doc-build/md004.md | 36 +++++ doc-build/md005.md | 45 ++++++ doc-build/md006.md | 36 +++++ doc-build/md007.md | 36 +++++ doc-build/md009.md | 34 +++++ doc-build/md010.md | 41 +++++ doc-build/md011.md | 22 +++ doc-build/md012.md | 26 ++++ doc-build/md013.md | 36 +++++ doc-build/md014.md | 46 ++++++ doc-build/md018.md | 19 +++ doc-build/md019.md | 20 +++ doc-build/md020.md | 21 +++ doc-build/md021.md | 23 +++ doc-build/md022.md | 33 ++++ doc-build/md023.md | 18 +++ doc-build/md024.md | 35 +++++ doc-build/md025.md | 36 +++++ doc-build/md026.md | 26 ++++ doc-build/md027.md | 16 ++ doc-build/md028.md | 34 +++++ doc-build/md029.md | 87 +++++++++++ doc-build/md030.md | 64 ++++++++ doc-build/md031.md | 38 +++++ doc-build/md032.md | 30 ++++ doc-build/md033.md | 17 +++ doc-build/md034.md | 36 +++++ doc-build/md035.md | 32 ++++ doc-build/md036.md | 35 +++++ doc-build/md037.md | 29 ++++ doc-build/md038.md | 30 ++++ doc-build/md039.md | 13 ++ doc-build/md040.md | 34 +++++ doc-build/md041.md | 36 +++++ doc-build/md042.md | 25 ++++ doc-build/md043.md | 60 ++++++++ doc-build/md044.md | 20 +++ doc-build/md045.md | 24 +++ doc-build/md046.md | 28 ++++ doc-build/md047.md | 22 +++ doc-build/md048.md | 30 ++++ doc-build/md049.md | 19 +++ doc-build/md050.md | 19 +++ doc-build/md051.md | 29 ++++ doc-build/md052.md | 27 ++++ doc-build/md053.md | 26 ++++ doc/Rules.md | 225 ++++++++++++++++++---------- doc/md001.md | 37 +++++ doc/md002.md | 37 +++++ doc/md003.md | 48 ++++++ doc/md004.md | 48 ++++++ doc/md005.md | 53 +++++++ doc/md006.md | 46 ++++++ doc/md007.md | 50 +++++++ doc/md009.md | 48 ++++++ doc/md010.md | 55 +++++++ doc/md011.md | 30 ++++ doc/md012.md | 38 +++++ doc/md013.md | 54 +++++++ doc/md014.md | 54 +++++++ doc/md018.md | 27 ++++ doc/md019.md | 28 ++++ doc/md020.md | 29 ++++ doc/md021.md | 31 ++++ doc/md022.md | 46 ++++++ doc/md023.md | 26 ++++ doc/md024.md | 46 ++++++ doc/md025.md | 47 ++++++ doc/md026.md | 38 +++++ doc/md027.md | 24 +++ doc/md028.md | 40 +++++ doc/md029.md | 97 ++++++++++++ doc/md030.md | 79 ++++++++++ doc/md031.md | 50 +++++++ doc/md032.md | 38 +++++ doc/md033.md | 27 ++++ doc/md034.md | 44 ++++++ doc/md035.md | 42 ++++++ doc/md036.md | 45 ++++++ doc/md037.md | 37 +++++ doc/md038.md | 38 +++++ doc/md039.md | 21 +++ doc/md040.md | 44 ++++++ doc/md041.md | 47 ++++++ doc/md042.md | 31 ++++ doc/md043.md | 72 +++++++++ doc/md044.md | 34 +++++ doc/md045.md | 30 ++++ doc/md046.md | 38 +++++ doc/md047.md | 30 ++++ doc/md048.md | 40 +++++ doc/md049.md | 31 ++++ doc/md050.md | 31 ++++ doc/md051.md | 35 +++++ doc/md052.md | 33 ++++ doc/md053.md | 38 +++++ lib/constants.js | 7 + package.json | 4 +- test/markdownlint-test-scenarios.js | 5 + test/markdownlint-test.js | 116 +++----------- 110 files changed, 3875 insertions(+), 179 deletions(-) create mode 100644 doc-build/.markdownlint.jsonc create mode 100644 doc-build/build-rules.mjs create mode 100644 doc-build/footing.md create mode 100644 doc-build/heading.md create mode 100644 doc-build/md001.md create mode 100644 doc-build/md002.md create mode 100644 doc-build/md003.md create mode 100644 doc-build/md004.md create mode 100644 doc-build/md005.md create mode 100644 doc-build/md006.md create mode 100644 doc-build/md007.md create mode 100644 doc-build/md009.md create mode 100644 doc-build/md010.md create mode 100644 doc-build/md011.md create mode 100644 doc-build/md012.md create mode 100644 doc-build/md013.md create mode 100644 doc-build/md014.md create mode 100644 doc-build/md018.md create mode 100644 doc-build/md019.md create mode 100644 doc-build/md020.md create mode 100644 doc-build/md021.md create mode 100644 doc-build/md022.md create mode 100644 doc-build/md023.md create mode 100644 doc-build/md024.md create mode 100644 doc-build/md025.md create mode 100644 doc-build/md026.md create mode 100644 doc-build/md027.md create mode 100644 doc-build/md028.md create mode 100644 doc-build/md029.md create mode 100644 doc-build/md030.md create mode 100644 doc-build/md031.md create mode 100644 doc-build/md032.md create mode 100644 doc-build/md033.md create mode 100644 doc-build/md034.md create mode 100644 doc-build/md035.md create mode 100644 doc-build/md036.md create mode 100644 doc-build/md037.md create mode 100644 doc-build/md038.md create mode 100644 doc-build/md039.md create mode 100644 doc-build/md040.md create mode 100644 doc-build/md041.md create mode 100644 doc-build/md042.md create mode 100644 doc-build/md043.md create mode 100644 doc-build/md044.md create mode 100644 doc-build/md045.md create mode 100644 doc-build/md046.md create mode 100644 doc-build/md047.md create mode 100644 doc-build/md048.md create mode 100644 doc-build/md049.md create mode 100644 doc-build/md050.md create mode 100644 doc-build/md051.md create mode 100644 doc-build/md052.md create mode 100644 doc-build/md053.md create mode 100644 doc/md001.md create mode 100644 doc/md002.md create mode 100644 doc/md003.md create mode 100644 doc/md004.md create mode 100644 doc/md005.md create mode 100644 doc/md006.md create mode 100644 doc/md007.md create mode 100644 doc/md009.md create mode 100644 doc/md010.md create mode 100644 doc/md011.md create mode 100644 doc/md012.md create mode 100644 doc/md013.md create mode 100644 doc/md014.md create mode 100644 doc/md018.md create mode 100644 doc/md019.md create mode 100644 doc/md020.md create mode 100644 doc/md021.md create mode 100644 doc/md022.md create mode 100644 doc/md023.md create mode 100644 doc/md024.md create mode 100644 doc/md025.md create mode 100644 doc/md026.md create mode 100644 doc/md027.md create mode 100644 doc/md028.md create mode 100644 doc/md029.md create mode 100644 doc/md030.md create mode 100644 doc/md031.md create mode 100644 doc/md032.md create mode 100644 doc/md033.md create mode 100644 doc/md034.md create mode 100644 doc/md035.md create mode 100644 doc/md036.md create mode 100644 doc/md037.md create mode 100644 doc/md038.md create mode 100644 doc/md039.md create mode 100644 doc/md040.md create mode 100644 doc/md041.md create mode 100644 doc/md042.md create mode 100644 doc/md043.md create mode 100644 doc/md044.md create mode 100644 doc/md045.md create mode 100644 doc/md046.md create mode 100644 doc/md047.md create mode 100644 doc/md048.md create mode 100644 doc/md049.md create mode 100644 doc/md050.md create mode 100644 doc/md051.md create mode 100644 doc/md052.md create mode 100644 doc/md053.md diff --git a/.github/dictionary.txt b/.github/dictionary.txt index 62f109ff..3865c608 100644 --- a/.github/dictionary.txt +++ b/.github/dictionary.txt @@ -3,6 +3,7 @@ APIs async atx ATX +atx_closed atx-style axibase backtick diff --git a/README.md b/README.md index 08815aec..b960252f 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ playground for learning and exploring. See [Rules.md](doc/Rules.md) for more details. -~~Struck through~~ rules are deprecated, and provided for backward-compatibility. +~~Struck through~~ rules are deprecated and provided for backward-compatibility. > All rules with `heading` as part of their name are also available as > `header` aliases (e.g. `heading-increment` is also available as `header-increment`). diff --git a/demo/markdownlint-browser.js b/demo/markdownlint-browser.js index 4fc25b27..2e781505 100644 --- a/demo/markdownlint-browser.js +++ b/demo/markdownlint-browser.js @@ -1199,6 +1199,13 @@ module.exports.referenceLinkImageData = // @ts-check module.exports.deprecatedRuleNames = ["MD002", "MD006"]; +module.exports.fixableRuleNames = [ + "MD004", "MD005", "MD006", "MD007", "MD009", "MD010", + "MD011", "MD012", "MD014", "MD018", "MD019", "MD020", + "MD021", "MD022", "MD023", "MD026", "MD027", "MD030", + "MD031", "MD032", "MD034", "MD037", "MD038", "MD039", + "MD044", "MD047", "MD049", "MD050", "MD053" +]; module.exports.homepage = "https://github.com/DavidAnson/markdownlint"; module.exports.version = "0.26.2"; diff --git a/doc-build/.markdownlint.jsonc b/doc-build/.markdownlint.jsonc new file mode 100644 index 00000000..7460c9a6 --- /dev/null +++ b/doc-build/.markdownlint.jsonc @@ -0,0 +1,3 @@ +{ + "first-line-heading": false +} diff --git a/doc-build/build-rules.mjs b/doc-build/build-rules.mjs new file mode 100644 index 00000000..470cc80d --- /dev/null +++ b/doc-build/build-rules.mjs @@ -0,0 +1,96 @@ +import { readFile, writeFile } from "node:fs/promises"; +import { EOL } from "node:os"; +import { default as rules } from "../lib/rules.js"; +import { newLineRe } from "../helpers/helpers.js"; +import { deprecatedRuleNames, fixableRuleNames } from "../lib/constants.js"; + +const pathFor = (relativePath) => new URL(relativePath, import.meta.url); +const sortedComma = (items) => items.sort().join(", "); +const linesFrom = (text) => text.split(newLineRe); + +// import { default as schema } from "file.json" assert { type: "json" }; +const importJson = + async(file) => JSON.parse(await readFile(pathFor(file))); +const schema = await importJson("../schema/markdownlint-config-schema.json"); + +const lines = []; + +const heading = await readFile(pathFor("./heading.md"), "utf8"); +lines.push(...linesFrom(heading)); + +for (const rule of rules) { + const name = rule.names[0]; + const deprecated = deprecatedRuleNames.includes(name); + const decorator = deprecated ? "~~" : ""; + lines.push( + ``, + "" + ); + const section = []; + section.push( + `## ${decorator}${name} - ${rule.description}${decorator}`, + "" + ); + if (deprecated) { + section.push( + "> This rule is deprecated and provided for backward-compatibility", + "" + ); + } + section.push( + `Tags: ${sortedComma(rule.tags)}`, + "", + `Aliases: ${sortedComma(rule.names.slice(1))}`, + "" + ); + const ruleData = schema.properties[name]; + if (ruleData.properties) { + section.push( + "Parameters:", + "", + ...Object.keys(ruleData.properties).sort().map((property) => { + const propData = ruleData.properties[property]; + const propType = (propData.type === "array") ? + `${propData.items.type}[]` : + propData.type; + const defaultValue = Array.isArray(propData.default) ? + JSON.stringify(propData.default) : + propData.default; + const allValues = propData.enum?.sort(); + return `* \`${property}\`: ${propData.description} (` + + `\`${propType}\`, default \`${defaultValue}\`` + + (propData.enum ? + `, values ${allValues.map((value) => `\`${value}\``).join("/")}` : + "" + ) + + ")"; + }), + "" + ); + } + if (fixableRuleNames.includes(name)) { + section.push( + "Fixable: Most violations can be fixed by tooling", + "" + ); + } + const contents = + // eslint-disable-next-line no-await-in-loop + await readFile(pathFor(`./${name.toLowerCase()}.md`), "utf8"); + section.push(...linesFrom(contents)); + + // eslint-disable-next-line no-await-in-loop + await writeFile( + pathFor(`../doc/${name.toLowerCase()}.md`), + section.join(EOL).slice(1), + "utf8" + ); + + lines.push(...section); +} + +const footing = await readFile(pathFor("./footing.md"), "utf8"); +lines.push(...linesFrom(footing)); + +const content = lines.join(EOL); +await writeFile(pathFor("../doc/Rules.md"), content, "utf8"); diff --git a/doc-build/footing.md b/doc-build/footing.md new file mode 100644 index 00000000..c0ea00fb --- /dev/null +++ b/doc-build/footing.md @@ -0,0 +1,7 @@ + diff --git a/doc-build/heading.md b/doc-build/heading.md new file mode 100644 index 00000000..0581c8b7 --- /dev/null +++ b/doc-build/heading.md @@ -0,0 +1,6 @@ +# Rules + +This document contains a description of all rules, what they are checking for, +as well as examples of documents that break the rule and corrected +versions of the examples. Any rule whose heading is ~~struck through~~ is +deprecated, but still provided for backward-compatibility. diff --git a/doc-build/md001.md b/doc-build/md001.md new file mode 100644 index 00000000..95c47ced --- /dev/null +++ b/doc-build/md001.md @@ -0,0 +1,31 @@ +This rule is triggered when you skip heading levels in a Markdown document, for +example: + +```markdown +# Heading 1 + +### Heading 3 + +We skipped out a 2nd level heading in this document +``` + +When using multiple heading levels, nested headings should increase by only one +level at a time: + +```markdown +# Heading 1 + +## Heading 2 + +### Heading 3 + +#### Heading 4 + +## Another Heading 2 + +### Another Heading 3 +``` + +Rationale: Headings represent the structure of a document and can be confusing +when skipped - especially for accessibility scenarios. More information: +. diff --git a/doc-build/md002.md b/doc-build/md002.md new file mode 100644 index 00000000..c3d6fb24 --- /dev/null +++ b/doc-build/md002.md @@ -0,0 +1,25 @@ +> Note: *MD002 has been deprecated and is disabled by default.* +> [MD041/first-line-heading](md041.md) offers an improved implementation. + +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 an H1 heading + +### Another heading +``` + +The first heading in the document should be an h1 heading: + +```markdown +# Start with an H1 heading + +## 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. + +Rationale: The top-level heading often acts as the title of a document. More +information: . diff --git a/doc-build/md003.md b/doc-build/md003.md new file mode 100644 index 00000000..6e039588 --- /dev/null +++ b/doc-build/md003.md @@ -0,0 +1,38 @@ +This rule is triggered when different heading styles (atx, setext, and 'closed' +atx) are used in the same document: + +```markdown +# ATX style H1 + +## Closed ATX style H2 ## + +Setext style H1 +=============== +``` + +Be consistent with the style of heading used in a document: + +```markdown +# ATX style H1 + +## ATX style H2 +``` + +The setext_with_atx and setext_with_atx_closed doc styles allow atx-style +headings of level 3 or more in documents with setext style headings: + +```markdown +Setext style H1 +=============== + +Setext style H2 +--------------- + +### ATX style H3 +``` + +Note: the configured heading style can be a specific style to use (atx, +atx_closed, setext, setext_with_atx, setext_with_atx_closed), or simply require +that the usage is consistent within the document. + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc-build/md004.md b/doc-build/md004.md new file mode 100644 index 00000000..f7405a61 --- /dev/null +++ b/doc-build/md004.md @@ -0,0 +1,36 @@ +This rule is triggered when the symbols used in the document for unordered +list items do not match the configured unordered list style: + +```markdown +* Item 1 ++ Item 2 +- Item 3 +``` + +To fix this issue, use the configured style for list items throughout the +document: + +```markdown +* Item 1 +* Item 2 +* Item 3 +``` + +The configured list style can be a specific symbol to use (asterisk, plus, dash), +to ensure that all list styling is consistent, or to ensure that each +sublist has a consistent symbol that differs from its parent list. + +For example, the following is valid for the `sublist` style because the outer-most +indent uses asterisk, the middle indent uses plus, and the inner-most indent uses +dash: + +```markdown +* Item 1 + + Item 2 + - Item 3 + + Item 4 +* Item 4 + + Item 5 +``` + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc-build/md005.md b/doc-build/md005.md new file mode 100644 index 00000000..9c667074 --- /dev/null +++ b/doc-build/md005.md @@ -0,0 +1,45 @@ +This rule is triggered when list items are parsed as being at the same level, +but don't have the same indentation: + +```markdown +* Item 1 + * Nested Item 1 + * Nested Item 2 + * A misaligned item +``` + +Usually, this rule will be triggered because of a typo. Correct the indentation +for the list to fix it: + +```markdown +* Item 1 + * Nested Item 1 + * Nested Item 2 + * Nested Item 3 +``` + +Sequentially-ordered list markers are usually left-aligned such that all items +have the same starting column: + +```markdown +... +8. Item +9. Item +10. Item +11. Item +... +``` + +This rule also supports right-alignment of list markers such that all items have +the same ending column: + +```markdown +... + 8. Item + 9. Item +10. Item +11. Item +... +``` + +Rationale: Violations of this rule can lead to improperly rendered content. diff --git a/doc-build/md006.md b/doc-build/md006.md new file mode 100644 index 00000000..d6ef6c0f --- /dev/null +++ b/doc-build/md006.md @@ -0,0 +1,36 @@ +This rule is triggered when top-level lists don't start at the beginning of a +line: + +```markdown +Some text + + * List item + * List item +``` + +To fix, ensure that top-level list items are not indented: + +```markdown +Some test + +* List item +* List item +``` + +Note: This rule is triggered for the following scenario because the unordered +sublist is not recognized as such by the parser. Not being nested 3 characters +as required by the outer ordered list, it creates a top-level unordered list +instead. + +```markdown +1. List item + - List item + - List item +1. List item +``` + +Rationale: Starting lists at the beginning of the line means that nested list +items can all be indented by the same amount when an editor's indent function +or the tab key is used to indent. Starting a list 1 space in means that the +indent of the first nested list is less than the indent of the second level (3 +characters if you use 4 space tabs, or 1 character if you use 2 space tabs). diff --git a/doc-build/md007.md b/doc-build/md007.md new file mode 100644 index 00000000..f836b6c8 --- /dev/null +++ b/doc-build/md007.md @@ -0,0 +1,36 @@ +This rule is triggered when list items are not indented by the configured +number of spaces (default: 2). + +Example: + +```markdown +* List item + * Nested list item indented by 3 spaces +``` + +Corrected Example: + +```markdown +* List item + * Nested list item indented by 2 spaces +``` + +Note: This rule applies to a sublist only if its parent lists are all also +unordered (otherwise, extra indentation of ordered lists interferes with the +rule). + +The `start_indented` parameter allows the first level of lists to be indented by +the configured number of spaces rather than starting at zero (the inverse of +MD006). The `start_indent` parameter allows the first level of lists to be indented +by a different number of spaces than the rest (ignored when `start_indented` is not +set). + +Rationale: Indenting by 2 spaces allows the content of a nested list to be in +line with the start of the content of the parent list when a single space is +used after the list marker. Indenting by 4 spaces is consistent with code blocks +and simpler for editors to implement. Additionally, this can be a compatibility +issue for other Markdown parsers, which require 4-space indents. More information: + +and . + +Note: See [Prettier.md](Prettier.md) for compatibility information. diff --git a/doc-build/md009.md b/doc-build/md009.md new file mode 100644 index 00000000..3b017b3c --- /dev/null +++ b/doc-build/md009.md @@ -0,0 +1,34 @@ +This rule is triggered on any lines that end with unexpected whitespace. To fix this, +remove the trailing space from the end of the line. + +Note: Trailing space is allowed in indented and fenced code blocks because some +languages require it. + +The `br_spaces` parameter allows an exception to this rule for a specific number +of trailing spaces, typically used to insert an explicit line break. The default +value allows 2 spaces to indicate a hard break (\
element). + +Note: You must set `br_spaces` to a value >= 2 for this parameter to take effect. +Setting `br_spaces` to 1 behaves the same as 0, disallowing any trailing spaces. + +By default, this rule will not trigger when the allowed number of spaces is used, +even when it doesn't create a hard break (for example, at the end of a paragraph). +To report such instances as well, set the `strict` parameter to `true`. + +```markdown +Text text text +text[2 spaces] +``` + +Using spaces to indent blank lines inside a list item is usually not necessary, +but some parsers require it. Set the `list_item_empty_lines` parameter to `true` +to allow this (even when `strict` is `true`): + +```markdown +- list item text + [2 spaces] + list item text +``` + +Rationale: Except when being used to create a line break, trailing whitespace +has no purpose and does not affect the rendering of content. diff --git a/doc-build/md010.md b/doc-build/md010.md new file mode 100644 index 00000000..a3b304ca --- /dev/null +++ b/doc-build/md010.md @@ -0,0 +1,41 @@ +This rule is triggered by any lines that contain hard tab characters instead +of using spaces for indentation. To fix this, replace any hard tab characters +with spaces instead. + +Example: + + + +```markdown +Some text + + * hard tab character used to indent the list item +``` + + + +Corrected example: + +```markdown +Some text + + * Spaces used to indent the list item instead +``` + +You have the option to exclude this rule for code blocks and spans. To do so, +set the `code_blocks` parameter to `false`. Code blocks and spans are included +by default since handling of tabs by Markdown tools can be inconsistent (e.g., +using 4 vs. 8 spaces). + +When code blocks are scanned (e.g., by default or if `code_blocks` is `true`), +the `ignore_code_languages` parameter can be set to a list of languages that +should be ignored (i.e., hard tabs will be allowed, though not required). This +makes it easier for documents to include code for languages that require hard +tabs. + +By default, violations of this rule are fixed by replacing the tab with 1 space +character. To use a different number of spaces, set the `spaces_per_tab` +parameter to the desired value. + +Rationale: Hard tabs are often rendered inconsistently by different editors and +can be harder to work with than spaces. diff --git a/doc-build/md011.md b/doc-build/md011.md new file mode 100644 index 00000000..fcc25e8e --- /dev/null +++ b/doc-build/md011.md @@ -0,0 +1,22 @@ +This rule is triggered when text that appears to be a link is encountered, but +where the syntax appears to have been reversed (the `[]` and `()` are +reversed): + +```markdown +(Incorrect link syntax)[https://www.example.com/] +``` + +To fix this, swap the `[]` and `()` around: + +```markdown +[Correct link syntax](https://www.example.com/) +``` + +Note: [Markdown Extra](https://en.wikipedia.org/wiki/Markdown_Extra)-style +footnotes do not trigger this rule: + +```markdown +For (example)[^1] +``` + +Rationale: Reversed links are not rendered as usable links. diff --git a/doc-build/md012.md b/doc-build/md012.md new file mode 100644 index 00000000..7a5291e2 --- /dev/null +++ b/doc-build/md012.md @@ -0,0 +1,26 @@ +This rule is triggered when there are multiple consecutive blank lines in the +document: + +```markdown +Some text here + + +Some more text here +``` + +To fix this, delete the offending lines: + +```markdown +Some text here + +Some more text here +``` + +Note: this rule will not be triggered if there are multiple consecutive blank +lines inside code blocks. + +Note: The `maximum` parameter can be used to configure the maximum number of +consecutive blank lines. + +Rationale: Except in a code block, blank lines serve no purpose and do not +affect the rendering of content. diff --git a/doc-build/md013.md b/doc-build/md013.md new file mode 100644 index 00000000..3878986c --- /dev/null +++ b/doc-build/md013.md @@ -0,0 +1,36 @@ +> If `headings` is not provided, `headers` (deprecated) will be used. + +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 +up into multiple lines. To set a different maximum length for headings, use +`heading_line_length`. To set a different maximum length for code blocks, use +`code_block_line_length` + +This rule has an exception when there is no whitespace beyond the configured +line length. This allows you to still include items such as long URLs without +being forced to break them in the middle. To disable this exception, set the +`strict` parameter to `true` to report an issue when any line is too long. +To warn for lines that are too long and could be fixed but allow lines without +spaces, set the `stern` parameter to `true`. + +For example (assuming normal behavior): + +```markdown +IF THIS LINE IS THE MAXIMUM LENGTH +This line is okay because there are-no-spaces-beyond-that-length +And this line is a violation because there are +This-line-is-also-okay-because-there-are-no-spaces +``` + +In `strict` or `stern` modes, the two middle lines above are a violation. The +third line is a violation in `strict` mode but allowed in `stern` mode. + +You have the option to exclude this rule for code blocks, tables, or headings. +To do so, set the `code_blocks`, `tables`, or `headings` parameter(s) to false. + +Code blocks are included in this rule by default since it is often a +requirement for document readability, and tentatively compatible with code +rules. Still, some languages do not lend themselves to short lines. + +Rationale: Extremely long lines can be difficult to work with in some editors. +More information: . diff --git a/doc-build/md014.md b/doc-build/md014.md new file mode 100644 index 00000000..51e380c4 --- /dev/null +++ b/doc-build/md014.md @@ -0,0 +1,46 @@ +This rule is triggered when there are code blocks showing shell commands to be +typed, and *all* of the shell commands are preceded by dollar signs ($): + + + +```markdown +$ ls +$ cat foo +$ less bar +``` + + + +The dollar signs are unnecessary in this situation, and should not be +included: + +```markdown +ls +cat foo +less bar +``` + +Showing output for commands preceded by dollar signs does not trigger this rule: + +```markdown +$ ls +foo bar +$ cat foo +Hello world +$ cat bar +baz +``` + +Because some commands do not produce output, it is not a violation if *some* +commands do not have output: + +```markdown +$ mkdir test +mkdir: created directory 'test' +$ ls test +``` + +Rationale: It is easier to copy/paste and less noisy if the dollar signs +are omitted when they are not needed. See + +for more information. diff --git a/doc-build/md018.md b/doc-build/md018.md new file mode 100644 index 00000000..65c7a8dc --- /dev/null +++ b/doc-build/md018.md @@ -0,0 +1,19 @@ +This rule is triggered when spaces are missing after the hash characters +in an atx style heading: + +```markdown +#Heading 1 + +##Heading 2 +``` + +To fix this, separate the heading text from the hash character by a single +space: + +```markdown +# Heading 1 + +## Heading 2 +``` + +Rationale: Violations of this rule can lead to improperly rendered content. diff --git a/doc-build/md019.md b/doc-build/md019.md new file mode 100644 index 00000000..2ca6f34b --- /dev/null +++ b/doc-build/md019.md @@ -0,0 +1,20 @@ +This rule is triggered when more than one space is used to separate the +heading text from the hash characters in an atx style heading: + +```markdown +# Heading 1 + +## Heading 2 +``` + +To fix this, separate the heading text from the hash character by a single +space: + +```markdown +# Heading 1 + +## Heading 2 +``` + +Rationale: Extra space has no purpose and does not affect the rendering of +content. diff --git a/doc-build/md020.md b/doc-build/md020.md new file mode 100644 index 00000000..4e87320d --- /dev/null +++ b/doc-build/md020.md @@ -0,0 +1,21 @@ +This rule is triggered when spaces are missing inside the hash characters +in a closed atx style heading: + +```markdown +#Heading 1# + +##Heading 2## +``` + +To fix this, separate the heading text from the hash character by a single +space: + +```markdown +# Heading 1 # + +## Heading 2 ## +``` + +Note: this rule will fire if either side of the heading is missing spaces. + +Rationale: Violations of this rule can lead to improperly rendered content. diff --git a/doc-build/md021.md b/doc-build/md021.md new file mode 100644 index 00000000..07d97750 --- /dev/null +++ b/doc-build/md021.md @@ -0,0 +1,23 @@ +This rule is triggered when more than one space is used to separate the +heading text from the hash characters in a closed atx style heading: + +```markdown +# Heading 1 # + +## Heading 2 ## +``` + +To fix this, separate the heading text from the hash character by a single +space: + +```markdown +# Heading 1 # + +## Heading 2 ## +``` + +Note: this rule will fire if either side of the heading contains multiple +spaces. + +Rationale: Extra space has no purpose and does not affect the rendering of +content. diff --git a/doc-build/md022.md b/doc-build/md022.md new file mode 100644 index 00000000..4f3828c9 --- /dev/null +++ b/doc-build/md022.md @@ -0,0 +1,33 @@ +This rule is triggered when headings (any style) are either not preceded or not +followed by at least one blank line: + +```markdown +# Heading 1 +Some text + +Some more text +## Heading 2 +``` + +To fix this, ensure that all headings have a blank line both before and after +(except where the heading is at the beginning or end of the document): + +```markdown +# Heading 1 + +Some text + +Some more text + +## Heading 2 +``` + +The `lines_above` and `lines_below` parameters can be used to specify a different +number of blank lines (including 0) above or below each heading. + +Note: If `lines_above` or `lines_below` are configured to require more than one +blank line, [MD012/no-multiple-blanks](md012.md) should also be customized. + +Rationale: Aside from aesthetic reasons, some parsers, including `kramdown`, will +not parse headings that don't have a blank line before, and will parse them as +regular text. diff --git a/doc-build/md023.md b/doc-build/md023.md new file mode 100644 index 00000000..57d549e8 --- /dev/null +++ b/doc-build/md023.md @@ -0,0 +1,18 @@ +This rule is triggered when a heading is indented by one or more spaces: + +```markdown +Some text + + # Indented heading +``` + +To fix this, ensure that all headings start at the beginning of the line: + +```markdown +Some text + +# Heading +``` + +Rationale: Headings that don't start at the beginning of the line will not be +parsed as headings, and will instead appear as regular text. diff --git a/doc-build/md024.md b/doc-build/md024.md new file mode 100644 index 00000000..afe663f5 --- /dev/null +++ b/doc-build/md024.md @@ -0,0 +1,35 @@ +This rule is triggered if there are multiple headings in the document that have +the same text: + +```markdown +# Some text + +## Some text +``` + +To fix this, ensure that the content of each heading is different: + +```markdown +# Some text + +## Some more text +``` + +If the parameter `siblings_only` (alternatively `allow_different_nesting`) is +set to `true`, heading duplication is allowed for non-sibling headings (common +in changelogs): + +```markdown +# Change log + +## 1.0.0 + +### Features + +## 2.0.0 + +### Features +``` + +Rationale: Some Markdown parsers generate anchors for headings based on the +heading name; headings with the same content can cause problems with that. diff --git a/doc-build/md025.md b/doc-build/md025.md new file mode 100644 index 00000000..d5904e88 --- /dev/null +++ b/doc-build/md025.md @@ -0,0 +1,36 @@ +This rule is triggered when a top-level heading is in use (the first line of +the file is an h1 heading), and more than one h1 heading is in use in the +document: + +```markdown +# Top level heading + +# Another top-level heading +``` + +To fix, structure your document so there is a single h1 heading that is +the title for the document. Subsequent headings must be +lower-level headings (h2, h3, etc.): + +```markdown +# Title + +## Heading + +## Another heading +``` + +Note: The `level` parameter can be used to change the top-level (ex: to h2) in +cases where an h1 is added externally. + +If [YAML](https://en.wikipedia.org/wiki/YAML) front matter is present and contains +a `title` property (commonly used with blog posts), this rule treats that as a top +level heading and will report a violation for any subsequent top-level headings. +To use a different property name in the 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`. + +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. diff --git a/doc-build/md026.md b/doc-build/md026.md new file mode 100644 index 00000000..949fd2b2 --- /dev/null +++ b/doc-build/md026.md @@ -0,0 +1,26 @@ +This rule is triggered on any heading that has one of the specified normal or +full-width punctuation characters as the last character in the line: + +```markdown +# This is a heading. +``` + +To fix this, remove the trailing punctuation: + +```markdown +# This is a heading +``` + +Note: The `punctuation` parameter can be used to specify what characters count +as punctuation at the end of a heading. For example, you can change it to +`".,;:"` to allow headings that end with an exclamation point. `?` is +allowed by default because of how common it is in headings of FAQ-style documents. +Setting the `punctuation` parameter to `""` allows all characters - and is +equivalent to disabling the rule. + +Note: The trailing semicolon of +[HTML entity references](https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references) +like `©`, `©`, and `©` is ignored by this rule. + +Rationale: Headings are not meant to be full sentences. More information: + diff --git a/doc-build/md027.md b/doc-build/md027.md new file mode 100644 index 00000000..14d79de4 --- /dev/null +++ b/doc-build/md027.md @@ -0,0 +1,16 @@ +This rule is triggered when blockquotes have more than one space after the +blockquote (`>`) symbol: + +```markdown +> This is a blockquote with bad indentation +> there should only be one. +``` + +To fix, remove any extraneous space: + +```markdown +> This is a blockquote with correct +> indentation. +``` + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc-build/md028.md b/doc-build/md028.md new file mode 100644 index 00000000..4272ce53 --- /dev/null +++ b/doc-build/md028.md @@ -0,0 +1,34 @@ +This rule is triggered when two blockquote blocks are separated by nothing +except for a blank line: + +```markdown +> This is a blockquote +> which is immediately followed by + +> this blockquote. Unfortunately +> In some parsers, these are treated as the same blockquote. +``` + +To fix this, ensure that any blockquotes that are right next to each other +have some text in between: + +```markdown +> This is a blockquote. + +And Jimmy also said: + +> This too is a blockquote. +``` + +Alternatively, if they are supposed to be the same quote, then add the +blockquote symbol at the beginning of the blank line: + +```markdown +> This is a blockquote. +> +> This is the same blockquote. +``` + +Rationale: Some Markdown parsers will treat two blockquotes separated by one +or more blank lines as the same blockquote, while others will treat them as +separate blockquotes. diff --git a/doc-build/md029.md b/doc-build/md029.md new file mode 100644 index 00000000..3921cfa7 --- /dev/null +++ b/doc-build/md029.md @@ -0,0 +1,87 @@ +This rule is triggered for ordered lists that do not either start with '1.' or +do not have a prefix that increases in numerical order (depending on the +configured style). The less-common pattern of using '0.' as a first prefix or +for all prefixes is also supported. + +Example valid list if the style is configured as 'one': + +```markdown +1. Do this. +1. Do that. +1. Done. +``` + +Examples of valid lists if the style is configured as 'ordered': + +```markdown +1. Do this. +2. Do that. +3. Done. +``` + +```markdown +0. Do this. +1. Do that. +2. Done. +``` + +All three examples are valid when the style is configured as 'one_or_ordered'. + +Example valid list if the style is configured as 'zero': + +```markdown +0. Do this. +0. Do that. +0. Done. +``` + +Example invalid list for all styles: + +```markdown +1. Do this. +3. Done. +``` + +This rule supports 0-prefixing ordered list items for uniform indentation: + +```markdown +... +08. Item +09. Item +10. Item +11. Item +... +``` + +Note: This rule will report violations for cases like the following where an +improperly-indented code block (or similar) appears between two list items and +"breaks" the list in two: + + + +~~~markdown +1. First list + +```text +Code block +``` + +1. Second list +~~~ + +The fix is to indent the code block so it becomes part of the preceding list +item as intended: + +~~~markdown +1. First list + + ```text + Code block + ``` + +2. Still first list +~~~ + + + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc-build/md030.md b/doc-build/md030.md new file mode 100644 index 00000000..dae56eda --- /dev/null +++ b/doc-build/md030.md @@ -0,0 +1,64 @@ +This rule checks for the number of spaces between a list marker (e.g. '`-`', +'`*`', '`+`' or '`1.`') and the text of the list item. + +The number of spaces checked for depends on the document style in use, but the +default is 1 space after any list marker: + +```markdown +* Foo +* Bar +* Baz + +1. Foo +1. Bar +1. Baz + +1. Foo + * Bar +1. Baz +``` + +A document style may change the number of spaces after unordered list items +and ordered list items independently, as well as based on whether the content +of every item in the list consists of a single paragraph or multiple +paragraphs (including sub-lists and code blocks). + +For example, the style guide at + +specifies that 1 space after the list marker should be used if every item in +the list fits within a single paragraph, but to use 2 or 3 spaces (for ordered +and unordered lists respectively) if there are multiple paragraphs of content +inside the list: + +```markdown +* Foo +* Bar +* Baz +``` + +vs. + +```markdown +* Foo + + Second paragraph + +* Bar +``` + +or + +```markdown +1. Foo + + Second paragraph + +1. Bar +``` + +To fix this, ensure the correct number of spaces are used after the list marker +for your selected document style. + +Rationale: Violations of this rule can lead to improperly rendered content. + +Note: See [Prettier.md](Prettier.md) for compatibility information. diff --git a/doc-build/md031.md b/doc-build/md031.md new file mode 100644 index 00000000..4cc1fb0a --- /dev/null +++ b/doc-build/md031.md @@ -0,0 +1,38 @@ +This rule is triggered when fenced code blocks are either not preceded or not +followed by a blank line: + +````markdown +Some text +``` +Code block +``` + +``` +Another code block +``` +Some more text +```` + +To fix this, ensure that all fenced code blocks have a blank line both before +and after (except where the block is at the beginning or end of the document): + +````markdown +Some text + +``` +Code block +``` + +``` +Another code block +``` + +Some more text +```` + +Set the `list_items` parameter to `false` to disable this rule for list items. +Disabling this behavior for lists can be useful if it is necessary to create a +[tight](https://spec.commonmark.org/0.29/#tight) list containing a code fence. + +Rationale: Aside from aesthetic reasons, some parsers, including kramdown, will +not parse fenced code blocks that don't have blank lines before and after them. diff --git a/doc-build/md032.md b/doc-build/md032.md new file mode 100644 index 00000000..0cf4b715 --- /dev/null +++ b/doc-build/md032.md @@ -0,0 +1,30 @@ +This rule is triggered when lists (of any kind) are either not preceded or not +followed by a blank line: + +```markdown +Some text +* Some +* List + +1. Some +2. List +Some text +``` + +To fix this, ensure that all lists have a blank line both before and after +(except where the block is at the beginning or end of the document): + +```markdown +Some text + +* Some +* List + +1. Some +2. List + +Some text +``` + +Rationale: Aside from aesthetic reasons, some parsers, including kramdown, will +not parse lists that don't have blank lines before and after them. diff --git a/doc-build/md033.md b/doc-build/md033.md new file mode 100644 index 00000000..98dc8a73 --- /dev/null +++ b/doc-build/md033.md @@ -0,0 +1,17 @@ +This rule is triggered whenever raw HTML is used in a Markdown document: + +```markdown +

Inline HTML heading

+``` + +To fix this, use 'pure' Markdown instead of including raw HTML: + +```markdown +# Markdown heading +``` + +Note: To allow specific HTML elements, use the `allowed_elements` parameter. + +Rationale: Raw HTML is allowed in Markdown, but this rule is included for +those who want their documents to only include "pure" Markdown, or for those +who are rendering Markdown documents into something other than HTML. diff --git a/doc-build/md034.md b/doc-build/md034.md new file mode 100644 index 00000000..9a013b46 --- /dev/null +++ b/doc-build/md034.md @@ -0,0 +1,36 @@ +This rule is triggered whenever a URL is given that isn't surrounded by angle +brackets: + +```markdown +For more information, see https://www.example.com/. +``` + +To fix this, add angle brackets around the URL: + +```markdown +For more information, see . +``` + +Note: To use a bare URL without it being converted into a link, enclose it in +a code block, otherwise in some Markdown parsers it *will* be converted: + +```markdown +`https://www.example.com` +``` + +Note: The following scenario does *not* trigger this rule to avoid conflicts +with `MD011`/`no-reversed-links`: + +```markdown +[https://www.example.com] +``` + +The use of quotes around a bare link will *not* trigger this rule, either: + +```markdown +"https://www.example.com" +'https://www.example.com' +``` + +Rationale: Without angle brackets, the URL isn't converted into a link by many +Markdown parsers. diff --git a/doc-build/md035.md b/doc-build/md035.md new file mode 100644 index 00000000..7238c4eb --- /dev/null +++ b/doc-build/md035.md @@ -0,0 +1,32 @@ +This rule is triggered when inconsistent styles of horizontal rules are used +in the document: + +```markdown +--- + +- - - + +*** + +* * * + +**** +``` + +To fix this, ensure any horizontal rules used in the document are consistent, +or match the given style if the rule is so configured: + +```markdown +--- + +--- +``` + +Note: by default, this rule is configured to just require that all horizontal +rules in the document are the same and will trigger if any of the horizontal +rules are different than the first one encountered in the document. If you +want to configure the rule to match a specific style, the parameter given to +the 'style' option is a string containing the exact horizontal rule text that +is allowed. + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc-build/md036.md b/doc-build/md036.md new file mode 100644 index 00000000..4b39bf37 --- /dev/null +++ b/doc-build/md036.md @@ -0,0 +1,35 @@ +This check looks for instances where emphasized (i.e. bold or italic) text is +used to separate sections, where a heading should be used instead: + +```markdown +**My document** + +Lorem ipsum dolor sit amet... + +_Another section_ + +Consectetur adipiscing elit, sed do eiusmod. +``` + +To fix this, use Markdown headings instead of emphasized text to denote +sections: + +```markdown +# My document + +Lorem ipsum dolor sit amet... + +## Another section + +Consectetur adipiscing elit, sed do eiusmod. +``` + +Note: This rule looks for single-line paragraphs that consist entirely +of emphasized text. It won't fire on emphasis used within regular text, +multi-line emphasized paragraphs, or paragraphs ending in punctuation +(normal or full-width). Similarly to rule MD026, you can configure what +characters are recognized as punctuation. + +Rationale: Using emphasis instead of a heading prevents tools from inferring +the structure of a document. More information: +. diff --git a/doc-build/md037.md b/doc-build/md037.md new file mode 100644 index 00000000..683d5f0e --- /dev/null +++ b/doc-build/md037.md @@ -0,0 +1,29 @@ +This rule is triggered when emphasis markers (bold, italic) are used, but they +have spaces between the markers and the text: + +```markdown +Here is some ** bold ** text. + +Here is some * italic * text. + +Here is some more __ bold __ text. + +Here is some more _ italic _ text. +``` + +To fix this, remove the spaces around the emphasis markers: + +```markdown +Here is some **bold** text. + +Here is some *italic* text. + +Here is some more __bold__ text. + +Here is some more _italic_ text. +``` + +Rationale: Emphasis is only parsed as such when the asterisks/underscores +aren't surrounded by spaces. This rule attempts to detect where +they were surrounded by spaces, but it appears that emphasized text was +intended by the author. diff --git a/doc-build/md038.md b/doc-build/md038.md new file mode 100644 index 00000000..4579f250 --- /dev/null +++ b/doc-build/md038.md @@ -0,0 +1,30 @@ +This rule is triggered for code span elements that have spaces adjacent to the +backticks: + +```markdown +`some text ` + +` some text` +``` + +To fix this, remove any spaces adjacent to the backticks: + +```markdown +`some text` +``` + +Note: A single leading and trailing space is allowed by the specification and +automatically trimmed (to allow for embedded backticks): + +```markdown +`` `backticks` `` +``` + +Note: A single leading or trailing space is allowed if used to separate code span +markers from an embedded backtick: + +```markdown +`` ` embedded backtick`` +``` + +Rationale: Violations of this rule can lead to improperly rendered content. diff --git a/doc-build/md039.md b/doc-build/md039.md new file mode 100644 index 00000000..e6f5903d --- /dev/null +++ b/doc-build/md039.md @@ -0,0 +1,13 @@ +This rule is triggered on links that have spaces surrounding the link text: + +```markdown +[ a link ](https://www.example.com/) +``` + +To fix this, remove the spaces surrounding the link text: + +```markdown +[a link](https://www.example.com/) +``` + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc-build/md040.md b/doc-build/md040.md new file mode 100644 index 00000000..7f75ffed --- /dev/null +++ b/doc-build/md040.md @@ -0,0 +1,34 @@ +This rule is triggered when fenced code blocks are used, but a language isn't +specified: + +````markdown +``` +#!/bin/bash +echo Hello world +``` +```` + +To fix this, add a language specifier to the code block: + +````markdown +```bash +#!/bin/bash +echo Hello world +``` +```` + +To display a code block without syntax highlighting, use: + +````markdown +```text +Plain text in a code block +``` +```` + +You can configure the `allowed_languages` parameter to specify a list of +languages code blocks could use. The default value is `[]` which means any +language specifier is valid. + +Rationale: Specifying a language improves content rendering by using the +correct syntax highlighting for code. More information: +. diff --git a/doc-build/md041.md b/doc-build/md041.md new file mode 100644 index 00000000..4e17856a --- /dev/null +++ b/doc-build/md041.md @@ -0,0 +1,36 @@ +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 top-level heading to the beginning of the file: + +```markdown +# File with heading + +This is a file with a top-level heading +``` + +Because it is common for projects on GitHub to use an image for the heading of +`README.md` and that is not well-supported by Markdown, HTML headings are also +permitted by this rule. For example: + +```markdown +

+ +This is a file with a top-level HTML heading +``` + +Note: The `level` parameter can be used to change the top-level (ex: to h2) in cases +where an h1 is added externally. + +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 the 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`. + +Rationale: The top-level heading often acts as the title of a document. More +information: . diff --git a/doc-build/md042.md b/doc-build/md042.md new file mode 100644 index 00000000..785bd2c0 --- /dev/null +++ b/doc-build/md042.md @@ -0,0 +1,25 @@ +This rule is triggered when an empty link is encountered: + +```markdown +[an empty link]() +``` + +To fix the violation, provide a destination for the link: + +```markdown +[a valid link](https://example.com/) +``` + +Empty fragments will trigger this rule: + +```markdown +[an empty fragment](#) +``` + +But non-empty fragments will not: + +```markdown +[a valid fragment](#fragment) +``` + +Rationale: Empty links do not lead anywhere and therefore don't function as links. diff --git a/doc-build/md043.md b/doc-build/md043.md new file mode 100644 index 00000000..eafcd738 --- /dev/null +++ b/doc-build/md043.md @@ -0,0 +1,60 @@ +> If `headings` is not provided, `headers` (deprecated) will be used. + +This rule is triggered when the headings in a file do not match the array of +headings passed to the rule. It can be used to enforce a standard heading +structure for a set of files. + +To require exactly the following structure: + +```markdown +# Head +## Item +### Detail +``` + +Set the `headings` parameter to: + +```json +[ + "# Head", + "## Item", + "### Detail" +] +``` + +To allow optional headings as with the following structure: + +```markdown +# Head +## Item +### Detail (optional) +## Foot +### Notes (optional) +``` + +Use the special value `"*"` meaning "zero or more unspecified headings" or the +special value `"+"` meaning "one or more unspecified headings" and set the +`headings` parameter to: + +```json +[ + "# Head", + "## Item", + "*", + "## Foot", + "*" +] +``` + +When an error is detected, this rule outputs the line number of the first +problematic heading (otherwise, it outputs the last line number of the file). + +Note that while the `headings` parameter uses the "## Text" ATX heading style for +simplicity, a file may use any supported heading style. + +By default, the case of headings in the document is not required to match that of +`headings`. To require that case match exactly, set the `match_case` parameter to +`true`. + +Rationale: Projects may wish to enforce a consistent document structure across +a set of similar content. diff --git a/doc-build/md044.md b/doc-build/md044.md new file mode 100644 index 00000000..ed8adc5e --- /dev/null +++ b/doc-build/md044.md @@ -0,0 +1,20 @@ +This rule is triggered when any of the strings in the `names` array do not have +the specified capitalization. It can be used to enforce a standard letter case +for the names of projects and products. + +For example, the language "JavaScript" is usually written with both the 'J' and +'S' capitalized - though sometimes the 's' or 'j' appear in lower-case. To enforce +the proper capitalization, specify the desired letter case in the `names` array: + +```json +[ + "JavaScript" +] +``` + +Set the `code_blocks` parameter to `false` to disable this rule for code blocks +and spans. Set the `html_elements` parameter to `false` to disable this rule +for HTML elements and attributes (such as when using a proper name as part of +a path for `a`/`href` or `img`/`src`). + +Rationale: Incorrect capitalization of proper names is usually a mistake. diff --git a/doc-build/md045.md b/doc-build/md045.md new file mode 100644 index 00000000..09f544fb --- /dev/null +++ b/doc-build/md045.md @@ -0,0 +1,24 @@ +This rule is triggered when an image is missing alternate text (alt text) information. + +Alternate text is commonly specified inline as: + +```markdown +![Alternate text](image.jpg) +``` + +Or with reference syntax as: + +```markdown +![Alternate text][ref] + +... + +[ref]: image.jpg "Optional title" +``` + +Guidance for writing alternate text is available from the [W3C](https://www.w3.org/WAI/alt/), +[Wikipedia](https://en.wikipedia.org/wiki/Alt_attribute), and +[other locations](https://www.phase2technology.com/blog/no-more-excuses). + +Rationale: Alternate text is important for accessibility and describes the +content of an image for people who may not be able to see it. diff --git a/doc-build/md046.md b/doc-build/md046.md new file mode 100644 index 00000000..4dd13bdf --- /dev/null +++ b/doc-build/md046.md @@ -0,0 +1,28 @@ +This rule is triggered when unwanted or different code block styles are used in +the same document. + +In the default configuration this rule reports a violation for the following document: + + + + Some text. + + # Indented code + + More text. + + ```ruby + # Fenced code + ``` + + More text. + + + +To fix violations of this rule, use a consistent style (either indenting or code +fences). + +The specified style can be specific (`fenced`, `indented`) or simply require +that usage be consistent within the document (`consistent`). + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc-build/md047.md b/doc-build/md047.md new file mode 100644 index 00000000..d2cf131a --- /dev/null +++ b/doc-build/md047.md @@ -0,0 +1,22 @@ +This rule is triggered when there is not a single newline character at the end +of a file. + +An example that triggers the rule: + +```markdown +# Heading + +This file ends without a newline.[EOF] +``` + +To fix the violation, add a newline character to the end of the file: + +```markdown +# Heading + +This file ends with a newline. +[EOF] +``` + +Rationale: Some programs have trouble with files that do not end with a newline. +More information: . diff --git a/doc-build/md048.md b/doc-build/md048.md new file mode 100644 index 00000000..6246184a --- /dev/null +++ b/doc-build/md048.md @@ -0,0 +1,30 @@ +This rule is triggered when the symbols used in the document for fenced code +blocks do not match the configured code fence style: + +````markdown +```ruby +# Fenced code +``` + +~~~ruby +# Fenced code +~~~ +```` + +To fix this issue, use the configured code fence style throughout the +document: + +````markdown +```ruby +# Fenced code +``` + +```ruby +# Fenced code +``` +```` + +The configured list style can be a specific symbol to use (backtick, tilde), or +can require that usage be consistent within the document. + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc-build/md049.md b/doc-build/md049.md new file mode 100644 index 00000000..8130da2b --- /dev/null +++ b/doc-build/md049.md @@ -0,0 +1,19 @@ +This rule is triggered when the symbols used in the document for emphasis do not +match the configured emphasis style: + +```markdown +*Text* +_Text_ +``` + +To fix this issue, use the configured emphasis style throughout the document: + +```markdown +*Text* +*Text* +``` + +The configured emphasis style can be a specific symbol to use ("asterisk", +"underscore"), or can require that usage be consistent within the document. + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc-build/md050.md b/doc-build/md050.md new file mode 100644 index 00000000..7cc5c5e6 --- /dev/null +++ b/doc-build/md050.md @@ -0,0 +1,19 @@ +This rule is triggered when the symbols used in the document for strong do not +match the configured strong style: + +```markdown +**Text** +__Text__ +``` + +To fix this issue, use the configured strong style throughout the document: + +```markdown +**Text** +**Text** +``` + +The configured strong style can be a specific symbol to use ("asterisk", +"underscore"), or can require that usage be consistent within the document. + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc-build/md051.md b/doc-build/md051.md new file mode 100644 index 00000000..59ce3b4c --- /dev/null +++ b/doc-build/md051.md @@ -0,0 +1,29 @@ +This rule is triggered when a link fragment does not correspond to a heading +in the document: + +```markdown +# Title + +[Link](#fragment) +``` + +To fix the issue, change the fragment to reference an existing heading: + +```markdown +[Link](#title) +``` + +Alternatively, an HTML `a` tag with an `id` (or a `name`) attribute defines a +valid anchor: + +```markdown + +``` + +Some platforms (e.g., [GitHub][github-section-links]) automatically create HTML +anchors for every heading. This makes it easy to link to different sections in +a document. These internal links can break over time as headings are renamed. + +Note: Creating anchors for headings is not part of the CommonMark specification. + +[github-section-links]: https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#section-links diff --git a/doc-build/md052.md b/doc-build/md052.md new file mode 100644 index 00000000..f8a2ae3f --- /dev/null +++ b/doc-build/md052.md @@ -0,0 +1,27 @@ +Links and images in Markdown can provide the link destination or image source +at the time of use or can define it elsewhere and use a label for reference. +The reference format is convenient for keeping paragraph text clutter-free +and makes it easy to reuse the same URL in multiple places. + +There are three kinds of reference links and images: + +```markdown +Full: [text][label] +Collapsed: [label][] +Shortcut: [label] + +Full: ![text][image] +Collapsed: ![image][] +Shortcut: ![image] + +[label]: https://example.com/label +[image]: https://example.com/image +``` + +A link or image renders correctly when a corresponding label is defined, but +the text displays with brackets if the label is not present. This rule warns +of undefined labels for "full" and "collapsed" reference syntax. + +> "Shortcut" syntax is ambiguous and a missing label will not generate an + error. For example, `[shortcut]` could be a shortcut link or the text + "shortcut" in brackets. diff --git a/doc-build/md053.md b/doc-build/md053.md new file mode 100644 index 00000000..bc11bcae --- /dev/null +++ b/doc-build/md053.md @@ -0,0 +1,26 @@ +Links and images in Markdown can provide the link destination or image source +at the time of use or can define it elsewhere and use a label for reference. +The reference format is convenient for keeping paragraph text clutter-free +and makes it easy to reuse the same URL in multiple places. + +Because link and image reference definitions are located separately from +where they are used, there are two scenarios where a definition can be +unnecessary: + +1. If a label is not referenced by any link or image in a document, that + definition is unused and can be deleted. +1. If a label is defined multiple times in a document, the first definition is + used and the others can be deleted. + +This rule considers a reference definition to be used if any link or image +reference has the corresponding label. The "full", "collapsed", and "shortcut" +formats are all supported. + +If there are reference definitions that are deliberately unreferenced, they can +be ignored by setting the `ignored_definitions` parameter. The default value of +this parameter ignores the following convention for adding non-HTML comments to +Markdown: + +```md +[//]: # (This behaves like a comment) +``` diff --git a/doc/Rules.md b/doc/Rules.md index 0c425c3d..4cd31b44 100644 --- a/doc/Rules.md +++ b/doc/Rules.md @@ -9,9 +9,9 @@ deprecated, but still provided for backward-compatibility. ## MD001 - Heading levels should only increment by one level at a time -Tags: headings, headers +Tags: headers, headings -Aliases: heading-increment, header-increment +Aliases: header-increment, heading-increment This rule is triggered when you skip heading levels in a Markdown document, for example: @@ -49,14 +49,18 @@ when skipped - especially for accessibility scenarios. More information: ## ~~MD002 - First heading should be a top-level heading~~ -Tags: headings, headers +> This rule is deprecated and provided for backward-compatibility -Aliases: first-heading-h1, first-header-h1 +Tags: headers, headings -Parameters: level (number; default 1) +Aliases: first-header-h1, first-heading-h1 + +Parameters: + +* `level`: Heading level (`integer`, default `1`) > Note: *MD002 has been deprecated and is disabled by default.* -> [MD041/first-line-heading](#md041) offers an improved implementation. +> [MD041/first-line-heading](md041.md) offers an improved implementation. 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: @@ -85,12 +89,13 @@ information: . ## MD003 - Heading style -Tags: headings, headers +Tags: headers, headings -Aliases: heading-style, header-style +Aliases: header-style, heading-style -Parameters: style ("consistent", "atx", "atx_closed", "setext", -"setext_with_atx", "setext_with_atx_closed"; default "consistent") +Parameters: + +* `style`: Heading style (`string`, default `consistent`, values `atx`/`atx_closed`/`consistent`/`setext`/`setext_with_atx`/`setext_with_atx_closed`) This rule is triggered when different heading styles (atx, setext, and 'closed' atx) are used in the same document: @@ -139,8 +144,9 @@ Tags: bullet, ul Aliases: ul-style -Parameters: style ("consistent", "asterisk", "plus", "dash", "sublist"; default -"consistent") +Parameters: + +* `style`: List style (`string`, default `consistent`, values `asterisk`/`consistent`/`dash`/`plus`/`sublist`) Fixable: Most violations can be fixed by tooling @@ -185,7 +191,7 @@ Rationale: Consistent formatting makes it easier to understand a document. ## MD005 - Inconsistent indentation for list items at the same level -Tags: bullet, ul, indentation +Tags: bullet, indentation, ul Aliases: list-indent @@ -241,7 +247,9 @@ Rationale: Violations of this rule can lead to improperly rendered content. ## ~~MD006 - Consider starting bulleted lists at the beginning of the line~~ -Tags: bullet, ul, indentation +> This rule is deprecated and provided for backward-compatibility + +Tags: bullet, indentation, ul Aliases: ul-start-left @@ -288,15 +296,15 @@ characters if you use 4 space tabs, or 1 character if you use 2 space tabs). ## MD007 - Unordered list indentation -Tags: bullet, ul, indentation +Tags: bullet, indentation, ul Aliases: ul-indent - +Parameters: -Parameters: indent, start_indented, start_indent (number; default 2, boolean; default false, number; defaults to indent) - - +* `indent`: Spaces for indent (`integer`, default `2`) +* `start_indent`: Spaces for first level indent (when start_indented is set) (`integer`, default `2`) +* `start_indented`: Whether to indent the first level of the list (`boolean`, default `false`) Fixable: Most violations can be fixed by tooling @@ -345,11 +353,11 @@ Tags: whitespace Aliases: no-trailing-spaces - +Parameters: -Parameters: br_spaces, list_item_empty_lines, strict (number; default 2, boolean; default false, boolean; default false) - - +* `br_spaces`: Spaces for line break (`integer`, default `2`) +* `list_item_empty_lines`: Allow spaces for empty lines in list items (`boolean`, default `false`) +* `strict`: Include unnecessary breaks (`boolean`, default `false`) Fixable: Most violations can be fixed by tooling @@ -392,11 +400,15 @@ has no purpose and does not affect the rendering of content. ## MD010 - Hard tabs -Tags: whitespace, hard_tab +Tags: hard_tab, whitespace Aliases: no-hard-tabs -Parameters: code_blocks, ignore_code_languages, spaces_per_tab (boolean; default true, array of string; default empty, number; default 1) +Parameters: + +* `code_blocks`: Include code blocks (`boolean`, default `true`) +* `ignore_code_languages`: Fenced code languages to ignore (`string[]`, default `[]`) +* `spaces_per_tab`: Number of spaces for each hard tab (`integer`, default `1`) Fixable: Most violations can be fixed by tooling @@ -479,11 +491,13 @@ Rationale: Reversed links are not rendered as usable links. ## MD012 - Multiple consecutive blank lines -Tags: whitespace, blank_lines +Tags: blank_lines, whitespace Aliases: no-multiple-blanks -Parameters: maximum (number; default 1) +Parameters: + +* `maximum`: Consecutive blank lines (`integer`, default `1`) Fixable: Most violations can be fixed by tooling @@ -522,11 +536,17 @@ Tags: line_length Aliases: line-length - +Parameters: -Parameters: line_length, heading_line_length, code_block_line_length, code_blocks, tables, headings, headers, strict, stern (number; default 80 for *_length, boolean; default true (except strict/stern which default false)) - - +* `code_block_line_length`: Number of characters for code blocks (`integer`, default `80`) +* `code_blocks`: Include code blocks (`boolean`, default `true`) +* `headers`: Include headings (`boolean`, default `true`) +* `heading_line_length`: Number of characters for headings (`integer`, default `80`) +* `headings`: Include headings (`boolean`, default `true`) +* `line_length`: Number of characters (`integer`, default `80`) +* `stern`: Stern length checking (`boolean`, default `false`) +* `strict`: Strict length checking (`boolean`, default `false`) +* `tables`: Include tables (`boolean`, default `true`) > If `headings` is not provided, `headers` (deprecated) will be used. @@ -626,7 +646,7 @@ for more information. ## MD018 - No space after hash on atx style heading -Tags: headings, headers, atx, spaces +Tags: atx, headers, headings, spaces Aliases: no-missing-space-atx @@ -656,7 +676,7 @@ Rationale: Violations of this rule can lead to improperly rendered content. ## MD019 - Multiple spaces after hash on atx style heading -Tags: headings, headers, atx, spaces +Tags: atx, headers, headings, spaces Aliases: no-multiple-space-atx @@ -687,7 +707,7 @@ content. ## MD020 - No space inside hashes on closed atx style heading -Tags: headings, headers, atx_closed, spaces +Tags: atx_closed, headers, headings, spaces Aliases: no-missing-space-closed-atx @@ -719,7 +739,7 @@ Rationale: Violations of this rule can lead to improperly rendered content. ## MD021 - Multiple spaces inside hashes on closed atx style heading -Tags: headings, headers, atx_closed, spaces +Tags: atx_closed, headers, headings, spaces Aliases: no-multiple-space-closed-atx @@ -753,11 +773,14 @@ content. ## MD022 - Headings should be surrounded by blank lines -Tags: headings, headers, blank_lines +Tags: blank_lines, headers, headings -Aliases: blanks-around-headings, blanks-around-headers +Aliases: blanks-around-headers, blanks-around-headings -Parameters: lines_above, lines_below (number; default 1) +Parameters: + +* `lines_above`: Blank lines above heading (`integer`, default `1`) +* `lines_below`: Blank lines below heading (`integer`, default `1`) Fixable: Most violations can be fixed by tooling @@ -789,7 +812,7 @@ The `lines_above` and `lines_below` parameters can be used to specify a differen number of blank lines (including 0) above or below each heading. Note: If `lines_above` or `lines_below` are configured to require more than one -blank line, [MD012/no-multiple-blanks](#md012) should also be customized. +blank line, [MD012/no-multiple-blanks](md012.md) should also be customized. Rationale: Aside from aesthetic reasons, some parsers, including `kramdown`, will not parse headings that don't have a blank line before, and will parse them as @@ -799,9 +822,9 @@ regular text. ## MD023 - Headings must start at the beginning of the line -Tags: headings, headers, spaces +Tags: headers, headings, spaces -Aliases: heading-start-left, header-start-left +Aliases: header-start-left, heading-start-left Fixable: Most violations can be fixed by tooling @@ -828,11 +851,14 @@ parsed as headings, and will instead appear as regular text. ## MD024 - Multiple headings with the same content -Tags: headings, headers +Tags: headers, headings -Aliases: no-duplicate-heading, no-duplicate-header +Aliases: no-duplicate-header, no-duplicate-heading -Parameters: siblings_only, allow_different_nesting (boolean; default `false`) +Parameters: + +* `allow_different_nesting`: Only check sibling headings (`boolean`, default `false`) +* `siblings_only`: Only check sibling headings (`boolean`, default `false`) This rule is triggered if there are multiple headings in the document that have the same text: @@ -874,11 +900,14 @@ heading name; headings with the same content can cause problems with that. ## MD025 - Multiple top-level headings in the same document -Tags: headings, headers +Tags: headers, headings -Aliases: single-title, single-h1 +Aliases: single-h1, single-title -Parameters: level, front_matter_title (number; default 1, string; default "^\s*"?title"?\s*[:=]") +Parameters: + +* `front_matter_title`: RegExp for matching title in front matter (`string`, default `^\s*title\s*[:=]`) +* `level`: Heading level (`integer`, default `1`) This rule is triggered when a top-level heading is in use (the first line of the file is an h1 heading), and more than one h1 heading is in use in the @@ -921,11 +950,13 @@ should be contained within this heading. ## MD026 - Trailing punctuation in heading -Tags: headings, headers +Tags: headers, headings Aliases: no-trailing-punctuation -Parameters: punctuation (string; default ".,;:!。,;:!") +Parameters: + +* `punctuation`: Punctuation characters not allowed at end of headings (`string`, default `.,;:!。,;:!`) Fixable: Most violations can be fixed by tooling @@ -960,7 +991,7 @@ Rationale: Headings are not meant to be full sentences. More information: ## MD027 - Multiple spaces after blockquote symbol -Tags: blockquote, whitespace, indentation +Tags: blockquote, indentation, whitespace Aliases: no-multiple-space-blockquote @@ -1034,7 +1065,9 @@ Tags: ol Aliases: ol-prefix -Parameters: style ("one", "ordered", "one_or_ordered", "zero"; default "one_or_ordered") +Parameters: + +* `style`: List style (`string`, default `one_or_ordered`, values `one`/`one_or_ordered`/`ordered`/`zero`) This rule is triggered for ordered lists that do not either start with '1.' or do not have a prefix that increases in numerical order (depending on the @@ -1132,7 +1165,12 @@ Tags: ol, ul, whitespace Aliases: list-marker-space -Parameters: ul_single, ol_single, ul_multi, ol_multi (number; default 1) +Parameters: + +* `ol_multi`: Spaces for multi-line ordered list items (`integer`, default `1`) +* `ol_single`: Spaces for single-line ordered list items (`integer`, default `1`) +* `ul_multi`: Spaces for multi-line unordered list items (`integer`, default `1`) +* `ul_single`: Spaces for single-line unordered list items (`integer`, default `1`) Fixable: Most violations can be fixed by tooling @@ -1205,11 +1243,13 @@ Note: See [Prettier.md](Prettier.md) for compatibility information. ## MD031 - Fenced code blocks should be surrounded by blank lines -Tags: code, blank_lines +Tags: blank_lines, code Aliases: blanks-around-fences -Parameters: list_items (boolean; default true) +Parameters: + +* `list_items`: Include list items (`boolean`, default `true`) Fixable: Most violations can be fixed by tooling @@ -1256,7 +1296,7 @@ not parse fenced code blocks that don't have blank lines before and after them. ## MD032 - Lists should be surrounded by blank lines -Tags: bullet, ul, ol, blank_lines +Tags: blank_lines, bullet, ol, ul Aliases: blanks-around-lists @@ -1301,7 +1341,9 @@ Tags: html Aliases: no-inline-html -Parameters: allowed_elements (array of string; default empty) +Parameters: + +* `allowed_elements`: Allowed elements (`string[]`, default `[]`) This rule is triggered whenever raw HTML is used in a Markdown document: @@ -1376,8 +1418,9 @@ Tags: hr Aliases: hr-style -Parameters: style ("consistent", "---", "***", "___", or other string specifying -the horizontal rule; default "consistent") +Parameters: + +* `style`: Horizontal rule style (`string`, default `consistent`) This rule is triggered when inconsistent styles of horizontal rules are used in the document: @@ -1416,11 +1459,13 @@ Rationale: Consistent formatting makes it easier to understand a document. ## MD036 - Emphasis used instead of a heading -Tags: headings, headers, emphasis +Tags: emphasis, headers, headings -Aliases: no-emphasis-as-heading, no-emphasis-as-header +Aliases: no-emphasis-as-header, no-emphasis-as-heading -Parameters: punctuation (string; default ".,;:!?。,;:!?") +Parameters: + +* `punctuation`: Punctuation characters (`string`, default `.,;:!?。,;:!?`) This check looks for instances where emphasized (i.e. bold or italic) text is used to separate sections, where a heading should be used instead: @@ -1462,7 +1507,7 @@ the structure of a document. More information: ## MD037 - Spaces inside emphasis markers -Tags: whitespace, emphasis +Tags: emphasis, whitespace Aliases: no-space-in-emphasis @@ -1502,7 +1547,7 @@ intended by the author. ## MD038 - Spaces inside code span elements -Tags: whitespace, code +Tags: code, whitespace Aliases: no-space-in-code @@ -1543,7 +1588,7 @@ Rationale: Violations of this rule can lead to improperly rendered content. ## MD039 - Spaces inside link text -Tags: whitespace, links +Tags: links, whitespace Aliases: no-space-in-links @@ -1571,7 +1616,9 @@ Tags: code, language Aliases: fenced-code-language -Parameters: allowed_languages (array of string; default []) +Parameters: + +* `allowed_languages`: List of languages (`string[]`, default `[]`) This rule is triggered when fenced code blocks are used, but a language isn't specified: @@ -1601,7 +1648,8 @@ Plain text in a code block ```` You can configure the `allowed_languages` parameter to specify a list of -languages code blocks could use. The default value is `[]` which means any language specifier is valid. +languages code blocks could use. The default value is `[]` which means any +language specifier is valid. Rationale: Specifying a language improves content rendering by using the correct syntax highlighting for code. More information: @@ -1611,11 +1659,14 @@ correct syntax highlighting for code. More information: ## MD041 - First line in a file should be a top-level heading -Tags: headings, headers +Tags: headers, headings -Aliases: first-line-heading, first-line-h1 +Aliases: first-line-h1, first-line-heading -Parameters: level, front_matter_title (number; default 1, string; default "^\s*"?title"?\s*[:=]") +Parameters: + +* `front_matter_title`: RegExp for matching title in front matter (`string`, default `^\s*title\s*[:=]`) +* `level`: Heading level (`integer`, default `1`) 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: @@ -1692,11 +1743,15 @@ Rationale: Empty links do not lead anywhere and therefore don't function as link ## MD043 - Required heading structure -Tags: headings, headers +Tags: headers, headings -Aliases: required-headings, required-headers +Aliases: required-headers, required-headings -Parameters: headings, headers, match_case (array of string; default `null` for disabled, boolean; default false) +Parameters: + +* `headers`: List of headings (`string[]`, default `[]`) +* `headings`: List of headings (`string[]`, default `[]`) +* `match_case`: Match case of headings (`boolean`, default `false`) > If `headings` is not provided, `headers` (deprecated) will be used. @@ -1767,7 +1822,11 @@ Tags: spelling Aliases: proper-names -Parameters: names, code_blocks, html_elements (string array; default `null`, boolean; default `true`, boolean; default `true`) +Parameters: + +* `code_blocks`: Include code blocks (`boolean`, default `true`) +* `html_elements`: Include HTML elements (`boolean`, default `true`) +* `names`: List of proper names (`string[]`, default `[]`) Fixable: Most violations can be fixed by tooling @@ -1833,7 +1892,9 @@ Tags: code Aliases: code-block-style -Parameters: style ("consistent", "fenced", "indented"; default "consistent") +Parameters: + +* `style`: Block style (`string`, default `consistent`, values `consistent`/`fenced`/`indented`) This rule is triggered when unwanted or different code block styles are used in the same document. @@ -1905,7 +1966,9 @@ Tags: code Aliases: code-fence-style -Parameters: style ("consistent", "tilde", "backtick"; default "consistent") +Parameters: + +* `style`: Code fence style (`string`, default `consistent`, values `backtick`/`consistent`/`tilde`) This rule is triggered when the symbols used in the document for fenced code blocks do not match the configured code fence style: @@ -1946,7 +2009,9 @@ Tags: emphasis Aliases: emphasis-style -Parameters: style ("consistent", "asterisk", "underscore"; default "consistent") +Parameters: + +* `style`: Emphasis style should be consistent (`string`, default `consistent`, values `asterisk`/`consistent`/`underscore`) Fixable: Most violations can be fixed by tooling @@ -1978,7 +2043,9 @@ Tags: emphasis Aliases: strong-style -Parameters: style ("consistent", "asterisk", "underscore"; default "consistent") +Parameters: + +* `style`: Strong style should be consistent (`string`, default `consistent`, values `asterisk`/`consistent`/`underscore`) Fixable: Most violations can be fixed by tooling @@ -2084,7 +2151,9 @@ Tags: images, links Aliases: link-image-reference-definitions -Parameters: ignored_definitions (array of string; default [ "//" ]) +Parameters: + +* `ignored_definitions`: Ignored definitions (`string[]`, default `["//"]`) Fixable: Most violations can be fixed by tooling diff --git a/doc/md001.md b/doc/md001.md new file mode 100644 index 00000000..12cf4b95 --- /dev/null +++ b/doc/md001.md @@ -0,0 +1,37 @@ +# MD001 - Heading levels should only increment by one level at a time + +Tags: headers, headings + +Aliases: header-increment, heading-increment + +This rule is triggered when you skip heading levels in a Markdown document, for +example: + +```markdown +# Heading 1 + +### Heading 3 + +We skipped out a 2nd level heading in this document +``` + +When using multiple heading levels, nested headings should increase by only one +level at a time: + +```markdown +# Heading 1 + +## Heading 2 + +### Heading 3 + +#### Heading 4 + +## Another Heading 2 + +### Another Heading 3 +``` + +Rationale: Headings represent the structure of a document and can be confusing +when skipped - especially for accessibility scenarios. More information: +. diff --git a/doc/md002.md b/doc/md002.md new file mode 100644 index 00000000..c9f109a5 --- /dev/null +++ b/doc/md002.md @@ -0,0 +1,37 @@ +# ~~MD002 - First heading should be a top-level heading~~ + +> This rule is deprecated and provided for backward-compatibility + +Tags: headers, headings + +Aliases: first-header-h1, first-heading-h1 + +Parameters: + +* `level`: Heading level (`integer`, default `1`) + +> Note: *MD002 has been deprecated and is disabled by default.* +> [MD041/first-line-heading](md041.md) offers an improved implementation. + +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 an H1 heading + +### Another heading +``` + +The first heading in the document should be an h1 heading: + +```markdown +# Start with an H1 heading + +## 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. + +Rationale: The top-level heading often acts as the title of a document. More +information: . diff --git a/doc/md003.md b/doc/md003.md new file mode 100644 index 00000000..49762d98 --- /dev/null +++ b/doc/md003.md @@ -0,0 +1,48 @@ +# MD003 - Heading style + +Tags: headers, headings + +Aliases: header-style, heading-style + +Parameters: + +* `style`: Heading style (`string`, default `consistent`, values `atx`/`atx_closed`/`consistent`/`setext`/`setext_with_atx`/`setext_with_atx_closed`) + +This rule is triggered when different heading styles (atx, setext, and 'closed' +atx) are used in the same document: + +```markdown +# ATX style H1 + +## Closed ATX style H2 ## + +Setext style H1 +=============== +``` + +Be consistent with the style of heading used in a document: + +```markdown +# ATX style H1 + +## ATX style H2 +``` + +The setext_with_atx and setext_with_atx_closed doc styles allow atx-style +headings of level 3 or more in documents with setext style headings: + +```markdown +Setext style H1 +=============== + +Setext style H2 +--------------- + +### ATX style H3 +``` + +Note: the configured heading style can be a specific style to use (atx, +atx_closed, setext, setext_with_atx, setext_with_atx_closed), or simply require +that the usage is consistent within the document. + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc/md004.md b/doc/md004.md new file mode 100644 index 00000000..84b3746a --- /dev/null +++ b/doc/md004.md @@ -0,0 +1,48 @@ +# MD004 - Unordered list style + +Tags: bullet, ul + +Aliases: ul-style + +Parameters: + +* `style`: List style (`string`, default `consistent`, values `asterisk`/`consistent`/`dash`/`plus`/`sublist`) + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when the symbols used in the document for unordered +list items do not match the configured unordered list style: + +```markdown +* Item 1 ++ Item 2 +- Item 3 +``` + +To fix this issue, use the configured style for list items throughout the +document: + +```markdown +* Item 1 +* Item 2 +* Item 3 +``` + +The configured list style can be a specific symbol to use (asterisk, plus, dash), +to ensure that all list styling is consistent, or to ensure that each +sublist has a consistent symbol that differs from its parent list. + +For example, the following is valid for the `sublist` style because the outer-most +indent uses asterisk, the middle indent uses plus, and the inner-most indent uses +dash: + +```markdown +* Item 1 + + Item 2 + - Item 3 + + Item 4 +* Item 4 + + Item 5 +``` + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc/md005.md b/doc/md005.md new file mode 100644 index 00000000..4b41af43 --- /dev/null +++ b/doc/md005.md @@ -0,0 +1,53 @@ +# MD005 - Inconsistent indentation for list items at the same level + +Tags: bullet, indentation, ul + +Aliases: list-indent + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when list items are parsed as being at the same level, +but don't have the same indentation: + +```markdown +* Item 1 + * Nested Item 1 + * Nested Item 2 + * A misaligned item +``` + +Usually, this rule will be triggered because of a typo. Correct the indentation +for the list to fix it: + +```markdown +* Item 1 + * Nested Item 1 + * Nested Item 2 + * Nested Item 3 +``` + +Sequentially-ordered list markers are usually left-aligned such that all items +have the same starting column: + +```markdown +... +8. Item +9. Item +10. Item +11. Item +... +``` + +This rule also supports right-alignment of list markers such that all items have +the same ending column: + +```markdown +... + 8. Item + 9. Item +10. Item +11. Item +... +``` + +Rationale: Violations of this rule can lead to improperly rendered content. diff --git a/doc/md006.md b/doc/md006.md new file mode 100644 index 00000000..7d9d5aef --- /dev/null +++ b/doc/md006.md @@ -0,0 +1,46 @@ +# ~~MD006 - Consider starting bulleted lists at the beginning of the line~~ + +> This rule is deprecated and provided for backward-compatibility + +Tags: bullet, indentation, ul + +Aliases: ul-start-left + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when top-level lists don't start at the beginning of a +line: + +```markdown +Some text + + * List item + * List item +``` + +To fix, ensure that top-level list items are not indented: + +```markdown +Some test + +* List item +* List item +``` + +Note: This rule is triggered for the following scenario because the unordered +sublist is not recognized as such by the parser. Not being nested 3 characters +as required by the outer ordered list, it creates a top-level unordered list +instead. + +```markdown +1. List item + - List item + - List item +1. List item +``` + +Rationale: Starting lists at the beginning of the line means that nested list +items can all be indented by the same amount when an editor's indent function +or the tab key is used to indent. Starting a list 1 space in means that the +indent of the first nested list is less than the indent of the second level (3 +characters if you use 4 space tabs, or 1 character if you use 2 space tabs). diff --git a/doc/md007.md b/doc/md007.md new file mode 100644 index 00000000..a8382b0c --- /dev/null +++ b/doc/md007.md @@ -0,0 +1,50 @@ +# MD007 - Unordered list indentation + +Tags: bullet, indentation, ul + +Aliases: ul-indent + +Parameters: + +* `indent`: Spaces for indent (`integer`, default `2`) +* `start_indent`: Spaces for first level indent (when start_indented is set) (`integer`, default `2`) +* `start_indented`: Whether to indent the first level of the list (`boolean`, default `false`) + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when list items are not indented by the configured +number of spaces (default: 2). + +Example: + +```markdown +* List item + * Nested list item indented by 3 spaces +``` + +Corrected Example: + +```markdown +* List item + * Nested list item indented by 2 spaces +``` + +Note: This rule applies to a sublist only if its parent lists are all also +unordered (otherwise, extra indentation of ordered lists interferes with the +rule). + +The `start_indented` parameter allows the first level of lists to be indented by +the configured number of spaces rather than starting at zero (the inverse of +MD006). The `start_indent` parameter allows the first level of lists to be indented +by a different number of spaces than the rest (ignored when `start_indented` is not +set). + +Rationale: Indenting by 2 spaces allows the content of a nested list to be in +line with the start of the content of the parent list when a single space is +used after the list marker. Indenting by 4 spaces is consistent with code blocks +and simpler for editors to implement. Additionally, this can be a compatibility +issue for other Markdown parsers, which require 4-space indents. More information: + +and . + +Note: See [Prettier.md](Prettier.md) for compatibility information. diff --git a/doc/md009.md b/doc/md009.md new file mode 100644 index 00000000..f1c8ef34 --- /dev/null +++ b/doc/md009.md @@ -0,0 +1,48 @@ +# MD009 - Trailing spaces + +Tags: whitespace + +Aliases: no-trailing-spaces + +Parameters: + +* `br_spaces`: Spaces for line break (`integer`, default `2`) +* `list_item_empty_lines`: Allow spaces for empty lines in list items (`boolean`, default `false`) +* `strict`: Include unnecessary breaks (`boolean`, default `false`) + +Fixable: Most violations can be fixed by tooling + +This rule is triggered on any lines that end with unexpected whitespace. To fix this, +remove the trailing space from the end of the line. + +Note: Trailing space is allowed in indented and fenced code blocks because some +languages require it. + +The `br_spaces` parameter allows an exception to this rule for a specific number +of trailing spaces, typically used to insert an explicit line break. The default +value allows 2 spaces to indicate a hard break (\
element). + +Note: You must set `br_spaces` to a value >= 2 for this parameter to take effect. +Setting `br_spaces` to 1 behaves the same as 0, disallowing any trailing spaces. + +By default, this rule will not trigger when the allowed number of spaces is used, +even when it doesn't create a hard break (for example, at the end of a paragraph). +To report such instances as well, set the `strict` parameter to `true`. + +```markdown +Text text text +text[2 spaces] +``` + +Using spaces to indent blank lines inside a list item is usually not necessary, +but some parsers require it. Set the `list_item_empty_lines` parameter to `true` +to allow this (even when `strict` is `true`): + +```markdown +- list item text + [2 spaces] + list item text +``` + +Rationale: Except when being used to create a line break, trailing whitespace +has no purpose and does not affect the rendering of content. diff --git a/doc/md010.md b/doc/md010.md new file mode 100644 index 00000000..7712f6a9 --- /dev/null +++ b/doc/md010.md @@ -0,0 +1,55 @@ +# MD010 - Hard tabs + +Tags: hard_tab, whitespace + +Aliases: no-hard-tabs + +Parameters: + +* `code_blocks`: Include code blocks (`boolean`, default `true`) +* `ignore_code_languages`: Fenced code languages to ignore (`string[]`, default `[]`) +* `spaces_per_tab`: Number of spaces for each hard tab (`integer`, default `1`) + +Fixable: Most violations can be fixed by tooling + +This rule is triggered by any lines that contain hard tab characters instead +of using spaces for indentation. To fix this, replace any hard tab characters +with spaces instead. + +Example: + + + +```markdown +Some text + + * hard tab character used to indent the list item +``` + + + +Corrected example: + +```markdown +Some text + + * Spaces used to indent the list item instead +``` + +You have the option to exclude this rule for code blocks and spans. To do so, +set the `code_blocks` parameter to `false`. Code blocks and spans are included +by default since handling of tabs by Markdown tools can be inconsistent (e.g., +using 4 vs. 8 spaces). + +When code blocks are scanned (e.g., by default or if `code_blocks` is `true`), +the `ignore_code_languages` parameter can be set to a list of languages that +should be ignored (i.e., hard tabs will be allowed, though not required). This +makes it easier for documents to include code for languages that require hard +tabs. + +By default, violations of this rule are fixed by replacing the tab with 1 space +character. To use a different number of spaces, set the `spaces_per_tab` +parameter to the desired value. + +Rationale: Hard tabs are often rendered inconsistently by different editors and +can be harder to work with than spaces. diff --git a/doc/md011.md b/doc/md011.md new file mode 100644 index 00000000..1572250c --- /dev/null +++ b/doc/md011.md @@ -0,0 +1,30 @@ +# MD011 - Reversed link syntax + +Tags: links + +Aliases: no-reversed-links + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when text that appears to be a link is encountered, but +where the syntax appears to have been reversed (the `[]` and `()` are +reversed): + +```markdown +(Incorrect link syntax)[https://www.example.com/] +``` + +To fix this, swap the `[]` and `()` around: + +```markdown +[Correct link syntax](https://www.example.com/) +``` + +Note: [Markdown Extra](https://en.wikipedia.org/wiki/Markdown_Extra)-style +footnotes do not trigger this rule: + +```markdown +For (example)[^1] +``` + +Rationale: Reversed links are not rendered as usable links. diff --git a/doc/md012.md b/doc/md012.md new file mode 100644 index 00000000..e8698dc0 --- /dev/null +++ b/doc/md012.md @@ -0,0 +1,38 @@ +# MD012 - Multiple consecutive blank lines + +Tags: blank_lines, whitespace + +Aliases: no-multiple-blanks + +Parameters: + +* `maximum`: Consecutive blank lines (`integer`, default `1`) + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when there are multiple consecutive blank lines in the +document: + +```markdown +Some text here + + +Some more text here +``` + +To fix this, delete the offending lines: + +```markdown +Some text here + +Some more text here +``` + +Note: this rule will not be triggered if there are multiple consecutive blank +lines inside code blocks. + +Note: The `maximum` parameter can be used to configure the maximum number of +consecutive blank lines. + +Rationale: Except in a code block, blank lines serve no purpose and do not +affect the rendering of content. diff --git a/doc/md013.md b/doc/md013.md new file mode 100644 index 00000000..bd964d39 --- /dev/null +++ b/doc/md013.md @@ -0,0 +1,54 @@ +# MD013 - Line length + +Tags: line_length + +Aliases: line-length + +Parameters: + +* `code_block_line_length`: Number of characters for code blocks (`integer`, default `80`) +* `code_blocks`: Include code blocks (`boolean`, default `true`) +* `headers`: Include headings (`boolean`, default `true`) +* `heading_line_length`: Number of characters for headings (`integer`, default `80`) +* `headings`: Include headings (`boolean`, default `true`) +* `line_length`: Number of characters (`integer`, default `80`) +* `stern`: Stern length checking (`boolean`, default `false`) +* `strict`: Strict length checking (`boolean`, default `false`) +* `tables`: Include tables (`boolean`, default `true`) + +> If `headings` is not provided, `headers` (deprecated) will be used. + +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 +up into multiple lines. To set a different maximum length for headings, use +`heading_line_length`. To set a different maximum length for code blocks, use +`code_block_line_length` + +This rule has an exception when there is no whitespace beyond the configured +line length. This allows you to still include items such as long URLs without +being forced to break them in the middle. To disable this exception, set the +`strict` parameter to `true` to report an issue when any line is too long. +To warn for lines that are too long and could be fixed but allow lines without +spaces, set the `stern` parameter to `true`. + +For example (assuming normal behavior): + +```markdown +IF THIS LINE IS THE MAXIMUM LENGTH +This line is okay because there are-no-spaces-beyond-that-length +And this line is a violation because there are +This-line-is-also-okay-because-there-are-no-spaces +``` + +In `strict` or `stern` modes, the two middle lines above are a violation. The +third line is a violation in `strict` mode but allowed in `stern` mode. + +You have the option to exclude this rule for code blocks, tables, or headings. +To do so, set the `code_blocks`, `tables`, or `headings` parameter(s) to false. + +Code blocks are included in this rule by default since it is often a +requirement for document readability, and tentatively compatible with code +rules. Still, some languages do not lend themselves to short lines. + +Rationale: Extremely long lines can be difficult to work with in some editors. +More information: . diff --git a/doc/md014.md b/doc/md014.md new file mode 100644 index 00000000..cfe999a2 --- /dev/null +++ b/doc/md014.md @@ -0,0 +1,54 @@ +# MD014 - Dollar signs used before commands without showing output + +Tags: code + +Aliases: commands-show-output + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when there are code blocks showing shell commands to be +typed, and *all* of the shell commands are preceded by dollar signs ($): + + + +```markdown +$ ls +$ cat foo +$ less bar +``` + + + +The dollar signs are unnecessary in this situation, and should not be +included: + +```markdown +ls +cat foo +less bar +``` + +Showing output for commands preceded by dollar signs does not trigger this rule: + +```markdown +$ ls +foo bar +$ cat foo +Hello world +$ cat bar +baz +``` + +Because some commands do not produce output, it is not a violation if *some* +commands do not have output: + +```markdown +$ mkdir test +mkdir: created directory 'test' +$ ls test +``` + +Rationale: It is easier to copy/paste and less noisy if the dollar signs +are omitted when they are not needed. See + +for more information. diff --git a/doc/md018.md b/doc/md018.md new file mode 100644 index 00000000..efdc5c85 --- /dev/null +++ b/doc/md018.md @@ -0,0 +1,27 @@ +# MD018 - No space after hash on atx style heading + +Tags: atx, headers, headings, spaces + +Aliases: no-missing-space-atx + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when spaces are missing after the hash characters +in an atx style heading: + +```markdown +#Heading 1 + +##Heading 2 +``` + +To fix this, separate the heading text from the hash character by a single +space: + +```markdown +# Heading 1 + +## Heading 2 +``` + +Rationale: Violations of this rule can lead to improperly rendered content. diff --git a/doc/md019.md b/doc/md019.md new file mode 100644 index 00000000..7b454d86 --- /dev/null +++ b/doc/md019.md @@ -0,0 +1,28 @@ +# MD019 - Multiple spaces after hash on atx style heading + +Tags: atx, headers, headings, spaces + +Aliases: no-multiple-space-atx + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when more than one space is used to separate the +heading text from the hash characters in an atx style heading: + +```markdown +# Heading 1 + +## Heading 2 +``` + +To fix this, separate the heading text from the hash character by a single +space: + +```markdown +# Heading 1 + +## Heading 2 +``` + +Rationale: Extra space has no purpose and does not affect the rendering of +content. diff --git a/doc/md020.md b/doc/md020.md new file mode 100644 index 00000000..4080167a --- /dev/null +++ b/doc/md020.md @@ -0,0 +1,29 @@ +# MD020 - No space inside hashes on closed atx style heading + +Tags: atx_closed, headers, headings, spaces + +Aliases: no-missing-space-closed-atx + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when spaces are missing inside the hash characters +in a closed atx style heading: + +```markdown +#Heading 1# + +##Heading 2## +``` + +To fix this, separate the heading text from the hash character by a single +space: + +```markdown +# Heading 1 # + +## Heading 2 ## +``` + +Note: this rule will fire if either side of the heading is missing spaces. + +Rationale: Violations of this rule can lead to improperly rendered content. diff --git a/doc/md021.md b/doc/md021.md new file mode 100644 index 00000000..dbbaa4df --- /dev/null +++ b/doc/md021.md @@ -0,0 +1,31 @@ +# MD021 - Multiple spaces inside hashes on closed atx style heading + +Tags: atx_closed, headers, headings, spaces + +Aliases: no-multiple-space-closed-atx + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when more than one space is used to separate the +heading text from the hash characters in a closed atx style heading: + +```markdown +# Heading 1 # + +## Heading 2 ## +``` + +To fix this, separate the heading text from the hash character by a single +space: + +```markdown +# Heading 1 # + +## Heading 2 ## +``` + +Note: this rule will fire if either side of the heading contains multiple +spaces. + +Rationale: Extra space has no purpose and does not affect the rendering of +content. diff --git a/doc/md022.md b/doc/md022.md new file mode 100644 index 00000000..2779a2a0 --- /dev/null +++ b/doc/md022.md @@ -0,0 +1,46 @@ +# MD022 - Headings should be surrounded by blank lines + +Tags: blank_lines, headers, headings + +Aliases: blanks-around-headers, blanks-around-headings + +Parameters: + +* `lines_above`: Blank lines above heading (`integer`, default `1`) +* `lines_below`: Blank lines below heading (`integer`, default `1`) + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when headings (any style) are either not preceded or not +followed by at least one blank line: + +```markdown +# Heading 1 +Some text + +Some more text +## Heading 2 +``` + +To fix this, ensure that all headings have a blank line both before and after +(except where the heading is at the beginning or end of the document): + +```markdown +# Heading 1 + +Some text + +Some more text + +## Heading 2 +``` + +The `lines_above` and `lines_below` parameters can be used to specify a different +number of blank lines (including 0) above or below each heading. + +Note: If `lines_above` or `lines_below` are configured to require more than one +blank line, [MD012/no-multiple-blanks](md012.md) should also be customized. + +Rationale: Aside from aesthetic reasons, some parsers, including `kramdown`, will +not parse headings that don't have a blank line before, and will parse them as +regular text. diff --git a/doc/md023.md b/doc/md023.md new file mode 100644 index 00000000..e5885c2b --- /dev/null +++ b/doc/md023.md @@ -0,0 +1,26 @@ +# MD023 - Headings must start at the beginning of the line + +Tags: headers, headings, spaces + +Aliases: header-start-left, heading-start-left + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when a heading is indented by one or more spaces: + +```markdown +Some text + + # Indented heading +``` + +To fix this, ensure that all headings start at the beginning of the line: + +```markdown +Some text + +# Heading +``` + +Rationale: Headings that don't start at the beginning of the line will not be +parsed as headings, and will instead appear as regular text. diff --git a/doc/md024.md b/doc/md024.md new file mode 100644 index 00000000..fa821b86 --- /dev/null +++ b/doc/md024.md @@ -0,0 +1,46 @@ +# MD024 - Multiple headings with the same content + +Tags: headers, headings + +Aliases: no-duplicate-header, no-duplicate-heading + +Parameters: + +* `allow_different_nesting`: Only check sibling headings (`boolean`, default `false`) +* `siblings_only`: Only check sibling headings (`boolean`, default `false`) + +This rule is triggered if there are multiple headings in the document that have +the same text: + +```markdown +# Some text + +## Some text +``` + +To fix this, ensure that the content of each heading is different: + +```markdown +# Some text + +## Some more text +``` + +If the parameter `siblings_only` (alternatively `allow_different_nesting`) is +set to `true`, heading duplication is allowed for non-sibling headings (common +in changelogs): + +```markdown +# Change log + +## 1.0.0 + +### Features + +## 2.0.0 + +### Features +``` + +Rationale: Some Markdown parsers generate anchors for headings based on the +heading name; headings with the same content can cause problems with that. diff --git a/doc/md025.md b/doc/md025.md new file mode 100644 index 00000000..24dd5ff5 --- /dev/null +++ b/doc/md025.md @@ -0,0 +1,47 @@ +# MD025 - Multiple top-level headings in the same document + +Tags: headers, headings + +Aliases: single-h1, single-title + +Parameters: + +* `front_matter_title`: RegExp for matching title in front matter (`string`, default `^\s*title\s*[:=]`) +* `level`: Heading level (`integer`, default `1`) + +This rule is triggered when a top-level heading is in use (the first line of +the file is an h1 heading), and more than one h1 heading is in use in the +document: + +```markdown +# Top level heading + +# Another top-level heading +``` + +To fix, structure your document so there is a single h1 heading that is +the title for the document. Subsequent headings must be +lower-level headings (h2, h3, etc.): + +```markdown +# Title + +## Heading + +## Another heading +``` + +Note: The `level` parameter can be used to change the top-level (ex: to h2) in +cases where an h1 is added externally. + +If [YAML](https://en.wikipedia.org/wiki/YAML) front matter is present and contains +a `title` property (commonly used with blog posts), this rule treats that as a top +level heading and will report a violation for any subsequent top-level headings. +To use a different property name in the 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`. + +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. diff --git a/doc/md026.md b/doc/md026.md new file mode 100644 index 00000000..d5188fc9 --- /dev/null +++ b/doc/md026.md @@ -0,0 +1,38 @@ +# MD026 - Trailing punctuation in heading + +Tags: headers, headings + +Aliases: no-trailing-punctuation + +Parameters: + +* `punctuation`: Punctuation characters not allowed at end of headings (`string`, default `.,;:!。,;:!`) + +Fixable: Most violations can be fixed by tooling + +This rule is triggered on any heading that has one of the specified normal or +full-width punctuation characters as the last character in the line: + +```markdown +# This is a heading. +``` + +To fix this, remove the trailing punctuation: + +```markdown +# This is a heading +``` + +Note: The `punctuation` parameter can be used to specify what characters count +as punctuation at the end of a heading. For example, you can change it to +`".,;:"` to allow headings that end with an exclamation point. `?` is +allowed by default because of how common it is in headings of FAQ-style documents. +Setting the `punctuation` parameter to `""` allows all characters - and is +equivalent to disabling the rule. + +Note: The trailing semicolon of +[HTML entity references](https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references) +like `©`, `©`, and `©` is ignored by this rule. + +Rationale: Headings are not meant to be full sentences. More information: + diff --git a/doc/md027.md b/doc/md027.md new file mode 100644 index 00000000..4d5a8105 --- /dev/null +++ b/doc/md027.md @@ -0,0 +1,24 @@ +# MD027 - Multiple spaces after blockquote symbol + +Tags: blockquote, indentation, whitespace + +Aliases: no-multiple-space-blockquote + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when blockquotes have more than one space after the +blockquote (`>`) symbol: + +```markdown +> This is a blockquote with bad indentation +> there should only be one. +``` + +To fix, remove any extraneous space: + +```markdown +> This is a blockquote with correct +> indentation. +``` + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc/md028.md b/doc/md028.md new file mode 100644 index 00000000..4bba169c --- /dev/null +++ b/doc/md028.md @@ -0,0 +1,40 @@ +# MD028 - Blank line inside blockquote + +Tags: blockquote, whitespace + +Aliases: no-blanks-blockquote + +This rule is triggered when two blockquote blocks are separated by nothing +except for a blank line: + +```markdown +> This is a blockquote +> which is immediately followed by + +> this blockquote. Unfortunately +> In some parsers, these are treated as the same blockquote. +``` + +To fix this, ensure that any blockquotes that are right next to each other +have some text in between: + +```markdown +> This is a blockquote. + +And Jimmy also said: + +> This too is a blockquote. +``` + +Alternatively, if they are supposed to be the same quote, then add the +blockquote symbol at the beginning of the blank line: + +```markdown +> This is a blockquote. +> +> This is the same blockquote. +``` + +Rationale: Some Markdown parsers will treat two blockquotes separated by one +or more blank lines as the same blockquote, while others will treat them as +separate blockquotes. diff --git a/doc/md029.md b/doc/md029.md new file mode 100644 index 00000000..c30c6462 --- /dev/null +++ b/doc/md029.md @@ -0,0 +1,97 @@ +# MD029 - Ordered list item prefix + +Tags: ol + +Aliases: ol-prefix + +Parameters: + +* `style`: List style (`string`, default `one_or_ordered`, values `one`/`one_or_ordered`/`ordered`/`zero`) + +This rule is triggered for ordered lists that do not either start with '1.' or +do not have a prefix that increases in numerical order (depending on the +configured style). The less-common pattern of using '0.' as a first prefix or +for all prefixes is also supported. + +Example valid list if the style is configured as 'one': + +```markdown +1. Do this. +1. Do that. +1. Done. +``` + +Examples of valid lists if the style is configured as 'ordered': + +```markdown +1. Do this. +2. Do that. +3. Done. +``` + +```markdown +0. Do this. +1. Do that. +2. Done. +``` + +All three examples are valid when the style is configured as 'one_or_ordered'. + +Example valid list if the style is configured as 'zero': + +```markdown +0. Do this. +0. Do that. +0. Done. +``` + +Example invalid list for all styles: + +```markdown +1. Do this. +3. Done. +``` + +This rule supports 0-prefixing ordered list items for uniform indentation: + +```markdown +... +08. Item +09. Item +10. Item +11. Item +... +``` + +Note: This rule will report violations for cases like the following where an +improperly-indented code block (or similar) appears between two list items and +"breaks" the list in two: + + + +~~~markdown +1. First list + +```text +Code block +``` + +1. Second list +~~~ + +The fix is to indent the code block so it becomes part of the preceding list +item as intended: + +~~~markdown +1. First list + + ```text + Code block + ``` + +2. Still first list +~~~ + + + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc/md030.md b/doc/md030.md new file mode 100644 index 00000000..d3a022ed --- /dev/null +++ b/doc/md030.md @@ -0,0 +1,79 @@ +# MD030 - Spaces after list markers + +Tags: ol, ul, whitespace + +Aliases: list-marker-space + +Parameters: + +* `ol_multi`: Spaces for multi-line ordered list items (`integer`, default `1`) +* `ol_single`: Spaces for single-line ordered list items (`integer`, default `1`) +* `ul_multi`: Spaces for multi-line unordered list items (`integer`, default `1`) +* `ul_single`: Spaces for single-line unordered list items (`integer`, default `1`) + +Fixable: Most violations can be fixed by tooling + +This rule checks for the number of spaces between a list marker (e.g. '`-`', +'`*`', '`+`' or '`1.`') and the text of the list item. + +The number of spaces checked for depends on the document style in use, but the +default is 1 space after any list marker: + +```markdown +* Foo +* Bar +* Baz + +1. Foo +1. Bar +1. Baz + +1. Foo + * Bar +1. Baz +``` + +A document style may change the number of spaces after unordered list items +and ordered list items independently, as well as based on whether the content +of every item in the list consists of a single paragraph or multiple +paragraphs (including sub-lists and code blocks). + +For example, the style guide at + +specifies that 1 space after the list marker should be used if every item in +the list fits within a single paragraph, but to use 2 or 3 spaces (for ordered +and unordered lists respectively) if there are multiple paragraphs of content +inside the list: + +```markdown +* Foo +* Bar +* Baz +``` + +vs. + +```markdown +* Foo + + Second paragraph + +* Bar +``` + +or + +```markdown +1. Foo + + Second paragraph + +1. Bar +``` + +To fix this, ensure the correct number of spaces are used after the list marker +for your selected document style. + +Rationale: Violations of this rule can lead to improperly rendered content. + +Note: See [Prettier.md](Prettier.md) for compatibility information. diff --git a/doc/md031.md b/doc/md031.md new file mode 100644 index 00000000..0f215f2b --- /dev/null +++ b/doc/md031.md @@ -0,0 +1,50 @@ +# MD031 - Fenced code blocks should be surrounded by blank lines + +Tags: blank_lines, code + +Aliases: blanks-around-fences + +Parameters: + +* `list_items`: Include list items (`boolean`, default `true`) + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when fenced code blocks are either not preceded or not +followed by a blank line: + +````markdown +Some text +``` +Code block +``` + +``` +Another code block +``` +Some more text +```` + +To fix this, ensure that all fenced code blocks have a blank line both before +and after (except where the block is at the beginning or end of the document): + +````markdown +Some text + +``` +Code block +``` + +``` +Another code block +``` + +Some more text +```` + +Set the `list_items` parameter to `false` to disable this rule for list items. +Disabling this behavior for lists can be useful if it is necessary to create a +[tight](https://spec.commonmark.org/0.29/#tight) list containing a code fence. + +Rationale: Aside from aesthetic reasons, some parsers, including kramdown, will +not parse fenced code blocks that don't have blank lines before and after them. diff --git a/doc/md032.md b/doc/md032.md new file mode 100644 index 00000000..2f424886 --- /dev/null +++ b/doc/md032.md @@ -0,0 +1,38 @@ +# MD032 - Lists should be surrounded by blank lines + +Tags: blank_lines, bullet, ol, ul + +Aliases: blanks-around-lists + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when lists (of any kind) are either not preceded or not +followed by a blank line: + +```markdown +Some text +* Some +* List + +1. Some +2. List +Some text +``` + +To fix this, ensure that all lists have a blank line both before and after +(except where the block is at the beginning or end of the document): + +```markdown +Some text + +* Some +* List + +1. Some +2. List + +Some text +``` + +Rationale: Aside from aesthetic reasons, some parsers, including kramdown, will +not parse lists that don't have blank lines before and after them. diff --git a/doc/md033.md b/doc/md033.md new file mode 100644 index 00000000..82fbefe5 --- /dev/null +++ b/doc/md033.md @@ -0,0 +1,27 @@ +# MD033 - Inline HTML + +Tags: html + +Aliases: no-inline-html + +Parameters: + +* `allowed_elements`: Allowed elements (`string[]`, default `[]`) + +This rule is triggered whenever raw HTML is used in a Markdown document: + +```markdown +

Inline HTML heading

+``` + +To fix this, use 'pure' Markdown instead of including raw HTML: + +```markdown +# Markdown heading +``` + +Note: To allow specific HTML elements, use the `allowed_elements` parameter. + +Rationale: Raw HTML is allowed in Markdown, but this rule is included for +those who want their documents to only include "pure" Markdown, or for those +who are rendering Markdown documents into something other than HTML. diff --git a/doc/md034.md b/doc/md034.md new file mode 100644 index 00000000..446f27ed --- /dev/null +++ b/doc/md034.md @@ -0,0 +1,44 @@ +# MD034 - Bare URL used + +Tags: links, url + +Aliases: no-bare-urls + +Fixable: Most violations can be fixed by tooling + +This rule is triggered whenever a URL is given that isn't surrounded by angle +brackets: + +```markdown +For more information, see https://www.example.com/. +``` + +To fix this, add angle brackets around the URL: + +```markdown +For more information, see . +``` + +Note: To use a bare URL without it being converted into a link, enclose it in +a code block, otherwise in some Markdown parsers it *will* be converted: + +```markdown +`https://www.example.com` +``` + +Note: The following scenario does *not* trigger this rule to avoid conflicts +with `MD011`/`no-reversed-links`: + +```markdown +[https://www.example.com] +``` + +The use of quotes around a bare link will *not* trigger this rule, either: + +```markdown +"https://www.example.com" +'https://www.example.com' +``` + +Rationale: Without angle brackets, the URL isn't converted into a link by many +Markdown parsers. diff --git a/doc/md035.md b/doc/md035.md new file mode 100644 index 00000000..64dae8f6 --- /dev/null +++ b/doc/md035.md @@ -0,0 +1,42 @@ +# MD035 - Horizontal rule style + +Tags: hr + +Aliases: hr-style + +Parameters: + +* `style`: Horizontal rule style (`string`, default `consistent`) + +This rule is triggered when inconsistent styles of horizontal rules are used +in the document: + +```markdown +--- + +- - - + +*** + +* * * + +**** +``` + +To fix this, ensure any horizontal rules used in the document are consistent, +or match the given style if the rule is so configured: + +```markdown +--- + +--- +``` + +Note: by default, this rule is configured to just require that all horizontal +rules in the document are the same and will trigger if any of the horizontal +rules are different than the first one encountered in the document. If you +want to configure the rule to match a specific style, the parameter given to +the 'style' option is a string containing the exact horizontal rule text that +is allowed. + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc/md036.md b/doc/md036.md new file mode 100644 index 00000000..7602315e --- /dev/null +++ b/doc/md036.md @@ -0,0 +1,45 @@ +# MD036 - Emphasis used instead of a heading + +Tags: emphasis, headers, headings + +Aliases: no-emphasis-as-header, no-emphasis-as-heading + +Parameters: + +* `punctuation`: Punctuation characters (`string`, default `.,;:!?。,;:!?`) + +This check looks for instances where emphasized (i.e. bold or italic) text is +used to separate sections, where a heading should be used instead: + +```markdown +**My document** + +Lorem ipsum dolor sit amet... + +_Another section_ + +Consectetur adipiscing elit, sed do eiusmod. +``` + +To fix this, use Markdown headings instead of emphasized text to denote +sections: + +```markdown +# My document + +Lorem ipsum dolor sit amet... + +## Another section + +Consectetur adipiscing elit, sed do eiusmod. +``` + +Note: This rule looks for single-line paragraphs that consist entirely +of emphasized text. It won't fire on emphasis used within regular text, +multi-line emphasized paragraphs, or paragraphs ending in punctuation +(normal or full-width). Similarly to rule MD026, you can configure what +characters are recognized as punctuation. + +Rationale: Using emphasis instead of a heading prevents tools from inferring +the structure of a document. More information: +. diff --git a/doc/md037.md b/doc/md037.md new file mode 100644 index 00000000..06900ac2 --- /dev/null +++ b/doc/md037.md @@ -0,0 +1,37 @@ +# MD037 - Spaces inside emphasis markers + +Tags: emphasis, whitespace + +Aliases: no-space-in-emphasis + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when emphasis markers (bold, italic) are used, but they +have spaces between the markers and the text: + +```markdown +Here is some ** bold ** text. + +Here is some * italic * text. + +Here is some more __ bold __ text. + +Here is some more _ italic _ text. +``` + +To fix this, remove the spaces around the emphasis markers: + +```markdown +Here is some **bold** text. + +Here is some *italic* text. + +Here is some more __bold__ text. + +Here is some more _italic_ text. +``` + +Rationale: Emphasis is only parsed as such when the asterisks/underscores +aren't surrounded by spaces. This rule attempts to detect where +they were surrounded by spaces, but it appears that emphasized text was +intended by the author. diff --git a/doc/md038.md b/doc/md038.md new file mode 100644 index 00000000..3c1fdf1a --- /dev/null +++ b/doc/md038.md @@ -0,0 +1,38 @@ +# MD038 - Spaces inside code span elements + +Tags: code, whitespace + +Aliases: no-space-in-code + +Fixable: Most violations can be fixed by tooling + +This rule is triggered for code span elements that have spaces adjacent to the +backticks: + +```markdown +`some text ` + +` some text` +``` + +To fix this, remove any spaces adjacent to the backticks: + +```markdown +`some text` +``` + +Note: A single leading and trailing space is allowed by the specification and +automatically trimmed (to allow for embedded backticks): + +```markdown +`` `backticks` `` +``` + +Note: A single leading or trailing space is allowed if used to separate code span +markers from an embedded backtick: + +```markdown +`` ` embedded backtick`` +``` + +Rationale: Violations of this rule can lead to improperly rendered content. diff --git a/doc/md039.md b/doc/md039.md new file mode 100644 index 00000000..f95dbf36 --- /dev/null +++ b/doc/md039.md @@ -0,0 +1,21 @@ +# MD039 - Spaces inside link text + +Tags: links, whitespace + +Aliases: no-space-in-links + +Fixable: Most violations can be fixed by tooling + +This rule is triggered on links that have spaces surrounding the link text: + +```markdown +[ a link ](https://www.example.com/) +``` + +To fix this, remove the spaces surrounding the link text: + +```markdown +[a link](https://www.example.com/) +``` + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc/md040.md b/doc/md040.md new file mode 100644 index 00000000..be1676c8 --- /dev/null +++ b/doc/md040.md @@ -0,0 +1,44 @@ +# MD040 - Fenced code blocks should have a language specified + +Tags: code, language + +Aliases: fenced-code-language + +Parameters: + +* `allowed_languages`: List of languages (`string[]`, default `[]`) + +This rule is triggered when fenced code blocks are used, but a language isn't +specified: + +````markdown +``` +#!/bin/bash +echo Hello world +``` +```` + +To fix this, add a language specifier to the code block: + +````markdown +```bash +#!/bin/bash +echo Hello world +``` +```` + +To display a code block without syntax highlighting, use: + +````markdown +```text +Plain text in a code block +``` +```` + +You can configure the `allowed_languages` parameter to specify a list of +languages code blocks could use. The default value is `[]` which means any +language specifier is valid. + +Rationale: Specifying a language improves content rendering by using the +correct syntax highlighting for code. More information: +. diff --git a/doc/md041.md b/doc/md041.md new file mode 100644 index 00000000..cfcc84fe --- /dev/null +++ b/doc/md041.md @@ -0,0 +1,47 @@ +# MD041 - First line in a file should be a top-level heading + +Tags: headers, headings + +Aliases: first-line-h1, first-line-heading + +Parameters: + +* `front_matter_title`: RegExp for matching title in front matter (`string`, default `^\s*title\s*[:=]`) +* `level`: Heading level (`integer`, default `1`) + +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 top-level heading to the beginning of the file: + +```markdown +# File with heading + +This is a file with a top-level heading +``` + +Because it is common for projects on GitHub to use an image for the heading of +`README.md` and that is not well-supported by Markdown, HTML headings are also +permitted by this rule. For example: + +```markdown +

+ +This is a file with a top-level HTML heading +``` + +Note: The `level` parameter can be used to change the top-level (ex: to h2) in cases +where an h1 is added externally. + +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 the 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`. + +Rationale: The top-level heading often acts as the title of a document. More +information: . diff --git a/doc/md042.md b/doc/md042.md new file mode 100644 index 00000000..6f5e2100 --- /dev/null +++ b/doc/md042.md @@ -0,0 +1,31 @@ +# MD042 - No empty links + +Tags: links + +Aliases: no-empty-links + +This rule is triggered when an empty link is encountered: + +```markdown +[an empty link]() +``` + +To fix the violation, provide a destination for the link: + +```markdown +[a valid link](https://example.com/) +``` + +Empty fragments will trigger this rule: + +```markdown +[an empty fragment](#) +``` + +But non-empty fragments will not: + +```markdown +[a valid fragment](#fragment) +``` + +Rationale: Empty links do not lead anywhere and therefore don't function as links. diff --git a/doc/md043.md b/doc/md043.md new file mode 100644 index 00000000..51e260f2 --- /dev/null +++ b/doc/md043.md @@ -0,0 +1,72 @@ +# MD043 - Required heading structure + +Tags: headers, headings + +Aliases: required-headers, required-headings + +Parameters: + +* `headers`: List of headings (`string[]`, default `[]`) +* `headings`: List of headings (`string[]`, default `[]`) +* `match_case`: Match case of headings (`boolean`, default `false`) + +> If `headings` is not provided, `headers` (deprecated) will be used. + +This rule is triggered when the headings in a file do not match the array of +headings passed to the rule. It can be used to enforce a standard heading +structure for a set of files. + +To require exactly the following structure: + +```markdown +# Head +## Item +### Detail +``` + +Set the `headings` parameter to: + +```json +[ + "# Head", + "## Item", + "### Detail" +] +``` + +To allow optional headings as with the following structure: + +```markdown +# Head +## Item +### Detail (optional) +## Foot +### Notes (optional) +``` + +Use the special value `"*"` meaning "zero or more unspecified headings" or the +special value `"+"` meaning "one or more unspecified headings" and set the +`headings` parameter to: + +```json +[ + "# Head", + "## Item", + "*", + "## Foot", + "*" +] +``` + +When an error is detected, this rule outputs the line number of the first +problematic heading (otherwise, it outputs the last line number of the file). + +Note that while the `headings` parameter uses the "## Text" ATX heading style for +simplicity, a file may use any supported heading style. + +By default, the case of headings in the document is not required to match that of +`headings`. To require that case match exactly, set the `match_case` parameter to +`true`. + +Rationale: Projects may wish to enforce a consistent document structure across +a set of similar content. diff --git a/doc/md044.md b/doc/md044.md new file mode 100644 index 00000000..24c99ac7 --- /dev/null +++ b/doc/md044.md @@ -0,0 +1,34 @@ +# MD044 - Proper names should have the correct capitalization + +Tags: spelling + +Aliases: proper-names + +Parameters: + +* `code_blocks`: Include code blocks (`boolean`, default `true`) +* `html_elements`: Include HTML elements (`boolean`, default `true`) +* `names`: List of proper names (`string[]`, default `[]`) + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when any of the strings in the `names` array do not have +the specified capitalization. It can be used to enforce a standard letter case +for the names of projects and products. + +For example, the language "JavaScript" is usually written with both the 'J' and +'S' capitalized - though sometimes the 's' or 'j' appear in lower-case. To enforce +the proper capitalization, specify the desired letter case in the `names` array: + +```json +[ + "JavaScript" +] +``` + +Set the `code_blocks` parameter to `false` to disable this rule for code blocks +and spans. Set the `html_elements` parameter to `false` to disable this rule +for HTML elements and attributes (such as when using a proper name as part of +a path for `a`/`href` or `img`/`src`). + +Rationale: Incorrect capitalization of proper names is usually a mistake. diff --git a/doc/md045.md b/doc/md045.md new file mode 100644 index 00000000..0f7c82f3 --- /dev/null +++ b/doc/md045.md @@ -0,0 +1,30 @@ +# MD045 - Images should have alternate text (alt text) + +Tags: accessibility, images + +Aliases: no-alt-text + +This rule is triggered when an image is missing alternate text (alt text) information. + +Alternate text is commonly specified inline as: + +```markdown +![Alternate text](image.jpg) +``` + +Or with reference syntax as: + +```markdown +![Alternate text][ref] + +... + +[ref]: image.jpg "Optional title" +``` + +Guidance for writing alternate text is available from the [W3C](https://www.w3.org/WAI/alt/), +[Wikipedia](https://en.wikipedia.org/wiki/Alt_attribute), and +[other locations](https://www.phase2technology.com/blog/no-more-excuses). + +Rationale: Alternate text is important for accessibility and describes the +content of an image for people who may not be able to see it. diff --git a/doc/md046.md b/doc/md046.md new file mode 100644 index 00000000..85ed43ce --- /dev/null +++ b/doc/md046.md @@ -0,0 +1,38 @@ +# MD046 - Code block style + +Tags: code + +Aliases: code-block-style + +Parameters: + +* `style`: Block style (`string`, default `consistent`, values `consistent`/`fenced`/`indented`) + +This rule is triggered when unwanted or different code block styles are used in +the same document. + +In the default configuration this rule reports a violation for the following document: + + + + Some text. + + # Indented code + + More text. + + ```ruby + # Fenced code + ``` + + More text. + + + +To fix violations of this rule, use a consistent style (either indenting or code +fences). + +The specified style can be specific (`fenced`, `indented`) or simply require +that usage be consistent within the document (`consistent`). + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc/md047.md b/doc/md047.md new file mode 100644 index 00000000..3f4ddefa --- /dev/null +++ b/doc/md047.md @@ -0,0 +1,30 @@ +# MD047 - Files should end with a single newline character + +Tags: blank_lines + +Aliases: single-trailing-newline + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when there is not a single newline character at the end +of a file. + +An example that triggers the rule: + +```markdown +# Heading + +This file ends without a newline.[EOF] +``` + +To fix the violation, add a newline character to the end of the file: + +```markdown +# Heading + +This file ends with a newline. +[EOF] +``` + +Rationale: Some programs have trouble with files that do not end with a newline. +More information: . diff --git a/doc/md048.md b/doc/md048.md new file mode 100644 index 00000000..148292c1 --- /dev/null +++ b/doc/md048.md @@ -0,0 +1,40 @@ +# MD048 - Code fence style + +Tags: code + +Aliases: code-fence-style + +Parameters: + +* `style`: Code fence style (`string`, default `consistent`, values `backtick`/`consistent`/`tilde`) + +This rule is triggered when the symbols used in the document for fenced code +blocks do not match the configured code fence style: + +````markdown +```ruby +# Fenced code +``` + +~~~ruby +# Fenced code +~~~ +```` + +To fix this issue, use the configured code fence style throughout the +document: + +````markdown +```ruby +# Fenced code +``` + +```ruby +# Fenced code +``` +```` + +The configured list style can be a specific symbol to use (backtick, tilde), or +can require that usage be consistent within the document. + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc/md049.md b/doc/md049.md new file mode 100644 index 00000000..289cb410 --- /dev/null +++ b/doc/md049.md @@ -0,0 +1,31 @@ +# MD049 - Emphasis style should be consistent + +Tags: emphasis + +Aliases: emphasis-style + +Parameters: + +* `style`: Emphasis style should be consistent (`string`, default `consistent`, values `asterisk`/`consistent`/`underscore`) + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when the symbols used in the document for emphasis do not +match the configured emphasis style: + +```markdown +*Text* +_Text_ +``` + +To fix this issue, use the configured emphasis style throughout the document: + +```markdown +*Text* +*Text* +``` + +The configured emphasis style can be a specific symbol to use ("asterisk", +"underscore"), or can require that usage be consistent within the document. + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc/md050.md b/doc/md050.md new file mode 100644 index 00000000..f61993ee --- /dev/null +++ b/doc/md050.md @@ -0,0 +1,31 @@ +# MD050 - Strong style should be consistent + +Tags: emphasis + +Aliases: strong-style + +Parameters: + +* `style`: Strong style should be consistent (`string`, default `consistent`, values `asterisk`/`consistent`/`underscore`) + +Fixable: Most violations can be fixed by tooling + +This rule is triggered when the symbols used in the document for strong do not +match the configured strong style: + +```markdown +**Text** +__Text__ +``` + +To fix this issue, use the configured strong style throughout the document: + +```markdown +**Text** +**Text** +``` + +The configured strong style can be a specific symbol to use ("asterisk", +"underscore"), or can require that usage be consistent within the document. + +Rationale: Consistent formatting makes it easier to understand a document. diff --git a/doc/md051.md b/doc/md051.md new file mode 100644 index 00000000..18df2112 --- /dev/null +++ b/doc/md051.md @@ -0,0 +1,35 @@ +# MD051 - Link fragments should be valid + +Tags: links + +Aliases: link-fragments + +This rule is triggered when a link fragment does not correspond to a heading +in the document: + +```markdown +# Title + +[Link](#fragment) +``` + +To fix the issue, change the fragment to reference an existing heading: + +```markdown +[Link](#title) +``` + +Alternatively, an HTML `a` tag with an `id` (or a `name`) attribute defines a +valid anchor: + +```markdown + +``` + +Some platforms (e.g., [GitHub][github-section-links]) automatically create HTML +anchors for every heading. This makes it easy to link to different sections in +a document. These internal links can break over time as headings are renamed. + +Note: Creating anchors for headings is not part of the CommonMark specification. + +[github-section-links]: https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#section-links diff --git a/doc/md052.md b/doc/md052.md new file mode 100644 index 00000000..fb6e678c --- /dev/null +++ b/doc/md052.md @@ -0,0 +1,33 @@ +# MD052 - Reference links and images should use a label that is defined + +Tags: images, links + +Aliases: reference-links-images + +Links and images in Markdown can provide the link destination or image source +at the time of use or can define it elsewhere and use a label for reference. +The reference format is convenient for keeping paragraph text clutter-free +and makes it easy to reuse the same URL in multiple places. + +There are three kinds of reference links and images: + +```markdown +Full: [text][label] +Collapsed: [label][] +Shortcut: [label] + +Full: ![text][image] +Collapsed: ![image][] +Shortcut: ![image] + +[label]: https://example.com/label +[image]: https://example.com/image +``` + +A link or image renders correctly when a corresponding label is defined, but +the text displays with brackets if the label is not present. This rule warns +of undefined labels for "full" and "collapsed" reference syntax. + +> "Shortcut" syntax is ambiguous and a missing label will not generate an + error. For example, `[shortcut]` could be a shortcut link or the text + "shortcut" in brackets. diff --git a/doc/md053.md b/doc/md053.md new file mode 100644 index 00000000..e2a23b12 --- /dev/null +++ b/doc/md053.md @@ -0,0 +1,38 @@ +# MD053 - Link and image reference definitions should be needed + +Tags: images, links + +Aliases: link-image-reference-definitions + +Parameters: + +* `ignored_definitions`: Ignored definitions (`string[]`, default `["//"]`) + +Fixable: Most violations can be fixed by tooling + +Links and images in Markdown can provide the link destination or image source +at the time of use or can define it elsewhere and use a label for reference. +The reference format is convenient for keeping paragraph text clutter-free +and makes it easy to reuse the same URL in multiple places. + +Because link and image reference definitions are located separately from +where they are used, there are two scenarios where a definition can be +unnecessary: + +1. If a label is not referenced by any link or image in a document, that + definition is unused and can be deleted. +1. If a label is defined multiple times in a document, the first definition is + used and the others can be deleted. + +This rule considers a reference definition to be used if any link or image +reference has the corresponding label. The "full", "collapsed", and "shortcut" +formats are all supported. + +If there are reference definitions that are deliberately unreferenced, they can +be ignored by setting the `ignored_definitions` parameter. The default value of +this parameter ignores the following convention for adding non-HTML comments to +Markdown: + +```md +[//]: # (This behaves like a comment) +``` diff --git a/lib/constants.js b/lib/constants.js index 466d03b4..87189d59 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -3,5 +3,12 @@ "use strict"; module.exports.deprecatedRuleNames = [ "MD002", "MD006" ]; +module.exports.fixableRuleNames = [ + "MD004", "MD005", "MD006", "MD007", "MD009", "MD010", + "MD011", "MD012", "MD014", "MD018", "MD019", "MD020", + "MD021", "MD022", "MD023", "MD026", "MD027", "MD030", + "MD031", "MD032", "MD034", "MD037", "MD038", "MD039", + "MD044", "MD047", "MD049", "MD050", "MD053" +]; module.exports.homepage = "https://github.com/DavidAnson/markdownlint"; module.exports.version = "0.26.2"; diff --git a/package.json b/package.json index 67d5f131..909a41d9 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,9 @@ "build-config-schema": "node schema/build-config-schema.js", "build-declaration": "tsc --allowJs --declaration --emitDeclarationOnly --module commonjs --resolveJsonModule --target es2015 lib/markdownlint.js && node scripts delete 'lib/{c,md,r}*.d.ts' 'helpers/*.d.ts'", "build-demo": "node scripts copy node_modules/markdown-it/dist/markdown-it.min.js demo/markdown-it.min.js && cd demo && webpack --no-stats", + "build-docs": "node doc-build/build-rules.mjs", "build-example": "npm install --no-save --ignore-scripts grunt grunt-cli gulp through2", - "ci": "npm-run-all --continue-on-error --parallel build-config lint serial-declaration-demo test-cover && git diff --exit-code", + "ci": "npm-run-all --continue-on-error --parallel lint serial-config-docs serial-declaration-demo test-cover && git diff --exit-code", "clone-test-repos-dotnet-docs": "cd test-repos && git clone https://github.com/dotnet/docs dotnet-docs --depth 1 --no-tags --quiet", "clone-test-repos-eslint-eslint": "cd test-repos && git clone https://github.com/eslint/eslint eslint-eslint --depth 1 --no-tags --quiet", "clone-test-repos-mkdocs-mkdocs": "cd test-repos && git clone https://github.com/mkdocs/mkdocs mkdocs-mkdocs --depth 1 --no-tags --quiet", @@ -45,6 +46,7 @@ "docker-npm-run-upgrade": "docker run --rm --tty --name npm-run-upgrade --volume $PWD:/home/workdir --workdir /home/workdir --user node node:16 npm run upgrade", "lint": "eslint --ext .js,.mjs --max-warnings 0 .", "lint-test-repos": "ava --timeout=5m test/markdownlint-test-repos.js", + "serial-config-docs": "npm run build-config && npm run build-docs", "serial-declaration-demo": "npm run build-declaration && npm-run-all --continue-on-error --parallel build-demo test-declaration", "test": "ava test/markdownlint-test.js test/markdownlint-test-config.js test/markdownlint-test-custom-rules.js test/markdownlint-test-helpers.js test/markdownlint-test-result-object.js test/markdownlint-test-scenarios.js", "test-cover": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 npm test", diff --git a/test/markdownlint-test-scenarios.js b/test/markdownlint-test-scenarios.js index de4b713f..57757604 100644 --- a/test/markdownlint-test-scenarios.js +++ b/test/markdownlint-test-scenarios.js @@ -7,6 +7,7 @@ const path = require("node:path"); const test = require("ava").default; const { markdownlint } = require("../lib/markdownlint").promises; const helpers = require("../helpers"); +const constants = require("../lib/constants"); /** * Create a test function for the specified test file. @@ -64,6 +65,10 @@ function createTestForFile(file) { if (indices[indices.length - 1] !== error.lineNumber) { indices.push(error.lineNumber); } + t.true( + !error.fixInfo || constants.fixableRuleNames.includes(rule), + `Fixable rule ${rule} is not tagged as such.` + ); } t.deepEqual(actual, expected, "Too few or too many issues found."); // Create snapshot diff --git a/test/markdownlint-test.js b/test/markdownlint-test.js index d779e83b..470b52a1 100644 --- a/test/markdownlint-test.js +++ b/test/markdownlint-test.js @@ -105,18 +105,23 @@ test("projectFilesNoInlineConfig", (t) => new Promise((resolve) => { test("projectFilesInlineConfig", (t) => new Promise((resolve) => { t.plan(2); - const options = { - "files": [ "doc/Rules.md" ], - "config": require("../.markdownlint.json") - }; - markdownlint(options, function callback(err, actual) { - t.falsy(err); - const expected = { - "doc/Rules.md": [] - }; - t.deepEqual(actual, expected, "Issue(s) with project files."); - resolve(); - }); + import("globby") + .then((module) => module.globby("doc/*.md")) + .then((files) => { + const options = { + files, + "config": require("../.markdownlint.json") + }; + markdownlint(options, function callback(err, actual) { + t.falsy(err); + const expected = {}; + for (const file of files) { + expected[file] = []; + } + t.deepEqual(actual, expected, "Issue(s) with project files."); + resolve(); + }); + }); })); test("stringInputLineEndings", (t) => new Promise((resolve) => { @@ -925,93 +930,6 @@ test("readme", (t) => new Promise((resolve) => { }); })); -test("rules", (t) => new Promise((resolve) => { - t.plan(375); - fs.readFile("doc/Rules.md", "utf8", - (err, contents) => { - t.falsy(err); - const rulesLeft = [ ...rules ]; - let inHeading = false; - let rule = null; - let ruleHasTags = true; - let ruleHasAliases = true; - let ruleUsesParams = null; - const tagAliasParameterRe = /, |: | /; - const testTagsAliasesParams = (r) => { - // eslint-disable-next-line unicorn/prefer-default-parameters - r = r || "[NO RULE]"; - t.true(ruleHasTags, - "Missing tags for rule " + r.names + "."); - t.true(ruleHasAliases, - "Missing aliases for rule " + r.names + "."); - t.true(!ruleUsesParams, - "Missing parameters for rule " + r.names + "."); - }; - // @ts-ignore - for (const token of md.parse(contents, {})) { - if ((token.type === "heading_open") && (token.tag === "h2")) { - inHeading = true; - } else if (token.type === "heading_close") { - inHeading = false; - } else if (token.type === "inline") { - if (inHeading) { - testTagsAliasesParams(rule); - rule = rulesLeft.shift(); - ruleHasTags = false; - ruleHasAliases = false; - t.truthy(rule, - "Missing rule implementation for " + token.content + "."); - const ruleName = rule.names[0]; - let headingContent = ruleName + " - " + rule.description; - if (deprecatedRuleNames.has(ruleName)) { - headingContent = "~~" + headingContent + "~~"; - } - t.is(token.content, - headingContent, - "Rule mismatch."); - ruleUsesParams = rule.function.toString() - .match(/params\.config\.[_a-z]*/gi); - if (ruleUsesParams) { - ruleUsesParams = ruleUsesParams.map(function forUse(use) { - return use.split(".").pop(); - }); - ruleUsesParams.sort(); - } - } else if (token.content.startsWith("Tags: ") && rule) { - t.deepEqual(token.content.split(tagAliasParameterRe).slice(1), - rule.tags, "Tag mismatch for rule " + rule.names + "."); - ruleHasTags = true; - } else if (token.content.startsWith("Aliases: ") && rule) { - t.deepEqual(token.content.split(tagAliasParameterRe).slice(1), - rule.names.slice(1), - "Alias mismatch for rule " + rule.names + "."); - ruleHasAliases = true; - } else if (token.content.startsWith("Parameters: ") && rule) { - let inDetails = false; - const parameters = token.content.split(tagAliasParameterRe) - .slice(1) - .filter(function forPart(part) { - inDetails = inDetails || (part[0] === "("); - return !inDetails; - }); - parameters.sort(); - t.deepEqual(parameters, ruleUsesParams, - "Missing parameter for rule " + rule.names); - ruleUsesParams = null; - } - } - } - const ruleLeft = rulesLeft.shift(); - t.true(!ruleLeft, - "Missing rule documentation for " + - (ruleLeft || { "names": "[NO RULE]" }).names + "."); - if (rule) { - testTagsAliasesParams(rule); - } - resolve(); - }); -})); - test("validateJsonUsingConfigSchemaStrict", (t) => { const jsonFileRe = /\.json$/i; const resultsFileRe = /\.results\.json$/i;