Skip to content

Feature-request: Transform relative file links #897

@Abrynos

Description

@Abrynos

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..]);
                });
            }
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions