feat: 美化文章界面 #3
|
@ -24,6 +24,8 @@ public static class WebApplicationBuilderExtensions
|
||||||
builder.Services.AddSingleton<IEssayContentService, EssayContentService>(provider =>
|
builder.Services.AddSingleton<IEssayContentService, EssayContentService>(provider =>
|
||||||
provider.GetRequiredService<EssayContentService>());
|
provider.GetRequiredService<EssayContentService>());
|
||||||
builder.Services.AddTransient<ImagePostRenderProcessor>();
|
builder.Services.AddTransient<ImagePostRenderProcessor>();
|
||||||
|
builder.Services.AddTransient<CodeBlockPostRenderProcessor>();
|
||||||
|
builder.Services.AddTransient<TablePostRenderProcessor>();
|
||||||
builder.Services.AddTransient<BlogOptions>(provider =>
|
builder.Services.AddTransient<BlogOptions>(provider =>
|
||||||
provider.GetRequiredService<IOptions<BlogOptions>>().Value);
|
provider.GetRequiredService<IOptions<BlogOptions>>().Value);
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,11 @@ namespace YaeBlog.Core.Extensions;
|
||||||
|
|
||||||
public static class WebApplicationExtensions
|
public static class WebApplicationExtensions
|
||||||
{
|
{
|
||||||
public static WebApplication UseMiddleRenderProcessors(this WebApplication application)
|
public static void UseYaeBlog(this WebApplication application)
|
||||||
{
|
{
|
||||||
application.UsePostRenderProcessor<ImagePostRenderProcessor>();
|
application.UsePostRenderProcessor<ImagePostRenderProcessor>();
|
||||||
|
application.UsePostRenderProcessor<CodeBlockPostRenderProcessor>();
|
||||||
return application;
|
application.UsePostRenderProcessor<TablePostRenderProcessor>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void UsePreRenderProcessor<T>(this WebApplication application) where T : IPreRenderProcessor
|
private static void UsePreRenderProcessor<T>(this WebApplication application) where T : IPreRenderProcessor
|
||||||
|
|
29
YaeBlog.Core/Processors/CodeBlockPostRenderProcessor.cs
Normal file
29
YaeBlog.Core/Processors/CodeBlockPostRenderProcessor.cs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
using AngleSharp;
|
||||||
|
using AngleSharp.Dom;
|
||||||
|
using YaeBlog.Core.Abstractions;
|
||||||
|
using YaeBlog.Core.Models;
|
||||||
|
|
||||||
|
namespace YaeBlog.Core.Processors;
|
||||||
|
|
||||||
|
public class CodeBlockPostRenderProcessor : IPostRenderProcessor
|
||||||
|
{
|
||||||
|
public async Task<BlogEssay> ProcessAsync(BlogEssay essay)
|
||||||
|
{
|
||||||
|
BrowsingContext context = new(Configuration.Default);
|
||||||
|
IDocument document = await context.OpenAsync(
|
||||||
|
req => req.Content(essay.HtmlContent));
|
||||||
|
|
||||||
|
IEnumerable<IElement> 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);
|
||||||
|
}
|
|
@ -38,7 +38,7 @@ public class ImagePostRenderProcessor(ILogger<ImagePostRenderProcessor> logger,
|
||||||
return essay.WithNewHtmlContent(html.DocumentElement.OuterHtml);
|
return essay.WithNewHtmlContent(html.DocumentElement.OuterHtml);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name => "ImagePostRenderProcessor";
|
public string Name => nameof(ImagePostRenderProcessor);
|
||||||
|
|
||||||
private string GenerateImageLink(string filename, string essayFilename)
|
private string GenerateImageLink(string filename, string essayFilename)
|
||||||
{
|
{
|
||||||
|
|
34
YaeBlog.Core/Processors/TablePostRenderProcessor.cs
Normal file
34
YaeBlog.Core/Processors/TablePostRenderProcessor.cs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
using AngleSharp;
|
||||||
|
using AngleSharp.Dom;
|
||||||
|
using AngleSharp.Html.Dom;
|
||||||
|
using YaeBlog.Core.Abstractions;
|
||||||
|
using YaeBlog.Core.Models;
|
||||||
|
|
||||||
|
namespace YaeBlog.Core.Processors;
|
||||||
|
|
||||||
|
public class TablePostRenderProcessor: IPostRenderProcessor
|
||||||
|
{
|
||||||
|
public async Task<BlogEssay> ProcessAsync(BlogEssay essay)
|
||||||
|
{
|
||||||
|
BrowsingContext browsingContext = new(Configuration.Default);
|
||||||
|
IDocument document = await browsingContext.OpenAsync(
|
||||||
|
req => req.Content(essay.HtmlContent));
|
||||||
|
|
||||||
|
IEnumerable<IHtmlTableElement> tableElements = from item in document.All
|
||||||
|
where item.LocalName == "table"
|
||||||
|
select item as IHtmlTableElement;
|
||||||
|
|
||||||
|
foreach (IHtmlTableElement element in tableElements)
|
||||||
|
{
|
||||||
|
IHtmlDivElement divElement = document.CreateElement<IHtmlDivElement>();
|
||||||
|
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);
|
||||||
|
}
|
|
@ -19,6 +19,10 @@
|
||||||
|
|
||||||
<script src="_framework/blazor.web.js"></script>
|
<script src="_framework/blazor.web.js"></script>
|
||||||
<script src="bootstrap.bundle.min.js"></script>
|
<script src="bootstrap.bundle.min.js"></script>
|
||||||
|
<script src="clipboard.min.js"></script>
|
||||||
|
<script>
|
||||||
|
const clipboard = new ClipboardJS('.btn');
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -13,7 +13,7 @@ WebApplication application = builder.Build();
|
||||||
|
|
||||||
application.UseStaticFiles();
|
application.UseStaticFiles();
|
||||||
application.UseAntiforgery();
|
application.UseAntiforgery();
|
||||||
application.UseMiddleRenderProcessors();
|
application.UseYaeBlog();
|
||||||
|
|
||||||
application.MapRazorComponents<App>()
|
application.MapRazorComponents<App>()
|
||||||
.AddInteractiveServerRenderMode();
|
.AddInteractiveServerRenderMode();
|
||||||
|
|
7
YaeBlog/wwwroot/clipboard.min.js
vendored
Normal file
7
YaeBlog/wwwroot/clipboard.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,18 +1,3 @@
|
||||||
body a {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
body main {
|
|
||||||
flex: 1;
|
|
||||||
min-height: 100vh;
|
|
||||||
overflow-x: visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
body p {
|
|
||||||
margin: 0;
|
|
||||||
margin-block: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Font Awesome 6 Free";
|
font-family: "Font Awesome 6 Free";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
|
@ -38,3 +23,59 @@ body p {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table-wrapper {
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
body a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body main {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 100vh;
|
||||||
|
overflow-x: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
body p {
|
||||||
|
margin: 0;
|
||||||
|
margin-block: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2, h3 {
|
||||||
|
margin-block-start: 1.5em;
|
||||||
|
margin-block-end: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4, h5 {
|
||||||
|
margin-block-start: 1em;
|
||||||
|
margin-block-end: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
margin: 0 auto;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td {
|
||||||
|
padding: 3px 20px;
|
||||||
|
border: 1px var(--bs-border-color) solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
table thead {
|
||||||
|
background: var(--bs-secondary-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
table thead td {
|
||||||
|
font-weight: 700;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
table thead th {
|
||||||
|
padding: 3px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table thead tr {
|
||||||
|
border: 1px var(--bs-border-color) solid;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user