@@ -311,9 +311,18 @@ bool FilesToSnippets(
311
311
return true ;
312
312
}
313
313
314
+ string ? lineExpression = null ;
315
+
316
+ if ( key . Contains ( '#' ) )
317
+ {
318
+ var splitByHash = key . Split ( '#' , StringSplitOptions . None ) ;
319
+ key = splitByHash [ 0 ] ;
320
+ lineExpression = splitByHash [ 1 ] ;
321
+ }
322
+
314
323
if ( RelativeFile . Find ( allFiles , targetDirectory , key , relativePath , linePath , out var path ) )
315
324
{
316
- snippetsForKey = SnippetsForFile ( key , path ) ;
325
+ snippetsForKey = SnippetsForFile ( key , path , lineExpression ) ;
317
326
return true ;
318
327
}
319
328
@@ -322,8 +331,7 @@ bool FilesToSnippets(
322
331
}
323
332
324
333
325
- List < Snippet > SnippetsForFile ( string key , string relativeToRoot ) =>
326
- [ FileToSnippet ( key , relativeToRoot , null ) ] ;
334
+ List < Snippet > SnippetsForFile ( string key , string relativeToRoot , string ? lines = null ) => [ FileToSnippet ( key , relativeToRoot , null , lines ) ] ;
327
335
328
336
bool GetForHttp ( string key , out IReadOnlyList < Snippet > snippetsForKey )
329
337
{
@@ -338,22 +346,77 @@ bool GetForHttp(string key, out IReadOnlyList<Snippet> snippetsForKey)
338
346
return true ;
339
347
}
340
348
341
- Snippet FileToSnippet ( string key , string file , string ? path )
349
+ Snippet FileToSnippet ( string key , string file , string ? path , string ? linesExpression = null )
350
+ {
351
+ var language = Path . GetExtension ( file ) [ 1 ..] ;
352
+
353
+ if ( linesExpression == null )
354
+ {
355
+ var ( text , endLine ) = ReadNonStartEndLines ( file ) ;
356
+ return Snippet . Build ( startLine : 0 , endLine : endLine , value : text , key : key , language : language , path : path ) ;
357
+ }
358
+
359
+ if ( linesExpression [ 0 ] == 'L' )
360
+ {
361
+ return ParseSpecificLines ( key , file , path , linesExpression , language ) ;
362
+ }
363
+
364
+ if ( linesExpression [ 0 ] == 'M' && language == "cs" )
365
+ {
366
+ return ParseCSharpMethod ( key , file , path , linesExpression , language ) ;
367
+ }
368
+
369
+ throw new SnippetException ( $ "Unable to parse expression '{ linesExpression } '") ;
370
+ }
371
+
372
+ static Snippet ParseCSharpMethod ( string key , string file , string ? path , string linesExpression , string language )
342
373
{
343
- var ( text , lineCount ) = ReadNonStartEndLines ( file ) ;
374
+ var methodName = linesExpression [ 2 ..] ;
375
+
376
+ var code = File . ReadAllText ( file ) ;
377
+ var tree = CSharpSyntaxTree . ParseText ( code ) ;
378
+ var root = tree . GetCompilationUnitRoot ( ) ;
379
+
380
+ var method = root . DescendantNodes ( )
381
+ . OfType < MethodDeclarationSyntax > ( )
382
+ . FirstOrDefault ( m => m . Identifier . Text == methodName ) ;
383
+
384
+ if ( method != null )
385
+ {
386
+ var text = method . ToFullString ( ) ;
387
+ var startLine = method . Span . Start ;
388
+ var endLine = method . Span . End ;
389
+
390
+ return Snippet . Build ( startLine : startLine , endLine : endLine , value : text , key : key , language : language , path : path ) ;
391
+ }
392
+
393
+ throw new SnippetException (
394
+ $ """
395
+ Failed to find method { methodName } in file { file } configuration.
396
+ Content:
397
+ { code }
398
+ """ ) ;
399
+ }
400
+
401
+ static Snippet ParseSpecificLines ( string key , string file , string ? path , string linesExpression , string language )
402
+ {
403
+ var text = string . Empty ;
404
+
405
+ var expressionSplit = linesExpression . Split ( '-' ) ;
406
+ var startLine = int . Parse ( expressionSplit [ 0 ] [ 1 ..] ) ;
407
+ var endLine = int . Parse ( expressionSplit [ 1 ] ) ;
408
+
409
+ var fileLines = File . ReadAllLines ( file ) ;
410
+
411
+ var selectedText = new StringBuilder ( ) ;
344
412
345
- if ( lineCount == 0 )
413
+ for ( var index = startLine ; index < endLine ; index ++ )
346
414
{
347
- lineCount ++ ;
415
+ selectedText . AppendLine ( fileLines [ index ] ) ;
416
+ text = selectedText . ToString ( ) ;
348
417
}
349
418
350
- return Snippet . Build (
351
- startLine : 1 ,
352
- endLine : lineCount ,
353
- value : text ,
354
- key : key ,
355
- language : Path . GetExtension ( file ) [ 1 ..] ,
356
- path : path ) ;
419
+ return Snippet . Build ( startLine : 1 , endLine : endLine , value : text , key : key , language : language , path : path ) ;
357
420
}
358
421
359
422
( string text , int lineCount ) ReadNonStartEndLines ( string file )
0 commit comments