mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-09-22 05:40:48 +02:00
Add strings
option to enable file-less scenarios.
This commit is contained in:
parent
fde1947031
commit
548e3d35cb
4 changed files with 176 additions and 87 deletions
34
README.md
34
README.md
|
@ -143,6 +143,25 @@ responsibility.
|
|||
|
||||
Example: `[ "one.md", "dir/two.md" ]`
|
||||
|
||||
#### options.strings
|
||||
|
||||
Type: `Object` mapping `String` to `String`
|
||||
|
||||
Map of identifiers to strings for linting.
|
||||
|
||||
When Markdown content is not available as files, it can be passed as strings.
|
||||
The keys of the `strings` object are used to identify each input value in the
|
||||
`result` summary.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"readme": "# README\n...",
|
||||
"changelog": "# CHANGELOG\n..."
|
||||
}
|
||||
```
|
||||
|
||||
#### options.config
|
||||
|
||||
Type: `Object` mapping `String` to `Boolean | Object`
|
||||
|
@ -205,7 +224,11 @@ Invoke `markdownlint` and use the `result` object's `toString` method:
|
|||
var markdownlint = require("markdownlint");
|
||||
|
||||
var options = {
|
||||
"files": [ "good.md", "bad.md" ]
|
||||
"files": [ "good.md", "bad.md" ],
|
||||
"strings": {
|
||||
"good.string": "# good.string\n\nThis string passes all rules.",
|
||||
"bad.string": "#bad.string\n\n#This string fails\tsome rules."
|
||||
}
|
||||
};
|
||||
|
||||
markdownlint(options, function callback(err, result) {
|
||||
|
@ -225,6 +248,9 @@ console.log(result.toString());
|
|||
Output of both calls:
|
||||
|
||||
```text
|
||||
bad.string: 3: MD010 Hard tabs
|
||||
bad.string: 1: MD018 No space after hash on atx style header
|
||||
bad.string: 3: MD018 No space after hash on atx style header
|
||||
bad.md: 3: MD010 Hard tabs
|
||||
bad.md: 1: MD018 No space after hash on atx style header
|
||||
bad.md: 3: MD018 No space after hash on atx style header
|
||||
|
@ -244,6 +270,11 @@ Output:
|
|||
|
||||
```json
|
||||
{
|
||||
"good.string": {},
|
||||
"bad.string": {
|
||||
"MD010": [ 3 ],
|
||||
"MD018": [ 1, 3 ]
|
||||
},
|
||||
"good.md": {},
|
||||
"bad.md": {
|
||||
"MD010": [ 3 ],
|
||||
|
@ -331,6 +362,7 @@ bad.md: 3: MD018 No space after hash on atx style header
|
|||
* 0.0.2 - Improve documentation, tests, and code.
|
||||
* 0.0.3 - Add synchronous API, improve documentation and code.
|
||||
* 0.0.4 - Add tests MD033-MD040, update dependencies.
|
||||
* *PENDING* - Add `strings` option to enable file-less scenarios.
|
||||
|
||||
[npm-image]: https://img.shields.io/npm/v/markdownlint.svg
|
||||
[npm-url]: https://www.npmjs.com/package/markdownlint
|
||||
|
|
|
@ -3,7 +3,11 @@
|
|||
var markdownlint = require("../lib/markdownlint");
|
||||
|
||||
var options = {
|
||||
"files": [ "good.md", "bad.md" ]
|
||||
"files": [ "good.md", "bad.md" ],
|
||||
"strings": {
|
||||
"good.string": "# good.string\n\nThis string passes all rules.",
|
||||
"bad.string": "#bad.string\n\n#This string fails\tsome rules."
|
||||
}
|
||||
};
|
||||
|
||||
// Uses result.toString for pretty formatting
|
||||
|
|
|
@ -53,16 +53,11 @@ function uniqueFilterForSorted(value, index, array) {
|
|||
return (index === 0) || (value > array[index - 1]);
|
||||
}
|
||||
|
||||
// Lints a single file
|
||||
function lintFile(file, config, synchronous, callback) {
|
||||
// Callback for read file API
|
||||
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);
|
||||
// Lints a single string
|
||||
function lintContent(content, config) {
|
||||
// Parse content into tokens and lines
|
||||
var tokens = md.parse(content, {});
|
||||
var lines = content.split(shared.newLineRe);
|
||||
// Annotate tokens with line/lineNumber
|
||||
tokens.forEach(function forToken(token) {
|
||||
if (token.map) {
|
||||
|
@ -125,14 +120,23 @@ function lintFile(file, config, synchronous, callback) {
|
|||
}
|
||||
}
|
||||
});
|
||||
callback(null, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Lints a single file
|
||||
function lintFile(file, config, synchronous, callback) {
|
||||
function lintContentWrapper(err, content) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
var result = lintContent(content, config);
|
||||
callback(null, result);
|
||||
}
|
||||
// Make a/synchronous call to read file
|
||||
if (synchronous) {
|
||||
readFile(null, fs.readFileSync(file, shared.utf8Encoding));
|
||||
lintContentWrapper(null, fs.readFileSync(file, shared.utf8Encoding));
|
||||
} else {
|
||||
fs.readFile(file, shared.utf8Encoding, readFile);
|
||||
fs.readFile(file, shared.utf8Encoding, lintContentWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,27 +160,34 @@ function markdownlint(options, callback) {
|
|||
options = options || {};
|
||||
callback = callback || function noop() {};
|
||||
var files = (options.files || []).slice();
|
||||
var strings = options.strings || {};
|
||||
var config = options.config || { "default": true };
|
||||
var synchronous = (callback === markdownlintSynchronousCallback);
|
||||
var results = new Results();
|
||||
// Lint each input file
|
||||
function lintFiles() {
|
||||
// Helper to lint the next file in the array
|
||||
function lintFilesArray() {
|
||||
var file = files.shift();
|
||||
if (file) {
|
||||
lintFile(file, config, synchronous, function lintedFile(err, result) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
} else {
|
||||
return callback(err);
|
||||
}
|
||||
// Record errors and lint next file
|
||||
results[file] = result;
|
||||
lintFiles();
|
||||
}
|
||||
lintFilesArray();
|
||||
});
|
||||
} else {
|
||||
callback(null, results);
|
||||
}
|
||||
}
|
||||
lintFiles();
|
||||
// Lint strings
|
||||
Object.keys(strings).forEach(function forKey(key) {
|
||||
var result = lintContent(strings[key] || "", config);
|
||||
results[key] = result;
|
||||
});
|
||||
// Lint files
|
||||
lintFilesArray();
|
||||
// Return results
|
||||
if (synchronous) {
|
||||
return results;
|
||||
}
|
||||
|
|
|
@ -158,6 +158,27 @@ module.exports.resultFormattingSync = function resultFormattingSync(test) {
|
|||
test.done();
|
||||
};
|
||||
|
||||
module.exports.stringInputLineEndings = function stringInputLineEndings(test) {
|
||||
test.expect(2);
|
||||
var options = {
|
||||
"strings": {
|
||||
"lf": "One\nTwo\n#Three",
|
||||
"crlf": "One\r\nTwo\r\n#Three",
|
||||
"mixed": "One\r\nTwo\n#Three"
|
||||
}
|
||||
};
|
||||
markdownlint(options, function callback(err, actualResult) {
|
||||
test.ifError(err);
|
||||
var expectedResult = {
|
||||
"lf": { "MD018": [ 3 ] },
|
||||
"crlf": { "MD018": [ 3 ] },
|
||||
"mixed": { "MD018": [ 3 ] }
|
||||
};
|
||||
test.deepEqual(actualResult, expectedResult, "Undetected issues.");
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.defaultTrue = function defaultTrue(test) {
|
||||
test.expect(2);
|
||||
var options = {
|
||||
|
@ -442,7 +463,7 @@ module.exports.styleRelaxed = function styleRelaxed(test) {
|
|||
});
|
||||
};
|
||||
|
||||
module.exports.filesNotModified = function filesNotModified(test) {
|
||||
module.exports.filesArrayNotModified = function filesArrayNotModified(test) {
|
||||
test.expect(2);
|
||||
var files = [
|
||||
"./test/atx_header_spacing.md",
|
||||
|
@ -460,16 +481,16 @@ module.exports.missingOptions = function missingOptions(test) {
|
|||
test.expect(2);
|
||||
markdownlint(null, function callback(err, result) {
|
||||
test.ifError(err);
|
||||
test.ok(result, "Did not get result for missing options.");
|
||||
test.deepEqual(result, {}, "Did not get empty result for missing options.");
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.missingFiles = function missingFiles(test) {
|
||||
module.exports.missingFilesAndStrings = function missingFilesAndStrings(test) {
|
||||
test.expect(2);
|
||||
markdownlint({}, function callback(err, result) {
|
||||
test.ifError(err);
|
||||
test.ok(result, "Did not get result for missing files.");
|
||||
test.ok(result, "Did not get result for missing files/strings.");
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
@ -494,12 +515,13 @@ module.exports.badFile = function badFile(test) {
|
|||
};
|
||||
|
||||
module.exports.badFileSync = function badFileSync(test) {
|
||||
test.expect(3);
|
||||
test.expect(4);
|
||||
test.throws(function badFileCall() {
|
||||
markdownlint.sync({
|
||||
"files": [ "./badFile" ]
|
||||
});
|
||||
}, function testError(err) {
|
||||
test.ok(err, "Did not get an error for bad file.");
|
||||
test.ok(err instanceof Error, "Error not instance of Error.");
|
||||
test.equal(err.code, "ENOENT", "Error code for bad file not ENOENT.");
|
||||
return true;
|
||||
|
@ -507,6 +529,26 @@ module.exports.badFileSync = function badFileSync(test) {
|
|||
test.done();
|
||||
};
|
||||
|
||||
module.exports.missingStringValue = function missingStringValue(test) {
|
||||
test.expect(2);
|
||||
markdownlint({
|
||||
"strings": {
|
||||
"undefined": undefined,
|
||||
"null": null,
|
||||
"empty": ""
|
||||
}
|
||||
}, function callback(err, result) {
|
||||
test.ifError(err);
|
||||
var expectedResult = {
|
||||
"undefined": {},
|
||||
"null": {},
|
||||
"empty": {}
|
||||
};
|
||||
test.deepEqual(result, expectedResult, "Did not get empty results.");
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.readme = function readme(test) {
|
||||
test.expect(95);
|
||||
var tagToRules = {};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue