mirror of
https://github.com/status-im/status-app.git
synced 2026-08-27 07:01:14 +00:00
chore(l10n): remove base Lokalise TS file, update README
- the l10n workflow using an external service is no longer used - update the I18N.md readme file Fixes #21334
This commit is contained in:
@@ -16,13 +16,10 @@ $ make update-translations
|
||||
The resulting binary QM files are also produced by simply running `make` via `make compile-translations` subtarget
|
||||
|
||||
### Update translations
|
||||
1. Create pull request with exported translations using lokalise.com, see [docs](https://docs.lokalise.com/en/articles/1684090-github)
|
||||
1. Simply attach the changed TS files to your PR; we have CI checks in place that enforce this
|
||||
2. If adding a brand new language, make sure to add the new TS file to `ui/i18n/CMakeLists.txt` as well
|
||||
|
||||
## Translator workflow
|
||||
Lokalise is a continuous localization and translation management platform. It integrates into development workflow and automates localization process.
|
||||
|
||||
Lokalise workflow:
|
||||
1. Upload base strings (`qml_base.ts` and `qml_en.ts` files) to Lokalise project. This is done automatically, Lokalise auto-pulls changes done to master's TS files.
|
||||
2. Translate strings to target languages. Target languages are driven by Lokalise configuration. Translations are done by community
|
||||
3. Export *.ts files with translations (e.g. qml_de.ts, qml_fr.ts)
|
||||
4. Create pull request with exported translations
|
||||
1. For editing TS files, we use the Qt's official [Linguist](https://doc.qt.io/qt-6/linguist-translators.html) tool
|
||||
2. For AI guided translations, please refer to the respective Linguist's chapter: [AI translation](https://doc.qt.io/qt-6/linguist-ai-translation.html)
|
||||
3. Recommended AI model: [translategemma:27b](https://ollama.com/library/translategemma:27b); offers large enough context window, and supports a wide array of 55 languages
|
||||
|
||||
@@ -670,7 +670,6 @@ log-update-translations:
|
||||
update-translations: | log-update-translations
|
||||
cmake -S $(TS_SOURCE_DIR) -B $(TS_BUILD_DIR) -Wno-dev $(TS_CMAKE_PARAMS) $(HANDLE_OUTPUT)
|
||||
cmake --build $(TS_BUILD_DIR) --target update_application_translations $(HANDLE_OUTPUT)
|
||||
+ cd scripts/translationScripts && go run fixup-base-ts-for-lokalise.go $(HANDLE_OUTPUT)
|
||||
|
||||
log-compile-translations:
|
||||
echo -e "\033[92mCompiling:\033[39m translations"
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// TS represents the root TS element
|
||||
type TS struct {
|
||||
XMLName xml.Name `xml:"TS"`
|
||||
Language string `xml:"language,attr"`
|
||||
SourceLanguage string `xml:"sourcelanguage,attr"`
|
||||
Contexts []Context `xml:"context"`
|
||||
}
|
||||
|
||||
// Context represents a context element
|
||||
type Context struct {
|
||||
Name string `xml:"name"`
|
||||
Messages []Message `xml:"message"`
|
||||
}
|
||||
|
||||
// Message represents a message element
|
||||
type Message struct {
|
||||
Numerus string `xml:"numerus,attr,omitempty"`
|
||||
Source string `xml:"source"`
|
||||
Comment string `xml:"comment,omitempty"`
|
||||
Translation Translation `xml:"translation"`
|
||||
Extra []xml.Token `xml:",any"` // For any extra elements like unfinished
|
||||
}
|
||||
|
||||
// Translation represents a translation element, handling numerus forms
|
||||
type Translation struct {
|
||||
Type string `xml:"type,attr,omitempty"`
|
||||
Text string `xml:",chardata"`
|
||||
NumerusForms []NumerusForm `xml:"numerusform,omitempty"`
|
||||
}
|
||||
|
||||
// NumerusForm represents a numerusform element
|
||||
type NumerusForm struct {
|
||||
Text string `xml:",chardata"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Relative paths from project root
|
||||
baseFile := "../../ui/i18n/qml_base_en.ts"
|
||||
pluralFile := "../../ui/i18n/qml_en.ts"
|
||||
outputFile := "../../ui/i18n/qml_base_lokalise_en.ts"
|
||||
|
||||
// Parse the base TS file
|
||||
baseData, err := os.ReadFile(baseFile)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error reading %s: %v\n", baseFile, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
var baseTS TS
|
||||
if err := xml.Unmarshal(baseData, &baseTS); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error parsing %s: %v\n", baseFile, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Parse the plural TS file
|
||||
pluralData, err := os.ReadFile(pluralFile)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error reading %s: %v\n", pluralFile, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
var pluralTS TS
|
||||
if err := xml.Unmarshal(pluralData, &pluralTS); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error parsing %s: %v\n", pluralFile, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Create a dictionary for quick lookup of plural translations by source
|
||||
pluralLookup := make(map[string]Translation)
|
||||
for _, context := range pluralTS.Contexts {
|
||||
for _, message := range context.Messages {
|
||||
if message.Source != "" {
|
||||
pluralLookup[message.Source] = message.Translation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process each message in the base file
|
||||
for i := range baseTS.Contexts {
|
||||
context := &baseTS.Contexts[i]
|
||||
contextName := context.Name
|
||||
for j := range context.Messages {
|
||||
message := &context.Messages[j]
|
||||
// Add comment if missing
|
||||
if message.Comment == "" {
|
||||
message.Comment = contextName
|
||||
}
|
||||
|
||||
if message.Numerus == "yes" && message.Source != "" {
|
||||
if pluralTrans, exists := pluralLookup[message.Source]; exists {
|
||||
message.Translation = pluralTrans
|
||||
// Clean up whitespace in text and numerus forms
|
||||
message.Translation.Text = strings.TrimSpace(message.Translation.Text)
|
||||
for k := range message.Translation.NumerusForms {
|
||||
message.Translation.NumerusForms[k].Text = strings.TrimSpace(message.Translation.NumerusForms[k].Text)
|
||||
}
|
||||
// Remove unfinished type
|
||||
if message.Translation.Type == "unfinished" {
|
||||
message.Translation.Type = ""
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Set translation to source, trimmed
|
||||
message.Translation.Text = strings.TrimSpace(message.Source)
|
||||
message.Translation.NumerusForms = nil // Clear numerus forms
|
||||
// Remove unfinished type
|
||||
if message.Translation.Type == "unfinished" {
|
||||
message.Translation.Type = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set language attributes
|
||||
baseTS.Language = "en"
|
||||
baseTS.SourceLanguage = "en"
|
||||
|
||||
// Write the modified XML to output file
|
||||
outputData, err := xml.MarshalIndent(baseTS, "", " ")
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error marshaling XML: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
// Add XML declaration
|
||||
outputData = []byte(xml.Header + string(outputData))
|
||||
if err := os.WriteFile(outputFile, outputData, 0644); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error writing to %s: %v\n", outputFile, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("Successfully transformed %s to %s\n", baseFile, outputFile)
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user