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" ]`
|
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
|
#### options.config
|
||||||
|
|
||||||
Type: `Object` mapping `String` to `Boolean | Object`
|
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 markdownlint = require("markdownlint");
|
||||||
|
|
||||||
var options = {
|
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) {
|
markdownlint(options, function callback(err, result) {
|
||||||
|
@ -225,6 +248,9 @@ console.log(result.toString());
|
||||||
Output of both calls:
|
Output of both calls:
|
||||||
|
|
||||||
```text
|
```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: 3: MD010 Hard tabs
|
||||||
bad.md: 1: MD018 No space after hash on atx style header
|
bad.md: 1: MD018 No space after hash on atx style header
|
||||||
bad.md: 3: 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
|
```json
|
||||||
{
|
{
|
||||||
|
"good.string": {},
|
||||||
|
"bad.string": {
|
||||||
|
"MD010": [ 3 ],
|
||||||
|
"MD018": [ 1, 3 ]
|
||||||
|
},
|
||||||
"good.md": {},
|
"good.md": {},
|
||||||
"bad.md": {
|
"bad.md": {
|
||||||
"MD010": [ 3 ],
|
"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.2 - Improve documentation, tests, and code.
|
||||||
* 0.0.3 - Add synchronous API, improve documentation and code.
|
* 0.0.3 - Add synchronous API, improve documentation and code.
|
||||||
* 0.0.4 - Add tests MD033-MD040, update dependencies.
|
* 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-image]: https://img.shields.io/npm/v/markdownlint.svg
|
||||||
[npm-url]: https://www.npmjs.com/package/markdownlint
|
[npm-url]: https://www.npmjs.com/package/markdownlint
|
||||||
|
|
|
@ -3,7 +3,11 @@
|
||||||
var markdownlint = require("../lib/markdownlint");
|
var markdownlint = require("../lib/markdownlint");
|
||||||
|
|
||||||
var options = {
|
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
|
// Uses result.toString for pretty formatting
|
||||||
|
|
|
@ -53,16 +53,11 @@ function uniqueFilterForSorted(value, index, array) {
|
||||||
return (index === 0) || (value > array[index - 1]);
|
return (index === 0) || (value > array[index - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lints a single file
|
// Lints a single string
|
||||||
function lintFile(file, config, synchronous, callback) {
|
function lintContent(content, config) {
|
||||||
// Callback for read file API
|
// Parse content into tokens and lines
|
||||||
function readFile(err, contents) {
|
var tokens = md.parse(content, {});
|
||||||
if (err) {
|
var lines = content.split(shared.newLineRe);
|
||||||
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
|
// Annotate tokens with line/lineNumber
|
||||||
tokens.forEach(function forToken(token) {
|
tokens.forEach(function forToken(token) {
|
||||||
if (token.map) {
|
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
|
// Make a/synchronous call to read file
|
||||||
if (synchronous) {
|
if (synchronous) {
|
||||||
readFile(null, fs.readFileSync(file, shared.utf8Encoding));
|
lintContentWrapper(null, fs.readFileSync(file, shared.utf8Encoding));
|
||||||
} else {
|
} else {
|
||||||
fs.readFile(file, shared.utf8Encoding, readFile);
|
fs.readFile(file, shared.utf8Encoding, lintContentWrapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,27 +160,34 @@ function markdownlint(options, callback) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
callback = callback || function noop() {};
|
callback = callback || function noop() {};
|
||||||
var files = (options.files || []).slice();
|
var files = (options.files || []).slice();
|
||||||
|
var strings = options.strings || {};
|
||||||
var config = options.config || { "default": true };
|
var config = options.config || { "default": true };
|
||||||
var synchronous = (callback === markdownlintSynchronousCallback);
|
var synchronous = (callback === markdownlintSynchronousCallback);
|
||||||
var results = new Results();
|
var results = new Results();
|
||||||
// Lint each input file
|
// Helper to lint the next file in the array
|
||||||
function lintFiles() {
|
function lintFilesArray() {
|
||||||
var file = files.shift();
|
var file = files.shift();
|
||||||
if (file) {
|
if (file) {
|
||||||
lintFile(file, config, synchronous, function lintedFile(err, result) {
|
lintFile(file, config, synchronous, function lintedFile(err, result) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
return callback(err);
|
||||||
} else {
|
}
|
||||||
// Record errors and lint next file
|
// Record errors and lint next file
|
||||||
results[file] = result;
|
results[file] = result;
|
||||||
lintFiles();
|
lintFilesArray();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
callback(null, results);
|
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) {
|
if (synchronous) {
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,6 +158,27 @@ module.exports.resultFormattingSync = function resultFormattingSync(test) {
|
||||||
test.done();
|
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) {
|
module.exports.defaultTrue = function defaultTrue(test) {
|
||||||
test.expect(2);
|
test.expect(2);
|
||||||
var options = {
|
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);
|
test.expect(2);
|
||||||
var files = [
|
var files = [
|
||||||
"./test/atx_header_spacing.md",
|
"./test/atx_header_spacing.md",
|
||||||
|
@ -460,16 +481,16 @@ module.exports.missingOptions = function missingOptions(test) {
|
||||||
test.expect(2);
|
test.expect(2);
|
||||||
markdownlint(null, function callback(err, result) {
|
markdownlint(null, function callback(err, result) {
|
||||||
test.ifError(err);
|
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();
|
test.done();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.missingFiles = function missingFiles(test) {
|
module.exports.missingFilesAndStrings = function missingFilesAndStrings(test) {
|
||||||
test.expect(2);
|
test.expect(2);
|
||||||
markdownlint({}, function callback(err, result) {
|
markdownlint({}, function callback(err, result) {
|
||||||
test.ifError(err);
|
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();
|
test.done();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -494,12 +515,13 @@ module.exports.badFile = function badFile(test) {
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.badFileSync = function badFileSync(test) {
|
module.exports.badFileSync = function badFileSync(test) {
|
||||||
test.expect(3);
|
test.expect(4);
|
||||||
test.throws(function badFileCall() {
|
test.throws(function badFileCall() {
|
||||||
markdownlint.sync({
|
markdownlint.sync({
|
||||||
"files": [ "./badFile" ]
|
"files": [ "./badFile" ]
|
||||||
});
|
});
|
||||||
}, function testError(err) {
|
}, 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.ok(err instanceof Error, "Error not instance of Error.");
|
||||||
test.equal(err.code, "ENOENT", "Error code for bad file not ENOENT.");
|
test.equal(err.code, "ENOENT", "Error code for bad file not ENOENT.");
|
||||||
return true;
|
return true;
|
||||||
|
@ -507,6 +529,26 @@ module.exports.badFileSync = function badFileSync(test) {
|
||||||
test.done();
|
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) {
|
module.exports.readme = function readme(test) {
|
||||||
test.expect(95);
|
test.expect(95);
|
||||||
var tagToRules = {};
|
var tagToRules = {};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue