add: 渲染前处理器和渲染后处理器
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using Markdig;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using YaeBlog.Core.Abstractions;
|
||||
using YaeBlog.Core.Exceptions;
|
||||
using YaeBlog.Core.Models;
|
||||
using YamlDotNet.Core;
|
||||
@@ -16,18 +18,23 @@ public class RendererService(ILogger<RendererService> logger,
|
||||
{
|
||||
private readonly Stopwatch _stopwatch = new();
|
||||
|
||||
private readonly List<IPreRenderProcessor> _preRenderProcessors = [];
|
||||
|
||||
private readonly List<IPostRenderProcessor> _postRenderProcessors = [];
|
||||
|
||||
public async Task RenderAsync()
|
||||
{
|
||||
_stopwatch.Start();
|
||||
logger.LogInformation("Render essays start.");
|
||||
|
||||
List<BlogContent> contents = await essayScanService.ScanAsync();
|
||||
IEnumerable<BlogContent> preProcessedContents =
|
||||
PreProcess(contents);
|
||||
|
||||
List<BlogEssay> essays = [];
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
foreach (BlogContent content in contents)
|
||||
foreach (BlogContent content in preProcessedContents)
|
||||
{
|
||||
MarkdownMetadata? metadata = TryParseMetadata(content);
|
||||
BlogEssay essay = new()
|
||||
@@ -46,6 +53,7 @@ public class RendererService(ILogger<RendererService> logger,
|
||||
}
|
||||
});
|
||||
|
||||
ConcurrentBag<BlogEssay> postProcessEssays = [];
|
||||
Parallel.ForEach(essays, essay =>
|
||||
{
|
||||
|
||||
@@ -58,19 +66,79 @@ public class RendererService(ILogger<RendererService> logger,
|
||||
};
|
||||
newEssay.Tags.AddRange(essay.Tags);
|
||||
|
||||
if (!essayContentService.TryAdd(newEssay.FileName, newEssay))
|
||||
{
|
||||
throw new BlogFileException(
|
||||
$"There are two essays with the same name: '{newEssay.FileName}'.");
|
||||
}
|
||||
postProcessEssays.Add(newEssay);
|
||||
logger.LogDebug("Render markdown file {}.", newEssay);
|
||||
});
|
||||
|
||||
PostProcess(postProcessEssays);
|
||||
|
||||
_stopwatch.Stop();
|
||||
logger.LogInformation("Render finished, consuming {} s.",
|
||||
_stopwatch.Elapsed.ToString("s\\.fff"));
|
||||
}
|
||||
|
||||
public void AddPreRenderProcessor(IPreRenderProcessor processor)
|
||||
{
|
||||
bool exist = _preRenderProcessors.Any(p => p.Name == processor.Name);
|
||||
|
||||
if (exist)
|
||||
{
|
||||
throw new InvalidOperationException("There exists one pre-render processor " +
|
||||
$"with the same name: {processor.Name}.");
|
||||
}
|
||||
|
||||
_preRenderProcessors.Add(processor);
|
||||
}
|
||||
|
||||
public void AddPostRenderProcessor(IPostRenderProcessor processor)
|
||||
{
|
||||
bool exist = _postRenderProcessors.Any(p => p.Name == processor.Name);
|
||||
|
||||
if (exist)
|
||||
{
|
||||
throw new InvalidCastException("There exists one post-render processor " +
|
||||
$"with the same name: {processor.Name}.");
|
||||
}
|
||||
|
||||
_postRenderProcessors.Add(processor);
|
||||
}
|
||||
|
||||
private IEnumerable<BlogContent> PreProcess(IEnumerable<BlogContent> contents)
|
||||
{
|
||||
ConcurrentBag<BlogContent> processedContents = [];
|
||||
|
||||
Parallel.ForEach(contents, content =>
|
||||
{
|
||||
foreach (IPreRenderProcessor processor in _preRenderProcessors)
|
||||
{
|
||||
content = processor.Process(content);
|
||||
}
|
||||
|
||||
processedContents.Add(content);
|
||||
});
|
||||
|
||||
return processedContents;
|
||||
}
|
||||
|
||||
private void PostProcess(IEnumerable<BlogEssay> essays)
|
||||
{
|
||||
Parallel.ForEach(essays, essay =>
|
||||
{
|
||||
foreach (IPostRenderProcessor processor in _postRenderProcessors)
|
||||
{
|
||||
essay = processor.Process(essay);
|
||||
}
|
||||
|
||||
if (!essayContentService.TryAdd(essay.FileName, essay))
|
||||
{
|
||||
throw new BlogFileException(
|
||||
$"There are two essays with the same name: '{essay.FileName}'.");
|
||||
}
|
||||
|
||||
logger.LogDebug("Post-Process essay: {}.", essay);
|
||||
});
|
||||
}
|
||||
|
||||
private MarkdownMetadata? TryParseMetadata(BlogContent content)
|
||||
{
|
||||
string fileContent = content.FileContent.Trim();
|
||||
|
Reference in New Issue
Block a user