Document public API, comment framework code.

This commit is contained in:
David Anson 2015-03-15 23:39:17 -07:00
parent ec7684b95f
commit 63a52e9dea
4 changed files with 94 additions and 5 deletions

View file

@ -60,6 +60,71 @@ cases come directly from that project.
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
Invoke `markdownlint` and use the `result` object's `toString` method:

View file

@ -5,6 +5,7 @@ var md = require("markdown-it")();
var rules = require("./rules");
var shared = require("./shared");
// Mapping from rule name to description
var ruleToDescription = {};
rules.forEach(function forRule(rule) {
ruleToDescription[rule.name] = rule.desc;
@ -12,6 +13,7 @@ rules.forEach(function forRule(rule) {
// console.log("* " + rule.name + " - " + rule.desc);
});
// Class for results with toString for pretty display
function Results() { }
Results.prototype.toString = function resultsToString() {
var self = this;
@ -31,40 +33,48 @@ Results.prototype.toString = function resultsToString() {
return results.join("\n");
};
// Array.sort comparison for number objects
function numberComparison(a, b) {
return a - b;
}
// Function to return unique values from a sorted array
function uniqueFilterForSorted(value, index, array) {
return (index === 0) || (value > array[index - 1]);
}
// Lints a single file
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) {
callback(err);
} else {
// Parse file into tokens and lines
var tokens = md.parse(contents, {});
var lines = contents.split(shared.newLineRe);
// Annotate tokens with line/lineNumber
tokens.forEach(function forToken(token) {
if (token.lines) {
token.line = lines[token.lines[0]];
token.lineNumber = token.lines[0] + 1;
}
});
// Create parameters for rules
var params = {
"tokens": tokens,
"lines": lines
};
var result = {};
var configDefault = config.default;
var defaultRule = (configDefault !== undefined) && !!configDefault;
var defaultRule = (config.default !== undefined) && !!config.default;
// Run each rule
rules.forEach(function forRule(rule) {
var ruleConfig = config[rule.name];
if (ruleConfig || (defaultRule && (ruleConfig === undefined))) {
// Pass rule-specific options
params.options = (ruleConfig instanceof Object) ? ruleConfig : {};
var errors = [];
rule.func(params, errors);
// Record any errors
if (errors.length) {
errors.sort(numberComparison);
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) {
// Normalize inputs
options = options || {};
callback = callback || function noop() {};
var files = (options.files || []).slice();
var config = options.config || { "default": true };
var results = new Results();
// Lint each input file
function lintFiles() {
var file = files.shift();
if (file) {
@ -89,6 +108,7 @@ module.exports = function markdownlint(options, callback) {
if (err) {
callback(err);
} else {
// Record errors and lint next file
results[file] = result;
lintFiles();
}

View file

@ -1,3 +1,7 @@
"use strict";
// Regular expression for matching common newline characters
module.exports.newLineRe = /\r\n|\r|\n/;
// readFile options for reading with the UTF-8 encoding
module.exports.utf8Encoding = { "encoding": "utf8" };

View file

@ -13,7 +13,7 @@ function createTestForFile(file) {
var actualPromise = Q.nfcall(fs.stat, configFile)
.then(
function configFileExists() {
return Q.nfcall(fs.readFile, configFile, { "encoding": "utf8" })
return Q.nfcall(fs.readFile, configFile, shared.utf8Encoding)
.then(
function configFileContents(contents) {
return JSON.parse(contents);
@ -29,7 +29,7 @@ function createTestForFile(file) {
"config": config
});
});
var expectedPromise = Q.nfcall(fs.readFile, file, { "encoding": "utf8" })
var expectedPromise = Q.nfcall(fs.readFile, file, shared.utf8Encoding)
.then(
function fileContents(contents) {
var lines = contents.split(shared.newLineRe);