@@ -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 * # ? r e g i o n \b \s * ( .* ?) \s * $ / ,
31+ end : / ^ \s * \/ \/ \s * # ? e n d r e g i o n \b \s * ( .* ?) \s * $ / ,
32+ } ,
33+ {
34+ start : / ^ \s * < ! - - \s * # ? r e g i o n \b \s * ( .* ?) \s * - - > / ,
35+ end : / ^ \s * < ! - - \s * # ? e n d r e g i o n \b \s * ( .* ?) \s * - - > / ,
36+ } ,
37+ {
38+ start : / ^ \s * \/ \* \s * # r e g i o n \b \s * ( .* ?) \s * \* \/ / ,
39+ end : / ^ \s * \/ \* \s * # e n d r e g i o n \b \s * ( .* ?) \s * \* \/ / ,
40+ } ,
41+ {
42+ start : / ^ \s * # [ r R ] e g i o n \b \s * ( .* ?) \s * $ / ,
43+ end : / ^ \s * # [ e E ] n d ? [ r R ] e g i o n \b \s * ( .* ?) \s * $ / ,
44+ } ,
45+ {
46+ start : / ^ \s * # \s * # ? r e g i o n \b \s * ( .* ?) \s * $ / ,
47+ end : / ^ \s * # \s * # ? e n d r e g i o n \b \s * ( .* ?) \s * $ / ,
48+ } ,
49+ {
50+ start : / ^ \s * (?: - - | : : | @ ? R E M ) \s * # r e g i o n \b \s * ( .* ?) \s * $ / ,
51+ end : / ^ \s * (?: - - | : : | @ ? R E M ) \s * # e n d r e g i o n \b \s * ( .* ?) \s * $ / ,
52+ } ,
53+ {
54+ start : / ^ \s * # p r a g m a \s + r e g i o n \b \s * ( .* ?) \s * $ / ,
55+ end : / ^ \s * # p r a g m a \s + e n d r e g i o n \b \s * ( .* ?) \s * $ / ,
56+ } ,
57+ {
58+ start : / ^ \s * \( \* \s * # r e g i o n \b \s * ( .* ?) \s * \* \) / ,
59+ end : / ^ \s * \( \* \s * # e n d r e g i o n \b \s * ( .* ?) \s * \* \) / ,
60+ } ,
61+ ]
62+ /* eslint-enable regexp/no-super-linear-backtracking */
63+
2764function findRegion ( lines : Array < string > , regionName : string ) {
28- const regionRegexps = [
29- // javascript, typescript, java
30- [ / ^ \/ \/ ? # ? r e g i o n ( [ \w * - ] + ) $ / , / ^ \/ \/ ? # ? e n d r e g i o n / ] ,
31- // css, less, scss
32- [ / ^ \/ \* ? # r e g i o n ( [ \w * - ] + ) ? \* \/ $ / , / ^ \/ \* ? # e n d r e g i o n [ \s \w * - ] * \* \/ $ / ] ,
33- // C, C++
34- [ / ^ # p r a g m a r e g i o n ( [ \w * - ] + ) $ / , / ^ # p r a g m a e n d r e g i o n / ] ,
35- // HTML, markdown
36- [ / ^ < ! - - # ? r e g i o n ( [ \w * - ] + ) - - > $ / , / ^ < ! - - # ? r e g i o n [ \s \w * - ] * - - > $ / ] ,
37- // Visual Basic
38- [ / ^ # R e g i o n ( [ \w * - ] + ) $ / , / ^ # E n d R e g i o n / ] ,
39- // Bat
40- [ / ^ : : # r e g i o n ( [ \w * - ] + ) $ / , / ^ : : # e n d r e g i o n / ] ,
41- // C#, PHP, Powershell, Python, perl & misc
42- [ / ^ # ? r e g i o n ( [ \w * - ] + ) $ / , / ^ # ? e n d r e g i o n / ] ,
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