mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-09-22 05:40:48 +02:00
Add options.resultVersion for more detailed error reporting (fixes #23).
This commit is contained in:
parent
3a356467cd
commit
0ca8bc7bb6
11 changed files with 454 additions and 160 deletions
|
@ -38,34 +38,51 @@ Results.prototype.toString = function resultsToString(useAlias) {
|
|||
var results = [];
|
||||
Object.keys(that).forEach(function forFile(file) {
|
||||
var fileResults = that[file];
|
||||
Object.keys(fileResults).forEach(function forRule(ruleName) {
|
||||
var rule = ruleNameToRule[ruleName];
|
||||
var ruleResults = fileResults[ruleName];
|
||||
ruleResults.forEach(function forLine(lineNumber) {
|
||||
var result =
|
||||
if (Array.isArray(fileResults)) {
|
||||
fileResults.forEach(function forResult(result) {
|
||||
results.push(
|
||||
file + ": " +
|
||||
lineNumber + ": " +
|
||||
(useAlias ? rule.aliases[0] : rule.name) + " " +
|
||||
rule.desc;
|
||||
results.push(result);
|
||||
result.lineNumber + ": " +
|
||||
result.ruleName + "/" +
|
||||
result.ruleAlias + " " +
|
||||
result.ruleDescription +
|
||||
(result.errorDetail ?
|
||||
" [" + result.errorDetail + "]" :
|
||||
"") +
|
||||
(result.errorContext ?
|
||||
" [Context: \"" + result.errorContext + "\"]" :
|
||||
""));
|
||||
});
|
||||
});
|
||||
} else {
|
||||
Object.keys(fileResults).forEach(function forRule(ruleName) {
|
||||
var rule = ruleNameToRule[ruleName];
|
||||
var ruleResults = fileResults[ruleName];
|
||||
ruleResults.forEach(function forLine(lineNumber) {
|
||||
var result =
|
||||
file + ": " +
|
||||
lineNumber + ": " +
|
||||
(useAlias ? rule.aliases[0] : rule.name) + " " +
|
||||
rule.desc;
|
||||
results.push(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
return results.join("\n");
|
||||
};
|
||||
|
||||
// Array.sort comparison for number objects
|
||||
function numberComparison(a, b) {
|
||||
return a - b;
|
||||
// Array.sort comparison for objects in errors array
|
||||
function lineNumberComparison(a, b) {
|
||||
return a.lineNumber - b.lineNumber;
|
||||
}
|
||||
|
||||
// Function to return unique values from a sorted array
|
||||
function uniqueFilterForSorted(value, index, array) {
|
||||
return (index === 0) || (value > array[index - 1]);
|
||||
// Function to return unique values from a sorted errors array
|
||||
function uniqueFilterForSortedErrors(value, index, array) {
|
||||
return (index === 0) || (value.lineNumber > array[index - 1].lineNumber);
|
||||
}
|
||||
|
||||
// Lints a single string
|
||||
function lintContent(content, config, frontMatter) { // eslint-disable-line
|
||||
function lintContent(content, config, frontMatter, resultVersion) {
|
||||
// Remove front matter (if present at beginning of content)
|
||||
var frontMatterLines = 0;
|
||||
if (frontMatter) {
|
||||
|
@ -163,7 +180,7 @@ function lintContent(content, config, frontMatter) { // eslint-disable-line
|
|||
}
|
||||
});
|
||||
}
|
||||
var enabledRulesPerLineNumber = [ null ];
|
||||
var enabledRulesPerLineNumber = new Array(1 + frontMatterLines);
|
||||
lines.forEach(function forLine(line) {
|
||||
var match = shared.inlineCommentRe.exec(line);
|
||||
if (match) {
|
||||
|
@ -182,25 +199,69 @@ function lintContent(content, config, frontMatter) { // eslint-disable-line
|
|||
"lines": lines
|
||||
};
|
||||
// Run each rule
|
||||
var result = {};
|
||||
var result = (resultVersion === 1) ? [] : {};
|
||||
rules.forEach(function forRule(rule) {
|
||||
// Configure rule
|
||||
params.options = mergedRules[rule.name];
|
||||
var errors = [];
|
||||
function addError(lineNumber, detail, context) {
|
||||
errors.push({
|
||||
"lineNumber": lineNumber + frontMatterLines,
|
||||
"detail": detail || null,
|
||||
"context": context || null
|
||||
});
|
||||
}
|
||||
errors.add = function add(lineNumber) {
|
||||
addError(lineNumber);
|
||||
};
|
||||
errors.addDetail = function addDetail(lineNumber, detail) {
|
||||
addError(lineNumber, detail);
|
||||
};
|
||||
errors.addDetailIf = function addDetailIf(lineNumber, expected, actual) {
|
||||
if (expected !== actual) {
|
||||
addError(lineNumber, "Expected: " + expected + "; Actual: " + actual);
|
||||
}
|
||||
};
|
||||
errors.addContext = function addContext(lineNumber, context, left, right) {
|
||||
if (context.length <= 30) {
|
||||
// Nothing to do
|
||||
} else if (left && right) {
|
||||
context = context.substr(0, 15) + "..." + context.substr(-15);
|
||||
} else if (right) {
|
||||
context = "..." + context.substr(-30);
|
||||
} else {
|
||||
context = context.substr(0, 30) + "...";
|
||||
}
|
||||
addError(lineNumber, null, context);
|
||||
};
|
||||
rule.func(params, errors);
|
||||
// Record any errors (significant performance benefit from length check)
|
||||
if (errors.length) {
|
||||
errors.sort(numberComparison);
|
||||
errors.sort(lineNumberComparison);
|
||||
var filteredErrors = errors
|
||||
.filter(uniqueFilterForSorted)
|
||||
.filter(function removeDisabledRules(lineNumber) {
|
||||
return enabledRulesPerLineNumber[lineNumber][rule.name];
|
||||
.filter(uniqueFilterForSortedErrors)
|
||||
.filter(function removeDisabledRules(error) {
|
||||
return enabledRulesPerLineNumber[error.lineNumber][rule.name];
|
||||
})
|
||||
.map(function adjustLineNumbers(error) {
|
||||
return error + frontMatterLines;
|
||||
.map(function formatResults(error) {
|
||||
if (resultVersion === 1) {
|
||||
return {
|
||||
"lineNumber": error.lineNumber,
|
||||
"ruleName": rule.name,
|
||||
"ruleAlias": rule.aliases[0],
|
||||
"ruleDescription": rule.desc,
|
||||
"errorDetail": error.detail,
|
||||
"errorContext": error.context
|
||||
};
|
||||
}
|
||||
return error.lineNumber;
|
||||
});
|
||||
if (filteredErrors.length) {
|
||||
result[rule.name] = filteredErrors;
|
||||
if (resultVersion === 1) {
|
||||
result.push.apply(result, filteredErrors);
|
||||
} else {
|
||||
result[rule.name] = filteredErrors;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -208,12 +269,18 @@ function lintContent(content, config, frontMatter) { // eslint-disable-line
|
|||
}
|
||||
|
||||
// Lints a single file
|
||||
function lintFile(file, config, frontMatter, synchronous, callback) {
|
||||
function lintFile(
|
||||
file,
|
||||
config,
|
||||
frontMatter,
|
||||
resultVersion,
|
||||
synchronous,
|
||||
callback) {
|
||||
function lintContentWrapper(err, content) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
var result = lintContent(content, config, frontMatter);
|
||||
var result = lintContent(content, config, frontMatter, resultVersion);
|
||||
callback(null, result);
|
||||
}
|
||||
// Make a/synchronous call to read file
|
||||
|
@ -253,13 +320,14 @@ function markdownlint(options, callback) {
|
|||
var frontMatter = (options.frontMatter === undefined) ?
|
||||
shared.frontMatterRe : options.frontMatter;
|
||||
var config = options.config || { "default": true };
|
||||
var resultVersion = options.resultVersion || 0;
|
||||
var synchronous = (callback === markdownlintSynchronousCallback);
|
||||
var results = new Results();
|
||||
// Helper to lint the next file in the array
|
||||
function lintFilesArray() {
|
||||
var file = files.shift();
|
||||
if (file) {
|
||||
lintFile(file, config, frontMatter, synchronous,
|
||||
lintFile(file, config, frontMatter, resultVersion, synchronous,
|
||||
function lintedFile(err, result) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
|
@ -274,7 +342,11 @@ function markdownlint(options, callback) {
|
|||
}
|
||||
// Lint strings
|
||||
Object.keys(strings).forEach(function forKey(key) {
|
||||
var result = lintContent(strings[key] || "", config, frontMatter);
|
||||
var result = lintContent(
|
||||
strings[key] || "",
|
||||
config,
|
||||
frontMatter,
|
||||
resultVersion);
|
||||
results[key] = result;
|
||||
});
|
||||
// Lint files
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue