mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-09-21 21:30:47 +02:00
parent
fd06a50ee5
commit
e9b3cc4c18
17 changed files with 232 additions and 25 deletions
|
@ -90,6 +90,7 @@ playground for learning and exploring.
|
||||||
* **[MD045](doc/Rules.md#md045)** *no-alt-text* - Images should have alternate text (alt text)
|
* **[MD045](doc/Rules.md#md045)** *no-alt-text* - Images should have alternate text (alt text)
|
||||||
* **[MD046](doc/Rules.md#md046)** *code-block-style* - Code block style
|
* **[MD046](doc/Rules.md#md046)** *code-block-style* - Code block style
|
||||||
* **[MD047](doc/Rules.md#md047)** *single-trailing-newline* - Files should end with a single newline character
|
* **[MD047](doc/Rules.md#md047)** *single-trailing-newline* - Files should end with a single newline character
|
||||||
|
* **[MD048](doc/Rules.md#md048)** *code-fence-style* - Code fence style
|
||||||
|
|
||||||
See [Rules.md](doc/Rules.md) for more details.
|
See [Rules.md](doc/Rules.md) for more details.
|
||||||
|
|
||||||
|
@ -109,7 +110,7 @@ Tags group related rules and can be used to enable/disable multiple rules at onc
|
||||||
* **blank_lines** - MD012, MD022, MD031, MD032, MD047
|
* **blank_lines** - MD012, MD022, MD031, MD032, MD047
|
||||||
* **blockquote** - MD027, MD028
|
* **blockquote** - MD027, MD028
|
||||||
* **bullet** - MD004, MD005, MD006, MD007, MD032
|
* **bullet** - MD004, MD005, MD006, MD007, MD032
|
||||||
* **code** - MD014, MD031, MD038, MD040, MD046
|
* **code** - MD014, MD031, MD038, MD040, MD046, MD048
|
||||||
* **emphasis** - MD036, MD037
|
* **emphasis** - MD036, MD037
|
||||||
* **hard_tab** - MD010
|
* **hard_tab** - MD010
|
||||||
* **headers** - MD001, MD002, MD003, MD018, MD019, MD020, MD021, MD022, MD023,
|
* **headers** - MD001, MD002, MD003, MD018, MD019, MD020, MD021, MD022, MD023,
|
||||||
|
|
38
doc/Rules.md
38
doc/Rules.md
|
@ -1601,3 +1601,41 @@ To fix the violation, add a newline character to the end of the file:
|
||||||
This file ends with a newline.
|
This file ends with a newline.
|
||||||
[EOF]
|
[EOF]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a name="md048"></a>
|
||||||
|
|
||||||
|
## MD048 - Code fence style
|
||||||
|
|
||||||
|
Tags: code
|
||||||
|
|
||||||
|
Aliases: code-fence-style
|
||||||
|
|
||||||
|
Parameters: style ("consistent", "tilde", "backtick"; default "consistent")
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
38
lib/md048.js
Normal file
38
lib/md048.js
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const { addErrorDetailIf } = require("../helpers");
|
||||||
|
|
||||||
|
function fencedCodeBlockStyleFor(markup) {
|
||||||
|
switch (markup[0]) {
|
||||||
|
case "~":
|
||||||
|
return "tilde";
|
||||||
|
default:
|
||||||
|
return "backtick";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
"names": [ "MD048", "code-fence-style" ],
|
||||||
|
"description": "Code fence style",
|
||||||
|
"tags": [ "code" ],
|
||||||
|
"function": function MD048(params, onError) {
|
||||||
|
const style = params.config.style || "consistent";
|
||||||
|
let expectedStyle = style;
|
||||||
|
params.tokens
|
||||||
|
.filter((token) => token.type === "fence")
|
||||||
|
.forEach((fenceToken) => {
|
||||||
|
const { lineNumber, markup } = fenceToken;
|
||||||
|
if (expectedStyle === "consistent") {
|
||||||
|
expectedStyle = fencedCodeBlockStyleFor(markup);
|
||||||
|
}
|
||||||
|
addErrorDetailIf(
|
||||||
|
onError,
|
||||||
|
lineNumber,
|
||||||
|
expectedStyle,
|
||||||
|
fencedCodeBlockStyleFor(markup)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
|
@ -50,7 +50,8 @@ const rules = [
|
||||||
require("./md044"),
|
require("./md044"),
|
||||||
require("./md045"),
|
require("./md045"),
|
||||||
require("./md046"),
|
require("./md046"),
|
||||||
require("./md047")
|
require("./md047"),
|
||||||
|
require("./md048")
|
||||||
];
|
];
|
||||||
rules.forEach((rule) => {
|
rules.forEach((rule) => {
|
||||||
const name = rule.names[0].toLowerCase();
|
const name = rule.names[0].toLowerCase();
|
||||||
|
|
|
@ -334,6 +334,20 @@ rules.forEach(function forRule(rule) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
case "MD048":
|
||||||
|
scheme.properties = {
|
||||||
|
"style": {
|
||||||
|
"description": "Code fence syle",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"consistent",
|
||||||
|
"backtick",
|
||||||
|
"tilde"
|
||||||
|
],
|
||||||
|
"default": "consistent"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
custom = false;
|
custom = false;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1339,6 +1339,48 @@
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
|
"MD048": {
|
||||||
|
"description": "MD048/code-fence-style - Code fence style",
|
||||||
|
"type": [
|
||||||
|
"boolean",
|
||||||
|
"object"
|
||||||
|
],
|
||||||
|
"default": true,
|
||||||
|
"properties": {
|
||||||
|
"style": {
|
||||||
|
"description": "Code fence syle",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"consistent",
|
||||||
|
"backtick",
|
||||||
|
"tilde"
|
||||||
|
],
|
||||||
|
"default": "consistent"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"code-fence-style": {
|
||||||
|
"description": "MD048/code-fence-style - Code fence style",
|
||||||
|
"type": [
|
||||||
|
"boolean",
|
||||||
|
"object"
|
||||||
|
],
|
||||||
|
"default": true,
|
||||||
|
"properties": {
|
||||||
|
"style": {
|
||||||
|
"description": "Code fence syle",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"consistent",
|
||||||
|
"backtick",
|
||||||
|
"tilde"
|
||||||
|
],
|
||||||
|
"default": "consistent"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
"headings": {
|
"headings": {
|
||||||
"description": "headings - MD001, MD002, MD003, MD018, MD019, MD020, MD021, MD022, MD023, MD024, MD025, MD026, MD036, MD041, MD043",
|
"description": "headings - MD001, MD002, MD003, MD018, MD019, MD020, MD021, MD022, MD023, MD024, MD025, MD026, MD036, MD041, MD043",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
@ -1390,7 +1432,7 @@
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
"code": {
|
"code": {
|
||||||
"description": "code - MD014, MD031, MD038, MD040, MD046",
|
"description": "code - MD014, MD031, MD038, MD040, MD046, MD048",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
|
|
|
@ -74,6 +74,10 @@ Code `with ` space {MD038}
|
||||||
code fence without language {MD040:73} {MD046:73}
|
code fence without language {MD040:73} {MD046:73}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
~~~js
|
||||||
|
code fence with different style {MD048:77} {MD046:77}
|
||||||
|
~~~
|
||||||
|
|
||||||
[empty link]() {MD042}
|
[empty link]() {MD042}
|
||||||
|
|
||||||
markdownLint {MD044}
|
markdownLint {MD044}
|
||||||
|
|
6
test/code_fence_style_backtick.json
Normal file
6
test/code_fence_style_backtick.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"default": true,
|
||||||
|
"MD048": {
|
||||||
|
"style": "backtick"
|
||||||
|
}
|
||||||
|
}
|
19
test/code_fence_style_backtick.md
Normal file
19
test/code_fence_style_backtick.md
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
```text
|
||||||
|
This is a code block
|
||||||
|
```
|
||||||
|
|
||||||
|
~~~text
|
||||||
|
This is {MD048:5} a code block
|
||||||
|
~~~
|
||||||
|
|
||||||
|
```text
|
||||||
|
~~~
|
||||||
|
This is fine
|
||||||
|
~~~
|
||||||
|
```
|
||||||
|
|
||||||
|
~~~text
|
||||||
|
```
|
||||||
|
This is not {MD048:15}
|
||||||
|
```
|
||||||
|
~~~
|
6
test/code_fence_style_tilde.json
Normal file
6
test/code_fence_style_tilde.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"default": true,
|
||||||
|
"MD048": {
|
||||||
|
"style": "tilde"
|
||||||
|
}
|
||||||
|
}
|
19
test/code_fence_style_tilde.md
Normal file
19
test/code_fence_style_tilde.md
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
```text
|
||||||
|
This is {MD048:1} a code block
|
||||||
|
```
|
||||||
|
|
||||||
|
~~~text
|
||||||
|
This is a code block
|
||||||
|
~~~
|
||||||
|
|
||||||
|
```text
|
||||||
|
~~~
|
||||||
|
This is not fine {MD048:9}
|
||||||
|
~~~
|
||||||
|
```
|
||||||
|
|
||||||
|
~~~text
|
||||||
|
```
|
||||||
|
This is
|
||||||
|
```
|
||||||
|
~~~
|
|
@ -24,4 +24,8 @@ Fenced code
|
||||||
|
|
||||||
Indented code
|
Indented code
|
||||||
|
|
||||||
|
~~~text
|
||||||
|
Fenced code
|
||||||
|
~~~
|
||||||
|
|
||||||
Missing newline character
|
Missing newline character
|
|
@ -24,4 +24,8 @@ Fenced code
|
||||||
|
|
||||||
Indented code
|
Indented code
|
||||||
|
|
||||||
|
~~~text
|
||||||
|
Fenced code
|
||||||
|
~~~
|
||||||
|
|
||||||
Missing newline character
|
Missing newline character
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
"errorRange": [25, 13]
|
"errorRange": [25, 13]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"lineNumber": 27,
|
"lineNumber": 31,
|
||||||
"ruleNames": [ "MD043", "required-headings", "required-headers" ],
|
"ruleNames": [ "MD043", "required-headings", "required-headers" ],
|
||||||
"ruleDescription": "Required heading structure",
|
"ruleDescription": "Required heading structure",
|
||||||
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md043",
|
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md043",
|
||||||
|
@ -99,12 +99,21 @@
|
||||||
"errorRange": null
|
"errorRange": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"lineNumber": 27,
|
"lineNumber": 31,
|
||||||
"ruleNames": [ "MD047", "single-trailing-newline" ],
|
"ruleNames": [ "MD047", "single-trailing-newline" ],
|
||||||
"ruleDescription": "Files should end with a single newline character",
|
"ruleDescription": "Files should end with a single newline character",
|
||||||
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md047",
|
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md047",
|
||||||
"errorDetail": null,
|
"errorDetail": null,
|
||||||
"errorContext": null,
|
"errorContext": null,
|
||||||
"errorRange": [ 25, 1 ]
|
"errorRange": [ 25, 1 ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lineNumber": 27,
|
||||||
|
"ruleNames": [ "MD048", "code-fence-style" ],
|
||||||
|
"ruleDescription": "Code fence style",
|
||||||
|
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md048",
|
||||||
|
"errorDetail": "Expected: backtick; Actual: tilde",
|
||||||
|
"errorContext": null,
|
||||||
|
"errorRange": null
|
||||||
}
|
}
|
||||||
]
|
]
|
|
@ -24,4 +24,4 @@ None of the above should trigger any heading related rules.
|
||||||
Code block without a language specifier
|
Code block without a language specifier
|
||||||
```
|
```
|
||||||
|
|
||||||
{MD040:23}
|
{MD040:23} {MD048:13}
|
||||||
|
|
|
@ -4,7 +4,7 @@ text {MD031:4}
|
||||||
```fence
|
```fence
|
||||||
code {MD031:6}
|
code {MD031:6}
|
||||||
```
|
```
|
||||||
text {MD031:8}
|
text {MD031:8} {MD048:8}
|
||||||
~~~fence
|
~~~fence
|
||||||
code
|
code
|
||||||
~~~
|
~~~
|
||||||
|
@ -14,7 +14,7 @@ text {MD031:10} {MD031:12}
|
||||||
code
|
code
|
||||||
~~~
|
~~~
|
||||||
```
|
```
|
||||||
text {MD031:16} {MD031:18}
|
text {MD031:16} {MD031:18} {MD048:18}
|
||||||
~~~fence
|
~~~fence
|
||||||
```fence
|
```fence
|
||||||
code
|
code
|
||||||
|
@ -28,7 +28,7 @@ code
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
```
|
```
|
||||||
text {MD031:30} {MD031:32}
|
text {MD031:30} {MD031:32} {MD048:32}
|
||||||
~~~fence
|
~~~fence
|
||||||
|
|
||||||
```fence
|
```fence
|
||||||
|
@ -41,7 +41,7 @@ text {MD031:38} {MD031:40}
|
||||||
code
|
code
|
||||||
~~~
|
~~~
|
||||||
```
|
```
|
||||||
text {MD031:43} {MD031:45}
|
text {MD031:43} {MD031:45} {MD048:45}
|
||||||
~~~fence
|
~~~fence
|
||||||
code
|
code
|
||||||
```
|
```
|
||||||
|
@ -52,7 +52,7 @@ text {MD031:48} {MD031:50}
|
||||||
code
|
code
|
||||||
```
|
```
|
||||||
````
|
````
|
||||||
text {MD031:54} {MD031:56}
|
text {MD031:54} {MD031:56} {MD048:56}
|
||||||
~~~~fence
|
~~~~fence
|
||||||
~~~fence
|
~~~fence
|
||||||
code
|
code
|
||||||
|
@ -64,7 +64,7 @@ text {MD031:60} {MD031:62}
|
||||||
code
|
code
|
||||||
```
|
```
|
||||||
`````
|
`````
|
||||||
text {MD031:66} {MD031:68}
|
text {MD031:66} {MD031:68} {MD048:68}
|
||||||
~~~~fence
|
~~~~fence
|
||||||
~~~fence
|
~~~fence
|
||||||
code
|
code
|
||||||
|
|
|
@ -1124,7 +1124,7 @@ module.exports.styleAll = function styleAll(test) {
|
||||||
"MD019": [ 27 ],
|
"MD019": [ 27 ],
|
||||||
"MD020": [ 29 ],
|
"MD020": [ 29 ],
|
||||||
"MD021": [ 31 ],
|
"MD021": [ 31 ],
|
||||||
"MD022": [ 82 ],
|
"MD022": [ 86 ],
|
||||||
"MD023": [ 40 ],
|
"MD023": [ 40 ],
|
||||||
"MD024": [ 35 ],
|
"MD024": [ 35 ],
|
||||||
"MD026": [ 40 ],
|
"MD026": [ 40 ],
|
||||||
|
@ -1143,10 +1143,11 @@ module.exports.styleAll = function styleAll(test) {
|
||||||
"MD039": [ 71 ],
|
"MD039": [ 71 ],
|
||||||
"MD040": [ 73 ],
|
"MD040": [ 73 ],
|
||||||
"MD041": [ 1 ],
|
"MD041": [ 1 ],
|
||||||
"MD042": [ 77 ],
|
"MD042": [ 81 ],
|
||||||
"MD045": [ 81 ],
|
"MD045": [ 85 ],
|
||||||
"MD046": [ 49, 73 ],
|
"MD046": [ 49, 73, 77 ],
|
||||||
"MD047": [ 84 ]
|
"MD047": [ 88 ],
|
||||||
|
"MD048": [ 77 ]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
test.deepEqual(actualResult, expectedResult, "Undetected issues.");
|
test.deepEqual(actualResult, expectedResult, "Undetected issues.");
|
||||||
|
@ -1175,7 +1176,7 @@ module.exports.styleRelaxed = function styleRelaxed(test) {
|
||||||
"MD019": [ 27 ],
|
"MD019": [ 27 ],
|
||||||
"MD020": [ 29 ],
|
"MD020": [ 29 ],
|
||||||
"MD021": [ 31 ],
|
"MD021": [ 31 ],
|
||||||
"MD022": [ 82 ],
|
"MD022": [ 86 ],
|
||||||
"MD023": [ 40 ],
|
"MD023": [ 40 ],
|
||||||
"MD024": [ 35 ],
|
"MD024": [ 35 ],
|
||||||
"MD026": [ 40 ],
|
"MD026": [ 40 ],
|
||||||
|
@ -1184,10 +1185,11 @@ module.exports.styleRelaxed = function styleRelaxed(test) {
|
||||||
"MD032": [ 7, 8, 51 ],
|
"MD032": [ 7, 8, 51 ],
|
||||||
"MD035": [ 61 ],
|
"MD035": [ 61 ],
|
||||||
"MD036": [ 65 ],
|
"MD036": [ 65 ],
|
||||||
"MD042": [ 77 ],
|
"MD042": [ 81 ],
|
||||||
"MD045": [ 81 ],
|
"MD045": [ 85 ],
|
||||||
"MD046": [ 49, 73 ],
|
"MD046": [ 49, 73, 77 ],
|
||||||
"MD047": [ 84 ]
|
"MD047": [ 88 ],
|
||||||
|
"MD048": [ 77 ]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
test.deepEqual(actualResult, expectedResult, "Undetected issues.");
|
test.deepEqual(actualResult, expectedResult, "Undetected issues.");
|
||||||
|
@ -1430,7 +1432,7 @@ module.exports.missingStringValue = function missingStringValue(test) {
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.readme = function readme(test) {
|
module.exports.readme = function readme(test) {
|
||||||
test.expect(113);
|
test.expect(115);
|
||||||
const tagToRules = {};
|
const tagToRules = {};
|
||||||
rules.forEach(function forRule(rule) {
|
rules.forEach(function forRule(rule) {
|
||||||
rule.tags.forEach(function forTag(tag) {
|
rule.tags.forEach(function forTag(tag) {
|
||||||
|
@ -1499,7 +1501,7 @@ module.exports.readme = function readme(test) {
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.doc = function doc(test) {
|
module.exports.doc = function doc(test) {
|
||||||
test.expect(328);
|
test.expect(336);
|
||||||
fs.readFile("doc/Rules.md", helpers.utf8Encoding,
|
fs.readFile("doc/Rules.md", helpers.utf8Encoding,
|
||||||
function readFile(err, contents) {
|
function readFile(err, contents) {
|
||||||
test.ifError(err);
|
test.ifError(err);
|
||||||
|
@ -2787,7 +2789,7 @@ module.exports.configBadHybridSync = function configBadHybridSync(test) {
|
||||||
|
|
||||||
module.exports.allBuiltInRulesHaveValidUrl =
|
module.exports.allBuiltInRulesHaveValidUrl =
|
||||||
function allBuiltInRulesHaveValidUrl(test) {
|
function allBuiltInRulesHaveValidUrl(test) {
|
||||||
test.expect(129);
|
test.expect(132);
|
||||||
rules.forEach(function forRule(rule) {
|
rules.forEach(function forRule(rule) {
|
||||||
test.ok(rule.information);
|
test.ok(rule.information);
|
||||||
test.ok(Object.getPrototypeOf(rule.information) === URL.prototype);
|
test.ok(Object.getPrototypeOf(rule.information) === URL.prototype);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue