Feature-request: Transform relative file links
Sometimes text is distributed among multiple markdown files, which refer to each other with links such as [Configuration-section](./configuration.md).
When transforming to HTML, it would be nice to link to the corresponding files (./configuration.html in the example above).
While I already have written a RelativeFileLinkExtension and included it in our project, I'd prefer to have it officially supported and would therefore like to create a merge-request for it. Would this be a welcome contribution, @xoofx ?
Code from our project as follows:
public static MarkdownPipelineBuilder TransformFileLinks(this MarkdownPipelineBuilder pipeline)
{
pipeline.Extensions.AddIfNotAlready<RelativeFileLinkExtension>();
return pipeline;
}
internal sealed class RelativeFileLinkExtension : IMarkdownExtension
{
/// <inheritdoc/>
public void Setup(MarkdownPipelineBuilder pipeline)
{
// Make sure we do not have a delegate twice
pipeline.DocumentProcessed -= OnDocumentProcessed;
pipeline.DocumentProcessed += OnDocumentProcessed;
}
/// <inheritdoc/>
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) { }
private static void OnDocumentProcessed(MarkdownDocument document)
{
foreach (MarkdownObject node in document.Descendants())
{
if (node is not LinkInline link)
{
continue;
}
string? url = link.Url;
if (string.IsNullOrEmpty(url))
{
continue;
}
const string oldExtension = "md";
const string newExtension = "html";
// we only want to modify relative paths linking to other .md files
if (url.StartsWith('.') && url.EndsWith($".{oldExtension}", StringComparison.InvariantCultureIgnoreCase))
{
link.Url = string.Create(url.Length + (newExtension.Length - oldExtension.Length), url, static (chars, source) =>
{
source.AsSpan()[..(source.Length - (newExtension.Length - oldExtension.Length))].CopyTo(chars);
newExtension.AsSpan().CopyTo(chars[^newExtension.Length..]);
});
}
}
}
}
Also some feedback on the implementation would be appreciated, because I'm sure this is far from ideal 😅
Yes, this is what I do for example in a static website generator here but the resolution is specific to my case (e.g. central place to resolve all links...etc.)
But it could be of some use in simple scenarios. PR welcome. 🙂