forked from fastapi/fastapi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mkdocs_hooks.py
132 lines (109 loc) · 4.87 KB
/
mkdocs_hooks.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
from functools import lru_cache
from pathlib import Path
from typing import Any, List, Union
import material
from mkdocs.config.defaults import MkDocsConfig
from mkdocs.structure.files import File, Files
from mkdocs.structure.nav import Link, Navigation, Section
from mkdocs.structure.pages import Page
@lru_cache()
def get_missing_translation_content(docs_dir: str) -> str:
docs_dir_path = Path(docs_dir)
missing_translation_path = docs_dir_path.parent.parent / "missing-translation.md"
return missing_translation_path.read_text(encoding="utf-8")
@lru_cache()
def get_mkdocs_material_langs() -> List[str]:
material_path = Path(material.__file__).parent
material_langs_path = material_path / "partials" / "languages"
langs = [file.stem for file in material_langs_path.glob("*.html")]
return langs
class EnFile(File):
pass
def on_config(config: MkDocsConfig, **kwargs: Any) -> MkDocsConfig:
available_langs = get_mkdocs_material_langs()
dir_path = Path(config.docs_dir)
lang = dir_path.parent.name
if lang in available_langs:
config.theme["language"] = lang
if not (config.site_url or "").endswith(f"{lang}/") and not lang == "en":
config.site_url = f"{config.site_url}{lang}/"
return config
def resolve_file(*, item: str, files: Files, config: MkDocsConfig) -> None:
item_path = Path(config.docs_dir) / item
if not item_path.is_file():
en_src_dir = (Path(config.docs_dir) / "../../en/docs").resolve()
potential_path = en_src_dir / item
if potential_path.is_file():
files.append(
EnFile(
path=item,
src_dir=str(en_src_dir),
dest_dir=config.site_dir,
use_directory_urls=config.use_directory_urls,
)
)
def resolve_files(*, items: List[Any], files: Files, config: MkDocsConfig) -> None:
for item in items:
if isinstance(item, str):
resolve_file(item=item, files=files, config=config)
elif isinstance(item, dict):
assert len(item) == 1
values = list(item.values())
if not values:
continue
if isinstance(values[0], str):
resolve_file(item=values[0], files=files, config=config)
elif isinstance(values[0], list):
resolve_files(items=values[0], files=files, config=config)
else:
raise ValueError(f"Unexpected value: {values}")
def on_files(files: Files, *, config: MkDocsConfig) -> Files:
resolve_files(items=config.nav or [], files=files, config=config)
if "logo" in config.theme:
resolve_file(item=config.theme["logo"], files=files, config=config)
if "favicon" in config.theme:
resolve_file(item=config.theme["favicon"], files=files, config=config)
resolve_files(items=config.extra_css, files=files, config=config)
resolve_files(items=config.extra_javascript, files=files, config=config)
return files
def generate_renamed_section_items(
items: List[Union[Page, Section, Link]], *, config: MkDocsConfig
) -> List[Union[Page, Section, Link]]:
new_items: List[Union[Page, Section, Link]] = []
for item in items:
if isinstance(item, Section):
new_title = item.title
new_children = generate_renamed_section_items(item.children, config=config)
first_child = new_children[0]
if isinstance(first_child, Page):
if first_child.file.src_path.endswith("index.md"):
# Read the source so that the title is parsed and available
first_child.read_source(config=config)
new_title = first_child.title or new_title
# Creating a new section makes it render it collapsed by default
# no idea why, so, let's just modify the existing one
# new_section = Section(title=new_title, children=new_children)
item.title = new_title
item.children = new_children
new_items.append(item)
else:
new_items.append(item)
return new_items
def on_nav(
nav: Navigation, *, config: MkDocsConfig, files: Files, **kwargs: Any
) -> Navigation:
new_items = generate_renamed_section_items(nav.items, config=config)
return Navigation(items=new_items, pages=nav.pages)
def on_pre_page(page: Page, *, config: MkDocsConfig, files: Files) -> Page:
return page
def on_page_markdown(
markdown: str, *, page: Page, config: MkDocsConfig, files: Files
) -> str:
if isinstance(page.file, EnFile):
missing_translation_content = get_missing_translation_content(config.docs_dir)
header = ""
body = markdown
if markdown.startswith("#"):
header, _, body = markdown.partition("\n\n")
return f"{header}\n\n{missing_translation_content}\n\n{body}"
return markdown