""" # Summary MkDocs plugin that fixes cross-kind relative links in generated wikis. A repository served under ``///`` (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 ``//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 ``///`` 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 )