Guide / HTML destinations
URL resolution
URL resolution runs while rendering HTML, after parsing, and never mutates the AST.
Resolve against a base URL
The base URI resolver follows RFC 3986 path resolution and leaves destinations with a scheme unchanged.
Base URL resolution
import io.heapy.kotmark.renderer.html.BaseUriUrlResolver
import io.heapy.kotmark.renderer.html.htmlRenderer
val baseUrlRenderer = htmlRenderer {
urlResolver = BaseUriUrlResolver(
baseUri = "https://example.org/docs/guide/",
resolveLocalAnchors = false,
)
sanitizeUrls = true
percentEncodeUrls = true
}
// ../images/example.png -> https://example.org/docs/images/example.pngINPUT · Markdown
 [Top](#top)OUTPUT · HTML
<p><img src="https://example.org/docs/images/example.png" alt="Example" /> <a rel="nofollow" href="#top">Top</a></p>Route links in your application
Implement UrlResolver to map Markdown destinations to application routes or to use another host for images.
Custom routing
import io.heapy.kotmark.node.Image
import io.heapy.kotmark.renderer.html.BaseUriUrlResolver
import io.heapy.kotmark.renderer.html.UrlResolver
import io.heapy.kotmark.renderer.html.htmlRenderer
val pages = BaseUriUrlResolver("https://example.org/docs/")
val images = BaseUriUrlResolver("https://cdn.example.org/assets/")
val routingRenderer = htmlRenderer {
urlResolver = UrlResolver { node, destination ->
if (node is Image) {
images.resolveUrl(node, destination)
} else {
val page = if (destination.endsWith(".md")) destination.removeSuffix(".md") + ".html" else destination
pages.resolveUrl(node, page)
}
}
}INPUT · Markdown
[Guide](guide.md) OUTPUT · HTML
<p><a href="https://example.org/docs/guide.html">Guide</a> <img src="https://cdn.example.org/assets/logo.png" alt="Logo" /></p>Processing order
Core links, reference links, autolinks, and images go through resolve, optional sanitize, optional percent-encode, then HTML attribute escaping.
- Raw HTML is not affected.
- A fragment-only destination remains local by default.
- With
urlResolver = null, rendering is unchanged.