diff --git a/YaeBlog/Components/BlogInformationCard.razor b/YaeBlog/Components/BlogInformationCard.razor index 72de03a..11f8a88 100644 --- a/YaeBlog/Components/BlogInformationCard.razor +++ b/YaeBlog/Components/BlogInformationCard.razor @@ -18,9 +18,11 @@ 文章 -
- @(Contents.Count) -
+ +
+ @(Contents.Count) +
+
@@ -28,9 +30,11 @@ 标签
-
- @(Contents.Tags.Count) -
+ +
+ @(Contents.Tags.Count) +
+
diff --git a/YaeBlog/Components/LicenseDisclaimer.razor b/YaeBlog/Components/LicenseDisclaimer.razor index a95ca67..ab77a81 100644 --- a/YaeBlog/Components/LicenseDisclaimer.razor +++ b/YaeBlog/Components/LicenseDisclaimer.razor @@ -9,8 +9,8 @@
文章地址: - - @($"https://rrricardo.top/blog/essays/{EssayAddress}") + + @($"https://rrricardo.top/blog/essays/{EssayFilename}")
@@ -19,15 +19,15 @@ CC BY-NC-SA 4.0 - 许可协议,转载请注明来自 + 许可协议,诸位读者如有兴趣可任意转载,不必征询许可,但请注明“转载自 Ricardo's Blog - 。 + ”。
@code { - [Parameter] public string? EssayAddress { get; set; } + [Parameter] public string? EssayFilename { get; set; } } diff --git a/YaeBlog/Extensions/WebApplicationBuilderExtensions.cs b/YaeBlog/Extensions/WebApplicationBuilderExtensions.cs index 6add932..078c89a 100644 --- a/YaeBlog/Extensions/WebApplicationBuilderExtensions.cs +++ b/YaeBlog/Extensions/WebApplicationBuilderExtensions.cs @@ -22,9 +22,8 @@ public static class WebApplicationBuilderExtensions builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddTransient(); - builder.Services.AddTransient(); - builder.Services.AddTransient(); builder.Services.AddTransient(); + builder.Services.AddTransient(); builder.Services.AddTransient(provider => provider.GetRequiredService>().Value); diff --git a/YaeBlog/Extensions/WebApplicationExtensions.cs b/YaeBlog/Extensions/WebApplicationExtensions.cs index 5ebb045..21757ea 100644 --- a/YaeBlog/Extensions/WebApplicationExtensions.cs +++ b/YaeBlog/Extensions/WebApplicationExtensions.cs @@ -9,9 +9,8 @@ public static class WebApplicationExtensions public static void UseYaeBlog(this WebApplication application) { application.UsePostRenderProcessor(); - application.UsePostRenderProcessor(); - application.UsePostRenderProcessor(); application.UsePostRenderProcessor(); + application.UsePostRenderProcessor(); } private static void UsePreRenderProcessor(this WebApplication application) where T : IPreRenderProcessor diff --git a/YaeBlog/Pages/Essays.razor b/YaeBlog/Pages/Essays.razor index e423c1d..d1d1b74 100644 --- a/YaeBlog/Pages/Essays.razor +++ b/YaeBlog/Pages/Essays.razor @@ -41,10 +41,14 @@
-
- @((MarkupString)_essay!.HtmlContent) +
+
+ @((MarkupString)_essay!.HtmlContent) +
- +
+ +
diff --git a/YaeBlog/Pages/Tags.razor b/YaeBlog/Pages/Tags.razor index 9135d12..7a7a826 100644 --- a/YaeBlog/Pages/Tags.razor +++ b/YaeBlog/Pages/Tags.razor @@ -38,7 +38,7 @@
  • -
    +
    # @(pair.Key.TagName)
    diff --git a/YaeBlog/Processors/CodeBlockPostRenderProcessor.cs b/YaeBlog/Processors/CodeBlockPostRenderProcessor.cs deleted file mode 100644 index 3721db5..0000000 --- a/YaeBlog/Processors/CodeBlockPostRenderProcessor.cs +++ /dev/null @@ -1,29 +0,0 @@ -using AngleSharp; -using AngleSharp.Dom; -using YaeBlog.Abstraction; -using YaeBlog.Models; - -namespace YaeBlog.Processors; - -public class CodeBlockPostRenderProcessor : IPostRenderProcessor -{ - public async Task ProcessAsync(BlogEssay essay) - { - BrowsingContext context = new(Configuration.Default); - IDocument document = await context.OpenAsync( - req => req.Content(essay.HtmlContent)); - - IEnumerable preElements = from e in document.All - where e.LocalName == "pre" - select e; - - foreach (IElement element in preElements) - { - element.ClassList.Add("p-3 text-bg-secondary rounded-1"); - } - - return essay.WithNewHtmlContent(document.DocumentElement.OuterHtml); - } - - public string Name => nameof(CodeBlockPostRenderProcessor); -} diff --git a/YaeBlog/Processors/EssayStylesPostRenderProcessor.cs b/YaeBlog/Processors/EssayStylesPostRenderProcessor.cs new file mode 100644 index 0000000..8329d18 --- /dev/null +++ b/YaeBlog/Processors/EssayStylesPostRenderProcessor.cs @@ -0,0 +1,102 @@ +using AngleSharp; +using AngleSharp.Dom; +using YaeBlog.Abstraction; +using YaeBlog.Models; + +namespace YaeBlog.Processors; + +/// +/// 向渲染的HTML中插入Tailwind CSS的渲染后处理器 +/// +public sealed class EssayStylesPostRenderProcessor : IPostRenderProcessor +{ + public string Name => nameof(EssayStylesPostRenderProcessor); + + public async Task ProcessAsync(BlogEssay essay) + { + BrowsingContext context = new(Configuration.Default); + IDocument document = await context.OpenAsync( + req => req.Content(essay.HtmlContent)); + + ApplyGlobalCssStyles(document); + BeatifyTable(document); + + return essay.WithNewHtmlContent(document.DocumentElement.OuterHtml); + } + + private readonly Dictionary _globalCssStyles = new() + { + { "pre", "p-4 bg-slate-300 rounded-sm overflow-x-auto" }, + { "h2", "text-3xl font-bold py-4" }, + { "h3", "text-2xl font-bold py-3" }, + { "h4", "text-xl font-bold py-2" }, + { "h5", "text-lg font-bold py-1" }, + { "p", "p-2" }, + { "img", "w-11/12 block mx-auto my-2 rounded-md shadow-md" }, + { "ul", "list-disc pl-2" } + }; + + private void ApplyGlobalCssStyles(IDocument document) + { + foreach ((string tag, string style) in _globalCssStyles) + { + foreach (IElement element in document.GetElementsByTagName(tag)) + { + element.ClassList.Add(style); + } + } + } + + private static void BeatifyTable(IDocument document) + { + foreach (IElement element in from e in document.All + where e.LocalName == "table" + select e) + { + element.ClassList.Add("mx-auto border-collapse table-auto overflow-x-auto"); + + // thead元素 + foreach (IElement headElement in from e in element.Children + where e.LocalName == "thead" + select e) + { + headElement.ClassList.Add("bg-slate-200"); + + // tr in thead + foreach (IElement trElement in from e in headElement.Children + where e.LocalName == "tr" + select e) + { + trElement.ClassList.Add("border border-slate-300"); + + // th in tr + foreach (IElement thElement in from e in trElement.Children + where e.LocalName == "th" + select e) + { + thElement.ClassList.Add("px-4 py-1"); + } + } + } + + // tbody元素 + foreach (IElement bodyElement in from e in element.Children + where e.LocalName == "tbody" + select e) + { + // tr in tbody + foreach (IElement trElement in from e in bodyElement.Children + where e.LocalName == "tr" + select e) + { + foreach (IElement tdElement in from e in trElement.Children + where e.LocalName == "td" + select e) + { + tdElement.ClassList.Add("px-4 py-1 border border-slate-300"); + } + } + } + } + } +} diff --git a/YaeBlog/Processors/ImagePostRenderProcessor.cs b/YaeBlog/Processors/ImagePostRenderProcessor.cs index a474d46..f64a03a 100644 --- a/YaeBlog/Processors/ImagePostRenderProcessor.cs +++ b/YaeBlog/Processors/ImagePostRenderProcessor.cs @@ -11,13 +11,11 @@ public class ImagePostRenderProcessor(ILogger logger, IOptions options) : IPostRenderProcessor { - private static readonly AngleSharp.IConfiguration s_configuration = Configuration.Default; - private readonly BlogOptions _options = options.Value; public async Task ProcessAsync(BlogEssay essay) { - BrowsingContext context = new(s_configuration); + BrowsingContext context = new(Configuration.Default); IDocument html = await context.OpenAsync( req => req.Content(essay.HtmlContent)); @@ -33,7 +31,6 @@ public class ImagePostRenderProcessor(ILogger logger, logger.LogDebug("Found image link: '{}'", attr.Value); attr.Value = GenerateImageLink(attr.Value, essay.FileName); } - element.ClassList.Add("essay-image"); } return essay.WithNewHtmlContent(html.DocumentElement.OuterHtml); } diff --git a/YaeBlog/Processors/TablePostRenderProcessor.cs b/YaeBlog/Processors/TablePostRenderProcessor.cs deleted file mode 100644 index 2d47a01..0000000 --- a/YaeBlog/Processors/TablePostRenderProcessor.cs +++ /dev/null @@ -1,34 +0,0 @@ -using AngleSharp; -using AngleSharp.Dom; -using AngleSharp.Html.Dom; -using YaeBlog.Abstraction; -using YaeBlog.Models; - -namespace YaeBlog.Processors; - -public class TablePostRenderProcessor: IPostRenderProcessor -{ - public async Task ProcessAsync(BlogEssay essay) - { - BrowsingContext browsingContext = new(Configuration.Default); - IDocument document = await browsingContext.OpenAsync( - req => req.Content(essay.HtmlContent)); - - IEnumerable tableElements = from item in document.All - where item.LocalName == "table" - select item as IHtmlTableElement; - - foreach (IHtmlTableElement element in tableElements) - { - IHtmlDivElement divElement = document.CreateElement(); - divElement.InnerHtml = element.OuterHtml; - divElement.ClassList.Add("py-2", "table-wrapper"); - - element.Replace(divElement); - } - - return essay.WithNewHtmlContent(document.DocumentElement.OuterHtml); - } - - public string Name => nameof(TablePostRenderProcessor); -} diff --git a/YaeBlog/YaeBlog.csproj b/YaeBlog/YaeBlog.csproj index f592469..31b222f 100644 --- a/YaeBlog/YaeBlog.csproj +++ b/YaeBlog/YaeBlog.csproj @@ -7,10 +7,6 @@ - - - - net9.0 enable diff --git a/YaeBlog/tailwind.config.js b/YaeBlog/tailwind.config.js index 4225e86..36dd647 100644 --- a/YaeBlog/tailwind.config.js +++ b/YaeBlog/tailwind.config.js @@ -1,6 +1,6 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - content: ["**/*.razor", "**/*.cshtml", "**/*.html"], + content: ["**/*.razor", "**/*.cshtml", "**/*.html", "Processors/EssayStylesPostRenderProcessor.cs"], theme: { extend: {}, },