diff --git a/lib/processor.js b/lib/processor.js index 94cf816d..a79f2435 100644 --- a/lib/processor.js +++ b/lib/processor.js @@ -11,8 +11,12 @@ * @property {string} [lang] * * @typedef {Object} RangeMap - * @property {number} js - * @property {number} md + * @property {number} indent Number of code block indent characters trimmed from + * the beginning of the line during extraction. + * @property {number} js Offset from the start of the code block's range in the + * extracted JS. + * @property {number} md Offset from the start of the code block's range in the + * original Markdown. * * @typedef {Object} BlockBase * @property {string} baseIndentText @@ -24,8 +28,7 @@ "use strict"; -const unified = require("unified"); -const remarkParse = require("remark-parse"); +const parse = require("mdast-util-from-markdown"); const UNSATISFIABLE_RULES = [ "eol-last", // The Markdown parser strips trailing newlines in code fences @@ -33,8 +36,6 @@ const UNSATISFIABLE_RULES = [ ]; const SUPPORTS_AUTOFIX = true; -const markdown = unified().use(remarkParse); - /** * @type {Map} */ @@ -152,7 +153,7 @@ function getBlockRangeMap(text, node, comments) { /* * The parser sets the fenced code block's start offset to wherever content * should normally begin (typically the first column of the line, but more - * inside a list item, for example). The code block's opening fance may be + * inside a list item, for example). The code block's opening fence may be * further indented by up to three characters. If the code block has * additional indenting, the opening fence's first backtick may be up to * three whitespace characters after the start offset. @@ -187,6 +188,7 @@ function getBlockRangeMap(text, node, comments) { * last range that matches, skipping this initialization entry. */ const rangeMap = [{ + indent: baseIndent, js: 0, md: 0 }]; @@ -215,6 +217,7 @@ function getBlockRangeMap(text, node, comments) { const trimLength = Math.min(baseIndent, leadingWhitespaceLength); rangeMap.push({ + indent: trimLength, js: jsOffset, // Advance `trimLength` character from the beginning of the Markdown @@ -239,7 +242,7 @@ function getBlockRangeMap(text, node, comments) { * @returns {Array<{ filename: string, text: string }>} Source code blocks to lint. */ function preprocess(text, filename) { - const ast = markdown.parse(text); + const ast = parse(text); const blocks = []; blocksCache.set(filename, blocks); @@ -327,7 +330,7 @@ function adjustBlock(block) { const out = { line: lineInCode + blockStart, - column: message.column + block.position.indent[lineInCode - 1] - 1 + column: message.column + block.rangeMap[lineInCode].indent }; if (Number.isInteger(message.endLine)) { diff --git a/package.json b/package.json index ab5f376e..7e934990 100644 --- a/package.json +++ b/package.json @@ -47,8 +47,7 @@ "nyc": "^14.1.1" }, "dependencies": { - "remark-parse": "^7.0.0", - "unified": "^6.1.2" + "mdast-util-from-markdown": "^0.8.5" }, "peerDependencies": { "eslint": ">=6.0.0" diff --git a/tests/lib/plugin.js b/tests/lib/plugin.js index f187d5e5..c889d797 100644 --- a/tests/lib/plugin.js +++ b/tests/lib/plugin.js @@ -597,6 +597,33 @@ describe("plugin", () => { assert.strictEqual(actual, expected); }); + it("with multiline autofix and CRLF", () => { + const input = [ + "This is Markdown.", + "", + "```js", + "console.log('Hello, \\", + "world!')", + "console.log('Hello, \\", + "world!')", + "```" + ].join("\r\n"); + const expected = [ + "This is Markdown.", + "", + "```js", + "console.log(\"Hello, \\", + "world!\")", + "console.log(\"Hello, \\", + "world!\")", + "```" + ].join("\r\n"); + const report = cli.executeOnText(input, "test.md"); + const actual = report.results[0].output; + + assert.strictEqual(actual, expected); + }); + // https://spec.commonmark.org/0.28/#fenced-code-blocks describe("when indented", () => { it("by one space", () => { diff --git a/tests/lib/processor.js b/tests/lib/processor.js index 6aa0b73f..02a02de3 100644 --- a/tests/lib/processor.js +++ b/tests/lib/processor.js @@ -376,7 +376,7 @@ describe("processor", () => { const blocks = processor.preprocess(code); assert.strictEqual(blocks[0].filename, "0.js"); - assert.strictEqual(blocks[0].text, "var answer = 6 * 7;\nconsole.log(answer);\n"); + assert.strictEqual(blocks[0].text, "var answer = 6 * 7;\r\nconsole.log(answer);\n"); }); it("should unindent space-indented code fences", () => { @@ -691,7 +691,7 @@ describe("processor", () => { const result = processor.postprocess(messages); assert.strictEqual(result[2].column, 9); - assert.strictEqual(result[3].column, 2); + assert.strictEqual(result[3].column, 4); assert.strictEqual(result[4].column, 2); });