Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

markdownlint

Package Overview
Dependencies
Maintainers
1
Versions
70
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

markdownlint - npm Package Compare versions

Comparing version 0.18.0 to 0.19.0

188

doc/Rules.md

@@ -1,2 +0,1 @@

# Rules

@@ -45,2 +44,6 @@

Rationale: Headings represent the structure of a document and can be confusing
when skipped - especially for accessibility scenarios. More information:
<https://www.w3.org/WAI/tutorials/page-structure/headings/>.
<a name="md002"></a>

@@ -79,2 +82,5 @@

Rationale: The top level heading often acts as the title of a document. More
information: <https://cirosantilli.com/markdown-style-guide#top-level-header>.
<a name="md003"></a>

@@ -128,2 +134,4 @@

Rationale: Consistent formatting makes it easier to understand a document.
<a name="md004"></a>

@@ -174,2 +182,4 @@

Rationale: Consistent formatting makes it easier to understand a document.
<a name="md005"></a>

@@ -227,5 +237,7 @@

Rationale: Violations of this rule can lead to improperly rendered content.
<a name="md006"></a>
## MD006 - Consider starting bulleted lists at the beginning of the line
## ~~MD006 - Consider starting bulleted lists at the beginning of the line~~

@@ -255,8 +267,2 @@ Tags: bullet, ul, indentation

Rationale: Starting lists at the beginning of the line means that nested list
items can all be indented by the same amount when an editor's indent function
or the tab key is used to indent. Starting a list 1 space in means that the
indent of the first nested list is less than the indent of the second level (3
characters if you use 4 space tabs, or 1 character if you use 2 space tabs).
Note: This rule is triggered for the following scenario because the unordered

@@ -274,2 +280,8 @@ sublist is not recognized as such by the parser. Not being nested 3 characters

Rationale: Starting lists at the beginning of the line means that nested list
items can all be indented by the same amount when an editor's indent function
or the tab key is used to indent. Starting a list 1 space in means that the
indent of the first nested list is less than the indent of the second level (3
characters if you use 4 space tabs, or 1 character if you use 2 space tabs).
<a name="md007"></a>

@@ -283,3 +295,3 @@

Parameters: indent (number; default 2)
Parameters: indent, start_indented (number; default 2, boolean; default false)

@@ -303,16 +315,2 @@ This rule is triggered when list items are not indented by the configured

Rationale (2 space indent): indenting by 2 spaces allows the content of a
nested list to be in line with the start of the content of the parent list
when a single space is used after the list marker.
Rationale (4 space indent): Same indent as code blocks, simpler for editors to
implement. See
<https://www.cirosantilli.com/markdown-style-guide/#indentation-of-content-inside-lists> for more
information.
In addition, this is a compatibility issue with multi-markdown parsers, which
require a 4 space indents. See
<http://support.markedapp.com/discussions/problems/21-sub-lists-not-indenting>
for a description of the problem.
Note: This rule applies to a sublist only if its parent lists are all also

@@ -322,2 +320,14 @@ unordered (otherwise, extra indentation of ordered lists interferes with the

The `start_indented` parameter allows the first level of lists to be indented by
the configured number of spaces rather than starting at zero (the inverse of
MD006).
Rationale: Indenting by 2 spaces allows the content of a nested list to be in
line with the start of the content of the parent list when a single space is
used after the list marker. Indenting by 4 spaces is consistent with code blocks
and simpler for editors to implement. Additionally, this can be a compatibility
issue for multi-markdown parsers, which require a 4-space indents. More information:
<https://cirosantilli.com/markdown-style-guide#indentation-of-content-inside-lists>
and <http://support.markedapp.com/discussions/problems/21-sub-lists-not-indenting>.
<a name="md009"></a>

@@ -362,2 +372,5 @@

Rationale: Except when being used to create a line break, trailing whitespace
has no purpose and does not affect the rendering of content.
<a name="md010"></a>

@@ -397,2 +410,5 @@

Rationale: Hard tabs are often rendered inconsistently by different editors and
can be harder to work with than spaces.
<a name="md011"></a>

@@ -426,2 +442,4 @@

Rationale: Reversed links are not rendered as usable links.
<a name="md012"></a>

@@ -461,2 +479,5 @@

Rationale: Except in a code block, blank lines serve no purpose and do not
affect the rendering of content.
<a name="md013"></a>

@@ -492,2 +513,5 @@

Rationale: Extremely long lines can be difficult to work with in some editors.
More information: <https://cirosantilli.com/markdown-style-guide#line-wrapping>.
<a name="md014"></a>

@@ -502,3 +526,3 @@

This rule is triggered when there are code blocks showing shell commands to be
typed, and the shell commands are preceded by dollar signs ($):
typed, and *all* of the shell commands are preceded by dollar signs ($):

@@ -511,3 +535,3 @@ ```markdown

The dollar signs are unnecessary in the above situation, and should not be
The dollar signs are unnecessary in this situation, and should not be
included:

@@ -521,4 +545,3 @@

However, an exception is made when there is a need to distinguish between
typed commands and command output, as in the following example:
Showing output for commands preceded by dollar signs does not trigger this rule:

@@ -534,5 +557,14 @@ ```markdown

Rationale: it is easier to copy and paste and less noisy if the dollar signs
Because some commands do not produce output, it is not a violation if *some*
commands do not have output:
```markdown
$ mkdir test
mkdir: created directory 'test'
$ ls test
```
Rationale: It is easier to copy/paste and less noisy if the dollar signs
are omitted when they are not needed. See
<https://www.cirosantilli.com/markdown-style-guide/#dollar-signs-in-shell-code>
<https://cirosantilli.com/markdown-style-guide#dollar-signs-in-shell-code>
for more information.

@@ -566,2 +598,4 @@

Rationale: Violations of this rule can lead to improperly rendered content.
<a name="md019"></a>

@@ -593,2 +627,5 @@

Rationale: Extra space has no purpose and does not affect the rendering of
content.
<a name="md020"></a>

@@ -622,2 +659,4 @@

Rationale: Violations of this rule can lead to improperly rendered content.
<a name="md021"></a>

@@ -652,2 +691,5 @@

Rationale: Extra space has no purpose and does not affect the rendering of
content.
<a name="md022"></a>

@@ -687,6 +729,2 @@

Rationale: Aside from aesthetic reasons, some parsers, including kramdown, will
not parse headings that don't have a blank line before, and will parse them as
regular text.
The `lines_above` and `lines_below` parameters can be used to specify a different

@@ -698,2 +736,6 @@ number of blank lines (including 0) above or below each heading.

Rationale: Aside from aesthetic reasons, some parsers, including kramdown, will
not parse headings that don't have a blank line before, and will parse them as
regular text.
<a name="md023"></a>

@@ -753,6 +795,2 @@

Rationale: Some markdown parses generate anchors for headings based on the
heading name, and having headings with the same content can cause problems with
this.
If the parameter `siblings_only` (alternatively `allow_different_nesting`) is

@@ -774,2 +812,5 @@ set to `true`, heading duplication is allowed for non-sibling headings (common

Rationale: Some markdown parsers generate anchors for headings based on the
heading name; headings with the same content can cause problems with that.
<a name="md025"></a>

@@ -807,7 +848,2 @@

Rationale: A top level heading is an h1 on the first line of the file, and
serves as the title for the document. If this convention is in use, then there
can not be more than one title for the document, and the entire document
should be contained within this heading.
Note: The `level` parameter can be used to change the top level (ex: to h2) in

@@ -823,2 +859,7 @@ cases where an h1 is added externally.

Rationale: A top level heading is an h1 on the first line of the file, and
serves as the title for the document. If this convention is in use, then there
can not be more than one title for the document, and the entire document
should be contained within this heading.
<a name="md026"></a>

@@ -853,2 +894,5 @@

Rationale: Headings are not meant to be full sentences. More information:
<https://cirosantilli.com/markdown-style-guide#punctuation-at-the-end-of-headers>
<a name="md027"></a>

@@ -877,2 +921,4 @@

Rationale: Consistent formatting makes it easier to understand a document.
<a name="md028"></a>

@@ -980,2 +1026,4 @@

Rationale: Consistent formatting makes it easier to understand a document.
<a name="md030"></a>

@@ -1017,3 +1065,3 @@

For example, the style guide at
<https://www.cirosantilli.com/markdown-style-guide/#spaces-after-list-marker>
<https://cirosantilli.com/markdown-style-guide#spaces-after-list-marker>
specifies that 1 space after the list marker should be used if every item in

@@ -1053,2 +1101,4 @@ the list fits within a single paragraph, but to use 2 or 3 spaces (for ordered

Rationale: Violations of this rule can lead to improperly rendered content.
<a name="md031"></a>

@@ -1096,5 +1146,2 @@

Rationale: Aside from aesthetic reasons, some parsers, including kramdown, will
not parse fenced code blocks that don't have blank lines before and after them.
Set the `list_items` parameter to `false` to disable this rule for list items.

@@ -1104,2 +1151,5 @@ Disabling this behavior for lists can be useful if it is necessary to create a

Rationale: Aside from aesthetic reasons, some parsers, including kramdown, will
not parse fenced code blocks that don't have blank lines before and after them.
<a name="md032"></a>

@@ -1166,2 +1216,4 @@

Note: To allow specific HTML elements, use the 'allowed_elements' parameter.
Rationale: Raw HTML is allowed in markdown, but this rule is included for

@@ -1171,4 +1223,2 @@ those who want their documents to only include "pure" markdown, or for those

Note: To allow specific HTML elements, use the 'allowed_elements' parameter.
<a name="md034"></a>

@@ -1195,5 +1245,2 @@

Rationale: Without angle brackets, the URL isn't converted into a link in many
markdown parsers.
Note: if you do want a bare URL without it being converted into a link,

@@ -1207,2 +1254,5 @@ enclose it in a code block, otherwise in some markdown parsers it _will_ be

Rationale: Without angle brackets, the URL isn't converted into a link in many
markdown parsers.
<a name="md035"></a>

@@ -1250,2 +1300,4 @@

Rationale: Consistent formatting makes it easier to understand a document.
<a name="md036"></a>

@@ -1293,2 +1345,6 @@

Rationale: Using emphasis instead of a heading prevents tools from inferring
the structure of a document. More information:
<https://cirosantilli.com/markdown-style-guide#emphasis-vs-headers>.
<a name="md037"></a>

@@ -1364,2 +1420,4 @@

Rationale: Violations of this rule can lead to improperly rendered content.
<a name="md039"></a>

@@ -1385,2 +1443,4 @@

Rationale: Consistent formatting makes it easier to understand a document.
<a name="md040"></a>

@@ -1413,2 +1473,6 @@

Rationale: Specifying a language improves content rendering by using the
correct syntax highlighting for code. More information:
<https://cirosantilli.com/markdown-style-guide#option-code-fenced>.
<a name="md041"></a>

@@ -1448,2 +1512,5 @@

Rationale: The top level heading often acts as the title of a document. More
information: <https://cirosantilli.com/markdown-style-guide#top-level-header>.
<a name="md042"></a>

@@ -1481,2 +1548,4 @@

Rationale: Empty links do not lead anywhere and therefore don't function as links.
<a name="md043"></a>

@@ -1545,2 +1614,5 @@

Rationale: Projects may wish to enforce a consistent document structure across
a set of similar content.
<a name="md044"></a>

@@ -1572,2 +1644,4 @@

Rationale: Incorrect capitalization of proper names is usually a mistake.
<a name="md045"></a>

@@ -1582,4 +1656,2 @@

This rule is triggered when an image is missing alternate text (alt text) information.
Alternate text is important for accessibility, describing the content of an image for
people who may not be able to see it.

@@ -1606,2 +1678,5 @@ Alternate text is commonly specified inline as:

Rationale: Alternate text is important for accessibility and describes the
content of an image for people who may not be able to see it.
<a name="md046"></a>

@@ -1639,2 +1714,4 @@

Rationale: Consistent formatting makes it easier to understand a document.
<a name="md047"></a>

@@ -1667,2 +1744,5 @@

Rationale: Some programs have trouble with files that do not end with a newline.
More information: <https://unix.stackexchange.com/questions/18743/whats-the-point-in-adding-a-new-line-to-the-end-of-a-file>.
<a name="md048"></a>

@@ -1705,1 +1785,3 @@

can require that usage be consistent within the document.
Rationale: Consistent formatting makes it easier to understand a document.

@@ -61,2 +61,13 @@ // @ts-check

/**
* Compare function for Array.prototype.sort for ascending order of numbers.
*
* @param {number} a First number.
* @param {number} b Second number.
* @returns {number} Positive value if a>b, negative value if b<a, 0 otherwise.
*/
module.exports.numericSortAscending = function numericSortAscending(a, b) {
return a - b;
};
// Returns true iff the sorted array contains the specified element

@@ -130,3 +141,24 @@ module.exports.includesSorted = function includesSorted(array, element) {

// Returns the indent for a token
/**
* Return the string representation of a fence markup character.
*
* @param {string} markup Fence string.
* @returns {string} String representation.
*/
module.exports.fencedCodeBlockStyleFor =
function fencedCodeBlockStyleFor(markup) {
switch (markup[0]) {
case "~":
return "tilde";
default:
return "backtick";
}
};
/**
* Return the number of characters of indent for a token.
*
* @param {Object} token MarkdownItToken instance.
* @returns {number} Characters of indent.
*/
function indentFor(token) {

@@ -149,3 +181,28 @@ const line = token.line.replace(/^[\s>]*(> |>)/, "");

// Calls the provided function for each matching token
/**
* Return the string representation of an unordered list marker.
*
* @param {Object} token MarkdownItToken instance.
* @returns {string} String representation.
*/
module.exports.unorderedListStyleFor = function unorderedListStyleFor(token) {
switch (token.markup) {
case "-":
return "dash";
case "+":
return "plus";
// case "*":
default:
return "asterisk";
}
};
/**
* Calls the provided function for each matching token.
*
* @param {Object} params RuleParams instance.
* @param {string} type Token type identifier.
* @param {Function} handler Callback function.
* @returns {void}
*/
function filterTokens(params, type, handler) {

@@ -344,3 +401,13 @@ params.tokens.forEach(function forToken(token) {

// Adds a generic error object via the onError callback
/**
* Adds a generic error object via the onError callback.
*
* @param {Object} onError RuleOnError instance.
* @param {number} lineNumber Line number.
* @param {string} [detail] Error details.
* @param {string} [context] Error context.
* @param {number[]} [range] Column and length of error.
* @param {Object} [fixInfo] RuleOnErrorFixInfo instance.
* @returns {void}
*/
function addError(onError, lineNumber, detail, context, range, fixInfo) {

@@ -405,3 +472,3 @@ onError({

const frontMatterTitleRe =
new RegExp(frontMatterTitlePattern || "^\\s*title\\s*[:=]", "i");
new RegExp(String(frontMatterTitlePattern || "^\\s*title\\s*[:=]"), "i");
return !ignoreFrontMatter &&

@@ -411,3 +478,8 @@ frontMatterLines.some((line) => frontMatterTitleRe.test(line));

// Gets the most common line ending, falling back to platform default
/**
* Gets the most common line ending, falling back to the platform default.
*
* @param {string} input Markdown content to analyze.
* @returns {string} Preferred line ending.
*/
function getPreferredLineEnding(input) {

@@ -446,3 +518,9 @@ let cr = 0;

// Normalizes the fields of a fixInfo object
/**
* Normalizes the fields of a RuleOnErrorFixInfo instance.
*
* @param {Object} fixInfo RuleOnErrorFixInfo instance.
* @param {number} [lineNumber] Line number.
* @returns {Object} Normalized RuleOnErrorFixInfo instance.
*/
function normalizeFixInfo(fixInfo, lineNumber) {

@@ -457,3 +535,10 @@ return {

// Fixes the specifide error on a line
/**
* Fixes the specified error on a line of Markdown content.
*
* @param {string} line Line of Markdown content.
* @param {Object} fixInfo RuleOnErrorFixInfo instance.
* @param {string} lineEnding Line ending to use.
* @returns {string} Fixed content.
*/
function applyFix(line, fixInfo, lineEnding) {

@@ -460,0 +545,0 @@ const { editColumn, deleteCount, insertText } = normalizeFixInfo(fixInfo);

{
"name": "markdownlint-rule-helpers",
"version": "0.6.0",
"version": "0.7.0",
"description": "A collection of markdownlint helper functions for custom rules",

@@ -5,0 +5,0 @@ "main": "helpers.js",

@@ -77,7 +77,8 @@ export = markdownlint;

* @param {string} file Configuration file name.
* @param {ConfigurationParser[] | null} parsers Parsing function(s).
* @param {ReadConfigCallback} callback Callback (err, result) function.
* @param {ConfigurationParser[] | ReadConfigCallback} parsers Parsing
* function(s).
* @param {ReadConfigCallback} [callback] Callback (err, result) function.
* @returns {void}
*/
declare function readConfig(file: string, parsers: ConfigurationParser[], callback: ReadConfigCallback): void;
declare function readConfig(file: string, parsers: ConfigurationParser[] | ReadConfigCallback, callback?: ReadConfigCallback): void;
/**

@@ -84,0 +85,0 @@ * Read specified configuration file synchronously.

@@ -13,5 +13,11 @@ // @ts-check

const deprecatedRuleNames = [ "MD002" ];
const deprecatedRuleNames = [ "MD002", "MD006" ];
// Validates the list of rules for structure and reuse
/**
* Validate the list of rules for structure and reuse.
*
* @param {Rule[]} ruleList List of rules.
* @returns {string} Error message if validation fails.
*/
function validateRuleList(ruleList) {

@@ -26,2 +32,3 @@ let result = null;

const customIndex = index - rules.length;
// eslint-disable-next-line jsdoc/require-jsdoc
function newError(property) {

@@ -77,4 +84,10 @@ return new Error(

// Class for results with toString for pretty display
/**
* Creates a LintResults instance with toString for pretty display.
*
* @param {Rule[]} ruleList List of rules.
* @returns {LintResults} New LintResults instance.
*/
function newResults(ruleList) {
// eslint-disable-next-line jsdoc/require-jsdoc
function Results() {}

@@ -129,6 +142,13 @@ Results.prototype.toString = function toString(useAlias) {

};
// @ts-ignore
return new Results();
}
// Remove front matter (if present at beginning of content)
/**
* Remove front matter (if present at beginning of content).
*
* @param {string} content Markdown content.
* @param {RegExp} frontMatter Regular expression to match front matter.
* @returns {Object} Trimmed content and front matter lines.
*/
function removeFrontMatter(content, frontMatter) {

@@ -154,3 +174,9 @@ let frontMatterLines = [];

// Annotate tokens with line/lineNumber
/**
* Annotate tokens with line/lineNumber.
*
* @param {MarkdownItToken[]} tokens Array of markdown-it tokens.
* @param {string[]} lines Lines of Markdown content.
* @returns {void}
*/
function annotateTokens(tokens, lines) {

@@ -200,3 +226,8 @@ let tbodyMap = null;

// Map rule names/tags to canonical rule name
/**
* Map rule names/tags to canonical rule name.
*
* @param {Rule[]} ruleList List of rules.
* @returns {Object.<string, string[]>} Map of alias to rule name.
*/
function mapAliasToRuleNames(ruleList) {

@@ -228,6 +259,15 @@ const aliasToRuleNames = {};

// });
// @ts-ignore
return aliasToRuleNames;
}
// Apply (and normalize) config
/**
* Apply (and normalize) configuration object.
*
* @param {Rule[]} ruleList List of rules.
* @param {Configuration} config Configuration object.
* @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule
* names.
* @returns {Configuration} Effective configuration.
*/
function getEffectiveConfig(ruleList, config, aliasToRuleNames) {

@@ -263,6 +303,21 @@ const defaultKey = Object.keys(config).filter(

// Create mapping of enabled rules per line
/**
* Create a mapping of enabled rules per line.
*
* @param {Rule[]} ruleList List of rules.
* @param {string[]} lines List of content lines.
* @param {string[]} frontMatterLines List of front matter lines.
* @param {boolean} noInlineConfig Whether to allow inline configuration.
* @param {Configuration} effectiveConfig Effective configuration.
* @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule
* names.
* @returns {Object.<string, RuleConfiguration>[]} Enabled rules for each line.
*/
function getEnabledRulesPerLineNumber(
ruleList, lines, frontMatterLines, noInlineConfig,
effectiveConfig, aliasToRuleNames) {
ruleList,
lines,
frontMatterLines,
noInlineConfig,
effectiveConfig,
aliasToRuleNames) {
let enabledRules = {};

@@ -276,2 +331,3 @@ const allRuleNames = [];

let capturedRules = enabledRules;
// eslint-disable-next-line jsdoc/require-jsdoc
function forMatch(match, byLine) {

@@ -324,3 +380,9 @@ const action = match[1].toUpperCase();

// Array.sort comparison for objects in errors array
/**
* Compare function for Array.prototype.sort for ascending order of errors.
*
* @param {LintError} a First error.
* @param {LintError} b Second error.
* @returns {number} Positive value if a>b, negative value if b<a, 0 otherwise.
*/
function lineNumberComparison(a, b) {

@@ -330,3 +392,7 @@ return a.lineNumber - b.lineNumber;

// Function to return true for all inputs
/**
* Filter function to include everything.
*
* @returns {boolean} True.
*/
function filterAllValues() {

@@ -336,3 +402,10 @@ return true;

// Function to return unique values from a sorted errors array
/**
* Function to return unique values from a sorted errors array.
*
* @param {LintError} value Error instance.
* @param {number} index Index in array.
* @param {LintError[]} array Array of errors.
* @returns {boolean} Filter value.
*/
function uniqueFilterForSortedErrors(value, index, array) {

@@ -342,3 +415,17 @@ return (index === 0) || (value.lineNumber > array[index - 1].lineNumber);

// Lints a single string
/**
* Lints a string containing Markdown content.
*
* @param {Rule[]} ruleList List of rules.
* @param {string} name Identifier for the content.
* @param {string} content Markdown content
* @param {Object} md markdown-it instance.
* @param {Configuration} config Configuration object.
* @param {RegExp} frontMatter Regular expression for front matter.
* @param {boolean} handleRuleFailures Whether to handle exceptions in rules.
* @param {boolean} noInlineConfig Whether to allow inline configuration.
* @param {number} resultVersion Version of the LintResults object to return.
* @param {Function} callback Callback (err, result) function.
* @returns {void}
*/
function lintContent(

@@ -383,2 +470,3 @@ ruleList,

const result = (resultVersion === 0) ? {} : [];
// eslint-disable-next-line jsdoc/require-jsdoc
function forRule(rule) {

@@ -389,2 +477,3 @@ // Configure rule

params.config = effectiveConfig[ruleName];
// eslint-disable-next-line jsdoc/require-jsdoc
function throwError(property) {

@@ -395,2 +484,3 @@ throw new Error(

const errors = [];
// eslint-disable-next-line jsdoc/require-jsdoc
function onError(errorInfo) {

@@ -467,3 +557,3 @@ if (!errorInfo ||

"context": errorInfo.context || null,
"range": errorInfo.range || null,
"range": errorInfo.range ? [ ...errorInfo.range ] : null,
"fixInfo": fixInfo ? cleanFixInfo : null

@@ -538,3 +628,17 @@ });

// Lints a single file
/**
* Lints a file containing Markdown content.
*
* @param {Rule[]} ruleList List of rules.
* @param {string} file Path of file to lint.
* @param {Object} md markdown-it instance.
* @param {Configuration} config Configuration object.
* @param {RegExp} frontMatter Regular expression for front matter.
* @param {boolean} handleRuleFailures Whether to handle exceptions in rules.
* @param {boolean} noInlineConfig Whether to allow inline configuration.
* @param {number} resultVersion Version of the LintResults object to return.
* @param {boolean} synchronous Whether to execute synchronously.
* @param {Function} callback Callback (err, result) function.
* @returns {void}
*/
function lintFile(

@@ -551,2 +655,3 @@ ruleList,

callback) {
// eslint-disable-next-line jsdoc/require-jsdoc
function lintContentWrapper(err, content) {

@@ -567,3 +672,10 @@ if (err) {

// Lints files and strings
/**
* Lint files and strings specified in the Options object.
*
* @param {Options} options Options object.
* @param {boolean} synchronous Whether to execute synchronously.
* @param {Function} callback Callback (err, result) function.
* @returns {void}
*/
function lintInput(options, synchronous, callback) {

@@ -602,5 +714,7 @@ // Normalize inputs

/* eslint-disable consistent-return */
// 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) {

@@ -676,3 +790,10 @@ if (err) {

// Parses the content of a configuration file
/**
* Parse the content of a configuration file.
*
* @param {string} name Name of the configuration file.
* @param {string} content Configuration content.
* @param {ConfigurationParser[]} parsers Parsing function(s).
* @returns {Object} Configuration object and error message.
*/
function parseConfiguration(name, content, parsers) {

@@ -706,4 +827,5 @@ let config = null;

* @param {string} file Configuration file name.
* @param {ConfigurationParser[] | null} parsers Parsing function(s).
* @param {ReadConfigCallback} callback Callback (err, result) function.
* @param {ConfigurationParser[] | ReadConfigCallback} parsers Parsing
* function(s).
* @param {ReadConfigCallback} [callback] Callback (err, result) function.
* @returns {void}

@@ -723,2 +845,3 @@ */

// Try to parse file
// @ts-ignore
const { config, message } = parseConfiguration(file, content, parsers);

@@ -725,0 +848,0 @@ if (!config) {

@@ -12,3 +12,3 @@ // @ts-check

"function": function MD002(params, onError) {
const level = params.config.level || 1;
const level = Number(params.config.level || 1);
const tag = "h" + level;

@@ -15,0 +15,0 @@ params.tokens.every(function forToken(token) {

@@ -13,3 +13,3 @@ // @ts-check

"function": function MD003(params, onError) {
let style = params.config.style || "consistent";
let style = String(params.config.style || "consistent");
filterTokens(params, "heading_open", function forToken(token) {

@@ -16,0 +16,0 @@ const styleForToken = headingStyleFor(token);

@@ -6,18 +6,5 @@ // @ts-check

const { addErrorDetailIf, listItemMarkerRe,
rangeFromRegExp } = require("../helpers");
rangeFromRegExp, unorderedListStyleFor } = require("../helpers");
const { flattenedLists } = require("./cache");
// Returns the unordered list style for a list item token
function unorderedListStyleFor(token) {
switch (token.markup) {
case "-":
return "dash";
case "+":
return "plus";
// case "*":
default:
return "asterisk";
}
}
module.exports = {

@@ -28,3 +15,3 @@ "names": [ "MD004", "ul-style" ],

"function": function MD004(params, onError) {
const style = params.config.style || "consistent";
const style = String(params.config.style || "consistent");
let expectedStyle = style;

@@ -31,0 +18,0 @@ const nestingStyles = [];

@@ -20,11 +20,20 @@ // @ts-check

list.items.forEach((item) => {
const { line, lineNumber } = item;
const actualIndent = indentFor(item);
if (list.unordered) {
addErrorDetailIf(onError, item.lineNumber,
expectedIndent, actualIndent, null, null,
rangeFromRegExp(item.line, listItemMarkerRe));
addErrorDetailIf(
onError,
lineNumber,
expectedIndent,
actualIndent,
null,
null,
rangeFromRegExp(line, listItemMarkerRe)
// No fixInfo; MD007 handles this scenario better
);
} else {
const match = orderedListItemMarkerRe.exec(item.line);
actualEnd = match && match[0].length;
const match = orderedListItemMarkerRe.exec(line);
actualEnd = match[0].length;
expectedEnd = expectedEnd || actualEnd;
const markerLength = match[1].length + 1;
if ((expectedIndent !== actualIndent) || endMatching) {

@@ -37,4 +46,20 @@ if (expectedEnd === actualEnd) {

`Expected: ${expectedIndent}; Actual: ${actualIndent}`;
addError(onError, item.lineNumber, detail, null,
rangeFromRegExp(item.line, listItemMarkerRe));
const expected = endMatching ?
expectedEnd - markerLength :
expectedIndent;
const actual = endMatching ?
actualEnd - markerLength :
actualIndent;
addError(
onError,
lineNumber,
detail,
null,
rangeFromRegExp(line, listItemMarkerRe),
{
"editColumn": Math.min(actual, expected) + 1,
"deleteCount": Math.max(actual - expected, 0),
"insertText": "".padEnd(Math.max(expected - actual, 0))
}
);
}

@@ -41,0 +66,0 @@ }

@@ -14,3 +14,4 @@ // @ts-check

"function": function MD007(params, onError) {
const optionsIndent = params.config.indent || 2;
const indent = Number(params.config.indent || 2);
const startIndented = !!params.config.start_indented;
flattenedLists().forEach((list) => {

@@ -20,3 +21,4 @@ if (list.unordered && list.parentsUnordered) {

const { lineNumber, line } = item;
const expectedIndent = list.nesting * optionsIndent;
const expectedNesting = list.nesting + (startIndented ? 1 : 0);
const expectedIndent = expectedNesting * indent;
const actualIndent = indentFor(item);

@@ -23,0 +25,0 @@ let range = null;

@@ -6,9 +6,5 @@ // @ts-check

const { addError, filterTokens, forEachInlineCodeSpan, forEachLine,
includesSorted, newLineRe } = require("../helpers");
includesSorted, newLineRe, numericSortAscending } = require("../helpers");
const { lineMetadata } = require("./cache");
function numericSortAscending(a, b) {
return a - b;
}
module.exports = {

@@ -20,5 +16,3 @@ "names": [ "MD009", "no-trailing-spaces" ],

let brSpaces = params.config.br_spaces;
if (brSpaces === undefined) {
brSpaces = 2;
}
brSpaces = Number((brSpaces === undefined) ? 2 : brSpaces);
const listItemEmptyLines = !!params.config.list_item_empty_lines;

@@ -25,0 +19,0 @@ const strict = !!params.config.strict;

@@ -13,3 +13,3 @@ // @ts-check

"function": function MD012(params, onError) {
const maximum = params.config.maximum || 1;
const maximum = Number(params.config.maximum || 1);
let count = 0;

@@ -16,0 +16,0 @@ forEachLine(lineMetadata(), (line, lineIndex, inCode) => {

@@ -13,6 +13,7 @@ // @ts-check

const labelRe = /^\s*\[.*[^\\]]:/;
const linkOnlyLineRe = /^[es]*lT?L[ES]*$/;
const linkOrImageOnlyLineRe = /^[es]*(lT?L|I)[ES]*$/;
const tokenTypeMap = {
"em_open": "e",
"em_close": "E",
"image": "I",
"link_open": "l",

@@ -30,5 +31,7 @@ "link_close": "L",

"function": function MD013(params, onError) {
const lineLength = params.config.line_length || 80;
const headingLineLength = params.config.heading_line_length || lineLength;
const codeLineLength = params.config.code_block_line_length || lineLength;
const lineLength = Number(params.config.line_length || 80);
const headingLineLength =
Number(params.config.heading_line_length || lineLength);
const codeLineLength =
Number(params.config.code_block_line_length || lineLength);
const strict = !!params.config.strict;

@@ -64,3 +67,3 @@ const longLineRePostfix =

});
if (linkOnlyLineRe.test(childTokenTypes)) {
if (linkOrImageOnlyLineRe.test(childTokenTypes)) {
linkOnlyLineNumbers.push(token.lineNumber);

@@ -67,0 +70,0 @@ }

@@ -9,20 +9,2 @@ // @ts-check

function addErrorIfPreviousWasCommand(onError, previous) {
if (previous) {
const { lineNumber, lineTrim, column, length } = previous;
addErrorContext(
onError,
lineNumber,
lineTrim,
null,
null,
[ column, length ],
{
"editColumn": column,
"deleteCount": length
}
);
}
}
module.exports = {

@@ -35,19 +17,36 @@ "names": [ "MD014", "commands-show-output" ],

filterTokens(params, type, (token) => {
let previous = null;
const margin = (token.type === "fence") ? 1 : 0;
const dollarInstances = [];
let allDollars = true;
for (let i = token.map[0] + margin; i < token.map[1] - margin; i++) {
const line = params.lines[i];
const lineTrim = line.trim();
const match = dollarCommandRe.exec(line);
if (!lineTrim || match) {
addErrorIfPreviousWasCommand(onError, previous);
if (lineTrim) {
const match = dollarCommandRe.exec(line);
if (match) {
const column = match[1].length + 1;
const length = match[2].length;
dollarInstances.push([ i, lineTrim, column, length ]);
} else {
allDollars = false;
}
}
previous = match ? {
"lineNumber": i + 1,
"lineTrim": lineTrim,
"column": match[1].length + 1,
"length": match[2].length
} : null;
}
addErrorIfPreviousWasCommand(onError, previous);
if (allDollars) {
dollarInstances.forEach((instance) => {
const [ i, lineTrim, column, length ] = instance;
addErrorContext(
onError,
i + 1,
lineTrim,
null,
null,
[ column, length ],
{
"editColumn": column,
"deleteCount": length
}
);
});
}
});

@@ -54,0 +53,0 @@ });

@@ -13,9 +13,5 @@ // @ts-check

let linesAbove = params.config.lines_above;
if (linesAbove === undefined) {
linesAbove = 1;
}
linesAbove = Number((linesAbove === undefined) ? 1 : linesAbove);
let linesBelow = params.config.lines_below;
if (linesBelow === undefined) {
linesBelow = 1;
}
linesBelow = Number((linesBelow === undefined) ? 1 : linesBelow);
const { lines } = params;

@@ -22,0 +18,0 @@ filterTokens(params, "heading_open", (token) => {

@@ -12,4 +12,4 @@ // @ts-check

"function": function MD024(params, onError) {
const siblingsOnly = params.config.siblings_only ||
params.config.allow_different_nesting || false;
const siblingsOnly = !!params.config.siblings_only ||
!!params.config.allow_different_nesting || false;
const knownContents = [ null, [] ];

@@ -16,0 +16,0 @@ let lastLevel = 1;

@@ -13,3 +13,3 @@ // @ts-check

"function": function MD025(params, onError) {
const level = params.config.level || 1;
const level = Number(params.config.level || 1);
const tag = "h" + level;

@@ -16,0 +16,0 @@ const foundFrontMatterTitle =

@@ -14,5 +14,4 @@ // @ts-check

let punctuation = params.config.punctuation;
if (punctuation === undefined) {
punctuation = allPunctuation;
}
punctuation =
String((punctuation === undefined) ? allPunctuation : punctuation);
const trailingPunctuationRe =

@@ -19,0 +18,0 @@ new RegExp("\\s*[" + escapeForRegExp(punctuation) + "]+$");

@@ -20,3 +20,3 @@ // @ts-check

"function": function MD029(params, onError) {
const style = params.config.style || "one_or_ordered";
const style = String(params.config.style || "one_or_ordered");
flattenedLists().forEach((list) => {

@@ -23,0 +23,0 @@ if (!list.unordered) {

@@ -13,6 +13,6 @@ // @ts-check

"function": function MD030(params, onError) {
const ulSingle = params.config.ul_single || 1;
const olSingle = params.config.ol_single || 1;
const ulMulti = params.config.ul_multi || 1;
const olMulti = params.config.ol_multi || 1;
const ulSingle = Number(params.config.ul_single || 1);
const olSingle = Number(params.config.ol_single || 1);
const ulMulti = Number(params.config.ul_multi || 1);
const olMulti = Number(params.config.ol_multi || 1);
flattenedLists().forEach((list) => {

@@ -19,0 +19,0 @@ const lineCount = list.lastLineIndex - list.open.map[0];

@@ -21,4 +21,5 @@ // @ts-check

"function": function MD033(params, onError) {
const allowedElements = (params.config.allowed_elements || [])
.map((element) => element.toLowerCase());
let allowedElements = params.config.allowed_elements;
allowedElements = Array.isArray(allowedElements) ? allowedElements : [];
allowedElements = allowedElements.map((element) => element.toLowerCase());
forEachLine(lineMetadata(), (line, lineIndex, inCode) => {

@@ -25,0 +26,0 @@ let match = null;

@@ -12,3 +12,3 @@ // @ts-check

"function": function MD035(params, onError) {
let style = params.config.style || "consistent";
let style = String(params.config.style || "consistent");
filterTokens(params, "hr", function forToken(token) {

@@ -15,0 +15,0 @@ const lineTrim = token.line.trim();

@@ -12,4 +12,7 @@ // @ts-check

"function": function MD036(params, onError) {
const punctuation = params.config.punctuation || allPunctuation;
let punctuation = params.config.punctuation;
punctuation =
String((punctuation === undefined) ? allPunctuation : punctuation);
const re = new RegExp("[" + punctuation + "]$");
// eslint-disable-next-line jsdoc/require-jsdoc
function base(token) {

@@ -16,0 +19,0 @@ if (token.type === "paragraph_open") {

@@ -12,3 +12,3 @@ // @ts-check

"function": function MD041(params, onError) {
const level = params.config.level || 1;
const level = Number(params.config.level || 1);
const tag = "h" + level;

@@ -15,0 +15,0 @@ const foundFrontMatterTitle =

@@ -14,3 +14,3 @@ // @ts-check

const requiredHeadings = params.config.headings || params.config.headers;
if (requiredHeadings) {
if (Array.isArray(requiredHeadings)) {
const levels = {};

@@ -17,0 +17,0 @@ [ 1, 2, 3, 4, 5, 6 ].forEach(function forLevel(level) {

@@ -13,3 +13,4 @@ // @ts-check

"function": function MD044(params, onError) {
const names = params.config.names || [];
let names = params.config.names;
names = Array.isArray(names) ? names : [];
const codeBlocks = params.config.code_blocks;

@@ -21,2 +22,3 @@ const includeCodeBlocks = (codeBlocks === undefined) ? true : !!codeBlocks;

const anyNameRe = new RegExp(namePattern, "gi");
// eslint-disable-next-line jsdoc/require-jsdoc
function forToken(token) {

@@ -23,0 +25,0 @@ const fenceOffset = (token.type === "fence") ? 1 : 0;

@@ -17,3 +17,3 @@ // @ts-check

"function": function MD046(params, onError) {
let expectedStyle = params.config.style || "consistent";
let expectedStyle = String(params.config.style || "consistent");
params.tokens

@@ -20,0 +20,0 @@ .filter((token) => token.type === "code_block" || token.type === "fence")

@@ -5,13 +5,4 @@ // @ts-check

const { addErrorDetailIf } = require("../helpers");
const { addErrorDetailIf, fencedCodeBlockStyleFor } = require("../helpers");
function fencedCodeBlockStyleFor(markup) {
switch (markup[0]) {
case "~":
return "tilde";
default:
return "backtick";
}
}
module.exports = {

@@ -22,3 +13,3 @@ "names": [ "MD048", "code-fence-style" ],

"function": function MD048(params, onError) {
const style = params.config.style || "consistent";
const style = String(params.config.style || "consistent");
let expectedStyle = style;

@@ -25,0 +16,0 @@ params.tokens

{
"name": "markdownlint",
"version": "0.18.0",
"version": "0.19.0",
"description": "A Node.js style checker and lint tool for Markdown/CommonMark files.",

@@ -16,9 +16,9 @@ "main": "lib/markdownlint.js",

"scripts": {
"test": "nodeunit test/markdownlint-test.js",
"test-cover": "nyc --check-coverage --skip-full node_modules/nodeunit/bin/nodeunit test/markdownlint-test.js",
"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-declaration": "cd example/typescript && tsc && node type-check.js",
"test-extra": "nodeunit test/markdownlint-test-extra.js",
"test-extra": "node 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 && npm run test-declaration",
"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",
"ci": "npm run test-cover && npm run lint && npm run test-declaration",
"build-config-schema": "node schema/build-config-schema.js",

@@ -31,3 +31,3 @@ "build-declaration": "tsc --allowJs --declaration --outDir declaration --resolveJsonModule lib/markdownlint.js && cpy declaration/lib/markdownlint.d.ts lib && rimraf declaration",

"engines": {
"node": ">=8"
"node": ">=10"
},

@@ -38,6 +38,8 @@ "dependencies": {

"devDependencies": {
"@types/node": "~12.12.17",
"@types/node": "~13.5.0",
"browserify": "~16.5.0",
"c8": "~7.0.1",
"cpy-cli": "~3.0.0",
"eslint": "~6.7.2",
"eslint": "~6.8.0",
"eslint-plugin-jsdoc": "~21.0.0",
"glob": "~7.1.6",

@@ -49,10 +51,9 @@ "js-yaml": "~3.13.1",

"markdown-it-sup": "~1.0.0",
"markdownlint-rule-helpers": "~0.5.0",
"nodeunit": "~0.11.3",
"nyc": "~14.1.1",
"markdownlint-rule-helpers": "~0.6.0",
"rimraf": "~3.0.0",
"tape": "~4.13.0",
"toml": "~3.0.0",
"tv4": "~1.3.0",
"typescript": "~3.7.3",
"uglify-js": "~3.7.2"
"typescript": "~3.7.5",
"uglify-js": "~3.7.6"
},

@@ -59,0 +60,0 @@ "keywords": [

@@ -55,3 +55,3 @@ # markdownlint

* **[MD005](doc/Rules.md#md005)** *list-indent* - Inconsistent indentation for list items at the same level
* **[MD006](doc/Rules.md#md006)** *ul-start-left* - Consider starting bulleted lists at the beginning of the line
* ~~**[MD006](doc/Rules.md#md006)** *ul-start-left* - Consider starting bulleted lists at the beginning of the line~~
* **[MD007](doc/Rules.md#md007)** *ul-indent* - Unordered list indentation

@@ -828,2 +828,6 @@ * **[MD009](doc/Rules.md#md009)** *no-trailing-spaces* - Trailing spaces

MD006/MD007/MD009/MD013/MD030, update dependencies.
* 0.19.0 - Remove support for end-of-life Node version 8, add fix information for
MD005/list-indent, improve MD007/MD013/MD014, deprecate MD006/ul-start-left, add
rationale for every rule, update test runner and code coverage, add more JSDoc
comments, update dependencies.

@@ -830,0 +834,0 @@ [npm-image]: https://img.shields.io/npm/v/markdownlint.svg

@@ -98,2 +98,7 @@ // @ts-check

"default": 2
},
"start_indented": {
"description": "Whether to indent the first level of the list",
"type": "boolean",
"default": false
}

@@ -100,0 +105,0 @@ };

@@ -233,2 +233,7 @@ {

"default": 2
},
"start_indented": {
"description": "Whether to indent the first level of the list",
"type": "boolean",
"default": false
}

@@ -250,2 +255,7 @@ },

"default": 2
},
"start_indented": {
"description": "Whether to indent the first level of the list",
"type": "boolean",
"default": false
}

@@ -252,0 +262,0 @@ },

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc