44
55using System . Buffers ;
66using System . IO . Abstractions ;
7+ using System . IO . Compression ;
78using System . Text ;
89using Elastic . Documentation . Configuration ;
910using Elastic . Markdown . Helpers ;
1011using Elastic . Markdown . Myst ;
1112using Elastic . Markdown . Myst . FrontMatter ;
12- using Markdig . Syntax ;
1313
1414namespace Elastic . Markdown . Exporters ;
1515
@@ -19,26 +19,53 @@ public class LLMTextExporter : IMarkdownExporter
1919
2020 public ValueTask StopAsync ( Cancel ctx = default ) => ValueTask . CompletedTask ;
2121
22- public async ValueTask < bool > ExportAsync ( MarkdownExportContext context , Cancel ctx )
22+ public async ValueTask < bool > ExportAsync ( MarkdownExportFileContext fileContext , Cancel ctx )
2323 {
24- var source = context . SourceFile . SourceFile ;
24+ var source = fileContext . SourceFile . SourceFile ;
2525 var fs = source . FileSystem ;
26- var llmText = context . LLMText ??= ToLLMText ( context . BuildContext , context . SourceFile . YamlFrontMatter , context . Resolvers , source ) ;
26+ var llmText = fileContext . LLMText ??= ToLLMText ( fileContext . BuildContext , fileContext . SourceFile . YamlFrontMatter , fileContext . Resolvers , source ) ;
2727
2828 // write to the output version of the Markdown file directly
29- var outputFile = context . DefaultOutputFile ;
29+ var outputFile = fileContext . DefaultOutputFile ;
3030 if ( outputFile . Name == "index.md" )
3131 {
32+ var root = fileContext . BuildContext . DocumentationOutputDirectory ;
3233 // Write to a file named after the parent folder
33- outputFile = fs . FileInfo . New ( outputFile . Directory ! . FullName + ".md" ) ;
34+ if ( outputFile . Directory ! . FullName == root . FullName )
35+ {
36+ // TODO in FinishExportAsync find a way to generate llms.txt
37+ // e.g should it embedd all the links?
38+ outputFile = fs . FileInfo . New ( Path . Combine ( root . FullName , "llms.md" ) ) ;
39+ }
40+ else
41+ outputFile = fs . FileInfo . New ( outputFile . Directory ! . FullName + ".md" ) ;
3442 }
43+
3544 if ( outputFile . Directory is { Exists : false } )
3645 outputFile . Directory . Create ( ) ;
3746
3847 await fs . File . WriteAllTextAsync ( outputFile . FullName , llmText , ctx ) ;
3948 return true ;
4049 }
4150
51+ /// <inheritdoc />
52+ public ValueTask < bool > FinishExportAsync ( IDirectoryInfo outputFolder , Cancel ctx )
53+ {
54+ var outputDirectory = Path . Combine ( outputFolder . FullName , "docs" ) ;
55+ var zipPath = Path . Combine ( outputDirectory , "llm.zip" ) ;
56+ using ( var zip = ZipFile . Open ( zipPath , ZipArchiveMode . Create ) )
57+ {
58+ var markdownFiles = Directory . GetFiles ( outputDirectory , "*.md" , SearchOption . AllDirectories ) ;
59+
60+ foreach ( var file in markdownFiles )
61+ {
62+ var relativePath = Path . GetRelativePath ( outputDirectory , file ) ;
63+ _ = zip . CreateEntryFromFile ( file , relativePath ) ;
64+ }
65+ }
66+ return ValueTask . FromResult ( true ) ;
67+ }
68+
4269 public static string ToLLMText ( BuildContext buildContext , YamlFrontMatter ? frontMatter , IParserResolvers resolvers , IFileInfo source )
4370 {
4471 var fs = source . FileSystem ;
@@ -56,7 +83,6 @@ public static string ToLLMText(BuildContext buildContext, YamlFrontMatter? front
5683 DocumentationObjectPoolProvider . StringBuilderPool . Return ( sb ) ;
5784 var replaced = full . ReplaceSubstitutions ( new ParserContext ( state ) ) ;
5885 return replaced ;
59-
6086 }
6187
6288 private static void Read ( IFileInfo source , IFileSystem fs , StringBuilder sb , IDirectoryInfo setDirectory )
@@ -83,6 +109,7 @@ private static void Read(IFileInfo source, IFileSystem fs, StringBuilder sb, IDi
83109 includePath = Path . Combine ( setDirectory . FullName , relativeFile . TrimStart ( '/' ) . ToString ( ) ) ;
84110 includeSource = fs . FileInfo . New ( includePath ) ;
85111 }
112+
86113 if ( includeSource . Extension == "md" && includePath . Contains ( "_snippets" ) )
87114 Read ( includeSource , fs , sb , setDirectory ) ;
88115 startIndex = cursor + relativeFileEnd ;
@@ -94,7 +121,7 @@ private static void Read(IFileInfo source, IFileSystem fs, StringBuilder sb, IDi
94121 startIndex = Math . Min ( text . Length , startIndex ) ;
95122 }
96123 }
124+
97125 _ = sb . Append ( text [ startIndex ..] ) ;
98126 }
99127}
100-
0 commit comments