Skip to content

Commit 8992a4d

Browse files
authored
refactor: replace findOffsets helper with native methods (#536)
* refactor: replace `findOffsets` helper with native methods * wip: `no-html` * wip: `no-html` * wip * wip: `no-reversed-media-syntax` * wip: `no-reversed-media-syntax` * wip: complete `no-reversed-media-syntax` * wip: complete `no-multiple-h1` * wip * wip: resolve conflicts * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip: type * wip * wip * wip * wip * wip * wip: remove `findOffsets` util
1 parent d6f2d0f commit 8992a4d

File tree

3 files changed

+19
-107
lines changed

3 files changed

+19
-107
lines changed

src/language/markdown-source-code.js

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
ConfigCommentParser,
1414
Directive,
1515
} from "@eslint/plugin-kit";
16-
import { findOffsets } from "../util.js";
1716

1817
//-----------------------------------------------------------------------------
1918
// Types
@@ -66,53 +65,38 @@ class InlineConfigComment {
6665
/**
6766
* Extracts inline configuration comments from an HTML node.
6867
* @param {Html} node The HTML node to extract comments from.
68+
* @param {MarkdownSourceCode} sourceCode The Markdown source code object.
6969
* @returns {Array<InlineConfigComment>} The inline configuration comments found in the node.
7070
*/
71-
function extractInlineConfigCommentsFromHTML(node) {
71+
function extractInlineConfigCommentsFromHTML(node, sourceCode) {
7272
if (!configCommentStart.test(node.value)) {
7373
return [];
7474
}
75+
76+
/** @type {Array<InlineConfigComment>} */
7577
const comments = [];
7678

79+
/** @type {RegExpExecArray} */
7780
let match;
7881

7982
while ((match = htmlComment.exec(node.value))) {
8083
if (configCommentStart.test(match[0])) {
81-
const comment = match[0];
82-
83-
// calculate location of the comment inside the node
84-
const start = {
85-
...node.position.start,
86-
};
87-
88-
const end = {
89-
...node.position.start,
90-
};
91-
92-
const {
93-
lineOffset: startLineOffset,
94-
columnOffset: startColumnOffset,
95-
} = findOffsets(node.value, match.index);
96-
97-
start.line += startLineOffset;
98-
start.column += startColumnOffset;
99-
start.offset += match.index;
100-
101-
const commentLineCount = comment.split("\n").length - 1;
102-
103-
end.line = start.line + commentLineCount;
104-
end.column =
105-
commentLineCount === 0
106-
? start.column + comment.length
107-
: comment.length - comment.lastIndexOf("\n");
108-
end.offset = start.offset + comment.length;
84+
// calculate offset of the comment inside the node
85+
const startOffset = match.index + node.position.start.offset;
86+
const endOffset = startOffset + match[0].length;
10987

11088
comments.push(
11189
new InlineConfigComment({
11290
value: match[1].trim(),
11391
position: {
114-
start,
115-
end,
92+
start: {
93+
...sourceCode.getLocFromIndex(startOffset),
94+
offset: startOffset,
95+
},
96+
end: {
97+
...sourceCode.getLocFromIndex(endOffset),
98+
offset: endOffset,
99+
},
116100
},
117101
}),
118102
);
@@ -191,8 +175,8 @@ export class MarkdownSourceCode extends TextSourceCodeBase {
191175
*/
192176
getInlineConfigNodes() {
193177
if (!this.#inlineConfigComments) {
194-
this.#inlineConfigComments = this.#htmlNodes.flatMap(
195-
extractInlineConfigCommentsFromHTML,
178+
this.#inlineConfigComments = this.#htmlNodes.flatMap(htmlNode =>
179+
extractInlineConfigCommentsFromHTML(htmlNode, this),
196180
);
197181
}
198182

src/util.js

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,34 +23,6 @@ export const htmlCommentPattern = /<!--[\s\S]*?-->/gu;
2323
// Helpers
2424
//-----------------------------------------------------------------------------
2525

26-
/**
27-
* Finds the line and column offsets for a given offset in a string.
28-
* @param {string} text The text to search.
29-
* @param {number} offset The offset to find.
30-
* @returns {{lineOffset:number,columnOffset:number}} The location of the offset.
31-
* Note that `columnOffset` should be used as an offset to the column number
32-
* of the given text in the source code only when `lineOffset` is 0.
33-
* Otherwise, it should be used as a 0-based column number in the source code.
34-
*/
35-
export function findOffsets(text, offset) {
36-
let lineOffset = 0;
37-
let columnOffset = 0;
38-
39-
for (let i = 0; i < offset; i++) {
40-
if (text[i] === "\n") {
41-
lineOffset++;
42-
columnOffset = 0;
43-
} else {
44-
columnOffset++;
45-
}
46-
}
47-
48-
return {
49-
lineOffset,
50-
columnOffset,
51-
};
52-
}
53-
5426
/**
5527
* Checks if a frontmatter block contains a title matching the given pattern
5628
* @param {string} value The frontmatter content

tests/util.test.js

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -8,57 +8,13 @@
88
//------------------------------------------------------------------------------
99

1010
import assert from "node:assert";
11-
import {
12-
findOffsets,
13-
frontmatterHasTitle,
14-
stripHtmlComments,
15-
} from "../src/util.js";
11+
import { frontmatterHasTitle, stripHtmlComments } from "../src/util.js";
1612

1713
//------------------------------------------------------------------------------
1814
// Tests
1915
//------------------------------------------------------------------------------
2016

2117
describe("util", () => {
22-
describe("findOffsets()", () => {
23-
it("should return correct offsets for a simple string", () => {
24-
const text = "Hello world!";
25-
const offset = 6; // 'w' in "world"
26-
const result = findOffsets(text, offset);
27-
assert.deepStrictEqual(result, { lineOffset: 0, columnOffset: 6 });
28-
});
29-
30-
it("should handle line breaks correctly", () => {
31-
const text = "Hello\nworld!";
32-
const offset = 6; // 'w' in "world"
33-
const result = findOffsets(text, offset);
34-
assert.deepStrictEqual(result, { lineOffset: 1, columnOffset: 0 });
35-
});
36-
37-
it("should handle Windows-style line endings", () => {
38-
const text = "Hello\r\nworld!";
39-
const offset = 7; // 'w' in "world"
40-
const result = findOffsets(text, offset);
41-
assert.deepStrictEqual(result, { lineOffset: 1, columnOffset: 0 });
42-
});
43-
44-
it("should handle offsets at the start of the string", () => {
45-
const text = "Hello, world!";
46-
const offset = 0; // Start of the string
47-
const result = findOffsets(text, offset);
48-
assert.deepStrictEqual(result, { lineOffset: 0, columnOffset: 0 });
49-
});
50-
51-
it("should handle offsets at the end of the string", () => {
52-
const text = "Hello, world!";
53-
const offset = text.length - 1; // Last character '!'
54-
const result = findOffsets(text, offset);
55-
assert.deepStrictEqual(result, {
56-
lineOffset: 0,
57-
columnOffset: text.length - 1,
58-
});
59-
});
60-
});
61-
6218
describe("frontmatterHasTitle()", () => {
6319
const pattern = /^title:\s*My Document$/u;
6420

0 commit comments

Comments
 (0)