diff --git a/tests/test_prepare_mdbook.py b/tests/test_prepare_mdbook.py
index bfce92e..ffcdf1d 100644
--- a/tests/test_prepare_mdbook.py
+++ b/tests/test_prepare_mdbook.py
@@ -109,6 +109,57 @@ Reference :cite:`smith2024`.
self.assertIn("## References", rewritten)
self.assertNotIn("## 参考文献", rewritten)
+ def test_rewrite_markdown_inlines_frontpage_with_language_switch(self) -> None:
+ with tempfile.TemporaryDirectory() as tmpdir:
+ root = Path(tmpdir)
+ source = root / "en_chapters"
+ static_dir = source / "static"
+ static_dir.mkdir(parents=True)
+
+ index = source / "index.md"
+ index.write_text(
+ """# Home
+
+```eval_rst
+.. raw:: html
+ :file: frontpage.html
+```
+""",
+ encoding="utf-8",
+ )
+ (static_dir / "frontpage.html").write_text(
+ "
frontpage
\n",
+ encoding="utf-8",
+ )
+
+ rewritten = rewrite_markdown(
+ index.read_text(encoding="utf-8"),
+ index.resolve(),
+ {index.resolve(): "Home"},
+ frontpage_switch_label="中文",
+ frontpage_switch_href="cn/",
+ )
+
+ self.assertIn('class="openmlsys-frontpage-switch"', rewritten)
+ self.assertIn('href="cn/"', rewritten)
+ self.assertIn(">中文", rewritten)
+
+ def test_regular_page_does_not_render_frontpage_switch(self) -> None:
+ with tempfile.TemporaryDirectory() as tmpdir:
+ root = Path(tmpdir)
+ page = root / "chapter.md"
+ page.write_text("# Chapter\n\nRegular body.\n", encoding="utf-8")
+
+ rewritten = rewrite_markdown(
+ page.read_text(encoding="utf-8"),
+ page.resolve(),
+ {page.resolve(): "Chapter"},
+ frontpage_switch_label="中文",
+ frontpage_switch_href="cn/",
+ )
+
+ self.assertNotIn('openmlsys-frontpage-switch', rewritten)
+
if __name__ == "__main__":
unittest.main()
diff --git a/tests/test_prepare_mdbook_zh.py b/tests/test_prepare_mdbook_zh.py
index 7182438..e6a7e4c 100644
--- a/tests/test_prepare_mdbook_zh.py
+++ b/tests/test_prepare_mdbook_zh.py
@@ -221,6 +221,9 @@ missing
self.assertIn("static/image/logo.png", rewritten)
self.assertIn("static/image/jinxuefeng.png", rewritten)
self.assertIn("console.log('frontpage')", rewritten)
+ self.assertIn('class="openmlsys-frontpage-switch"', rewritten)
+ self.assertIn('href="../"', rewritten)
+ self.assertIn(">English", rewritten)
if __name__ == "__main__":
diff --git a/tools/mdbook_preprocessor.py b/tools/mdbook_preprocessor.py
index 15c4d15..d02f5bb 100644
--- a/tools/mdbook_preprocessor.py
+++ b/tools/mdbook_preprocessor.py
@@ -12,6 +12,8 @@ except ModuleNotFoundError:
PLACEHOLDER_PREFIX = "[TODO: src = zh_chapters/"
BIBLIOGRAPHY_TITLE = "References"
+FRONTPAGE_SWITCH_LABEL = "中文"
+FRONTPAGE_SWITCH_HREF = "cn/"
def iter_chapters(items: list[dict]) -> list[dict]:
@@ -47,6 +49,8 @@ def main() -> int:
title_cache,
bib_db,
bibliography_title=BIBLIOGRAPHY_TITLE,
+ frontpage_switch_label=FRONTPAGE_SWITCH_LABEL,
+ frontpage_switch_href=FRONTPAGE_SWITCH_HREF,
)
json.dump(book, sys.stdout, ensure_ascii=False)
diff --git a/tools/mdbook_zh_preprocessor.py b/tools/mdbook_zh_preprocessor.py
index e58d8d1..3940cda 100644
--- a/tools/mdbook_zh_preprocessor.py
+++ b/tools/mdbook_zh_preprocessor.py
@@ -11,6 +11,8 @@ except ModuleNotFoundError:
BIBLIOGRAPHY_TITLE = "参考文献"
+FRONTPAGE_SWITCH_LABEL = "English"
+FRONTPAGE_SWITCH_HREF = "../"
def iter_chapters(items: list[dict]) -> list[dict]:
@@ -46,6 +48,8 @@ def main() -> int:
title_cache,
bib_db,
bibliography_title=BIBLIOGRAPHY_TITLE,
+ frontpage_switch_label=FRONTPAGE_SWITCH_LABEL,
+ frontpage_switch_href=FRONTPAGE_SWITCH_HREF,
)
json.dump(book, sys.stdout, ensure_ascii=False)
diff --git a/tools/prepare_mdbook.py b/tools/prepare_mdbook.py
index 154bcfb..d094bd4 100644
--- a/tools/prepare_mdbook.py
+++ b/tools/prepare_mdbook.py
@@ -26,6 +26,31 @@ FRONTPAGE_LAYOUT_CSS = """
.openmlsys-frontpage {
width: 100%;
margin: 0 auto 3rem;
+ position: relative;
+}
+.openmlsys-frontpage-switch {
+ position: absolute;
+ top: 20px;
+ right: 20px;
+ z-index: 2;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 88px;
+ padding: 10px 16px;
+ border-radius: 999px;
+ border: 1px solid rgba(11, 107, 203, 0.25);
+ background: rgba(255, 255, 255, 0.92);
+ color: var(--links, #0b6bcb);
+ font-size: 14px;
+ font-weight: 600;
+ text-decoration: none;
+ box-shadow: 0 12px 30px rgba(11, 107, 203, 0.12);
+ backdrop-filter: blur(10px);
+}
+.openmlsys-frontpage-switch:hover {
+ background: #fff;
+ border-color: rgba(11, 107, 203, 0.4);
}
.openmlsys-frontpage .mdl-grid {
display: flex;
@@ -79,6 +104,10 @@ FRONTPAGE_LAYOUT_CSS = """
max-width: 960px;
}
@media (max-width: 1000px) {
+ .openmlsys-frontpage-switch {
+ top: 12px;
+ right: 12px;
+ }
.openmlsys-frontpage .mdl-cell,
.openmlsys-frontpage .mdl-cell--1-col,
.openmlsys-frontpage .mdl-cell--3-col,
@@ -373,11 +402,28 @@ def _minify_style_block(match: re.Match[str]) -> str:
return f""
-def wrap_frontpage_html(html: str) -> str:
- return "\n".join([FRONTPAGE_LAYOUT_CSS, '', html.strip(), "
"])
+def render_frontpage_switch(label: str, href: str) -> str:
+ return f'{label}'
-def inline_raw_html(block_lines: list[str], current_file: Path) -> str | None:
+def wrap_frontpage_html(
+ html: str,
+ frontpage_switch_label: str | None = None,
+ frontpage_switch_href: str | None = None,
+) -> str:
+ parts = [FRONTPAGE_LAYOUT_CSS, '']
+ if frontpage_switch_label and frontpage_switch_href:
+ parts.append(render_frontpage_switch(frontpage_switch_label, frontpage_switch_href))
+ parts.extend([html.strip(), "
"])
+ return "\n".join(parts)
+
+
+def inline_raw_html(
+ block_lines: list[str],
+ current_file: Path,
+ frontpage_switch_label: str | None = None,
+ frontpage_switch_href: str | None = None,
+) -> str | None:
stripped = [line.strip() for line in block_lines if line.strip()]
if not stripped or stripped[0] != ".. raw:: html":
return None
@@ -395,7 +441,11 @@ def inline_raw_html(block_lines: list[str], current_file: Path) -> str | None:
html_path = resolve_raw_html_file(current_file, filename)
html = rewrite_frontpage_assets(html_path.read_text(encoding="utf-8")).strip()
if Path(filename).name == "frontpage.html":
- return wrap_frontpage_html(html)
+ return wrap_frontpage_html(
+ html,
+ frontpage_switch_label=frontpage_switch_label,
+ frontpage_switch_href=frontpage_switch_href,
+ )
return html
@@ -430,6 +480,8 @@ def rewrite_markdown(
title_cache: dict[Path, str],
bib_db: dict[str, dict[str, str]] | None = None,
bibliography_title: str = DEFAULT_BIBLIOGRAPHY_TITLE,
+ frontpage_switch_label: str | None = None,
+ frontpage_switch_href: str | None = None,
) -> str:
output: list[str] = []
lines = markdown.splitlines()
@@ -455,7 +507,12 @@ def rewrite_markdown(
if rendered and output and output[-1] != "":
output.append("")
elif fence == EVAL_RST_FENCE:
- raw_html = inline_raw_html(block_lines, current_file)
+ raw_html = inline_raw_html(
+ block_lines,
+ current_file,
+ frontpage_switch_label=frontpage_switch_label,
+ frontpage_switch_href=frontpage_switch_href,
+ )
if raw_html:
if output and output[-1] != "":
output.append("")
diff --git a/tools/prepare_mdbook_zh.py b/tools/prepare_mdbook_zh.py
index a5e17c5..ec8bac9 100644
--- a/tools/prepare_mdbook_zh.py
+++ b/tools/prepare_mdbook_zh.py
@@ -7,6 +7,7 @@ try:
from tools.prepare_mdbook import (
build_title_cache,
extract_title,
+ inline_raw_html,
parse_bib,
rewrite_markdown,
write_summary,
@@ -15,12 +16,17 @@ except ModuleNotFoundError:
from prepare_mdbook import (
build_title_cache,
extract_title,
+ inline_raw_html,
parse_bib,
rewrite_markdown,
write_summary,
)
+FRONTPAGE_SWITCH_LABEL = "English"
+FRONTPAGE_SWITCH_HREF = "../"
+
+
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Generate mdBook SUMMARY.md for zh_chapters.")
parser.add_argument("--source", type=Path, default=Path("zh_chapters"), help="Source chapter directory")
@@ -40,5 +46,28 @@ def main() -> int:
return 0
+def rewrite_markdown(
+ markdown: str,
+ current_file: Path,
+ title_cache: dict[Path, str],
+ bib_db: dict[str, dict[str, str]] | None = None,
+ bibliography_title: str = "参考文献",
+) -> str:
+ try:
+ from tools.prepare_mdbook import rewrite_markdown as generic_rewrite_markdown
+ except ModuleNotFoundError:
+ from prepare_mdbook import rewrite_markdown as generic_rewrite_markdown
+
+ return generic_rewrite_markdown(
+ markdown,
+ current_file,
+ title_cache,
+ bib_db=bib_db,
+ bibliography_title=bibliography_title,
+ frontpage_switch_label=FRONTPAGE_SWITCH_LABEL,
+ frontpage_switch_href=FRONTPAGE_SWITCH_HREF,
+ )
+
+
if __name__ == "__main__":
raise SystemExit(main())