Convert var to const/let (except in browser-only code).

This commit is contained in:
David Anson 2018-04-27 22:05:34 -07:00
parent 78c1af7bfd
commit 213aef4564
56 changed files with 524 additions and 518 deletions

View file

@ -1,5 +1,8 @@
{ {
"parser": "espree", "parser": "espree",
"parserOptions": {
"ecmaVersion": 6
},
"env": { "env": {
"node": true "node": true
}, },
@ -203,7 +206,7 @@
"no-useless-escape": "error", "no-useless-escape": "error",
"no-useless-rename": "error", "no-useless-rename": "error",
"no-useless-return": "error", "no-useless-return": "error",
"no-var": "off", "no-var": "error",
"no-void": "error", "no-void": "error",
"no-warning-comments": "error", "no-warning-comments": "error",
"no-whitespace-before-property": "error", "no-whitespace-before-property": "error",
@ -220,7 +223,7 @@
"padded-blocks": "off", "padded-blocks": "off",
"padding-line-between-statements": "off", "padding-line-between-statements": "off",
"prefer-arrow-callback": "off", "prefer-arrow-callback": "off",
"prefer-const": "off", "prefer-const": "error",
"prefer-destructuring": "off", "prefer-destructuring": "off",
"prefer-numeric-literals": "error", "prefer-numeric-literals": "error",
"prefer-promise-reject-errors": "error", "prefer-promise-reject-errors": "error",

View file

@ -203,8 +203,8 @@ package, but can be defined inline.
Example: Example:
```js ```js
var extraRules = require("extraRules"); const extraRules = require("extraRules");
var options = { const options = {
"customRules": [ extraRules.one, extraRules.two ] "customRules": [ extraRules.one, extraRules.two ]
}; };
``` ```
@ -276,7 +276,7 @@ Sets of rules (known as a "style") can be stored separately and loaded as
Example: Example:
```js ```js
var options = { const options = {
"files": [ "..." ], "files": [ "..." ],
"config": require("style/relaxed.json") "config": require("style/relaxed.json")
}; };
@ -310,7 +310,7 @@ And a `custom.json` configuration file:
Then code like the following: Then code like the following:
```js ```js
var options = { const options = {
"config": markdownlint.readConfigSync("./custom.json") "config": markdownlint.readConfigSync("./custom.json")
}; };
``` ```
@ -318,7 +318,7 @@ var options = {
Merges `custom.json` and `base.json` and is equivalent to: Merges `custom.json` and `base.json` and is equivalent to:
```js ```js
var options = { const options = {
"config": { "config": {
"default": true, "default": true,
"line-length": false "line-length": false
@ -458,9 +458,9 @@ Configuration object.
Invoke `markdownlint` and use the `result` object's `toString` method: Invoke `markdownlint` and use the `result` object's `toString` method:
```js ```js
var markdownlint = require("markdownlint"); const markdownlint = require("markdownlint");
var options = { const options = {
"files": [ "good.md", "bad.md" ], "files": [ "good.md", "bad.md" ],
"strings": { "strings": {
"good.string": "# good.string\n\nThis string passes all rules.", "good.string": "# good.string\n\nThis string passes all rules.",
@ -491,7 +491,7 @@ bad.md: 1: MD041/first-line-h1 First line in file should be a top level heading
Or invoke `markdownlint.sync` for a synchronous call: Or invoke `markdownlint.sync` for a synchronous call:
```js ```js
var result = markdownlint.sync(options); const result = markdownlint.sync(options);
console.log(result.toString()); console.log(result.toString());
``` ```
@ -542,9 +542,9 @@ Output:
Integration with the [gulp](http://gulpjs.com/) build system is straightforward: Integration with the [gulp](http://gulpjs.com/) build system is straightforward:
```js ```js
var gulp = require("gulp"); const gulp = require("gulp");
var through2 = require("through2"); const through2 = require("through2");
var markdownlint = require("markdownlint"); const markdownlint = require("markdownlint");
gulp.task("markdownlint", function task() { gulp.task("markdownlint", function task() {
return gulp.src("*.md", { "read": false }) return gulp.src("*.md", { "read": false })
@ -552,7 +552,7 @@ gulp.task("markdownlint", function task() {
markdownlint( markdownlint(
{ "files": [ file.relative ] }, { "files": [ file.relative ] },
function callback(err, result) { function callback(err, result) {
var resultString = (result || "").toString(); const resultString = (result || "").toString();
if (resultString) { if (resultString) {
console.log(resultString); console.log(resultString);
} }
@ -576,7 +576,7 @@ bad.md: 1: MD041/first-line-h1 First line in file should be a top level heading
Integration with the [Grunt](http://gruntjs.com/) build system is similar: Integration with the [Grunt](http://gruntjs.com/) build system is similar:
```js ```js
var markdownlint = require("markdownlint"); const markdownlint = require("markdownlint");
module.exports = function wrapper(grunt) { module.exports = function wrapper(grunt) {
grunt.initConfig({ grunt.initConfig({
@ -588,11 +588,11 @@ module.exports = function wrapper(grunt) {
}); });
grunt.registerMultiTask("markdownlint", function task() { grunt.registerMultiTask("markdownlint", function task() {
var done = this.async(); const done = this.async();
markdownlint( markdownlint(
{ "files": this.filesSrc }, { "files": this.filesSrc },
function callback(err, result) { function callback(err, result) {
var resultString = err || ((result || "").toString()); const resultString = err || ((result || "").toString());
if (resultString) { if (resultString) {
grunt.fail.warn("\n" + resultString + "\n"); grunt.fail.warn("\n" + resultString + "\n");
} }
@ -634,12 +634,12 @@ Then reference `markdown-it` and `markdownlint`:
And call it like so: And call it like so:
```js ```js
var options = { const options = {
"strings": { "strings": {
"content": "Some Markdown to lint." "content": "Some Markdown to lint."
} }
}; };
var results = window.markdownlint.sync(options).toString(); const results = window.markdownlint.sync(options).toString();
``` ```
## Examples ## Examples

View file

@ -1,6 +1,6 @@
"use strict"; "use strict";
var markdownlint = require("../lib/markdownlint"); const markdownlint = require("../lib/markdownlint");
module.exports = function wrapper(grunt) { module.exports = function wrapper(grunt) {
grunt.initConfig({ grunt.initConfig({
@ -12,11 +12,11 @@ module.exports = function wrapper(grunt) {
}); });
grunt.registerMultiTask("markdownlint", function task() { grunt.registerMultiTask("markdownlint", function task() {
var done = this.async(); const done = this.async();
markdownlint( markdownlint(
{ "files": this.filesSrc }, { "files": this.filesSrc },
function callback(err, result) { function callback(err, result) {
var resultString = err || ((result || "").toString()); const resultString = err || ((result || "").toString());
if (resultString) { if (resultString) {
grunt.fail.warn("\n" + resultString + "\n"); grunt.fail.warn("\n" + resultString + "\n");
} }

View file

@ -1,8 +1,8 @@
"use strict"; "use strict";
var gulp = require("gulp"); const gulp = require("gulp");
var through2 = require("through2"); const through2 = require("through2");
var markdownlint = require("../lib/markdownlint"); const markdownlint = require("../lib/markdownlint");
// Simple task wrapper // Simple task wrapper
gulp.task("markdownlint", function task() { gulp.task("markdownlint", function task() {
@ -11,7 +11,7 @@ gulp.task("markdownlint", function task() {
markdownlint( markdownlint(
{ "files": [ file.relative ] }, { "files": [ file.relative ] },
function callback(err, result) { function callback(err, result) {
var resultString = (result || "").toString(); const resultString = (result || "").toString();
if (resultString) { if (resultString) {
console.log(resultString); console.log(resultString);
} }

View file

@ -1,8 +1,8 @@
"use strict"; "use strict";
var markdownlint = require("../lib/markdownlint"); const markdownlint = require("../lib/markdownlint");
var options = { const options = {
"files": [ "good.md", "bad.md" ], "files": [ "good.md", "bad.md" ],
"strings": { "strings": {
"good.string": "# good.string\n\nThis string passes all rules.", "good.string": "# good.string\n\nThis string passes all rules.",
@ -11,7 +11,7 @@ var options = {
}; };
// Makes a synchronous call, using result.toString for pretty formatting // Makes a synchronous call, using result.toString for pretty formatting
var result = markdownlint.sync(options); const result = markdownlint.sync(options);
console.log(result.toString()); console.log(result.toString());
// Makes an asynchronous call // Makes an asynchronous call

View file

@ -2,29 +2,29 @@
"use strict"; "use strict";
var fs = require("fs"); const fs = require("fs");
var path = require("path"); const path = require("path");
var md = require("markdown-it")({ "html": true }); const md = require("markdown-it")({ "html": true });
var rules = require("./rules"); const rules = require("./rules");
var shared = require("./shared"); const shared = require("./shared");
// Validates the list of rules for structure and reuse // Validates the list of rules for structure and reuse
function validateRuleList(ruleList) { function validateRuleList(ruleList) {
var result = null; let result = null;
if (ruleList.length === rules.length) { if (ruleList.length === rules.length) {
// No need to validate if only using built-in rules // No need to validate if only using built-in rules
return result; return result;
} }
var allIds = {}; const allIds = {};
ruleList.forEach(function forRule(rule, index) { ruleList.forEach(function forRule(rule, index) {
var customIndex = index - rules.length; const customIndex = index - rules.length;
function newError(property) { function newError(property) {
return new Error( return new Error(
"Property '" + property + "' of custom rule at index " + "Property '" + property + "' of custom rule at index " +
customIndex + " is incorrect."); customIndex + " is incorrect.");
} }
[ "names", "tags" ].forEach(function forProperty(property) { [ "names", "tags" ].forEach(function forProperty(property) {
var value = rule[property]; const value = rule[property];
if (!result && if (!result &&
(!value || !Array.isArray(value) || (value.length === 0) || (!value || !Array.isArray(value) || (value.length === 0) ||
!value.every(shared.isString) || value.some(shared.isEmptyString))) { !value.every(shared.isString) || value.some(shared.isEmptyString))) {
@ -35,15 +35,15 @@ function validateRuleList(ruleList) {
[ "description", "string" ], [ "description", "string" ],
[ "function", "function" ] [ "function", "function" ]
].forEach(function forProperty(propertyInfo) { ].forEach(function forProperty(propertyInfo) {
var property = propertyInfo[0]; const property = propertyInfo[0];
var value = rule[property]; const value = rule[property];
if (!result && (!value || (typeof value !== propertyInfo[1]))) { if (!result && (!value || (typeof value !== propertyInfo[1]))) {
result = newError(property); result = newError(property);
} }
}); });
if (!result) { if (!result) {
rule.names.forEach(function forName(name) { rule.names.forEach(function forName(name) {
var nameUpper = name.toUpperCase(); const nameUpper = name.toUpperCase();
if (!result && (allIds[nameUpper] !== undefined)) { if (!result && (allIds[nameUpper] !== undefined)) {
result = new Error("Name '" + name + "' of custom rule at index " + result = new Error("Name '" + name + "' of custom rule at index " +
customIndex + " is already used as a name or tag."); customIndex + " is already used as a name or tag.");
@ -51,7 +51,7 @@ function validateRuleList(ruleList) {
allIds[nameUpper] = true; allIds[nameUpper] = true;
}); });
rule.tags.forEach(function forTag(tag) { rule.tags.forEach(function forTag(tag) {
var tagUpper = tag.toUpperCase(); const tagUpper = tag.toUpperCase();
if (!result && allIds[tagUpper]) { if (!result && allIds[tagUpper]) {
result = new Error("Tag '" + tag + "' of custom rule at index " + result = new Error("Tag '" + tag + "' of custom rule at index " +
customIndex + " is already used as a name."); customIndex + " is already used as a name.");
@ -67,14 +67,14 @@ function validateRuleList(ruleList) {
function newResults(ruleList) { function newResults(ruleList) {
function Results() {} function Results() {}
Results.prototype.toString = function resultsToString(useAlias) { Results.prototype.toString = function resultsToString(useAlias) {
var that = this; const that = this;
var ruleNameToRule = null; let ruleNameToRule = null;
var results = []; const results = [];
Object.keys(that).forEach(function forFile(file) { Object.keys(that).forEach(function forFile(file) {
var fileResults = that[file]; const fileResults = that[file];
if (Array.isArray(fileResults)) { if (Array.isArray(fileResults)) {
fileResults.forEach(function forResult(result) { fileResults.forEach(function forResult(result) {
var ruleMoniker = result.ruleNames ? const ruleMoniker = result.ruleNames ?
result.ruleNames.join("/") : result.ruleNames.join("/") :
(result.ruleName + "/" + result.ruleAlias); (result.ruleName + "/" + result.ruleAlias);
results.push( results.push(
@ -93,16 +93,16 @@ function newResults(ruleList) {
if (!ruleNameToRule) { if (!ruleNameToRule) {
ruleNameToRule = {}; ruleNameToRule = {};
ruleList.forEach(function forRule(rule) { ruleList.forEach(function forRule(rule) {
var ruleName = rule.names[0].toUpperCase(); const ruleName = rule.names[0].toUpperCase();
ruleNameToRule[ruleName] = rule; ruleNameToRule[ruleName] = rule;
}); });
} }
Object.keys(fileResults).forEach(function forRule(ruleName) { Object.keys(fileResults).forEach(function forRule(ruleName) {
var rule = ruleNameToRule[ruleName.toUpperCase()]; const rule = ruleNameToRule[ruleName.toUpperCase()];
var ruleResults = fileResults[ruleName]; const ruleResults = fileResults[ruleName];
ruleResults.forEach(function forLine(lineNumber) { ruleResults.forEach(function forLine(lineNumber) {
var nameIndex = Math.min(useAlias ? 1 : 0, rule.names.length - 1); const nameIndex = Math.min(useAlias ? 1 : 0, rule.names.length - 1);
var result = const result =
file + ": " + file + ": " +
lineNumber + ": " + lineNumber + ": " +
rule.names[nameIndex] + " " + rule.names[nameIndex] + " " +
@ -119,11 +119,11 @@ function newResults(ruleList) {
// Remove front matter (if present at beginning of content) // Remove front matter (if present at beginning of content)
function removeFrontMatter(content, frontMatter) { function removeFrontMatter(content, frontMatter) {
var frontMatterLines = []; let frontMatterLines = [];
if (frontMatter) { if (frontMatter) {
var frontMatterMatch = content.match(frontMatter); const frontMatterMatch = content.match(frontMatter);
if (frontMatterMatch && !frontMatterMatch.index) { if (frontMatterMatch && !frontMatterMatch.index) {
var contentMatched = frontMatterMatch[0]; const contentMatched = frontMatterMatch[0];
content = content.slice(contentMatched.length); content = content.slice(contentMatched.length);
frontMatterLines = contentMatched.split(shared.newLineRe); frontMatterLines = contentMatched.split(shared.newLineRe);
if (frontMatterLines.length && if (frontMatterLines.length &&
@ -140,7 +140,7 @@ function removeFrontMatter(content, frontMatter) {
// Annotate tokens with line/lineNumber // Annotate tokens with line/lineNumber
function annotateTokens(tokens, lines) { function annotateTokens(tokens, lines) {
var tbodyMap = null; let tbodyMap = null;
tokens.forEach(function forToken(token) { tokens.forEach(function forToken(token) {
// Handle missing maps for table body // Handle missing maps for table body
if (token.type === "tbody_open") { if (token.type === "tbody_open") {
@ -162,7 +162,7 @@ function annotateTokens(tokens, lines) {
token.map[1]--; token.map[1]--;
} }
// Annotate children with lineNumber // Annotate children with lineNumber
var lineNumber = token.lineNumber; let lineNumber = token.lineNumber;
(token.children || []).forEach(function forChild(child) { (token.children || []).forEach(function forChild(child) {
child.lineNumber = lineNumber; child.lineNumber = lineNumber;
child.line = lines[lineNumber - 1]; child.line = lines[lineNumber - 1];
@ -176,21 +176,21 @@ function annotateTokens(tokens, lines) {
// Map rule names/tags to canonical rule name // Map rule names/tags to canonical rule name
function mapAliasToRuleNames(ruleList) { function mapAliasToRuleNames(ruleList) {
var aliasToRuleNames = {}; const aliasToRuleNames = {};
// var tagToRuleNames = {}; // const tagToRuleNames = {};
ruleList.forEach(function forRule(rule) { ruleList.forEach(function forRule(rule) {
var ruleName = rule.names[0].toUpperCase(); const ruleName = rule.names[0].toUpperCase();
// The following is useful for updating README.md: // The following is useful for updating README.md:
// console.log( // console.log(
// "* **[" + ruleName + "](doc/Rules.md#" + ruleName.toLowerCase() + // "* **[" + ruleName + "](doc/Rules.md#" + ruleName.toLowerCase() +
// ")** *" + rule.names.slice(1).join("/") + "* - " + rule.description); // ")** *" + rule.names.slice(1).join("/") + "* - " + rule.description);
rule.names.forEach(function forName(name) { rule.names.forEach(function forName(name) {
var nameUpper = name.toUpperCase(); const nameUpper = name.toUpperCase();
aliasToRuleNames[nameUpper] = [ ruleName ]; aliasToRuleNames[nameUpper] = [ ruleName ];
}); });
rule.tags.forEach(function forTag(tag) { rule.tags.forEach(function forTag(tag) {
var tagUpper = tag.toUpperCase(); const tagUpper = tag.toUpperCase();
var ruleNames = aliasToRuleNames[tagUpper] || []; const ruleNames = aliasToRuleNames[tagUpper] || [];
ruleNames.push(ruleName); ruleNames.push(ruleName);
aliasToRuleNames[tagUpper] = ruleNames; aliasToRuleNames[tagUpper] = ruleNames;
// tagToRuleNames[tag] = ruleName; // tagToRuleNames[tag] = ruleName;
@ -206,17 +206,17 @@ function mapAliasToRuleNames(ruleList) {
// Apply (and normalize) config // Apply (and normalize) config
function getEffectiveConfig(ruleList, config, aliasToRuleNames) { function getEffectiveConfig(ruleList, config, aliasToRuleNames) {
var defaultKey = Object.keys(config).filter(function forKey(key) { const defaultKey = Object.keys(config).filter(function forKey(key) {
return key.toUpperCase() === "DEFAULT"; return key.toUpperCase() === "DEFAULT";
}); });
var ruleDefault = (defaultKey.length === 0) || !!config[defaultKey[0]]; const ruleDefault = (defaultKey.length === 0) || !!config[defaultKey[0]];
var effectiveConfig = {}; const effectiveConfig = {};
ruleList.forEach(function forRule(rule) { ruleList.forEach(function forRule(rule) {
var ruleName = rule.names[0].toUpperCase(); const ruleName = rule.names[0].toUpperCase();
effectiveConfig[ruleName] = ruleDefault; effectiveConfig[ruleName] = ruleDefault;
}); });
Object.keys(config).forEach(function forKey(key) { Object.keys(config).forEach(function forKey(key) {
var value = config[key]; let value = config[key];
if (value) { if (value) {
if (!(value instanceof Object)) { if (!(value instanceof Object)) {
value = {}; value = {};
@ -224,7 +224,7 @@ function getEffectiveConfig(ruleList, config, aliasToRuleNames) {
} else { } else {
value = false; value = false;
} }
var keyUpper = key.toUpperCase(); const keyUpper = key.toUpperCase();
(aliasToRuleNames[keyUpper] || []).forEach(function forRule(ruleName) { (aliasToRuleNames[keyUpper] || []).forEach(function forRule(ruleName) {
effectiveConfig[ruleName] = value; effectiveConfig[ruleName] = value;
}); });
@ -236,16 +236,16 @@ function getEffectiveConfig(ruleList, config, aliasToRuleNames) {
function getEnabledRulesPerLineNumber( function getEnabledRulesPerLineNumber(
ruleList, lines, frontMatterLines, noInlineConfig, ruleList, lines, frontMatterLines, noInlineConfig,
effectiveConfig, aliasToRuleNames) { effectiveConfig, aliasToRuleNames) {
var enabledRules = {}; let enabledRules = {};
var allRuleNames = []; const allRuleNames = [];
ruleList.forEach(function forRule(rule) { ruleList.forEach(function forRule(rule) {
var ruleName = rule.names[0].toUpperCase(); const ruleName = rule.names[0].toUpperCase();
allRuleNames.push(ruleName); allRuleNames.push(ruleName);
enabledRules[ruleName] = !!effectiveConfig[ruleName]; enabledRules[ruleName] = !!effectiveConfig[ruleName];
}); });
function forMatch(match) { function forMatch(match) {
var enabled = match[1].toUpperCase() === "EN"; const enabled = match[1].toUpperCase() === "EN";
var items = match[2] ? const items = match[2] ?
match[2].trim().toUpperCase().split(/\s+/) : match[2].trim().toUpperCase().split(/\s+/) :
allRuleNames; allRuleNames;
items.forEach(function forItem(nameUpper) { items.forEach(function forItem(nameUpper) {
@ -254,10 +254,10 @@ function getEnabledRulesPerLineNumber(
}); });
}); });
} }
var enabledRulesPerLineNumber = new Array(1 + frontMatterLines.length); const enabledRulesPerLineNumber = new Array(1 + frontMatterLines.length);
lines.forEach(function forLine(line) { lines.forEach(function forLine(line) {
if (!noInlineConfig) { if (!noInlineConfig) {
var match = shared.inlineCommentRe.exec(line); let match = shared.inlineCommentRe.exec(line);
if (match) { if (match) {
enabledRules = shared.clone(enabledRules); enabledRules = shared.clone(enabledRules);
while (match) { while (match) {
@ -288,38 +288,39 @@ function lintContent(
// Remove UTF-8 byte order marker (if present) // Remove UTF-8 byte order marker (if present)
content = content.replace(/^\ufeff/, ""); content = content.replace(/^\ufeff/, "");
// Remove front matter // Remove front matter
var removeFrontMatterResult = removeFrontMatter(content, frontMatter); const removeFrontMatterResult = removeFrontMatter(content, frontMatter);
var frontMatterLines = removeFrontMatterResult.frontMatterLines; const frontMatterLines = removeFrontMatterResult.frontMatterLines;
// Ignore the content of HTML comments // Ignore the content of HTML comments
content = shared.clearHtmlCommentText(removeFrontMatterResult.content); content = shared.clearHtmlCommentText(removeFrontMatterResult.content);
// Parse content into tokens and lines // Parse content into tokens and lines
var tokens = md.parse(content, {}); const tokens = md.parse(content, {});
var lines = content.split(shared.newLineRe); const lines = content.split(shared.newLineRe);
annotateTokens(tokens, lines); annotateTokens(tokens, lines);
var aliasToRuleNames = mapAliasToRuleNames(ruleList); const aliasToRuleNames = mapAliasToRuleNames(ruleList);
var effectiveConfig = getEffectiveConfig(ruleList, config, aliasToRuleNames); const effectiveConfig =
var enabledRulesPerLineNumber = getEnabledRulesPerLineNumber( getEffectiveConfig(ruleList, config, aliasToRuleNames);
const enabledRulesPerLineNumber = getEnabledRulesPerLineNumber(
ruleList, lines, frontMatterLines, noInlineConfig, ruleList, lines, frontMatterLines, noInlineConfig,
effectiveConfig, aliasToRuleNames); effectiveConfig, aliasToRuleNames);
// Create parameters for rules // Create parameters for rules
var params = { const params = {
"tokens": tokens, "tokens": tokens,
"lines": lines, "lines": lines,
"frontMatterLines": frontMatterLines "frontMatterLines": frontMatterLines
}; };
shared.makeTokenCache(params); shared.makeTokenCache(params);
// Function to run for each rule // Function to run for each rule
var result = (resultVersion === 0) ? {} : []; const result = (resultVersion === 0) ? {} : [];
function forRule(rule) { function forRule(rule) {
// Configure rule // Configure rule
var ruleNameFriendly = rule.names[0]; const ruleNameFriendly = rule.names[0];
var ruleName = ruleNameFriendly.toUpperCase(); const ruleName = ruleNameFriendly.toUpperCase();
params.config = effectiveConfig[ruleName]; params.config = effectiveConfig[ruleName];
function throwError(property) { function throwError(property) {
throw new Error( throw new Error(
"Property '" + property + "' of onError parameter is incorrect."); "Property '" + property + "' of onError parameter is incorrect.");
} }
var errors = []; const errors = [];
function onError(errorInfo) { function onError(errorInfo) {
if (!errorInfo || if (!errorInfo ||
!errorInfo.lineNumber || !errorInfo.lineNumber ||
@ -353,7 +354,7 @@ function lintContent(
// Record any errors (significant performance benefit from length check) // Record any errors (significant performance benefit from length check)
if (errors.length) { if (errors.length) {
errors.sort(lineNumberComparison); errors.sort(lineNumberComparison);
var filteredErrors = errors const filteredErrors = errors
.filter(uniqueFilterForSortedErrors) .filter(uniqueFilterForSortedErrors)
.filter(function removeDisabledRules(error) { .filter(function removeDisabledRules(error) {
return enabledRulesPerLineNumber[error.lineNumber][ruleName]; return enabledRulesPerLineNumber[error.lineNumber][ruleName];
@ -362,7 +363,7 @@ function lintContent(
if (resultVersion === 0) { if (resultVersion === 0) {
return error.lineNumber; return error.lineNumber;
} }
var errorObject = {}; const errorObject = {};
errorObject.lineNumber = error.lineNumber; errorObject.lineNumber = error.lineNumber;
if (resultVersion === 1) { if (resultVersion === 1) {
errorObject.ruleName = ruleNameFriendly; errorObject.ruleName = ruleNameFriendly;
@ -425,30 +426,30 @@ function lintInput(options, synchronous, callback) {
// Normalize inputs // Normalize inputs
options = options || {}; options = options || {};
callback = callback || function noop() {}; callback = callback || function noop() {};
var ruleList = rules.concat(options.customRules || []); const ruleList = rules.concat(options.customRules || []);
var ruleErr = validateRuleList(ruleList); const ruleErr = validateRuleList(ruleList);
if (ruleErr) { if (ruleErr) {
return callback(ruleErr); return callback(ruleErr);
} }
var files = []; let files = [];
if (Array.isArray(options.files)) { if (Array.isArray(options.files)) {
files = options.files.slice(); files = options.files.slice();
} else if (options.files) { } else if (options.files) {
files = [ String(options.files) ]; files = [ String(options.files) ];
} }
var strings = options.strings || {}; const strings = options.strings || {};
var stringsKeys = Object.keys(strings); const stringsKeys = Object.keys(strings);
var config = options.config || { "default": true }; const config = options.config || { "default": true };
var frontMatter = (options.frontMatter === undefined) ? const frontMatter = (options.frontMatter === undefined) ?
shared.frontMatterRe : options.frontMatter; shared.frontMatterRe : options.frontMatter;
var noInlineConfig = !!options.noInlineConfig; const noInlineConfig = !!options.noInlineConfig;
var resultVersion = (options.resultVersion === undefined) ? const resultVersion = (options.resultVersion === undefined) ?
2 : options.resultVersion; 2 : options.resultVersion;
var results = newResults(ruleList); const results = newResults(ruleList);
// Helper to lint the next string or file // Helper to lint the next string or file
function lintNextItem() { function lintNextItem() {
var iterating = true; let iterating = true;
var item = null; let item = null;
function lintNextItemCallback(err, result) { function lintNextItemCallback(err, result) {
if (err) { if (err) {
iterating = false; iterating = false;
@ -506,7 +507,7 @@ function markdownlint(options, callback) {
* @returns {Object} Result object. * @returns {Object} Result object.
*/ */
function markdownlintSync(options) { function markdownlintSync(options) {
var results = null; let results = null;
lintInput(options, true, function callback(error, res) { lintInput(options, true, function callback(error, res) {
if (error) { if (error) {
throw error; throw error;
@ -530,7 +531,7 @@ function readConfig(file, callback) {
return callback(err); return callback(err);
} }
// Parse file // Parse file
var config = null; let config = null;
try { try {
config = JSON.parse(content); config = JSON.parse(content);
} catch (ex) { } catch (ex) {
@ -538,7 +539,7 @@ function readConfig(file, callback) {
} }
if (config.extends) { if (config.extends) {
// Extend configuration // Extend configuration
var extendsFile = path.resolve(path.dirname(file), config.extends); const extendsFile = path.resolve(path.dirname(file), config.extends);
readConfig(extendsFile, function handleConfig(errr, extendsConfig) { readConfig(extendsFile, function handleConfig(errr, extendsConfig) {
if (errr) { if (errr) {
return callback(errr); return callback(errr);
@ -560,7 +561,7 @@ function readConfig(file, callback) {
*/ */
function readConfigSync(file) { function readConfigSync(file) {
// Parse file // Parse file
var config = JSON.parse(fs.readFileSync(file, shared.utf8Encoding)); let config = JSON.parse(fs.readFileSync(file, shared.utf8Encoding));
if (config.extends) { if (config.extends) {
// Extend configuration // Extend configuration
config = shared.assign( config = shared.assign(

View file

@ -2,16 +2,16 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD001", "heading-increment", "header-increment" ], "names": [ "MD001", "heading-increment", "header-increment" ],
"description": "Heading levels should only increment by one level at a time", "description": "Heading levels should only increment by one level at a time",
"tags": [ "headings", "headers" ], "tags": [ "headings", "headers" ],
"function": function MD001(params, onError) { "function": function MD001(params, onError) {
var prevLevel = 0; let prevLevel = 0;
shared.filterTokens(params, "heading_open", function forToken(token) { shared.filterTokens(params, "heading_open", function forToken(token) {
var level = parseInt(token.tag.slice(1), 10); const level = parseInt(token.tag.slice(1), 10);
if (prevLevel && (level > prevLevel)) { if (prevLevel && (level > prevLevel)) {
shared.addErrorDetailIf(onError, token.lineNumber, shared.addErrorDetailIf(onError, token.lineNumber,
"h" + (prevLevel + 1), "h" + level); "h" + (prevLevel + 1), "h" + level);

View file

@ -2,15 +2,15 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD002", "first-heading-h1", "first-header-h1" ], "names": [ "MD002", "first-heading-h1", "first-header-h1" ],
"description": "First heading should be a top level heading", "description": "First heading should be a top level heading",
"tags": [ "headings", "headers" ], "tags": [ "headings", "headers" ],
"function": function MD002(params, onError) { "function": function MD002(params, onError) {
var level = params.config.level || 1; const level = params.config.level || 1;
var tag = "h" + level; const tag = "h" + level;
params.tokens.every(function forToken(token) { params.tokens.every(function forToken(token) {
if (token.type === "heading_open") { if (token.type === "heading_open") {
shared.addErrorDetailIf(onError, token.lineNumber, tag, token.tag); shared.addErrorDetailIf(onError, token.lineNumber, tag, token.tag);

View file

@ -2,31 +2,31 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD003", "heading-style", "header-style" ], "names": [ "MD003", "heading-style", "header-style" ],
"description": "Heading style", "description": "Heading style",
"tags": [ "headings", "headers" ], "tags": [ "headings", "headers" ],
"function": function MD003(params, onError) { "function": function MD003(params, onError) {
var style = params.config.style || "consistent"; let style = params.config.style || "consistent";
shared.filterTokens(params, "heading_open", function forToken(token) { shared.filterTokens(params, "heading_open", function forToken(token) {
var styleForToken = shared.headingStyleFor(token); const styleForToken = shared.headingStyleFor(token);
if (style === "consistent") { if (style === "consistent") {
style = styleForToken; style = styleForToken;
} }
if (styleForToken !== style) { if (styleForToken !== style) {
var h12 = /h[12]/.test(token.tag); const h12 = /h[12]/.test(token.tag);
var setextWithAtx = const setextWithAtx =
(style === "setext_with_atx") && (style === "setext_with_atx") &&
((h12 && (styleForToken === "setext")) || ((h12 && (styleForToken === "setext")) ||
(!h12 && (styleForToken === "atx"))); (!h12 && (styleForToken === "atx")));
var setextWithAtxClosed = const setextWithAtxClosed =
(style === "setext_with_atx_closed") && (style === "setext_with_atx_closed") &&
((h12 && (styleForToken === "setext")) || ((h12 && (styleForToken === "setext")) ||
(!h12 && (styleForToken === "atx_closed"))); (!h12 && (styleForToken === "atx_closed")));
if (!setextWithAtx && !setextWithAtxClosed) { if (!setextWithAtx && !setextWithAtxClosed) {
var expected = style; let expected = style;
if (style === "setext_with_atx") { if (style === "setext_with_atx") {
expected = h12 ? "setext" : "atx"; expected = h12 ? "setext" : "atx";
} else if (style === "setext_with_atx_closed") { } else if (style === "setext_with_atx_closed") {

View file

@ -2,7 +2,7 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
// Returns the unordered list style for a list item token // Returns the unordered list style for a list item token
function unorderedListStyleFor(token) { function unorderedListStyleFor(token) {
@ -22,18 +22,18 @@ module.exports = {
"description": "Unordered list style", "description": "Unordered list style",
"tags": [ "bullet", "ul" ], "tags": [ "bullet", "ul" ],
"function": function MD004(params, onError) { "function": function MD004(params, onError) {
var style = params.config.style || "consistent"; const style = params.config.style || "consistent";
var expectedStyle = style; let expectedStyle = style;
var nestingStyles = []; const nestingStyles = [];
shared.flattenLists().forEach(function forList(list) { shared.flattenLists().forEach(function forList(list) {
if (list.unordered) { if (list.unordered) {
if (expectedStyle === "consistent") { if (expectedStyle === "consistent") {
expectedStyle = unorderedListStyleFor(list.items[0]); expectedStyle = unorderedListStyleFor(list.items[0]);
} }
list.items.forEach(function forItem(item) { list.items.forEach(function forItem(item) {
var itemStyle = unorderedListStyleFor(item); const itemStyle = unorderedListStyleFor(item);
if (style === "sublist") { if (style === "sublist") {
var nesting = list.nesting; const nesting = list.nesting;
if (!nestingStyles[nesting] && if (!nestingStyles[nesting] &&
(itemStyle !== nestingStyles[nesting - 1])) { (itemStyle !== nestingStyles[nesting - 1])) {
nestingStyles[nesting] = itemStyle; nestingStyles[nesting] = itemStyle;

View file

@ -2,7 +2,7 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD005", "list-indent" ], "names": [ "MD005", "list-indent" ],

View file

@ -2,7 +2,7 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD006", "ul-start-left" ], "names": [ "MD006", "ul-start-left" ],

View file

@ -2,14 +2,14 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD007", "ul-indent" ], "names": [ "MD007", "ul-indent" ],
"description": "Unordered list indentation", "description": "Unordered list indentation",
"tags": [ "bullet", "ul", "indentation" ], "tags": [ "bullet", "ul", "indentation" ],
"function": function MD007(params, onError) { "function": function MD007(params, onError) {
var optionsIndent = params.config.indent || 2; const optionsIndent = params.config.indent || 2;
shared.flattenLists().forEach(function forList(list) { shared.flattenLists().forEach(function forList(list) {
if (list.unordered && list.parentsUnordered && list.indent) { if (list.unordered && list.parentsUnordered && list.indent) {
shared.addErrorDetailIf(onError, list.open.lineNumber, shared.addErrorDetailIf(onError, list.open.lineNumber,

View file

@ -2,32 +2,32 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
var trailingSpaceRe = /\s+$/; const trailingSpaceRe = /\s+$/;
module.exports = { module.exports = {
"names": [ "MD009", "no-trailing-spaces" ], "names": [ "MD009", "no-trailing-spaces" ],
"description": "Trailing spaces", "description": "Trailing spaces",
"tags": [ "whitespace" ], "tags": [ "whitespace" ],
"function": function MD009(params, onError) { "function": function MD009(params, onError) {
var brSpaces = params.config.br_spaces || 0; const brSpaces = params.config.br_spaces || 0;
var listItemEmptyLines = params.config.list_item_empty_lines; const listItemEmptyLines = params.config.list_item_empty_lines;
var allowListItemEmptyLines = const allowListItemEmptyLines =
(listItemEmptyLines === undefined) ? false : !!listItemEmptyLines; (listItemEmptyLines === undefined) ? false : !!listItemEmptyLines;
var listItemLineNumbers = []; const listItemLineNumbers = [];
if (allowListItemEmptyLines) { if (allowListItemEmptyLines) {
shared.filterTokens(params, "list_item_open", function forToken(token) { shared.filterTokens(params, "list_item_open", function forToken(token) {
for (var i = token.map[0]; i < token.map[1]; i++) { for (let i = token.map[0]; i < token.map[1]; i++) {
listItemLineNumbers.push(i + 1); listItemLineNumbers.push(i + 1);
} }
}); });
} }
shared.forEachLine(function forLine(line, lineIndex) { shared.forEachLine(function forLine(line, lineIndex) {
var lineNumber = lineIndex + 1; const lineNumber = lineIndex + 1;
if (trailingSpaceRe.test(line) && if (trailingSpaceRe.test(line) &&
(listItemLineNumbers.indexOf(lineNumber) === -1)) { (listItemLineNumbers.indexOf(lineNumber) === -1)) {
var expected = (brSpaces < 2) ? 0 : brSpaces; const expected = (brSpaces < 2) ? 0 : brSpaces;
shared.addErrorDetailIf(onError, lineNumber, shared.addErrorDetailIf(onError, lineNumber,
expected, line.length - shared.trimRight(line).length, null, expected, line.length - shared.trimRight(line).length, null,
shared.rangeFromRegExp(line, trailingSpaceRe)); shared.rangeFromRegExp(line, trailingSpaceRe));

View file

@ -2,17 +2,17 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
var tabRe = /\t+/; const tabRe = /\t+/;
module.exports = { module.exports = {
"names": [ "MD010", "no-hard-tabs" ], "names": [ "MD010", "no-hard-tabs" ],
"description": "Hard tabs", "description": "Hard tabs",
"tags": [ "whitespace", "hard_tab" ], "tags": [ "whitespace", "hard_tab" ],
"function": function MD010(params, onError) { "function": function MD010(params, onError) {
var codeBlocks = params.config.code_blocks; const codeBlocks = params.config.code_blocks;
var includeCodeBlocks = (codeBlocks === undefined) ? true : !!codeBlocks; const includeCodeBlocks = (codeBlocks === undefined) ? true : !!codeBlocks;
shared.forEachLine(function forLine(line, lineIndex, inCode) { shared.forEachLine(function forLine(line, lineIndex, inCode) {
if (tabRe.test(line) && (!inCode || includeCodeBlocks)) { if (tabRe.test(line) && (!inCode || includeCodeBlocks)) {
shared.addError(onError, lineIndex + 1, shared.addError(onError, lineIndex + 1,

View file

@ -2,9 +2,9 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
var reversedLinkRe = /\([^)]+\)\[[^\]^][^\]]*]/; const reversedLinkRe = /\([^)]+\)\[[^\]^][^\]]*]/;
module.exports = { module.exports = {
"names": [ "MD011", "no-reversed-links" ], "names": [ "MD011", "no-reversed-links" ],
@ -12,7 +12,7 @@ module.exports = {
"tags": [ "links" ], "tags": [ "links" ],
"function": function MD011(params, onError) { "function": function MD011(params, onError) {
shared.forEachInlineChild(params, "text", function forToken(token) { shared.forEachInlineChild(params, "text", function forToken(token) {
var match = reversedLinkRe.exec(token.content); const match = reversedLinkRe.exec(token.content);
if (match) { if (match) {
shared.addError(onError, token.lineNumber, match[0], null, shared.addError(onError, token.lineNumber, match[0], null,
shared.rangeFromRegExp(token.line, reversedLinkRe)); shared.rangeFromRegExp(token.line, reversedLinkRe));

View file

@ -2,15 +2,15 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD012", "no-multiple-blanks" ], "names": [ "MD012", "no-multiple-blanks" ],
"description": "Multiple consecutive blank lines", "description": "Multiple consecutive blank lines",
"tags": [ "whitespace", "blank_lines" ], "tags": [ "whitespace", "blank_lines" ],
"function": function MD012(params, onError) { "function": function MD012(params, onError) {
var maximum = params.config.maximum || 1; const maximum = params.config.maximum || 1;
var count = 0; let count = 0;
shared.forEachLine(function forLine(line, lineIndex, inCode) { shared.forEachLine(function forLine(line, lineIndex, inCode) {
count = (inCode || line.trim().length) ? 0 : count + 1; count = (inCode || line.trim().length) ? 0 : count + 1;
if (maximum < count) { if (maximum < count) {

View file

@ -2,32 +2,32 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
var labelRe = /^\s*\[.*[^\\]]:/; const labelRe = /^\s*\[.*[^\\]]:/;
module.exports = { module.exports = {
"names": [ "MD013", "line-length" ], "names": [ "MD013", "line-length" ],
"description": "Line length", "description": "Line length",
"tags": [ "line_length" ], "tags": [ "line_length" ],
"function": function MD013(params, onError) { "function": function MD013(params, onError) {
var lineLength = params.config.line_length || 80; const lineLength = params.config.line_length || 80;
var codeBlocks = params.config.code_blocks; const codeBlocks = params.config.code_blocks;
var includeCodeBlocks = (codeBlocks === undefined) ? true : !!codeBlocks; const includeCodeBlocks = (codeBlocks === undefined) ? true : !!codeBlocks;
var tables = params.config.tables; const tables = params.config.tables;
var includeTables = (tables === undefined) ? true : !!tables; const includeTables = (tables === undefined) ? true : !!tables;
var headings = params.config.headings; let headings = params.config.headings;
if (headings === undefined) { if (headings === undefined) {
headings = params.config.headers; headings = params.config.headers;
} }
var includeHeadings = (headings === undefined) ? true : !!headings; const includeHeadings = (headings === undefined) ? true : !!headings;
var headingLineNumbers = []; const headingLineNumbers = [];
if (!includeHeadings) { if (!includeHeadings) {
shared.forEachHeading(params, function forHeading(heading) { shared.forEachHeading(params, function forHeading(heading) {
headingLineNumbers.push(heading.lineNumber); headingLineNumbers.push(heading.lineNumber);
}); });
} }
var tokenTypeMap = { const tokenTypeMap = {
"em_open": "e", "em_open": "e",
"em_close": "E", "em_close": "E",
"link_open": "l", "link_open": "l",
@ -36,9 +36,9 @@ module.exports = {
"strong_close": "S", "strong_close": "S",
"text": "T" "text": "T"
}; };
var linkOnlyLineNumbers = []; const linkOnlyLineNumbers = [];
shared.filterTokens(params, "inline", function forToken(token) { shared.filterTokens(params, "inline", function forToken(token) {
var childTokenTypes = ""; let childTokenTypes = "";
token.children.forEach(function forChild(child) { token.children.forEach(function forChild(child) {
if (child.type !== "text" || child.content !== "") { if (child.type !== "text" || child.content !== "") {
childTokenTypes += tokenTypeMap[child.type] || "x"; childTokenTypes += tokenTypeMap[child.type] || "x";
@ -48,10 +48,10 @@ module.exports = {
linkOnlyLineNumbers.push(token.lineNumber); linkOnlyLineNumbers.push(token.lineNumber);
} }
}); });
var longLineRe = new RegExp("^(.{" + lineLength + "})(.*\\s.*)$"); const longLineRe = new RegExp("^(.{" + lineLength + "})(.*\\s.*)$");
shared.forEachLine( shared.forEachLine(
function forLine(line, lineIndex, inCode, onFence, inTable) { function forLine(line, lineIndex, inCode, onFence, inTable) {
var lineNumber = lineIndex + 1; const lineNumber = lineIndex + 1;
if ((includeCodeBlocks || !inCode) && if ((includeCodeBlocks || !inCode) &&
(includeTables || !inTable) && (includeTables || !inTable) &&
(includeHeadings || (headingLineNumbers.indexOf(lineNumber)) < 0) && (includeHeadings || (headingLineNumbers.indexOf(lineNumber)) < 0) &&

View file

@ -2,9 +2,9 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
var dollarCommandRe = /^(\s*)(\$\s)/; const dollarCommandRe = /^(\s*)(\$\s)/;
module.exports = { module.exports = {
"names": [ "MD014", "commands-show-output" ], "names": [ "MD014", "commands-show-output" ],
@ -13,7 +13,7 @@ module.exports = {
"function": function MD014(params, onError) { "function": function MD014(params, onError) {
[ "code_block", "fence" ].forEach(function forType(type) { [ "code_block", "fence" ].forEach(function forType(type) {
shared.filterTokens(params, type, function forToken(token) { shared.filterTokens(params, type, function forToken(token) {
var allBlank = true; let allBlank = true;
if (token.content && token.content.split(shared.newLineRe) if (token.content && token.content.split(shared.newLineRe)
.every(function forLine(line) { .every(function forLine(line) {
return !line || (allBlank = false) || dollarCommandRe.test(line); return !line || (allBlank = false) || dollarCommandRe.test(line);

View file

@ -2,7 +2,7 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD018", "no-missing-space-atx" ], "names": [ "MD018", "no-missing-space-atx" ],

View file

@ -2,7 +2,7 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD019", "no-multiple-space-atx" ], "names": [ "MD019", "no-multiple-space-atx" ],

View file

@ -2,9 +2,9 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
var atxClosedHeadingNoSpaceRe = /(?:^#+[^#\s])|(?:[^#\s]#+\s*$)/; const atxClosedHeadingNoSpaceRe = /(?:^#+[^#\s])|(?:[^#\s]#+\s*$)/;
module.exports = { module.exports = {
"names": [ "MD020", "no-missing-space-closed-atx" ], "names": [ "MD020", "no-missing-space-closed-atx" ],
@ -13,8 +13,8 @@ module.exports = {
"function": function MD020(params, onError) { "function": function MD020(params, onError) {
shared.forEachLine(function forLine(line, lineIndex, inCode) { shared.forEachLine(function forLine(line, lineIndex, inCode) {
if (!inCode && /^#+[^#]*[^\\]#+$/.test(line)) { if (!inCode && /^#+[^#]*[^\\]#+$/.test(line)) {
var left = /^#+[^#\s]/.test(line); const left = /^#+[^#\s]/.test(line);
var right = /[^#\s]#+$/.test(line); const right = /[^#\s]#+$/.test(line);
if (left || right) { if (left || right) {
shared.addErrorContext(onError, lineIndex + 1, line.trim(), left, shared.addErrorContext(onError, lineIndex + 1, line.trim(), left,
right, shared.rangeFromRegExp(line, atxClosedHeadingNoSpaceRe)); right, shared.rangeFromRegExp(line, atxClosedHeadingNoSpaceRe));

View file

@ -2,9 +2,9 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
var atxClosedHeadingSpaceRe = /(?:^#+\s\s+?\S)|(?:\S\s\s+?#+\s*$)/; const atxClosedHeadingSpaceRe = /(?:^#+\s\s+?\S)|(?:\S\s\s+?#+\s*$)/;
module.exports = { module.exports = {
"names": [ "MD021", "no-multiple-space-closed-atx" ], "names": [ "MD021", "no-multiple-space-closed-atx" ],
@ -13,8 +13,8 @@ module.exports = {
"function": function MD021(params, onError) { "function": function MD021(params, onError) {
shared.filterTokens(params, "heading_open", function forToken(token) { shared.filterTokens(params, "heading_open", function forToken(token) {
if (shared.headingStyleFor(token) === "atx_closed") { if (shared.headingStyleFor(token) === "atx_closed") {
var left = /^#+\s\s/.test(token.line); const left = /^#+\s\s/.test(token.line);
var right = /\s\s#+$/.test(token.line); const right = /\s\s#+$/.test(token.line);
if (left || right) { if (left || right) {
shared.addErrorContext(onError, token.lineNumber, token.line.trim(), shared.addErrorContext(onError, token.lineNumber, token.line.trim(),
left, right, left, right,

View file

@ -2,16 +2,16 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD022", "blanks-around-headings", "blanks-around-headers" ], "names": [ "MD022", "blanks-around-headings", "blanks-around-headers" ],
"description": "Headings should be surrounded by blank lines", "description": "Headings should be surrounded by blank lines",
"tags": [ "headings", "headers", "blank_lines" ], "tags": [ "headings", "headers", "blank_lines" ],
"function": function MD022(params, onError) { "function": function MD022(params, onError) {
var prevHeadingLineNumber = 0; let prevHeadingLineNumber = 0;
var prevMaxLineIndex = -1; let prevMaxLineIndex = -1;
var needBlankLine = false; let needBlankLine = false;
params.tokens.forEach(function forToken(token) { params.tokens.forEach(function forToken(token) {
if (token.type === "heading_open") { if (token.type === "heading_open") {
if ((token.map[0] - prevMaxLineIndex) === 0) { if ((token.map[0] - prevMaxLineIndex) === 0) {

View file

@ -2,9 +2,9 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
var spaceBeforeHeadingRe = /^\s+\S/; const spaceBeforeHeadingRe = /^\s+\S/;
module.exports = { module.exports = {
"names": [ "MD023", "heading-start-left", "header-start-left" ], "names": [ "MD023", "heading-start-left", "header-start-left" ],

View file

@ -2,14 +2,14 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD024", "no-duplicate-heading", "no-duplicate-header" ], "names": [ "MD024", "no-duplicate-heading", "no-duplicate-header" ],
"description": "Multiple headings with the same content", "description": "Multiple headings with the same content",
"tags": [ "headings", "headers" ], "tags": [ "headings", "headers" ],
"function": function MD024(params, onError) { "function": function MD024(params, onError) {
var knownContent = []; const knownContent = [];
shared.forEachHeading(params, function forHeading(heading, content) { shared.forEachHeading(params, function forHeading(heading, content) {
if (knownContent.indexOf(content) === -1) { if (knownContent.indexOf(content) === -1) {
knownContent.push(content); knownContent.push(content);

View file

@ -2,16 +2,16 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD025", "single-h1" ], "names": [ "MD025", "single-h1" ],
"description": "Multiple top level headings in the same document", "description": "Multiple top level headings in the same document",
"tags": [ "headings", "headers" ], "tags": [ "headings", "headers" ],
"function": function MD025(params, onError) { "function": function MD025(params, onError) {
var level = params.config.level || 1; const level = params.config.level || 1;
var tag = "h" + level; const tag = "h" + level;
var hasTopLevelHeading = false; let hasTopLevelHeading = false;
shared.filterTokens(params, "heading_open", function forToken(token) { shared.filterTokens(params, "heading_open", function forToken(token) {
if (token.tag === tag) { if (token.tag === tag) {
if (hasTopLevelHeading) { if (hasTopLevelHeading) {

View file

@ -2,17 +2,17 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD026", "no-trailing-punctuation" ], "names": [ "MD026", "no-trailing-punctuation" ],
"description": "Trailing punctuation in heading", "description": "Trailing punctuation in heading",
"tags": [ "headings", "headers" ], "tags": [ "headings", "headers" ],
"function": function MD026(params, onError) { "function": function MD026(params, onError) {
var punctuation = params.config.punctuation || ".,;:!?"; const punctuation = params.config.punctuation || ".,;:!?";
var trailingPunctuationRe = new RegExp("[" + punctuation + "]$"); const trailingPunctuationRe = new RegExp("[" + punctuation + "]$");
shared.forEachHeading(params, function forHeading(heading, content) { shared.forEachHeading(params, function forHeading(heading, content) {
var match = trailingPunctuationRe.exec(content); const match = trailingPunctuationRe.exec(content);
if (match) { if (match) {
shared.addError(onError, heading.lineNumber, shared.addError(onError, heading.lineNumber,
"Punctuation: '" + match[0] + "'", null, "Punctuation: '" + match[0] + "'", null,

View file

@ -2,17 +2,17 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
var spaceAfterBlockQuote = /^\s*(?:>\s+)+\S/; const spaceAfterBlockQuote = /^\s*(?:>\s+)+\S/;
module.exports = { module.exports = {
"names": [ "MD027", "no-multiple-space-blockquote" ], "names": [ "MD027", "no-multiple-space-blockquote" ],
"description": "Multiple spaces after blockquote symbol", "description": "Multiple spaces after blockquote symbol",
"tags": [ "blockquote", "whitespace", "indentation" ], "tags": [ "blockquote", "whitespace", "indentation" ],
"function": function MD027(params, onError) { "function": function MD027(params, onError) {
var blockquoteNesting = 0; let blockquoteNesting = 0;
var listItemNesting = 0; let listItemNesting = 0;
params.tokens.forEach(function forToken(token) { params.tokens.forEach(function forToken(token) {
if (token.type === "blockquote_open") { if (token.type === "blockquote_open") {
blockquoteNesting++; blockquoteNesting++;
@ -23,7 +23,7 @@ module.exports = {
} else if (token.type === "list_item_close") { } else if (token.type === "list_item_close") {
listItemNesting--; listItemNesting--;
} else if ((token.type === "inline") && (blockquoteNesting > 0)) { } else if ((token.type === "inline") && (blockquoteNesting > 0)) {
var multipleSpaces = listItemNesting ? const multipleSpaces = listItemNesting ?
/^(\s*>)+\s\s+>/.test(token.line) : /^(\s*>)+\s\s+>/.test(token.line) :
/^(\s*>)+\s\s/.test(token.line); /^(\s*>)+\s\s/.test(token.line);
if (multipleSpaces) { if (multipleSpaces) {

View file

@ -2,14 +2,14 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD028", "no-blanks-blockquote" ], "names": [ "MD028", "no-blanks-blockquote" ],
"description": "Blank line inside blockquote", "description": "Blank line inside blockquote",
"tags": [ "blockquote", "whitespace" ], "tags": [ "blockquote", "whitespace" ],
"function": function MD028(params, onError) { "function": function MD028(params, onError) {
var prevToken = {}; let prevToken = {};
params.tokens.forEach(function forToken(token) { params.tokens.forEach(function forToken(token) {
if ((token.type === "blockquote_open") && if ((token.type === "blockquote_open") &&
(prevToken.type === "blockquote_close")) { (prevToken.type === "blockquote_close")) {

View file

@ -2,27 +2,27 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
var numberRe = /^[\s>]*([^.)]*)[.)]/; const numberRe = /^[\s>]*([^.)]*)[.)]/;
module.exports = { module.exports = {
"names": [ "MD029", "ol-prefix" ], "names": [ "MD029", "ol-prefix" ],
"description": "Ordered list item prefix", "description": "Ordered list item prefix",
"tags": [ "ol" ], "tags": [ "ol" ],
"function": function MD029(params, onError) { "function": function MD029(params, onError) {
var style = params.config.style || "one_or_ordered"; const style = params.config.style || "one_or_ordered";
shared.flattenLists().forEach(function forList(list) { shared.flattenLists().forEach(function forList(list) {
if (!list.unordered) { if (!list.unordered) {
var listStyle = style; let listStyle = style;
if (listStyle === "one_or_ordered") { if (listStyle === "one_or_ordered") {
var second = (list.items.length > 1) && const second = (list.items.length > 1) &&
numberRe.exec(list.items[1].line); numberRe.exec(list.items[1].line);
listStyle = (second && (second[1] !== "1")) ? "ordered" : "one"; listStyle = (second && (second[1] !== "1")) ? "ordered" : "one";
} }
var number = 1; let number = 1;
list.items.forEach(function forItem(item) { list.items.forEach(function forItem(item) {
var match = numberRe.exec(item.line); const match = numberRe.exec(item.line);
shared.addErrorDetailIf(onError, item.lineNumber, shared.addErrorDetailIf(onError, item.lineNumber,
String(number), !match || match[1], String(number), !match || match[1],
"Style: " + (listStyle === "one" ? "1/1/1" : "1/2/3"), "Style: " + (listStyle === "one" ? "1/1/1" : "1/2/3"),

View file

@ -2,25 +2,25 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD030", "list-marker-space" ], "names": [ "MD030", "list-marker-space" ],
"description": "Spaces after list markers", "description": "Spaces after list markers",
"tags": [ "ol", "ul", "whitespace" ], "tags": [ "ol", "ul", "whitespace" ],
"function": function MD030(params, onError) { "function": function MD030(params, onError) {
var ulSingle = params.config.ul_single || 1; const ulSingle = params.config.ul_single || 1;
var olSingle = params.config.ol_single || 1; const olSingle = params.config.ol_single || 1;
var ulMulti = params.config.ul_multi || 1; const ulMulti = params.config.ul_multi || 1;
var olMulti = params.config.ol_multi || 1; const olMulti = params.config.ol_multi || 1;
shared.flattenLists().forEach(function forList(list) { shared.flattenLists().forEach(function forList(list) {
var lineCount = list.lastLineIndex - list.open.map[0]; const lineCount = list.lastLineIndex - list.open.map[0];
var allSingle = lineCount === list.items.length; const allSingle = lineCount === list.items.length;
var expectedSpaces = list.unordered ? const expectedSpaces = list.unordered ?
(allSingle ? ulSingle : ulMulti) : (allSingle ? ulSingle : ulMulti) :
(allSingle ? olSingle : olMulti); (allSingle ? olSingle : olMulti);
list.items.forEach(function forItem(item) { list.items.forEach(function forItem(item) {
var match = /^[\s>]*\S+(\s+)/.exec(item.line); const match = /^[\s>]*\S+(\s+)/.exec(item.line);
shared.addErrorDetailIf(onError, item.lineNumber, shared.addErrorDetailIf(onError, item.lineNumber,
expectedSpaces, (match ? match[1].length : 0), null, expectedSpaces, (match ? match[1].length : 0), null,
shared.rangeFromRegExp(item.line, shared.listItemMarkerRe)); shared.rangeFromRegExp(item.line, shared.listItemMarkerRe));

View file

@ -2,14 +2,14 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD031", "blanks-around-fences" ], "names": [ "MD031", "blanks-around-fences" ],
"description": "Fenced code blocks should be surrounded by blank lines", "description": "Fenced code blocks should be surrounded by blank lines",
"tags": [ "code", "blank_lines" ], "tags": [ "code", "blank_lines" ],
"function": function MD031(params, onError) { "function": function MD031(params, onError) {
var lines = params.lines; const lines = params.lines;
shared.forEachLine(function forLine(line, i, inCode, onFence) { shared.forEachLine(function forLine(line, i, inCode, onFence) {
if (((onFence > 0) && (i - 1 >= 0) && lines[i - 1].length) || if (((onFence > 0) && (i - 1 >= 0) && lines[i - 1].length) ||
((onFence < 0) && (i + 1 < lines.length) && lines[i + 1].length)) { ((onFence < 0) && (i + 1 < lines.length) && lines[i + 1].length)) {

View file

@ -2,23 +2,23 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
var listItemMarkerInterruptsRe = /^[\s>]*(?:[*+-]|1\.)\s+/; const listItemMarkerInterruptsRe = /^[\s>]*(?:[*+-]|1\.)\s+/;
var blankOrListRe = /^[\s>]*($|\s)/; const blankOrListRe = /^[\s>]*($|\s)/;
module.exports = { module.exports = {
"names": [ "MD032", "blanks-around-lists" ], "names": [ "MD032", "blanks-around-lists" ],
"description": "Lists should be surrounded by blank lines", "description": "Lists should be surrounded by blank lines",
"tags": [ "bullet", "ul", "ol", "blank_lines" ], "tags": [ "bullet", "ul", "ol", "blank_lines" ],
"function": function MD032(params, onError) { "function": function MD032(params, onError) {
var inList = false; let inList = false;
var prevLine = ""; let prevLine = "";
shared.forEachLine( shared.forEachLine(
function forLine(line, lineIndex, inCode, onFence) { function forLine(line, lineIndex, inCode, onFence) {
if (!inCode || onFence) { if (!inCode || onFence) {
var lineTrim = line.trim(); const lineTrim = line.trim();
var listMarker = shared.listItemMarkerRe.test(lineTrim); let listMarker = shared.listItemMarkerRe.test(lineTrim);
if (listMarker && !inList && !blankOrListRe.test(prevLine)) { if (listMarker && !inList && !blankOrListRe.test(prevLine)) {
// Check whether this list prefix can interrupt a paragraph // Check whether this list prefix can interrupt a paragraph
if (listItemMarkerInterruptsRe.test(lineTrim)) { if (listItemMarkerInterruptsRe.test(lineTrim)) {

View file

@ -2,23 +2,23 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
var htmlRe = /<[^>]*>/; const htmlRe = /<[^>]*>/;
module.exports = { module.exports = {
"names": [ "MD033", "no-inline-html" ], "names": [ "MD033", "no-inline-html" ],
"description": "Inline HTML", "description": "Inline HTML",
"tags": [ "html" ], "tags": [ "html" ],
"function": function MD033(params, onError) { "function": function MD033(params, onError) {
var allowedElements = (params.config.allowed_elements || []) const allowedElements = (params.config.allowed_elements || [])
.map(function forElement(element) { .map(function forElement(element) {
return element.toLowerCase(); return element.toLowerCase();
}); });
function forToken(token) { function forToken(token) {
token.content.split(shared.newLineRe) token.content.split(shared.newLineRe)
.forEach(function forLine(line, offset) { .forEach(function forLine(line, offset) {
var allowed = (line.match(/<[^/\s>!]*/g) || []) const allowed = (line.match(/<[^/\s>!]*/g) || [])
.filter(function forElement(element) { .filter(function forElement(element) {
return element.length > 1; return element.length > 1;
}) })

View file

@ -2,7 +2,7 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD034", "no-bare-urls" ], "names": [ "MD034", "no-bare-urls" ],
@ -10,9 +10,9 @@ module.exports = {
"tags": [ "links", "url" ], "tags": [ "links", "url" ],
"function": function MD034(params, onError) { "function": function MD034(params, onError) {
shared.filterTokens(params, "inline", function forToken(token) { shared.filterTokens(params, "inline", function forToken(token) {
var inLink = false; let inLink = false;
token.children.forEach(function forChild(child) { token.children.forEach(function forChild(child) {
var match = null; let match = null;
if (child.type === "link_open") { if (child.type === "link_open") {
inLink = true; inLink = true;
} else if (child.type === "link_close") { } else if (child.type === "link_close") {

View file

@ -2,16 +2,16 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD035", "hr-style" ], "names": [ "MD035", "hr-style" ],
"description": "Horizontal rule style", "description": "Horizontal rule style",
"tags": [ "hr" ], "tags": [ "hr" ],
"function": function MD035(params, onError) { "function": function MD035(params, onError) {
var style = params.config.style || "consistent"; let style = params.config.style || "consistent";
shared.filterTokens(params, "hr", function forToken(token) { shared.filterTokens(params, "hr", function forToken(token) {
var lineTrim = token.line.trim(); const lineTrim = token.line.trim();
if (style === "consistent") { if (style === "consistent") {
style = lineTrim; style = lineTrim;
} }

View file

@ -2,21 +2,21 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD036", "no-emphasis-as-heading", "no-emphasis-as-header" ], "names": [ "MD036", "no-emphasis-as-heading", "no-emphasis-as-header" ],
"description": "Emphasis used instead of a heading", "description": "Emphasis used instead of a heading",
"tags": [ "headings", "headers", "emphasis" ], "tags": [ "headings", "headers", "emphasis" ],
"function": function MD036(params, onError) { "function": function MD036(params, onError) {
var punctuation = params.config.punctuation || ".,;:!?"; const punctuation = params.config.punctuation || ".,;:!?";
var re = new RegExp("[" + punctuation + "]$"); const re = new RegExp("[" + punctuation + "]$");
function base(token) { function base(token) {
if (token.type === "paragraph_open") { if (token.type === "paragraph_open") {
return function inParagraph(t) { return function inParagraph(t) {
// Always paragraph_open/inline/paragraph_close, // Always paragraph_open/inline/paragraph_close,
// omit (t.type === "inline") // omit (t.type === "inline")
var children = t.children.filter(function notEmptyText(child) { const children = t.children.filter(function notEmptyText(child) {
return (child.type !== "text") || (child.content !== ""); return (child.type !== "text") || (child.content !== "");
}); });
if ((children.length === 3) && if ((children.length === 3) &&
@ -46,7 +46,7 @@ module.exports = {
} }
return base; return base;
} }
var state = base; let state = base;
params.tokens.forEach(function forToken(token) { params.tokens.forEach(function forToken(token) {
state = state(token); state = state(token);
}); });

View file

@ -2,7 +2,7 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD037", "no-space-in-emphasis" ], "names": [ "MD037", "no-space-in-emphasis" ],
@ -10,17 +10,17 @@ module.exports = {
"tags": [ "whitespace", "emphasis" ], "tags": [ "whitespace", "emphasis" ],
"function": function MD037(params, onError) { "function": function MD037(params, onError) {
shared.forEachInlineChild(params, "text", function forToken(token) { shared.forEachInlineChild(params, "text", function forToken(token) {
var left = true; let left = true;
var match = /\s(\*\*?|__?)\s.+\1/.exec(token.content); let match = /\s(\*\*?|__?)\s.+\1/.exec(token.content);
if (!match) { if (!match) {
left = false; left = false;
match = /(\*\*?|__?).+\s\1\s/.exec(token.content); match = /(\*\*?|__?).+\s\1\s/.exec(token.content);
} }
if (match) { if (match) {
var text = match[0].trim(); const text = match[0].trim();
var line = params.lines[token.lineNumber - 1]; const line = params.lines[token.lineNumber - 1];
var column = line.indexOf(text) + 1; const column = line.indexOf(text) + 1;
var length = text.length; const length = text.length;
shared.addErrorContext(onError, token.lineNumber, shared.addErrorContext(onError, token.lineNumber,
text, left, !left, [ column, length ]); text, left, !left, [ column, length ]);
} }

View file

@ -2,9 +2,9 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
var inlineCodeSpansRe = /(?:^|[^\\])((`+)((?:.*?[^`])|)\2(?!`))/g; const inlineCodeSpansRe = /(?:^|[^\\])((`+)((?:.*?[^`])|)\2(?!`))/g;
module.exports = { module.exports = {
"names": [ "MD038", "no-space-in-code" ], "names": [ "MD038", "no-space-in-code" ],
@ -13,14 +13,14 @@ module.exports = {
"function": function MD038(params, onError) { "function": function MD038(params, onError) {
shared.forEachInlineChild(params, "code_inline", shared.forEachInlineChild(params, "code_inline",
function forToken(token) { function forToken(token) {
var line = params.lines[token.lineNumber - 1]; const line = params.lines[token.lineNumber - 1];
var match = null; let match = null;
while ((match = inlineCodeSpansRe.exec(line)) !== null) { while ((match = inlineCodeSpansRe.exec(line)) !== null) {
var inlineCodeSpan = match[1]; const inlineCodeSpan = match[1];
var content = match[3]; const content = match[3];
var length = inlineCodeSpan.length; const length = inlineCodeSpan.length;
var column = match.index + 1 + (match[0].length - length); const column = match.index + 1 + (match[0].length - length);
var range = [ column, length ]; const range = [ column, length ];
if (/^\s([^`]|$)/.test(content)) { if (/^\s([^`]|$)/.test(content)) {
shared.addErrorContext(onError, token.lineNumber, shared.addErrorContext(onError, token.lineNumber,
inlineCodeSpan, true, false, range); inlineCodeSpan, true, false, range);

View file

@ -2,9 +2,9 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
var spaceInLinkRe = /\[(?:\s+(?:[^\]]*?)\s*|(?:[^\]]*?)\s+)](?=\(\S*\))/; const spaceInLinkRe = /\[(?:\s+(?:[^\]]*?)\s*|(?:[^\]]*?)\s+)](?=\(\S*\))/;
module.exports = { module.exports = {
"names": [ "MD039", "no-space-in-links" ], "names": [ "MD039", "no-space-in-links" ],
@ -12,16 +12,16 @@ module.exports = {
"tags": [ "whitespace", "links" ], "tags": [ "whitespace", "links" ],
"function": function MD039(params, onError) { "function": function MD039(params, onError) {
shared.filterTokens(params, "inline", function forToken(token) { shared.filterTokens(params, "inline", function forToken(token) {
var inLink = false; let inLink = false;
var linkText = ""; let linkText = "";
token.children.forEach(function forChild(child) { token.children.forEach(function forChild(child) {
if (child.type === "link_open") { if (child.type === "link_open") {
inLink = true; inLink = true;
linkText = ""; linkText = "";
} else if (child.type === "link_close") { } else if (child.type === "link_close") {
inLink = false; inLink = false;
var left = shared.trimLeft(linkText).length !== linkText.length; const left = shared.trimLeft(linkText).length !== linkText.length;
var right = shared.trimRight(linkText).length !== linkText.length; const right = shared.trimRight(linkText).length !== linkText.length;
if (left || right) { if (left || right) {
shared.addErrorContext(onError, token.lineNumber, shared.addErrorContext(onError, token.lineNumber,
"[" + linkText + "]", left, right, "[" + linkText + "]", left, right,

View file

@ -2,7 +2,7 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD040", "fenced-code-language" ], "names": [ "MD040", "fenced-code-language" ],

View file

@ -2,17 +2,17 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD041", "first-line-h1" ], "names": [ "MD041", "first-line-h1" ],
"description": "First line in file should be a top level heading", "description": "First line in file should be a top level heading",
"tags": [ "headings", "headers" ], "tags": [ "headings", "headers" ],
"function": function MD041(params, onError) { "function": function MD041(params, onError) {
var level = params.config.level || 1; const level = params.config.level || 1;
var frontMatterTitle = params.config.front_matter_title; const frontMatterTitle = params.config.front_matter_title;
var tag = "h" + level; const tag = "h" + level;
var frontMatterTitleRe = const frontMatterTitleRe =
new RegExp(frontMatterTitle || "^\\s*title\\s*[:=]", "i"); new RegExp(frontMatterTitle || "^\\s*title\\s*[:=]", "i");
params.tokens.every(function forToken(token, index) { params.tokens.every(function forToken(token, index) {
if (token.type === "heading_open") { if (token.type === "heading_open") {

View file

@ -2,9 +2,9 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
var emptyLinkRe = /\[[^\]]*](?:\((?:#?|(?:<>))\))/; const emptyLinkRe = /\[[^\]]*](?:\((?:#?|(?:<>))\))/;
module.exports = { module.exports = {
"names": [ "MD042", "no-empty-links" ], "names": [ "MD042", "no-empty-links" ],
@ -12,9 +12,9 @@ module.exports = {
"tags": [ "links" ], "tags": [ "links" ],
"function": function MD042(params, onError) { "function": function MD042(params, onError) {
shared.filterTokens(params, "inline", function forToken(token) { shared.filterTokens(params, "inline", function forToken(token) {
var inLink = false; let inLink = false;
var linkText = ""; let linkText = "";
var emptyLink = false; let emptyLink = false;
token.children.forEach(function forChild(child) { token.children.forEach(function forChild(child) {
if (child.type === "link_open") { if (child.type === "link_open") {
inLink = true; inLink = true;

View file

@ -2,26 +2,26 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD043", "required-headings", "required-headers" ], "names": [ "MD043", "required-headings", "required-headers" ],
"description": "Required heading structure", "description": "Required heading structure",
"tags": [ "headings", "headers" ], "tags": [ "headings", "headers" ],
"function": function MD043(params, onError) { "function": function MD043(params, onError) {
var requiredHeadings = params.config.headings || params.config.headers; const requiredHeadings = params.config.headings || params.config.headers;
if (requiredHeadings) { if (requiredHeadings) {
var levels = {}; const levels = {};
[ 1, 2, 3, 4, 5, 6 ].forEach(function forLevel(level) { [ 1, 2, 3, 4, 5, 6 ].forEach(function forLevel(level) {
levels["h" + level] = "######".substr(-level); levels["h" + level] = "######".substr(-level);
}); });
var i = 0; let i = 0;
var optional = false; let optional = false;
var errorCount = 0; let errorCount = 0;
shared.forEachHeading(params, function forHeading(heading, content) { shared.forEachHeading(params, function forHeading(heading, content) {
if (!errorCount) { if (!errorCount) {
var actual = levels[heading.tag] + " " + content; const actual = levels[heading.tag] + " " + content;
var expected = requiredHeadings[i++] || "[None]"; const expected = requiredHeadings[i++] || "[None]";
if (expected === "*") { if (expected === "*") {
optional = true; optional = true;
} else if (expected.toLowerCase() === actual.toLowerCase()) { } else if (expected.toLowerCase() === actual.toLowerCase()) {

View file

@ -2,33 +2,33 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD044", "proper-names" ], "names": [ "MD044", "proper-names" ],
"description": "Proper names should have the correct capitalization", "description": "Proper names should have the correct capitalization",
"tags": [ "spelling" ], "tags": [ "spelling" ],
"function": function MD044(params, onError) { "function": function MD044(params, onError) {
var names = params.config.names || []; const names = params.config.names || [];
var codeBlocks = params.config.code_blocks; const codeBlocks = params.config.code_blocks;
var includeCodeBlocks = (codeBlocks === undefined) ? true : !!codeBlocks; const includeCodeBlocks = (codeBlocks === undefined) ? true : !!codeBlocks;
names.forEach(function forName(name) { names.forEach(function forName(name) {
var escapedName = shared.escapeForRegExp(name); const escapedName = shared.escapeForRegExp(name);
var namePattern = "\\S*\\b(" + escapedName + ")\\b\\S*"; const namePattern = "\\S*\\b(" + escapedName + ")\\b\\S*";
var anyNameRe = new RegExp(namePattern, "gi"); const anyNameRe = new RegExp(namePattern, "gi");
function forToken(token) { function forToken(token) {
var fenceOffset = (token.type === "fence") ? 1 : 0; const fenceOffset = (token.type === "fence") ? 1 : 0;
token.content.split(shared.newLineRe) token.content.split(shared.newLineRe)
.forEach(function forLine(line, index) { .forEach(function forLine(line, index) {
var match = null; let match = null;
while ((match = anyNameRe.exec(line)) !== null) { while ((match = anyNameRe.exec(line)) !== null) {
var fullMatch = match[0]; const fullMatch = match[0];
if (!shared.bareUrlRe.test(fullMatch)) { if (!shared.bareUrlRe.test(fullMatch)) {
var wordMatch = fullMatch const wordMatch = fullMatch
.replace(/^\W*/, "").replace(/\W*$/, ""); .replace(/^\W*/, "").replace(/\W*$/, "");
if (names.indexOf(wordMatch) === -1) { if (names.indexOf(wordMatch) === -1) {
var lineNumber = token.lineNumber + index + fenceOffset; const lineNumber = token.lineNumber + index + fenceOffset;
var range = [ match.index + 1, wordMatch.length ]; const range = [ match.index + 1, wordMatch.length ];
shared.addErrorDetailIf(onError, lineNumber, shared.addErrorDetailIf(onError, lineNumber,
name, match[1], null, range); name, match[1], null, range);
} }

View file

@ -2,7 +2,7 @@
"use strict"; "use strict";
var shared = require("./shared"); const shared = require("./shared");
module.exports = { module.exports = {
"names": [ "MD045", "no-alt-text" ], "names": [ "MD045", "no-alt-text" ],

View file

@ -9,7 +9,7 @@ module.exports.newLineRe = /\r\n|\r|\n/;
module.exports.frontMatterRe = /^(---|\+\+\+)$[^]*?^\1$(\r\n|\r|\n)/m; module.exports.frontMatterRe = /^(---|\+\+\+)$[^]*?^\1$(\r\n|\r|\n)/m;
// Regular expression for matching inline disable/enable comments // Regular expression for matching inline disable/enable comments
var inlineCommentRe = const inlineCommentRe =
/<!--\s*markdownlint-(dis|en)able((?:\s+[a-z0-9_-]+)*)\s*-->/ig; /<!--\s*markdownlint-(dis|en)able((?:\s+[a-z0-9_-]+)*)\s*-->/ig;
module.exports.inlineCommentRe = inlineCommentRe; module.exports.inlineCommentRe = inlineCommentRe;
@ -65,24 +65,24 @@ module.exports.isEmptyString = function isEmptyString(str) {
// This preserves the line/column information for the rest of the document // This preserves the line/column information for the rest of the document
// Trailing whitespace is avoided with a '\' character in the last column // Trailing whitespace is avoided with a '\' character in the last column
// See https://www.w3.org/TR/html5/syntax.html#comments for details // See https://www.w3.org/TR/html5/syntax.html#comments for details
var htmlCommentBegin = "<!--"; const htmlCommentBegin = "<!--";
var htmlCommentEnd = "-->"; const htmlCommentEnd = "-->";
module.exports.clearHtmlCommentText = function clearHtmlCommentText(text) { module.exports.clearHtmlCommentText = function clearHtmlCommentText(text) {
var i = 0; let i = 0;
while ((i = text.indexOf(htmlCommentBegin, i)) !== -1) { while ((i = text.indexOf(htmlCommentBegin, i)) !== -1) {
var j = text.indexOf(htmlCommentEnd, i); let j = text.indexOf(htmlCommentEnd, i);
if (j === -1) { if (j === -1) {
j = text.length; j = text.length;
text += "\\"; text += "\\";
} }
var comment = text.slice(i + htmlCommentBegin.length, j); const comment = text.slice(i + htmlCommentBegin.length, j);
if ((comment.length > 0) && if ((comment.length > 0) &&
(comment[0] !== ">") && (comment[0] !== ">") &&
(comment[comment.length - 1] !== "-") && (comment[comment.length - 1] !== "-") &&
(comment.indexOf("--") === -1) && (comment.indexOf("--") === -1) &&
(text.slice(i, j + htmlCommentEnd.length) (text.slice(i, j + htmlCommentEnd.length)
.search(inlineCommentRe) === -1)) { .search(inlineCommentRe) === -1)) {
var blanks = comment const blanks = comment
.replace(/[^\r\n]/g, " ") .replace(/[^\r\n]/g, " ")
.replace(/ ([\r\n])/g, "\\$1"); .replace(/ ([\r\n])/g, "\\$1");
text = text.slice(0, i + htmlCommentBegin.length) + text = text.slice(0, i + htmlCommentBegin.length) +
@ -100,7 +100,7 @@ module.exports.escapeForRegExp = function escapeForRegExp(str) {
// Returns the indent for a token // Returns the indent for a token
function indentFor(token) { function indentFor(token) {
var line = token.line.replace(/^[\s>]*(> |>)/, ""); const line = token.line.replace(/^[\s>]*(> |>)/, "");
return line.length - trimLeft(line).length; return line.length - trimLeft(line).length;
} }
module.exports.indentFor = indentFor; module.exports.indentFor = indentFor;
@ -126,7 +126,7 @@ function filterTokens(params, type, callback) {
} }
module.exports.filterTokens = filterTokens; module.exports.filterTokens = filterTokens;
var tokenCache = null; let tokenCache = null;
// Caches line metadata and flattened lists for reuse // Caches line metadata and flattened lists for reuse
function makeTokenCache(params) { function makeTokenCache(params) {
if (!params) { if (!params) {
@ -135,14 +135,14 @@ function makeTokenCache(params) {
} }
// Populate line metadata array // Populate line metadata array
var lineMetadata = new Array(params.lines.length); const lineMetadata = new Array(params.lines.length);
var fenceStart = null; let fenceStart = null;
var inFence = false; let inFence = false;
// Find fenced code by pattern (parser ignores "``` close fence") // Find fenced code by pattern (parser ignores "``` close fence")
params.lines.forEach(function forLine(line, lineIndex) { params.lines.forEach(function forLine(line, lineIndex) {
var metadata = 0; let metadata = 0;
var match = /^[ ]{0,3}(`{3,}|~{3,})/.exec(line); const match = /^[ ]{0,3}(`{3,}|~{3,})/.exec(line);
var fence = match && match[1]; const fence = match && match[1];
if (fence && if (fence &&
(!inFence || (fence.substr(0, fenceStart.length) === fenceStart))) { (!inFence || (fence.substr(0, fenceStart.length) === fenceStart))) {
metadata = inFence ? 2 : 6; metadata = inFence ? 2 : 6;
@ -155,22 +155,22 @@ function makeTokenCache(params) {
}); });
// Find code blocks normally // Find code blocks normally
filterTokens(params, "code_block", function forToken(token) { filterTokens(params, "code_block", function forToken(token) {
for (var i = token.map[0]; i < token.map[1]; i++) { for (let i = token.map[0]; i < token.map[1]; i++) {
lineMetadata[i] = 1; lineMetadata[i] = 1;
} }
}); });
// Find tables normally // Find tables normally
filterTokens(params, "table_open", function forToken(token) { filterTokens(params, "table_open", function forToken(token) {
for (var i = token.map[0]; i < token.map[1]; i++) { for (let i = token.map[0]; i < token.map[1]; i++) {
lineMetadata[i] += 8; lineMetadata[i] += 8;
} }
}); });
// Flatten lists // Flatten lists
var flattenedLists = []; const flattenedLists = [];
var stack = []; const stack = [];
var current = null; let current = null;
var lastWithMap = { "map": [ 0, 1 ] }; let lastWithMap = { "map": [ 0, 1 ] };
params.tokens.forEach(function forToken(token) { params.tokens.forEach(function forToken(token) {
if ((token.type === "bullet_list_open") || if ((token.type === "bullet_list_open") ||
(token.type === "ordered_list_open")) { (token.type === "ordered_list_open")) {
@ -217,7 +217,7 @@ module.exports.makeTokenCache = makeTokenCache;
module.exports.forEachLine = function forEachLine(callback) { module.exports.forEachLine = function forEachLine(callback) {
// Invoke callback // Invoke callback
tokenCache.params.lines.forEach(function forLine(line, lineIndex) { tokenCache.params.lines.forEach(function forLine(line, lineIndex) {
var metadata = tokenCache.lineMetadata[lineIndex]; const metadata = tokenCache.lineMetadata[lineIndex];
callback( callback(
line, line,
lineIndex, lineIndex,
@ -241,7 +241,7 @@ function forEachInlineChild(params, type, callback) {
// Calls the provided function for each heading's content // Calls the provided function for each heading's content
module.exports.forEachHeading = function forEachHeading(params, callback) { module.exports.forEachHeading = function forEachHeading(params, callback) {
var heading = null; let heading = null;
params.tokens.forEach(function forToken(token) { params.tokens.forEach(function forToken(token) {
if (token.type === "heading_open") { if (token.type === "heading_open") {
heading = token; heading = token;
@ -300,11 +300,11 @@ function addErrorContext(onError, lineNumber, context, left, right, range) {
// Returns a range object for a line by applying a RegExp // Returns a range object for a line by applying a RegExp
module.exports.rangeFromRegExp = function rangeFromRegExp(line, regexp) { module.exports.rangeFromRegExp = function rangeFromRegExp(line, regexp) {
var range = null; let range = null;
var match = line.match(regexp); const match = line.match(regexp);
if (match) { if (match) {
var column = match.index + 1; let column = match.index + 1;
var length = match[0].length; let length = match[0].length;
if (match[2]) { if (match[2]) {
column += match[1].length; column += match[1].length;
length -= match[1].length; length -= match[1].length;

View file

@ -16,7 +16,7 @@
"test-cover": "istanbul cover node_modules/nodeunit/bin/nodeunit test/markdownlint-test.js", "test-cover": "istanbul cover node_modules/nodeunit/bin/nodeunit test/markdownlint-test.js",
"test-extra": "nodeunit test/markdownlint-test-extra.js", "test-extra": "nodeunit test/markdownlint-test-extra.js",
"debug": "node debug node_modules/nodeunit/bin/nodeunit", "debug": "node debug node_modules/nodeunit/bin/nodeunit",
"lint": "eslint lib test schema && eslint --env browser --global markdownit --global markdownlint --rule \"no-unused-vars: 0, no-extend-native: 0, max-statements: 0, no-console: 0\" demo && eslint --rule \"no-console: 0, no-shadow: 0, object-property-newline: 0\" example", "lint": "eslint lib 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-shadow: 0, object-property-newline: 0\" example",
"build-config-schema": "node schema/build-config-schema.js", "build-config-schema": "node schema/build-config-schema.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 --outDir ../lib-es3 ../lib/markdownlint.js && browserify ../lib-es3/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 --outDir ../lib-es3 ../lib/markdownlint.js && browserify ../lib-es3/markdownlint.js --standalone markdownlint >> markdownlint-browser.js && uglifyjs markdownlint-browser.js --compress --mangle --comments --output markdownlint-browser.min.js",
"build-example": "npm install --no-save --ignore-scripts grunt grunt-cli gulp through2", "build-example": "npm install --no-save --ignore-scripts grunt grunt-cli gulp through2",

View file

@ -1,11 +1,11 @@
"use strict"; "use strict";
var fs = require("fs"); const fs = require("fs");
var path = require("path"); const path = require("path");
var rules = require("../lib/rules"); const rules = require("../lib/rules");
// Schema scaffolding // Schema scaffolding
var schema = { const schema = {
"title": "Markdownlint configuration schema", "title": "Markdownlint configuration schema",
"type": "object", "type": "object",
"properties": { "properties": {
@ -22,21 +22,21 @@ var schema = {
}, },
"additionalProperties": false "additionalProperties": false
}; };
var tags = {}; const tags = {};
// Add rules // Add rules
rules.forEach(function forRule(rule) { rules.forEach(function forRule(rule) {
rule.tags.forEach(function forTag(tag) { rule.tags.forEach(function forTag(tag) {
var tagRules = tags[tag] || []; const tagRules = tags[tag] || [];
tagRules.push(rule.names[0]); tagRules.push(rule.names[0]);
tags[tag] = tagRules; tags[tag] = tagRules;
}); });
var scheme = { const scheme = {
"description": rule.names.join("/") + " - " + rule.description, "description": rule.names.join("/") + " - " + rule.description,
"type": "boolean", "type": "boolean",
"default": true "default": true
}; };
var custom = true; let custom = true;
switch (rule.names[0]) { switch (rule.names[0]) {
case "MD002": case "MD002":
case "MD025": case "MD025":
@ -286,7 +286,7 @@ rules.forEach(function forRule(rule) {
// Add tags // Add tags
Object.keys(tags).forEach(function forTag(tag) { Object.keys(tags).forEach(function forTag(tag) {
var scheme = { const scheme = {
"description": tag + " - " + tags[tag].join(", "), "description": tag + " - " + tags[tag].join(", "),
"type": "boolean", "type": "boolean",
"default": true "default": true
@ -295,5 +295,5 @@ Object.keys(tags).forEach(function forTag(tag) {
}); });
// Write schema // Write schema
var schemaFile = path.join(__dirname, "markdownlint-config-schema.json"); const schemaFile = path.join(__dirname, "markdownlint-config-schema.json");
fs.writeFileSync(schemaFile, JSON.stringify(schema, null, " ")); fs.writeFileSync(schemaFile, JSON.stringify(schema, null, " "));

View file

@ -1,21 +1,21 @@
"use strict"; "use strict";
var fs = require("fs"); const fs = require("fs");
var path = require("path"); const path = require("path");
var glob = require("glob"); const glob = require("glob");
var markdownlint = require("../lib/markdownlint"); const markdownlint = require("../lib/markdownlint");
var shared = require("../lib/shared"); const shared = require("../lib/shared");
module.exports.typeTestFiles = function typeTestFiles(test) { module.exports.typeTestFiles = function typeTestFiles(test) {
// Simulates typing each test file to validate handling of partial input // Simulates typing each test file to validate handling of partial input
function validate(file, content) { function validate(file, content) {
var results = markdownlint.sync({ const results = markdownlint.sync({
"strings": { "strings": {
"content": content "content": content
}, },
"resultVersion": 0 "resultVersion": 0
}); });
var contentLineCount = content.split(shared.newLineRe).length; const contentLineCount = content.split(shared.newLineRe).length;
Object.keys(results.content).forEach(function forKey(ruleName) { Object.keys(results.content).forEach(function forKey(ruleName) {
results.content[ruleName].forEach(function forLine(line) { results.content[ruleName].forEach(function forLine(line) {
test.ok((line >= 1) && (line <= contentLineCount), test.ok((line >= 1) && (line <= contentLineCount),
@ -24,10 +24,10 @@ module.exports.typeTestFiles = function typeTestFiles(test) {
}); });
}); });
} }
var files = fs.readdirSync("./test"); const files = fs.readdirSync("./test");
files.forEach(function forFile(file) { files.forEach(function forFile(file) {
if (/\.md$/.test(file)) { if (/\.md$/.test(file)) {
var content = fs.readFileSync( let content = fs.readFileSync(
path.join("./test", file), shared.utf8Encoding); path.join("./test", file), shared.utf8Encoding);
while (content) { while (content) {
validate(file, content); validate(file, content);
@ -40,13 +40,13 @@ module.exports.typeTestFiles = function typeTestFiles(test) {
module.exports.parseAllFiles = function parseAllFiles(test) { module.exports.parseAllFiles = function parseAllFiles(test) {
// Parses all Markdown files in all dependencies // Parses all Markdown files in all dependencies
var globOptions = { const globOptions = {
// "cwd": "/", // "cwd": "/",
"realpath": true "realpath": true
}; };
glob("**/*.{md,markdown}", globOptions, function globCallback(err, matches) { glob("**/*.{md,markdown}", globOptions, function globCallback(err, matches) {
test.ifError(err); test.ifError(err);
var markdownlintOptions = { const markdownlintOptions = {
"files": matches "files": matches
}; };
markdownlint(markdownlintOptions, function markdownlintCallback(errr) { markdownlint(markdownlintOptions, function markdownlintCallback(errr) {

View file

@ -1,24 +1,24 @@
"use strict"; "use strict";
var fs = require("fs"); const fs = require("fs");
var path = require("path"); const path = require("path");
var md = require("markdown-it")(); const md = require("markdown-it")();
var Q = require("q"); const Q = require("q");
var tv4 = require("tv4"); const tv4 = require("tv4");
var markdownlint = require("../lib/markdownlint"); const markdownlint = require("../lib/markdownlint");
var shared = require("../lib/shared"); const shared = require("../lib/shared");
var rules = require("../lib/rules"); const rules = require("../lib/rules");
var customRules = require("./rules"); const customRules = require("./rules");
var defaultConfig = require("./markdownlint-test-default-config.json"); const defaultConfig = require("./markdownlint-test-default-config.json");
var configSchema = require("../schema/markdownlint-config-schema.json"); const configSchema = require("../schema/markdownlint-config-schema.json");
function createTestForFile(file) { function createTestForFile(file) {
return function testForFile(test) { return function testForFile(test) {
test.expect(1); test.expect(1);
var detailedResults = /[/\\]detailed-results-/.test(file); const detailedResults = /[/\\]detailed-results-/.test(file);
var resultsFile = file.replace(/\.md$/, ".results.json"); const resultsFile = file.replace(/\.md$/, ".results.json");
var configFile = file.replace(/\.md$/, ".json"); const configFile = file.replace(/\.md$/, ".json");
var actualPromise = Q.nfcall(fs.stat, configFile) const actualPromise = Q.nfcall(fs.stat, configFile)
.then( .then(
function configFileExists() { function configFileExists() {
return Q.nfcall(fs.readFile, configFile, shared.utf8Encoding) return Q.nfcall(fs.readFile, configFile, shared.utf8Encoding)
@ -29,32 +29,33 @@ function createTestForFile(file) {
}) })
.then( .then(
function lintWithConfig(config) { function lintWithConfig(config) {
var mergedConfig = shared.assign(shared.clone(defaultConfig), config); const mergedConfig =
shared.assign(shared.clone(defaultConfig), config);
return Q.nfcall(markdownlint, { return Q.nfcall(markdownlint, {
"files": [ file ], "files": [ file ],
"config": mergedConfig, "config": mergedConfig,
"resultVersion": detailedResults ? 2 : 0 "resultVersion": detailedResults ? 2 : 0
}); });
}); });
var expectedPromise = detailedResults ? const expectedPromise = detailedResults ?
Q.nfcall(fs.readFile, resultsFile, shared.utf8Encoding) Q.nfcall(fs.readFile, resultsFile, shared.utf8Encoding)
.then(JSON.parse) : .then(JSON.parse) :
Q.nfcall(fs.readFile, file, shared.utf8Encoding) Q.nfcall(fs.readFile, file, shared.utf8Encoding)
.then( .then(
function fileContents(contents) { function fileContents(contents) {
var lines = contents.split(shared.newLineRe); const lines = contents.split(shared.newLineRe);
var results = {}; const results = {};
lines.forEach(function forLine(line, lineNum) { lines.forEach(function forLine(line, lineNum) {
var regex = /\{(MD\d+)(?::(\d+))?\}/g; const regex = /\{(MD\d+)(?::(\d+))?\}/g;
var match = null; let match = null;
while ((match = regex.exec(line))) { while ((match = regex.exec(line))) {
var rule = match[1]; const rule = match[1];
var errors = results[rule] || []; const errors = results[rule] || [];
errors.push(match[2] ? parseInt(match[2], 10) : lineNum + 1); errors.push(match[2] ? parseInt(match[2], 10) : lineNum + 1);
results[rule] = errors; results[rule] = errors;
} }
}); });
var sortedResults = {}; const sortedResults = {};
Object.keys(results).sort().forEach(function forKey(key) { Object.keys(results).sort().forEach(function forKey(key) {
sortedResults[key] = results[key]; sortedResults[key] = results[key];
}); });
@ -63,9 +64,9 @@ function createTestForFile(file) {
Q.all([ actualPromise, expectedPromise ]) Q.all([ actualPromise, expectedPromise ])
.then( .then(
function compareResults(fulfillments) { function compareResults(fulfillments) {
var actual = fulfillments[0]; const actual = fulfillments[0];
var results = fulfillments[1]; const results = fulfillments[1];
var expected = {}; const expected = {};
expected[file] = results; expected[file] = results;
test.deepEqual(actual, expected, "Line numbers are not correct."); test.deepEqual(actual, expected, "Line numbers are not correct.");
}) })
@ -81,7 +82,7 @@ fs.readdirSync("./test").forEach(function forFile(file) {
module.exports.projectFiles = function projectFiles(test) { module.exports.projectFiles = function projectFiles(test) {
test.expect(2); test.expect(2);
var options = { const options = {
"files": [ "README.md" ], "files": [ "README.md" ],
"noInlineConfig": true, "noInlineConfig": true,
"config": { "config": {
@ -91,7 +92,7 @@ module.exports.projectFiles = function projectFiles(test) {
}; };
markdownlint(options, function callback(err, actual) { markdownlint(options, function callback(err, actual) {
test.ifError(err); test.ifError(err);
var expected = { "README.md": [] }; const expected = { "README.md": [] };
test.deepEqual(actual, expected, "Issue(s) with project files."); test.deepEqual(actual, expected, "Issue(s) with project files.");
test.done(); test.done();
}); });
@ -99,7 +100,7 @@ module.exports.projectFiles = function projectFiles(test) {
module.exports.resultFormattingV0 = function resultFormattingV0(test) { module.exports.resultFormattingV0 = function resultFormattingV0(test) {
test.expect(4); test.expect(4);
var options = { const options = {
"files": [ "files": [
"./test/atx_heading_spacing.md", "./test/atx_heading_spacing.md",
"./test/first_heading_bad_atx.md" "./test/first_heading_bad_atx.md"
@ -109,7 +110,7 @@ module.exports.resultFormattingV0 = function resultFormattingV0(test) {
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"./test/atx_heading_spacing.md": { "./test/atx_heading_spacing.md": {
"MD002": [ 3 ], "MD002": [ 3 ],
"MD018": [ 1 ], "MD018": [ 1 ],
@ -120,8 +121,8 @@ module.exports.resultFormattingV0 = function resultFormattingV0(test) {
} }
}; };
test.deepEqual(actualResult, expectedResult, "Undetected issues."); test.deepEqual(actualResult, expectedResult, "Undetected issues.");
var actualMessage = actualResult.toString(); let actualMessage = actualResult.toString();
var expectedMessage = let expectedMessage =
"./test/atx_heading_spacing.md: 3: MD002" + "./test/atx_heading_spacing.md: 3: MD002" +
" First heading should be a top level heading\n" + " First heading should be a top level heading\n" +
"./test/atx_heading_spacing.md: 1: MD018" + "./test/atx_heading_spacing.md: 1: MD018" +
@ -152,7 +153,7 @@ module.exports.resultFormattingV0 = function resultFormattingV0(test) {
module.exports.resultFormattingSyncV0 = function resultFormattingSyncV0(test) { module.exports.resultFormattingSyncV0 = function resultFormattingSyncV0(test) {
test.expect(3); test.expect(3);
var options = { const options = {
"files": [ "files": [
"./test/atx_heading_spacing.md", "./test/atx_heading_spacing.md",
"./test/first_heading_bad_atx.md" "./test/first_heading_bad_atx.md"
@ -160,8 +161,8 @@ module.exports.resultFormattingSyncV0 = function resultFormattingSyncV0(test) {
"config": defaultConfig, "config": defaultConfig,
"resultVersion": 0 "resultVersion": 0
}; };
var actualResult = markdownlint.sync(options); const actualResult = markdownlint.sync(options);
var expectedResult = { const expectedResult = {
"./test/atx_heading_spacing.md": { "./test/atx_heading_spacing.md": {
"MD002": [ 3 ], "MD002": [ 3 ],
"MD018": [ 1 ], "MD018": [ 1 ],
@ -172,8 +173,8 @@ module.exports.resultFormattingSyncV0 = function resultFormattingSyncV0(test) {
} }
}; };
test.deepEqual(actualResult, expectedResult, "Undetected issues."); test.deepEqual(actualResult, expectedResult, "Undetected issues.");
var actualMessage = actualResult.toString(); let actualMessage = actualResult.toString();
var expectedMessage = let expectedMessage =
"./test/atx_heading_spacing.md: 3: MD002" + "./test/atx_heading_spacing.md: 3: MD002" +
" First heading should be a top level heading\n" + " First heading should be a top level heading\n" +
"./test/atx_heading_spacing.md: 1: MD018" + "./test/atx_heading_spacing.md: 1: MD018" +
@ -203,7 +204,7 @@ module.exports.resultFormattingSyncV0 = function resultFormattingSyncV0(test) {
module.exports.resultFormattingV1 = function resultFormattingV1(test) { module.exports.resultFormattingV1 = function resultFormattingV1(test) {
test.expect(3); test.expect(3);
var options = { const options = {
"strings": { "strings": {
"truncate": "truncate":
"# Multiple spaces inside hashes on closed atx style heading #" "# Multiple spaces inside hashes on closed atx style heading #"
@ -217,7 +218,7 @@ module.exports.resultFormattingV1 = function resultFormattingV1(test) {
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"truncate": [ "truncate": [
{ "lineNumber": 1, { "lineNumber": 1,
"ruleName": "MD021", "ruleName": "MD021",
@ -269,8 +270,8 @@ module.exports.resultFormattingV1 = function resultFormattingV1(test) {
] ]
}; };
test.deepEqual(actualResult, expectedResult, "Undetected issues."); test.deepEqual(actualResult, expectedResult, "Undetected issues.");
var actualMessage = actualResult.toString(); const actualMessage = actualResult.toString();
var expectedMessage = const expectedMessage =
"truncate: 1: MD021/no-multiple-space-closed-atx" + "truncate: 1: MD021/no-multiple-space-closed-atx" +
" Multiple spaces inside hashes on closed atx style heading" + " Multiple spaces inside hashes on closed atx style heading" +
" [Context: \"# Multiple spa...tyle heading #\"]\n" + " [Context: \"# Multiple spa...tyle heading #\"]\n" +
@ -296,7 +297,7 @@ module.exports.resultFormattingV1 = function resultFormattingV1(test) {
module.exports.resultFormattingV2 = function resultFormattingV2(test) { module.exports.resultFormattingV2 = function resultFormattingV2(test) {
test.expect(3); test.expect(3);
var options = { const options = {
"strings": { "strings": {
"truncate": "truncate":
"# Multiple spaces inside hashes on closed atx style heading #" "# Multiple spaces inside hashes on closed atx style heading #"
@ -309,7 +310,7 @@ module.exports.resultFormattingV2 = function resultFormattingV2(test) {
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"truncate": [ "truncate": [
{ "lineNumber": 1, { "lineNumber": 1,
"ruleNames": [ "MD021", "no-multiple-space-closed-atx" ], "ruleNames": [ "MD021", "no-multiple-space-closed-atx" ],
@ -355,8 +356,8 @@ module.exports.resultFormattingV2 = function resultFormattingV2(test) {
] ]
}; };
test.deepEqual(actualResult, expectedResult, "Undetected issues."); test.deepEqual(actualResult, expectedResult, "Undetected issues.");
var actualMessage = actualResult.toString(); const actualMessage = actualResult.toString();
var expectedMessage = const expectedMessage =
"truncate: 1: MD021/no-multiple-space-closed-atx" + "truncate: 1: MD021/no-multiple-space-closed-atx" +
" Multiple spaces inside hashes on closed atx style heading" + " Multiple spaces inside hashes on closed atx style heading" +
" [Context: \"# Multiple spa...tyle heading #\"]\n" + " [Context: \"# Multiple spa...tyle heading #\"]\n" +
@ -384,7 +385,7 @@ module.exports.resultFormattingV2 = function resultFormattingV2(test) {
module.exports.stringInputLineEndings = function stringInputLineEndings(test) { module.exports.stringInputLineEndings = function stringInputLineEndings(test) {
test.expect(2); test.expect(2);
var options = { const options = {
"strings": { "strings": {
"cr": "One\rTwo\r#Three", "cr": "One\rTwo\r#Three",
"lf": "One\nTwo\n#Three", "lf": "One\nTwo\n#Three",
@ -396,7 +397,7 @@ module.exports.stringInputLineEndings = function stringInputLineEndings(test) {
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"cr": { "MD018": [ 3 ] }, "cr": { "MD018": [ 3 ] },
"lf": { "MD018": [ 3 ] }, "lf": { "MD018": [ 3 ] },
"crlf": { "MD018": [ 3 ] }, "crlf": { "MD018": [ 3 ] },
@ -409,7 +410,7 @@ module.exports.stringInputLineEndings = function stringInputLineEndings(test) {
module.exports.inputOnlyNewline = function inputOnlyNewline(test) { module.exports.inputOnlyNewline = function inputOnlyNewline(test) {
test.expect(2); test.expect(2);
var options = { const options = {
"strings": { "strings": {
"cr": "\r", "cr": "\r",
"lf": "\n", "lf": "\n",
@ -421,7 +422,7 @@ module.exports.inputOnlyNewline = function inputOnlyNewline(test) {
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"cr": [], "cr": [],
"lf": [], "lf": [],
"crlf": [] "crlf": []
@ -433,7 +434,7 @@ module.exports.inputOnlyNewline = function inputOnlyNewline(test) {
module.exports.defaultTrue = function defaultTrue(test) { module.exports.defaultTrue = function defaultTrue(test) {
test.expect(2); test.expect(2);
var options = { const options = {
"files": [ "files": [
"./test/atx_heading_spacing.md", "./test/atx_heading_spacing.md",
"./test/first_heading_bad_atx.md" "./test/first_heading_bad_atx.md"
@ -445,7 +446,7 @@ module.exports.defaultTrue = function defaultTrue(test) {
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"./test/atx_heading_spacing.md": { "./test/atx_heading_spacing.md": {
"MD002": [ 3 ], "MD002": [ 3 ],
"MD018": [ 1 ], "MD018": [ 1 ],
@ -464,7 +465,7 @@ module.exports.defaultTrue = function defaultTrue(test) {
module.exports.defaultFalse = function defaultFalse(test) { module.exports.defaultFalse = function defaultFalse(test) {
test.expect(2); test.expect(2);
var options = { const options = {
"files": [ "files": [
"./test/atx_heading_spacing.md", "./test/atx_heading_spacing.md",
"./test/first_heading_bad_atx.md" "./test/first_heading_bad_atx.md"
@ -476,7 +477,7 @@ module.exports.defaultFalse = function defaultFalse(test) {
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"./test/atx_heading_spacing.md": {}, "./test/atx_heading_spacing.md": {},
"./test/first_heading_bad_atx.md": {} "./test/first_heading_bad_atx.md": {}
}; };
@ -487,7 +488,7 @@ module.exports.defaultFalse = function defaultFalse(test) {
module.exports.defaultUndefined = function defaultUndefined(test) { module.exports.defaultUndefined = function defaultUndefined(test) {
test.expect(2); test.expect(2);
var options = { const options = {
"files": [ "files": [
"./test/atx_heading_spacing.md", "./test/atx_heading_spacing.md",
"./test/first_heading_bad_atx.md" "./test/first_heading_bad_atx.md"
@ -497,7 +498,7 @@ module.exports.defaultUndefined = function defaultUndefined(test) {
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"./test/atx_heading_spacing.md": { "./test/atx_heading_spacing.md": {
"MD002": [ 3 ], "MD002": [ 3 ],
"MD018": [ 1 ], "MD018": [ 1 ],
@ -516,7 +517,7 @@ module.exports.defaultUndefined = function defaultUndefined(test) {
module.exports.disableRules = function disableRules(test) { module.exports.disableRules = function disableRules(test) {
test.expect(2); test.expect(2);
var options = { const options = {
"files": [ "files": [
"./test/atx_heading_spacing.md", "./test/atx_heading_spacing.md",
"./test/first_heading_bad_atx.md" "./test/first_heading_bad_atx.md"
@ -531,7 +532,7 @@ module.exports.disableRules = function disableRules(test) {
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"./test/atx_heading_spacing.md": { "./test/atx_heading_spacing.md": {
"MD018": [ 1 ] "MD018": [ 1 ]
}, },
@ -544,7 +545,7 @@ module.exports.disableRules = function disableRules(test) {
module.exports.enableRules = function enableRules(test) { module.exports.enableRules = function enableRules(test) {
test.expect(2); test.expect(2);
var options = { const options = {
"files": [ "files": [
"./test/atx_heading_spacing.md", "./test/atx_heading_spacing.md",
"./test/first_heading_bad_atx.md" "./test/first_heading_bad_atx.md"
@ -558,7 +559,7 @@ module.exports.enableRules = function enableRules(test) {
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"./test/atx_heading_spacing.md": { "./test/atx_heading_spacing.md": {
"MD002": [ 3 ], "MD002": [ 3 ],
"MD019": [ 3, 5 ] "MD019": [ 3, 5 ]
@ -574,7 +575,7 @@ module.exports.enableRules = function enableRules(test) {
module.exports.enableRulesMixedCase = function enableRulesMixedCase(test) { module.exports.enableRulesMixedCase = function enableRulesMixedCase(test) {
test.expect(2); test.expect(2);
var options = { const options = {
"files": [ "files": [
"./test/atx_heading_spacing.md", "./test/atx_heading_spacing.md",
"./test/first_heading_bad_atx.md" "./test/first_heading_bad_atx.md"
@ -588,7 +589,7 @@ module.exports.enableRulesMixedCase = function enableRulesMixedCase(test) {
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"./test/atx_heading_spacing.md": { "./test/atx_heading_spacing.md": {
"MD002": [ 3 ], "MD002": [ 3 ],
"MD019": [ 3, 5 ] "MD019": [ 3, 5 ]
@ -604,7 +605,7 @@ module.exports.enableRulesMixedCase = function enableRulesMixedCase(test) {
module.exports.disableTag = function disableTag(test) { module.exports.disableTag = function disableTag(test) {
test.expect(2); test.expect(2);
var options = { const options = {
"files": [ "files": [
"./test/atx_heading_spacing.md", "./test/atx_heading_spacing.md",
"./test/first_heading_bad_atx.md" "./test/first_heading_bad_atx.md"
@ -617,7 +618,7 @@ module.exports.disableTag = function disableTag(test) {
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"./test/atx_heading_spacing.md": { "./test/atx_heading_spacing.md": {
"MD002": [ 3 ], "MD002": [ 3 ],
"MD041": [ 1 ] "MD041": [ 1 ]
@ -634,7 +635,7 @@ module.exports.disableTag = function disableTag(test) {
module.exports.enableTag = function enableTag(test) { module.exports.enableTag = function enableTag(test) {
test.expect(2); test.expect(2);
var options = { const options = {
"files": [ "files": [
"./test/atx_heading_spacing.md", "./test/atx_heading_spacing.md",
"./test/first_heading_bad_atx.md" "./test/first_heading_bad_atx.md"
@ -648,7 +649,7 @@ module.exports.enableTag = function enableTag(test) {
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"./test/atx_heading_spacing.md": { "./test/atx_heading_spacing.md": {
"MD018": [ 1 ], "MD018": [ 1 ],
"MD019": [ 3, 5 ] "MD019": [ 3, 5 ]
@ -662,7 +663,7 @@ module.exports.enableTag = function enableTag(test) {
module.exports.enableTagMixedCase = function enableTagMixedCase(test) { module.exports.enableTagMixedCase = function enableTagMixedCase(test) {
test.expect(2); test.expect(2);
var options = { const options = {
"files": [ "files": [
"./test/atx_heading_spacing.md", "./test/atx_heading_spacing.md",
"./test/first_heading_bad_atx.md" "./test/first_heading_bad_atx.md"
@ -676,7 +677,7 @@ module.exports.enableTagMixedCase = function enableTagMixedCase(test) {
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"./test/atx_heading_spacing.md": { "./test/atx_heading_spacing.md": {
"MD018": [ 1 ], "MD018": [ 1 ],
"MD019": [ 3, 5 ] "MD019": [ 3, 5 ]
@ -701,14 +702,14 @@ module.exports.styleFiles = function styleFiles(test) {
module.exports.styleAll = function styleAll(test) { module.exports.styleAll = function styleAll(test) {
test.expect(2); test.expect(2);
var options = { const options = {
"files": [ "./test/break-all-the-rules.md" ], "files": [ "./test/break-all-the-rules.md" ],
"config": require("../style/all.json"), "config": require("../style/all.json"),
"resultVersion": 0 "resultVersion": 0
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"./test/break-all-the-rules.md": { "./test/break-all-the-rules.md": {
"MD001": [ 3 ], "MD001": [ 3 ],
"MD002": [ 1 ], "MD002": [ 1 ],
@ -757,14 +758,14 @@ module.exports.styleAll = function styleAll(test) {
module.exports.styleRelaxed = function styleRelaxed(test) { module.exports.styleRelaxed = function styleRelaxed(test) {
test.expect(2); test.expect(2);
var options = { const options = {
"files": [ "./test/break-all-the-rules.md" ], "files": [ "./test/break-all-the-rules.md" ],
"config": require("../style/relaxed.json"), "config": require("../style/relaxed.json"),
"resultVersion": 0 "resultVersion": 0
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"./test/break-all-the-rules.md": { "./test/break-all-the-rules.md": {
"MD001": [ 3 ], "MD001": [ 3 ],
"MD002": [ 1 ], "MD002": [ 1 ],
@ -809,7 +810,7 @@ module.exports.nullFrontMatter = function nullFrontMatter(test) {
"resultVersion": 0 "resultVersion": 0
}, function callback(err, result) { }, function callback(err, result) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"content": { "MD010": [ 2 ] } "content": { "MD010": [ 2 ] }
}; };
test.deepEqual(result, expectedResult, "Undetected issues."); test.deepEqual(result, expectedResult, "Undetected issues.");
@ -830,7 +831,7 @@ module.exports.customFrontMatter = function customFrontMatter(test) {
} }
}, function callback(err, result) { }, function callback(err, result) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"content": [] "content": []
}; };
test.deepEqual(result, expectedResult, "Did not get empty results."); test.deepEqual(result, expectedResult, "Did not get empty results.");
@ -860,7 +861,7 @@ module.exports.noInlineConfig = function noInlineConfig(test) {
"resultVersion": 0 "resultVersion": 0
}, function callback(err, result) { }, function callback(err, result) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"content": { "content": {
"MD010": [ 3, 7, 11 ] "MD010": [ 3, 7, 11 ]
} }
@ -915,7 +916,7 @@ module.exports.readmeHeadings = function readmeHeadings(test) {
} }
}, function callback(err, result) { }, function callback(err, result) {
test.ifError(err); test.ifError(err);
var expected = { "README.md": [] }; const expected = { "README.md": [] };
test.deepEqual(result, expected, "Unexpected issues."); test.deepEqual(result, expected, "Unexpected issues.");
test.done(); test.done();
}); });
@ -923,11 +924,11 @@ module.exports.readmeHeadings = function readmeHeadings(test) {
module.exports.filesArrayNotModified = function filesArrayNotModified(test) { module.exports.filesArrayNotModified = function filesArrayNotModified(test) {
test.expect(2); test.expect(2);
var files = [ const files = [
"./test/atx_heading_spacing.md", "./test/atx_heading_spacing.md",
"./test/first_heading_bad_atx.md" "./test/first_heading_bad_atx.md"
]; ];
var expectedFiles = files.slice(); const expectedFiles = files.slice();
markdownlint({ "files": files }, function callback(err) { markdownlint({ "files": files }, function callback(err) {
test.ifError(err); test.ifError(err);
test.deepEqual(files, expectedFiles, "Files modified."); test.deepEqual(files, expectedFiles, "Files modified.");
@ -946,7 +947,7 @@ module.exports.filesArrayAsString = function filesArrayAsString(test) {
} }
}, function callback(err, actual) { }, function callback(err, actual) {
test.ifError(err); test.ifError(err);
var expected = { "README.md": [] }; const expected = { "README.md": [] };
test.deepEqual(actual, expected, "Unexpected issues."); test.deepEqual(actual, expected, "Unexpected issues.");
test.done(); test.done();
}); });
@ -1015,7 +1016,7 @@ module.exports.missingStringValue = function missingStringValue(test) {
"config": defaultConfig "config": defaultConfig
}, function callback(err, result) { }, function callback(err, result) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"undefined": [], "undefined": [],
"null": [], "null": [],
"empty": [] "empty": []
@ -1027,10 +1028,10 @@ module.exports.missingStringValue = function missingStringValue(test) {
module.exports.readme = function readme(test) { module.exports.readme = function readme(test) {
test.expect(109); test.expect(109);
var tagToRules = {}; const tagToRules = {};
rules.forEach(function forRule(rule) { rules.forEach(function forRule(rule) {
rule.tags.forEach(function forTag(tag) { rule.tags.forEach(function forTag(tag) {
var tagRules = tagToRules[tag] || []; const tagRules = tagToRules[tag] || [];
tagRules.push(rule.names[0]); tagRules.push(rule.names[0]);
tagToRules[tag] = tagRules; tagToRules[tag] = tagRules;
}); });
@ -1038,12 +1039,12 @@ module.exports.readme = function readme(test) {
fs.readFile("README.md", shared.utf8Encoding, fs.readFile("README.md", shared.utf8Encoding,
function readFile(err, contents) { function readFile(err, contents) {
test.ifError(err); test.ifError(err);
var rulesLeft = rules.slice(); const rulesLeft = rules.slice();
var seenRelated = false; let seenRelated = false;
var seenRules = false; let seenRules = false;
var inRules = false; let inRules = false;
var seenTags = false; let seenTags = false;
var inTags = false; let inTags = false;
md.parse(contents, {}).forEach(function forToken(token) { md.parse(contents, {}).forEach(function forToken(token) {
if (token.type === "bullet_list_open") { if (token.type === "bullet_list_open") {
if (!seenRelated) { if (!seenRelated) {
@ -1057,31 +1058,32 @@ module.exports.readme = function readme(test) {
inRules = inTags = false; inRules = inTags = false;
} else if (token.type === "inline") { } else if (token.type === "inline") {
if (inRules) { if (inRules) {
var rule = rulesLeft.shift(); const rule = rulesLeft.shift();
test.ok(rule, test.ok(rule,
"Missing rule implementation for " + token.content + "."); "Missing rule implementation for " + token.content + ".");
if (rule) { if (rule) {
var ruleName = rule.names[0]; const ruleName = rule.names[0];
var ruleAliases = rule.names.slice(1); const ruleAliases = rule.names.slice(1);
var expected = "**[" + ruleName + "](doc/Rules.md#" + const expected = "**[" + ruleName + "](doc/Rules.md#" +
ruleName.toLowerCase() + ")** *" + ruleName.toLowerCase() + ")** *" +
ruleAliases.join("/") + "* - " + rule.description; ruleAliases.join("/") + "* - " + rule.description;
test.equal(token.content, expected, "Rule mismatch."); test.equal(token.content, expected, "Rule mismatch.");
} }
} else if (inTags) { } else if (inTags) {
var parts = token.content.replace(/\*\*/g, "").split(/ - |, |,\n/); const parts =
var tag = parts.shift(); token.content.replace(/\*\*/g, "").split(/ - |, |,\n/);
const tag = parts.shift();
test.deepEqual(parts, tagToRules[tag] || [], test.deepEqual(parts, tagToRules[tag] || [],
"Rule mismatch for tag " + tag + "."); "Rule mismatch for tag " + tag + ".");
delete tagToRules[tag]; delete tagToRules[tag];
} }
} }
}); });
var ruleLeft = rulesLeft.shift(); const ruleLeft = rulesLeft.shift();
test.ok(!ruleLeft, test.ok(!ruleLeft,
"Missing rule documentation for " + "Missing rule documentation for " +
(ruleLeft || "[NO RULE]").toString() + "."); (ruleLeft || "[NO RULE]").toString() + ".");
var tagLeft = Object.keys(tagToRules).shift(); const tagLeft = Object.keys(tagToRules).shift();
test.ok(!tagLeft, "Undocumented tag " + tagLeft + "."); test.ok(!tagLeft, "Undocumented tag " + tagLeft + ".");
test.done(); test.done();
}); });
@ -1092,13 +1094,13 @@ module.exports.doc = function doc(test) {
fs.readFile("doc/Rules.md", shared.utf8Encoding, fs.readFile("doc/Rules.md", shared.utf8Encoding,
function readFile(err, contents) { function readFile(err, contents) {
test.ifError(err); test.ifError(err);
var rulesLeft = rules.slice(); const rulesLeft = rules.slice();
var inHeading = false; let inHeading = false;
var rule = null; let rule = null;
var ruleHasTags = true; let ruleHasTags = true;
var ruleHasAliases = true; let ruleHasAliases = true;
var ruleUsesParams = null; let ruleUsesParams = null;
var tagAliasParameterRe = /, |: | /; const tagAliasParameterRe = /, |: | /;
function testTagsAliasesParams(r) { function testTagsAliasesParams(r) {
r = r || "[NO RULE]"; r = r || "[NO RULE]";
test.ok(ruleHasTags, test.ok(ruleHasTags,
@ -1140,8 +1142,8 @@ module.exports.doc = function doc(test) {
"Alias mismatch for rule " + rule.toString() + "."); "Alias mismatch for rule " + rule.toString() + ".");
ruleHasAliases = true; ruleHasAliases = true;
} else if (/^Parameters: /.test(token.content) && rule) { } else if (/^Parameters: /.test(token.content) && rule) {
var inDetails = false; let inDetails = false;
var parameters = token.content.split(tagAliasParameterRe) const parameters = token.content.split(tagAliasParameterRe)
.slice(1) .slice(1)
.filter(function forPart(part) { .filter(function forPart(part) {
inDetails = inDetails || (part[0] === "("); inDetails = inDetails || (part[0] === "(");
@ -1153,7 +1155,7 @@ module.exports.doc = function doc(test) {
} }
} }
}); });
var ruleLeft = rulesLeft.shift(); const ruleLeft = rulesLeft.shift();
test.ok(!ruleLeft, test.ok(!ruleLeft,
"Missing rule documentation for " + "Missing rule documentation for " +
(ruleLeft || "[NO RULE]").toString() + "."); (ruleLeft || "[NO RULE]").toString() + ".");
@ -1165,14 +1167,14 @@ module.exports.doc = function doc(test) {
}; };
module.exports.validateConfigSchema = function validateConfigSchema(test) { module.exports.validateConfigSchema = function validateConfigSchema(test) {
var jsonFileRe = /\.json$/i; const jsonFileRe = /\.json$/i;
var resultsFileRe = /\.results\.json$/i; const resultsFileRe = /\.results\.json$/i;
var testDirectory = __dirname; const testDirectory = __dirname;
var testFiles = fs.readdirSync(testDirectory); const testFiles = fs.readdirSync(testDirectory);
testFiles.filter(function filterFile(file) { testFiles.filter(function filterFile(file) {
return jsonFileRe.test(file) && !resultsFileRe.test(file); return jsonFileRe.test(file) && !resultsFileRe.test(file);
}).forEach(function forFile(file) { }).forEach(function forFile(file) {
var data = fs.readFileSync(path.join(testDirectory, file)); const data = fs.readFileSync(path.join(testDirectory, file));
test.ok( test.ok(
tv4.validate(JSON.parse(data), configSchema), tv4.validate(JSON.parse(data), configSchema),
file + "\n" + JSON.stringify(tv4.error, null, 2)); file + "\n" + JSON.stringify(tv4.error, null, 2));
@ -1183,7 +1185,7 @@ module.exports.validateConfigSchema = function validateConfigSchema(test) {
module.exports.clearHtmlCommentTextValid = module.exports.clearHtmlCommentTextValid =
function clearHtmlCommentTextValid(test) { function clearHtmlCommentTextValid(test) {
test.expect(1); test.expect(1);
var validComments = [ const validComments = [
"<!-- text -->", "<!-- text -->",
"<!--text-->", "<!--text-->",
"<!-- -->", "<!-- -->",
@ -1219,7 +1221,7 @@ function clearHtmlCommentTextValid(test) {
"<!--", "<!--",
"text" "text"
]; ];
var validResult = [ const validResult = [
"<!-- -->", "<!-- -->",
"<!-- -->", "<!-- -->",
"<!-- -->", "<!-- -->",
@ -1255,8 +1257,8 @@ function clearHtmlCommentTextValid(test) {
"<!--", "<!--",
" \\" " \\"
]; ];
var actual = shared.clearHtmlCommentText(validComments.join("\n")); const actual = shared.clearHtmlCommentText(validComments.join("\n"));
var expected = validResult.join("\n"); const expected = validResult.join("\n");
test.equal(actual, expected); test.equal(actual, expected);
test.done(); test.done();
}; };
@ -1264,7 +1266,7 @@ function clearHtmlCommentTextValid(test) {
module.exports.clearHtmlCommentTextInvalid = module.exports.clearHtmlCommentTextInvalid =
function clearHtmlCommentTextInvalid(test) { function clearHtmlCommentTextInvalid(test) {
test.expect(1); test.expect(1);
var invalidComments = [ const invalidComments = [
"<!>", "<!>",
"<!->", "<!->",
"<!-->", "<!-->",
@ -1282,8 +1284,8 @@ function clearHtmlCommentTextInvalid(test) {
"<!--text--->", "<!--text--->",
"<!--te--xt-->" "<!--te--xt-->"
]; ];
var actual = shared.clearHtmlCommentText(invalidComments.join("\n")); const actual = shared.clearHtmlCommentText(invalidComments.join("\n"));
var expected = invalidComments.join("\n"); const expected = invalidComments.join("\n");
test.equal(actual, expected); test.equal(actual, expected);
test.done(); test.done();
}; };
@ -1291,20 +1293,20 @@ function clearHtmlCommentTextInvalid(test) {
module.exports.clearHtmlCommentTextNonGreedy = module.exports.clearHtmlCommentTextNonGreedy =
function clearHtmlCommentTextNonGreedy(test) { function clearHtmlCommentTextNonGreedy(test) {
test.expect(1); test.expect(1);
var nonGreedyComments = [ const nonGreedyComments = [
"<!-- text --> -->", "<!-- text --> -->",
"<!---text --> -->", "<!---text --> -->",
"<!--t--> -->", "<!--t--> -->",
"<!----> -->" "<!----> -->"
]; ];
var nonGreedyResult = [ const nonGreedyResult = [
"<!-- --> -->", "<!-- --> -->",
"<!-- --> -->", "<!-- --> -->",
"<!-- --> -->", "<!-- --> -->",
"<!----> -->" "<!----> -->"
]; ];
var actual = shared.clearHtmlCommentText(nonGreedyComments.join("\n")); const actual = shared.clearHtmlCommentText(nonGreedyComments.join("\n"));
var expected = nonGreedyResult.join("\n"); const expected = nonGreedyResult.join("\n");
test.equal(actual, expected); test.equal(actual, expected);
test.done(); test.done();
}; };
@ -1312,28 +1314,28 @@ function clearHtmlCommentTextNonGreedy(test) {
module.exports.clearHtmlCommentTextEmbedded = module.exports.clearHtmlCommentTextEmbedded =
function clearHtmlCommentTextEmbedded(test) { function clearHtmlCommentTextEmbedded(test) {
test.expect(1); test.expect(1);
var embeddedComments = [ const embeddedComments = [
"text<!--text-->text", "text<!--text-->text",
"<!-- markdownlint-disable MD010 -->", "<!-- markdownlint-disable MD010 -->",
"text<!--text-->text", "text<!--text-->text",
"text<!-- markdownlint-disable MD010 -->text", "text<!-- markdownlint-disable MD010 -->text",
"text<!--text-->text" "text<!--text-->text"
]; ];
var embeddedResult = [ const embeddedResult = [
"text<!-- -->text", "text<!-- -->text",
"<!-- markdownlint-disable MD010 -->", "<!-- markdownlint-disable MD010 -->",
"text<!-- -->text", "text<!-- -->text",
"text<!-- markdownlint-disable MD010 -->text", "text<!-- markdownlint-disable MD010 -->text",
"text<!-- -->text" "text<!-- -->text"
]; ];
var actual = shared.clearHtmlCommentText(embeddedComments.join("\n")); const actual = shared.clearHtmlCommentText(embeddedComments.join("\n"));
var expected = embeddedResult.join("\n"); const expected = embeddedResult.join("\n");
test.equal(actual, expected); test.equal(actual, expected);
test.done(); test.done();
}; };
module.exports.trimLeftRight = function trimLeftRight(test) { module.exports.trimLeftRight = function trimLeftRight(test) {
var inputs = [ const inputs = [
"text text", "text text",
" text text ", " text text ",
" text text ", " text text ",
@ -1365,7 +1367,7 @@ module.exports.configSingle = function configSingle(test) {
markdownlint.readConfig("./test/config-child.json", markdownlint.readConfig("./test/config-child.json",
function callback(err, actual) { function callback(err, actual) {
test.ifError(err); test.ifError(err);
var expected = require("./config-child.json"); const expected = require("./config-child.json");
test.deepEqual(actual, expected, "Config object not correct."); test.deepEqual(actual, expected, "Config object not correct.");
test.done(); test.done();
}); });
@ -1376,7 +1378,7 @@ module.exports.configAbsolute = function configAbsolute(test) {
markdownlint.readConfig(path.join(__dirname, "config-child.json"), markdownlint.readConfig(path.join(__dirname, "config-child.json"),
function callback(err, actual) { function callback(err, actual) {
test.ifError(err); test.ifError(err);
var expected = require("./config-child.json"); const expected = require("./config-child.json");
test.deepEqual(actual, expected, "Config object not correct."); test.deepEqual(actual, expected, "Config object not correct.");
test.done(); test.done();
}); });
@ -1387,7 +1389,7 @@ module.exports.configMultiple = function configMultiple(test) {
markdownlint.readConfig("./test/config-grandparent.json", markdownlint.readConfig("./test/config-grandparent.json",
function callback(err, actual) { function callback(err, actual) {
test.ifError(err); test.ifError(err);
var expected = shared.assign( const expected = shared.assign(
shared.assign( shared.assign(
shared.assign({}, require("./config-child.json")), shared.assign({}, require("./config-child.json")),
require("./config-parent.json")), require("./config-parent.json")),
@ -1447,25 +1449,25 @@ module.exports.configBadChildJson = function configBadChildJson(test) {
module.exports.configSingleSync = function configSingleSync(test) { module.exports.configSingleSync = function configSingleSync(test) {
test.expect(1); test.expect(1);
var actual = markdownlint.readConfigSync("./test/config-child.json"); const actual = markdownlint.readConfigSync("./test/config-child.json");
var expected = require("./config-child.json"); const expected = require("./config-child.json");
test.deepEqual(actual, expected, "Config object not correct."); test.deepEqual(actual, expected, "Config object not correct.");
test.done(); test.done();
}; };
module.exports.configAbsoluteSync = function configAbsoluteSync(test) { module.exports.configAbsoluteSync = function configAbsoluteSync(test) {
test.expect(1); test.expect(1);
var actual = markdownlint.readConfigSync( const actual = markdownlint.readConfigSync(
path.join(__dirname, "config-child.json")); path.join(__dirname, "config-child.json"));
var expected = require("./config-child.json"); const expected = require("./config-child.json");
test.deepEqual(actual, expected, "Config object not correct."); test.deepEqual(actual, expected, "Config object not correct.");
test.done(); test.done();
}; };
module.exports.configMultipleSync = function configMultipleSync(test) { module.exports.configMultipleSync = function configMultipleSync(test) {
test.expect(1); test.expect(1);
var actual = markdownlint.readConfigSync("./test/config-grandparent.json"); const actual = markdownlint.readConfigSync("./test/config-grandparent.json");
var expected = shared.assign( const expected = shared.assign(
shared.assign( shared.assign(
shared.assign({}, require("./config-child.json")), shared.assign({}, require("./config-child.json")),
require("./config-parent.json")), require("./config-parent.json")),
@ -1527,15 +1529,15 @@ module.exports.configBadChildJsonSync = function configBadChildJsonSync(test) {
module.exports.customRulesV0 = function customRulesV0(test) { module.exports.customRulesV0 = function customRulesV0(test) {
test.expect(4); test.expect(4);
var customRulesMd = "./test/custom-rules.md"; const customRulesMd = "./test/custom-rules.md";
var options = { const options = {
"customRules": customRules.all, "customRules": customRules.all,
"files": [ customRulesMd ], "files": [ customRulesMd ],
"resultVersion": 0 "resultVersion": 0
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = {}; const expectedResult = {};
expectedResult[customRulesMd] = { expectedResult[customRulesMd] = {
"any-blockquote": [ 12 ], "any-blockquote": [ 12 ],
"every-n-lines": [ 2, 4, 6, 10, 12 ], "every-n-lines": [ 2, 4, 6, 10, 12 ],
@ -1543,8 +1545,8 @@ module.exports.customRulesV0 = function customRulesV0(test) {
"letters-E-X": [ 3, 7 ] "letters-E-X": [ 3, 7 ]
}; };
test.deepEqual(actualResult, expectedResult, "Undetected issues."); test.deepEqual(actualResult, expectedResult, "Undetected issues.");
var actualMessage = actualResult.toString(); let actualMessage = actualResult.toString();
var expectedMessage = let expectedMessage =
"./test/custom-rules.md: 12: any-blockquote" + "./test/custom-rules.md: 12: any-blockquote" +
" Rule that reports an error for any blockquote\n" + " Rule that reports an error for any blockquote\n" +
"./test/custom-rules.md: 2: every-n-lines" + "./test/custom-rules.md: 2: every-n-lines" +
@ -1591,15 +1593,15 @@ module.exports.customRulesV0 = function customRulesV0(test) {
module.exports.customRulesV1 = function customRulesV1(test) { module.exports.customRulesV1 = function customRulesV1(test) {
test.expect(3); test.expect(3);
var customRulesMd = "./test/custom-rules.md"; const customRulesMd = "./test/custom-rules.md";
var options = { const options = {
"customRules": customRules.all, "customRules": customRules.all,
"files": [ customRulesMd ], "files": [ customRulesMd ],
"resultVersion": 1 "resultVersion": 1
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = {}; const expectedResult = {};
expectedResult[customRulesMd] = [ expectedResult[customRulesMd] = [
{ "lineNumber": 12, { "lineNumber": 12,
"ruleName": "any-blockquote", "ruleName": "any-blockquote",
@ -1668,8 +1670,8 @@ module.exports.customRulesV1 = function customRulesV1(test) {
"errorRange": null } "errorRange": null }
]; ];
test.deepEqual(actualResult, expectedResult, "Undetected issues."); test.deepEqual(actualResult, expectedResult, "Undetected issues.");
var actualMessage = actualResult.toString(); const actualMessage = actualResult.toString();
var expectedMessage = const expectedMessage =
"./test/custom-rules.md: 12: any-blockquote/any-blockquote" + "./test/custom-rules.md: 12: any-blockquote/any-blockquote" +
" Rule that reports an error for any blockquote" + " Rule that reports an error for any blockquote" +
" [Blockquote spans 1 line(s).] [Context: \"> Block\"]\n" + " [Blockquote spans 1 line(s).] [Context: \"> Block\"]\n" +
@ -1698,15 +1700,15 @@ module.exports.customRulesV1 = function customRulesV1(test) {
module.exports.customRulesV2 = function customRulesV2(test) { module.exports.customRulesV2 = function customRulesV2(test) {
test.expect(3); test.expect(3);
var customRulesMd = "./test/custom-rules.md"; const customRulesMd = "./test/custom-rules.md";
var options = { const options = {
"customRules": customRules.all, "customRules": customRules.all,
"files": [ customRulesMd ], "files": [ customRulesMd ],
"resultVersion": 2 "resultVersion": 2
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = {}; const expectedResult = {};
expectedResult[customRulesMd] = [ expectedResult[customRulesMd] = [
{ "lineNumber": 12, { "lineNumber": 12,
"ruleNames": [ "any-blockquote" ], "ruleNames": [ "any-blockquote" ],
@ -1766,8 +1768,8 @@ module.exports.customRulesV2 = function customRulesV2(test) {
"errorRange": null } "errorRange": null }
]; ];
test.deepEqual(actualResult, expectedResult, "Undetected issues."); test.deepEqual(actualResult, expectedResult, "Undetected issues.");
var actualMessage = actualResult.toString(); const actualMessage = actualResult.toString();
var expectedMessage = const expectedMessage =
"./test/custom-rules.md: 12: any-blockquote" + "./test/custom-rules.md: 12: any-blockquote" +
" Rule that reports an error for any blockquote" + " Rule that reports an error for any blockquote" +
" [Blockquote spans 1 line(s).] [Context: \"> Block\"]\n" + " [Blockquote spans 1 line(s).] [Context: \"> Block\"]\n" +
@ -1796,8 +1798,8 @@ module.exports.customRulesV2 = function customRulesV2(test) {
module.exports.customRulesConfig = function customRulesConfig(test) { module.exports.customRulesConfig = function customRulesConfig(test) {
test.expect(2); test.expect(2);
var customRulesMd = "./test/custom-rules.md"; const customRulesMd = "./test/custom-rules.md";
var options = { const options = {
"customRules": customRules.all, "customRules": customRules.all,
"files": [ customRulesMd ], "files": [ customRulesMd ],
"config": { "config": {
@ -1811,7 +1813,7 @@ module.exports.customRulesConfig = function customRulesConfig(test) {
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = {}; const expectedResult = {};
expectedResult[customRulesMd] = { expectedResult[customRulesMd] = {
"any-blockquote": [ 12 ], "any-blockquote": [ 12 ],
"every-n-lines": [ 3, 6, 12 ], "every-n-lines": [ 3, 6, 12 ],
@ -1831,11 +1833,11 @@ module.exports.customRulesBadProperty = function customRulesBadProperty(test) {
[ "tags", [ null, "string", [], [ null ], [ "" ], [ "string", 10 ] ] ], [ "tags", [ null, "string", [], [ null ], [ "" ], [ "string", 10 ] ] ],
[ "function", [ null, "string", [] ] ] [ "function", [ null, "string", [] ] ]
].forEach(function forProperty(property) { ].forEach(function forProperty(property) {
var propertyName = property[0]; const propertyName = property[0];
property[1].forEach(function forPropertyValue(propertyValue) { property[1].forEach(function forPropertyValue(propertyValue) {
var badRule = shared.clone(customRules.anyBlockquote); const badRule = shared.clone(customRules.anyBlockquote);
badRule[propertyName] = propertyValue; badRule[propertyName] = propertyValue;
var options = { const options = {
"customRules": [ badRule ] "customRules": [ badRule ]
}; };
test.throws(function badRuleCall() { test.throws(function badRuleCall() {
@ -1934,7 +1936,7 @@ function customRulesUsedTagName(test) {
module.exports.customRulesThrowForFile = module.exports.customRulesThrowForFile =
function customRulesThrowForFile(test) { function customRulesThrowForFile(test) {
test.expect(4); test.expect(4);
var exceptionMessage = "Test exception message"; const exceptionMessage = "Test exception message";
markdownlint({ markdownlint({
"customRules": [ "customRules": [
{ {
@ -1960,7 +1962,7 @@ function customRulesThrowForFile(test) {
module.exports.customRulesThrowForFileSync = module.exports.customRulesThrowForFileSync =
function customRulesThrowForFileSync(test) { function customRulesThrowForFileSync(test) {
test.expect(4); test.expect(4);
var exceptionMessage = "Test exception message"; const exceptionMessage = "Test exception message";
test.throws(function customRuleThrowsCall() { test.throws(function customRuleThrowsCall() {
markdownlint.sync({ markdownlint.sync({
"customRules": [ "customRules": [
@ -1988,7 +1990,7 @@ function customRulesThrowForFileSync(test) {
module.exports.customRulesThrowForString = module.exports.customRulesThrowForString =
function customRulesThrowForString(test) { function customRulesThrowForString(test) {
test.expect(4); test.expect(4);
var exceptionMessage = "Test exception message"; const exceptionMessage = "Test exception message";
markdownlint({ markdownlint({
"customRules": [ "customRules": [
{ {
@ -2015,7 +2017,7 @@ function customRulesThrowForString(test) {
module.exports.customRulesOnErrorNull = function customRulesOnErrorNull(test) { module.exports.customRulesOnErrorNull = function customRulesOnErrorNull(test) {
test.expect(4); test.expect(4);
var options = { const options = {
"customRules": [ "customRules": [
{ {
"names": [ "name" ], "names": [ "name" ],
@ -2051,13 +2053,13 @@ module.exports.customRulesOnErrorBad = function customRulesOnErrorBad(test) {
[ "context", [ 10, [] ] ], [ "context", [ 10, [] ] ],
[ "range", [ 10, [], [ 10 ], [ 10, null ], [ 10, 11, 12 ] ] ] [ "range", [ 10, [], [ 10 ], [ 10, null ], [ 10, 11, 12 ] ] ]
].forEach(function forProperty(property) { ].forEach(function forProperty(property) {
var propertyName = property[0]; const propertyName = property[0];
property[1].forEach(function forPropertyValue(propertyValue) { property[1].forEach(function forPropertyValue(propertyValue) {
var badObject = { const badObject = {
"lineNumber": 1 "lineNumber": 1
}; };
badObject[propertyName] = propertyValue; badObject[propertyName] = propertyValue;
var options = { const options = {
"customRules": [ "customRules": [
{ {
"names": [ "name" ], "names": [ "name" ],
@ -2089,7 +2091,7 @@ module.exports.customRulesOnErrorBad = function customRulesOnErrorBad(test) {
module.exports.customRulesOnErrorLazy = function customRulesOnErrorLazy(test) { module.exports.customRulesOnErrorLazy = function customRulesOnErrorLazy(test) {
test.expect(2); test.expect(2);
var options = { const options = {
"customRules": [ "customRules": [
{ {
"names": [ "name" ], "names": [ "name" ],
@ -2111,7 +2113,7 @@ module.exports.customRulesOnErrorLazy = function customRulesOnErrorLazy(test) {
}; };
markdownlint(options, function callback(err, actualResult) { markdownlint(options, function callback(err, actualResult) {
test.ifError(err); test.ifError(err);
var expectedResult = { const expectedResult = {
"string": [ "string": [
{ {
"lineNumber": 1, "lineNumber": 1,
@ -2137,7 +2139,7 @@ module.exports.customRulesDoc = function customRulesDoc(test) {
} }
}, function callback(err, actual) { }, function callback(err, actual) {
test.ifError(err); test.ifError(err);
var expected = { "doc/CustomRules.md": [] }; const expected = { "doc/CustomRules.md": [] };
test.deepEqual(actual, expected, "Unexpected issues."); test.deepEqual(actual, expected, "Unexpected issues.");
test.done(); test.done();
}); });

View file

@ -10,7 +10,7 @@ module.exports = {
params.tokens.filter(function filterToken(token) { params.tokens.filter(function filterToken(token) {
return token.type === "blockquote_open"; return token.type === "blockquote_open";
}).forEach(function forToken(blockquote) { }).forEach(function forToken(blockquote) {
var lines = blockquote.map[1] - blockquote.map[0]; const lines = blockquote.map[1] - blockquote.map[0];
onError({ onError({
"lineNumber": blockquote.lineNumber, "lineNumber": blockquote.lineNumber,
"detail": "Blockquote spans " + lines + " line(s).", "detail": "Blockquote spans " + lines + " line(s).",

View file

@ -7,9 +7,9 @@ module.exports = {
"description": "Rule that reports an error every N lines", "description": "Rule that reports an error every N lines",
"tags": [ "test" ], "tags": [ "test" ],
"function": function rule(params, onError) { "function": function rule(params, onError) {
var n = params.config.n || 2; const n = params.config.n || 2;
params.lines.forEach(function forLine(line, lineIndex) { params.lines.forEach(function forLine(line, lineIndex) {
var lineNumber = lineIndex + 1; const lineNumber = lineIndex + 1;
if ((lineNumber % n) === 0) { if ((lineNumber % n) === 0) {
onError({ onError({
"lineNumber": lineNumber, "lineNumber": lineNumber,

View file

@ -13,7 +13,7 @@ module.exports = {
inline.children.filter(function filterChild(child) { inline.children.filter(function filterChild(child) {
return child.type === "text"; return child.type === "text";
}).forEach(function forChild(text) { }).forEach(function forChild(text) {
var index = text.content.toLowerCase().indexOf("ex"); const index = text.content.toLowerCase().indexOf("ex");
if (index !== -1) { if (index !== -1) {
onError({ onError({
"lineNumber": text.lineNumber, "lineNumber": text.lineNumber,

View file

@ -2,16 +2,16 @@
"use strict"; "use strict";
var anyBlockquote = require("./any-blockquote"); const anyBlockquote = require("./any-blockquote");
module.exports.anyBlockquote = anyBlockquote; module.exports.anyBlockquote = anyBlockquote;
var everyNLines = require("./every-n-lines"); const everyNLines = require("./every-n-lines");
module.exports.everyNLines = everyNLines; module.exports.everyNLines = everyNLines;
var firstLine = require("./first-line"); const firstLine = require("./first-line");
module.exports.firstLine = firstLine; module.exports.firstLine = firstLine;
var lettersEX = require("./letters-E-X"); const lettersEX = require("./letters-E-X");
module.exports.lettersEX = lettersEX; module.exports.lettersEX = lettersEX;
module.exports.all = [ module.exports.all = [