338 lines
16 KiB
Markdown
338 lines
16 KiB
Markdown
|
|
# Localization
|
||
|
|
|
||
|
|
<!-- #BEGIN LANGUAGE_SWITCHER -->
|
||
|
|
**English** | [中文](Localization_zh.md)
|
||
|
|
<!-- #END LANGUAGE_SWITCHER -->
|
||
|
|
|
||
|
|
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` <br/> `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 | |
|
||
|
|
|
||
|
|
<details>
|
||
|
|
<summary>About Language Tags</summary>
|
||
|
|
|
||
|
|
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`.
|
||
|
|
|
||
|
|
</details>
|
||
|
|
|
||
|
|
<details>
|
||
|
|
<summary>About Localization Keys and File Suffixes</summary>
|
||
|
|
|
||
|
|
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.
|
||
|
|
|
||
|
|
</details>
|
||
|
|
|
||
|
|
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_<localization file suffix>.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 `<resource name><localization file suffix>.<extension>`.
|
||
|
|
|
||
|
|
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
|
||
|
|
{
|
||
|
|
"<Localization Key 1>": "<Localized Text 1>",
|
||
|
|
"<Localization Key 2>": "<Localized Text 2>",
|
||
|
|
// ...
|
||
|
|
"<Localization Key N>": "<Localized Text N>"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
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
|
||
|
|
|
||
|
|
<!-- #BEGIN BLOCK -->
|
||
|
|
<!-- #PROPERTY PROCESS_LINK=false -->
|
||
|
|
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
|
||
|
|
<!-- #BEGIN LANGUAGE_SWITCHER -->
|
||
|
|
<!-- #END LANGUAGE_SWITCHER -->
|
||
|
|
```
|
||
|
|
|
||
|
|
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).
|
||
|
|
<!-- #END BLOCK -->
|