fix(mkdocs): rebase cross-kind wiki links under directory URLs
All checks were successful
continuous-integration/drone/tag Build is passing
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.
This commit is contained in:
72
docforge/mkdocs_links.py
Normal file
72
docforge/mkdocs_links.py
Normal file
@@ -0,0 +1,72 @@
|
||||
"""
|
||||
# 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
|
||||
)
|
||||
Reference in New Issue
Block a user