mfgames-cil/src/MfGames.Markdown/RewriteLinkTransformer.cs
D. Moonfire edf6289dee
All checks were successful
deploy / deploy (push) Successful in 12m9s
feat: added a Markdown heading level transformer
2024-04-18 23:56:05 -05:00

63 lines
2 KiB
C#

using Markdig.Renderers.Normalize;
using Markdig.Syntax;
using Markdig.Syntax.Inlines;
namespace MfGames.Markdown;
/// <summary>
/// A transformer that goes through a Markdown document and visits each link
/// so it can be rewritten in a different format.
/// </summary>
public class RewriteLinkTransformer
{
public RewriteLinkTransformer() { }
public RewriteLinkTransformer(Action<LinkInline> onLink)
{
this.OnLink = onLink;
}
/// <summary>
/// A callback to trigger for every link found in the document.
/// </summary>
public Action<LinkInline>? OnLink { get; set; }
/// <summary>
/// Parses the given input as Markdown, goes through and transforms all
/// the links, and then returns the modified Markdown.
/// </summary>
/// <param name="input">The input text as Markdown.</param>
/// <returns>Modified Markdown text.</returns>
public string? Transform(string? input)
{
// If we get a null or blank string, we return it.
if (string.IsNullOrWhiteSpace(input) || this.OnLink == null)
{
return input;
}
// Parse the Markdown into an abstract syntax tree (AST). We need the
// trivia because we want to round-trip as much as possible and it
// contains things like extra whitespace or indention.
MarkdownDocument document = Markdig.Markdown.Parse(input, true);
// Go through all the links.
IEnumerable<LinkInline> linkList = document.Descendants<LinkInline>();
foreach (LinkInline oldLink in linkList)
{
this.OnLink.Invoke(oldLink);
}
// Convert the AST back into Markdown and return the results. The
// RoundtripRenderer doesn't work here, but NormalizeRenderer seems to
// allow us to modify the link above and get the results.
var writer = new StringWriter();
var renderer = new NormalizeRenderer(writer);
renderer.Write(document);
return writer.ToString();
}
}