From a563c082a5600509406361cb8a00ee3dda08cb65 Mon Sep 17 00:00:00 2001 From: Gabriel Kuznik Date: Fri, 1 Dec 2023 12:33:48 +0100 Subject: [PATCH] Add rule MD055/table-missing-border (fixes #93, refs #1039, no generated files). --- .github/dictionary.txt | 1 + README.md | 2 + doc-build/md055.md | 34 +++++ lib/md055.js | 27 ++++ lib/rules.js | 4 +- test/break-all-the-rules.md | 4 + test/html-comment-in-markdown-table.md | 4 + test/long_lines_code.md | 2 - test/markdownlint-test.js | 18 ++- ...md033-cannot-read-property-of-undefined.md | 4 + test/table-missing-pipes.md | 140 ++++++++++++++++++ 11 files changed, 228 insertions(+), 12 deletions(-) create mode 100644 doc-build/md055.md create mode 100644 lib/md055.js create mode 100644 test/table-missing-pipes.md diff --git a/.github/dictionary.txt b/.github/dictionary.txt index 39cd1f71..51267844 100644 --- a/.github/dictionary.txt +++ b/.github/dictionary.txt @@ -37,6 +37,7 @@ eslint-plugin-markdownlint first-line-h1 formatter fs +GFM globbing grunt-markdownlint h1 diff --git a/README.md b/README.md index 9c019221..3355233f 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,7 @@ playground for learning and exploring. - **[MD052](doc/md052.md)** *reference-links-images* - Reference links and images should use a label that is defined - **[MD053](doc/md053.md)** *link-image-reference-definitions* - Link and image reference definitions should be needed - **[MD054](doc/md054.md)** *link-image-style* - Link and image style +- **[MD055](doc/md055.md)** *table-missing-border* - Table is missing leading or trailing pipe character @@ -175,6 +176,7 @@ rules at once. - **`ol`** - `MD029`, `MD030`, `MD032` - **`spaces`** - `MD018`, `MD019`, `MD020`, `MD021`, `MD023` - **`spelling`** - `MD044` +- **`table`** - `MD055` - **`ul`** - `MD004`, `MD005`, `MD007`, `MD030`, `MD032` - **`url`** - `MD034` - **`whitespace`** - `MD009`, `MD010`, `MD012`, `MD027`, `MD028`, `MD030`, diff --git a/doc-build/md055.md b/doc-build/md055.md new file mode 100644 index 00000000..f29f3fef --- /dev/null +++ b/doc-build/md055.md @@ -0,0 +1,34 @@ +This rule is triggered when a [GFM table][gfm-table] is missing a leading +or trailing pipe character `|`. + +This table is missing pipes on both sides: + +```markdown +| Heading | Heading | +|---------|--------- + Cell | Cell | +``` + +To fix this, make sure there is a pipe character at the start and end of the +row: + +```markdown +| Heading | Heading | +|---------|---------| +| Cell | Cell | +``` + +Note that text immediately below a table is treated as part of the table and +will trigger this rule: + +```markdown +| Heading | Heading | +|---------|---------| +| Cell | Cell | +This text will trigger the rule +``` + +Rationale: Some parsers have difficulty with tables that are missing their +leading or trailing pipe characters. + +[gfm-table]: https://github.github.com/gfm/#tables-extension- diff --git a/lib/md055.js b/lib/md055.js new file mode 100644 index 00000000..d302d366 --- /dev/null +++ b/lib/md055.js @@ -0,0 +1,27 @@ +// @ts-check + +"use strict"; + +const { addErrorContext } = require("../helpers"); +const { filterByTypes } = require("../helpers/micromark.cjs"); + +module.exports = { + "names": [ "MD055", "table-missing-border" ], + "description": "Table is missing leading or trailing pipe character", + "tags": [ "table" ], + "function": function MD055(params, onError) { + const tables = filterByTypes(params.parsers.micromark.tokens, [ "table" ]); + for (const table of tables) { + const rows = filterByTypes(table.children, [ "tableRow", "tableDelimiterRow" ]); + for (const row of rows) { + const { startLine, text } = row; + if (!text.startsWith("|")) { + addErrorContext(onError, startLine, text, true); + } + if (!text.endsWith("|")) { + addErrorContext(onError, startLine, text, false, true); + } + } + } + } +} diff --git a/lib/rules.js b/lib/rules.js index eb946277..f6a7564b 100644 --- a/lib/rules.js +++ b/lib/rules.js @@ -51,8 +51,8 @@ const rules = [ require("./md051"), require("./md052"), require("./md053"), - require("./md054") - // md055: See https://github.com/markdownlint/markdownlint + require("./md054"), + require("./md055") // md056: See https://github.com/markdownlint/markdownlint // md057: See https://github.com/markdownlint/markdownlint ]; diff --git a/test/break-all-the-rules.md b/test/break-all-the-rules.md index b8b6d19b..3269fff0 100644 --- a/test/break-all-the-rules.md +++ b/test/break-all-the-rules.md @@ -105,6 +105,10 @@ Strong **with** different style {MD050} [url]: https://example.com/page +| table | header | +|--------|--------| + {MD055} | cell | + | | cell | cell | + + diff --git a/test/long_lines_code.md b/test/long_lines_code.md index 370a9199..8d366550 100644 --- a/test/long_lines_code.md +++ b/test/long_lines_code.md @@ -29,7 +29,6 @@ This is a short line. | Content Cell | Content Cell | Content Cell | Content Cell | Content Cell | Content Cell | | ============== | ============== | ============== | ============== | ============== | ============== | | Footer Cell | Footer Cell | Footer Cell | Footer Cell | Footer Cell | Footer Cell | -{: rules="groups"} This is a very very very very very very very very very very very very very very very very very very very very long line. {MD013} @@ -44,7 +43,6 @@ Another line. | Content Cell | Content Cell | Content Cell | Content Cell | Content Cell | Content Cell | | ============== | ============== | ============== | ============== | ============== | ============== | | Footer Cell | Footer Cell | Footer Cell | Footer Cell | Footer Cell | Footer Cell | -{: rules="groups"} diff --git a/test/table-missing-pipes.md b/test/table-missing-pipes.md new file mode 100644 index 00000000..781d1ecd --- /dev/null +++ b/test/table-missing-pipes.md @@ -0,0 +1,140 @@ +# Table Missing Pipes + +## Bad Header Row + +| Table | {MD055} +|-------|---------| + + Table | {MD055} | +|-------|---------| + + Table | {MD055} +|-------|---------| + +## Bad Separator Row + +| Table | Header | +|-------|--------- + +{MD055:17} + +| Table | Header | + -------|--------| + +{MD055:22} + +| Table | Header | + -------|-------- + +{MD055:27} + +## Missing everything + + {MD055} | Header +---------|------- + {MD055} | cell + +{MD055:34} + + {MD055} | Header +--------:|:-----: + {MD055} | cell + +{MD055:40} + +## Missing trailing pipe + +| Table | Header | +|--------:|:-------| +| {MD055} | cell + +| Table | Header | +|---------|--------| +| {MD055} | cell +| cell | cell | +| cell | cell | + +| Table | Header | +|---------|--------| +| cell | cell | +| {MD055} | cell +| cell | cell | + +| Table | Header | +|---------|--------| +| cell | cell | +| cell | cell | +| {MD055} | cell + +## Missing leading pipe + +| Table | Header | +|-------:|:-------| + {MD055} | cell | + +| Table | Header | +|--------|--------| + {MD055} | cell | +| cell | cell | +| cell | cell | + +| Table | Header | +|--------|--------| +| cell | cell | + {MD055} | cell | +| cell | cell | + +| Table | Header | +|--------|--------| +| cell | cell | +| cell | cell | + {MD055} | cell | + +## Missing both sides + +| Table | Header | +|-------:|:-------| + {MD055} | cell + +| Table | Header | +|--------|--------| + {MD055} | cell +| cell | cell | +| cell | cell | + +| Table | Header | +|--------|--------| +| cell | cell | + {MD055} | cell +| cell | cell | + +| Table | Header | +|--------|--------| +| cell | cell | +| cell | cell | + {MD055} | cell + +## No false-positive + +| Table | Header | +|-------|--------| +| cell | cell | + +| Table | Header | +|-------|--------| +| cell | cell | +| cell | cell | +| cell | cell | + +## No trailing blank line + +| Table | Header | +|-------|--------| +| cell | cell | +{MD055} Text + +## Markdown Combination + +> | Table | Header | +> |-------|--------| +> -{MD055}| cell |