Skip to content
This repository was archived by the owner on Dec 21, 2023. It is now read-only.

Commit cbed852

Browse files
committed
Add support for yaml metadata in markdown
1 parent 0577f6d commit cbed852

File tree

6 files changed

+85
-27
lines changed

6 files changed

+85
-27
lines changed

OpenTabletDriver.Web/Controllers/TabletsController.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
using System.IO;
2-
using System.Net.Http;
3-
using System.Runtime.Versioning;
41
using System.Threading.Tasks;
52
using Microsoft.AspNetCore.Html;
63
using Microsoft.AspNetCore.Mvc;
74
using OpenTabletDriver.Web.Core.Services;
85
using OpenTabletDriver.Web.Models;
6+
using OpenTabletDriver.Web.Utilities;
97

108
namespace OpenTabletDriver.Web.Controllers
119
{
@@ -22,8 +20,8 @@ public TabletsController(ITabletService tabletService)
2220
public async Task<IActionResult> Index(string search = null)
2321
{
2422
var markdown = await tabletService.GetMarkdownRaw();
25-
string html = Markdown.ToHtml(markdown);
26-
string patchedHtml = html.Replace(
23+
var html = Markdown.ToHtml(markdown);
24+
var patchedHtml = html.Replace(
2725
"<table>",
2826
"<table id=\"tablets\" class=\"table table-hover\">"
2927
);
Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
using System.Text.RegularExpressions;
1+
using System;
22
using System.Threading.Tasks;
3-
using Microsoft.AspNetCore.Html;
43
using Microsoft.AspNetCore.Mvc;
4+
using Microsoft.Extensions.Caching.Memory;
55
using OpenTabletDriver.Web.Core.Services;
6+
using OpenTabletDriver.Web.Models;
67

78
#nullable enable
89

@@ -11,10 +12,12 @@ namespace OpenTabletDriver.Web.Controllers
1112
public class WikiController : Controller
1213
{
1314
private readonly IMarkdownSource _markdownSource;
15+
private readonly IMemoryCache _memoryCache;
1416

15-
public WikiController(IMarkdownSource markdownSource)
17+
public WikiController(IMarkdownSource markdownSource, IMemoryCache memoryCache)
1618
{
1719
_markdownSource = markdownSource;
20+
_memoryCache = memoryCache;
1821
}
1922

2023
[ResponseCache(Duration = 300)]
@@ -27,22 +30,17 @@ public IActionResult Index()
2730
[Route("/Wiki/{category}/{page}")]
2831
public async Task<IActionResult> Wiki(string category, string page)
2932
{
30-
var markdown = await _markdownSource.GetPage(category, page);
31-
return markdown == null ? View($"{category}/{page}") : View("WikiMarkdownPage", Format(markdown));
32-
}
33+
var route = $"{category}/{page}";
34+
var model = await _memoryCache.GetOrCreateAsync(route, entry => GenerateMarkdownWikiPage(entry, category, page));
3335

34-
private static readonly Regex HeaderRegex = new Regex("(?<=.?\n)<h3", RegexOptions.Compiled);
36+
return model == null ? View(route) : View("WikiMarkdownPage", model);
37+
}
3538

36-
private IHtmlContent Format(string markdown)
39+
private async Task<MarkdownViewModel?> GenerateMarkdownWikiPage(ICacheEntry entry, string category, string page)
3740
{
38-
var html = Markdown.ToHtml(markdown);
39-
40-
var formatted = HeaderRegex.Replace(html, "<hr><h3")
41-
.Replace("<h3", "<h3 class=\"wiki-nav-item pb-2\"")
42-
.Replace("<table>", "<table class=\"table table-hover ms-3\">")
43-
.Replace("<p>", "<p class=\"ms-3\">");
44-
45-
return new HtmlString(formatted);
41+
entry.AbsoluteExpiration = DateTimeOffset.MaxValue;
42+
var markdown = await _markdownSource.GetPage(category, page);
43+
return markdown != null ? new MarkdownViewModel(markdown) : null;
4644
}
4745
}
4846
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using System.Collections.Generic;
2+
using System.IO;
3+
using System.Linq;
4+
using System.Text.RegularExpressions;
5+
using Markdig;
6+
using Markdig.Extensions.Yaml;
7+
using Markdig.Renderers;
8+
using Markdig.Syntax;
9+
using Microsoft.AspNetCore.Html;
10+
using YamlDotNet.Serialization;
11+
12+
namespace OpenTabletDriver.Web.Models
13+
{
14+
public class MarkdownViewModel
15+
{
16+
public MarkdownViewModel(string markdown)
17+
{
18+
var pipeline = new MarkdownPipelineBuilder()
19+
.UseYamlFrontMatter()
20+
.UseAdvancedExtensions()
21+
.Build();
22+
23+
using (var sw = new StringWriter())
24+
{
25+
var renderer = new HtmlRenderer(sw);
26+
pipeline.Setup(renderer);
27+
28+
var document = Markdown.Parse(markdown, pipeline);
29+
30+
var yamlBlock = document.Descendants<YamlFrontMatterBlock>().FirstOrDefault();
31+
if (yamlBlock != null)
32+
{
33+
var startIndex = yamlBlock.Span.Start + 4;
34+
var length = yamlBlock.Span.Length - 8;
35+
var yaml = markdown.Substring(startIndex, length);
36+
37+
Metadata = new Deserializer().Deserialize<Dictionary<string, object>>(yaml);
38+
}
39+
40+
renderer.Render(document);
41+
Content = GetHtmlContent(sw);
42+
}
43+
}
44+
45+
public IDictionary<string, object> Metadata { get; }
46+
public IHtmlContent Content { get; }
47+
48+
private static readonly Regex HeaderRegex = new Regex("(?<=.?\n)<h3", RegexOptions.Compiled);
49+
50+
private IHtmlContent GetHtmlContent(StringWriter sw)
51+
{
52+
sw.Flush();
53+
var html = sw.ToString()!;
54+
55+
var formattedHtml = HeaderRegex.Replace(html, "<hr><h3")
56+
.Replace("<h3", "<h3 class=\"wiki-nav-item pb-2\"")
57+
.Replace("<table>", "<table class=\"table table-hover ms-3\">")
58+
.Replace("<p>", "<p class=\"ms-3\">");
59+
60+
return new HtmlString(formattedHtml);
61+
}
62+
}
63+
}

OpenTabletDriver.Web/OpenTabletDriver.Web.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
<ItemGroup Label="NuGet Packages">
1313
<PackageReference Include="Markdig" Version="0.25.0" />
14+
<PackageReference Include="YamlDotNet" Version="11.2.1" />
1415
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="5.0.8" />
1516
</ItemGroup>
1617

OpenTabletDriver.Web/Markdown.cs renamed to OpenTabletDriver.Web/Utilities/Markdown.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
using System.Reflection.Metadata;
21
using Markdig;
32
using Microsoft.AspNetCore.Html;
4-
using Microsoft.AspNetCore.Mvc.Rendering;
53

6-
namespace OpenTabletDriver.Web
4+
namespace OpenTabletDriver.Web.Utilities
75
{
86
public class Markdown
97
{
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
@model Microsoft.AspNetCore.Html.IHtmlContent
1+
@model MarkdownViewModel
22

33
@{
4-
ViewBag.Title = "Wiki";
4+
ViewBag.Title = Model!.Metadata["title"];
55
}
66

7-
@Model
7+
@Model.Content

0 commit comments

Comments
 (0)