2024-01-19 20:33:41 +08:00
|
|
|
|
using Markdig;
|
2024-01-17 13:20:32 +08:00
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using YaeBlog.Core.Exceptions;
|
|
|
|
|
using YaeBlog.Core.Models;
|
2024-01-19 20:33:41 +08:00
|
|
|
|
using YamlDotNet.Serialization;
|
2024-01-17 13:20:32 +08:00
|
|
|
|
|
|
|
|
|
namespace YaeBlog.Core.Services;
|
|
|
|
|
|
|
|
|
|
public class RendererService(ILogger<RendererService> logger,
|
|
|
|
|
EssayScanService essayScanService,
|
|
|
|
|
MarkdownPipeline markdownPipeline,
|
2024-01-19 20:33:41 +08:00
|
|
|
|
IDeserializer yamlDeserializer,
|
2024-01-17 13:20:32 +08:00
|
|
|
|
EssayContentService essayContentService)
|
|
|
|
|
{
|
|
|
|
|
public async Task RenderAsync()
|
|
|
|
|
{
|
|
|
|
|
List<BlogContent> contents = await essayScanService.ScanAsync();
|
|
|
|
|
|
|
|
|
|
Parallel.ForEach(contents, content =>
|
|
|
|
|
{
|
2024-01-19 20:33:41 +08:00
|
|
|
|
MarkdownMetadata? metadata = TryParseMetadata(content);
|
|
|
|
|
|
2024-01-17 13:20:32 +08:00
|
|
|
|
BlogEssay essay = new()
|
|
|
|
|
{
|
2024-01-19 20:33:41 +08:00
|
|
|
|
Title = metadata?.Title ?? content.FileName,
|
|
|
|
|
PublishTime = metadata?.Date ?? DateTime.Now,
|
2024-01-17 13:20:32 +08:00
|
|
|
|
HtmlContent = Markdown.ToHtml(content.FileContent, markdownPipeline)
|
|
|
|
|
};
|
2024-01-19 20:33:41 +08:00
|
|
|
|
if (metadata is not null)
|
|
|
|
|
{
|
|
|
|
|
essay.Tags.AddRange(essay.Tags);
|
|
|
|
|
}
|
2024-01-17 13:20:32 +08:00
|
|
|
|
|
|
|
|
|
if (!essayContentService.TryAdd(essay.Title, essay))
|
|
|
|
|
{
|
|
|
|
|
throw new BlogFileException(
|
|
|
|
|
$"There are two essays with the same name: '{content.FileName}'.");
|
|
|
|
|
}
|
2024-01-19 20:33:41 +08:00
|
|
|
|
logger.LogDebug("Render markdown file {}.", essay);
|
|
|
|
|
logger.LogDebug("{}", essay.HtmlContent);
|
2024-01-17 13:20:32 +08:00
|
|
|
|
});
|
|
|
|
|
}
|
2024-01-19 20:33:41 +08:00
|
|
|
|
|
|
|
|
|
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<MarkdownMetadata>(yamlContent);
|
|
|
|
|
logger.LogDebug("Title: {}, Publish Date: {}.",
|
|
|
|
|
metadata.Title, metadata.Date);
|
|
|
|
|
|
|
|
|
|
// 返回去掉元数据之后的文本
|
|
|
|
|
lastPos += 3;
|
|
|
|
|
content.FileContent = fileContent[lastPos..];
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2024-01-17 13:20:32 +08:00
|
|
|
|
}
|