1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-28 23:42:51 -05:00

switch hto monorepo structure

This commit is contained in:
bbedward
2025-11-12 17:18:45 -05:00
parent 6013c994a6
commit 24e800501a
768 changed files with 76284 additions and 221 deletions

View File

@@ -0,0 +1,64 @@
# DankMaterialShell Translations
This directory contains translation files for DankMaterialShell extracted from all qsTr() calls in the QML codebase.
## Files
- **en.json** - Source language file with English strings and file references
- **template.json** - Empty template for creating new translations
- **extract_translations.py** - Script to regenerate translation files
## POEditor Format
The JSON files follow POEditor's import format:
```json
[
{
"term": "string to translate",
"context": "file:line",
"reference": "Modules/Settings/AboutTab.qml:45",
"comment": ""
}
]
```
### Field Descriptions
- **term**: The source string in English (from qsTr() calls)
- **context**: Primary location where the string appears (file:line)
- **reference**: All locations where this string is used (comma-separated)
- **comment**: Additional notes for translators (currently empty)
## How to Create a New Translation
1. Copy `template.json` to your language code (e.g., `es.json` for Spanish)
2. Fill in the `translation` field for each entry:
```json
{
"term": "Settings",
"translation": "Configuración",
"context": "Modals/Settings/SettingsModal.qml:147",
"reference": "Modals/Settings/SettingsModal.qml:147",
"comment": ""
}
```
3. Import to POEditor or use directly in your translation workflow
## Regenerating Translation Files
To update the translation files after code changes:
```bash
cd /home/brandon/.config/quickshell/DankMaterialShellGit/translations
./extract_translations.py
```
This will scan all QML files and regenerate `en.json` and `template.json`.
## Notes
- Strings are deduplicated - if the same string appears in multiple locations, references are merged
- File paths are relative to the project root
- Line numbers are preserved for accurate context
- Empty strings and comments are reserved for translator notes

View File

@@ -0,0 +1,185 @@
# Translation Workflow for DankMaterialShell
## POEditor Integration Guide
### Initial Setup
1. **Create POEditor Project**
- Go to https://poeditor.com
- Create new project "DankMaterialShell"
- Add languages you want to support (es, fr, de, etc.)
2. **Import Source Strings**
- Upload `en.json` as the source language
- POEditor will detect 336 translatable strings
- Format: Key-Value JSON
### Translation Workflow
#### Method 1: Using POEditor (Recommended)
1. **Upload source file**
```bash
# Upload en.json to POEditor
```
2. **Translate in POEditor**
- Use POEditor's web interface
- Invite translators
- Track progress per language
3. **Export translations**
```bash
# Download from POEditor as JSON
# Save to translations/{language_code}.json
# Example: translations/es.json, translations/fr.json
```
4. **Test translations**
```bash
# Set your locale and restart shell
export LANG=es_ES.UTF-8
qs -p .
```
#### Method 2: Manual Translation
1. **Copy template**
```bash
cp translations/template.json translations/es.json
```
2. **Fill in translations**
```json
{
"term": "Settings",
"context": "Modals/Settings/SettingsModal.qml:147",
"reference": "Modals/Settings/SettingsModal.qml:147",
"comment": "",
"translation": "Configuración"
}
```
3. **Upload to POEditor** (optional)
### Updating Translations After Code Changes
1. **Re-extract strings**
```bash
cd translations
python3 extract_translations.py
```
2. **Upload updated en.json to POEditor**
- POEditor will detect new/removed strings
- Preserves existing translations
3. **Download updated translations**
### Translation File Format
POEditor-compatible JSON format:
```json
[
{
"term": "source string in English",
"context": "file:line where it appears",
"reference": "full/path/to/file.qml:123",
"comment": "optional context for translators",
"translation": "translated string"
}
]
```
### Supported Languages
The shell will auto-detect your system locale. Supported format:
- `es.json` → Spanish (es_ES, es_MX, etc.)
- `fr.json` → French (fr_FR, fr_CA, etc.)
- `de.json` → German
- `zh.json` → Chinese
- `ja.json` → Japanese
- `pt.json` → Portuguese
- etc.
### Testing Translations
1. **Change system locale**
```bash
export LANG=es_ES.UTF-8
export LC_ALL=es_ES.UTF-8
```
2. **Restart shell**
```bash
qs -p .
```
3. **Verify translations appear correctly**
### File Structure
```
translations/
├── en.json # Source language (English)
├── template.json # Empty template for new languages
├── es.json # Spanish translation
├── fr.json # French translation
├── extract_translations.py # Auto-extraction script
├── README.md # Technical documentation
└── WORKFLOW.md # This file
```
### Translation Statistics
- **Total strings:** 336 unique terms
- **Most translated components:**
- Settings UI: 202 strings (60%)
- Weather: 25 strings (7%)
- System monitors: Various
- Modals: 43 strings (13%)
### POEditor API Integration (Advanced)
For automated sync, use POEditor's API:
```bash
# Export from POEditor
curl -X POST https://api.poeditor.com/v2/projects/export \
-d api_token="YOUR_TOKEN" \
-d id="PROJECT_ID" \
-d language="es" \
-d type="key_value_json"
# Import to POEditor
curl -X POST https://api.poeditor.com/v2/projects/upload \
-d api_token="YOUR_TOKEN" \
-d id="PROJECT_ID" \
-d updating="terms_translations" \
-d language="es" \
-F file=@"translations/es.json"
```
### Best Practices
1. **Context matters:** Use the reference field to understand where strings appear
2. **Test before committing:** Always test translations in the actual UI
3. **Keep synchronized:** Re-extract after significant UI changes
4. **Preserve formatting:** Keep placeholders like `%1`, `{0}` intact
5. **Cultural adaptation:** Some strings may need cultural context, not just literal translation
### Troubleshooting
**Translations not loading?**
- Check file exists: `~/.config/DankMaterialShell/translations/{language_code}.json`
- Verify JSON syntax: `python3 -m json.tool translations/es.json`
- Check console for errors: `qs -v -p .`
**Wrong language loading?**
- Check system locale: `echo $LANG`
- Verify file naming: Must match locale prefix (es_ES → es.json)
**Missing strings?**
- Re-run extraction: `python3 extract_translations.py`
- Compare with en.json to find new strings

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,98 @@
#!/usr/bin/env python3
import os
import re
import json
from pathlib import Path
from collections import defaultdict
def extract_qstr_strings(root_dir):
translations = defaultdict(list)
qstr_pattern = re.compile(r'qsTr\(["\']([^"\']+)["\']\)')
i18n_pattern = re.compile(r'I18n\.tr\(["\']([^"\']+)["\']\)')
for qml_file in Path(root_dir).rglob('*.qml'):
relative_path = qml_file.relative_to(root_dir)
with open(qml_file, 'r', encoding='utf-8') as f:
for line_num, line in enumerate(f, 1):
qstr_matches = qstr_pattern.findall(line)
for match in qstr_matches:
translations[match].append({
'file': str(relative_path),
'line': line_num
})
i18n_matches = i18n_pattern.findall(line)
for match in i18n_matches:
translations[match].append({
'file': str(relative_path),
'line': line_num
})
return translations
def create_poeditor_json(translations):
poeditor_data = []
for term, occurrences in sorted(translations.items()):
references = []
for occ in occurrences:
ref = f"{occ['file']}:{occ['line']}"
references.append(ref)
entry = {
"term": term,
"context": term,
"reference": ", ".join(references),
"comment": ""
}
poeditor_data.append(entry)
return poeditor_data
def create_template_json(translations):
template_data = []
for term in sorted(translations.keys()):
entry = {
"term": term,
"translation": "",
"context": "",
"reference": "",
"comment": ""
}
template_data.append(entry)
return template_data
def main():
script_dir = Path(__file__).parent
root_dir = script_dir.parent
translations_dir = script_dir
print("Extracting qsTr() strings from QML files...")
translations = extract_qstr_strings(root_dir)
print(f"Found {len(translations)} unique strings")
poeditor_data = create_poeditor_json(translations)
en_json_path = translations_dir / 'en.json'
with open(en_json_path, 'w', encoding='utf-8') as f:
json.dump(poeditor_data, f, indent=2, ensure_ascii=False)
print(f"Created source language file: {en_json_path}")
template_data = create_template_json(translations)
template_json_path = translations_dir / 'template.json'
with open(template_json_path, 'w', encoding='utf-8') as f:
json.dump(template_data, f, indent=2, ensure_ascii=False)
print(f"Created template file: {template_json_path}")
print("\nSummary:")
print(f" - Unique strings: {len(translations)}")
print(f" - Total occurrences: {sum(len(occs) for occs in translations.values())}")
print(f" - Source file: {en_json_path}")
print(f" - Template file: {template_json_path}")
if __name__ == '__main__':
main()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
#!/usr/bin/env python3
import os
import re
from pathlib import Path
def replace_qstr_in_file(file_path, root_dir):
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
original_content = content
relative_path = file_path.relative_to(root_dir)
qstr_pattern = re.compile(r'qsTr\("([^"]+)"\)')
def replacement(match):
term = match.group(1)
context = term
return f'I18n.tr("{term}", "{context}")'
content = qstr_pattern.sub(replacement, content)
if content != original_content:
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
return True
return False
def main():
script_dir = Path(__file__).parent
root_dir = script_dir.parent
modified_count = 0
for qml_file in root_dir.rglob('*.qml'):
if 'translations' in str(qml_file):
continue
try:
if replace_qstr_in_file(qml_file, root_dir):
modified_count += 1
print(f"Modified: {qml_file.relative_to(root_dir)}")
except Exception as e:
print(f"Error processing {qml_file}: {e}")
print(f"\nTotal files modified: {modified_count}")
if __name__ == '__main__':
main()

File diff suppressed because it is too large Load Diff