Created
October 10, 2020 13:06
-
-
Save laurentkempe/6bc27cde6742bb166ab5469032ed9874 to your computer and use it in GitHub Desktop.
Fixing blog permalinks in front matter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Linq; | |
using System.Threading.Tasks; | |
using Markdig; | |
using Markdig.Extensions.Yaml; | |
using Markdig.Syntax; | |
using YamlDotNet.Serialization; | |
namespace blogFix | |
{ | |
/// <summary> | |
/// Most code from https://khalidabuhakmeh.com/parse-markdown-front-matter-with-csharp | |
/// </summary> | |
internal class Program | |
{ | |
private static readonly MarkdownPipeline Pipeline | |
= new MarkdownPipelineBuilder() | |
// YAML Front Matter extension registered | |
.UseYamlFrontMatter() | |
.Build(); | |
private static async Task Main(string[] args) | |
{ | |
Console.WriteLine("Fixing blog!"); | |
var directory = Directory | |
.GetFiles(@"C:\Users\laure\projects\blog\source\_posts"); | |
var fileContent = directory.Select(f => new {file = f, fileContent = File.ReadAllText(f)}); | |
var posts = fileContent | |
.Select(md => new {file = md.file, fileContent = md.fileContent, fileFrontMatter = md.fileContent.GetFrontMatter<BlogFrontMatter>()}) | |
.ToList(); | |
foreach (var post in posts.OrderBy(p => p.fileFrontMatter.Date)) | |
{ | |
Console.WriteLine($"/{post.fileFrontMatter.Date.Year}/{post.fileFrontMatter.Date.Month:00}/{post.fileFrontMatter.Date.Day:00}/{post.fileFrontMatter.Permalink}/"); | |
await ReplacePermalink(post.file, post.fileFrontMatter); | |
} | |
} | |
private static async Task ReplacePermalink(string file, BlogFrontMatter fileFrontMatter) | |
{ | |
var allLines = await File.ReadAllLinesAsync(file); | |
var lines = allLines.ToList(); | |
for (var index = 0; index < allLines.ToList().Count; index++) | |
{ | |
if (lines[index].StartsWith("permalink")) | |
{ | |
lines[index] = "permalink: " + | |
$"/{fileFrontMatter.Date.Year}/{fileFrontMatter.Date.Month:00}/{fileFrontMatter.Date.Day:00}/{fileFrontMatter.Permalink}/"; | |
} | |
} | |
await File.WriteAllLinesAsync(file, lines); | |
} | |
} | |
public class BlogFrontMatter | |
{ | |
// [YamlMember(Alias = "tags")] | |
// public string Tags { get; set; } | |
[YamlMember(Alias = "title")] public string Title { get; set; } | |
[YamlMember(Alias = "permalink")] public string Permalink { get; set; } | |
[YamlMember(Alias = "date")] public DateTime Date { get; set; } | |
[YamlMember(Alias = "image")] public string Image { get; set; } | |
[YamlMember(Alias = "image_credit_name")] | |
public string ImageCreditName { get; set; } | |
[YamlMember(Alias = "image_credit_url")] | |
public string ImageCreditUrl { get; set; } | |
[YamlMember(Alias = "image_alt")] public string ImageAlt { get; set; } | |
[YamlMember(Alias = "redirect_from")] public string[] RedirectFrom { get; set; } | |
// [YamlIgnore] | |
// public IList<string> GetTags => Tags? | |
// .Split(",", StringSplitOptions.RemoveEmptyEntries) | |
// .Select(x => x.Trim()) | |
// .ToArray(); | |
} | |
public static class MarkdownExtensions | |
{ | |
private static readonly Deserializer YamlDeserializer = | |
new DeserializerBuilder() | |
.IgnoreUnmatchedProperties() | |
.Build(); | |
private static readonly MarkdownPipeline Pipeline | |
= new MarkdownPipelineBuilder() | |
.UseYamlFrontMatter() | |
.Build(); | |
public static T GetFrontMatter<T>(this string markdown) | |
{ | |
var document = Markdown.Parse(markdown, Pipeline); | |
var block = document | |
.Descendants<YamlFrontMatterBlock>() | |
.FirstOrDefault(); | |
if (block == null) | |
return default; | |
var yaml = | |
block | |
// this is not a mistake | |
// we have to call .Lines 2x | |
.Lines // StringLineGroup[] | |
.Lines // StringLine[] | |
.OrderByDescending(x => x.Line) | |
.Select(x => $"{x}\n") | |
.ToList() | |
.Select(x => x.Replace("---", string.Empty)) | |
.Where(x => !string.IsNullOrWhiteSpace(x)) | |
.Aggregate((s, agg) => agg + s); | |
return YamlDeserializer.Deserialize<T>(yaml); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment