@@ -7,7 +7,7 @@ import type { CommentDisplayPart, Reflection } from "../../models/index.js";
77import { MinimalSourceFile } from "../../utils/minimalSourceFile.js" ;
88import type { Converter } from "../converter.js" ;
99import { isFile } from "../../utils/fs.js" ;
10- import { escapeRegExp } from "../../utils/general.js" ;
10+ import { dedent , escapeRegExp } from "../../utils/general.js" ;
1111
1212/**
1313 * Handles `@include` and `@includeCode` within comments/documents.
@@ -63,9 +63,8 @@ export class IncludePlugin extends ConverterComponent {
6363 continue ;
6464 }
6565
66- const [ filename , target , requestedLines ] = parseIncludeCodeTextPart (
67- part . text ,
68- ) ;
66+ const { filename, regionTarget, requestedLines } =
67+ parseIncludeCodeTextPart ( part . text ) ;
6968
7069 const file = path . resolve ( relative , filename ) ;
7170 if ( included . includes ( file ) && part . tag === "@include" ) {
@@ -80,30 +79,31 @@ export class IncludePlugin extends ConverterComponent {
8079 } else if ( isFile ( file ) ) {
8180 const text = fs . readFileSync ( file , "utf-8" ) ;
8281 const ext = path . extname ( file ) . substring ( 1 ) ;
82+
83+ const includedText = regionTarget
84+ ? this . getRegions (
85+ refl ,
86+ file ,
87+ ext ,
88+ part . text ,
89+ text ,
90+ regionTarget ,
91+ part . tag ,
92+ part . tag === "@includeCode" ,
93+ )
94+ : requestedLines
95+ ? this . getLines (
96+ refl ,
97+ file ,
98+ part . text ,
99+ text ,
100+ requestedLines ,
101+ part . tag ,
102+ )
103+ : text ;
104+
83105 if ( part . tag === "@include" ) {
84- const sf = new MinimalSourceFile (
85- target
86- ? this . getRegion (
87- refl ,
88- file ,
89- ext ,
90- part . text ,
91- text ,
92- target ,
93- part . tag ,
94- )
95- : requestedLines
96- ? this . getLines (
97- refl ,
98- file ,
99- part . text ,
100- text ,
101- requestedLines ,
102- part . tag ,
103- )
104- : text ,
105- file ,
106- ) ;
106+ const sf = new MinimalSourceFile ( includedText , file ) ;
107107 const { content } = this . owner . parseRawComment (
108108 sf ,
109109 refl . project . files ,
@@ -118,29 +118,7 @@ export class IncludePlugin extends ConverterComponent {
118118 } else {
119119 parts [ i ] = {
120120 kind : "code" ,
121- text : makeCodeBlock (
122- ext ,
123- target
124- ? this . getRegion (
125- refl ,
126- file ,
127- ext ,
128- part . text ,
129- text ,
130- target ,
131- part . tag ,
132- )
133- : requestedLines
134- ? this . getLines (
135- refl ,
136- file ,
137- part . text ,
138- text ,
139- requestedLines ,
140- part . tag ,
141- )
142- : text ,
143- ) ,
121+ text : makeCodeBlock ( ext , includedText ) ,
144122 } ;
145123 }
146124 } else {
@@ -156,14 +134,15 @@ export class IncludePlugin extends ConverterComponent {
156134 }
157135 }
158136
159- getRegion (
137+ getRegions (
160138 refl : Reflection ,
161139 file : string ,
162140 ext : string ,
163141 textPart : string ,
164142 text : string ,
165- target : string ,
143+ regionTargets : string ,
166144 tag : string ,
145+ ignoreIndent : boolean ,
167146 ) {
168147 const regionTagsList = regionTagREsByExt [ ext ] ;
169148 if ( ! regionTagsList ) {
@@ -177,42 +156,21 @@ export class IncludePlugin extends ConverterComponent {
177156 return "" ;
178157 }
179158
180- let found : string | false = false ;
181- for ( const [ startTag , endTag ] of regionTagsList ) {
182- const safeTarget = escapeRegExp ( target ) ;
183- const start = text . match ( startTag ( safeTarget ) ) ;
184- const end = text . match ( endTag ( safeTarget ) ) ;
159+ const targets = regionTargets . split ( "," ) . map ( ( s ) => s . trim ( ) ) ;
160+ let content = "" ;
185161
186- const foundStart = start && start . length > 0 ;
187- const foundEnd = end && end . length > 0 ;
188- if ( foundStart && ! foundEnd ) {
189- this . logger . error (
190- this . logger . i18n . include_0_tag_in_1_specified_2_file_3_region_4_region_close_not_found (
191- tag ,
192- refl . getFriendlyFullName ( ) ,
193- textPart ,
194- file ,
195- target ,
196- ) ,
197- ) ;
198- return "" ;
199- }
200- if ( ! foundStart && foundEnd ) {
201- this . logger . error (
202- this . logger . i18n . include_0_tag_in_1_specified_2_file_3_region_4_region_open_not_found (
203- tag ,
204- refl . getFriendlyFullName ( ) ,
205- textPart ,
206- file ,
207- target ,
208- ) ,
209- ) ;
210- return "" ;
211- }
212- if ( foundStart && foundEnd ) {
213- if ( start . length > 1 ) {
162+ for ( const target of targets ) {
163+ let found : string | false = false ;
164+ for ( const [ startTag , endTag ] of regionTagsList ) {
165+ const safeTarget = escapeRegExp ( target ) ;
166+ const start = text . match ( startTag ( safeTarget ) ) ;
167+ const end = text . match ( endTag ( safeTarget ) ) ;
168+
169+ const foundStart = start && start . length > 0 ;
170+ const foundEnd = end && end . length > 0 ;
171+ if ( foundStart && ! foundEnd ) {
214172 this . logger . error (
215- this . logger . i18n . include_0_tag_in_1_specified_2_file_3_region_4_region_open_found_multiple_times (
173+ this . logger . i18n . include_0_tag_in_1_specified_2_file_3_region_4_region_close_not_found (
216174 tag ,
217175 refl . getFriendlyFullName ( ) ,
218176 textPart ,
@@ -222,9 +180,9 @@ export class IncludePlugin extends ConverterComponent {
222180 ) ;
223181 return "" ;
224182 }
225- if ( end . length > 1 ) {
183+ if ( ! foundStart && foundEnd ) {
226184 this . logger . error (
227- this . logger . i18n . include_0_tag_in_1_specified_2_file_3_region_4_region_close_found_multiple_times (
185+ this . logger . i18n . include_0_tag_in_1_specified_2_file_3_region_4_region_open_not_found (
228186 tag ,
229187 refl . getFriendlyFullName ( ) ,
230188 textPart ,
@@ -234,48 +192,77 @@ export class IncludePlugin extends ConverterComponent {
234192 ) ;
235193 return "" ;
236194 }
237- if ( found ) {
238- this . logger . error (
239- this . logger . i18n . include_0_tag_in_1_specified_2_file_3_region_4_region_found_multiple_times (
240- tag ,
241- refl . getFriendlyFullName ( ) ,
242- textPart ,
243- file ,
244- target ,
245- ) ,
195+ if ( foundStart && foundEnd ) {
196+ if ( start . length > 1 ) {
197+ this . logger . error (
198+ this . logger . i18n . include_0_tag_in_1_specified_2_file_3_region_4_region_open_found_multiple_times (
199+ tag ,
200+ refl . getFriendlyFullName ( ) ,
201+ textPart ,
202+ file ,
203+ target ,
204+ ) ,
205+ ) ;
206+ return "" ;
207+ }
208+ if ( end . length > 1 ) {
209+ this . logger . error (
210+ this . logger . i18n . include_0_tag_in_1_specified_2_file_3_region_4_region_close_found_multiple_times (
211+ tag ,
212+ refl . getFriendlyFullName ( ) ,
213+ textPart ,
214+ file ,
215+ target ,
216+ ) ,
217+ ) ;
218+ return "" ;
219+ }
220+ if ( found ) {
221+ this . logger . error (
222+ this . logger . i18n . include_0_tag_in_1_specified_2_file_3_region_4_region_found_multiple_times (
223+ tag ,
224+ refl . getFriendlyFullName ( ) ,
225+ textPart ,
226+ file ,
227+ target ,
228+ ) ,
229+ ) ;
230+ return "" ;
231+ }
232+ found = text . substring (
233+ text . indexOf ( start [ 0 ] ) + start [ 0 ] . length ,
234+ text . indexOf ( end [ 0 ] ) ,
246235 ) ;
247- return "" ;
248236 }
249- found = text . substring (
250- text . indexOf ( start [ 0 ] ) + start [ 0 ] . length ,
251- text . indexOf ( end [ 0 ] ) ,
237+ }
238+ if ( found === false ) {
239+ this . logger . error (
240+ this . logger . i18n . include_0_tag_in_1_specified_2_file_3_region_4_region_not_found (
241+ tag ,
242+ refl . getFriendlyFullName ( ) ,
243+ textPart ,
244+ file ,
245+ target ,
246+ ) ,
252247 ) ;
248+ return "" ;
253249 }
250+ if ( found . trim ( ) === "" ) {
251+ this . logger . warn (
252+ this . logger . i18n . include_0_tag_in_1_specified_2_file_3_region_4_region_empty (
253+ tag ,
254+ refl . getFriendlyFullName ( ) ,
255+ textPart ,
256+ file ,
257+ target ,
258+ ) ,
259+ ) ;
260+ }
261+
262+ content += ignoreIndent ? dedent ( found ) + "\n" : found ;
254263 }
255- if ( found === false ) {
256- this . logger . error (
257- this . logger . i18n . include_0_tag_in_1_specified_2_file_3_region_4_region_not_found (
258- tag ,
259- refl . getFriendlyFullName ( ) ,
260- textPart ,
261- file ,
262- target ,
263- ) ,
264- ) ;
265- return "" ;
266- }
267- if ( found . trim ( ) === "" ) {
268- this . logger . warn (
269- this . logger . i18n . include_0_tag_in_1_specified_2_file_3_region_4_region_empty (
270- tag ,
271- refl . getFriendlyFullName ( ) ,
272- textPart ,
273- file ,
274- target ,
275- ) ,
276- ) ;
277- }
278- return found ;
264+
265+ return content ;
279266 }
280267
281268 getLines (
@@ -345,22 +332,24 @@ function makeCodeBlock(lang: string, code: string) {
345332 return "\n\n```" + lang + "\n" + escaped . trimEnd ( ) + "\n```" ;
346333}
347334
348- function parseIncludeCodeTextPart (
349- text : string ,
350- ) : [ string , string | undefined , string | undefined ] {
335+ function parseIncludeCodeTextPart ( text : string ) : {
336+ filename : string ;
337+ regionTarget : string | undefined ;
338+ requestedLines : string | undefined ;
339+ } {
351340 let filename = text . trim ( ) ;
352- let target ;
353- let requestedLines ;
341+ let regionTarget : string | undefined ;
342+ let requestedLines : string | undefined ;
354343 if ( filename . includes ( "#" ) ) {
355344 const parsed = filename . split ( "#" ) ;
356345 filename = parsed [ 0 ] ;
357- target = parsed [ 1 ] ;
346+ regionTarget = parsed [ 1 ] ;
358347 } else if ( filename . includes ( ":" ) ) {
359348 const parsed = filename . split ( ":" ) ;
360349 filename = parsed [ 0 ] ;
361350 requestedLines = parsed [ 1 ] ;
362351 }
363- return [ filename , target , requestedLines ] ;
352+ return { filename, regionTarget , requestedLines } ;
364353}
365354
366355type RegionTagRETuple = [
0 commit comments