mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-12-17 06:20:12 +01:00
Document public API, comment framework code.
This commit is contained in:
parent
ec7684b95f
commit
63a52e9dea
4 changed files with 94 additions and 5 deletions
65
README.md
65
README.md
|
|
@ -60,6 +60,71 @@ cases come directly from that project.
|
||||||
|
|
||||||
See [Rules.md](doc/Rules.md) for more details.
|
See [Rules.md](doc/Rules.md) for more details.
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
```js
|
||||||
|
/**
|
||||||
|
* Lint specified Markdown files according to configurable rules.
|
||||||
|
*
|
||||||
|
* @param {Object} options Configuration options.
|
||||||
|
* @param {Function} callback Callback (err, result) function.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function markdownlint(options, callback) { ... }
|
||||||
|
```
|
||||||
|
|
||||||
|
### options
|
||||||
|
|
||||||
|
Type: `Object`
|
||||||
|
|
||||||
|
Configures the function.
|
||||||
|
|
||||||
|
#### options.files
|
||||||
|
|
||||||
|
Type: `Array` of `String`
|
||||||
|
|
||||||
|
List of files to lint.
|
||||||
|
|
||||||
|
Each array element should be a single file (via relative or absolute path);
|
||||||
|
[globbing](http://en.wikipedia.org/wiki/Glob_%28programming%29) is the caller's
|
||||||
|
responsibility.
|
||||||
|
|
||||||
|
Example: `[ "one.md", "dir/two.md" ]`
|
||||||
|
|
||||||
|
#### options.config
|
||||||
|
|
||||||
|
Type: `Object` mapping `String` to `Object | Boolean`
|
||||||
|
|
||||||
|
Configures the rules to use.
|
||||||
|
|
||||||
|
Object keys are rule names and values are the rule's configuration.
|
||||||
|
The value `false` disables a rule, `true` enables its default configuration,
|
||||||
|
and passing an object customizes its settings. Setting the special `default`
|
||||||
|
rule to `true` or `false` includes/excludes all rules by default.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"default": true,
|
||||||
|
"MD007": {
|
||||||
|
"indent": 4
|
||||||
|
},
|
||||||
|
"MD013": {
|
||||||
|
"line_length": 100
|
||||||
|
},
|
||||||
|
"MD029": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### callback
|
||||||
|
|
||||||
|
Type: `Function` taking (`Error`, `Object`)
|
||||||
|
|
||||||
|
Function to call upon completion.
|
||||||
|
|
||||||
|
See below for an example of the structure of the `result` object.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Invoke `markdownlint` and use the `result` object's `toString` method:
|
Invoke `markdownlint` and use the `result` object's `toString` method:
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ var md = require("markdown-it")();
|
||||||
var rules = require("./rules");
|
var rules = require("./rules");
|
||||||
var shared = require("./shared");
|
var shared = require("./shared");
|
||||||
|
|
||||||
|
// Mapping from rule name to description
|
||||||
var ruleToDescription = {};
|
var ruleToDescription = {};
|
||||||
rules.forEach(function forRule(rule) {
|
rules.forEach(function forRule(rule) {
|
||||||
ruleToDescription[rule.name] = rule.desc;
|
ruleToDescription[rule.name] = rule.desc;
|
||||||
|
|
@ -12,6 +13,7 @@ rules.forEach(function forRule(rule) {
|
||||||
// console.log("* " + rule.name + " - " + rule.desc);
|
// console.log("* " + rule.name + " - " + rule.desc);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Class for results with toString for pretty display
|
||||||
function Results() { }
|
function Results() { }
|
||||||
Results.prototype.toString = function resultsToString() {
|
Results.prototype.toString = function resultsToString() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
@ -31,40 +33,48 @@ Results.prototype.toString = function resultsToString() {
|
||||||
return results.join("\n");
|
return results.join("\n");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Array.sort comparison for number objects
|
||||||
function numberComparison(a, b) {
|
function numberComparison(a, b) {
|
||||||
return a - b;
|
return a - b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to return unique values from a sorted array
|
||||||
function uniqueFilterForSorted(value, index, array) {
|
function uniqueFilterForSorted(value, index, array) {
|
||||||
return (index === 0) || (value > array[index - 1]);
|
return (index === 0) || (value > array[index - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lints a single file
|
||||||
function lintFile(file, config, callback) {
|
function lintFile(file, config, callback) {
|
||||||
fs.readFile(file, { "encoding": "utf8" }, function readFile(err, contents) {
|
fs.readFile(file, shared.utf8Encoding, function readFile(err, contents) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
} else {
|
} else {
|
||||||
|
// Parse file into tokens and lines
|
||||||
var tokens = md.parse(contents, {});
|
var tokens = md.parse(contents, {});
|
||||||
var lines = contents.split(shared.newLineRe);
|
var lines = contents.split(shared.newLineRe);
|
||||||
|
// Annotate tokens with line/lineNumber
|
||||||
tokens.forEach(function forToken(token) {
|
tokens.forEach(function forToken(token) {
|
||||||
if (token.lines) {
|
if (token.lines) {
|
||||||
token.line = lines[token.lines[0]];
|
token.line = lines[token.lines[0]];
|
||||||
token.lineNumber = token.lines[0] + 1;
|
token.lineNumber = token.lines[0] + 1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// Create parameters for rules
|
||||||
var params = {
|
var params = {
|
||||||
"tokens": tokens,
|
"tokens": tokens,
|
||||||
"lines": lines
|
"lines": lines
|
||||||
};
|
};
|
||||||
var result = {};
|
var result = {};
|
||||||
var configDefault = config.default;
|
var defaultRule = (config.default !== undefined) && !!config.default;
|
||||||
var defaultRule = (configDefault !== undefined) && !!configDefault;
|
// Run each rule
|
||||||
rules.forEach(function forRule(rule) {
|
rules.forEach(function forRule(rule) {
|
||||||
var ruleConfig = config[rule.name];
|
var ruleConfig = config[rule.name];
|
||||||
if (ruleConfig || (defaultRule && (ruleConfig === undefined))) {
|
if (ruleConfig || (defaultRule && (ruleConfig === undefined))) {
|
||||||
|
// Pass rule-specific options
|
||||||
params.options = (ruleConfig instanceof Object) ? ruleConfig : {};
|
params.options = (ruleConfig instanceof Object) ? ruleConfig : {};
|
||||||
var errors = [];
|
var errors = [];
|
||||||
rule.func(params, errors);
|
rule.func(params, errors);
|
||||||
|
// Record any errors
|
||||||
if (errors.length) {
|
if (errors.length) {
|
||||||
errors.sort(numberComparison);
|
errors.sort(numberComparison);
|
||||||
result[rule.name] = errors.filter(uniqueFilterForSorted);
|
result[rule.name] = errors.filter(uniqueFilterForSorted);
|
||||||
|
|
@ -76,12 +86,21 @@ function lintFile(file, config, callback) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lint specified Markdown files according to configurable rules.
|
||||||
|
*
|
||||||
|
* @param {Object} options Configuration options.
|
||||||
|
* @param {Function} callback Callback (err, results) function.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
module.exports = function markdownlint(options, callback) {
|
module.exports = function markdownlint(options, callback) {
|
||||||
|
// Normalize inputs
|
||||||
options = options || {};
|
options = options || {};
|
||||||
callback = callback || function noop() {};
|
callback = callback || function noop() {};
|
||||||
var files = (options.files || []).slice();
|
var files = (options.files || []).slice();
|
||||||
var config = options.config || { "default": true };
|
var config = options.config || { "default": true };
|
||||||
var results = new Results();
|
var results = new Results();
|
||||||
|
// Lint each input file
|
||||||
function lintFiles() {
|
function lintFiles() {
|
||||||
var file = files.shift();
|
var file = files.shift();
|
||||||
if (file) {
|
if (file) {
|
||||||
|
|
@ -89,6 +108,7 @@ module.exports = function markdownlint(options, callback) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
} else {
|
} else {
|
||||||
|
// Record errors and lint next file
|
||||||
results[file] = result;
|
results[file] = result;
|
||||||
lintFiles();
|
lintFiles();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
// Regular expression for matching common newline characters
|
||||||
module.exports.newLineRe = /\r\n|\r|\n/;
|
module.exports.newLineRe = /\r\n|\r|\n/;
|
||||||
|
|
||||||
|
// readFile options for reading with the UTF-8 encoding
|
||||||
|
module.exports.utf8Encoding = { "encoding": "utf8" };
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ function createTestForFile(file) {
|
||||||
var actualPromise = Q.nfcall(fs.stat, configFile)
|
var actualPromise = Q.nfcall(fs.stat, configFile)
|
||||||
.then(
|
.then(
|
||||||
function configFileExists() {
|
function configFileExists() {
|
||||||
return Q.nfcall(fs.readFile, configFile, { "encoding": "utf8" })
|
return Q.nfcall(fs.readFile, configFile, shared.utf8Encoding)
|
||||||
.then(
|
.then(
|
||||||
function configFileContents(contents) {
|
function configFileContents(contents) {
|
||||||
return JSON.parse(contents);
|
return JSON.parse(contents);
|
||||||
|
|
@ -29,7 +29,7 @@ function createTestForFile(file) {
|
||||||
"config": config
|
"config": config
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
var expectedPromise = Q.nfcall(fs.readFile, file, { "encoding": "utf8" })
|
var expectedPromise = Q.nfcall(fs.readFile, file, shared.utf8Encoding)
|
||||||
.then(
|
.then(
|
||||||
function fileContents(contents) {
|
function fileContents(contents) {
|
||||||
var lines = contents.split(shared.newLineRe);
|
var lines = contents.split(shared.newLineRe);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue