Skip to content

Commit 68b2028

Browse files
authored
fix: code block filename regexp group names missed (#567)
1 parent a94f74e commit 68b2028

File tree

6 files changed

+49
-43
lines changed

6 files changed

+49
-43
lines changed

.changeset/smart-pillows-hang.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"eslint-plugin-mdx": patch
3+
---
4+
5+
fix: code block filename regexp group names missed

packages/eslint-plugin-mdx/src/processors/helpers.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export const DEFAULT_LANGUAGE_MAPPER: Record<string, string> = {
1+
export const DEFAULT_LANGUAGE_MAPPER = {
22
ecmascript: 'js',
33
javascript: 'js',
44
javascriptreact: 'jsx',
@@ -9,7 +9,7 @@ export const DEFAULT_LANGUAGE_MAPPER: Record<string, string> = {
99
markdownreact: 'mdx',
1010
mdown: 'md',
1111
mkdn: 'md',
12-
}
12+
} as const
1313

1414
export function getShortLang(
1515
filename: string,
@@ -19,7 +19,13 @@ export function getShortLang(
1919
if (languageMapper === false) {
2020
return language
2121
}
22-
languageMapper = { ...DEFAULT_LANGUAGE_MAPPER, ...languageMapper }
22+
languageMapper = languageMapper
23+
? { ...DEFAULT_LANGUAGE_MAPPER, ...languageMapper }
24+
: DEFAULT_LANGUAGE_MAPPER
25+
const mapped = languageMapper[language]
26+
if (mapped) {
27+
return mapped
28+
}
2329
const lang = language.toLowerCase()
24-
return languageMapper[language] || languageMapper[lang] || lang
30+
return languageMapper[lang] || lang
2531
}

packages/eslint-plugin-mdx/src/processors/markdown.ts

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44

55
import type { AST, Linter, Rule } from 'eslint'
66
import type { Node, Parent, Nodes, Root, RootContentMap } from 'mdast'
7+
import type { MdxFlowExpression, MdxTextExpression } from 'mdast-util-mdx'
78

89
import { fromMarkdown } from '../from-markdown.js'
910
import { meta } from '../meta.js'
1011

11-
import type { Block, RangeMap } from './types.js'
12+
import type { CodeBlock, RangeMap } from './types.js'
1213

1314
const UNSATISFIABLE_RULES = new Set([
1415
'eol-last', // The Markdown parser strips trailing newlines in code fences
@@ -18,7 +19,7 @@ const SUPPORTS_AUTOFIX = true
1819

1920
const BOM = '\uFEFF'
2021

21-
const blocksCache: Map<string, Block[]> = new Map()
22+
const blocksCache: Map<string, CodeBlock[]> = new Map()
2223

2324
/**
2425
* Performs a depth-first traversal of the Markdown AST.
@@ -64,10 +65,10 @@ const COMMENTS = [
6465
const eslintCommentRegex = /^(?:eslint\b|global\s)/u
6566

6667
/**
67-
* Extracts `eslint-*` or `global` comments from HTML comments if present.
68-
* @param value The text content of an HTML AST node.
68+
* Extracts `eslint-*` or `global` comments from HTML/MDX comments if present.
69+
* @param value The text content of an HTML/MDX AST node.
6970
* @returns The comment's text without the opening and closing tags or
70-
* an empty string if the text is not an ESLint HTML comment.
71+
* an empty string if the text is not an ESLint HTML/MDX comment.
7172
*/
7273
function getComment(value: string, isMdx = false) {
7374
const [commentStart, commentEnd] = COMMENTS[+isMdx]
@@ -241,14 +242,15 @@ function getBlockRangeMap(text: string, node: Node, comments: string[]) {
241242
return rangeMap
242243
}
243244

244-
const codeBlockFileNameRegex = /filename=(["']).*?\1/u
245+
// eslint-disable-next-line sonarjs/unused-named-groups -- https://community.sonarsource.com/t/names-of-regular-expressions-named-groups-should-be-used-for-self-reference/138306
246+
const codeBlockFileNameRegex = /filename=(?<quote>["'])(?<filename>.*?)\1/u
245247

246248
/**
247249
* Parses the file name from a block meta, if available.
248250
* @param block A code block.
249251
* @returns The filename, if parsed from block meta.
250252
*/
251-
function fileNameFromMeta(block: Block) {
253+
function fileNameFromMeta(block: CodeBlock) {
252254
// istanbul ignore next
253255
return codeBlockFileNameRegex
254256
.exec(block.meta)
@@ -270,19 +272,28 @@ function preprocess(sourceText: string, filename: string) {
270272
// FIXME: how to read `extensions` and `markdownExtensions` parser options?
271273
filename.endsWith('.mdx'),
272274
)
273-
const blocks: Block[] = []
275+
const blocks: CodeBlock[] = []
274276

275277
blocksCache.set(filename, blocks)
276278

277279
/**
278-
* During the depth-first traversal, keep track of any sequences of HTML
280+
* During the depth-first traversal, keep track of any sequences of HTML/MDX
279281
* comment nodes containing `eslint-*` or `global` comments. If a code
280282
* block immediately follows such a sequence, insert the comments at the
281283
* top of the code block. Any non-ESLint comment or other node type breaks
282284
* and empties the sequence.
283285
*/
284286
let allComments: string[] = []
285287

288+
function mdxExpression(node: MdxFlowExpression | MdxTextExpression) {
289+
const comment = getComment(node.value, true)
290+
if (comment) {
291+
allComments.push(comment)
292+
} else {
293+
allComments = []
294+
}
295+
}
296+
286297
traverse(ast, {
287298
'*'() {
288299
allComments = []
@@ -330,25 +341,11 @@ function preprocess(sourceText: string, filename: string) {
330341
allComments = []
331342
}
332343
},
333-
mdxFlowExpression(node) {
334-
const comment = getComment(node.value, true)
335-
if (comment) {
336-
allComments.push(comment)
337-
} else {
338-
allComments = []
339-
}
340-
},
341-
mdxTextExpression(node) {
342-
const comment = getComment(node.value, true)
343-
if (comment) {
344-
allComments.push(comment)
345-
} else {
346-
allComments = []
347-
}
348-
},
344+
345+
mdxFlowExpression: mdxExpression,
346+
mdxTextExpression: mdxExpression,
349347
})
350348

351-
// istanbul ignore next
352349
return blocks.map((block, index) => {
353350
const [language] = block.lang.trim().split(' ')
354351
return {
@@ -364,7 +361,7 @@ function preprocess(sourceText: string, filename: string) {
364361
* @param fix A fix to adjust.
365362
* @returns The fix with adjusted ranges.
366363
*/
367-
function adjustFix(block: Block, fix: Rule.Fix): Rule.Fix {
364+
function adjustFix(block: CodeBlock, fix: Rule.Fix): Rule.Fix {
368365
return {
369366
range: fix.range.map(range => {
370367
// Advance through the block's range map to find the last
@@ -388,7 +385,7 @@ function adjustFix(block: Block, fix: Rule.Fix): Rule.Fix {
388385
* @param block A code block.
389386
* @returns A function that adjusts messages in a code block.
390387
*/
391-
function adjustBlock(block: Block) {
388+
function adjustBlock(block: CodeBlock) {
392389
const leadingCommentLines = block.comments.reduce(
393390
(count, comment) => count + comment.split('\n').length,
394391
0,

packages/eslint-plugin-mdx/src/processors/types.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,8 @@ export interface RangeMap {
1616
md: number
1717
}
1818

19-
export interface BlockBase {
19+
export interface CodeBlock extends Code {
2020
baseIndentText: string
2121
comments: string[]
2222
rangeMap: RangeMap[]
2323
}
24-
25-
export interface Block extends Code, BlockBase {}

test/__snapshots__/fixtures.test.ts.snap

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@ exports[`fixtures lint code blocks should work as expected: code-blocks/455.mdx
176176
"endLine": 2,
177177
"fix": {
178178
"range": [
179-
6,
180-
9,
179+
25,
180+
28,
181181
],
182182
"text": "let",
183183
},
@@ -194,8 +194,8 @@ exports[`fixtures lint code blocks should work as expected: code-blocks/455.mdx
194194
"endLine": 4,
195195
"fix": {
196196
"range": [
197-
13,
198-
30,
197+
32,
198+
49,
199199
],
200200
"text": "const b = [1, 2, 3]",
201201
},
@@ -212,8 +212,8 @@ exports[`fixtures lint code blocks should work as expected: code-blocks/455.mdx
212212
"endLine": 6,
213213
"fix": {
214214
"range": [
215-
43,
216-
57,
215+
62,
216+
76,
217217
],
218218
"text": ".at(-1)",
219219
},
@@ -228,7 +228,7 @@ exports[`fixtures lint code blocks should work as expected: code-blocks/455.mdx
228228
`;
229229

230230
exports[`fixtures lint code blocks should work as expected: code-blocks/455.mdx 2`] = `
231-
"\`\`\`js
231+
"\`\`\`js filename="test.js"
232232
let a
233233
234234
const b = [1, 2, 3]

test/fixtures/code-blocks/455.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
```js
1+
```js filename="test.js"
22
var a
33

44
let b = [1, 2, 3]

0 commit comments

Comments
 (0)