## Summary fixes just a small typo in docs. --- ### AI Usage Did you use AI tools to help write this code? _**< NO >**_
240 lines
5.7 KiB
Markdown
240 lines
5.7 KiB
Markdown
# Internationalization (I18N)
|
|
|
|
This guide explains the multi-language support system in CrossPoint Reader.
|
|
|
|
## Supported Languages
|
|
|
|
- English
|
|
- French
|
|
- German
|
|
- Portuguese
|
|
- Spanish
|
|
- Swedish
|
|
- Czech
|
|
- Russian
|
|
- Ukrainian
|
|
- Danish
|
|
|
|
---
|
|
|
|
|
|
## For Developers
|
|
|
|
### Translation System Architecture
|
|
|
|
The I18N system uses **per-language YAML files** to maintain translations and a Python script to generate C++ code:
|
|
|
|
```
|
|
lib/I18n/
|
|
├── translations/ # One YAML file per language
|
|
│ ├── english.yaml
|
|
│ ├── spanish.yaml
|
|
│ ├── french.yaml
|
|
│ └── ...
|
|
├── I18n.h
|
|
├── I18n.cpp
|
|
├── I18nKeys.h # Enums (auto-generated)
|
|
├── I18nStrings.h # String array declarations (auto-generated)
|
|
└── I18nStrings.cpp # String array definitions (auto-generated)
|
|
|
|
scripts/
|
|
└── gen_i18n.py # Code generator script
|
|
```
|
|
|
|
**Key principle:** All translations are managed in the YAML files under `lib/I18n/translations/`. The Python script generates the necessary C++ code automatically.
|
|
|
|
---
|
|
|
|
### YAML File Format
|
|
|
|
Each language has its own file in `lib/I18n/translations/` (e.g. `spanish.yaml`).
|
|
|
|
A file looks like this:
|
|
|
|
```yaml
|
|
_language_name: "Español"
|
|
_language_code: "ES"
|
|
_order: "1"
|
|
|
|
STR_CROSSPOINT: "CrossPoint"
|
|
STR_BOOTING: "BOOTING"
|
|
STR_BROWSE_FILES: "Buscar archivos"
|
|
```
|
|
|
|
**Metadata keys** (prefixed with `_`):
|
|
- `_language_name` — Native display name shown to the user (e.g. "Français")
|
|
- `_language_code` — C++ enum name (e.g. "FR"). Please use the [ISO Code](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes) of the language. Must be a valid C++ identifier.
|
|
- `_order` — Controls the position in the Language enum (English is always 0)
|
|
|
|
**Rules:**
|
|
- Use UTF-8 encoding
|
|
- Every line must follow the format: `KEY: "value"`
|
|
- Keys must be valid C++ identifiers (uppercase, starts with STR_)
|
|
- Keys must be unique within a file
|
|
- String values must be quoted
|
|
- Use `\n` for newlines, `\\` for literal backslashes, `\"` for literal quotes inside values
|
|
|
|
---
|
|
|
|
### Adding New Strings
|
|
|
|
To add a new translatable string:
|
|
|
|
#### 1. Edit the English YAML file
|
|
|
|
Add the key to `lib/I18n/translations/english.yaml`:
|
|
|
|
```yaml
|
|
STR_MY_NEW_STRING: "My New String"
|
|
```
|
|
|
|
Then add translations in each language file. If a key is missing from a
|
|
language file, the generator will automatically use the English text as a
|
|
fallback (and print a warning).
|
|
|
|
#### 2. Run the generator script
|
|
|
|
```bash
|
|
python3 scripts/gen_i18n.py lib/I18n/translations lib/I18n/
|
|
```
|
|
|
|
This automatically:
|
|
- Fills missing translations from English
|
|
- Updates the `StrId` enum in `I18nKeys.h`
|
|
- Regenerates all language arrays in `I18nStrings.cpp`
|
|
|
|
#### 3. Use in code
|
|
|
|
```cpp
|
|
#include <I18n.h>
|
|
|
|
// Using the tr() macro (recommended)
|
|
renderer.drawText(font, x, y, tr(STR_MY_NEW_STRING));
|
|
|
|
// Using I18N.get() directly
|
|
const char* text = I18N.get(StrId::STR_MY_NEW_STRING);
|
|
```
|
|
|
|
**That's it!** No manual array synchronization needed.
|
|
|
|
---
|
|
|
|
### Adding a New Language
|
|
|
|
To add support for a new language (e.g., Italian):
|
|
|
|
#### 1. Create a new YAML file
|
|
|
|
Create `lib/I18n/translations/italian.yaml`:
|
|
|
|
```yaml
|
|
_language_name: "Italiano"
|
|
_language_code: "IT"
|
|
_order: "7"
|
|
|
|
STR_CROSSPOINT: "CrossPoint"
|
|
STR_BOOTING: "AVVIO"
|
|
```
|
|
|
|
You only need to include the strings you have translations for. Missing
|
|
keys will fall back to English automatically.
|
|
|
|
#### 2. Run the generator
|
|
|
|
```bash
|
|
python3 scripts/gen_i18n.py lib/I18n/translations lib/I18n/
|
|
```
|
|
|
|
This automatically updates all necessary code.
|
|
|
|
---
|
|
|
|
### Modifying Existing Translations
|
|
|
|
Simply edit the relevant YAML file and regenerate:
|
|
|
|
```bash
|
|
python3 scripts/gen_i18n.py lib/I18n/translations lib/I18n/
|
|
```
|
|
|
|
---
|
|
|
|
### UTF-8 Encoding
|
|
|
|
The YAML files use UTF-8 encoding. Special characters are automatically converted to C++ UTF-8 hex sequences by the generator.
|
|
|
|
---
|
|
|
|
### I18N API Reference
|
|
|
|
```cpp
|
|
// === Convenience Macros (Recommended) ===
|
|
|
|
// tr(id) - Get translated string without StrId:: prefix
|
|
const char* text = tr(STR_SETTINGS_TITLE);
|
|
renderer.drawText(font, x, y, tr(STR_BROWSE_FILES));
|
|
Serial.printf("Status: %s\n", tr(STR_CONNECTED));
|
|
|
|
// I18N - Shorthand for I18n::getInstance()
|
|
I18N.setLanguage(Language::ES);
|
|
Language lang = I18N.getLanguage();
|
|
|
|
// === Full API ===
|
|
|
|
// Get the singleton instance
|
|
I18n& instance = I18n::getInstance();
|
|
|
|
// Get translated string (three equivalent ways)
|
|
const char* text = tr(STR_SETTINGS_TITLE); // Macro (recommended)
|
|
const char* text = I18N.get(StrId::STR_SETTINGS_TITLE); // Direct call
|
|
const char* text = I18N[StrId::STR_SETTINGS_TITLE]; // Operator overload
|
|
|
|
// Set language
|
|
I18N.setLanguage(Language::ES);
|
|
|
|
// Get current language
|
|
Language lang = I18N.getLanguage();
|
|
|
|
// Save language setting to file
|
|
I18N.saveSettings();
|
|
|
|
// Load language setting from file
|
|
I18N.loadSettings();
|
|
|
|
// Get character set for font subsetting (static method)
|
|
const char* chars = I18n::getCharacterSet(Language::FR);
|
|
```
|
|
|
|
---
|
|
|
|
## File Storage
|
|
|
|
Language settings are stored in:
|
|
```
|
|
/.crosspoint/language.bin
|
|
```
|
|
|
|
This file contains:
|
|
- Version byte
|
|
- Current language selection (1 byte)
|
|
|
|
---
|
|
|
|
## Translation Workflow
|
|
|
|
### For Developers (Adding Features)
|
|
|
|
1. Add new strings to `lib/I18n/translations/english.yaml`
|
|
2. Run `python3 scripts/gen_i18n.py lib/I18n/translations lib/I18n/`
|
|
3. Use the new `StrId` in your code
|
|
4. Request translations from translators
|
|
|
|
### For Translators
|
|
|
|
1. Open the YAML file for your language in `lib/I18n/translations/`
|
|
2. Add or update translations using the format `STR_KEY: "translated text"`
|
|
3. Keep translations concise (E-ink space constraints)
|
|
4. Make sure the file is in UTF-8 encoding
|
|
5. Run `python3 scripts/gen_i18n.py lib/I18n/translations lib/I18n/` to verify
|
|
6. Test on device or submit for review
|