Skip to content

Commit 2f24e2e

Browse files
NetdocsCopilot
andcommitted
fix(links): decode percent-encoding when resolving markdown links
Hand-written `.md` links sometimes URL-encode spaces (e.g. `../My%20Page.md`). The link rewriter keyed the link map on raw relative paths (literal spaces), so encoded links failed the lookup and were left pointing at a non-existent `.md` URL. Decode the link path with Uri.UnescapeDataString before normalizing so both literal-space and `%20`-encoded links resolve to the correct (optionally slugified) target. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 45f5701 commit 2f24e2e

2 files changed

Lines changed: 30 additions & 0 deletions

File tree

src/Netdocs.Core/Markdown/DocumentRenderer.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ private void RewriteMarkdownLinks(MarkdownDocument document, string currentRelat
111111
!path.EndsWith(".markdown", StringComparison.OrdinalIgnoreCase))
112112
return null;
113113

114+
// Decode percent-encoding (e.g. hand-written `%20` for spaces) so the link path
115+
// matches the raw relative paths used as map keys.
116+
path = Uri.UnescapeDataString(path);
117+
114118
var currentDir = Path.GetDirectoryName(currentRelativePath.Replace('\\', '/'))?.Replace('\\', '/') ?? "";
115119
var combined = currentDir.Length == 0 ? path : currentDir + "/" + path;
116120
var normalized = NormalizeRelative(combined);

tests/Netdocs.Core.Tests/CoreTests.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,4 +368,30 @@ public void MarkdownLinks_AreRewrittenRelativeToPage_ForBasePathSafety()
368368
Assert.Contains("href=\"../getting-started/quickstart/\"", nested.HtmlContent);
369369
Assert.DoesNotContain("href=\"/reference/cli/\"", nested.HtmlContent);
370370
}
371+
372+
[Fact]
373+
public void MarkdownLinks_WithPercentEncodedSpaces_ResolveToSlugifiedTarget()
374+
{
375+
// A hand-written `.md` link may URL-encode spaces (`%20`). The rewriter must decode
376+
// it so it matches the raw relative path used as the link-map key, and rewrite it to
377+
// the (possibly slugified) target URL.
378+
var site = new SiteContext { Config = new SiteConfig(), Options = new BuildOptions(), LoggerFactory = NullLoggerFactory.Instance };
379+
var pipeline = MarkdownPipelineFactory.Build(site, []);
380+
var map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
381+
{
382+
["cluster/Openshift Registry Setup.md"] = "cluster/openshift-registry-setup/",
383+
};
384+
385+
var page = new Page
386+
{
387+
SourcePath = "cluster/deploy/index.md",
388+
RelativePath = "cluster/deploy/index.md",
389+
Url = "cluster/deploy/",
390+
ProcessedMarkdown = "See [reg](../Openshift%20Registry%20Setup.md).",
391+
};
392+
new DocumentRenderer(pipeline, map).Render(page);
393+
394+
Assert.Contains("href=\"../../cluster/openshift-registry-setup/\"", page.HtmlContent);
395+
Assert.DoesNotContain("%20", page.HtmlContent);
396+
}
371397
}

0 commit comments

Comments
 (0)