diff --git a/src/NaiveStaticGenerator/NaiveStaticGenerator.csproj b/src/NaiveStaticGenerator/NaiveStaticGenerator.csproj index abf1a0d21..6765a8fef 100644 --- a/src/NaiveStaticGenerator/NaiveStaticGenerator.csproj +++ b/src/NaiveStaticGenerator/NaiveStaticGenerator.csproj @@ -6,6 +6,10 @@ preview + + + + diff --git a/src/NaiveStaticGenerator/Program.cs b/src/NaiveStaticGenerator/Program.cs index 33704e76f..e5391e624 100644 --- a/src/NaiveStaticGenerator/Program.cs +++ b/src/NaiveStaticGenerator/Program.cs @@ -1,4 +1,10 @@ -using NaiveStaticGenerator; +using Markdig; +using Markdig.Renderers; +using Markdig.Renderers.Html; +using Markdig.Renderers.Html.Inlines; +using Markdig.Syntax; +using Markdig.Syntax.Inlines; +using NaiveStaticGenerator; using System.Text; using YadgNet; @@ -89,33 +95,34 @@ void GenerateWikiToPages() static string MdToHtml(string md, string title) { - // + // The wiki is written for GitHub, so it is read as GitHub reads it: markdown, with the HTML in it passed through + var pipeline = new MarkdownPipelineBuilder().UsePipeTables().UseEmphasisExtras().UseAutoLinks().UseTaskLists().Build(); + var document = Markdown.Parse(md.Replace("\r", ""), pipeline); + + // A link to another page of the wiki names the page, as `[Expressions](Expressions)` does, and the page is Expressions.html here + foreach (var link in document.Descendants()) + if (!link.IsImage && link.Url is { } url && IsWikiPage(url)) + link.Url = url.IndexOf('#') is var hash and >= 0 ? url[..hash] + ".html" + url[hash..] : url + ".html"; + + // The site's highlight.js guesses each block's language, and it has no F#: a block marked as F# would not be highlighted at all + foreach (var block in document.Descendants()) + block.GetAttributes().Classes?.Clear(); + + var html = new StringWriter(); + var renderer = new HtmlRenderer(html); + pipeline.Setup(renderer); + renderer.ObjectRenderers.Replace(new CodeInlineAsCw()); + renderer.Render(document); + var sb = new StringBuilder(); sb.Append($"

{title}


"); sb.Append("

← Back to the main page

"); - sb.Append($"{md}"); - sb.Replace("\r", ""); - // sb.Replace("\n\n", "

"); + sb.Append(html); sb.Replace("", "", - Wrap("```", "```", "
", "
", - Wrap("```cs", "```", "
", "
", - Wrap("```fs", "```", "
", "
", - sb.ToString() - ) - ) - ) - ); + return sb.ToString(); - static string Wrap(string before, string after, string newBefore, string newAfter, string src) - { - var unjailed = DescriptionFromXmlBuilder.Unjail(before, after, src); - if (unjailed is not { } notNull) - return src; - var (inside, first, last) = notNull; - return src[..first] + newBefore + inside.Trim() + newAfter + Wrap(before, after, newBefore, newAfter, src[last..]); - } + static bool IsWikiPage(string url) + => !url.Contains(':') && !url.StartsWith('/') && !url.StartsWith('#') && !Path.HasExtension(url.Split('#')[0]); } } @@ -378,6 +385,17 @@ public void Save(string path, string text) } } +// Inline code in the wiki's pages, in the site's own style for it +public sealed class CodeInlineAsCw : HtmlObjectRenderer +{ + protected override void Write(HtmlRenderer renderer, CodeInline code) + { + renderer.Write(""); + renderer.WriteEscape(code.ContentSpan); + renderer.Write(""); + } +} + public static class Extensions { public static string _(this string a, string b) => Path.Combine(a, b);