feat: 美化文章界面 #3

Merged
jackfiled merged 8 commits from feat-markdown into master 2024-07-29 22:32:27 +08:00
9 changed files with 143 additions and 26 deletions
Showing only changes of commit d1fa453952 - Show all commits

View File

@ -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);

View File

@ -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

View 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);
}

View File

@ -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)
{ {

View 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);
}

View File

@ -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>

View File

@ -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

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,33 @@
@font-face {
font-family: "Font Awesome 6 Free";
font-style: normal;
font-weight: 400;
font-display: block;
src: url(fonts/fa-regular-400.woff2) format("woff2"), url(fonts/fa-regular-400.ttf) format("truetype")
}
@font-face {
font-family: "Font Awesome 6 Free";
font-style: normal;
font-weight: 900;
font-display: block;
src: url(fonts/fa-solid-900.woff2) format("woff2"), url(fonts/fa-solid-900.ttf) format("truetype")
}
.essay-image {
width: 90%;
display: block;
margin: 1.5rem auto;
box-shadow: 0 5px 11px 0 rgba(0, 0, 0, 0.18),
0 4px 15px 0 rgba(0, 0, 0, 0.15);
border-radius: 4px;
background-color: transparent;
}
.table-wrapper {
overflow-x: auto;
}
body a { body a {
text-decoration: none; text-decoration: none;
} }
@ -10,31 +40,42 @@ body main {
body p { body p {
margin: 0; margin: 0;
margin-block: 0; margin-block: 1em;
} }
@font-face { h2, h3 {
font-family: "Font Awesome 6 Free"; margin-block-start: 1.5em;
font-style: normal; margin-block-end: 1em;
font-weight: 400;
font-display: block;
src: url(fonts/fa-regular-400.woff2) format("woff2"),url(fonts/fa-regular-400.ttf) format("truetype")
} }
@font-face { h4, h5 {
font-family: "Font Awesome 6 Free"; margin-block-start: 1em;
font-style: normal; margin-block-end: 1em;
font-weight: 900;
font-display: block;
src: url(fonts/fa-solid-900.woff2) format("woff2"),url(fonts/fa-solid-900.ttf) format("truetype")
} }
.essay-image { table {
width: 90%; margin: 0 auto;
display: block; border-collapse: collapse;
margin: 1.5rem auto; }
box-shadow: 0 5px 11px 0 rgba(0,0,0,0.18),
0 4px 15px 0 rgba(0,0,0,0.15); table td {
border-radius: 4px; padding: 3px 20px;
background-color: transparent; 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;
} }