markdownlint
Advanced tools
Comparing version 0.20.4 to 0.21.0
@@ -26,3 +26,3 @@ # Contributing | ||
Tests should all pass on all platforms. | ||
The test runner is [nodeunit](https://www.npmjs.com/package/nodeunit) and test cases are located in `test/markdownlint-test.js`. | ||
The test runner is [tape](https://www.npmjs.com/package/tape) and test cases are located in `test/markdownlint-test*.js`. | ||
When running tests, `test/*.md` files are enumerated, linted, and fail if any violations are missing a corresponding `{MD###}` marker in the test file. | ||
@@ -36,4 +36,4 @@ For example, the line `### Heading {MD001}` is expected to trigger the rule `MD001`. | ||
Run code coverage before sending a pull request with `npm run test-cover`. | ||
Coverage should remain at 100%. | ||
Run a full continuous integration pass before sending a pull request via `npm run ci`. | ||
Code coverage should remain at 100%. | ||
@@ -47,4 +47,7 @@ Pull requests should contain a single commit. | ||
Include the text "(fixes #??)" at the end of the commit message so the pull request will be associated with the relevant issue. | ||
End commit messages with a period (`.`). | ||
Once accepted, the tag `fixed in next` will be added to the issue. | ||
When the commit is merged to the main branch during the release process, the issue will be closed automatically. | ||
(See [Closing issues using keywords](https://help.github.com/articles/closing-issues-using-keywords/) for details.) | ||
Thank you! |
# Custom Rules | ||
In addition to its built-in rules, `markdownlint` lets you enhance the linting experience by passing a list of custom rules using the [`options.customRules` property](../README.md#optionscustomrules). | ||
Custom rules can do everything the built-in rules can and are defined inline or imported from another package ([keyword `markdownlint-rule` on npm](https://www.npmjs.com/search?q=keywords:markdownlint-rule)). | ||
In addition to its built-in rules, `markdownlint` lets you enhance the linting experience by passing a list of custom rules using the | ||
[`options.customRules` property](../README.md#optionscustomrules). | ||
Custom rules can do everything the built-in rules can and are defined inline or imported from another package | ||
([keyword `markdownlint-rule` on npm](https://www.npmjs.com/search?q=keywords:markdownlint-rule)). | ||
Custom rules can be disabled, enabled, and customized using the same syntax as built-in rules. | ||
@@ -9,3 +11,4 @@ | ||
Rules are defined by a name (or multiple names), a description, an optional link to more information, one or more tags, and a function that implements the rule's behavior. | ||
Rules are defined by a name (or multiple names), a description, an optional link to more information, one or more tags, and a function that implements | ||
the rule's behavior. | ||
That function is called once for each file/string input and is passed the parsed input and a function to log any violations. | ||
@@ -16,4 +19,2 @@ | ||
```js | ||
const { URL } = require("url"); | ||
module.exports = { | ||
@@ -63,7 +64,8 @@ "names": [ "any-blockquote" ], | ||
- `editColumn` is an optional `Number` specifying the 1-based column number of the edit. | ||
- `deleteCount` is an optional `Number` specifying the count of characters to delete. | ||
- `deleteCount` is an optional `Number` specifying the number of characters to delete (the value `-1` is used to delete the line). | ||
- `insertText` is an optional `String` specifying the text to insert. `\n` is the platform-independent way to add | ||
a line break; line breaks should be added at the beginning of a line instead of at the end). | ||
The collection of helper functions shared by the built-in rules is available for use by custom rules in the [markdownlint-rule-helpers package](https://www.npmjs.com/package/markdownlint-rule-helpers). | ||
The collection of helper functions shared by the built-in rules is available for use by custom rules in the | ||
[markdownlint-rule-helpers package](https://www.npmjs.com/package/markdownlint-rule-helpers). | ||
@@ -76,3 +78,3 @@ ## Examples | ||
- Packages should export a single rule object or an `Array` of rule objects | ||
- [Custom rules from the Microsoft/vscode-docs-authoring repository](https://github.com/Microsoft/vscode-docs-authoring/tree/master/docs-markdown/markdownlint-custom-rules) | ||
- [Custom rules from the Microsoft/vscode-docs-authoring repository](https://github.com/microsoft/vscode-docs-authoring/tree/master/packages/docs-linting/markdownlint-custom-rules) | ||
- [Custom rules from the axibase/docs-util repository](https://github.com/axibase/docs-util/tree/master/linting-rules) | ||
@@ -79,0 +81,0 @@ - [Custom rules from the webhintio/hint repository](https://github.com/webhintio/hint/blob/master/scripts/lint-markdown.js) |
@@ -62,6 +62,6 @@ # Rules | ||
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: | ||
is triggered when the first heading in the document isn't a h1 heading: | ||
```markdown | ||
## This isn't an H1 heading | ||
## This isn't a H1 heading | ||
@@ -71,6 +71,6 @@ ### Another heading | ||
The first heading in the document should be an h1 heading: | ||
The first heading in the document should be a h1 heading: | ||
```markdown | ||
# Start with an H1 heading | ||
# Start with a H1 heading | ||
@@ -81,3 +81,3 @@ ## 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. | ||
cases where a h1 is added externally. | ||
@@ -394,2 +394,4 @@ Rationale: The top level heading often acts as the title of a document. More | ||
<!-- markdownlint-disable no-hard-tabs --> | ||
```markdown | ||
@@ -401,2 +403,4 @@ Some text | ||
<!-- markdownlint-enable no-hard-tabs --> | ||
Corrected example: | ||
@@ -496,4 +500,8 @@ | ||
<!-- markdownlint-disable line-length --> | ||
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)) | ||
<!-- markdownlint-enable line-length --> | ||
> If `headings` is not provided, `headers` (deprecated) will be used. | ||
@@ -549,2 +557,4 @@ | ||
<!-- markdownlint-disable commands-show-output --> | ||
```markdown | ||
@@ -556,2 +566,4 @@ $ ls | ||
<!-- markdownlint-enable commands-show-output --> | ||
The dollar signs are unnecessary in this situation, and should not be | ||
@@ -850,3 +862,3 @@ included: | ||
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 | ||
the file is a h1 heading), and more than one h1 heading is in use in the | ||
document: | ||
@@ -873,3 +885,3 @@ | ||
Note: The `level` parameter can be used to change the top level (ex: to h2) in | ||
cases where an h1 is added externally. | ||
cases where a h1 is added externally. | ||
@@ -883,3 +895,3 @@ If [YAML](https://en.wikipedia.org/wiki/YAML) front matter is present and contains | ||
Rationale: A top level heading is an h1 on the first line of the file, and | ||
Rationale: A top level heading is a h1 on the first line of the file, and | ||
serves as the title for the document. If this convention is in use, then there | ||
@@ -1060,4 +1072,7 @@ can not be more than one title for the document, and the entire document | ||
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: | ||
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: | ||
<!-- markdownlint-disable code-fence-style --> | ||
~~~markdown | ||
@@ -1085,2 +1100,4 @@ 1. First list | ||
<!-- markdownlint-enable code-fence-style --> | ||
Rationale: Consistent formatting makes it easier to understand a document. | ||
@@ -1582,3 +1599,3 @@ | ||
Note: The `level` parameter can be used to change the top level (ex: to h2) in cases | ||
where an h1 is added externally. | ||
where a h1 is added externally. | ||
@@ -1772,2 +1789,4 @@ If [YAML](https://en.wikipedia.org/wiki/YAML) front matter is present and contains a | ||
<!-- markdownlint-disable code-block-style --> | ||
Some text. | ||
@@ -1785,2 +1804,4 @@ | ||
<!-- markdownlint-enable code-block-style --> | ||
To fix violations of this rule, use a consistent style (either indenting or code fences). | ||
@@ -1787,0 +1808,0 @@ |
@@ -35,3 +35,3 @@ // @ts-check | ||
// readFile options for reading with the UTF-8 encoding | ||
module.exports.utf8Encoding = { "encoding": "utf8" }; | ||
module.exports.utf8Encoding = "utf8"; | ||
@@ -84,3 +84,3 @@ // All punctuation characters (normal and full-width) | ||
while (left <= right) { | ||
/* eslint-disable no-bitwise */ | ||
// eslint-disable-next-line no-bitwise | ||
const mid = (left + right) >> 1; | ||
@@ -87,0 +87,0 @@ if (array[mid] < element) { |
{ | ||
"name": "markdownlint-rule-helpers", | ||
"version": "0.11.0", | ||
"version": "0.12.0", | ||
"description": "A collection of markdownlint helper functions for custom rules", | ||
@@ -5,0 +5,0 @@ "main": "helpers.js", |
@@ -9,4 +9,4 @@ # markdownlint-rule-helpers | ||
[`markdownlint`](https://github.com/DavidAnson/markdownlint) offers a variety of built-in validation | ||
[rules](https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md) and supports the | ||
creation of [custom rules](https://github.com/DavidAnson/markdownlint/blob/master/doc/CustomRules.md). | ||
[rules](https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md) and supports the | ||
creation of [custom rules](https://github.com/DavidAnson/markdownlint/blob/main/doc/CustomRules.md). | ||
The internal rules share various helper functions; this package exposes those for reuse by custom rules. | ||
@@ -46,3 +46,3 @@ | ||
See also: [`markdownlint` built-in rule implementations](https://github.com/DavidAnson/markdownlint/tree/master/lib). | ||
See also: [`markdownlint` built-in rule implementations](https://github.com/DavidAnson/markdownlint/tree/main/lib). | ||
@@ -49,0 +49,0 @@ ## Tests |
@@ -11,3 +11,3 @@ export = markdownlint; | ||
declare namespace markdownlint { | ||
export { markdownlintSync as sync, readConfig, readConfigSync, RuleFunction, RuleParams, MarkdownItToken, RuleOnError, RuleOnErrorInfo, RuleOnErrorFixInfo, Rule, Options, Plugin, ToStringCallback, LintResults, LintError, FixInfo, LintCallback, Configuration, RuleConfiguration, ConfigurationParser, ReadConfigCallback }; | ||
export { markdownlintSync as sync, readConfig, readConfigSync, promises, RuleFunction, RuleParams, MarkdownItToken, RuleOnError, RuleOnErrorInfo, RuleOnErrorFixInfo, Rule, Options, Plugin, ToStringCallback, LintResults, LintError, FixInfo, LintCallback, Configuration, RuleConfiguration, ConfigurationParser, ReadConfigCallback }; | ||
} | ||
@@ -21,3 +21,3 @@ /** | ||
*/ | ||
files?: string | string[]; | ||
files?: string[] | string; | ||
/** | ||
@@ -32,9 +32,7 @@ * Strings to lint. | ||
*/ | ||
config?: { | ||
[x: string]: any; | ||
}; | ||
config?: Configuration; | ||
/** | ||
* Custom rules. | ||
*/ | ||
customRules?: Rule | Rule[]; | ||
customRules?: Rule[] | Rule; | ||
/** | ||
@@ -64,5 +62,3 @@ * Front matter pattern. | ||
*/ | ||
type LintCallback = (err: Error, results?: { | ||
[x: string]: LintError[]; | ||
}) => void; | ||
type LintCallback = (err: Error | null, results?: LintResults) => void; | ||
/** | ||
@@ -74,5 +70,3 @@ * Lint specified Markdown files synchronously. | ||
*/ | ||
declare function markdownlintSync(options: Options): { | ||
[x: string]: LintError[]; | ||
}; | ||
declare function markdownlintSync(options: Options): LintResults; | ||
/** | ||
@@ -95,5 +89,7 @@ * Read specified configuration file. | ||
*/ | ||
declare function readConfigSync(file: string, parsers?: ConfigurationParser[]): { | ||
[x: string]: any; | ||
}; | ||
declare function readConfigSync(file: string, parsers?: ConfigurationParser[]): Configuration; | ||
declare namespace promises { | ||
export { markdownlintPromise as markdownlint }; | ||
export { readConfigPromise as readConfig }; | ||
} | ||
/** | ||
@@ -126,3 +122,3 @@ * Function to implement rule logic. | ||
*/ | ||
config: any; | ||
config: RuleConfiguration; | ||
}; | ||
@@ -351,10 +347,21 @@ /** | ||
*/ | ||
type ConfigurationParser = (text: string) => { | ||
[x: string]: any; | ||
}; | ||
type ConfigurationParser = (text: string) => Configuration; | ||
/** | ||
* Called with the result of the readConfig operation. | ||
*/ | ||
type ReadConfigCallback = (err: Error, config?: { | ||
[x: string]: any; | ||
}) => void; | ||
type ReadConfigCallback = (err: Error | null, config?: Configuration) => void; | ||
/** | ||
* Lint specified Markdown files. | ||
* | ||
* @param {Options} options Configuration options. | ||
* @returns {Promise<LintResults>} Results object. | ||
*/ | ||
declare function markdownlintPromise(options: Options): Promise<LintResults>; | ||
/** | ||
* Read specified configuration file. | ||
* | ||
* @param {string} file Configuration file name. | ||
* @param {ConfigurationParser[]} [parsers] Parsing function(s). | ||
* @returns {Promise<Configuration>} Configuration object. | ||
*/ | ||
declare function readConfigPromise(file: string, parsers?: ConfigurationParser[]): Promise<Configuration>; |
@@ -7,3 +7,3 @@ // @ts-check | ||
const path = require("path"); | ||
const { URL } = require("url"); | ||
const util = require("util"); | ||
const markdownIt = require("markdown-it"); | ||
@@ -16,3 +16,2 @@ const rules = require("./rules"); | ||
/** | ||
@@ -91,10 +90,11 @@ * Validate the list of rules for structure and reuse. | ||
function newResults(ruleList) { | ||
const lintResults = {}; | ||
// eslint-disable-next-line jsdoc/require-jsdoc | ||
function Results() {} | ||
Results.prototype.toString = function toString(useAlias) { | ||
const that = this; | ||
function toString(useAlias) { | ||
let ruleNameToRule = null; | ||
const results = []; | ||
Object.keys(that).forEach(function forFile(file) { | ||
const fileResults = that[file]; | ||
const keys = Object.keys(lintResults); | ||
keys.sort(); | ||
keys.forEach(function forFile(file) { | ||
const fileResults = lintResults[file]; | ||
if (Array.isArray(fileResults)) { | ||
@@ -141,5 +141,6 @@ fileResults.forEach(function forResult(result) { | ||
return results.join("\n"); | ||
}; | ||
} | ||
Object.defineProperty(lintResults, "toString", { "value": toString }); | ||
// @ts-ignore | ||
return new Results(); | ||
return lintResults; | ||
} | ||
@@ -162,3 +163,3 @@ | ||
frontMatterLines = contentMatched.split(helpers.newLineRe); | ||
if (frontMatterLines.length && | ||
if ((frontMatterLines.length > 0) && | ||
(frontMatterLines[frontMatterLines.length - 1] === "")) { | ||
@@ -352,3 +353,4 @@ frontMatterLines.length--; | ||
}; | ||
} catch (ex) { | ||
// eslint-disable-next-line unicorn/prefer-optional-catch-binding | ||
} catch (error) { | ||
// Ignore parse errors for inline configuration | ||
@@ -469,3 +471,3 @@ } | ||
// Remove UTF-8 byte order marker (if present) | ||
content = content.replace(/^\ufeff/, ""); | ||
content = content.replace(/^\uFEFF/, ""); | ||
// Remove front matter | ||
@@ -593,6 +595,6 @@ const removeFrontMatterResult = removeFrontMatter(content, frontMatter); | ||
rule.function(params, onError); | ||
} catch (ex) { | ||
} catch (error) { | ||
onError({ | ||
"lineNumber": 1, | ||
"detail": `This rule threw an exception: ${ex.message}` | ||
"detail": `This rule threw an exception: ${error.message}` | ||
}); | ||
@@ -604,3 +606,3 @@ } | ||
// Record any errors (significant performance benefit from length check) | ||
if (errors.length) { | ||
if (errors.length > 0) { | ||
errors.sort(lineNumberComparison); | ||
@@ -637,3 +639,3 @@ const filteredErrors = errors | ||
}); | ||
if (filteredErrors.length) { | ||
if (filteredErrors.length > 0) { | ||
if (resultVersion === 0) { | ||
@@ -650,5 +652,5 @@ result[ruleNameFriendly] = filteredErrors; | ||
ruleList.forEach(forRule); | ||
} catch (ex) { | ||
} catch (error) { | ||
cache.clear(); | ||
return callback(ex); | ||
return callback(error); | ||
} | ||
@@ -695,2 +697,3 @@ cache.clear(); | ||
if (synchronous) { | ||
// @ts-ignore | ||
lintContentWrapper(null, fs.readFileSync(file, helpers.utf8Encoding)); | ||
@@ -741,49 +744,94 @@ } else { | ||
const results = newResults(ruleList); | ||
// Helper to lint the next string or file | ||
/* eslint-disable consistent-return */ | ||
let done = false; | ||
// Linting of strings is always synchronous | ||
let syncItem = null; | ||
// eslint-disable-next-line jsdoc/require-jsdoc | ||
function lintNextItem() { | ||
let iterating = true; | ||
let item = null; | ||
// eslint-disable-next-line jsdoc/require-jsdoc | ||
function lintNextItemCallback(err, result) { | ||
if (err) { | ||
iterating = false; | ||
return callback(err); | ||
} | ||
results[item] = result; | ||
return iterating || lintNextItem(); | ||
function syncCallback(err, result) { | ||
if (err) { | ||
done = true; | ||
return callback(err); | ||
} | ||
while (iterating) { | ||
if ((item = stringsKeys.shift())) { | ||
lintContent( | ||
ruleList, | ||
item, | ||
strings[item] || "", | ||
md, | ||
config, | ||
frontMatter, | ||
handleRuleFailures, | ||
noInlineConfig, | ||
resultVersion, | ||
lintNextItemCallback); | ||
} else if ((item = files.shift())) { | ||
iterating = synchronous; | ||
lintFile( | ||
ruleList, | ||
item, | ||
md, | ||
config, | ||
frontMatter, | ||
handleRuleFailures, | ||
noInlineConfig, | ||
resultVersion, | ||
synchronous, | ||
lintNextItemCallback); | ||
} else { | ||
return callback(null, results); | ||
} | ||
results[syncItem] = result; | ||
return null; | ||
} | ||
while (!done && (syncItem = stringsKeys.shift())) { | ||
lintContent( | ||
ruleList, | ||
syncItem, | ||
strings[syncItem] || "", | ||
md, | ||
config, | ||
frontMatter, | ||
handleRuleFailures, | ||
noInlineConfig, | ||
resultVersion, | ||
syncCallback | ||
); | ||
} | ||
if (synchronous) { | ||
// Lint files synchronously | ||
while (!done && (syncItem = files.shift())) { | ||
lintFile( | ||
ruleList, | ||
syncItem, | ||
md, | ||
config, | ||
frontMatter, | ||
handleRuleFailures, | ||
noInlineConfig, | ||
resultVersion, | ||
synchronous, | ||
syncCallback | ||
); | ||
} | ||
return done || callback(null, results); | ||
} | ||
return lintNextItem(); | ||
// Lint files asynchronously | ||
let concurrency = 0; | ||
// eslint-disable-next-line jsdoc/require-jsdoc | ||
function lintConcurrently() { | ||
const asyncItem = files.shift(); | ||
if (done) { | ||
// Nothing to do | ||
} else if (asyncItem) { | ||
concurrency++; | ||
lintFile( | ||
ruleList, | ||
asyncItem, | ||
md, | ||
config, | ||
frontMatter, | ||
handleRuleFailures, | ||
noInlineConfig, | ||
resultVersion, | ||
synchronous, | ||
(err, result) => { | ||
concurrency--; | ||
if (err) { | ||
done = true; | ||
return callback(err); | ||
} | ||
results[asyncItem] = result; | ||
lintConcurrently(); | ||
return null; | ||
} | ||
); | ||
} else if (concurrency === 0) { | ||
done = true; | ||
return callback(null, results); | ||
} | ||
return null; | ||
} | ||
// Testing on a Raspberry Pi 4 Model B with an artificial 5ms file access | ||
// delay suggests that a concurrency factor of 8 can eliminate the impact | ||
// of that delay (i.e., total time is the same as with no delay). | ||
lintConcurrently(); | ||
lintConcurrently(); | ||
lintConcurrently(); | ||
lintConcurrently(); | ||
lintConcurrently(); | ||
lintConcurrently(); | ||
lintConcurrently(); | ||
lintConcurrently(); | ||
return null; | ||
} | ||
@@ -802,3 +850,15 @@ | ||
const markdownlintPromisify = util.promisify(markdownlint); | ||
/** | ||
* Lint specified Markdown files. | ||
* | ||
* @param {Options} options Configuration options. | ||
* @returns {Promise<LintResults>} Results object. | ||
*/ | ||
function markdownlintPromise(options) { | ||
return markdownlintPromisify(options); | ||
} | ||
/** | ||
* Lint specified Markdown files synchronously. | ||
@@ -836,4 +896,4 @@ * | ||
config = parser(content); | ||
} catch (ex) { | ||
errors.push(ex.message); | ||
} catch (error) { | ||
errors.push(error.message); | ||
} | ||
@@ -898,3 +958,17 @@ return !config; | ||
const readConfigPromisify = util.promisify(readConfig); | ||
/** | ||
* Read specified configuration file. | ||
* | ||
* @param {string} file Configuration file name. | ||
* @param {ConfigurationParser[]} [parsers] Parsing function(s). | ||
* @returns {Promise<Configuration>} Configuration object. | ||
*/ | ||
function readConfigPromise(file, parsers) { | ||
// @ts-ignore | ||
return readConfigPromisify(file, parsers); | ||
} | ||
/** | ||
* Read specified configuration file synchronously. | ||
@@ -908,2 +982,3 @@ * | ||
// Read file | ||
// @ts-ignore | ||
const content = fs.readFileSync(file, helpers.utf8Encoding); | ||
@@ -930,6 +1005,10 @@ // Try to parse file | ||
// Export a/synchronous APIs | ||
// Export a/synchronous/Promise APIs | ||
markdownlint.sync = markdownlintSync; | ||
markdownlint.readConfig = readConfig; | ||
markdownlint.readConfigSync = readConfigSync; | ||
markdownlint.promises = { | ||
"markdownlint": markdownlintPromise, | ||
"readConfig": readConfigPromise | ||
}; | ||
module.exports = markdownlint; | ||
@@ -1053,7 +1132,4 @@ | ||
* @typedef {Object.<string, LintError[]>} LintResults | ||
* @property {ToStringCallback} toString String representation. | ||
*/ | ||
// 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 | ||
@@ -1060,0 +1136,0 @@ /** |
@@ -14,3 +14,3 @@ // @ts-check | ||
filterTokens(params, "heading_open", function forToken(token) { | ||
const level = parseInt(token.tag.slice(1), 10); | ||
const level = Number.parseInt(token.tag.slice(1), 10); | ||
if (prevLevel && (level > prevLevel)) { | ||
@@ -17,0 +17,0 @@ addErrorDetailIf(onError, token.lineNumber, |
@@ -16,3 +16,3 @@ // @ts-check | ||
forEachLine(lineMetadata(), (line, lineIndex, inCode) => { | ||
count = (inCode || line.trim().length) ? 0 : count + 1; | ||
count = (inCode || (line.trim().length > 0)) ? 0 : count + 1; | ||
if (maximum < count) { | ||
@@ -19,0 +19,0 @@ addErrorDetailIf( |
@@ -35,6 +35,6 @@ // @ts-check | ||
if (!emphasisLength) { | ||
content = content.trimStart(); | ||
content = content.trimLeft(); | ||
} | ||
if (!match) { | ||
content = content.trimEnd(); | ||
content = content.trimRight(); | ||
} | ||
@@ -41,0 +41,0 @@ const leftSpace = leftSpaceRe.test(content); |
@@ -34,2 +34,3 @@ // @ts-check | ||
rangeFromRegExp(child.line, emptyLinkRe)); | ||
emptyLink = false; | ||
} | ||
@@ -36,0 +37,0 @@ } else if (inLink) { |
@@ -20,2 +20,18 @@ // @ts-check | ||
const includeCodeBlocks = (codeBlocks === undefined) ? true : !!codeBlocks; | ||
// Text of automatic hyperlinks is implicitly a URL | ||
const autolinkText = new Set(); | ||
filterTokens(params, "inline", (token) => { | ||
let inAutoLink = false; | ||
token.children.forEach((child) => { | ||
const { info, type } = child; | ||
if ((type === "link_open") && (info === "auto")) { | ||
inAutoLink = true; | ||
} else if (type === "link_close") { | ||
inAutoLink = false; | ||
} else if ((type === "text") && inAutoLink) { | ||
autolinkText.add(child); | ||
} | ||
}); | ||
}); | ||
// For each proper name... | ||
names.forEach((name) => { | ||
@@ -30,5 +46,5 @@ const escapedName = escapeForRegExp(name); | ||
function forToken(token) { | ||
const fenceOffset = (token.type === "fence") ? 1 : 0; | ||
token.content.split(newLineRe) | ||
.forEach((line, index) => { | ||
if (!autolinkText.has(token)) { | ||
const fenceOffset = (token.type === "fence") ? 1 : 0; | ||
token.content.split(newLineRe).forEach((line, index) => { | ||
let match = null; | ||
@@ -70,2 +86,3 @@ while ((match = anyNameRe.exec(line)) !== null) { | ||
}); | ||
} | ||
} | ||
@@ -72,0 +89,0 @@ forEachInlineChild(params, "text", forToken); |
@@ -5,3 +5,2 @@ // @ts-check | ||
const { URL } = require("url"); | ||
const packageJson = require("../package.json"); | ||
@@ -8,0 +7,0 @@ const homepage = packageJson.homepage; |
{ | ||
"name": "markdownlint", | ||
"version": "0.20.4", | ||
"version": "0.21.0", | ||
"description": "A Node.js style checker and lint tool for Markdown/CommonMark files.", | ||
@@ -16,12 +16,11 @@ "main": "lib/markdownlint.js", | ||
"scripts": { | ||
"test": "node test/markdownlint-test.js", | ||
"test-cover": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 node test/markdownlint-test.js", | ||
"test": "tape test/markdownlint-test.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 tape test/markdownlint-test.js test/markdownlint-test-custom-rules.js test/markdownlint-test-helpers.js test/markdownlint-test-result-object.js test/markdownlint-test-scenarios.js", | ||
"test-declaration": "cd example/typescript && tsc && node type-check.js", | ||
"test-extra": "node test/markdownlint-test-extra.js", | ||
"debug": "node debug node_modules/nodeunit/bin/nodeunit", | ||
"lint": "eslint --max-warnings 0 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", | ||
"lint": "eslint --max-warnings 0 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, unicorn/prefer-add-event-listener: 0, unicorn/prefer-query-selector: 0, unicorn/prefer-replace-all: 0\" demo && eslint --rule \"no-console: 0, no-invalid-this: 0, no-shadow: 0, object-property-newline: 0, node/no-missing-require: 0, node/no-extraneous-require: 0\" example", | ||
"ci": "npm run test-cover && npm run lint && 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", | ||
"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 && browserify ../lib-es3/helpers/helpers.js --standalone helpers >> markdownlint-rule-helpers-browser.js && uglifyjs markdownlint-browser.js markdownlint-rule-helpers-browser.js --compress --mangle --comments --output markdownlint-browser.min.js", | ||
"build-example": "npm install --no-save --ignore-scripts grunt grunt-cli gulp through2", | ||
@@ -38,27 +37,29 @@ "example": "cd example && node standalone.js && grunt markdownlint --force && gulp markdownlint", | ||
"dependencies": { | ||
"markdown-it": "10.0.0" | ||
"markdown-it": "11.0.0" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "~13.11.1", | ||
"browserify": "~16.5.1", | ||
"c8": "~7.1.2", | ||
"cpy-cli": "~3.1.0", | ||
"eslint": "~6.8.0", | ||
"eslint-plugin-jsdoc": "~22.1.0", | ||
"globby": "~11.0.0", | ||
"js-yaml": "~3.13.1", | ||
"@types/node": "~14.6.4", | ||
"browserify": "~16.5.2", | ||
"c8": "~7.3.0", | ||
"cpy-cli": "~3.1.1", | ||
"eslint": "~7.8.1", | ||
"eslint-plugin-jsdoc": "~30.3.1", | ||
"eslint-plugin-node": "~11.1.0", | ||
"eslint-plugin-unicorn": "~21.0.0", | ||
"globby": "~11.0.1", | ||
"js-yaml": "~3.14.0", | ||
"make-dir-cli": "~2.0.0", | ||
"markdown-it-for-inline": "~0.1.1", | ||
"markdown-it-katex": "~2.0.3", | ||
"@iktakahiro/markdown-it-katex": "~4.0.0", | ||
"markdown-it-sub": "~1.0.0", | ||
"markdown-it-sup": "~1.0.0", | ||
"markdownlint-rule-helpers": "~0.7.0", | ||
"markdownlint-rule-helpers": "~0.11.0", | ||
"rimraf": "~3.0.2", | ||
"strip-json-comments": "~3.1.0", | ||
"tape": "~4.13.2", | ||
"tape-player": "~0.1.0", | ||
"strip-json-comments": "~3.1.1", | ||
"tape": "~5.0.1", | ||
"tape-player": "~0.1.1", | ||
"toml": "~3.0.0", | ||
"tv4": "~1.3.0", | ||
"typescript": "~3.8.3", | ||
"uglify-js": "~3.8.1" | ||
"typescript": "~4.0.2", | ||
"uglify-js": "~3.10.3" | ||
}, | ||
@@ -65,0 +66,0 @@ "keywords": [ |
@@ -37,2 +37,3 @@ # markdownlint | ||
* [markdownlint-cli command-line interface for Node.js](https://github.com/igorshubovych/markdownlint-cli) | ||
* [markdownlint-cli2 command-line interface for Node.js](https://github.com/DavidAnson/markdownlint-cli2) | ||
* GitHub | ||
@@ -238,3 +239,3 @@ * [GitHub Super-Linter Action](https://github.com/github/super-linter) | ||
Standard asynchronous interface: | ||
Standard asynchronous API: | ||
@@ -245,4 +246,4 @@ ```js | ||
* | ||
* @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} | ||
@@ -253,3 +254,3 @@ */ | ||
Synchronous interface (for build scripts, etc.): | ||
Synchronous API (for build scripts, etc.): | ||
@@ -260,4 +261,4 @@ ```js | ||
* | ||
* @param {Object} options Configuration options. | ||
* @returns {Object} Result object. | ||
* @param {Options} options Configuration options. | ||
* @returns {LintResults} Results object. | ||
*/ | ||
@@ -267,2 +268,15 @@ function markdownlint.sync(options) { ... } | ||
Promise API (in the `promises` namespace like Node.js's | ||
[`fs` Promises API](https://nodejs.org/api/fs.html#fs_fs_promises_api)): | ||
```js | ||
/** | ||
* Lint specified Markdown files. | ||
* | ||
* @param {Options} options Configuration options. | ||
* @returns {Promise<LintResults>} Results object. | ||
*/ | ||
function markdownlint(options) { ... } | ||
``` | ||
#### options | ||
@@ -281,3 +295,4 @@ | ||
Each array element should define a rule. Rules are typically exported by another | ||
package, but can be defined inline. | ||
package, but can be defined locally. Custom rules are identified by the | ||
[keyword `markdownlint-rule` on npm](https://www.npmjs.com/search?q=keywords:markdownlint-rule). | ||
@@ -526,3 +541,3 @@ Example: | ||
Asynchronous interface: | ||
Asynchronous API: | ||
@@ -533,5 +548,5 @@ ```js | ||
* | ||
* @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[] | ReadConfigCallback} parsers Parsing function(s). | ||
* @param {ReadConfigCallback} [callback] Callback (err, result) function. | ||
* @returns {void} | ||
@@ -542,3 +557,3 @@ */ | ||
Synchronous interface: | ||
Synchronous API: | ||
@@ -549,5 +564,5 @@ ```js | ||
* | ||
* @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. | ||
*/ | ||
@@ -557,2 +572,16 @@ function readConfigSync(file, parsers) { ... } | ||
Promise API (in the `promises` namespace like Node.js's | ||
[`fs` Promises API](https://nodejs.org/api/fs.html#fs_fs_promises_api)): | ||
```js | ||
/** | ||
* Read specified configuration file. | ||
* | ||
* @param {string} file Configuration file name. | ||
* @param {ConfigurationParser[]} [parsers] Parsing function(s). | ||
* @returns {Promise<Configuration>} Configuration object. | ||
*/ | ||
function readConfig(file, parsers) { ... } | ||
``` | ||
#### file | ||
@@ -800,3 +829,3 @@ | ||
* [ESLint](https://eslint.org/) ([Search repository](https://github.com/eslint/eslint/search?q=markdownlint)) | ||
* [Garden React Components](https://garden.zendesk.com/react-components/) ([Search repository](https://github.com/zendeskgarden/react-components/search?q=markdownlint)) | ||
* [Garden React Components](https://zendeskgarden.github.io/react-components/) ([Search repository](https://github.com/zendeskgarden/react-components/search?q=markdownlint)) | ||
* [MkDocs](https://www.mkdocs.org/) ([Search repository](https://github.com/mkdocs/mkdocs/search?q=markdownlint)) | ||
@@ -888,8 +917,12 @@ * [Mocha](https://mochajs.org/) ([Search repository](https://github.com/mochajs/mocha/search?q=markdownlint)) | ||
* 0.20.4 - Fix regression in MD037, improve MD034/MD044, improve documentation. | ||
* 0.21.0 - Lint concurrently for better performance (async only), add Promise-based APIs, | ||
update TypeScript declaration file, hide `toString` on `LintResults`, add ability | ||
to fix in browser demo, allow custom rules in `.markdownlint.json` schema, improve | ||
MD042/MD044, improve documentation, update dependencies. | ||
[npm-image]: https://img.shields.io/npm/v/markdownlint.svg | ||
[npm-url]: https://www.npmjs.com/package/markdownlint | ||
[ci-image]: https://github.com/DavidAnson/markdownlint/workflows/CI/badge.svg?branch=master | ||
[ci-url]: https://github.com/DavidAnson/markdownlint/actions?query=branch%3Amaster | ||
[ci-image]: https://github.com/DavidAnson/markdownlint/workflows/CI/badge.svg?branch=main | ||
[ci-url]: https://github.com/DavidAnson/markdownlint/actions?query=branch%3Amain | ||
[license-image]: https://img.shields.io/npm/l/markdownlint.svg | ||
[license-url]: https://opensource.org/licenses/MIT |
@@ -28,6 +28,11 @@ // @ts-check | ||
"default": "https://raw.githubusercontent.com/DavidAnson/markdownlint" + | ||
"/master/schema/markdownlint-config-schema.json" | ||
"/main/schema/markdownlint-config-schema.json" | ||
} | ||
}, | ||
"additionalProperties": false | ||
"additionalProperties": { | ||
"type:": [ | ||
"boolean", | ||
"object" | ||
] | ||
} | ||
}; | ||
@@ -34,0 +39,0 @@ const tags = {}; |
@@ -18,3 +18,3 @@ { | ||
"type": "string", | ||
"default": "https://raw.githubusercontent.com/DavidAnson/markdownlint/master/schema/markdownlint-config-schema.json" | ||
"default": "https://raw.githubusercontent.com/DavidAnson/markdownlint/main/schema/markdownlint-config-schema.json" | ||
}, | ||
@@ -1551,3 +1551,8 @@ "MD001": { | ||
}, | ||
"additionalProperties": false | ||
"additionalProperties": { | ||
"type:": [ | ||
"boolean", | ||
"object" | ||
] | ||
} | ||
} |
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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
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
915
468702
24
10652
7
+ Addedlinkify-it@3.0.3(transitive)
+ Addedmarkdown-it@11.0.0(transitive)
- Removedlinkify-it@2.2.0(transitive)
- Removedmarkdown-it@10.0.0(transitive)
Updatedmarkdown-it@11.0.0