63 lines
2 KiB
C#
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();
|
|
}
|
|
}
|