2023-01-28 22:18:09 +03:00
|
|
|
# Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
|
|
|
|
|
|
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
# of this software and associated documentation files (the "Software"), to
|
|
|
|
# deal in the Software without restriction, including without limitation the
|
|
|
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
|
|
# sell copies of the Software, and to permit persons to whom the Software is
|
|
|
|
# furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
# The above copyright notice and this permission notice shall be included in
|
|
|
|
# all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
|
|
# IN THE SOFTWARE.
|
|
|
|
|
|
|
|
import os
|
|
|
|
import re
|
|
|
|
|
|
|
|
from glob import glob
|
|
|
|
from mkdocs.config.defaults import MkDocsConfig
|
|
|
|
from mkdocs.structure.pages import Page
|
|
|
|
from urllib.parse import urlencode, urlparse
|
|
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
|
|
# Hooks
|
|
|
|
# -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
# Determine missing translations and render language overview in the setup
|
|
|
|
# guide, including links to provide missing translations.
|
|
|
|
def on_page_markdown(markdown: str, *, page: Page, config: MkDocsConfig, files):
|
|
|
|
issue_url = "https://github.com/squidfunk/mkdocs-material/issues/new"
|
|
|
|
if page.file.src_uri != "setup/changing-the-language.md":
|
|
|
|
return
|
|
|
|
|
|
|
|
# Collect all existing languages
|
|
|
|
names: dict[str, str] = dict()
|
|
|
|
known: dict[str, dict[str, str]] = dict()
|
|
|
|
for path in glob("src/partials/languages/*.html"):
|
|
|
|
with open(path, "r", encoding = "utf-8") as f:
|
|
|
|
data = f.read()
|
|
|
|
|
|
|
|
# Extract language code and name
|
|
|
|
name, = re.findall(r"<!-- Translations: (.+) -->", data)
|
|
|
|
code, _ = os.path.splitext(os.path.basename(path))
|
|
|
|
|
|
|
|
# Map names and available translations
|
|
|
|
names[code] = name
|
|
|
|
known[code] = dict(re.findall(
|
2023-01-30 23:13:55 +03:00
|
|
|
r"^ \"([^\"]+)\": \"([^\"]*)\"(?:,|$)?", data,
|
2023-01-28 22:18:09 +03:00
|
|
|
re.MULTILINE
|
|
|
|
))
|
|
|
|
|
|
|
|
# Remove technical stuff
|
|
|
|
for key in [
|
|
|
|
"direction",
|
|
|
|
"search.config.pipeline",
|
|
|
|
"search.config.lang",
|
|
|
|
"search.config.separator"
|
|
|
|
]:
|
|
|
|
if key in known[code]:
|
|
|
|
del known[code][key]
|
|
|
|
|
|
|
|
# Traverse all languages and compute missing translations
|
|
|
|
languages = []
|
|
|
|
reference = set(known["en"])
|
|
|
|
for code, name in names.items():
|
|
|
|
miss = reference - set(known[code])
|
|
|
|
|
|
|
|
# Check each translations
|
|
|
|
translations: list[str] = []
|
|
|
|
for key, value in known["en"].items():
|
|
|
|
if key in known[code]:
|
|
|
|
translations.append(
|
|
|
|
f" \"{key}\": \"{known[code][key]}\""
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
translations.append(
|
|
|
|
f" \"{key}\": \"{value} ⬅️\""
|
|
|
|
)
|
|
|
|
|
|
|
|
# Assemble GitHub issue URL
|
|
|
|
link = urlparse(issue_url)
|
|
|
|
link = link._replace(query = urlencode({
|
2023-01-29 22:20:36 +03:00
|
|
|
"template": "04-add-a-translation.yml",
|
2023-01-28 22:18:09 +03:00
|
|
|
"title": f"Update {name} translations",
|
|
|
|
"translations": "\n".join([
|
|
|
|
"{% macro t(key) %}{{ {",
|
|
|
|
",\n".join(translations),
|
|
|
|
"}[key] }}{% endmacro %}"
|
|
|
|
])
|
|
|
|
}))
|
|
|
|
|
|
|
|
# Add translation
|
|
|
|
languages.append({
|
|
|
|
"flag": countries[code],
|
|
|
|
"code": code,
|
|
|
|
"name": name,
|
|
|
|
"link": link.geturl(),
|
|
|
|
"miss": miss
|
|
|
|
})
|
|
|
|
|
|
|
|
# Load template and render translations
|
|
|
|
env = config.theme.get_env()
|
|
|
|
template = env.get_template( "hooks/translations.html")
|
|
|
|
translations = template.module.render(
|
|
|
|
sorted(languages, key = lambda language: language["name"])
|
|
|
|
)
|
|
|
|
|
|
|
|
# Replace translation marker
|
|
|
|
return markdown.replace(
|
|
|
|
"<!-- hooks/translations.py -->", "\n".join(
|
|
|
|
[line.lstrip() for line in translations.split("\n")
|
|
|
|
]
|
|
|
|
))
|
|
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
|
|
# Data
|
|
|
|
# -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
# Map ISO 639-1 (languages) to ISO 3166 (countries)
|
|
|
|
countries = dict({
|
|
|
|
"af": "za",
|
|
|
|
"ar": "ae",
|
|
|
|
"bg": "bg",
|
|
|
|
"bn": "bd",
|
|
|
|
"ca": "es",
|
|
|
|
"cs": "cz",
|
|
|
|
"da": "dk",
|
|
|
|
"de": "de",
|
|
|
|
"el": "gr",
|
|
|
|
"en": "us",
|
|
|
|
"eo": "eu",
|
|
|
|
"es": "es",
|
|
|
|
"et": "ee",
|
|
|
|
"fa": "ir",
|
|
|
|
"fi": "fi",
|
|
|
|
"fr": "fr",
|
|
|
|
"gl": "es",
|
|
|
|
"he": "il",
|
|
|
|
"hi": "in",
|
|
|
|
"hr": "hr",
|
|
|
|
"hu": "hu",
|
|
|
|
"hy": "am",
|
|
|
|
"id": "id",
|
|
|
|
"is": "is",
|
|
|
|
"it": "it",
|
|
|
|
"ja": "jp",
|
|
|
|
"ka": "ge",
|
2023-04-29 17:00:54 +03:00
|
|
|
"kn": "in",
|
2023-01-28 22:18:09 +03:00
|
|
|
"ko": "kr",
|
2023-03-11 11:46:55 +03:00
|
|
|
"ku-IQ": "iq",
|
2023-01-28 22:18:09 +03:00
|
|
|
"lt": "lt",
|
|
|
|
"lv": "lv",
|
|
|
|
"mk": "mk",
|
|
|
|
"mn": "mn",
|
|
|
|
"ms": "my",
|
|
|
|
"my": "mm",
|
|
|
|
"nb": "no",
|
|
|
|
"nl": "nl",
|
|
|
|
"nn": "no",
|
|
|
|
"pl": "pl",
|
|
|
|
"pt-BR": "br",
|
|
|
|
"pt": "pt",
|
|
|
|
"ro": "ro",
|
|
|
|
"ru": "ru",
|
2023-04-29 15:30:19 +03:00
|
|
|
"sa": "in",
|
2023-01-28 22:18:09 +03:00
|
|
|
"sh": "rs",
|
|
|
|
"si": "lk",
|
|
|
|
"sk": "sk",
|
|
|
|
"sl": "si",
|
|
|
|
"sr": "rs",
|
|
|
|
"sv": "se",
|
2023-04-29 21:06:24 +03:00
|
|
|
"te": "in",
|
2023-01-28 22:18:09 +03:00
|
|
|
"th": "th",
|
|
|
|
"tl": "ph",
|
|
|
|
"tr": "tr",
|
|
|
|
"uk": "ua",
|
|
|
|
"ur": "pk",
|
|
|
|
"uz": "uz",
|
|
|
|
"vi": "vn",
|
|
|
|
"zh": "cn",
|
|
|
|
"zh-Hant": "cn",
|
|
|
|
"zh-TW": "tw"
|
|
|
|
})
|