From 42794ab47b390cbec5ec612d02bfe00693855d61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Wed, 8 Oct 2025 20:23:20 +0900 Subject: [PATCH 01/16] wip --- src/rules/no-missing-atx-heading-space.js | 28 ++++++++++------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/rules/no-missing-atx-heading-space.js b/src/rules/no-missing-atx-heading-space.js index bffc2c41..edec073b 100644 --- a/src/rules/no-missing-atx-heading-space.js +++ b/src/rules/no-missing-atx-heading-space.js @@ -20,7 +20,7 @@ const leadingAtxHeadingHashPattern = /^(#{1,6})(?:[^# \t]|$)/u; const trailingAtxHeadingHashPattern = - /(?[ \t]*)(?<=(?#+)(?[ \t]*)$/u; const newLinePattern = /\r?\n/u; /** @@ -32,8 +32,8 @@ function findMissingSpaceBeforeClosingHash(text) { const match = trailingAtxHeadingHashPattern.exec(text); if (match) { - const [, closingSequenceSpaces, closingSequence, trailingSpaces] = - match; + const { closingSequenceSpaces, closingSequence, trailingSpaces } = + match.groups; if (closingSequenceSpaces.length === 0) { const closingHashIdx = @@ -99,31 +99,27 @@ export default { } const text = context.sourceCode.getText(node); - const lineNum = node.position.start.line; - const startColumn = node.position.start.column; + const nodeStartOffset = node.position.start.offset; const missingSpace = findMissingSpaceBeforeClosingHash(text); if (missingSpace) { context.report({ loc: { - start: { - line: lineNum, - column: - startColumn + missingSpace.beforeHashIdx, - }, - end: { - line: lineNum, - column: startColumn + missingSpace.endIdx, - }, + start: context.sourceCode.getLocFromIndex( + nodeStartOffset + missingSpace.beforeHashIdx, + ), + end: context.sourceCode.getLocFromIndex( + nodeStartOffset + missingSpace.endIdx, + ), }, messageId: "missingSpace", data: { position: "before" }, fix(fixer) { return fixer.insertTextBeforeRange( [ - node.position.start.offset + + nodeStartOffset + missingSpace.closingHashIdx, - node.position.start.offset + + nodeStartOffset + missingSpace.closingHashIdx + 1, ], From a80183afda732411ba819ba7c439d929b07f4ca0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Wed, 8 Oct 2025 20:24:19 +0900 Subject: [PATCH 02/16] wip --- src/rules/no-missing-atx-heading-space.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/rules/no-missing-atx-heading-space.js b/src/rules/no-missing-atx-heading-space.js index edec073b..1ab07997 100644 --- a/src/rules/no-missing-atx-heading-space.js +++ b/src/rules/no-missing-atx-heading-space.js @@ -90,6 +90,7 @@ export default { }, create(context) { + const { sourceCode } = context; const [{ checkClosedHeadings }] = context.options; return { @@ -98,17 +99,17 @@ export default { return; } - const text = context.sourceCode.getText(node); + const text = sourceCode.getText(node); const nodeStartOffset = node.position.start.offset; const missingSpace = findMissingSpaceBeforeClosingHash(text); if (missingSpace) { context.report({ loc: { - start: context.sourceCode.getLocFromIndex( + start: sourceCode.getLocFromIndex( nodeStartOffset + missingSpace.beforeHashIdx, ), - end: context.sourceCode.getLocFromIndex( + end: sourceCode.getLocFromIndex( nodeStartOffset + missingSpace.endIdx, ), }, @@ -131,7 +132,7 @@ export default { }, paragraph(node) { - const text = context.sourceCode.getText(node); + const text = sourceCode.getText(node); const lines = text.split(newLinePattern); const startColumn = node.position.start.column; let offset = node.position.start.offset; From 3c86d518dd710ae02457311f43ab811307d3d31c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Wed, 8 Oct 2025 20:34:51 +0900 Subject: [PATCH 03/16] wip --- src/rules/no-missing-atx-heading-space.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rules/no-missing-atx-heading-space.js b/src/rules/no-missing-atx-heading-space.js index 1ab07997..cf542238 100644 --- a/src/rules/no-missing-atx-heading-space.js +++ b/src/rules/no-missing-atx-heading-space.js @@ -18,7 +18,7 @@ // Helpers //----------------------------------------------------------------------------- -const leadingAtxHeadingHashPattern = /^(#{1,6})(?:[^# \t]|$)/u; +const leadingAtxHeadingHashPattern = /^(?#{1,6})(?:[^# \t]|$)/u; const trailingAtxHeadingHashPattern = /(?[ \t]*)(?<=(?#+)(?[ \t]*)$/u; const newLinePattern = /\r?\n/u; @@ -142,7 +142,7 @@ export default { const lineNum = node.position.start.line + idx; if (match) { - const hashes = match[1]; + const { hashes } = match.groups; context.report({ loc: { From b1b44c7da1f90f5c8dfd94303723e0ef4127df2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Wed, 8 Oct 2025 20:41:08 +0900 Subject: [PATCH 04/16] wip: add test (error) --- src/rules/no-missing-atx-heading-space.js | 2 +- tests/rules/no-missing-atx-heading-space.test.js | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/rules/no-missing-atx-heading-space.js b/src/rules/no-missing-atx-heading-space.js index cf542238..a31838a4 100644 --- a/src/rules/no-missing-atx-heading-space.js +++ b/src/rules/no-missing-atx-heading-space.js @@ -166,7 +166,7 @@ export default { }); } - offset += line.length + 1; + offset += line.length + 1; // TODO: `+1` should be replaced with the length of the line ending }); }, }; diff --git a/tests/rules/no-missing-atx-heading-space.test.js b/tests/rules/no-missing-atx-heading-space.test.js index ddb40758..26f7f9e5 100644 --- a/tests/rules/no-missing-atx-heading-space.test.js +++ b/tests/rules/no-missing-atx-heading-space.test.js @@ -463,6 +463,20 @@ const invalidTests = [ }, ], }, + { + code: "Text before\r\n#Heading with ``` code markers\r\nText after", + output: "Text before\r\n# Heading with ``` code markers\r\nText after", + errors: [ + { + messageId: "missingSpace", + data: { position: "after" }, + line: 2, + column: 1, + endLine: 2, + endColumn: 3, + }, + ], + }, { code: " ##Heading 2", From 495f65b87bb60739531415671752e5fded156b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Wed, 8 Oct 2025 20:50:57 +0900 Subject: [PATCH 05/16] wip --- src/rules/no-missing-atx-heading-space.js | 21 +++++++------------ .../no-missing-atx-heading-space.test.js | 2 ++ 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/rules/no-missing-atx-heading-space.js b/src/rules/no-missing-atx-heading-space.js index a31838a4..169aba56 100644 --- a/src/rules/no-missing-atx-heading-space.js +++ b/src/rules/no-missing-atx-heading-space.js @@ -134,39 +134,32 @@ export default { paragraph(node) { const text = sourceCode.getText(node); const lines = text.split(newLinePattern); - const startColumn = node.position.start.column; - let offset = node.position.start.offset; + let startOffset = node.position.start.offset; - lines.forEach((line, idx) => { + lines.forEach(line => { const match = leadingAtxHeadingHashPattern.exec(line); - const lineNum = node.position.start.line + idx; if (match) { const { hashes } = match.groups; + const endOffset = startOffset + hashes.length; context.report({ loc: { - start: { line: lineNum, column: startColumn }, - end: { - line: lineNum, - column: startColumn + hashes.length + 1, - }, + start: sourceCode.getLocFromIndex(startOffset), + end: sourceCode.getLocFromIndex(endOffset + 1), }, messageId: "missingSpace", data: { position: "after" }, fix(fixer) { return fixer.insertTextAfterRange( - [ - offset + hashes.length - 1, - offset + hashes.length, - ], + [endOffset - 1, endOffset], " ", ); }, }); } - offset += line.length + 1; // TODO: `+1` should be replaced with the length of the line ending + startOffset += line.length + 1; // TODO: `+1` should be replaced with the length of the line ending }); }, }; diff --git a/tests/rules/no-missing-atx-heading-space.test.js b/tests/rules/no-missing-atx-heading-space.test.js index 26f7f9e5..a649005d 100644 --- a/tests/rules/no-missing-atx-heading-space.test.js +++ b/tests/rules/no-missing-atx-heading-space.test.js @@ -463,6 +463,7 @@ const invalidTests = [ }, ], }, + /* { code: "Text before\r\n#Heading with ``` code markers\r\nText after", output: "Text before\r\n# Heading with ``` code markers\r\nText after", @@ -477,6 +478,7 @@ const invalidTests = [ }, ], }, + */ { code: " ##Heading 2", From 26e5eb2dd130f40b18be1cab71c6217733dd8f8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Wed, 8 Oct 2025 22:09:46 +0900 Subject: [PATCH 06/16] wip --- src/rules/no-missing-atx-heading-space.js | 58 +++++++++---------- .../no-missing-atx-heading-space.test.js | 16 ++++- 2 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/rules/no-missing-atx-heading-space.js b/src/rules/no-missing-atx-heading-space.js index 169aba56..c505ba08 100644 --- a/src/rules/no-missing-atx-heading-space.js +++ b/src/rules/no-missing-atx-heading-space.js @@ -18,10 +18,9 @@ // Helpers //----------------------------------------------------------------------------- -const leadingAtxHeadingHashPattern = /^(?#{1,6})(?:[^# \t]|$)/u; +const leadingAtxHeadingHashPattern = /^(?#{1,6})(?:[^# \t]|$)/gmu; const trailingAtxHeadingHashPattern = /(?[ \t]*)(?<=(?#+)(?[ \t]*)$/u; -const newLinePattern = /\r?\n/u; /** * Finds missing space before the closing hashes in an ATX heading. @@ -133,34 +132,33 @@ export default { paragraph(node) { const text = sourceCode.getText(node); - const lines = text.split(newLinePattern); - let startOffset = node.position.start.offset; - - lines.forEach(line => { - const match = leadingAtxHeadingHashPattern.exec(line); - - if (match) { - const { hashes } = match.groups; - const endOffset = startOffset + hashes.length; - - context.report({ - loc: { - start: sourceCode.getLocFromIndex(startOffset), - end: sourceCode.getLocFromIndex(endOffset + 1), - }, - messageId: "missingSpace", - data: { position: "after" }, - fix(fixer) { - return fixer.insertTextAfterRange( - [endOffset - 1, endOffset], - " ", - ); - }, - }); - } - - startOffset += line.length + 1; // TODO: `+1` should be replaced with the length of the line ending - }); + + /** @type {RegExpExecArray | null} */ + let match; + + while ( + (match = leadingAtxHeadingHashPattern.exec(text)) !== null + ) { + const { hashes } = match.groups; + const startOffset = + match.index + node.position.start.offset; + const endOffset = startOffset + hashes.length; + + context.report({ + loc: { + start: sourceCode.getLocFromIndex(startOffset), + end: sourceCode.getLocFromIndex(endOffset + 1), + }, + messageId: "missingSpace", + data: { position: "after" }, + fix(fixer) { + return fixer.insertTextAfterRange( + [endOffset - 1, endOffset], + " ", + ); + }, + }); + } }, }; }, diff --git a/tests/rules/no-missing-atx-heading-space.test.js b/tests/rules/no-missing-atx-heading-space.test.js index a649005d..3b6bcd98 100644 --- a/tests/rules/no-missing-atx-heading-space.test.js +++ b/tests/rules/no-missing-atx-heading-space.test.js @@ -463,7 +463,6 @@ const invalidTests = [ }, ], }, - /* { code: "Text before\r\n#Heading with ``` code markers\r\nText after", output: "Text before\r\n# Heading with ``` code markers\r\nText after", @@ -478,6 +477,21 @@ const invalidTests = [ }, ], }, + /* + { + code: "Text before\r#Heading with ``` code markers\rText after", + output: "Text before\r# Heading with ``` code markers\rText after", + errors: [ + { + messageId: "missingSpace", + data: { position: "after" }, + line: 2, + column: 1, + endLine: 2, + endColumn: 3, + }, + ], + }, */ { From 4af023a9ff29d9a22cd8b5d9c6a63e9b2ed9e516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Wed, 8 Oct 2025 22:22:48 +0900 Subject: [PATCH 07/16] wip: simplify --- src/rules/no-missing-atx-heading-space.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/rules/no-missing-atx-heading-space.js b/src/rules/no-missing-atx-heading-space.js index c505ba08..d40ce682 100644 --- a/src/rules/no-missing-atx-heading-space.js +++ b/src/rules/no-missing-atx-heading-space.js @@ -20,7 +20,7 @@ const leadingAtxHeadingHashPattern = /^(?#{1,6})(?:[^# \t]|$)/gmu; const trailingAtxHeadingHashPattern = - /(?[ \t]*)(?<=(?#+)(?[ \t]*)$/u; + /(?[ \t]*)(?<=(?#+)[ \t]*$/u; /** * Finds missing space before the closing hashes in an ATX heading. @@ -31,12 +31,10 @@ function findMissingSpaceBeforeClosingHash(text) { const match = trailingAtxHeadingHashPattern.exec(text); if (match) { - const { closingSequenceSpaces, closingSequence, trailingSpaces } = - match.groups; + const { closingSequenceSpaces, closingSequence } = match.groups; if (closingSequenceSpaces.length === 0) { - const closingHashIdx = - text.length - (trailingSpaces.length + closingSequence.length); + const closingHashIdx = match.index + closingSequenceSpaces.length; const beforeHashIdx = closingHashIdx - 1; const endIdx = closingHashIdx + closingSequence.length; return { From 8d51e205dd384149f02d945257907adef369992b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Wed, 8 Oct 2025 22:41:31 +0900 Subject: [PATCH 08/16] wip --- src/rules/no-missing-atx-heading-space.js | 89 +++++++++-------------- 1 file changed, 34 insertions(+), 55 deletions(-) diff --git a/src/rules/no-missing-atx-heading-space.js b/src/rules/no-missing-atx-heading-space.js index d40ce682..a95f1a5d 100644 --- a/src/rules/no-missing-atx-heading-space.js +++ b/src/rules/no-missing-atx-heading-space.js @@ -20,33 +20,7 @@ const leadingAtxHeadingHashPattern = /^(?#{1,6})(?:[^# \t]|$)/gmu; const trailingAtxHeadingHashPattern = - /(?[ \t]*)(?<=(?#+)[ \t]*$/u; - -/** - * Finds missing space before the closing hashes in an ATX heading. - * @param {string} text The input text to check. - * @returns {{ closingHashIdx: number, beforeHashIdx: number, endIdx: number } | null} The positions of the closing hashes in the heading, or null if no missing space is found. - */ -function findMissingSpaceBeforeClosingHash(text) { - const match = trailingAtxHeadingHashPattern.exec(text); - - if (match) { - const { closingSequenceSpaces, closingSequence } = match.groups; - - if (closingSequenceSpaces.length === 0) { - const closingHashIdx = match.index + closingSequenceSpaces.length; - const beforeHashIdx = closingHashIdx - 1; - const endIdx = closingHashIdx + closingSequence.length; - return { - closingHashIdx, - beforeHashIdx, - endIdx, - }; - } - } - - return null; -} + /(?[ \t]*)(?<=(?#+)[ \t]*$/gu; //----------------------------------------------------------------------------- // Rule Definition @@ -97,34 +71,39 @@ export default { } const text = sourceCode.getText(node); - const nodeStartOffset = node.position.start.offset; - const missingSpace = findMissingSpaceBeforeClosingHash(text); - if (missingSpace) { - context.report({ - loc: { - start: sourceCode.getLocFromIndex( - nodeStartOffset + missingSpace.beforeHashIdx, - ), - end: sourceCode.getLocFromIndex( - nodeStartOffset + missingSpace.endIdx, - ), - }, - messageId: "missingSpace", - data: { position: "before" }, - fix(fixer) { - return fixer.insertTextBeforeRange( - [ - nodeStartOffset + - missingSpace.closingHashIdx, - nodeStartOffset + - missingSpace.closingHashIdx + - 1, - ], - " ", - ); - }, - }); + /** @type {RegExpExecArray | null} */ + let match; + + while ( + (match = trailingAtxHeadingHashPattern.exec(text)) !== null + ) { + const { spaces, hashes } = match.groups; + + if (spaces.length === 0) { + const startOffset = + node.position.start.offset + + match.index + + spaces.length; + const endOffset = startOffset + hashes.length; + + context.report({ + loc: { + start: sourceCode.getLocFromIndex( + startOffset - 1, + ), + end: sourceCode.getLocFromIndex(endOffset), + }, + messageId: "missingSpace", + data: { position: "before" }, + fix(fixer) { + return fixer.insertTextBeforeRange( + [startOffset, startOffset + 1], + " ", + ); + }, + }); + } } }, @@ -139,7 +118,7 @@ export default { ) { const { hashes } = match.groups; const startOffset = - match.index + node.position.start.offset; + node.position.start.offset + match.index; const endOffset = startOffset + hashes.length; context.report({ From 4c9e9244a9259e3fcbfcd91ce6204c5c1f950474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Fri, 10 Oct 2025 14:48:20 +0900 Subject: [PATCH 09/16] wip: test --- tests/rules/no-missing-atx-heading-space.test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/rules/no-missing-atx-heading-space.test.js b/tests/rules/no-missing-atx-heading-space.test.js index 3b6bcd98..d4e7db77 100644 --- a/tests/rules/no-missing-atx-heading-space.test.js +++ b/tests/rules/no-missing-atx-heading-space.test.js @@ -477,7 +477,6 @@ const invalidTests = [ }, ], }, - /* { code: "Text before\r#Heading with ``` code markers\rText after", output: "Text before\r# Heading with ``` code markers\rText after", @@ -492,7 +491,6 @@ const invalidTests = [ }, ], }, - */ { code: " ##Heading 2", From 5aad55b388bcad69d886c165d7dbb523fdf7eb2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Fri, 10 Oct 2025 15:24:10 +0900 Subject: [PATCH 10/16] wip --- src/rules/no-missing-atx-heading-space.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/rules/no-missing-atx-heading-space.js b/src/rules/no-missing-atx-heading-space.js index a95f1a5d..245c3cc7 100644 --- a/src/rules/no-missing-atx-heading-space.js +++ b/src/rules/no-missing-atx-heading-space.js @@ -82,9 +82,7 @@ export default { if (spaces.length === 0) { const startOffset = - node.position.start.offset + - match.index + - spaces.length; + node.position.start.offset + match.index; const endOffset = startOffset + hashes.length; context.report({ From 312243f2278acab970cb351e9c638b209c9fb11c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Sat, 11 Oct 2025 19:25:50 +0900 Subject: [PATCH 11/16] wip --- src/rules/no-missing-atx-heading-space.js | 57 +++++++++++------------ 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/src/rules/no-missing-atx-heading-space.js b/src/rules/no-missing-atx-heading-space.js index 245c3cc7..20c9d428 100644 --- a/src/rules/no-missing-atx-heading-space.js +++ b/src/rules/no-missing-atx-heading-space.js @@ -20,7 +20,7 @@ const leadingAtxHeadingHashPattern = /^(?#{1,6})(?:[^# \t]|$)/gmu; const trailingAtxHeadingHashPattern = - /(?[ \t]*)(?<=(?#+)[ \t]*$/gu; + /(?[ \t]*)(?<=(?#+)[ \t]*$/u; //----------------------------------------------------------------------------- // Rule Definition @@ -71,38 +71,35 @@ export default { } const text = sourceCode.getText(node); + const match = trailingAtxHeadingHashPattern.exec(text); - /** @type {RegExpExecArray | null} */ - let match; + if (match === null) { + return; + } - while ( - (match = trailingAtxHeadingHashPattern.exec(text)) !== null - ) { - const { spaces, hashes } = match.groups; - - if (spaces.length === 0) { - const startOffset = - node.position.start.offset + match.index; - const endOffset = startOffset + hashes.length; - - context.report({ - loc: { - start: sourceCode.getLocFromIndex( - startOffset - 1, - ), - end: sourceCode.getLocFromIndex(endOffset), - }, - messageId: "missingSpace", - data: { position: "before" }, - fix(fixer) { - return fixer.insertTextBeforeRange( - [startOffset, startOffset + 1], - " ", - ); - }, - }); - } + const { spaces, hashes } = match.groups; + + if (spaces.length > 0) { + return; } + + const startOffset = node.position.start.offset + match.index; + const endOffset = startOffset + hashes.length; + + context.report({ + loc: { + start: sourceCode.getLocFromIndex(startOffset - 1), + end: sourceCode.getLocFromIndex(endOffset), + }, + messageId: "missingSpace", + data: { position: "before" }, + fix(fixer) { + return fixer.insertTextBeforeRange( + [startOffset, startOffset + 1], + " ", + ); + }, + }); }, paragraph(node) { From 36c9e600971c2dab5fcc9e54e53ce8ffd3527f65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Sat, 11 Oct 2025 19:43:12 +0900 Subject: [PATCH 12/16] wip: resolve Bun CI failure --- package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package.json b/package.json index 52d01489..27421a6b 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,8 @@ "devDependencies": { "@eslint/js": "^9.36.0", "@eslint/json": "^0.13.2", + "@types/mdast": "^4.0.4", + "@types/unist": "^3.0.3", "c8": "^10.1.3", "dedent": "^1.5.3", "eslint": "^9.36.0", From ad01802b2529ac55a369a1568d8568ecdfec2a00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Sat, 11 Oct 2025 19:45:46 +0900 Subject: [PATCH 13/16] wip: resolve Bun CI error (`semver`) --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 27421a6b..5c8ea689 100644 --- a/package.json +++ b/package.json @@ -86,6 +86,7 @@ "lint-staged": "^15.2.9", "mocha": "^11.6.0", "prettier": "^3.3.3", + "semver": "^7.7.3", "typescript": "^5.9.2", "yorkie": "^2.0.0" }, From 900ac55b34898d3fdd7d45c8efd0d6ab2a8c4858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Tue, 14 Oct 2025 19:15:59 +0900 Subject: [PATCH 14/16] wip: add test case for LS and PS --- tests/rules/no-missing-atx-heading-space.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/rules/no-missing-atx-heading-space.test.js b/tests/rules/no-missing-atx-heading-space.test.js index d4e7db77..7c854f7a 100644 --- a/tests/rules/no-missing-atx-heading-space.test.js +++ b/tests/rules/no-missing-atx-heading-space.test.js @@ -62,6 +62,7 @@ const validHeadings = [ "Not a heading", "This is a paragraph with a #hashtag", "Text with # in the middle", + "foo\u2028\u2028#Bar\u2029\u2029#Baz", // with line and paragraph separators // 7. Code blocks containing hash symbols // 7.1 Fenced code blocks From c815d6072c4ff04b521359648634b65fc88d67e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Tue, 14 Oct 2025 19:30:15 +0900 Subject: [PATCH 15/16] wip: remove `m` flag --- src/rules/no-missing-atx-heading-space.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rules/no-missing-atx-heading-space.js b/src/rules/no-missing-atx-heading-space.js index 20c9d428..aa5f6a1b 100644 --- a/src/rules/no-missing-atx-heading-space.js +++ b/src/rules/no-missing-atx-heading-space.js @@ -18,7 +18,8 @@ // Helpers //----------------------------------------------------------------------------- -const leadingAtxHeadingHashPattern = /^(?#{1,6})(?:[^# \t]|$)/gmu; +const leadingAtxHeadingHashPattern = + /(?:^|(?<=\r\n)|(?<=[\r\n]))(?#{1,6})(?:[^# \t]|$)/gu; const trailingAtxHeadingHashPattern = /(?[ \t]*)(?<=(?#+)[ \t]*$/u; From 85dc6e6fbc7c0197ae53fff43da66bd906811122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Wed, 22 Oct 2025 18:54:43 +0900 Subject: [PATCH 16/16] Update src/rules/no-missing-atx-heading-space.js Co-authored-by: Milos Djermanovic --- src/rules/no-missing-atx-heading-space.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rules/no-missing-atx-heading-space.js b/src/rules/no-missing-atx-heading-space.js index aa5f6a1b..795f4441 100644 --- a/src/rules/no-missing-atx-heading-space.js +++ b/src/rules/no-missing-atx-heading-space.js @@ -19,7 +19,7 @@ //----------------------------------------------------------------------------- const leadingAtxHeadingHashPattern = - /(?:^|(?<=\r\n)|(?<=[\r\n]))(?#{1,6})(?:[^# \t]|$)/gu; + /(?:^|(?<=[\r\n]))(?#{1,6})(?:[^# \t]|$)/gu; const trailingAtxHeadingHashPattern = /(?[ \t]*)(?<=(?#+)[ \t]*$/u;