mirror of
https://github.com/squidfunk/mkdocs-material.git
synced 2024-06-14 11:52:32 +03:00
Added hook to automatically compute and update translations
This commit is contained in:
parent
663b39fb10
commit
d32ca846f1
@ -29,78 +29,23 @@ theme:
|
||||
|
||||
The following languages are supported:
|
||||
|
||||
<div class="mdx-columns" markdown>
|
||||
|
||||
- `af` – Afrikaans
|
||||
- `ar` – Arabic
|
||||
- `bg` – Bulgarian
|
||||
- `bn` – Bengali (Bangla)
|
||||
- `ca` – Catalan
|
||||
- `cs` – Czech
|
||||
- `da` – Danish
|
||||
- `de` – German
|
||||
- `el` – Greek
|
||||
- `en` – English
|
||||
- `eo` – Esperanto
|
||||
- `es` – Spanish
|
||||
- `et` – Estonian
|
||||
- `fa` – Persian (Farsi)
|
||||
- `fi` – Finnish
|
||||
- `fr` – French
|
||||
- `gl` – Galician
|
||||
- `he` – Hebrew
|
||||
- `hi` – Hindi
|
||||
- `hr` – Croatian
|
||||
- `hu` – Hungarian
|
||||
- `hy` – Armenian
|
||||
- `id` – Indonesian
|
||||
- `is` – Icelandic
|
||||
- `it` – Italian
|
||||
- `ja` – Japanese
|
||||
- `ka` – Georgian
|
||||
- `ko` – Korean
|
||||
- `lt` – Lithuanian
|
||||
- `lv` – Latvian
|
||||
- `mk` – Macedonian
|
||||
- `mn` – Mongolian
|
||||
- `ms` – Bahasa Malaysia
|
||||
- `my` – Burmese
|
||||
- `nl` – Dutch
|
||||
- `nb` – Norwegian (Bokmål)
|
||||
- `nn` – Norwegian (Nynorsk)
|
||||
- `pl` – Polish
|
||||
- `pt` – Portuguese
|
||||
- `pt-BR` – Portuguese (Brasilian)
|
||||
- `ro` – Romanian
|
||||
- `ru` – Russian
|
||||
- `sh` – Serbo-Croatian
|
||||
- `si` – Sinhalese
|
||||
- `sk` – Slovak
|
||||
- `sl` – Slovenian
|
||||
- `sr` – Serbian
|
||||
- `sv` – Swedish
|
||||
- `th` – Thai
|
||||
- `tl` – Tagalog
|
||||
- `tr` – Turkish
|
||||
- `uk` – Ukrainian
|
||||
- `ur` – Urdu
|
||||
- `uz` – Uzbek
|
||||
- `vi` – Vietnamese
|
||||
- `zh` – Chinese (Simplified)
|
||||
- `zh-Hant` – Chinese (Traditional)
|
||||
- `zh-TW` – Chinese (Taiwanese)
|
||||
- [Add language]
|
||||
|
||||
</div>
|
||||
<!-- hooks/translations.py -->
|
||||
|
||||
Note that some languages will produce unreadable anchor links due to the way
|
||||
the default slug function works. Consider using a [Unicode-aware slug function].
|
||||
|
||||
!!! tip "Translations missing? Help us out, it takes only 5 minutes"
|
||||
|
||||
Material for MkDocs relies on outside contributions for adding and updating
|
||||
translations for the almost 60 languages it supports. If your language shows
|
||||
that some translations are missing, click on the link to add them. If your
|
||||
language is not in the list, click here to [add a new language].
|
||||
|
||||
[Site language support]: https://github.com/squidfunk/mkdocs-material/releases/tag/1.12.0
|
||||
[single language per document]: https://www.w3.org/International/questions/qa-html-language-declarations.en#attributes
|
||||
[language selector]: #site-language-selector
|
||||
[Unicode-aware slug function]: extensions/python-markdown.md#toc-slugify
|
||||
[Add language]: https://github.com/squidfunk/mkdocs-material/issues/new?template=translate.yml&title=New+language%3A+%7Breplace+with+language+name%7D
|
||||
[add a new language]: https://github.com/squidfunk/mkdocs-material/issues/new?template=translate.yml&title=Add+translations+for+...
|
||||
|
||||
### Site language selector
|
||||
|
||||
|
1
material/.overrides/assets/stylesheets/custom.75ba462f.min.css
vendored
Normal file
1
material/.overrides/assets/stylesheets/custom.75ba462f.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
{"version":3,"sources":["src/.overrides/assets/stylesheets/custom/_typeset.scss","../../../../src/.overrides/assets/stylesheets/custom.scss","src/assets/stylesheets/utilities/_break.scss","src/.overrides/assets/stylesheets/custom/layout/_banner.scss","src/.overrides/assets/stylesheets/custom/layout/_hero.scss","src/.overrides/assets/stylesheets/custom/layout/_iconsearch.scss","src/.overrides/assets/stylesheets/custom/layout/_sponsorship.scss"],"names":[],"mappings":"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","file":"custom.css"}
|
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
{"version":3,"sources":["src/.overrides/assets/stylesheets/custom/_typeset.scss","../../../../src/.overrides/assets/stylesheets/custom.scss","src/assets/stylesheets/utilities/_break.scss","src/.overrides/assets/stylesheets/custom/layout/_banner.scss","src/.overrides/assets/stylesheets/custom/layout/_hero.scss","src/.overrides/assets/stylesheets/custom/layout/_iconsearch.scss","src/.overrides/assets/stylesheets/custom/layout/_sponsorship.scss"],"names":[],"mappings":"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","file":"custom.css"}
|
32
material/.overrides/hooks/translations.html
Normal file
32
material/.overrides/hooks/translations.html
Normal file
@ -0,0 +1,32 @@
|
||||
{#-
|
||||
This file was automatically generated - do not edit
|
||||
-#}
|
||||
{% macro render_language(language) %}
|
||||
<div class="mdx-flags__item" markdown>
|
||||
:flag_{{ language.flag }}:{ .lg .middle }
|
||||
<span class="mdx-flags__content">
|
||||
<span>
|
||||
<strong>{{ language.name }}</strong>
|
||||
<code>{{ language.code }}</code>
|
||||
</span>
|
||||
{% if language.miss %}
|
||||
<span>
|
||||
<a href="{{ language.link }}">
|
||||
{{ language.miss | length }} translations missing
|
||||
</a>
|
||||
</span>
|
||||
{% else %}
|
||||
<small>Complete</small>
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
{% macro render(translations, start = 1) %}
|
||||
<div class="mdx-columns mdx-flags" markdown>
|
||||
<ol markdown>
|
||||
{% for language in translations %}
|
||||
<li markdown>{{ render_language(language) }}</li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
</div>
|
||||
{% endmacro %}
|
185
material/.overrides/hooks/translations.py
Normal file
185
material/.overrides/hooks/translations.py
Normal file
@ -0,0 +1,185 @@
|
||||
# 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(
|
||||
r"^ \"([^\"]+)\": \"([^\"]+)\"(?:,|$)?", data,
|
||||
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({
|
||||
"template": "translate.yml",
|
||||
"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",
|
||||
"ko": "kr",
|
||||
"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",
|
||||
"sh": "rs",
|
||||
"si": "lk",
|
||||
"sk": "sk",
|
||||
"sl": "si",
|
||||
"sr": "rs",
|
||||
"sv": "se",
|
||||
"th": "th",
|
||||
"tl": "ph",
|
||||
"tr": "tr",
|
||||
"uk": "ua",
|
||||
"ur": "pk",
|
||||
"uz": "uz",
|
||||
"vi": "vn",
|
||||
"zh": "cn",
|
||||
"zh-Hant": "cn",
|
||||
"zh-TW": "tw"
|
||||
})
|
@ -3,7 +3,7 @@
|
||||
-#}
|
||||
{% extends "base.html" %}
|
||||
{% block extrahead %}
|
||||
<link rel="stylesheet" href="{{ 'assets/stylesheets/custom.9097afc2.min.css' | url }}">
|
||||
<link rel="stylesheet" href="{{ 'assets/stylesheets/custom.75ba462f.min.css' | url }}">
|
||||
{% endblock %}
|
||||
{% block announce %}
|
||||
<a href="https://twitter.com/squidfunk">
|
||||
|
@ -88,6 +88,10 @@ plugins:
|
||||
- minify:
|
||||
minify_html: true
|
||||
|
||||
# Hooks
|
||||
hooks:
|
||||
- material/.overrides/hooks/translations.py
|
||||
|
||||
# Customization
|
||||
extra:
|
||||
analytics:
|
||||
|
@ -134,6 +134,51 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Language list
|
||||
.mdx-flags {
|
||||
margin: 2em auto;
|
||||
|
||||
// Language list
|
||||
ol {
|
||||
list-style: none;
|
||||
|
||||
// Language list item
|
||||
li {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
// Language item
|
||||
&__item {
|
||||
display: flex;
|
||||
gap: px2rem(12px);
|
||||
}
|
||||
|
||||
// Language content
|
||||
&__content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
|
||||
// Language name
|
||||
span {
|
||||
display: inline-flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
// Language link
|
||||
> span:nth-child(2) {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
// Language code
|
||||
code {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Blog author
|
||||
.mdx-author {
|
||||
display: flex;
|
||||
|
54
src/.overrides/hooks/translations.html
Normal file
54
src/.overrides/hooks/translations.html
Normal file
@ -0,0 +1,54 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<!-- Render translation language -->
|
||||
{% macro render_language(language) %}
|
||||
<div class="mdx-flags__item" markdown>
|
||||
:flag_{{ language.flag }}:{ .lg .middle }
|
||||
<span class="mdx-flags__content">
|
||||
<span>
|
||||
<strong>{{ language.name }}</strong>
|
||||
<code>{{ language.code }}</code>
|
||||
</span>
|
||||
{% if language.miss %}
|
||||
<span>
|
||||
<a href="{{ language.link }}">
|
||||
{{ language.miss | length }} translations missing
|
||||
</a>
|
||||
</span>
|
||||
{% else %}
|
||||
<small>Complete</small>
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
<!-- Render translations -->
|
||||
{% macro render(translations, start = 1) %}
|
||||
<div class="mdx-columns mdx-flags" markdown>
|
||||
<ol markdown>
|
||||
{% for language in translations %}
|
||||
<li markdown>{{ render_language(language) }}</li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
</div>
|
||||
{% endmacro %}
|
185
src/.overrides/hooks/translations.py
Normal file
185
src/.overrides/hooks/translations.py
Normal file
@ -0,0 +1,185 @@
|
||||
# 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(
|
||||
r"^ \"([^\"]+)\": \"([^\"]+)\"(?:,|$)?", data,
|
||||
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({
|
||||
"template": "translate.yml",
|
||||
"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",
|
||||
"ko": "kr",
|
||||
"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",
|
||||
"sh": "rs",
|
||||
"si": "lk",
|
||||
"sk": "sk",
|
||||
"sl": "si",
|
||||
"sr": "rs",
|
||||
"sv": "se",
|
||||
"th": "th",
|
||||
"tl": "ph",
|
||||
"tr": "tr",
|
||||
"uk": "ua",
|
||||
"ur": "pk",
|
||||
"uz": "uz",
|
||||
"vi": "vn",
|
||||
"zh": "cn",
|
||||
"zh-Hant": "cn",
|
||||
"zh-TW": "tw"
|
||||
})
|
Loading…
Reference in New Issue
Block a user