From fd7f9095614d9403a0a1308f89331a26ba55141c Mon Sep 17 00:00:00 2001 From: Glavo Date: Fri, 24 Oct 2025 11:55:14 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=86=20Localization.md=20=E7=BF=BB?= =?UTF-8?q?=E8=AF=91=E8=87=B3=E8=8B=B1=E8=AF=AD=20(#4669)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jackhuang/hmcl/gradle/docs/Document.java | 8 +- docs/Localization.md | 337 ++++++++++++++++++ docs/Localization_zh.md | 12 +- 3 files changed, 347 insertions(+), 10 deletions(-) create mode 100644 docs/Localization.md diff --git a/buildSrc/src/main/java/org/jackhuang/hmcl/gradle/docs/Document.java b/buildSrc/src/main/java/org/jackhuang/hmcl/gradle/docs/Document.java index e2c39ad8a..f7d674d91 100644 --- a/buildSrc/src/main/java/org/jackhuang/hmcl/gradle/docs/Document.java +++ b/buildSrc/src/main/java/org/jackhuang/hmcl/gradle/docs/Document.java @@ -103,12 +103,8 @@ public record Document(DocumentFileTree directory, if (line == null) throw new IOException("Missing end line for macro: " + macroName); - else if (line.startsWith(" +**English** | [中文](Localization_zh.md) + + +HMCL provides localization support for multiple languages. + +This document describes HMCL's support status for these languages and provides a guide for contributors who want to help with HMCL localization. + +## Supported languages + +Currently, HMCL supports the following languages: + +| Language | Language Tag | Preferred Localization Key | Preferred Localization File Suffix | [Game Language Files](https://minecraft.wiki/w/Language) | Support Status | Volunteers | +|-----------------------|--------------|----------------------------|------------------------------------|----------------------------------------------------------|----------------|-------------------------------------------| +| English | `en` | `default` | (empty) | `en_us` | **Primary** | [Glavo](https://github.com/Glavo) | +| English (Upside Down) | `en-Qabs` | `en-Qabs` | `en_Qabs` | `en_ud` | Automatic | | +| Chinese (Simplified) | `zh-Hans` | `zh` | `_zh` | `zh_cn` | **Primary** | [Glavo](https://github.com/Glavo) | +| Chinese (Traditional) | `zh-Hant` | `zh-Hant` | `_zh_Hant` | `zh_tw`
`zh_hk` | **Primary** | [Glavo](https://github.com/Glavo) | +| Chinese (Classical) | `lzh` | `lzh` | `_lzh` | `lzh` | Secondary | | +| Japanese | `ja` | `ja` | `_ja` | `ja_jp` | Secondary | | +| Spanish | `es` | `es` | `_es` | `es_es` | Secondary | [3gf8jv4dv](https://github.com/3gf8jv4dv) | +| Russian | `ru` | `ru` | `_ru` | `ru_ru` | Secondary | [3gf8jv4dv](https://github.com/3gf8jv4dv) | +| Ukrainian | `uk` | `uk` | `_uk` | `uk_ua` | Secondary | | + +
+About Language Tags + +HMCL uses language tags that conform to the IETF BCP 47 standard. + +When choosing language tags, we follow these principles: + +1. For languages defined in the ISO 639 standard, if a tag has already been registered in the [IANA Language Subtag Registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry), + we always use the registered tag. + + For example, for English, we use `en` instead of `eng` as the language code. + +2. For non-standard languages defined by Minecraft, the code defined in the language file's `language.code` should be preferred over the game language file's name. + + This is because Minecraft sometimes uses real-world country/region codes to represent joke languages + (for example, Pirate English uses the language file `en_pt`, but `PT` is actually the country code for Portugal). + + For example, for Upside down English, we use `en-Qabs` as the language code instead of `en-UD`. + +
+ +
+About Localization Keys and File Suffixes + +Localization file suffixes and keys are used to name [localization resources](#localization-resources). + +Generally, the localization key is the language code for the resource, and the localization file suffix is obtained by replacing `-` with `_` in the language code and adding a leading underscore. + +As a special case, for default resources, the localization key is `default` and the file suffix is empty. + +Due to the existence of the [resource fallback mechanism](#resource-fallback-mechanism), +if there is no resource that exactly matches the current locale, +HMCL will derive a search list from the current language tag and search for resources in order. + +We recommend always providing a default resource (with the `default` key and empty file suffix) when providing localization resources, +to ensure all users can load resources properly. + +We also recommend using broader language tags for localization resources whenever possible, +so users are less likely to fall back to the default resource. + +For example, if you provide a Simplified Chinese localization resource, +we recommend using `zh` as the localization key instead of the more specific `zh-Hans`, +so it will apply to all Chinese users and avoid falling back to the default resource for them. + +If you want to provide both Simplified and Traditional Chinese resources, +it is recommended to use the broader `zh` as the key for the resource with more users (as the default Chinese resource), +and use the more specific `zh-Hans`/`zh-Hant` as the key for the resource with fewer users. + +
+ +HMCL requires all pull requests that update documentation and localization resources to also update the resources +for all **primary** supported languages. +If the PR author is not familiar with the relevant languages, they can request translation help in the comments, +and maintainers will help translate these texts before merging the PR. + +For **secondary** supported languages, we cannot guarantee that these localization resources will always be updated in sync. +We need collaborators who are proficient in these languages to help with maintenance. + +We will record volunteers willing to help maintain these language resources in the documentation. +If contributors want to have new localization texts translated into these languages in a timely manner, +they can @ these volunteers in the PR for help. + +If you are willing to help maintain localization resources for any language, please open a PR +and add your GitHub username to the volunteer list above. +We greatly appreciate your help. + +## Adding Support for a New Language + +HMCL welcomes anyone to participate in translation and contribution. +However, maintaining translations for more languages requires more maintenance effort, so we have some requirements for newly added languages. +Please confirm the following requirements before contributing: + +- We prioritize [languages officially supported by Minecraft](https://minecraft.wiki/w/Language). + + Unless there are special reasons, we do not provide support for languages not yet supported by Minecraft. +- We hope to provide long-term maintenance support for all languages. + + Since the maintainers of this project are proficient in only a limited number of languages, + to avoid support for new languages quickly becoming outdated due to lack of maintainers, + we hope to find people proficient in the language to help us maintain the newly added localization files in the long term. + If there may be a lack of long-term maintainers, we will be more cautious about adding support for that language. + +We recommend that contributors submit a [feature request](https://github.com/HMCL-dev/HMCL/issues/new?template=feature.yml) before providing a new language translation, +discuss with other contributors first, and determine the future maintenance plan before starting the translation work. + +### Getting Started with Translation + +If you want to add support for a new language to HMCL, please start by translating [`I18N.properties`](../HMCL/src/main/resources/assets/lang/I18N.properties). +The vast majority of HMCL's texts are in this file, and translating it will translate the entire interface. + +This is a Java Properties file, which is very simple in format. +Before translating, please read the introduction to this format: [Properties file](https://en.wikipedia.org/wiki/.properties). + +As the first step of translation, please look up the two- or three-letter language tag for your language in [this table](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry). +For example, the language tag for English is `en`. + +After determining the language tag, please create a file named `I18N_.properties` (e.g., `I18N_en.properties`) next to the [`I18N.properties` file](../HMCL/src/main/resources/assets/lang). +Then you can start translating in this file. + +The `I18N.properties` file follows the [resource fallback mechanism](#resource-fallback-mechanism) to look up missing translations. +That is, you can translate entry by entry, and any untranslated entries will automatically fall back to English. + +After translating part of the file, you can [build HMCL yourself](./README.md#compilation), +and your translations will be included in the compiled HMCL. +If your computer's default environment is not the target language, +you can set the environment variable `HMCL_LANGUAGE` to the language tag you just found from the table, +and HMCL will automatically switch to that language. + +At this point, you can push the file to GitHub and submit a PR to HMCL. +The maintainers of HMCL will complete the remaining steps for you. + +## Localization Resources + +All documentation and localization resource files follow the naming rule `.`. + +For example, for `README.md`, the localized versions in different languages are named as follows: + +- English: `README.md` +- Chinese (Simplified): `README_zh.md` +- Chinese (Traditional): `README_zh_Hant.md` +- Chinese (Classical): `README_lzh.md` + +In addition to localized files, HMCL also supports localizing certain text fields in JSON. Localized text in JSON uses the following format: + +```json5 +{ + "": "", + "": "", + // ... + "": "" +} +``` + +For example, for the following text field: + +```json +{ + "meow": "Meow" +} +``` + +It can be rewritten as localized text: + +```json +{ + "meow": { + "default": "Meow", + "zh": "喵呜", + "zh-Hant": "喵嗚" + } +} +``` + +## Resource Fallback Mechanism + +For missing resources in a certain language, HMCL supports a resource fallback mechanism, +which derives a search list based on different language tags and searches for resources in order according to this list. + +Before searching, we first refine the language tag through the following steps. + +1. Normalize Language Codes + + If the language code subtag in the current language tag is not registered in the IANA Language Subtag Registry, + HMCL will try to map it to a registered tag. + + For example, HMCL will replace the language code `eng` with `en`. + +2. Map Macrolanguages to Individual Languages + + If the current language code is an [ISO 639 macrolanguage](https://en.wikipedia.org/wiki/ISO_639_macrolanguage), + and the macrolanguage usually refers to a specific individual language, HMCL will replace it with that individual language. + + For example, `zh` (Chinese) usually actually refers to `cmn` (Mandarin), so we replace the language code `zh` with `cmn`. + +3. Derive Script + + If the current language tag does not specify a script, HMCL will try to derive the script according to the following rules in order: + + 1. If the current language tag specifies a variant, and the variant is registered in the IANA Language Subtag Registry, + and all its `Prefix` entries in the registry contain the same script, then set the current script to that script. + + For example, if the current variant is `pinyin` (Chinese Pinyin), the script will be set to `Latn` (Latin). + + 2. If the current language code is assigned a `Suppress-Script` in the IANA Language Subtag Registry, set the current script to that script. + + For example, if the current language code is `en` (English), the script will be set to `Latn` (Latin); + if the code is `ru` (Russian), the script will be set to `Cyrl` (Cyrillic). + + 3. If the current language code is `lzh` (Classical Chinese), set the script to `Hant` (Traditional Chinese Characters). + + 4. If the current language code is `zh` or a sublanguage of `zh`, check if the current region code is one of `TW`, `HK`, or `MO`. + If true, set the script to `Hant` (Traditional Chinese Characters); + otherwise, set it to `Hans` (Simplified Chinese Characters). + +After refining the language code, HMCL will derive a list of language tags based on this language tag. + +For example, for the language tag `en-US`, HMCL will refine it to `en-Latn-US` and derive the following search list: + +1. `en-Latn-US` +2. `en-Latn` +3. `en-US` +4. `en` +5. `und` + +For the language tag `zh-CN`, HMCL will refine it to `cmn-Hans-CN` and derive the following search list: + +1. `cmn-Hans-CN` +2. `cmn-Hans` +3. `cmn-CN` +4. `cmn` +5. `zh-Hans-CN` +6. `zh-Hans` +7. `zh-CN` +8. `zh` +9. `und` + +For resources that can be merged (such as `.properties` files), +HMCL will merge resources according to the priority of this list; for resources that are difficult to merge (such as font files), +HMCL will load the highest-priority resource found in this list. + +If the current language uses a three-letter ISO 639 code, but there is also a corresponding two-letter code, +HMCL will map it to the two-letter code before searching for resources. + +For example, if the current environment's language tag is `eng-US`, +HMCL will map it to `en-US` and then search for localization resources according to the above rules. + +### Additional Rules for Chinese + +HMCL always adds `zh-CN` to the search list for all Chinese environments, +and adds `zh-TW` to the search list for all Traditional Chinese environments. + +Below are the localization resource search lists for several common Chinese environments. + +- `zh-CN`: + 1. `cmn-Hans-CN` + 2. `cmn-Hans` + 3. `cmn-CN` + 4. `cmn` + 5. `zh-Hans-CN` + 6. `zh-Hans` + 7. `zh-CN` + 8. `zh` + 9. `und` +- `zh-SG`: + 1. `cmn-Hans-SG` + 2. `cmn-Hans` + 3. `cmn-SG` + 4. `cmn` + 5. `zh-Hans-SG` + 6. `zh-Hans` + 7. `zh-SG` + 8. `zh-CN` + 9. `zh` + 10. `und` +- `zh-TW`: + 1. `zh-Hant-TW` + 2. `zh-Hant` + 3. `zh-TW` + 4. `zh` + 5. `zh-CN` + 6. `und` +- `zh-HK`: + 1. `cmn-Hant-HK` + 2. `cmn-Hant` + 3. `cmn-HK` + 4. `cmn` + 5. `zh-Hant-HK` + 6. `zh-Hant` + 7. `zh-HK` + 8. `zh-TW` + 9. `zh` + 10. `zh-CN` + 11. `und` +- `lzh`: + 1. `lzh-Hant` + 2. `lzh` + 3. `zh-Hant` + 4. `zh-TW` + 5. `zh` + 6. `zh-CN` + 7. `und` + +## Automatic Synchronization of Documentation Content + + + +To simplify documentation maintenance, HMCL uses a macro mechanism to automatically maintain parts of the documentation content. +Run the following command in the terminal: + +```bash +./gradlew updateDocuments +``` + +This will automatically update all documentation content. + +For example, to create links for switching between different language versions of the same document, +add the following content under the document title: + +```markdown + + +``` + +After running `./gradlew updateDocuments`, these two lines will be automatically replaced with language switcher links like the following: + +```markdown +**English** (**Standard**, [uʍoᗡ ǝpᴉsd∩](README_en_Qabs.md)) | 中文 ([简体](README_zh.md), [繁體](README_zh_Hant.md), [文言](README_lzh.md)) | [日本語](README_ja.md) | [español](README_es.md) | [русский](README_ru.md) | [українська](README_uk.md) +``` + +For more about macros, see [MacroProcessor.java](../buildSrc/src/main/java/org/jackhuang/hmcl/gradle/docs/MacroProcessor.java). + diff --git a/docs/Localization_zh.md b/docs/Localization_zh.md index f57d23c85..549896808 100644 --- a/docs/Localization_zh.md +++ b/docs/Localization_zh.md @@ -1,6 +1,8 @@ # 本地化 - + +[English](Localization.md) | **中文** + HMCL 为多种语言提供本地化支持。 @@ -107,7 +109,7 @@ HMCL 的绝大多数文本都位于这个文件中,翻译此文件就能翻译 作为翻译的第一步,请从[这张表格](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry)中查询这个语言对应的两字母或三字母语言标签。 例如,英语的语言标签为 `en`。 -在确定了语言标签后,请在 [`I18N.properties` 文件旁](../HMCL/src/main/resources/assets/lang)创建 `I18N_<语言标签>.properites` (例如 `I18N_en.properties`) 文件。 +在确定了语言标签后,请在 [`I18N.properties` 文件旁](../HMCL/src/main/resources/assets/lang)创建 `I18N_<本地化文件后缀>.properties` (例如 `I18N_en.properties`) 文件。 随后,你就可以开始在这个文件中进行翻译工作了。 `I18N.properties` 文件会遵循[资源回退机制](#资源回退机制)查询缺失的译文。 @@ -287,6 +289,8 @@ HMCL 总是会将 `zh-CN` 加入所有中文环境的搜索列表中,将 `zh-T ## 自动同步文档内容 + + 为了简化文档的维护,HMCL 使用了一套宏机制自动维护文档的部分内容。在命令行中执行 ```bash @@ -305,8 +309,8 @@ HMCL 总是会将 `zh-CN` 加入所有中文环境的搜索列表中,将 `zh-T 随后执行 `./gradlew updateDocuments`,这两行内容会被自动替换为类似这样的跳转链接: ```markdown -**English** | -中文 ([简体](README_zh.md), [繁體](README_zh.md), [文言](README_zh.md)) | [日本語](README_zh.md) | [español](README_zh.md) | [русский](README_zh.md) | [українська](README_zh.md) +**English** (**Standard**, [uʍoᗡ ǝpᴉsd∩](README_en_Qabs.md)) | 中文 ([简体](README_zh.md), [繁體](README_zh_Hant.md), [文言](README_lzh.md)) | [日本語](README_ja.md) | [español](README_es.md) | [русский](README_ru.md) | [українська](README_uk.md) ``` 关于宏的更多内容,请见 [MacroProcessor.java](../buildSrc/src/main/java/org/jackhuang/hmcl/gradle/docs/MacroProcessor.java)。 +