feat: Add full i18n support to Smart Mind Map plugin
- Consolidated smart_mind_map.py and smart_mind_map_cn.py into a single file. - Added TRANSLATIONS dictionary supporting 18 languages (en-US, ko-KR, fr-FR, es-AR, en-CA, fr-CA, ja-JP, de-DE, zh-HK, it-IT, zh-CN, en-GB, es-MX, id-ID, es-ES, de-AT, en-AU, vi-VN, zh-TW). - Implemented automatic language detection with fallback to browser/local storage. - Added localized date formatting for various locales. - Added explicit support for zh-TW (Traditional Chinese) with correct translations. - Updated HTML/JS templates to use injected translations. - Restored clickable "Markmap" link in the footer for all languages. - Fixed SyntaxWarning in regex strings by properly escaping backslashes in standard strings. - Implemented robust UI translation loading to prevent crashes on missing keys. - Verified frontend rendering with Playwright and backend logic with unit tests. Co-authored-by: Fu-Jie <33599649+Fu-Jie@users.noreply.github.com>
This commit is contained in:
@@ -810,7 +810,7 @@ CONTENT_TEMPLATE_MINDMAP = """
|
|||||||
<script type="text/template" id="markdown-source-{unique_id}">{markdown_syntax}</script>
|
<script type="text/template" id="markdown-source-{unique_id}">{markdown_syntax}</script>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
SCRIPT_TEMPLATE_MINDMAP = r"""
|
SCRIPT_TEMPLATE_MINDMAP = """
|
||||||
<script>
|
<script>
|
||||||
(function() {
|
(function() {
|
||||||
const uniqueId = "{unique_id}";
|
const uniqueId = "{unique_id}";
|
||||||
@@ -852,7 +852,7 @@ SCRIPT_TEMPLATE_MINDMAP = r"""
|
|||||||
return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;
|
return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;
|
||||||
}
|
}
|
||||||
// rgb(r, g, b) or rgba(r, g, b, a)
|
// rgb(r, g, b) or rgba(r, g, b, a)
|
||||||
m = colorStr.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i);
|
m = colorStr.match(/rgba?\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)/i);
|
||||||
if (m) {
|
if (m) {
|
||||||
const r = parseInt(m[1], 10);
|
const r = parseInt(m[1], 10);
|
||||||
const g = parseInt(m[2], 10);
|
const g = parseInt(m[2], 10);
|
||||||
@@ -2017,20 +2017,14 @@ class Action:
|
|||||||
# Prepare content components
|
# Prepare content components
|
||||||
# Resolve translations for UI
|
# Resolve translations for UI
|
||||||
ui_trans = {}
|
ui_trans = {}
|
||||||
target_lang = user_language
|
# Iterate over base language keys to ensure no missing placeholders
|
||||||
if target_lang not in TRANSLATIONS and target_lang in self.fallback_map:
|
for k in TRANSLATIONS["en-US"]:
|
||||||
target_lang = self.fallback_map[target_lang]
|
|
||||||
if target_lang not in TRANSLATIONS:
|
|
||||||
target_lang = "en-US"
|
|
||||||
|
|
||||||
full_trans = TRANSLATIONS.get(target_lang, TRANSLATIONS["en-US"])
|
|
||||||
for k in full_trans:
|
|
||||||
if k.startswith("ui_"):
|
if k.startswith("ui_"):
|
||||||
# For ui_footer which has {year}
|
val = self._get_translation(user_language, k)
|
||||||
if k == "ui_footer":
|
if k == "ui_footer":
|
||||||
ui_trans[f"t_{k}"] = full_trans[k].format(year=current_year)
|
ui_trans[f"t_{k}"] = val.format(year=current_year)
|
||||||
else:
|
else:
|
||||||
ui_trans[f"t_{k}"] = full_trans[k]
|
ui_trans[f"t_{k}"] = val
|
||||||
|
|
||||||
content_html = (
|
content_html = (
|
||||||
CONTENT_TEMPLATE_MINDMAP.format(
|
CONTENT_TEMPLATE_MINDMAP.format(
|
||||||
|
|||||||
Reference in New Issue
Block a user