Skip to content

Commit 300c619

Browse files
Updated llms.txt handling
1 parent 5d54eaf commit 300c619

5 files changed

Lines changed: 103 additions & 70 deletions

File tree

Docs.IndexGenerator/Config/root-config.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,10 @@
66
"repositoryUrl": "https://github.com/rabanti-github/NanoXLSX",
77
"demoRepositoryUrl": "https://github.com/rabanti-github/NanoXLSX.Demo",
88
"demoRepositoryUseCaseUrl": "https://github.com/rabanti-github/NanoXLSX.Demo/tree/main/NanoXLSX/Demo/UseCases",
9-
"llmsSummary": "A small, dependency-free .NET library to create and read Microsoft Excel (XLSX) files. Modular plugin architecture: a Core package plus optional Reader, Writer, and Formatting plugins. Targets .NET Standard 2.0 and .NET Framework 4.5+."
9+
"llmsSummary": "A small, dependency-free .NET library to create and read Microsoft Excel (XLSX) files. Modular plugin architecture: a Core package plus optional Reader, Writer, and Formatting plugins. Targets .NET Standard 2.0 and .NET Framework 4.5+.",
10+
"llmsBodyParagraph": "NanoXLSX is a meta-package bundling NanoXLSX.Core, NanoXLSX.Reader, NanoXLSX.Writer, and NanoXLSX.Formatting.",
11+
"llmsUsageSnippetLanguage": "csharp",
12+
"llmsUsageSnippet": "Workbook workbook = new Workbook(\"myWorkbook.xlsx\", \"Sheet1\");\nworkbook.CurrentWorksheet.AddNextCell(\"Some Data\");\nworkbook.CurrentWorksheet.AddNextCell(42);\nworkbook.CurrentWorksheet.GoToNextRow();\nworkbook.CurrentWorksheet.AddNextCell(DateTime.Now);\nworkbook.Save();\n\n\\\\Reading a workbook\nWorkbook workbook = WorkbookReader.Load(\"myWorkbook.xlsx\");",
13+
"wikiUrl": "https://github.com/rabanti-github/NanoXLSX/wiki/Getting-started"
1014
}
15+

Docs.IndexGenerator/Generation/LlmsTxtGenerator.cs

Lines changed: 60 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -22,95 +22,105 @@ public static string Build(RootConfig root, MetaPackageConfig meta, PluginConfig
2222
{
2323
var sb = new StringBuilder();
2424

25+
// H1 + blockquote (required by spec)
2526
sb.Append("# ").AppendLine(root.ProjectName);
2627
sb.AppendLine();
2728
sb.Append("> ").AppendLine(root.LlmsSummary);
28-
sb.AppendLine();
2929

30-
sb.AppendLine("## Packages");
30+
// Optional prose paragraph between blockquote and first H2
31+
if (!string.IsNullOrEmpty(root.LlmsBodyParagraph))
32+
{
33+
sb.AppendLine();
34+
sb.AppendLine(root.LlmsBodyParagraph);
35+
}
36+
37+
// Installation section
38+
bool hasPm = !string.IsNullOrEmpty(meta.PmInstallCommand);
39+
bool hasCli = !string.IsNullOrEmpty(meta.CliInstallCommand);
40+
if (hasPm || hasCli)
41+
{
42+
sb.AppendLine();
43+
sb.AppendLine("## Installation");
44+
sb.AppendLine();
45+
if (hasPm)
46+
sb.Append("- Install via NuGet (Package Manager): `").Append(meta.PmInstallCommand).AppendLine("`");
47+
if (hasCli)
48+
sb.Append("- Install via .NET CLI: `").Append(meta.CliInstallCommand).AppendLine("`");
49+
}
50+
51+
// Packages section — spec-compliant [name](url): description links
3152
sb.AppendLine();
32-
sb.Append("Meta package **").Append(meta.PackageName).Append(" v").Append(meta.Version)
33-
.AppendLine("** bundles all of the below.");
53+
sb.AppendLine("## Packages");
3454
sb.AppendLine();
3555

36-
string metaUrl = !string.IsNullOrEmpty(meta.NuGetUrl)
37-
? meta.NuGetUrl
38-
: root.RepositoryUrl;
56+
string metaUrl = !string.IsNullOrEmpty(meta.NuGetUrl) ? meta.NuGetUrl : root.RepositoryUrl;
3957
sb.Append("- [").Append(meta.PackageName).Append("](").Append(metaUrl).Append("): ")
4058
.AppendLine(meta.Description ?? string.Empty);
4159

42-
List<DocEntry> nonBundledEntries = new List<DocEntry>();
43-
4460
foreach (DocEntry e in plugins.Entries)
4561
{
46-
if (!e.Bundled)
47-
{
48-
nonBundledEntries.Add(e);
49-
continue;
50-
}
51-
string url = !string.IsNullOrEmpty(e.NuGetUrl)
52-
? e.NuGetUrl
53-
: (e.Repository ?? string.Empty);
62+
string url = !string.IsNullOrEmpty(e.NuGetUrl) ? e.NuGetUrl : (e.Repository ?? string.Empty);
5463
string description = e.Description ?? string.Empty;
55-
string bundledTag = e.Bundled ? " (bundled)" : string.Empty;
64+
string tag = e.Bundled ? " (bundled)" : string.Empty;
5665
sb.Append("- [").Append(e.Id).Append("](").Append(url).Append("): ")
57-
.Append(description).AppendLine(bundledTag);
66+
.Append(description).AppendLine(tag);
5867
}
5968

60-
if (nonBundledEntries.Count > 0)
69+
// Usage / quick-start section
70+
if (!string.IsNullOrEmpty(root.LlmsUsageSnippet))
6171
{
72+
string lang = root.LlmsUsageSnippetLanguage ?? "csharp";
6273
sb.AppendLine();
63-
sb.AppendLine("Other available packages (not bundled in meta package):");
74+
sb.AppendLine("## Usage");
6475
sb.AppendLine();
65-
foreach (DocEntry e in nonBundledEntries)
66-
{
67-
string url = !string.IsNullOrEmpty(e.NuGetUrl)
68-
? e.NuGetUrl
69-
: (e.Repository ?? string.Empty);
70-
string description = e.Description ?? string.Empty;
71-
sb.Append("- [").Append(e.Id).Append("](").Append(url).Append("): ")
72-
.Append(description).AppendLine();
73-
}
76+
sb.Append("```").AppendLine(lang);
77+
sb.AppendLine(root.LlmsUsageSnippet);
78+
sb.AppendLine("```");
7479
}
7580

81+
// API Documentation — spec-compliant [name](url): description links
7682
sb.AppendLine();
7783
sb.AppendLine("## API Documentation");
7884
sb.AppendLine();
79-
sb.Append("- Combined documentation portal: ").AppendLine(root.ApiDocsUrl);
80-
foreach (var e in plugins.Entries)
85+
sb.Append("- [Combined documentation portal](").Append(root.ApiDocsUrl).AppendLine("): All NanoXLSX packages");
86+
foreach (DocEntry e in plugins.Entries)
8187
{
8288
if (!string.IsNullOrEmpty(e.ApiDocsUrl))
8389
{
84-
sb.Append("- ").Append(e.Id).Append(": ").AppendLine(e.ApiDocsUrl);
90+
string note = !string.IsNullOrEmpty(e.Description) ? e.Description : e.Id + " API reference";
91+
sb.Append("- [").Append(e.Id).Append("](").Append(e.ApiDocsUrl).Append("): ").AppendLine(note);
8592
}
8693
}
8794

95+
// Source — spec-compliant [name](url): description links
8896
sb.AppendLine();
8997
sb.AppendLine("## Source");
9098
sb.AppendLine();
91-
sb.Append("- Primary repository: ").AppendLine(root.RepositoryUrl);
92-
foreach (var e in plugins.Entries)
99+
sb.Append("- [").Append(root.ProjectName).Append("](").Append(root.RepositoryUrl).AppendLine("): Primary repository (meta-package, docs)");
100+
101+
// Deduplicate external repos (multiple entries may share the same repo URL)
102+
var seenRepos = new System.Collections.Generic.HashSet<string>(StringComparer.OrdinalIgnoreCase);
103+
foreach (DocEntry e in plugins.Entries)
93104
{
94-
if (!string.IsNullOrEmpty(e.Repository) &&
95-
!string.Equals(e.Repository, root.RepositoryUrl, StringComparison.OrdinalIgnoreCase))
96-
{
97-
sb.Append("- ").Append(e.Id).Append(" (external): ").AppendLine(e.Repository);
98-
}
105+
if (string.IsNullOrEmpty(e.Repository) ||
106+
string.Equals(e.Repository, root.RepositoryUrl, StringComparison.OrdinalIgnoreCase))
107+
continue;
108+
if (!seenRepos.Add(e.Repository))
109+
continue;
110+
string repoName = !string.IsNullOrEmpty(e.RepositoryDisplayName) ? e.RepositoryDisplayName : e.Id;
111+
sb.Append("- [").Append(repoName).Append("](").Append(e.Repository).AppendLine("): Source code (external)");
99112
}
100113

114+
// Optional section (spec-defined: these entries can be skipped in short contexts)
101115
sb.AppendLine();
102-
sb.AppendLine("## Demos");
103-
sb.AppendLine();
104-
sb.Append("- Repository with running demo use cases: ").AppendLine(root.DemoRepositoryUrl);
105-
sb.Append("- Direct folder URL with use cases for ").Append(root.ProjectName).Append(": ").AppendLine(root.DemoRepositoryUseCaseUrl);
106-
107-
sb.AppendLine();
108-
sb.AppendLine("## Notes");
116+
sb.AppendLine("## Optional");
109117
sb.AppendLine();
110-
sb.AppendLine("- Docs.IndexGenerator/ is a build utility and not part of the public API.");
111-
sb.AppendLine("- This file is generated automatically on build from Docs.IndexGenerator/Config/*.json — do not edit by hand.");
118+
sb.Append("- [Demo repository](").Append(root.DemoRepositoryUrl).AppendLine("): Running demo use cases");
119+
sb.Append("- [").Append(root.ProjectName).Append(" demo use cases](").Append(root.DemoRepositoryUseCaseUrl).AppendLine("): Direct folder with NanoXLSX examples");
120+
if (!string.IsNullOrEmpty(root.WikiUrl))
121+
sb.Append("- [Getting started](").Append(root.WikiUrl).AppendLine("): Wiki / getting started guide");
112122

113123
return sb.ToString();
114124
}
115125
}
116-
}
126+
}

Docs.IndexGenerator/Models/ConfigModels.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,19 @@ internal record RootConfig(
2727
string RepositoryUrl,
2828
string DemoRepositoryUrl,
2929
string DemoRepositoryUseCaseUrl,
30-
string LlmsSummary);
30+
string LlmsSummary,
31+
string? LlmsBodyParagraph,
32+
string? LlmsUsageSnippet,
33+
string? LlmsUsageSnippetLanguage,
34+
string? WikiUrl);
3135

3236
internal record MetaPackageConfig(
3337
string PackageName,
3438
string Version,
3539
string? Description,
36-
string? NuGetUrl);
40+
string? NuGetUrl,
41+
string? PmInstallCommand,
42+
string? CliInstallCommand);
3743

3844
internal record PluginConfig(DocEntry[] Entries);
3945
}

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ There are some limitations:
7373
* Due to the potential high complexity, custom number format codes are currently not automatically escaped on writing or un-escaped on reading
7474

7575
## :robot: For AI Agents
76+
7677
For AI agents and LLM tooling, a machine-readable [`llms.txt`](./llms.txt) is available.
78+
It lists all packages, installation commands, API documentation, source repositories, and a quick-start code snippet.
7779

7880
## :gear: Requirements
7981

llms.txt

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,45 @@
22

33
> A small, dependency-free .NET library to create and read Microsoft Excel (XLSX) files. Modular plugin architecture: a Core package plus optional Reader, Writer, and Formatting plugins. Targets .NET Standard 2.0 and .NET Framework 4.5+.
44

5-
## Packages
5+
NanoXLSX is a meta-package bundling NanoXLSX.Core, NanoXLSX.Reader, NanoXLSX.Writer, and NanoXLSX.Formatting.
66

7-
Meta package **NanoXLSX v3.1.0** bundles all of the below.
7+
## Packages
88

99
- [NanoXLSX](https://www.nuget.org/packages/NanoXLSX): NanoXLSX is a library to generate and read Microsoft Excel files (XLSX) in an easy and native way. This package is the meta package of NanoXLSX and should be used in most cases as dependency in your project.
1010
- [NanoXLSX.Core](https://www.nuget.org/packages/NanoXLSX.Core): Core library: workbooks, worksheets, cells, styles, colors. Has no external dependencies. (bundled)
1111
- [NanoXLSX.Reader](https://www.nuget.org/packages/NanoXLSX.Reader): Reader plugin: extension methods to load XLSX files. Depends on Core. (bundled)
1212
- [NanoXLSX.Writer](https://www.nuget.org/packages/NanoXLSX.Writer): Writer plugin: extension methods to save XLSX files. Depends on Core. (bundled)
1313
- [NanoXLSX.Formatting](https://www.nuget.org/packages/NanoXLSX.Formatting): Formatting plugin: in-line cell formatting (rich text). Depends on Core. Maintained in an external repository. (bundled)
1414

15-
## API Documentation
15+
## Usage
1616

17-
- Combined documentation portal: https://rabanti-github.github.io/NanoXLSX/
18-
- NanoXLSX.Core: https://rabanti-github.github.io/NanoXLSX/NanoXLSX.Core/
19-
- NanoXLSX.Reader: https://rabanti-github.github.io/NanoXLSX/NanoXLSX.Reader/
20-
- NanoXLSX.Writer: https://rabanti-github.github.io/NanoXLSX/NanoXLSX.Writer/
21-
- NanoXLSX.Formatting: https://rabanti-github.github.io/NanoXLSX.Formatting/
17+
```csharp
18+
Workbook workbook = new Workbook("myWorkbook.xlsx", "Sheet1");
19+
workbook.CurrentWorksheet.AddNextCell("Some Data");
20+
workbook.CurrentWorksheet.AddNextCell(42);
21+
workbook.CurrentWorksheet.GoToNextRow();
22+
workbook.CurrentWorksheet.AddNextCell(DateTime.Now);
23+
workbook.Save();
2224

23-
## Source
25+
\\Reading a workbook
26+
Workbook workbook = WorkbookReader.Load("myWorkbook.xlsx");
27+
```
2428

25-
- Primary repository: https://github.com/rabanti-github/NanoXLSX
26-
- NanoXLSX.Formatting (external): https://github.com/rabanti-github/NanoXLSX.Formatting
29+
## API Documentation
30+
31+
- [Combined documentation portal](https://rabanti-github.github.io/NanoXLSX/): All NanoXLSX packages
32+
- [NanoXLSX.Core](https://rabanti-github.github.io/NanoXLSX/NanoXLSX.Core/): Core library: workbooks, worksheets, cells, styles, colors. Has no external dependencies.
33+
- [NanoXLSX.Reader](https://rabanti-github.github.io/NanoXLSX/NanoXLSX.Reader/): Reader plugin: extension methods to load XLSX files. Depends on Core.
34+
- [NanoXLSX.Writer](https://rabanti-github.github.io/NanoXLSX/NanoXLSX.Writer/): Writer plugin: extension methods to save XLSX files. Depends on Core.
35+
- [NanoXLSX.Formatting](https://rabanti-github.github.io/NanoXLSX.Formatting/): Formatting plugin: in-line cell formatting (rich text). Depends on Core. Maintained in an external repository.
2736

28-
## Demos
37+
## Source
2938

30-
- Repository with running demo use cases: https://github.com/rabanti-github/NanoXLSX.Demo
31-
- Direct folder URL with use cases for NanoXLSX: https://github.com/rabanti-github/NanoXLSX.Demo/tree/main/NanoXLSX/Demo/UseCases
39+
- [NanoXLSX](https://github.com/rabanti-github/NanoXLSX): Primary repository (meta-package, docs)
40+
- [NanoXLSX.Formatting](https://github.com/rabanti-github/NanoXLSX.Formatting): Source code (external)
3241

33-
## Notes
42+
## Optional
3443

35-
- Docs.IndexGenerator/ is a build utility and not part of the public API.
36-
- This file is generated automatically on build from Docs.IndexGenerator/Config/*.json — do not edit by hand.
44+
- [Demo repository](https://github.com/rabanti-github/NanoXLSX.Demo): Running demo use cases
45+
- [NanoXLSX demo use cases](https://github.com/rabanti-github/NanoXLSX.Demo/tree/main/NanoXLSX/Demo/UseCases): Direct folder with NanoXLSX examples
46+
- [Getting started](https://github.com/rabanti-github/NanoXLSX/wiki/Getting-started): Wiki / getting started guide

0 commit comments

Comments
 (0)