Skip to content

Commit 6a7c10c

Browse files
Copilotkermanx
andauthored
fix: update region marker patterns (#2349)
Co-authored-by: kermanx <63178754+kermanx@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: _Kerman <kermanx@qq.com>
1 parent 6f18698 commit 6a7c10c

File tree

1 file changed

+68
-35
lines changed

1 file changed

+68
-35
lines changed

packages/slidev/node/syntax/transform/snippet.ts

Lines changed: 68 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -24,43 +24,76 @@ function dedent(text: string): string {
2424
return text
2525
}
2626

27+
/* eslint-disable regexp/no-super-linear-backtracking */
28+
const markers = [
29+
{
30+
start: /^\s*\/\/\s*#?region\b\s*(.*?)\s*$/,
31+
end: /^\s*\/\/\s*#?endregion\b\s*(.*?)\s*$/,
32+
},
33+
{
34+
start: /^\s*<!--\s*#?region\b\s*(.*?)\s*-->/,
35+
end: /^\s*<!--\s*#?endregion\b\s*(.*?)\s*-->/,
36+
},
37+
{
38+
start: /^\s*\/\*\s*#region\b\s*(.*?)\s*\*\//,
39+
end: /^\s*\/\*\s*#endregion\b\s*(.*?)\s*\*\//,
40+
},
41+
{
42+
start: /^\s*#[rR]egion\b\s*(.*?)\s*$/,
43+
end: /^\s*#[eE]nd ?[rR]egion\b\s*(.*?)\s*$/,
44+
},
45+
{
46+
start: /^\s*#\s*#?region\b\s*(.*?)\s*$/,
47+
end: /^\s*#\s*#?endregion\b\s*(.*?)\s*$/,
48+
},
49+
{
50+
start: /^\s*(?:--|::|@?REM)\s*#region\b\s*(.*?)\s*$/,
51+
end: /^\s*(?:--|::|@?REM)\s*#endregion\b\s*(.*?)\s*$/,
52+
},
53+
{
54+
start: /^\s*#pragma\s+region\b\s*(.*?)\s*$/,
55+
end: /^\s*#pragma\s+endregion\b\s*(.*?)\s*$/,
56+
},
57+
{
58+
start: /^\s*\(\*\s*#region\b\s*(.*?)\s*\*\)/,
59+
end: /^\s*\(\*\s*#endregion\b\s*(.*?)\s*\*\)/,
60+
},
61+
]
62+
/* eslint-enable regexp/no-super-linear-backtracking */
63+
2764
function findRegion(lines: Array<string>, regionName: string) {
28-
const regionRegexps = [
29-
// javascript, typescript, java
30-
[/^\/\/ ?#?region ([\w*-]+)$/, /^\/\/ ?#?endregion/],
31-
// css, less, scss
32-
[/^\/\* ?#region ([\w*-]+) ?\*\/$/, /^\/\* ?#endregion[\s\w*-]*\*\/$/],
33-
// C, C++
34-
[/^#pragma region ([\w*-]+)$/, /^#pragma endregion/],
35-
// HTML, markdown
36-
[/^<!-- #?region ([\w*-]+) -->$/, /^<!-- #?region[\s\w*-]*-->$/],
37-
// Visual Basic
38-
[/^#Region ([\w*-]+)$/, /^#End Region/],
39-
// Bat
40-
[/^::#region ([\w*-]+)$/, /^::#endregion/],
41-
// C#, PHP, Powershell, Python, perl & misc
42-
[/^# ?region ([\w*-]+)$/, /^# ?endregion/],
43-
]
44-
45-
let endReg = null
46-
let start = -1
47-
48-
for (const [lineId, line] of lines.entries()) {
49-
if (endReg === null) {
50-
for (const [startReg, end] of regionRegexps) {
51-
const match = line.trim().match(startReg)
52-
if (match && match[1] === regionName) {
53-
start = lineId + 1
54-
endReg = end
55-
break
56-
}
65+
let chosen: { re: (typeof markers)[number], start: number } | null = null
66+
// find the regex pair for a start marker that matches the given region name
67+
for (let i = 0; i < lines.length; i++) {
68+
for (const re of markers) {
69+
if (re.start.exec(lines[i])?.[1] === regionName) {
70+
chosen = { re, start: i + 1 }
71+
break
5772
}
5873
}
59-
else if (endReg.test(line.trim())) {
60-
return {
61-
start,
62-
end: lineId,
63-
regexp: endReg,
74+
if (chosen)
75+
break
76+
}
77+
if (!chosen)
78+
return null
79+
80+
let counter = 1
81+
// scan the rest of the lines to find the matching end marker, handling nested markers
82+
for (let i = chosen.start; i < lines.length; i++) {
83+
// check for an inner start marker for the same region
84+
if (chosen.re.start.exec(lines[i])?.[1] === regionName) {
85+
counter++
86+
continue
87+
}
88+
// check for an end marker for the same region
89+
const endRegion = chosen.re.end.exec(lines[i])?.[1]
90+
// allow empty region name on the end marker as a fallback
91+
if (endRegion === regionName || endRegion === '') {
92+
if (--counter === 0) {
93+
return {
94+
...chosen,
95+
end: i,
96+
}
6497
}
6598
}
6699
}
@@ -116,7 +149,7 @@ export function transformSnippet({ s, slide, options }: MarkdownTransformContext
116149
content = dedent(
117150
lines
118151
.slice(region.start, region.end)
119-
.filter(line => !region.regexp.test(line.trim()))
152+
.filter(l => !(region.re.start.test(l) || region.re.end.test(l)))
120153
.join('\n'),
121154
)
122155
}

0 commit comments

Comments
 (0)