From cc3e7f1e4b98ea1ff49abca0ab04c0ba1c6dae83 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Fri, 19 Jan 2024 20:33:41 +0800 Subject: [PATCH] =?UTF-8?q?add:=20=E5=85=83=E6=95=B0=E6=8D=AE=E6=8F=90?= =?UTF-8?q?=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Builder/BlogApplicationBuilder.cs | 6 ++- .../Extensions/BlogApplicationExtension.cs | 12 ++++- YaeBlog.Core/Models/BlogContent.cs | 2 +- YaeBlog.Core/Models/BlogEssay.cs | 7 +++ YaeBlog.Core/Models/MarkdownMetadata.cs | 10 ++++ YaeBlog.Core/Services/RendererService.cs | 48 +++++++++++++++++-- YaeBlog.Core/YaeBlog.Core.csproj | 1 + 7 files changed, 77 insertions(+), 9 deletions(-) create mode 100644 YaeBlog.Core/Models/MarkdownMetadata.cs diff --git a/YaeBlog.Core/Builder/BlogApplicationBuilder.cs b/YaeBlog.Core/Builder/BlogApplicationBuilder.cs index b284137..0b18ee1 100644 --- a/YaeBlog.Core/Builder/BlogApplicationBuilder.cs +++ b/YaeBlog.Core/Builder/BlogApplicationBuilder.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.Diagnostics.Metrics; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using YaeBlog.Core.Extensions; +using YamlDotNet.Serialization; namespace YaeBlog.Core.Builder; @@ -12,12 +13,15 @@ public sealed class BlogApplicationBuilder : IHostApplicationBuilder { private readonly HostApplicationBuilder _hostApplicationBuilder; - public MarkdownPipelineBuilder MarkdigPipelineBuilder { get; set; } + public MarkdownPipelineBuilder MarkdigPipelineBuilder { get; } + + public DeserializerBuilder YamlDeserializerBuilder { get; } internal BlogApplicationBuilder(BlogApplicationOptions options) { ConfigurationManager configuration = new(); MarkdigPipelineBuilder = new MarkdownPipelineBuilder(); + YamlDeserializerBuilder = new DeserializerBuilder(); _hostApplicationBuilder = new HostApplicationBuilder(new HostApplicationBuilderSettings { diff --git a/YaeBlog.Core/Extensions/BlogApplicationExtension.cs b/YaeBlog.Core/Extensions/BlogApplicationExtension.cs index ae07567..eaf1507 100644 --- a/YaeBlog.Core/Extensions/BlogApplicationExtension.cs +++ b/YaeBlog.Core/Extensions/BlogApplicationExtension.cs @@ -4,6 +4,8 @@ using Microsoft.Extensions.DependencyInjection; using YaeBlog.Core.Builder; using YaeBlog.Core.Models; using YaeBlog.Core.Services; +using YamlDotNet.Serialization; +using YamlDotNet.Serialization.NamingConventions; namespace YaeBlog.Core.Extensions; @@ -19,11 +21,17 @@ internal static class BlogApplicationExtension builder.Services.Configure( builder.Configuration.GetSection(BlogOptions.OptionName)); + builder.YamlDeserializerBuilder.WithNamingConvention(CamelCaseNamingConvention.Instance); + builder.YamlDeserializerBuilder.IgnoreUnmatchedProperties(); + + builder.Services.AddSingleton( + _ => builder.MarkdigPipelineBuilder.Build()); + builder.Services.AddSingleton( + _ => builder.YamlDeserializerBuilder.Build()); + builder.Services.AddHostedService(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); - builder.Services.AddSingleton( - _ => builder.MarkdigPipelineBuilder.Build()); builder.Services.AddSingleton(); return builder; diff --git a/YaeBlog.Core/Models/BlogContent.cs b/YaeBlog.Core/Models/BlogContent.cs index c8fa6c8..f7999d6 100644 --- a/YaeBlog.Core/Models/BlogContent.cs +++ b/YaeBlog.Core/Models/BlogContent.cs @@ -4,5 +4,5 @@ public class BlogContent { public required string FileName { get; init; } - public required string FileContent { get; init; } + public required string FileContent { get; set; } } diff --git a/YaeBlog.Core/Models/BlogEssay.cs b/YaeBlog.Core/Models/BlogEssay.cs index 30e5923..b06e887 100644 --- a/YaeBlog.Core/Models/BlogEssay.cs +++ b/YaeBlog.Core/Models/BlogEssay.cs @@ -6,5 +6,12 @@ public class BlogEssay public required DateTime PublishTime { get; init; } + public List Tags { get; } = []; + public required string HtmlContent { get; init; } + + public override string ToString() + { + return $"{Title}-{PublishTime}"; + } } diff --git a/YaeBlog.Core/Models/MarkdownMetadata.cs b/YaeBlog.Core/Models/MarkdownMetadata.cs new file mode 100644 index 0000000..f276b34 --- /dev/null +++ b/YaeBlog.Core/Models/MarkdownMetadata.cs @@ -0,0 +1,10 @@ +namespace YaeBlog.Core.Models; + +public class MarkdownMetadata +{ + public string? Title { get; set; } + + public DateTime? Date { get; set; } + + public List Tags { get; set; } = []; +} diff --git a/YaeBlog.Core/Services/RendererService.cs b/YaeBlog.Core/Services/RendererService.cs index 507c676..611edfc 100644 --- a/YaeBlog.Core/Services/RendererService.cs +++ b/YaeBlog.Core/Services/RendererService.cs @@ -1,14 +1,15 @@ -using System.Collections.Concurrent; -using Markdig; +using Markdig; using Microsoft.Extensions.Logging; using YaeBlog.Core.Exceptions; using YaeBlog.Core.Models; +using YamlDotNet.Serialization; namespace YaeBlog.Core.Services; public class RendererService(ILogger logger, EssayScanService essayScanService, MarkdownPipeline markdownPipeline, + IDeserializer yamlDeserializer, EssayContentService essayContentService) { public async Task RenderAsync() @@ -17,19 +18,56 @@ public class RendererService(ILogger logger, Parallel.ForEach(contents, content => { - logger.LogDebug("Render markdown file {}.", content.FileName); + MarkdownMetadata? metadata = TryParseMetadata(content); + BlogEssay essay = new() { - Title = content.FileName, - PublishTime = DateTime.Now, + Title = metadata?.Title ?? content.FileName, + PublishTime = metadata?.Date ?? DateTime.Now, HtmlContent = Markdown.ToHtml(content.FileContent, markdownPipeline) }; + if (metadata is not null) + { + essay.Tags.AddRange(essay.Tags); + } if (!essayContentService.TryAdd(essay.Title, essay)) { throw new BlogFileException( $"There are two essays with the same name: '{content.FileName}'."); } + logger.LogDebug("Render markdown file {}.", essay); + logger.LogDebug("{}", essay.HtmlContent); }); } + + private MarkdownMetadata? TryParseMetadata(BlogContent content) + { + string fileContent = content.FileContent.Trim(); + + if (!fileContent.StartsWith("---")) + { + return null; + } + + // 移除起始的--- + fileContent = fileContent[3..]; + + int lastPos = fileContent.IndexOf("---", StringComparison.Ordinal); + if (lastPos is -1 or 0) + { + return null; + } + + string yamlContent = fileContent[..lastPos]; + MarkdownMetadata metadata = yamlDeserializer.Deserialize(yamlContent); + logger.LogDebug("Title: {}, Publish Date: {}.", + metadata.Title, metadata.Date); + + // 返回去掉元数据之后的文本 + lastPos += 3; + content.FileContent = fileContent[lastPos..]; + + return null; + } } diff --git a/YaeBlog.Core/YaeBlog.Core.csproj b/YaeBlog.Core/YaeBlog.Core.csproj index 67ea826..f588dac 100644 --- a/YaeBlog.Core/YaeBlog.Core.csproj +++ b/YaeBlog.Core/YaeBlog.Core.csproj @@ -15,6 +15,7 @@ +