Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
8d5f4d7
refactor: replace `findOffsets` helper with native methods
lumirlumir Sep 23, 2025
7a4b4e9
Merge branch 'main' of https://github.com/eslint/markdown into refact…
lumirlumir Sep 26, 2025
e9e51e6
wip: `no-html`
lumirlumir Sep 26, 2025
64d06c9
wip: `no-html`
lumirlumir Sep 26, 2025
f6aa2cb
wip
lumirlumir Sep 26, 2025
b9b1d48
wip: `no-reversed-media-syntax`
lumirlumir Sep 26, 2025
a65a9b2
wip: `no-reversed-media-syntax`
lumirlumir Sep 26, 2025
1048d45
wip: complete `no-reversed-media-syntax`
lumirlumir Sep 26, 2025
e2d1987
wip: complete `no-multiple-h1`
lumirlumir Sep 26, 2025
5c9d1ee
wip
lumirlumir Sep 26, 2025
2e3de8c
wip: resolve conflicts
lumirlumir Sep 30, 2025
360fabc
Merge branch 'main' of https://github.com/eslint/markdown into refact…
lumirlumir Sep 30, 2025
72acb60
wip
lumirlumir Sep 30, 2025
4487b99
Merge branch 'main' into refactor-replace-findoffsets-helper-with-nat…
lumirlumir Oct 1, 2025
98bf9d4
wip
lumirlumir Oct 1, 2025
263fddc
wip
lumirlumir Oct 1, 2025
ba43975
wip
lumirlumir Oct 1, 2025
7eda527
wip
lumirlumir Oct 1, 2025
565fc7d
wip
lumirlumir Oct 1, 2025
0b3b4c3
wip
lumirlumir Oct 1, 2025
e871962
wip
lumirlumir Oct 2, 2025
fa40141
Merge branch 'main' of https://github.com/eslint/markdown into refact…
lumirlumir Oct 2, 2025
8d31e8f
wip
lumirlumir Oct 3, 2025
7f1f3e2
Merge branch 'main' of https://github.com/eslint/markdown into refact…
lumirlumir Oct 3, 2025
a747fc4
wip
lumirlumir Oct 4, 2025
d8d5d56
Merge branch 'main' of https://github.com/eslint/markdown into refact…
lumirlumir Oct 4, 2025
36df411
wip
lumirlumir Oct 4, 2025
91b5f0d
wip
lumirlumir Oct 4, 2025
2f936f1
wip
lumirlumir Oct 4, 2025
abad67e
wip: type
lumirlumir Oct 4, 2025
0fbb81a
wip
lumirlumir Oct 4, 2025
3229b6a
wip
lumirlumir Oct 4, 2025
89bef4f
wip
lumirlumir Oct 4, 2025
d3e535e
wip
lumirlumir Oct 4, 2025
21245b4
Merge branch 'main' into refactor-replace-findoffsets-helper-with-nat…
lumirlumir Oct 7, 2025
ba4cf41
wip
lumirlumir Oct 7, 2025
42f977f
Merge branch 'refactor-replace-findoffsets-helper-with-native-methods…
lumirlumir Oct 7, 2025
5759d19
wip: remove `findOffsets` util
lumirlumir Oct 7, 2025
7a56f5f
Merge branch 'main' of https://github.com/eslint/markdown into refact…
lumirlumir Oct 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 18 additions & 34 deletions src/language/markdown-source-code.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
ConfigCommentParser,
Directive,
} from "@eslint/plugin-kit";
import { findOffsets } from "../util.js";

//-----------------------------------------------------------------------------
// Types
Expand Down Expand Up @@ -66,53 +65,38 @@ class InlineConfigComment {
/**
* Extracts inline configuration comments from an HTML node.
* @param {Html} node The HTML node to extract comments from.
* @param {MarkdownSourceCode} sourceCode The Markdown source code object.
* @returns {Array<InlineConfigComment>} The inline configuration comments found in the node.
*/
function extractInlineConfigCommentsFromHTML(node) {
function extractInlineConfigCommentsFromHTML(node, sourceCode) {
if (!configCommentStart.test(node.value)) {
return [];
}

/** @type {Array<InlineConfigComment>} */
const comments = [];

/** @type {RegExpExecArray} */
let match;

while ((match = htmlComment.exec(node.value))) {
if (configCommentStart.test(match[0])) {
const comment = match[0];

// calculate location of the comment inside the node
const start = {
...node.position.start,
};

const end = {
...node.position.start,
};

const {
lineOffset: startLineOffset,
columnOffset: startColumnOffset,
} = findOffsets(node.value, match.index);

start.line += startLineOffset;
start.column += startColumnOffset;
start.offset += match.index;

const commentLineCount = comment.split("\n").length - 1;

end.line = start.line + commentLineCount;
end.column =
commentLineCount === 0
? start.column + comment.length
: comment.length - comment.lastIndexOf("\n");
end.offset = start.offset + comment.length;
// calculate offset of the comment inside the node
const startOffset = match.index + node.position.start.offset;
const endOffset = startOffset + match[0].length;

comments.push(
new InlineConfigComment({
value: match[1].trim(),
position: {
start,
end,
start: {
...sourceCode.getLocFromIndex(startOffset),
offset: startOffset,
},
end: {
...sourceCode.getLocFromIndex(endOffset),
offset: endOffset,
},
},
}),
);
Expand Down Expand Up @@ -191,8 +175,8 @@ export class MarkdownSourceCode extends TextSourceCodeBase {
*/
getInlineConfigNodes() {
if (!this.#inlineConfigComments) {
this.#inlineConfigComments = this.#htmlNodes.flatMap(
extractInlineConfigCommentsFromHTML,
this.#inlineConfigComments = this.#htmlNodes.flatMap(htmlNode =>
extractInlineConfigCommentsFromHTML(htmlNode, this),
);
}

Expand Down
28 changes: 0 additions & 28 deletions src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,34 +23,6 @@ export const htmlCommentPattern = /<!--[\s\S]*?-->/gu;
// Helpers
//-----------------------------------------------------------------------------

/**
* Finds the line and column offsets for a given offset in a string.
* @param {string} text The text to search.
* @param {number} offset The offset to find.
* @returns {{lineOffset:number,columnOffset:number}} The location of the offset.
* Note that `columnOffset` should be used as an offset to the column number
* of the given text in the source code only when `lineOffset` is 0.
* Otherwise, it should be used as a 0-based column number in the source code.
*/
export function findOffsets(text, offset) {
let lineOffset = 0;
let columnOffset = 0;

for (let i = 0; i < offset; i++) {
if (text[i] === "\n") {
lineOffset++;
columnOffset = 0;
} else {
columnOffset++;
}
}

return {
lineOffset,
columnOffset,
};
}

/**
* Checks if a frontmatter block contains a title matching the given pattern
* @param {string} value The frontmatter content
Expand Down
46 changes: 1 addition & 45 deletions tests/util.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,57 +8,13 @@
//------------------------------------------------------------------------------

import assert from "node:assert";
import {
findOffsets,
frontmatterHasTitle,
stripHtmlComments,
} from "../src/util.js";
import { frontmatterHasTitle, stripHtmlComments } from "../src/util.js";

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

describe("util", () => {
describe("findOffsets()", () => {
it("should return correct offsets for a simple string", () => {
const text = "Hello world!";
const offset = 6; // 'w' in "world"
const result = findOffsets(text, offset);
assert.deepStrictEqual(result, { lineOffset: 0, columnOffset: 6 });
});

it("should handle line breaks correctly", () => {
const text = "Hello\nworld!";
const offset = 6; // 'w' in "world"
const result = findOffsets(text, offset);
assert.deepStrictEqual(result, { lineOffset: 1, columnOffset: 0 });
});

it("should handle Windows-style line endings", () => {
const text = "Hello\r\nworld!";
const offset = 7; // 'w' in "world"
const result = findOffsets(text, offset);
assert.deepStrictEqual(result, { lineOffset: 1, columnOffset: 0 });
});

it("should handle offsets at the start of the string", () => {
const text = "Hello, world!";
const offset = 0; // Start of the string
const result = findOffsets(text, offset);
assert.deepStrictEqual(result, { lineOffset: 0, columnOffset: 0 });
});

it("should handle offsets at the end of the string", () => {
const text = "Hello, world!";
const offset = text.length - 1; // Last character '!'
const result = findOffsets(text, offset);
assert.deepStrictEqual(result, {
lineOffset: 0,
columnOffset: text.length - 1,
});
});
});

describe("frontmatterHasTitle()", () => {
const pattern = /^title:\s*My Document$/u;

Expand Down