Files
doc-forge/docforge/mkdocs_links.py
Vishesh 'ironeagle' Bangotra 09118115a4
All checks were successful
continuous-integration/drone/tag Build is passing
fix(mkdocs): rebase cross-kind wiki links under directory URLs
Wiki pages linking to a sibling kind (for example ../lib/...) were emitted verbatim by MkDocs and, with use_directory_urls, resolved into a non-existent <kind>/<kind>/ path. Add a docforge-linkfix plugin (doc-forge 0.0.8) that rebases those links to the repository root.
2026-10-17 17:22:23 +05:30

73 lines
2.4 KiB
Python

"""
# Summary
MkDocs plugin that fixes cross-kind relative links in generated wikis.
A repository served under ``/<repo>/<kind>/`` (for example a wiki at
``/myrepo/wiki/`` and a library reference at ``/myrepo/lib/``) is built as
two independent MkDocs sites. Authors naturally write links between them
using source-relative paths such as ``../lib/01_build_recipe/``.
MkDocs only rewrites links whose target lives inside ``docs_dir``; anything
pointing at a sibling site is emitted verbatim. When ``use_directory_urls``
is enabled (the default) the rendered page sits one or more directory levels
deeper than its source, so ``../lib/`` resolves to ``/<repo>/wiki/lib/`` and
breaks.
`docforge-linkfix` rewrites such links at render time, prefixing them with
enough ``../`` segments to climb back to the repository root so they resolve
to ``/<repo>/<kind>/`` regardless of how deeply the page is nested.
"""
from __future__ import annotations
import re
from typing import TYPE_CHECKING
from mkdocs.plugins import BasePlugin
if TYPE_CHECKING:
from mkdocs.config.defaults import MkDocsConfig
from mkdocs.structure.files import Files
from mkdocs.structure.pages import Page
__all__ = ["LinkFixPlugin"]
_CROSS_KIND_LINK = re.compile(r"\]\((?:\.\./)+(lib|api|wiki)/")
"""Matches a Markdown link whose target climbs out of the current doc kind."""
class LinkFixPlugin(BasePlugin): # type: ignore[no-untyped-call, type-arg]
"""
Rewrite cross-kind relative links so they survive directory URLs.
"""
def on_page_markdown(
self,
markdown: str,
/,
*,
page: Page,
config: MkDocsConfig,
files: Files,
) -> str:
"""
Prefix cross-kind links with the depth required to reach the repo root.
Args:
markdown (str): The raw Markdown source of the current page.
page (Page): The page being rendered; its destination URI is used
to determine how many directory levels the output sits below
the site root.
config (MkDocsConfig): The active MkDocs configuration.
files (Files): The collection of files in the site.
Returns:
str: The Markdown with cross-kind links rebased to the repo root.
"""
depth = page.file.dest_uri.count("/")
prefix = "../" * (depth + 1)
return _CROSS_KIND_LINK.sub(
lambda match: f"]({prefix}{match.group(1)}/", markdown
)