Add line and number to token, refactor to simplify rules.

This commit is contained in:
David Anson 2015-03-02 23:52:39 -08:00
parent 9eb3eb9083
commit e366ee071c
2 changed files with 34 additions and 33 deletions

View file

@ -17,9 +17,17 @@ function lintFile(file, config, callback) {
if (err) { if (err) {
callback(err); callback(err);
} else { } else {
var tokens = md.parse(contents);
var lines = contents.split(/\r\n|\r|\n/g);
tokens.forEach(function forToken(token) {
if (token.lines) {
token.line = lines[token.lines[0]];
token.lineNumber = token.lines[0] + 1;
}
});
var params = { var params = {
"tokens": md.parse(contents), "tokens": tokens,
"lines": contents.split(/\r\n|\r|\n/g) "lines": lines
}; };
var result = {}; var result = {};
var configDefault = config.default; var configDefault = config.default;

View file

@ -1,17 +1,12 @@
"use strict"; "use strict";
function lineNumberFrom(token) { function indentFrom(token) {
return token.lines[0] + 1; return token.line.length - token.line.trimLeft().length;
} }
function indentFrom(token, lines) { function headingStyleFrom(token) {
var line = lines[token.lines[0]];
return line.length - line.trimLeft().length;
}
function headingStyleFrom(token, lines) {
if ((token.lines[1] - token.lines[0]) === 1) { if ((token.lines[1] - token.lines[0]) === 1) {
if (lines[token.lines[0]].match(/#\s*$/)) { if (token.line.match(/#\s*$/)) {
return "atx_closed"; return "atx_closed";
} }
return "atx"; return "atx";
@ -19,8 +14,8 @@ function headingStyleFrom(token, lines) {
return "setext"; return "setext";
} }
function unorderedListStyleFrom(token, lines) { function unorderedListStyleFrom(token) {
switch (lines[token.lines[0]].trim().substr(0, 1)) { switch (token.line.trimLeft().substr(0, 1)) {
case "*": case "*":
return "asterisk"; return "asterisk";
case "-": case "-":
@ -51,7 +46,7 @@ module.exports = [
return (token.type === "heading_open"); return (token.type === "heading_open");
}).forEach(function forToken(token) { }).forEach(function forToken(token) {
if (prevLevel && (token.hLevel > prevLevel + 1)) { if (prevLevel && (token.hLevel > prevLevel + 1)) {
errors.push(lineNumberFrom(token)); errors.push(token.lineNumber);
} }
prevLevel = token.hLevel; prevLevel = token.hLevel;
}); });
@ -65,7 +60,7 @@ module.exports = [
params.tokens.every(function forToken(token) { params.tokens.every(function forToken(token) {
if (token.type === "heading_open") { if (token.type === "heading_open") {
if (token.hLevel !== 1) { if (token.hLevel !== 1) {
errors.push(lineNumberFrom(token)); errors.push(token.lineNumber);
} }
return false; return false;
} }
@ -83,11 +78,11 @@ module.exports = [
return (token.type === "heading_open"); return (token.type === "heading_open");
}); });
if ((style === "consistent") && headings.length) { if ((style === "consistent") && headings.length) {
style = headingStyleFrom(headings[0], params.lines); style = headingStyleFrom(headings[0]);
} }
headings.forEach(function forToken(token) { headings.forEach(function forToken(token) {
if (headingStyleFrom(token, params.lines) !== style) { if (headingStyleFrom(token) !== style) {
errors.push(lineNumberFrom(token)); errors.push(token.lineNumber);
} }
}); });
} }
@ -102,11 +97,11 @@ module.exports = [
return (token.type === "list_item_open"); return (token.type === "list_item_open");
}); });
if ((style === "consistent") && listItems.length) { if ((style === "consistent") && listItems.length) {
style = unorderedListStyleFrom(listItems[0], params.lines); style = unorderedListStyleFrom(listItems[0]);
} }
listItems.forEach(function forToken(token) { listItems.forEach(function forToken(token) {
if (unorderedListStyleFrom(token, params.lines) !== style) { if (unorderedListStyleFrom(token) !== style) {
errors.push(lineNumberFrom(token)); errors.push(token.lineNumber);
} }
}); });
} }
@ -116,16 +111,15 @@ module.exports = [
"name": "MD005", "name": "MD005",
"desc": "Inconsistent indentation for list items at the same level", "desc": "Inconsistent indentation for list items at the same level",
"func": function MD005(params, errors) { "func": function MD005(params, errors) {
var listItems = params.tokens.filter(function filterToken(token) {
return (token.type === "list_item_open");
});
var indentLevels = []; var indentLevels = [];
listItems.forEach(function forToken(token) { params.tokens.filter(function filterToken(token) {
var indentLevel = indentFrom(token, params.lines); return (token.type === "list_item_open");
}).forEach(function forToken(token) {
var indentLevel = indentFrom(token);
if (!indentLevels[token.level]) { if (!indentLevels[token.level]) {
indentLevels[token.level] = indentLevel; indentLevels[token.level] = indentLevel;
} else if (indentLevel !== indentLevels[token.level]) { } else if (indentLevel !== indentLevels[token.level]) {
errors.push(lineNumberFrom(token)); errors.push(token.lineNumber);
} }
}); });
} }
@ -136,15 +130,14 @@ module.exports = [
"desc": "Unordered list indentation", "desc": "Unordered list indentation",
"func": function MD007(params, errors) { "func": function MD007(params, errors) {
var optionsIndent = params.options.indent || 2; var optionsIndent = params.options.indent || 2;
var bulletLists = params.tokens.filter(function filterToken(token) {
return (token.type === "bullet_list_open");
});
var prevIndent = 0; var prevIndent = 0;
bulletLists.forEach(function forToken(token) { params.tokens.filter(function filterToken(token) {
var indent = indentFrom(token, params.lines); return (token.type === "bullet_list_open");
}).forEach(function forToken(token) {
var indent = indentFrom(token);
if ((indent > prevIndent) && if ((indent > prevIndent) &&
((indent - prevIndent) !== optionsIndent)) { ((indent - prevIndent) !== optionsIndent)) {
errors.push(lineNumberFrom(token)); errors.push(token.lineNumber);
} }
prevIndent = indent; prevIndent = indent;
}); });