Use YAML parser

This commit is contained in:
Laura Hausmann 2022-11-20 22:26:21 +01:00
parent ef1e976eda
commit 49457ff42f
Signed by: zotan
GPG key ID: D044E84C5BE01605
18 changed files with 84 additions and 34 deletions

View file

@ -153,4 +153,4 @@
@section postfooter { @section postfooter {
<img src="/files/help.svg" height="450rem" title="Designed by someone I love, ~fr2"> <img src="/files/help.svg" height="450rem" title="Designed by someone I love, ~fr2">
} }

View file

@ -37,4 +37,4 @@
<a href="https://music.apple.com/gb/album/%E3%83%AA%E3%83%95%E3%82%A1%E3%82%AF%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0-%E3%83%88%E3%83%A9%E3%83%99%E3%83%AB/1494424249">Apple Music</a> <a href="https://music.apple.com/gb/album/%E3%83%AA%E3%83%95%E3%82%A1%E3%82%AF%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0-%E3%83%88%E3%83%A9%E3%83%99%E3%83%AB/1494424249">Apple Music</a>
</td> </td>
</tr> </tr>
</table> </table>

View file

@ -52,4 +52,4 @@
</div> </div>
<script src="~/js/site.js"></script> <script src="~/js/site.js"></script>
</body> </body>
</html> </html>

View file

@ -1,40 +1,80 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Markdig; using Markdig;
using Markdig.Extensions.Yaml;
using Markdig.Renderers;
using Markdig.Syntax;
using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.RazorPages;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
namespace zotanpw_web.Pages.blog; namespace zotanpw_web.Pages.blog;
public class BlogModel : PageModel { public class BlogModel : PageModel {
public static readonly List<BlogPost> Posts = new() { public static readonly List<BlogPost> Posts = new();
new BlogPost("adhd-and-notes", "ADHD & Notetaking: an autistic perspective", DateOnly.Parse("2021-08-07")),
new BlogPost("ipv6-networking", "IPv6-native networking: a project report", DateOnly.Parse("2021-08-23"))
};
static BlogModel() { static BlogModel() {
foreach (var file in Directory.EnumerateFiles("Pages/blog/posts"))
Posts.Add(new BlogPost(Path.GetFileNameWithoutExtension(file)));
Posts = Posts.OrderByDescending(p => p.PublishedOn).ToList(); Posts = Posts.OrderByDescending(p => p.PublishedOn).ToList();
} }
public void OnGet() { } public void OnGet() { }
public class BlogPost { public class BlogPost {
public readonly DateOnly PublishedOn; public readonly string Shorthand;
public readonly string Shorthand; public string Content = "";
public readonly string Title;
public string Content = "";
public int ReadTimeMinutes;
public BlogPost(string shorthand, string title, DateOnly publishedOn) { public DateOnly PublishedOn;
Title = title; public int ReadTimeMinutes;
PublishedOn = publishedOn; public string Title = null!;
Shorthand = shorthand;
UpdateContent(); public BlogPost(string shorthand) {
Shorthand = shorthand;
UpdateContentAndMetadata();
} }
public void UpdateContent() { public void UpdateContentAndMetadata() {
var markdownText = System.IO.File.ReadAllText($"Pages/blog/posts/{Shorthand}.md"); var markdownText = System.IO.File.ReadAllText($"Pages/blog/posts/{Shorthand}.md");
Content = Markdown.ToHtml(markdownText, new MarkdownPipelineBuilder().UseGenericAttributes().Build()); var parsed = ParseBlogPost(markdownText);
Title = parsed.metadata.Title!;
PublishedOn = parsed.metadata.Date;
ReadTimeMinutes = Regex.Matches(markdownText, @"\b\w+\b").Count / 150; ReadTimeMinutes = Regex.Matches(markdownText, @"\b\w+\b").Count / 150;
Content = parsed.html;
}
private static (PostMetadata metadata, string html) ParseBlogPost(string markdown) {
var yaml = "";
var pipeline = new MarkdownPipelineBuilder().UseGenericAttributes().UseYamlFrontMatter().Build();
var writer = new StringWriter();
var renderer = new HtmlRenderer(writer);
pipeline.Setup(renderer);
var document = Markdown.Parse(markdown, pipeline);
var yamlBlock = document.Descendants<YamlFrontMatterBlock>().FirstOrDefault();
if (yamlBlock != null)
yaml = markdown.Substring(yamlBlock.Span.Start, yamlBlock.Span.Length);
renderer.Render(document);
writer.Flush();
var html = writer.ToString();
var yamlDeserializer = new DeserializerBuilder().WithNamingConvention(LowerCaseNamingConvention.Instance).Build();
var metadata = yamlDeserializer.Deserialize<PostMetadata>(yaml);
return (metadata, html);
}
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Local")]
private class PostMetadata {
#pragma warning disable CS0649
public string? Title;
public DateOnly Date;
#pragma warning restore CS0649
} }
} }
} }

View file

@ -12,7 +12,7 @@
ViewData["title"] = "blog"; ViewData["title"] = "blog";
ViewData["subtitle"] = post.Shorthand; ViewData["subtitle"] = post.Shorthand;
#if (DEBUG) #if (DEBUG)
post.UpdateContent(); post.UpdateContentAndMetadata();
#endif #endif
} }
@ -20,4 +20,4 @@
<h1 id="post">IPv6-native networking: a project report</h1> <h1 id="post">IPv6-native networking: a project report</h1>
<div align="justify"> <div align="justify">
@Html.Raw(post.Content) @Html.Raw(post.Content)
</div> </div>

View file

@ -1,3 +1,7 @@
---
title: "ADHD & Notetaking: an autistic perspective"
date: 2021-08-07
...
If you are living with ADHD, diagnosed or not, the following things If you are living with ADHD, diagnosed or not, the following things
might sound familiar: *"I forgot to write that down"*, *"I forgot to do might sound familiar: *"I forgot to write that down"*, *"I forgot to do
that"*, *"I don't remember that"*. that"*, *"I don't remember that"*.

View file

@ -1,3 +1,7 @@
---
title: "IPv6-native networking: a project report"
date: 2021-08-23
...
If you have reached this post, chances are you already know my [AS211579](https://zotan.network){target="_blank"} If you have reached this post, chances are you already know my [AS211579](https://zotan.network){target="_blank"}
project. project.
This post serves as a summary of the things I learnt and the roadblocks This post serves as a summary of the things I learnt and the roadblocks

View file

@ -38,4 +38,4 @@ public class LogPlayback : Controller {
Response.StatusCode = 403; Response.StatusCode = 403;
return null!; return null!;
} }
} }

View file

@ -5,4 +5,4 @@ public class LogPlaybackRequest {
public string? Title { get; set; } public string? Title { get; set; }
public string? Source { get; set; } public string? Source { get; set; }
public string? Link { get; set; } public string? Link { get; set; }
} }

View file

@ -42,4 +42,4 @@ app.UseAuthorization();
app.MapRazorPages(); app.MapRazorPages();
app.MapControllers(); app.MapControllers();
app.Run(); app.Run();

View file

@ -18,7 +18,7 @@ public class Travelynx : Controller {
db.InsertWithIdentity(new TravelynxInfo { CheckedIn = false }); db.InsertWithIdentity(new TravelynxInfo { CheckedIn = false });
var status = db.TravelynxInfo.First(); var status = db.TravelynxInfo.First();
status.CheckedIn = rq.Status.CheckedIn; status.CheckedIn = rq.Status!.CheckedIn;
status.Train = $"{rq.Status.Train?.Type} {rq.Status.Train?.No}"; status.Train = $"{rq.Status.Train?.Type} {rq.Status.Train?.No}";
status.Destination = rq.Status.ToStation?.Name; status.Destination = rq.Status.ToStation?.Name;
db.Update(status); db.Update(status);

View file

@ -1,8 +1,8 @@
namespace zotanpw_web.Travelynx; namespace zotanpw_web.Travelynx;
public class WebhookRequest { public class WebhookRequest {
public string Reason { get; set; } public string? Reason { get; set; }
public Status Status { get; set; } public Status? Status { get; set; }
} }
public class Status { public class Status {
@ -38,4 +38,4 @@ public class Train {
public string? Line { get; set; } public string? Line { get; set; }
public string? No { get; set; } public string? No { get; set; }
public string? Id { get; set; } public string? Id { get; set; }
} }

View file

@ -12,4 +12,4 @@ public class AlbumHistoryEntry {
[Column(Name = "Title"), NotNull] public string Title { get; set; } [Column(Name = "Title"), NotNull] public string Title { get; set; }
[Column(Name = "Source"), NotNull] public string Source { get; set; } [Column(Name = "Source"), NotNull] public string Source { get; set; }
[Column(Name = "Link")] public string Link { get; set; } [Column(Name = "Link")] public string Link { get; set; }
} }

View file

@ -12,4 +12,4 @@ public class PlaylistHistoryEntry {
[Column(Name = "Title"), NotNull] public string Title { get; set; } [Column(Name = "Title"), NotNull] public string Title { get; set; }
[Column(Name = "Source"), NotNull] public string Source { get; set; } [Column(Name = "Source"), NotNull] public string Source { get; set; }
[Column(Name = "Link")] public string Link { get; set; } [Column(Name = "Link")] public string Link { get; set; }
} }

View file

@ -8,4 +8,4 @@ public class TravelynxInfo {
[Column(Name = "CheckedIn"), NotNull] public bool CheckedIn { get; set; } [Column(Name = "CheckedIn"), NotNull] public bool CheckedIn { get; set; }
[Column(Name = "Train")] public string? Train { get; set; } [Column(Name = "Train")] public string? Train { get; set; }
[Column(Name = "Destination")] public string? Destination { get; set; } [Column(Name = "Destination")] public string? Destination { get; set; }
} }

View file

@ -6,4 +6,4 @@ namespace zotanpw_web.well_known;
public class Pronouns : Controller { public class Pronouns : Controller {
[HttpGet] [HttpGet]
public string Get() => "she/they\n"; public string Get() => "she/they\n";
} }

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<svg xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" width="500mm" height="400mm" <svg xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" width="500mm" height="400mm"
version="1.1" viewBox="0 0 500 400" version="1.1" viewBox="0 0 500 400"
xmlns="http://www.w3.org/2000/svg"> xmlns="http://www.w3.org/2000/svg">
<metadata> <metadata>

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

View file

@ -66,6 +66,7 @@
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="7.0.0"/> <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="7.0.0"/>
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="7.0.0"/> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="7.0.0"/>
<PackageReference Include="System.Data.SQLite" Version="1.0.115"/> <PackageReference Include="System.Data.SQLite" Version="1.0.115"/>
<PackageReference Include="YamlDotNet" Version="12.0.2"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>