Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Spectre.Docs/Components/Layouts/MainLayout.razor
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@
<!-- Main Content -->
<main data-spa-region="content" data-spa-loading="skeleton" class="flex-1 min-w-0 lg:py-8 ">
<div class="bg-white dark:bg-base-900 lg:rounded-lg lg:shadow-sm lg:border lg:border-base-200 lg:dark:border-base-800">
<div class="p-6 lg:p-8">
<article class="p-6 lg:p-8">
@Body
</div>
</article>
</div>
</main>
</div>
Expand Down
4 changes: 4 additions & 0 deletions Spectre.Docs/Components/Pages/Blog.razor.metadata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Metadata sidecar for the Razor landing page at "/blog/" so it projects a content record
# and gets a social card + og:image / description meta tags.
title: Blog
description: "News, updates, and insights from the Spectre.Console team."
4 changes: 4 additions & 0 deletions Spectre.Docs/Components/Pages/CliIndex.razor.metadata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Metadata sidecar for the Razor landing page at "/cli/" so it projects a content record
# and gets a social card + og:image / description meta tags.
title: Spectre.Console.Cli Documentation
description: "Build powerful command-line applications with Spectre.Console.Cli - type-safe argument parsing, nested commands, and dependency injection for .NET"
4 changes: 4 additions & 0 deletions Spectre.Docs/Components/Pages/ConsoleIndex.razor.metadata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Metadata sidecar for the Razor landing page at "/console/" so it projects a content record
# and gets a social card + og:image / description meta tags.
title: Spectre.Console Documentation
description: "Create beautiful, cross-platform console applications with Spectre.Console - tables, progress bars, charts, and rich text formatting for .NET"
4 changes: 4 additions & 0 deletions Spectre.Docs/Components/Pages/Home.razor.metadata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Metadata sidecar for the Razor landing page at "/". Makes the home page project a content
# record so it gets a social card (/social-cards/index.png) and the og:image / description meta tags.
title: Spectre.Console
description: "Beautiful, cross-platform console applications for .NET - tables, charts, prompts, and live displays."
44 changes: 38 additions & 6 deletions Spectre.Docs/Program.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
using System.Reflection;
using Ashcroft;
using Mdazor;
using Pennington.ApiMetadata.Reflection;
using Pennington.Infrastructure;
using Pennington.LlmsTxt;
using Pennington.MonorailCss;
using Pennington.SocialCards;
using Pennington.TreeSitter;
using Pennington.UI.Components;
using Spectre.Console;
using Spectre.Docs.Components;
using Spectre.Docs.Components.Reference;
using Spectre.Docs.Components.Shared;
using Spectre.Docs.Services;
using Spectre.Docs.SocialCardAssets;
using ColorName = Pennington.MonorailCss.ColorName;
using IContentService = Pennington.Content.IContentService;
using IContentRenderer = Pennington.Pipeline.IContentRenderer;

var builder = WebApplication.CreateBuilder(args);

// The documented subject's version for the /llms.txt front door. Resolved from the referenced
// Spectre.Console assembly so it tracks package bumps; the +<sha> SourceLink suffix is stripped.
var spectreVersion = typeof(AnsiConsole).Assembly
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?
.InformationalVersion?.Split('+', 2)[0];

builder.Services.AddRazorComponents();

// Typed views over the Pennington content pipeline that preserve the ergonomics the Razor
Expand Down Expand Up @@ -43,7 +54,23 @@
{
penn.SiteTitle = "Spectre.Console Documentation";
penn.SiteDescription = "Beautiful console applications with Spectre.Console";
penn.SiteVersion = spectreVersion; // → llms.txt `version:` (replaces penningtonVersion:)
penn.CanonicalBaseUrl = "https://spectreconsole.net";
penn.ContentRootPath = "Content";
penn.SiteProjection.ContentSelector = "article";

// OpenGraph / Twitter social cards. Pennington discovers one card per page, auto-maps the
// /social-cards/{**slug}.png route (via UsePennington), and emits the og:image / twitter:image
// meta tags; Ashcroft does the drawing — the branded PNG as the background with the page
// title set in JetBrains Mono, anchored bottom-left clear of the watermark on the right.
penn.SocialCards = new SocialCardOptions
{
Render = (request, sp, _) =>
{
var environment = sp.GetRequiredService<IWebHostEnvironment>();
return SocialCardGenerator.Build(request, environment);
},
};

penn.AddMarkdownContent<SpectreConsoleFrontMatter>(md =>
{
Expand All @@ -64,6 +91,8 @@
md.ContentPath = "Content/blog";
md.BasePageUrl = "/blog";
});

penn.AddLlmsTxt();
});

// Reflection-backed API metadata providers, one keyed registration per reference area.
Expand All @@ -80,6 +109,13 @@
builder.Services.AddApiMetadataFromCompiledAssembly("cli", opts =>
opts.FromPackageReference("Spectre.Console.Cli"));

builder.Services.AddLlmsSubtree(new LlmsSubtree(
"/cli/reference/api/", "CLI reference",
"Spectre.Console.Cli — command, configuration, and settings types."));
builder.Services.AddLlmsSubtree(new LlmsSubtree(
"/console/reference/api/", "Console reference",
"Spectre.Console — widgets, prompts, rendering, and markup types."));

builder.Services.AddScoped<ApiReferenceService>();

// Supplies API route discovery (so the static build emits the pages) and the sidebar
Expand Down Expand Up @@ -114,11 +150,7 @@
PrimaryColorName = ColorName.Sky,
AccentColorName = ColorName.Amber,
BaseColorName = ColorName.Neutral,
AdditionalMappings =
{
["tertiary-one"] = ColorName.Emerald,
["tertiary-two"] = ColorName.Violet,
},
AdditionalMappings = { ["tertiary-one"] = ColorName.Emerald, ["tertiary-two"] = ColorName.Violet, },
},
});

Expand All @@ -130,4 +162,4 @@
app.UsePennington();
app.UseMonorailCss();

await app.RunOrBuildAsync(args);
await app.RunOrBuildAsync(args);
8 changes: 5 additions & 3 deletions Spectre.Docs/Services/ApiReferenceContentService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ public async Task<ImmutableList<ContentTocItem>> GetIndexableEntriesAsync()
// The default would index only the nav entries (the two index pages), so a type that
// appears nowhere else — e.g. IAnsiConsole — is unreachable via search, and types that do
// appear only match the big index listing rather than their own page. Add one searchable
// entry per type so each type page surfaces directly. Kept out of nav (SearchOnly) and out
// of llms.txt (ExcludeFromLlms) to avoid bloating either with the full type list.
// entry per type so each type page surfaces directly. Kept out of nav (SearchOnly); they
// still feed llms.txt, where the per-area `/{area}/reference/api/` subtree (declared via
// AddLlmsSubtree in Program.cs) splits them into a dedicated {prefix}llms.txt rather than
// bloating the front door.
var builder = ImmutableList.CreateBuilder<ContentTocItem>();
builder.AddRange(await GetContentTocEntriesAsync());

Expand All @@ -82,7 +84,7 @@ public async Task<ImmutableList<ContentTocItem>> GetIndexableEntriesAsync()
int.MaxValue,
[area, "reference", "api"],
area,
null) { Description = type.Summary, SearchOnly = true, ExcludeFromLlms = true });
null) { Description = type.Summary, SearchOnly = true });
}
}
return builder.ToImmutable();
Expand Down
Binary file not shown.
44 changes: 44 additions & 0 deletions Spectre.Docs/SocialCardAssets/SocialCardGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Ashcroft;
using Pennington.SocialCards;

namespace Spectre.Docs.SocialCardAssets;

public static class SocialCardGenerator
{
// Social-card assets live in the project's SocialCardAssets folder. Resolved against the
// content root, so the paths are correct under both `dotnet run` and `dotnet run -- build`
// (the static-build crawler fetches /social-cards/*.png from the in-memory host).
public static Task<byte[]?> Build(SocialCardRequest socialCardRequest, IWebHostEnvironment environment)
{
var socialCardAssetsPath = Path.Combine(environment.ContentRootPath, "SocialCardAssets");
var cardBackgroundPath = Path.Combine(socialCardAssetsPath, "spectre-og-card.png");
var cardFontPath = Path.Combine(socialCardAssetsPath, "JetBrainsMono[wght].ttf");

var card = SocialCard.Create(socialCardRequest.Width, socialCardRequest.Height)
.Background(cardBackgroundPath)
.Theme(new Theme { FontPath = cardFontPath })
.At(Anchor.BottomLeft, stack =>
{
stack.MaxWidth(960);

stack.Text(socialCardRequest.Title, new TextStyle { Size = 72, Weight = 800, MaxLines = 2, ShrinkToFit = true });
if (!string.IsNullOrWhiteSpace(socialCardRequest.Description))
{
stack.Text(socialCardRequest.Description,
new TextStyle
{
MaxLines = 2,
ShrinkToFit = true,
Size = 30,
Weight = 200,
LetterSpacing = -0.5f
});
}

stack.Spacer(8);
stack.Meta(socialCardRequest.SiteTitle, color: "#38bdf8");
});

return Task.FromResult<byte[]?>(card.ToBytes());
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 17 additions & 8 deletions Spectre.Docs/Spectre.Docs.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,24 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Pennington" Version="0.1.1" />
<PackageReference Include="Pennington.ApiMetadata.Reflection" Version="0.1.1" />
<PackageReference Include="Pennington.MonorailCss" Version="0.1.1" />
<PackageReference Include="Pennington.UI" Version="0.1.1" />
<PackageReference Include="Pennington.TreeSitter" Version="0.1.1" />
<PackageReference Include="Ashcroft" Version="0.5.1" />
<!-- Ashcroft renders social cards with SkiaSharp/HarfBuzz. The base packages ship no Linux
native binaries, so these are required for the static build on the ubuntu-latest GitHub
Pages runner. Inert on Windows/macOS (native assets only apply to the linux RID). The
NoDependencies SkiaSharp variant avoids libfontconfig: Ashcroft bundles its own fonts.
These must stay in lockstep with the managed SkiaSharp/HarfBuzzSharp that Ashcroft pulls
in — SkiaSharp asserts the native version at startup and throws if it drifts. -->
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="4.150.0" />
<PackageReference Include="HarfBuzzSharp.NativeAssets.Linux" Version="14.2.1" />
<PackageReference Include="Pennington" Version="0.1.8" />
<PackageReference Include="Pennington.ApiMetadata.Reflection" Version="0.1.8" />
<PackageReference Include="Pennington.MonorailCss" Version="0.1.8" />
<PackageReference Include="Pennington.UI" Version="0.1.8" />
<PackageReference Include="Pennington.TreeSitter" Version="0.1.8" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" />
<PackageReference Include="Spectre.Console" Version="0.57.0" />
<PackageReference Include="Spectre.Console" Version="0.57.2" />
<PackageReference Include="Spectre.Console.Cli" Version="1.0.0-alpha.0.11" />
<PackageReference Include="Spectre.Console.ImageSharp" Version="0.57.0" />
<PackageReference Include="Spectre.Console.Json" Version="0.57.0" />
<PackageReference Include="Spectre.Console.ImageSharp" Version="0.57.2" />
<PackageReference Include="Spectre.Console.Json" Version="0.57.2" />
</ItemGroup>
</Project>
Loading