Skip to content

Commit

Permalink
fix(rule): support non-Markdown file (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
azu authored Oct 12, 2019
1 parent cc76d0f commit 2bb23d2
Show file tree
Hide file tree
Showing 6 changed files with 578 additions and 900 deletions.
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,15 @@
"textlint"
],
"devDependencies": {
"eslint": "6.0.1",
"textlint-scripts": "^2.1.0"
"@types/structured-source": "^3.0.0",
"eslint": "6.5.1",
"textlint-scripts": "^2.1.0",
"textlint-plugin-asciidoctor": "^1.0.3"
},
"peerDependencies": {
"eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0"
},
"dependencies": {
"structured-source": "^3.0.2"
}
}
43 changes: 29 additions & 14 deletions src/textlint-rule-eslint.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// LICENSE : MIT
"use strict";
const CLIEngine = require("eslint").CLIEngine;
const path = require("path");
const Source = require("structured-source");
const CLIEngine = require("eslint").CLIEngine;
const defaultOptions = {
// path to .eslintrc file
"configFile": null,
Expand Down Expand Up @@ -37,7 +38,7 @@ const reporter = (context, options) => {
}
const raw = getSource(node);
const code = getUntrimmedCode(node, raw);

const source = new Source(code);
const resultLinting = engine.executeOnText(code, node.lang);
if (resultLinting.errorCount === 0) {
return;
Expand All @@ -54,24 +55,33 @@ const reporter = (context, options) => {
ESLint message line and column start with 1
*/
if (options.ignoreParsingErrors && message.message.includes("Parsing error")) {
return;
return;
}

const prefix = message.ruleId ? `${message.ruleId}: ` : "";
if (message.fix) {
const paddingIndex = raw.indexOf(code);
const fixedRange = message.fix.range;
const fixedText = message.fix.text;
const fixedWithPadding = [fixedRange[0] + paddingIndex, fixedRange[1] + paddingIndex];
report(node, new RuleError(`${prefix}${message.message}`, {
const sourceBlockDiffIndex = (raw !== node.value) ? raw.indexOf(code) : 0;
const fixedWithPadding = [fixedRange[0] + sourceBlockDiffIndex, fixedRange[1] + sourceBlockDiffIndex];
const index = source.positionToIndex({
line: message.line,
column: message.column - 1,
column: message.column
});
const adjustedIndex = index + sourceBlockDiffIndex - 1;
report(node, new RuleError(`${prefix}${message.message}`, {
index: adjustedIndex,
fix: fixer.replaceTextRange(fixedWithPadding, fixedText)
}));
} else {
report(node, new RuleError(`${prefix}${message.message}`, {
const sourceBlockDiffIndex = (raw !== node.value) ? raw.indexOf(code) : 0;
const index = source.positionToIndex({
line: message.line,
column: message.column - 1
column: message.column
});
const adjustedIndex = index + sourceBlockDiffIndex - 1;
report(node, new RuleError(`${prefix}${message.message}`, {
index: adjustedIndex
}));
}

Expand All @@ -82,7 +92,7 @@ const reporter = (context, options) => {
};

/**
* get actual code value from CodeBlock node
* [Markdown] get actual code value from CodeBlock node
* @param {Object} node
* @param {string} raw raw value include CodeBlock syntax
* @returns {string}
Expand All @@ -91,18 +101,23 @@ function getUntrimmedCode(node, raw) {
if (node.type !== "CodeBlock") {
return node.value
}

// Space indented CodeBlock that has not lang
if (!node.lang) {
return node.value;
}

// If it is not markdown codeBlock, just use node.value
if (!(raw.startsWith("```") && raw.endsWith("```"))) {
if (node.value.endsWith("\n")) {
return node.value
}
return node.value + "\n";
}
// Markdown(remark) specific hack
// https://github.com/wooorm/remark/issues/207#issuecomment-244620590
const lines = raw.split("\n");

// code lines without the first line and the last line
const codeLines = lines.slice(1, lines.length - 1);

// add last new line
// \n```
return codeLines.join("\n") + "\n";
Expand All @@ -111,4 +126,4 @@ function getUntrimmedCode(node, raw) {
module.exports = {
linter: reporter,
fixer: reporter
};
};
68 changes: 68 additions & 0 deletions test/asciidoc.disabled
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// LICENSE : MIT
"use strict";
import rule from "../src/textlint-rule-eslint";
const path = require("path");
const TextLintTester = require("textlint-tester");
const asciidoctorPlugin = require("textlint-plugin-asciidoctor");
const tester = new TextLintTester();
const configFilePath = path.join(__dirname, "fixtures/style.eslintconfig.js");
tester.run("textlint-rule-eslint with asciidoctor plugin", {
plugins: [
{
pluginId: "asciidoc",
plugin: asciidoctorPlugin,
}
],
rules: [
{
ruleId: "eslint",
rule: rule,
options: {
configFile: configFilePath
}
}
]
}, {
valid: [
{
text: `
[role="executable"]
[source,javascript]
.thenコード例
----
var promise = new Promise(function(resolve, reject) {
resolve("thenに渡す値");
});
promise.then(function(value) {
console.log(value);
}, function(error) {
console.error(error);
});
----
`,
ext: ".adoc",

}
],
invalid: [
{
text: `
[source,javascript]
----
var a = 1
----
`,
output: `
[source,javascript]
----
var a = 1;
----
`,
ext: ".adoc",
errors: [{
index: 35
}]
}
]

});
1 change: 1 addition & 0 deletions test/mocha.opts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--require textlint-scripts/register
84 changes: 55 additions & 29 deletions test/textlint-rule-eslint-test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// LICENSE : MIT
"use strict";
import rule from "../src/textlint-rule-eslint";

const path = require("path");
const TextLintTester = require("textlint-tester");
const tester = new TextLintTester();
Expand All @@ -17,35 +18,35 @@ tester.run("textlint-rule-eslint", rule, {
},
{
text: "```js\n" +
"var a = 1;\n" +
"```",
"var a = 1;\n" +
"```",
options: {
configFile: configFilePath
configFile: configFilePath
}
},
{
text: "```js\n\n" +
"var a = 1;\n\n" +
"```",
"var a = 1;\n\n" +
"```",
options: {
configFile: configFilePath
configFile: configFilePath
}
},
{
text: "```js\n\n" +
"+++1+++\n" +
"```",
"+++1+++\n" +
"```",
options: {
configFile: configFilePath,
ignoreParsingErrors: true
configFile: configFilePath,
ignoreParsingErrors: true
}
},
],
invalid: [
{
text: "```js\n" +
"+++1+++\n" +
"```",
"+++1+++\n" +
"```",
errors: [
{
message: "Parsing error: Assigning to rvalue",
Expand All @@ -59,11 +60,11 @@ tester.run("textlint-rule-eslint", rule, {
},
{
text: "```js\n" +
WrongCode1 + "\n" +
"```",
WrongCode1 + "\n" +
"```",
output: "```js\n" +
WrongCode1 + ";\n" +
"```",
WrongCode1 + ";\n" +
"```",
errors: [
{
message: "semi: Missing semicolon.",
Expand All @@ -75,22 +76,47 @@ tester.run("textlint-rule-eslint", rule, {
configFile: configFilePath
}
},
{
text: "```javascript\n" +
"var a = 1\n" +
"var b = 2\n" +
"```",
output: "```javascript\n" +
"var a = 1;\n" +
"var b = 2;\n" +
"```",
errors: [
{
message: "semi: Missing semicolon.",
line: 2,
column: 10
},
{
message: "semi: Missing semicolon.",
line: 3,
column: 10
}
],
options: {
configFile: configFilePath
}
},
// multiple
{
text: "```js\n" +
WrongCode1 + "\n" +
"```\n" +
"This is text.\n" +
"```js\n" +
WrongCode2 + "\n" +
"```",
WrongCode1 + "\n" +
"```\n" +
"This is text.\n" +
"```js\n" +
WrongCode2 + "\n" +
"```",
output: "```js\n" +
WrongCode1 + ";\n" +
"```\n" +
"This is text.\n" +
"```js\n" +
WrongCode2 + ";\n" +
"```",
WrongCode1 + ";\n" +
"```\n" +
"This is text.\n" +
"```js\n" +
WrongCode2 + ";\n" +
"```",
errors: [
{
message: "semi: Missing semicolon.",
Expand All @@ -107,4 +133,4 @@ tester.run("textlint-rule-eslint", rule, {
}
}
]
});
});
Loading

0 comments on commit 2bb23d2

Please sign in to comment.