All checks were successful
continuous-integration/drone/tag Build is passing
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.
73 lines
2.4 KiB
Python
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
|
|
)
|