forked from rook/rook
mkdocs uses a markdown renderer that is hardcoded to 4 spaces per tab
for detecting indentation levels, including ordered- and
unordered-lists. Since we cannot easily change the renderer, begin using
a markdown linter in CI that will fail if official docs do not adhere to
the spacing rules.
As a starting point, the markdownlint config does not begin with the
default set of checks, which might overwhelm attempts to fix them.
Instead, focus on list-tab-spacing rules and a few other highly useful
checks.
markdownlint also has some gaps in its abilities that allow common Rook
doc issues to pass acceptance. However, it allows creating custom
linting plugins. Create 2 such linting plugins to check 2 things:
- all doc lines (except code blocks) must be aligned to a 4-space
boundary, without exception. This ensures that markdown will render
correctly with mkdocs. This unfortunately makes it possible to create
lists that are internally aligned strangely.
- admonitions must all follow the same format of
```
!!! header
body
```
For the strange lists, this is allowed and renders correctly, but it
looks strange:
```md
- first bullet
- second bullet
still second bullet
- third bullet
has a paragraph
of text inside
- last bullet
Signed-off-by: Blaine Gardner <blaine.gardner@ibm.com>
78 lines
3.3 KiB
JavaScript
78 lines
3.3 KiB
JavaScript
// enforce that lines must be indented to a strict number of tab-spaces
|
|
// this lint rule is largely non-contextual and requires nearly all lines to adhere to the rule
|
|
// this is even true for ordered/unordered lists in which mkdocs **usually** allows spacing to match
|
|
// that of the parent line. but this rule is quick and dirty, and it does not harm to enforce
|
|
// indenting to 4-space boundaries to be entirely certain that mkdocs will render as intended.
|
|
|
|
const expected_tab_spaces = 4
|
|
|
|
// it's hard to know exactly what spacing the user intended, but we can make an educated guess
|
|
// considering 2 things:
|
|
// 1. most code editors are likely to indent to 2 spaces by default. therefore, suggest
|
|
// that anything indented 2 spaces or more should be indented all the way
|
|
// 2. some users put a single space in front of bullets/numbers when starting a list.
|
|
// therefore, suggest that anything indented only a single space should be non-indented
|
|
const suggested_spacing_indent_cutoff = 2
|
|
|
|
module.exports = {
|
|
"names": [ "strict-tab-spacing" ],
|
|
"description": "Enforce strict tab spacing",
|
|
"tags": [ "test" ],
|
|
"parser": "none",
|
|
"function": function rule(params, onError) {
|
|
const { lines } = params;
|
|
const countTabSpaces = (line) => {
|
|
start_spaces = /^\s*/;
|
|
return line.match(start_spaces)[0].length
|
|
};
|
|
const generateTabSpaces = (count) => {
|
|
return ''.padStart(count, ' ')
|
|
}
|
|
const isCodeBlockEnd = (line) => {
|
|
trimmed = line.trim()
|
|
return ( trimmed === "```" )
|
|
}
|
|
const isCodeBlockStart = (line) => {
|
|
if ( isCodeBlockEnd(line) ) return false;
|
|
trimmed = line.trim()
|
|
return ( trimmed.startsWith("```") )
|
|
}
|
|
let code_block_depth = 0
|
|
lines.forEach((line, i) => {
|
|
// don't strictly enforce tab spacing inside code blocks
|
|
if ( isCodeBlockStart(line) ) {
|
|
code_block_depth++
|
|
// code block start lines must be indented to a tab-space boundary
|
|
} else if ( isCodeBlockEnd(line) ) {
|
|
code_block_depth--
|
|
// code block end lines must also be indented to a tab-space boundary
|
|
} else if ( code_block_depth > 0 ) {
|
|
// if inside of a code block, but not a start/end line, don't warn about spacing
|
|
return
|
|
}
|
|
|
|
const thisLineNumber = i+1 // "lineNumber" field is ones-based
|
|
got_tab_spaces = countTabSpaces(line)
|
|
const floor = got_tab_spaces / expected_tab_spaces
|
|
const remainder = got_tab_spaces % expected_tab_spaces
|
|
if ( remainder != 0 ) {
|
|
// begin with the assumption that the line should be non-indented
|
|
suggested_spacing = generateTabSpaces(floor)
|
|
if ( remainder >= suggested_spacing_indent_cutoff ) {
|
|
suggested_spacing = generateTabSpaces(floor + expected_tab_spaces)
|
|
}
|
|
onError({
|
|
"lineNumber": thisLineNumber,
|
|
"detail": "lines must be indented to a strict boundary of " + expected_tab_spaces + " spaces",
|
|
"context": line,
|
|
"fixInfo": {
|
|
"lineNumber": thisLineNumber,
|
|
"deleteCount": got_tab_spaces,
|
|
"insertText": suggested_spacing, // insert at beginning of lineNumber
|
|
},
|
|
});
|
|
}
|
|
});
|
|
}
|
|
};
|