markdownlint
Advanced tools
Comparing version 0.17.2 to 0.18.0
@@ -37,9 +37,9 @@ # Custom Rules | ||
A rule is implemented as an `Object` with four required properties: | ||
A rule is implemented as an `Object` with one optional and four required properties: | ||
- `names` is an `Array` of `String` values that identify the rule in output messages and config. | ||
- `description` is a `String` value that describes the rule in output messages. | ||
- `names` is a required `Array` of `String` values that identify the rule in output messages and config. | ||
- `description` is a required `String` value that describes the rule in output messages. | ||
- `information` is an optional (absolute) `URL` of a link to more information about the rule. | ||
- `tags` is an `Array` of `String` values that groups related rules for easier customization. | ||
- `function` is a synchronous `Function` that implements the rule and is passed two parameters: | ||
- `tags` is a required `Array` of `String` values that groups related rules for easier customization. | ||
- `function` is a required synchronous `Function` that implements the rule and is passed two parameters: | ||
- `params` is an `Object` with properties that describe the content being analyzed: | ||
@@ -52,3 +52,3 @@ - `name` is a `String` that identifies the input file/string. | ||
- `config` is an `Object` corresponding to the rule's entry in `options.config` (if present). | ||
- `onError` is a function that takes a single `Object` parameter with one required and three optional properties: | ||
- `onError` is a function that takes a single `Object` parameter with one required and four optional properties: | ||
- `lineNumber` is a required `Number` specifying the 1-based line number of the error. | ||
@@ -55,0 +55,0 @@ - `details` is an optional `String` with information about what caused the error. |
@@ -321,3 +321,3 @@ | ||
Parameters: br_spaces, list_item_empty_lines (number; default 2, boolean; default false) | ||
Parameters: br_spaces, list_item_empty_lines, strict (number; default 2, boolean; default false, boolean; default false) | ||
@@ -334,5 +334,14 @@ This rule is triggered on any lines that end with unexpected whitespace. To fix this, | ||
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: | ||
to allow this (even when `strict` is `true`): | ||
@@ -449,3 +458,3 @@ ```markdown | ||
Parameters: line_length, heading_line_length, code_block_line_length, code_blocks, tables, headings, headers (number; default 80, boolean; default true) | ||
Parameters: line_length, heading_line_length, code_block_line_length, code_blocks, tables, headings, headers, strict (number; default 80, boolean; default true) | ||
@@ -462,3 +471,4 @@ > If `headings` is not provided, `headers` (deprecated) will be used. | ||
line length. This allows you to still include items such as long URLs without | ||
being forced to break them in the middle. | ||
being forced to break them in the middle. To disable this exception, set the | ||
`strict` parameter to `true`. | ||
@@ -1608,1 +1618,39 @@ You have the option to exclude this rule for code blocks, tables, or headings. | ||
``` | ||
<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. |
@@ -20,3 +20,3 @@ // @ts-check | ||
// eslint-disable-next-line max-len | ||
/<!--\s*markdownlint-(disable|enable|capture|restore)((?:\s+[a-z0-9_-]+)*)\s*-->/ig; | ||
/<!--\s*markdownlint-(disable|enable|capture|restore|disable-file|enable-file)((?:\s+[a-z0-9_-]+)*)\s*-->/ig; | ||
module.exports.inlineCommentRe = inlineCommentRe; | ||
@@ -26,3 +26,3 @@ | ||
module.exports.bareUrlRe = /(?:http|ftp)s?:\/\/[^\s]*/ig; | ||
module.exports.listItemMarkerRe = /^[\s>]*(?:[*+-]|\d+[.)])\s+/; | ||
module.exports.listItemMarkerRe = /^([\s>]*)(?:[*+-]|\d+[.)])\s+/; | ||
module.exports.orderedListItemMarkerRe = /^[\s>]*0*(\d+)[.)]/; | ||
@@ -390,8 +390,4 @@ | ||
if (match) { | ||
let column = match.index + 1; | ||
let length = match[0].length; | ||
if (match[2]) { | ||
column += match[1].length; | ||
length -= match[1].length; | ||
} | ||
const column = match.index + 1; | ||
const length = match[0].length; | ||
range = [ column, length ]; | ||
@@ -398,0 +394,0 @@ } |
{ | ||
"name": "markdownlint-rule-helpers", | ||
"version": "0.5.0", | ||
"version": "0.6.0", | ||
"description": "A collection of markdownlint helper functions for custom rules", | ||
@@ -5,0 +5,0 @@ "main": "helpers.js", |
@@ -262,3 +262,3 @@ // @ts-check | ||
const allRuleNames = []; | ||
ruleList.forEach(function forRule(rule) { | ||
ruleList.forEach((rule) => { | ||
const ruleName = rule.names[0].toUpperCase(); | ||
@@ -269,33 +269,45 @@ allRuleNames.push(ruleName); | ||
let capturedRules = enabledRules; | ||
function forMatch(match) { | ||
function forMatch(match, byLine) { | ||
const action = match[1].toUpperCase(); | ||
if (action === "CAPTURE") { | ||
capturedRules = { ...enabledRules }; | ||
if (byLine) { | ||
capturedRules = { ...enabledRules }; | ||
} | ||
} else if (action === "RESTORE") { | ||
enabledRules = { ...capturedRules }; | ||
if (byLine) { | ||
enabledRules = { ...capturedRules }; | ||
} | ||
} else { | ||
const enabled = (action === "ENABLE"); | ||
const items = match[2] ? | ||
match[2].trim().toUpperCase().split(/\s+/) : | ||
allRuleNames; | ||
items.forEach(function forItem(nameUpper) { | ||
(aliasToRuleNames[nameUpper] || []).forEach(function forRule(ruleName) { | ||
enabledRules[ruleName] = enabled; | ||
// action in [ENABLE, DISABLE, ENABLE-FILE, DISABLE-FILE] | ||
const isfile = action.endsWith("-FILE"); | ||
if ((byLine && !isfile) || (!byLine && isfile)) { | ||
const enabled = (action.startsWith("ENABLE")); | ||
const items = match[2] ? | ||
match[2].trim().toUpperCase().split(/\s+/) : | ||
allRuleNames; | ||
items.forEach((nameUpper) => { | ||
(aliasToRuleNames[nameUpper] || []).forEach((ruleName) => { | ||
enabledRules[ruleName] = enabled; | ||
}); | ||
}); | ||
}); | ||
} | ||
} | ||
} | ||
const enabledRulesPerLineNumber = new Array(1 + frontMatterLines.length); | ||
lines.forEach(function forLine(line) { | ||
if (!noInlineConfig) { | ||
let match = helpers.inlineCommentRe.exec(line); | ||
if (match) { | ||
enabledRules = { ...enabledRules }; | ||
while (match) { | ||
forMatch(match); | ||
match = helpers.inlineCommentRe.exec(line); | ||
[ false, true ].forEach((byLine) => { | ||
lines.forEach((line) => { | ||
if (!noInlineConfig) { | ||
let match = helpers.inlineCommentRe.exec(line); | ||
if (match) { | ||
enabledRules = { ...enabledRules }; | ||
while (match) { | ||
forMatch(match, byLine); | ||
match = helpers.inlineCommentRe.exec(line); | ||
} | ||
} | ||
} | ||
} | ||
enabledRulesPerLineNumber.push(enabledRules); | ||
if (byLine) { | ||
enabledRulesPerLineNumber.push(enabledRules); | ||
} | ||
}); | ||
}); | ||
@@ -620,4 +632,4 @@ return enabledRulesPerLineNumber; | ||
* | ||
* @param {Object} options Configuration options. | ||
* @param {Function} callback Callback (err, result) function. | ||
* @param {Options} options Configuration options. | ||
* @param {LintCallback} callback Callback (err, result) function. | ||
* @returns {void} | ||
@@ -632,4 +644,4 @@ */ | ||
* | ||
* @param {Object} options Configuration options. | ||
* @returns {Object} Result object. | ||
* @param {Options} options Configuration options. | ||
* @returns {LintResults} Results object. | ||
*/ | ||
@@ -675,5 +687,5 @@ function markdownlintSync(options) { | ||
* | ||
* @param {String} file Configuration file name/path. | ||
* @param {Array} [parsers] Optional parsing function(s). | ||
* @param {Function} callback Callback (err, result) function. | ||
* @param {string} file Configuration file name. | ||
* @param {ConfigurationParser[] | null} parsers Parsing function(s). | ||
* @param {ReadConfigCallback} callback Callback (err, result) function. | ||
* @returns {void} | ||
@@ -719,5 +731,5 @@ */ | ||
* | ||
* @param {String} file Configuration file name/path. | ||
* @param {Array} [parsers] Optional parsing function(s). | ||
* @returns {Object} Configuration object. | ||
* @param {string} file Configuration file name. | ||
* @param {ConfigurationParser[]} [parsers] Parsing function(s). | ||
* @returns {Configuration} Configuration object. | ||
*/ | ||
@@ -752,1 +764,185 @@ function readConfigSync(file, parsers) { | ||
module.exports = markdownlint; | ||
// Type declarations | ||
/** | ||
* Function to implement rule logic. | ||
* | ||
* @callback RuleFunction | ||
* @param {RuleParams} params Rule parameters. | ||
* @param {RuleOnError} onError Error-reporting callback. | ||
* @returns {void} | ||
*/ | ||
/** | ||
* Rule parameters. | ||
* | ||
* @typedef {Object} RuleParams | ||
* @property {string} name File/string name. | ||
* @property {MarkdownItToken[]} tokens markdown-it token objects. | ||
* @property {string[]} lines File/string lines. | ||
* @property {string[]} frontMatterLines Front matter lines. | ||
* @property {RuleConfiguration} config Rule configuration. | ||
*/ | ||
/** | ||
* Markdown-It token. | ||
* | ||
* @typedef {Object} MarkdownItToken | ||
* @property {string[][]} attrs HTML attributes. | ||
* @property {boolean} block Block-level token. | ||
* @property {MarkdownItToken[]} children Child nodes. | ||
* @property {string} content Tag contents. | ||
* @property {boolean} hidden Ignore element. | ||
* @property {string} info Fence info. | ||
* @property {number} level Nesting level. | ||
* @property {number[]} map Beginning/ending line numbers. | ||
* @property {string} markup Markup text. | ||
* @property {Object} meta Arbitrary data. | ||
* @property {number} nesting Level change. | ||
* @property {string} tag HTML tag name. | ||
* @property {string} type Token type. | ||
* @property {number} lineNumber Line number (1-based). | ||
* @property {string} line Line content. | ||
*/ | ||
/** | ||
* Error-reporting callback. | ||
* | ||
* @callback RuleOnError | ||
* @param {RuleOnErrorInfo} onErrorInfo Error information. | ||
* @returns {void} | ||
*/ | ||
/** | ||
* Fix information for RuleOnError callback. | ||
* | ||
* @typedef {Object} RuleOnErrorInfo | ||
* @property {number} lineNumber Line number (1-based). | ||
* @property {string} [details] Details about the error. | ||
* @property {string} [context] Context for the error. | ||
* @property {number[]} [range] Column number (1-based) and length. | ||
* @property {RuleOnErrorFixInfo} [fixInfo] Fix information. | ||
*/ | ||
/** | ||
* Fix information for RuleOnErrorInfo. | ||
* | ||
* @typedef {Object} RuleOnErrorFixInfo | ||
* @property {number} [lineNumber] Line number (1-based). | ||
* @property {number} [editColumn] Column of the fix (1-based). | ||
* @property {number} [deleteCount] Count of characters to delete. | ||
* @property {string} [insertText] Text to insert (after deleting). | ||
*/ | ||
/** | ||
* Rule definition. | ||
* | ||
* @typedef {Object} Rule | ||
* @property {string[]} names Rule name(s). | ||
* @property {string} description Rule description. | ||
* @property {URL} [information] Link to more information. | ||
* @property {string[]} tags Rule tag(s). | ||
* @property {RuleFunction} function Rule implementation. | ||
*/ | ||
/** | ||
* Configuration options. | ||
* | ||
* @typedef {Object} Options | ||
* @property {string[] | string} [files] Files to lint. | ||
* @property {Object.<string, string>} [strings] Strings to lint. | ||
* @property {Configuration} [config] Configuration object. | ||
* @property {Rule[] | Rule} [customRules] Custom rules. | ||
* @property {RegExp} [frontMatter] Front matter pattern. | ||
* @property {boolean} [handleRuleFailures] True to catch exceptions. | ||
* @property {boolean} [noInlineConfig] True to ignore HTML directives. | ||
* @property {number} [resultVersion] Results object version. | ||
* @property {Plugin[]} [markdownItPlugins] Additional plugins. | ||
*/ | ||
/** | ||
* markdown-it plugin. | ||
* | ||
* @typedef {Array} Plugin | ||
*/ | ||
/** | ||
* Function to pretty-print lint results. | ||
* | ||
* @callback ToStringCallback | ||
* @param {boolean} [ruleAliases] True to use rule aliases. | ||
* @returns {string} | ||
*/ | ||
/** | ||
* Lint results (for resultVersion 3). | ||
* | ||
* @typedef {Object.<string, LintError[]>} LintResults | ||
*/ | ||
// The following should be part of the LintResults typedef, but that causes | ||
// TypeScript to "forget" about the string map. | ||
// * @property {ToStringCallback} toString String representation. | ||
// https://github.com/microsoft/TypeScript/issues/34911 | ||
/** | ||
* Lint error. | ||
* | ||
* @typedef {Object} LintError | ||
* @property {number} lineNumber Line number (1-based). | ||
* @property {string[]} ruleNames Rule name(s). | ||
* @property {string} ruleDescription Rule description. | ||
* @property {string} ruleInformation Link to more information. | ||
* @property {string} errorDetail Detail about the error. | ||
* @property {string} errorContext Context for the error. | ||
* @property {number[]} errorRange Column number (1-based) and length. | ||
* @property {FixInfo} fixInfo Fix information. | ||
*/ | ||
/** | ||
* Fix information. | ||
* | ||
* @typedef {Object} FixInfo | ||
* @property {number} [editColumn] Column of the fix (1-based). | ||
* @property {number} [deleteCount] Count of characters to delete. | ||
* @property {string} [insertText] Text to insert (after deleting). | ||
*/ | ||
/** | ||
* Called with the result of the lint operation. | ||
* | ||
* @callback LintCallback | ||
* @param {Error | null} err Error object or null. | ||
* @param {LintResults} [results] Lint results. | ||
* @returns {void} | ||
*/ | ||
/** | ||
* Configuration object for linting rules. For a detailed schema, see | ||
* {@link ../schema/markdownlint-config-schema.json}. | ||
* | ||
* @typedef {Object.<string, RuleConfiguration>} Configuration | ||
*/ | ||
/** | ||
* Rule configuration object. | ||
* | ||
* @typedef {boolean | Object} RuleConfiguration Rule configuration. | ||
*/ | ||
/** | ||
* Parses a configuration string and returns a configuration object. | ||
* | ||
* @callback ConfigurationParser | ||
* @param {string} text Configuration string. | ||
* @returns {Configuration} | ||
*/ | ||
/** | ||
* Called with the result of the readConfig operation. | ||
* | ||
* @callback ReadConfigCallback | ||
* @param {Error | null} err Error object or null. | ||
* @param {Configuration} [config] Configuration object. | ||
* @returns {void} | ||
*/ |
@@ -17,14 +17,16 @@ // @ts-check | ||
if (list.unordered && !list.nesting && (list.indent !== 0)) { | ||
const { lineNumber, line } = list.open; | ||
addErrorDetailIf( | ||
onError, | ||
lineNumber, | ||
0, | ||
list.indent, | ||
null, | ||
null, | ||
rangeFromRegExp(line, listItemMarkerRe), | ||
{ | ||
"deleteCount": line.length - line.trimLeft().length | ||
}); | ||
list.items.forEach((item) => { | ||
const { lineNumber, line } = item; | ||
addErrorDetailIf( | ||
onError, | ||
lineNumber, | ||
0, | ||
list.indent, | ||
null, | ||
null, | ||
rangeFromRegExp(line, listItemMarkerRe), | ||
{ | ||
"deleteCount": line.length - line.trimLeft().length | ||
}); | ||
}); | ||
} | ||
@@ -31,0 +33,0 @@ }); |
@@ -5,3 +5,3 @@ // @ts-check | ||
const { addErrorDetailIf, listItemMarkerRe, rangeFromRegExp } = | ||
const { addErrorDetailIf, indentFor, listItemMarkerRe } = | ||
require("../helpers"); | ||
@@ -17,6 +17,28 @@ const { flattenedLists } = require("./cache"); | ||
flattenedLists().forEach((list) => { | ||
if (list.unordered && list.parentsUnordered && list.indent) { | ||
addErrorDetailIf(onError, list.open.lineNumber, | ||
list.parentIndent + optionsIndent, list.indent, null, null, | ||
rangeFromRegExp(list.open.line, listItemMarkerRe)); | ||
if (list.unordered && list.parentsUnordered) { | ||
list.items.forEach((item) => { | ||
const { lineNumber, line } = item; | ||
const expectedIndent = list.nesting * optionsIndent; | ||
const actualIndent = indentFor(item); | ||
let range = null; | ||
let editColumn = 1; | ||
const match = line.match(listItemMarkerRe); | ||
if (match) { | ||
range = [ 1, match[0].length ]; | ||
editColumn += match[1].length - actualIndent; | ||
} | ||
addErrorDetailIf( | ||
onError, | ||
lineNumber, | ||
expectedIndent, | ||
actualIndent, | ||
null, | ||
null, | ||
range, | ||
{ | ||
editColumn, | ||
"deleteCount": actualIndent, | ||
"insertText": "".padEnd(expectedIndent) | ||
}); | ||
}); | ||
} | ||
@@ -23,0 +45,0 @@ }); |
@@ -5,6 +5,10 @@ // @ts-check | ||
const { addError, filterTokens, forEachLine, includesSorted } = | ||
require("../helpers"); | ||
const { addError, filterTokens, forEachInlineCodeSpan, forEachLine, | ||
includesSorted, newLineRe } = require("../helpers"); | ||
const { lineMetadata } = require("./cache"); | ||
function numericSortAscending(a, b) { | ||
return a - b; | ||
} | ||
module.exports = { | ||
@@ -19,7 +23,6 @@ "names": [ "MD009", "no-trailing-spaces" ], | ||
} | ||
const listItemEmptyLines = params.config.list_item_empty_lines; | ||
const allowListItemEmptyLines = | ||
(listItemEmptyLines === undefined) ? false : !!listItemEmptyLines; | ||
const listItemEmptyLines = !!params.config.list_item_empty_lines; | ||
const strict = !!params.config.strict; | ||
const listItemLineNumbers = []; | ||
if (allowListItemEmptyLines) { | ||
if (listItemEmptyLines) { | ||
filterTokens(params, "list_item_open", (token) => { | ||
@@ -30,4 +33,26 @@ for (let i = token.map[0]; i < token.map[1]; i++) { | ||
}); | ||
listItemLineNumbers.sort((a, b) => a - b); | ||
listItemLineNumbers.sort(numericSortAscending); | ||
} | ||
const paragraphLineNumbers = []; | ||
const codeInlineLineNumbers = []; | ||
if (strict) { | ||
filterTokens(params, "paragraph_open", (token) => { | ||
for (let i = token.map[0]; i < token.map[1] - 1; i++) { | ||
paragraphLineNumbers.push(i + 1); | ||
} | ||
}); | ||
paragraphLineNumbers.sort(numericSortAscending); | ||
filterTokens(params, "inline", (token) => { | ||
if (token.children.some((child) => child.type === "code_inline")) { | ||
const tokenLines = params.lines.slice(token.map[0], token.map[1]); | ||
forEachInlineCodeSpan(tokenLines.join("\n"), (code, lineIndex) => { | ||
const codeLineCount = code.split(newLineRe).length; | ||
for (let i = 0; i < codeLineCount; i++) { | ||
codeInlineLineNumbers.push(token.lineNumber + lineIndex + i); | ||
} | ||
}); | ||
} | ||
}); | ||
codeInlineLineNumbers.sort(numericSortAscending); | ||
} | ||
const expected = (brSpaces < 2) ? 0 : brSpaces; | ||
@@ -41,3 +66,6 @@ let inFencedCode = 0; | ||
!includesSorted(listItemLineNumbers, lineNumber)) { | ||
if (expected !== trailingSpaces) { | ||
if ((expected !== trailingSpaces) || | ||
(strict && | ||
(!includesSorted(paragraphLineNumbers, lineNumber) || | ||
includesSorted(codeInlineLineNumbers, lineNumber)))) { | ||
const column = line.length - trailingSpaces + 1; | ||
@@ -44,0 +72,0 @@ addError( |
@@ -6,7 +6,8 @@ // @ts-check | ||
const { addErrorDetailIf, filterTokens, forEachHeading, forEachLine, | ||
includesSorted, rangeFromRegExp } = require("../helpers"); | ||
includesSorted } = require("../helpers"); | ||
const { lineMetadata } = require("./cache"); | ||
const longLineRePrefix = "^(.{"; | ||
const longLineRePostfix = "})(.*\\s.*)$"; | ||
const longLineRePrefix = "^.{"; | ||
const longLineRePostfixRelaxed = "}.*\\s.*$"; | ||
const longLineRePostfixStrict = "}.+$"; | ||
const labelRe = /^\s*\[.*[^\\]]:/; | ||
@@ -32,2 +33,5 @@ const linkOnlyLineRe = /^[es]*lT?L[ES]*$/; | ||
const codeLineLength = params.config.code_block_line_length || lineLength; | ||
const strict = !!params.config.strict; | ||
const longLineRePostfix = | ||
strict ? longLineRePostfixStrict : longLineRePostfixRelaxed; | ||
const longLineRe = | ||
@@ -76,7 +80,14 @@ new RegExp(longLineRePrefix + lineLength + longLineRePostfix); | ||
(includeHeadings || !isHeading) && | ||
!includesSorted(linkOnlyLineNumbers, lineNumber) && | ||
lengthRe.test(line) && | ||
!labelRe.test(line)) { | ||
addErrorDetailIf(onError, lineNumber, length, line.length, | ||
null, null, rangeFromRegExp(line, lengthRe)); | ||
(strict || | ||
(!includesSorted(linkOnlyLineNumbers, lineNumber) && | ||
!labelRe.test(line))) && | ||
lengthRe.test(line)) { | ||
addErrorDetailIf( | ||
onError, | ||
lineNumber, | ||
length, | ||
line.length, | ||
null, | ||
null, | ||
[ length + 1, line.length - length ]); | ||
} | ||
@@ -83,0 +94,0 @@ }); |
@@ -27,20 +27,22 @@ // @ts-check | ||
const [ { "length": matchLength }, { "length": actualSpaces } ] = match; | ||
let fixInfo = null; | ||
if ((expectedSpaces !== actualSpaces) && (line.length > matchLength)) { | ||
fixInfo = { | ||
"editColumn": matchLength - actualSpaces + 1, | ||
"deleteCount": actualSpaces, | ||
"insertText": "".padEnd(expectedSpaces) | ||
}; | ||
if (matchLength < line.length) { | ||
let fixInfo = null; | ||
if (expectedSpaces !== actualSpaces) { | ||
fixInfo = { | ||
"editColumn": matchLength - actualSpaces + 1, | ||
"deleteCount": actualSpaces, | ||
"insertText": "".padEnd(expectedSpaces) | ||
}; | ||
} | ||
addErrorDetailIf( | ||
onError, | ||
lineNumber, | ||
expectedSpaces, | ||
actualSpaces, | ||
null, | ||
null, | ||
[ 1, matchLength ], | ||
fixInfo | ||
); | ||
} | ||
addErrorDetailIf( | ||
onError, | ||
lineNumber, | ||
expectedSpaces, | ||
actualSpaces, | ||
null, | ||
null, | ||
[ 1, matchLength ], | ||
fixInfo | ||
); | ||
}); | ||
@@ -47,0 +49,0 @@ }); |
@@ -18,3 +18,2 @@ // @ts-check | ||
// Always paragraph_open/inline/paragraph_close, | ||
// omit (t.type === "inline") | ||
const children = t.children.filter(function notEmptyText(child) { | ||
@@ -21,0 +20,0 @@ return (child.type !== "text") || (child.content !== ""); |
@@ -53,3 +53,4 @@ // @ts-check | ||
require("./md046"), | ||
require("./md047") | ||
require("./md047"), | ||
require("./md048") | ||
]; | ||
@@ -56,0 +57,0 @@ rules.forEach((rule) => { |
{ | ||
"name": "markdownlint", | ||
"version": "0.17.2", | ||
"version": "0.18.0", | ||
"description": "A Node.js style checker and lint tool for Markdown/CommonMark files.", | ||
"main": "lib/markdownlint.js", | ||
"types": "lib/markdownlint.d.ts", | ||
"author": "David Anson (https://dlaa.me/)", | ||
@@ -17,7 +18,9 @@ "license": "MIT", | ||
"test-cover": "nyc --check-coverage --skip-full node_modules/nodeunit/bin/nodeunit test/markdownlint-test.js", | ||
"test-declaration": "cd example/typescript && tsc && node type-check.js", | ||
"test-extra": "nodeunit test/markdownlint-test-extra.js", | ||
"debug": "node debug node_modules/nodeunit/bin/nodeunit", | ||
"lint": "eslint lib helpers test schema && eslint --env browser --global markdownit --global markdownlint --rule \"no-unused-vars: 0, no-extend-native: 0, max-statements: 0, no-console: 0, no-var: 0\" demo && eslint --rule \"no-console: 0, no-invalid-this: 0, no-shadow: 0, object-property-newline: 0\" example", | ||
"ci": "npm run test && npm run lint && npm run test-cover", | ||
"ci": "npm run test && npm run lint && npm run test-cover && npm run test-declaration", | ||
"build-config-schema": "node schema/build-config-schema.js", | ||
"build-declaration": "tsc --allowJs --declaration --outDir declaration --resolveJsonModule lib/markdownlint.js && cpy declaration/lib/markdownlint.d.ts lib && rimraf declaration", | ||
"build-demo": "cpy node_modules/markdown-it/dist/markdown-it.min.js demo && cd demo && rimraf markdownlint-browser.* && cpy file-header.js . --rename=markdownlint-browser.js && tsc --allowJs --resolveJsonModule --outDir ../lib-es3 ../lib/markdownlint.js && cpy ../helpers/package.json ../lib-es3/helpers && browserify ../lib-es3/lib/markdownlint.js --standalone markdownlint >> markdownlint-browser.js && uglifyjs markdownlint-browser.js --compress --mangle --comments --output markdownlint-browser.min.js", | ||
@@ -34,7 +37,7 @@ "build-example": "npm install --no-save --ignore-scripts grunt grunt-cli gulp through2", | ||
"devDependencies": { | ||
"@types/node": "~12.7.11", | ||
"@types/node": "~12.12.17", | ||
"browserify": "~16.5.0", | ||
"cpy-cli": "~2.0.0", | ||
"eslint": "~6.5.1", | ||
"glob": "~7.1.4", | ||
"cpy-cli": "~3.0.0", | ||
"eslint": "~6.7.2", | ||
"glob": "~7.1.6", | ||
"js-yaml": "~3.13.1", | ||
@@ -45,3 +48,3 @@ "markdown-it-for-inline": "~0.1.1", | ||
"markdown-it-sup": "~1.0.0", | ||
"markdownlint-rule-helpers": "~0.4.0", | ||
"markdownlint-rule-helpers": "~0.5.0", | ||
"nodeunit": "~0.11.3", | ||
@@ -52,4 +55,4 @@ "nyc": "~14.1.1", | ||
"tv4": "~1.3.0", | ||
"typescript": "~3.6.3", | ||
"uglify-js": "~3.6.0" | ||
"typescript": "~3.7.3", | ||
"uglify-js": "~3.7.2" | ||
}, | ||
@@ -56,0 +59,0 @@ "keywords": [ |
@@ -6,3 +6,3 @@ # markdownlint | ||
[![npm version][npm-image]][npm-url] | ||
[![CI Status][devops-image]][devops-url] | ||
[![CI Status][ci-image]][ci-url] | ||
[![License][license-image]][license-url] | ||
@@ -94,2 +94,3 @@ | ||
* **[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 | ||
@@ -114,3 +115,3 @@ See [Rules.md](doc/Rules.md) for more details. | ||
* **bullet** - MD004, MD005, MD006, MD007, MD032 | ||
* **code** - MD014, MD031, MD038, MD040, MD046 | ||
* **code** - MD014, MD031, MD038, MD040, MD046, MD048 | ||
* **emphasis** - MD036, MD037 | ||
@@ -146,7 +147,7 @@ * **hard_tab** - MD010 | ||
below) to define the expected behavior for a set of inputs. To enable or disable | ||
rules within a file, add one of these markers to the appropriate place (HTML | ||
comments don't appear in the final markup): | ||
rules at a particular location within a file, add one of these markers to the | ||
appropriate place (HTML comments don't appear in the final markup): | ||
* Disable all rules unconditionally: `<!-- markdownlint-disable -->` | ||
* Enable all rules unconditionally: `<!-- markdownlint-enable -->` | ||
* Disable all rules: `<!-- markdownlint-disable -->` | ||
* Enable all rules: `<!-- markdownlint-enable -->` | ||
* Disable one or more rules by name: `<!-- markdownlint-disable MD001 MD005 -->` | ||
@@ -191,2 +192,12 @@ * Enable one or more rules by name: `<!-- markdownlint-enable MD001 MD005 -->` | ||
To apply changes to an entire file regardless of where the comment is located, | ||
the following syntax is supported: | ||
* Disable all rules: `<!-- markdownlint-disable-file -->` | ||
* Enable all rules: `<!-- markdownlint-enable-file -->` | ||
* Disable one or more rules by name: `<!-- markdownlint-disable-file MD001 -->` | ||
* Enable one or more rules by name: `<!-- markdownlint-enable-file MD001 -->` | ||
This can be used to "hide" `markdownlint` comments at the bottom of a file. | ||
## API | ||
@@ -817,8 +828,12 @@ | ||
* 0.17.2 - Improve MD020/MD033/MD044. | ||
* 0.18.0 - Add MD048/code-fence-style, add fix information for MD007/ul-indent, add | ||
`markdownlint-disable-file`/`markdownlint-enable-file` inline comments, add | ||
type declaration file (.d.ts) for TypeScript dependents, update schema, improve | ||
MD006/MD007/MD009/MD013/MD030, update dependencies. | ||
[npm-image]: https://img.shields.io/npm/v/markdownlint.svg | ||
[npm-url]: https://www.npmjs.com/package/markdownlint | ||
[devops-image]: https://img.shields.io/azure-devops/build/DavidAnson/5b2bff85-0fe6-47b4-a561-fa87be89f032/1/master.svg?label=tests | ||
[devops-url]: https://dev.azure.com/DavidAnson/markdownlint-ci/_build/latest?definitionId=1&branchName=master | ||
[ci-image]: https://github.com/DavidAnson/markdownlint/workflows/CI/badge.svg?branch=master | ||
[ci-url]: https://github.com/DavidAnson/markdownlint/actions?query=branch%3Amaster | ||
[license-image]: https://img.shields.io/npm/l/markdownlint.svg | ||
[license-url]: https://opensource.org/licenses/MIT |
@@ -0,1 +1,3 @@ | ||
// @ts-check | ||
"use strict"; | ||
@@ -21,2 +23,8 @@ | ||
"default": null | ||
}, | ||
"$schema": { | ||
"description": "JSON Schema URI (used by some editors)", | ||
"type": "string", | ||
"default": "https://raw.githubusercontent.com/DavidAnson/markdownlint" + | ||
"/master/schema/markdownlint-config-schema.json" | ||
} | ||
@@ -105,2 +113,7 @@ }, | ||
"default": false | ||
}, | ||
"strict": { | ||
"description": "Include unnecessary breaks", | ||
"type": "boolean", | ||
"default": false | ||
} | ||
@@ -163,2 +176,7 @@ }; | ||
"default": true | ||
}, | ||
"strict": { | ||
"description": "Strict length checking", | ||
"type": "boolean", | ||
"default": false | ||
} | ||
@@ -340,2 +358,16 @@ }; | ||
break; | ||
case "MD048": | ||
scheme.properties = { | ||
"style": { | ||
"description": "Code fence syle", | ||
"type": "string", | ||
"enum": [ | ||
"consistent", | ||
"backtick", | ||
"tilde" | ||
], | ||
"default": "consistent" | ||
} | ||
}; | ||
break; | ||
default: | ||
@@ -346,2 +378,3 @@ custom = false; | ||
if (custom) { | ||
// @ts-ignore | ||
scheme.type = [ "boolean", "object" ]; | ||
@@ -348,0 +381,0 @@ scheme.additionalProperties = false; |
@@ -15,2 +15,7 @@ { | ||
}, | ||
"$schema": { | ||
"description": "JSON Schema URI (used by some editors)", | ||
"type": "string", | ||
"default": "https://raw.githubusercontent.com/DavidAnson/markdownlint/master/schema/markdownlint-config-schema.json" | ||
}, | ||
"MD001": { | ||
@@ -266,2 +271,7 @@ "description": "MD001/heading-increment/header-increment - Heading levels should only increment by one level at a time", | ||
"default": false | ||
}, | ||
"strict": { | ||
"description": "Include unnecessary breaks", | ||
"type": "boolean", | ||
"default": false | ||
} | ||
@@ -288,2 +298,7 @@ }, | ||
"default": false | ||
}, | ||
"strict": { | ||
"description": "Include unnecessary breaks", | ||
"type": "boolean", | ||
"default": false | ||
} | ||
@@ -409,2 +424,7 @@ }, | ||
"default": true | ||
}, | ||
"strict": { | ||
"description": "Strict length checking", | ||
"type": "boolean", | ||
"default": false | ||
} | ||
@@ -456,2 +476,7 @@ }, | ||
"default": true | ||
}, | ||
"strict": { | ||
"description": "Strict length checking", | ||
"type": "boolean", | ||
"default": false | ||
} | ||
@@ -1347,2 +1372,44 @@ }, | ||
}, | ||
"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": { | ||
@@ -1399,3 +1466,3 @@ "description": "headings - MD001, MD002, MD003, MD018, MD019, MD020, MD021, MD022, MD023, MD024, MD025, MD026, MD036, MD041, MD043", | ||
"code": { | ||
"description": "code - MD014, MD031, MD038, MD040, MD046", | ||
"description": "code - MD014, MD031, MD038, MD040, MD046, MD048", | ||
"type": "boolean", | ||
@@ -1402,0 +1469,0 @@ "default": true |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
452920
64
10239
834