mirror of
https://github.com/openmlsys/openmlsys-zh.git
synced 2026-04-01 01:41:17 +08:00
feat: add homepage language switch links
Inject a homepage-only language switch into the mdBook frontpage wrapper so the English homepage links to the Chinese homepage and the Chinese homepage links back to the English homepage.
This commit is contained in:
@@ -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(
|
||||
"<div class=\"hero\">frontpage</div>\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(">中文</a>", 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()
|
||||
|
||||
@@ -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</a>", rewritten)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"<style>{' '.join(parts)}</style>"
|
||||
|
||||
|
||||
def wrap_frontpage_html(html: str) -> str:
|
||||
return "\n".join([FRONTPAGE_LAYOUT_CSS, '<div class="openmlsys-frontpage">', html.strip(), "</div>"])
|
||||
def render_frontpage_switch(label: str, href: str) -> str:
|
||||
return f'<a class="openmlsys-frontpage-switch" href="{href}">{label}</a>'
|
||||
|
||||
|
||||
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, '<div class="openmlsys-frontpage">']
|
||||
if frontpage_switch_label and frontpage_switch_href:
|
||||
parts.append(render_frontpage_switch(frontpage_switch_label, frontpage_switch_href))
|
||||
parts.extend([html.strip(), "</div>"])
|
||||
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("")
|
||||
|
||||
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user