diff --git a/scripts/test-website.py b/scripts/test-website.py index 5c1aef876e..df4790702b 100644 --- a/scripts/test-website.py +++ b/scripts/test-website.py @@ -15,7 +15,7 @@ from urllib.request import urlopen import xml.etree.ElementTree as ET import polib -from website_i18n import Document, build_translations, checked_catalog, extract_catalogs, languages, reading_pages, read_runtime +from website_i18n import Document, build_translations, checked_catalog, extract_catalogs, is_language_code, languages, reading_pages, read_runtime ROOT = Path(__file__).resolve().parent.parent @@ -252,6 +252,19 @@ class WebsiteMaintenanceChecks(unittest.TestCase): class WebsiteTranslationChecks(unittest.TestCase): """Exercise source edits, translated evidence and language editions at their consumers.""" + def test_script_subtags_preserve_the_hinglish_edition(self): + for code in ("en", "zh-CN", "hi-Latn", "hi-Latn-IN"): + with self.subTest(code=code): + self.assertTrue(is_language_code(code)) + for code in ("hi-latn", "hi-LATN", "hi-IN-Latn", "hi/Latn"): + with self.subTest(code=code): + self.assertFalse(is_language_code(code)) + hinglish = next(item for item in languages(ROOT) if item["readme"] == "README_hi-Latn.md") + self.assertEqual(hinglish["code"], "hi-Latn") + catalog = polib.pofile(ROOT / "website/locales/hi-Latn/messages.po") + self.assertEqual(catalog.metadata["Language"], "hi-Latn") + self.assertFalse((ROOT / "website/locales/hi/messages.po").exists()) + @contextlib.contextmanager def translated_project(self): with tempfile.TemporaryDirectory() as directory: diff --git a/scripts/verify-website.py b/scripts/verify-website.py index 10af305dcd..58d9ee9e5c 100644 --- a/scripts/verify-website.py +++ b/scripts/verify-website.py @@ -11,6 +11,7 @@ import xml.etree.ElementTree as ET from zipfile import BadZipFile, ZipFile from website import NOTES_FIXTURES, SITE_ORIGIN, authored_markdown, page_url, sync_pages +from website_i18n import is_language_code LEGACY_ORIGIN = "morluto.github.io" SITE_TEXT_URL = re.compile( @@ -179,7 +180,7 @@ def check_search_metadata(site, pages): if not title: errors.append(f"{label}: needs exactly one nonempty head title") first = path.relative_to(site).parts[0] - expected_language = first if re.fullmatch(r"[a-z]{2}(?:-[A-Z]{2})?", first) else "en" + expected_language = first if is_language_code(first) else "en" if page.translation_fallback: if page.lang != "en" or not page.noindex(): errors.append(f"{label}: English translation fallback needs lang=en and noindex") diff --git a/scripts/website_i18n.py b/scripts/website_i18n.py index 928594df76..082f75a23f 100644 --- a/scripts/website_i18n.py +++ b/scripts/website_i18n.py @@ -25,6 +25,14 @@ LITERALS = {"REA", "Reverse Engineer Anything", "REA · Reverse Engineer Anythin FALLBACK_NOTICE = "Translation is being updated. Read this page in English for now." +LANGUAGE_CODE = re.compile(r"[a-z]{2}(?:-[A-Z][a-z]{3})?(?:-[A-Z]{2})?") + + +def is_language_code(value): + """Recognize canonical language, optional script and region inventory codes.""" + return LANGUAGE_CODE.fullmatch(value) is not None + + def languages(root): """Load the website language inventory and check it against README editions.""" path = root / "website/locales/languages.json" @@ -41,7 +49,7 @@ def languages(root): raise ValueError("Each language needs code, name, readme and dir") if not all(isinstance(value, str) and value for value in item.values()): raise ValueError("Language fields must be nonempty strings") - if not re.fullmatch(r"[a-z]{2}(?:-[A-Z]{2})?", item["code"]) or item["code"] in codes: + if not is_language_code(item["code"]) or item["code"] in codes: raise ValueError(f"Invalid or duplicate language: {item['code']}") if item["dir"] not in ("ltr", "rtl"): raise ValueError(f"Invalid text direction: {item['code']}") diff --git a/website/locales/hi/messages.po b/website/locales/hi-Latn/messages.po similarity index 99% rename from website/locales/hi/messages.po rename to website/locales/hi-Latn/messages.po index 88f0337568..15c7c552f3 100644 --- a/website/locales/hi/messages.po +++ b/website/locales/hi-Latn/messages.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: REA website\n" -"Language: hi\n" +"Language: hi-Latn\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/website/locales/languages.json b/website/locales/languages.json index 31ab11f981..0fdb902d2b 100644 --- a/website/locales/languages.json +++ b/website/locales/languages.json @@ -49,7 +49,7 @@ }, { "code": "it", "name": "Italiano", "readme": "README_it.md", "dir": "ltr" }, { - "code": "hi", + "code": "hi-Latn", "name": "Hinglish", "readme": "README_hi-Latn.md", "dir": "ltr" diff --git a/website/public/blog/index.html b/website/public/blog/index.html index a1a2428b0e..bb3dd9bf65 100644 --- a/website/public/blog/index.html +++ b/website/public/blog/index.html @@ -51,7 +51,7 @@ - + @@ -119,7 +119,7 @@ FAQ
-
English
+
English