Skip to content

Commit df6277c

Browse files
authored
1.2.0 (#55)
- Xcode localization file support — Added parsers for .strings, .stringsdict, and .xcstrings formats - Locked keys & exclude integration tests — Added test coverage for lockedKeys and exclude features - Plain text (.txt) file support — New parser for .txt files - Direct file and text translation — Ability to translate files or raw text directly, without requiring a full project config - Selective key translation (includeKeys) — Filter which keys get translated
1 parent f30f52c commit df6277c

52 files changed

Lines changed: 10748 additions & 479 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ coverage/
2626
# tmp files
2727
tmp/
2828

29-
.claude/
29+
.claude/
30+
CLAUDE.md

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
Lara Cli automates translation of your i18n files with a single command, preserving structure and formatting while integrating with a professional translation API. Given a source language, it translates your content to selected target languages based on your source i18n files.
66

7-
Supports multiple file formats including JSON, PO (gettext), TypeScript, Vue I18n single-file components, Markdown and MDX files, and Android XML string resource files. See [Supported Formats](docs/config/formats.md) for details.
7+
Supports multiple file formats including JSON, PO (gettext), TypeScript, Vue I18n single-file components, Markdown and MDX files, Android XML string resource files, Xcode localization files (.strings, .stringsdict, .xcstrings), and plain text (.txt) files. See [Supported Formats](docs/config/formats.md) for details.
88

9-
[![Version](https://img.shields.io/badge/version-1.1.0-blue.svg)](https://github.com/translated/lara-cli)
9+
[![Version](https://img.shields.io/badge/version-1.2.0-blue.svg)](https://github.com/translated/lara-cli)
1010

1111
</div>
1212

@@ -236,4 +236,8 @@ For detailed documentation on using Lara CLI:
236236
- [PO Files Guide](docs/config/files/po-files.md) - Complete guide for gettext PO files
237237
- [Vue Files Guide](docs/config/files/vue-files.md) - Complete guide for Vue I18n single-file components
238238
- [Markdown Files Guide](docs/config/files/md-files.md) - Complete guide for Markdown and MDX files
239-
- [Android XML Files Guide](docs/config/files/android-xml-files.md) - Complete guide for Android XML string resource files
239+
- [Android XML Files Guide](docs/config/files/android-xml-files.md) - Complete guide for Android XML string resource files
240+
- [Xcode Strings Files Guide](docs/config/files/xcode-strings-files.md) - Complete guide for Xcode .strings files
241+
- [Xcode Stringsdict Files Guide](docs/config/files/xcode-stringsdict-files.md) - Complete guide for Xcode .stringsdict plural files
242+
- [Xcode String Catalogs Guide](docs/config/files/xcode-xcstrings-files.md) - Complete guide for Xcode .xcstrings String Catalogs
243+
- [TXT Files Guide](docs/config/files/txt-files.md) - Complete guide for plain text files

docs/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@ To get started with Lara CLI, follow these steps:
1414
2. **Initialize your project**: Run `lara-cli init` to create a configuration file
1515
3. **Translate your files**: Run `lara-cli translate` to process translations
1616

17+
For quick, one-off translations or CI/CD pipelines, you can also use **direct translation** without any configuration:
18+
19+
```bash
20+
lara-cli translate --text "Hello, world!" --source en --target fr
21+
lara-cli translate --file "messages.json" --source en --target fr --output "messages-fr.json"
22+
```
23+
24+
See the [Translate Command](commands/translate.md) documentation for details.
25+
1726
## Command Reference
1827

1928
Lara CLI provides several commands to manage your internationalization:
@@ -43,3 +52,7 @@ The `lara.yaml` configuration file controls how Lara CLI works with your project
4352
- [Vue Files Guide](config/files/vue-files.md) - Complete guide for Vue I18n single-file components
4453
- [Markdown Files Guide](config/files/md-files.md) - Complete guide for Markdown and MDX files
4554
- [Android XML Files Guide](config/files/android-xml-files.md) - Complete guide for Android XML string resource files
55+
- [Xcode Strings Files Guide](config/files/xcode-strings-files.md) - Complete guide for Xcode .strings files
56+
- [Xcode Stringsdict Files Guide](config/files/xcode-stringsdict-files.md) - Complete guide for Xcode .stringsdict plural files
57+
- [Xcode String Catalogs Guide](config/files/xcode-xcstrings-files.md) - Complete guide for Xcode .xcstrings String Catalogs
58+
- [TXT Files Guide](config/files/txt-files.md) - Complete guide for plain text files

docs/commands/translate.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,86 @@ Use `--force` when you need to:
129129
- Fix translation errors by regenerating all translations
130130
- Reset translations after configuration changes
131131

132+
## Direct Translation
133+
134+
In addition to config-based translation, the `translate` command supports direct file and text translation. This mode is designed for CI/CD pipelines, scripting, and one-off translations — no `lara.yaml` configuration file is needed.
135+
136+
### Direct Text Translation
137+
138+
Translate a text string directly:
139+
140+
```bash
141+
lara-cli translate --text "Hello, world!" --source en-US --target fr-FR
142+
```
143+
144+
The translated text is printed to stdout, making it easy to pipe into other commands:
145+
146+
```bash
147+
lara-cli translate --text "Welcome" --source en --target es | pbcopy
148+
```
149+
150+
### Direct File Translation
151+
152+
Translate a file directly:
153+
154+
```bash
155+
lara-cli translate --file "/path/to/file.txt" --source en-US --target fr-FR
156+
```
157+
158+
By default, the translated content is printed to stdout. Use `--output` to write to a file:
159+
160+
```bash
161+
lara-cli translate --file "messages.json" --source en --target fr --output "messages-fr.json"
162+
```
163+
164+
#### Structured vs Plain Text Files
165+
166+
Only [supported file formats](../config/formats.md) are accepted (JSON, PO, XML, Markdown, TXT, etc.). Each format is parsed and translated preserving file structure, formatting, and non-string values. For `.txt` files, each non-empty line is translated independently while empty lines are preserved. Unsupported file types (e.g., `.png`, `.csv`) are rejected with an error.
167+
168+
### Direct Translation Options
169+
170+
| Option | Description |
171+
|--------|-------------|
172+
| `--file <path>` | Path to a file to translate directly |
173+
| `--text <string>` | Text string to translate directly |
174+
| `-s, --source <locale>` | Source locale (required with `--file` or `--text`) |
175+
| `-o, --output <path>` | Output file path (only with `--file`) |
176+
| `-m, --translation-memories <ids>` | Translation Memory IDs (comma-separated) |
177+
| `-g, --glossaries <ids>` | Glossary IDs (comma-separated) |
178+
179+
### Using Translation Memories & Glossaries
180+
181+
You can use Translation Memories and Glossaries in direct mode by passing their IDs:
182+
183+
```bash
184+
lara-cli translate --text "Hello" --source en --target fr -m "mem_abc123"
185+
lara-cli translate --file "messages.json" --source en --target fr -m "mem_abc,mem_def" -g "gls_xyz"
186+
```
187+
188+
Use `lara-cli memory` and `lara-cli glossary` to list available IDs.
189+
190+
### Differences from Config-Based Mode
191+
192+
| Feature | Config Mode | Direct Mode |
193+
|---------|-------------|-------------|
194+
| Requires `lara.yaml` | Yes | No |
195+
| Change detection (checksums) | Yes | No |
196+
| Locked/ignored keys | Yes | No |
197+
| Translation instructions | Yes | No |
198+
| Multiple target locales per invocation | Yes | No (one at a time) |
199+
| Translation Memories & Glossaries | Yes | Yes |
200+
201+
### Prerequisites
202+
203+
Direct translation only requires API credentials. No `lara-cli init` is needed:
204+
205+
```
206+
LARA_ACCESS_KEY_ID=your_access_key_id
207+
LARA_ACCESS_KEY_SECRET=your_access_key_secret
208+
```
209+
210+
Set these as environment variables or in a `.env` file in your working directory.
211+
132212
## Related
133213

134214
- [Configuration Reference](../config/README.md) - Detailed configuration options

docs/config/files.md

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ files:
2424
- "config/*/url"
2525
ignoredKeys:
2626
- "internal/**"
27+
includeKeys:
28+
- "ui/**"
29+
- "messages/**"
2730
```
2831
2932
## Properties
@@ -56,7 +59,14 @@ files:
5659
- **Description**: Identifies keys that should be left untouched in target files (not translated, not added, not removed)
5760
- **Format**: Uses glob patterns for matching keys (e.g., `internal/**`, `**/debug`)
5861

59-
## Locked vs Ignored Keys
62+
### includeKeys
63+
64+
- **Type**: Array of strings (key patterns)
65+
- **Required**: No (defaults to empty array)
66+
- **Description**: When specified, only keys matching these patterns will be translated. All other keys are treated as ignored (preserved in existing target files, not added to new ones). When empty (default), all keys are included.
67+
- **Format**: Uses glob patterns for matching keys (e.g., `ui/**`, `messages/*`)
68+
69+
## Locked vs Ignored vs Include Keys
6070

6171
Understanding the difference between `lockedKeys` and `ignoredKeys`:
6272

@@ -156,6 +166,57 @@ Target file (`es.json`) - if `debug` already existed:
156166

157167
Note: The `debug` key is never translated or modified by Lara. If it already exists in the target, it is preserved as-is. If it does not exist, it is not added.
158168

169+
### Include Keys
170+
171+
Keys listed in `includeKeys` define a whitelist: only matching keys are translated. All non-matching keys behave as if they were ignored. When `includeKeys` is empty (the default), all keys are in scope.
172+
173+
Use this for:
174+
175+
- Translating only a specific subset of a large file
176+
- Gradually rolling out translations for new keys
177+
- Focusing translation on specific namespaces
178+
179+
**Example:**
180+
181+
Source file (`en.json`):
182+
183+
```json
184+
{
185+
"ui": {
186+
"title": "My Application",
187+
"subtitle": "Welcome"
188+
},
189+
"internal": {
190+
"debug": "Debug mode",
191+
"version": "1.0.0"
192+
}
193+
}
194+
```
195+
196+
Configuration:
197+
198+
```yaml
199+
includeKeys:
200+
- "ui/**"
201+
```
202+
203+
Target file (`es.json`):
204+
205+
```json
206+
{
207+
"ui": {
208+
"title": "Mi Aplicación",
209+
"subtitle": "Bienvenido"
210+
}
211+
}
212+
```
213+
214+
Note: Only `ui/**` keys are translated. The `internal` keys are not added to the target file. If they already existed in the target, they would be preserved as-is.
215+
216+
**Interaction with `lockedKeys` and `ignoredKeys`:**
217+
218+
`includeKeys` is evaluated first. Among included keys, `lockedKeys` and `ignoredKeys` still apply normally. Non-included keys are always treated as ignored, regardless of other settings.
219+
159220
## Path Patterns
160221

161222
Paths in the `include` and `exclude` arrays must use the `[locale]` placeholder to indicate where locale codes should appear.
@@ -196,6 +257,7 @@ files:
196257
exclude: []
197258
lockedKeys: []
198259
ignoredKeys: []
260+
includeKeys: []
199261
```
200262

201263
### Complex Configuration
@@ -216,4 +278,7 @@ files:
216278
ignoredKeys:
217279
- "internal/**"
218280
- "**/debug"
281+
includeKeys:
282+
- "ui/**"
283+
- "messages/**"
219284
```

0 commit comments

Comments
 (0)