1
from functools import lru_cache
2
from pathlib import Path
3
from typing import Any, List, Union
6
from mkdocs.config.defaults import MkDocsConfig
7
from mkdocs.structure.files import File, Files
8
from mkdocs.structure.nav import Link, Navigation, Section
9
from mkdocs.structure.pages import Page
11
non_traslated_sections = [
18
def get_missing_translation_content(docs_dir: str) -> str:
19
docs_dir_path = Path(docs_dir)
20
missing_translation_path = docs_dir_path.parent.parent / "missing-translation.md"
21
return missing_translation_path.read_text(encoding="utf-8")
25
def get_mkdocs_material_langs() -> List[str]:
26
material_path = Path(material.__file__).parent
27
material_langs_path = material_path / "templates" / "partials" / "languages"
28
langs = [file.stem for file in material_langs_path.glob("*.html")]
36
def on_config(config: MkDocsConfig, **kwargs: Any) -> MkDocsConfig:
37
available_langs = get_mkdocs_material_langs()
38
dir_path = Path(config.docs_dir)
39
lang = dir_path.parent.name
40
if lang in available_langs:
41
config.theme["language"] = lang
42
if not (config.site_url or "").endswith(f"{lang}/") and not lang == "en":
43
config.site_url = f"{config.site_url}{lang}/"
47
def resolve_file(*, item: str, files: Files, config: MkDocsConfig) -> None:
48
item_path = Path(config.docs_dir) / item
49
if not item_path.is_file():
50
en_src_dir = (Path(config.docs_dir) / "../../en/docs").resolve()
51
potential_path = en_src_dir / item
52
if potential_path.is_file():
56
src_dir=str(en_src_dir),
57
dest_dir=config.site_dir,
58
use_directory_urls=config.use_directory_urls,
63
def resolve_files(*, items: List[Any], files: Files, config: MkDocsConfig) -> None:
65
if isinstance(item, str):
66
resolve_file(item=item, files=files, config=config)
67
elif isinstance(item, dict):
69
values = list(item.values())
72
if isinstance(values[0], str):
73
resolve_file(item=values[0], files=files, config=config)
74
elif isinstance(values[0], list):
75
resolve_files(items=values[0], files=files, config=config)
77
raise ValueError(f"Unexpected value: {values}")
80
def on_files(files: Files, *, config: MkDocsConfig) -> Files:
81
resolve_files(items=config.nav or [], files=files, config=config)
82
if "logo" in config.theme:
83
resolve_file(item=config.theme["logo"], files=files, config=config)
84
if "favicon" in config.theme:
85
resolve_file(item=config.theme["favicon"], files=files, config=config)
86
resolve_files(items=config.extra_css, files=files, config=config)
87
resolve_files(items=config.extra_javascript, files=files, config=config)
91
def generate_renamed_section_items(
92
items: List[Union[Page, Section, Link]], *, config: MkDocsConfig
93
) -> List[Union[Page, Section, Link]]:
94
new_items: List[Union[Page, Section, Link]] = []
96
if isinstance(item, Section):
97
new_title = item.title
98
new_children = generate_renamed_section_items(item.children, config=config)
99
first_child = new_children[0]
100
if isinstance(first_child, Page):
101
if first_child.file.src_path.endswith("index.md"):
102
# Read the source so that the title is parsed and available
103
first_child.read_source(config=config)
104
new_title = first_child.title or new_title
105
# Creating a new section makes it render it collapsed by default
106
# no idea why, so, let's just modify the existing one
107
# new_section = Section(title=new_title, children=new_children)
108
item.title = new_title
109
item.children = new_children
110
new_items.append(item)
112
new_items.append(item)
117
nav: Navigation, *, config: MkDocsConfig, files: Files, **kwargs: Any
119
new_items = generate_renamed_section_items(nav.items, config=config)
120
return Navigation(items=new_items, pages=nav.pages)
123
def on_pre_page(page: Page, *, config: MkDocsConfig, files: Files) -> Page:
128
markdown: str, *, page: Page, config: MkDocsConfig, files: Files
130
if isinstance(page.file, EnFile):
131
for excluded_section in non_traslated_sections:
132
if page.file.src_path.startswith(excluded_section):
134
missing_translation_content = get_missing_translation_content(config.docs_dir)
137
if markdown.startswith("#"):
138
header, _, body = markdown.partition("\n\n")
139
return f"{header}\n\n{missing_translation_content}\n\n{body}"