|
6 | 6 | [](https://discord.gg/4Yqfggm) |
7 | 7 | [](https://bgforge.net/irc) |
8 | 8 |
|
9 | | -This is a set of tools to convert Fallout 1/2 MSG and WeiDU TRA into GNU gettext PO and back, used in [BGforge Hive](https://hive.bgforge.net/). Ask questions [here](https://forums.bgforge.net/viewforum.php?f=9). |
| 9 | +A set of tools to convert Fallout 1/2 MSG and WeiDU TRA into GNU gettext PO and back, used in [BGforge Hive](https://hive.bgforge.net/). Ask questions [here](https://forums.bgforge.net/viewforum.php?f=9). |
10 | 10 |
|
11 | | -### Installation |
| 11 | +## Table of Contents |
| 12 | + |
| 13 | +- [Installation](#installation) |
| 14 | +- [Configuration](#configuration) |
| 15 | +- [Commands](#commands) |
| 16 | + - [poify](#poify) |
| 17 | + - [unpoify](#unpoify) |
| 18 | + - [file2po](#file2po) |
| 19 | + - [po2file](#po2file) |
| 20 | + - [file2msgstr](#file2msgstr) |
| 21 | + - [dir2msgstr](#dir2msgstr) |
| 22 | + - [msgmerge-female](#msgmerge-female) |
| 23 | + - [resave-po](#resave-po) |
| 24 | + - [lowercase](#lowercase) |
| 25 | + - [unfuzzy](#unfuzzy) |
| 26 | + - [bgforge-config](#bgforge-config) |
| 27 | +- [GitHub Action](#github-action) |
| 28 | +- [Changelog](docs/changelog.md) |
| 29 | + |
| 30 | +## Installation |
12 | 31 |
|
13 | 32 | ```bash |
14 | | -pip install msg2po |
| 33 | +pipx install msg2po |
15 | 34 | ``` |
16 | 35 |
|
17 | 36 | Also install [Gettext tools](https://www.gnu.org/software/gettext/), and make sure they are in PATH. |
18 | 37 |
|
19 | | -### Poify |
| 38 | +## Configuration |
| 39 | + |
| 40 | +Create a `.bgforge.yml` file in your project root to configure the tool: |
| 41 | + |
| 42 | +```yaml |
| 43 | +translation: |
| 44 | + encoding: cp1252 # source encoding (cp1252 default, cp1251/ru, cp1250/pl, cp1258/vi) |
| 45 | + tra_dir: "." # translation root directory |
| 46 | + src_lang: "english" # source language (used for poify) |
| 47 | + extract_format: "" # "" (default), "sfall" for Fallout |
| 48 | + no_female: false # skip female translations |
| 49 | + extract_fuzzy: false # include fuzzy entries |
| 50 | +``` |
| 51 | +
|
| 52 | +## Commands |
| 53 | +
|
| 54 | +### poify |
| 55 | +
|
| 56 | +Converts game translation files (MSG, SVE, TXT, TRA) from a source language directory into a single `.pot` (PO Template) file. |
| 57 | + |
| 58 | +```bash |
| 59 | +poify [DIR] [-e ENC] [-v] [-q] [-t] |
| 60 | +``` |
| 61 | + |
| 62 | +| Argument | Description | Default | |
| 63 | +|----------|-------------|---------| |
| 64 | +| `DIR` | Source language directory | `./english` | |
| 65 | +| `-e ENC` | Source encoding | `cp1252` | |
| 66 | +| `-v, --verbose` | Enable verbose output | - | |
| 67 | +| `-q, --quiet` | Suppress info messages | - | |
| 68 | +| `-t, --timestamps` | Show timestamps in log output | - | |
| 69 | + |
| 70 | +**Example:** |
| 71 | + |
| 72 | +```bash |
| 73 | +poify ./english -e cp1252 |
| 74 | +``` |
| 75 | + |
| 76 | +This scans the `./english` directory for all translation files and creates `./po/english.pot`. |
| 77 | + |
| 78 | +--- |
| 79 | + |
| 80 | +### unpoify |
| 81 | + |
| 82 | +Extracts translated files from PO files back into the game's directory structure. Used after translation is done in Weblate/PO editor. |
| 83 | + |
| 84 | +```bash |
| 85 | +unpoify [DIR] [-v] [-q] [-t] |
| 86 | +``` |
| 87 | + |
| 88 | +| Argument | Description | Default | |
| 89 | +|----------|-------------|---------| |
| 90 | +| `DIR` | Directory with PO files | `./po` | |
| 91 | +| `-v, --verbose` | Enable verbose output | - | |
| 92 | +| `-q, --quiet` | Suppress info messages | - | |
| 93 | +| `-t, --timestamps` | Show timestamps in log output | - | |
| 94 | + |
| 95 | +**Example:** |
| 96 | + |
| 97 | +```bash |
| 98 | +unpoify ./po |
| 99 | +``` |
| 100 | + |
| 101 | +This reads PO files from `./po` and extracts translations back into language-specific directories (e.g., `./french/`). |
| 102 | + |
| 103 | +--- |
| 104 | + |
| 105 | +### file2po |
| 106 | + |
| 107 | +Converts a single game translation file (MSG, SVE, TXT, TRA) into a PO file. Useful for extracting from individual files. |
| 108 | + |
| 109 | +```bash |
| 110 | +file2po INPUT_SOURCE OUTPUT_PO [-e ENC] [-v] [-q] [-t] |
| 111 | +``` |
| 112 | + |
| 113 | +| Argument | Description | Default | |
| 114 | +|----------|-------------|---------| |
| 115 | +| `INPUT_SOURCE` | Input translation file | - | |
| 116 | +| `OUTPUT_PO` | Output PO file | - | |
| 117 | +| `-e ENC` | Source encoding | `cp1252` | |
| 118 | +| `-v, --verbose` | Enable verbose output | - | |
| 119 | +| `-q, --quiet` | Suppress info messages | - | |
| 120 | +| `-t, --timestamps` | Show timestamps in log output | - | |
| 121 | + |
| 122 | +**Example:** |
| 123 | + |
| 124 | +```bash |
| 125 | +file2po ./english/dialog.msg ./output.pot -e cp1252 |
| 126 | +``` |
| 127 | + |
| 128 | +--- |
| 129 | + |
| 130 | +### po2file |
| 131 | + |
| 132 | +Converts PO entries back into a single game translation file. The reverse of `file2po`. |
| 133 | + |
| 134 | +```bash |
| 135 | +po2file INPUT_FILE OUTPUT_FILE [-e ENC] [--path PATH] [-v] [-q] [-t] |
| 136 | +``` |
| 137 | + |
| 138 | +| Argument | Description | Default | |
| 139 | +|----------|-------------|---------| |
| 140 | +| `INPUT_FILE` | Input PO file | - | |
| 141 | +| `OUTPUT_FILE` | Output translation file | - | |
| 142 | +| `-e ENC` | Output encoding | `cp1252` | |
| 143 | +| `--path PATH` | File occurrence in PO (relative path) | Output filename | |
| 144 | +| `-v, --verbose` | Enable verbose output | - | |
| 145 | +| `-q, --quiet` | Suppress info messages | - | |
| 146 | +| `-t, --timestamps` | Show timestamps in log output | - | |
| 147 | + |
| 148 | +**Example:** |
20 | 149 |
|
21 | 150 | ```bash |
22 | | -$ poify.py -h |
23 | | -.bgforge.yml not found, assuming defaults |
24 | | -usage: poify.py [-h] [-e ENC] [DIR] |
| 151 | +po2file ./french.po ./french/dialog.msg -e cp1252 |
| 152 | +``` |
25 | 153 |
|
26 | | -Poify files in selected directory |
| 154 | +--- |
27 | 155 |
|
28 | | -positional arguments: |
29 | | - DIR source language directory (default: ./english) |
| 156 | +### file2msgstr |
30 | 157 |
|
31 | | -options: |
32 | | - -h, --help show this help message and exit |
33 | | - -e ENC source encoding (default: cp1252) |
| 158 | +Loads translations from a game translation file into the `msgstr` fields of an existing PO file. Useful for reloading edited translations. |
| 159 | + |
| 160 | +```bash |
| 161 | +file2msgstr INPUT_FILE OUTPUT_FILE [-e ENC] [--path PATH] [--overwrite] [--same] [-v] [-q] [-t] |
34 | 162 | ``` |
35 | 163 |
|
36 | | -### Action |
| 164 | +| Argument | Description | Default | |
| 165 | +|----------|-------------|---------| |
| 166 | +| `INPUT_FILE` | Input translation file | - | |
| 167 | +| `OUTPUT_FILE` | Output PO file (must exist) | - | |
| 168 | +| `-e ENC` | Source encoding | `cp1252` | |
| 169 | +| `--path PATH` | PO occurrence path | Input filename | |
| 170 | +| `--overwrite` | Overwrite existing translations | - | |
| 171 | +| `--same` | Load translations identical to original strings | - | |
| 172 | +| `-v, --verbose` | Enable verbose output | - | |
| 173 | +| `-q, --quiet` | Suppress info messages | - | |
| 174 | +| `-t, --timestamps` | Show timestamps in log output | - | |
37 | 175 |
|
38 | | -Github [action](docs/action.md) is available for automatic processing. |
| 176 | +**Example:** |
| 177 | + |
| 178 | +```bash |
| 179 | +file2msgstr ./french/dialog.msg ./french.po --overwrite |
| 180 | +``` |
39 | 181 |
|
40 | 182 | --- |
41 | 183 |
|
42 | | -[Changelog](docs/changelog.md) |
| 184 | +### dir2msgstr |
43 | 185 |
|
44 | | -### Unfuzzy |
| 186 | +Batch loads translations from all files in a directory into corresponding PO files. Reverse of `unpoify` - used when translators edit files directly instead of PO. |
45 | 187 |
|
46 | | -Unfuzzy removes fuzzy flag and previous msgid from PO entries, if after all replacements current msgid and previous msgid match exactly. Usually it is run after spelling changes in source language, to reduce diff noise and avoid extra review burden. |
| 188 | +```bash |
| 189 | +dir2msgstr [--auto] [-s SRC_DIR] [-o OUTPUT_FILE] [--ext EXT] [--same] [--overwrite] [-v] [-q] [-t] |
| 190 | +``` |
| 191 | + |
| 192 | +| Argument | Description | Default | |
| 193 | +|----------|-------------|---------| |
| 194 | +| `--auto` | Auto-find POs and language dirs, process all valid extensions | - | |
| 195 | +| `-s SRC_DIR` | Directory to load from | `.` | |
| 196 | +| `-o OUTPUT_FILE` | Existing PO file | - | |
| 197 | +| `--ext EXT` | Load files with this extension | - | |
| 198 | +| `--same` | Load translations identical to original strings | - | |
| 199 | +| `--overwrite` | Overwrite existing translations | - | |
| 200 | +| `-v, --verbose` | Enable verbose output | - | |
| 201 | +| `-q, --quiet` | Suppress info messages | - | |
| 202 | +| `-t, --timestamps` | Show timestamps in log output | - | |
| 203 | + |
| 204 | +**Example:** |
| 205 | + |
| 206 | +```bash |
| 207 | +dir2msgstr --auto |
| 208 | +``` |
47 | 209 |
|
48 | | -The comparison is case sensitive. The replacements are read from `unfuzzy.yml` in current directory, example: |
| 210 | +Or manually: |
| 211 | + |
| 212 | +```bash |
| 213 | +dir2msgstr -s ./french -o ./french.po --ext msg --overwrite |
| 214 | +``` |
| 215 | + |
| 216 | +--- |
| 217 | + |
| 218 | +### msgmerge-female |
| 219 | + |
| 220 | +Updates PO files from a POT template using GNU gettext's `msgmerge`, with special handling to keep female translations. Requires Gettext tools in PATH. |
| 221 | + |
| 222 | +```bash |
| 223 | +msgmerge-female [PO POT] [-v] [-q] [-t] |
| 224 | +``` |
| 225 | + |
| 226 | +| Argument | Description | Default | |
| 227 | +|----------|-------------|---------| |
| 228 | +| `PO` | PO file to update | - | |
| 229 | +| `POT` | POT template file | - | |
| 230 | +| `-v, --verbose` | Enable verbose output | - | |
| 231 | +| `-q, --quiet` | Suppress info messages | - | |
| 232 | +| `-t, --timestamps` | Show timestamps in log output | - | |
| 233 | + |
| 234 | +**Single file:** |
| 235 | + |
| 236 | +```bash |
| 237 | +msgmerge-female french.po english.pot |
| 238 | +``` |
| 239 | + |
| 240 | +**Batch (uses .bgforge.yml config):** |
| 241 | + |
| 242 | +```bash |
| 243 | +msgmerge-female |
| 244 | +``` |
| 245 | + |
| 246 | +--- |
| 247 | + |
| 248 | +### resave-po |
| 249 | + |
| 250 | +Resaves a PO file using the polib API to correct formatting. Useful for normalizing PO file structure. |
| 251 | + |
| 252 | +```bash |
| 253 | +resave-po INPUT_FILE [-v] [-q] [-t] |
| 254 | +``` |
| 255 | + |
| 256 | +| Argument | Description | Default | |
| 257 | +|----------|-------------|---------| |
| 258 | +| `INPUT_FILE` | PO file to resave | - | |
| 259 | +| `-v, --verbose` | Enable verbose output | - | |
| 260 | +| `-q, --quiet` | Suppress info messages | - | |
| 261 | +| `-t, --timestamps` | Show timestamps in log output | - | |
| 262 | + |
| 263 | +**Example:** |
| 264 | + |
| 265 | +```bash |
| 266 | +resave-po ./french.po |
| 267 | +``` |
| 268 | + |
| 269 | +--- |
| 270 | + |
| 271 | +### lowercase |
| 272 | + |
| 273 | +Recursively renames files and directories to lowercase. Useful for preparing case-insensitive file systems. |
| 274 | + |
| 275 | +```bash |
| 276 | +lowercase DIR [-v] [-q] [-t] |
| 277 | +``` |
| 278 | + |
| 279 | +| Argument | Description | Default | |
| 280 | +|----------|-------------|---------| |
| 281 | +| `DIR` | Directory to process | - | |
| 282 | +| `-v, --verbose` | Enable verbose output | - | |
| 283 | +| `-q, --quiet` | Suppress info messages | - | |
| 284 | +| `-t, --timestamps` | Show timestamps in log output | - | |
| 285 | + |
| 286 | +**Example:** |
| 287 | + |
| 288 | +```bash |
| 289 | +lowercase ./french |
| 290 | +``` |
| 291 | + |
| 292 | +Note: Excludes `.git`, `.svn`, `.hg`, `.github` directories, `.po` files, and `README.md`. |
| 293 | + |
| 294 | +--- |
| 295 | + |
| 296 | +### unfuzzy |
| 297 | + |
| 298 | +Removes fuzzy flags from PO entries where the previous msgid matches the current msgid after applying string replacements. Used to reduce diff noise after source language spelling changes. |
| 299 | + |
| 300 | +Create `unfuzzy.yml` with replacements: |
49 | 301 |
|
50 | 302 | ```yaml |
51 | 303 | - ["Nuka Cola", "Nuka-Cola"] |
52 | 304 | - ["nuka cola", "Nuka-Cola"] |
53 | 305 | ``` |
54 | 306 |
|
55 | | -Run |
| 307 | +```bash |
| 308 | +unfuzzy INPUT_FILE [-w] [-v] [-q] [-t] |
| 309 | +``` |
| 310 | + |
| 311 | +| Argument | Description | Default | |
| 312 | +|----------|-------------|---------| |
| 313 | +| `INPUT_FILE` | PO file to process | - | |
| 314 | +| `-w` | Write changes to file (without this, previews only) | - | |
| 315 | +| `-v, --verbose` | Enable verbose output | - | |
| 316 | +| `-q, --quiet` | Suppress info messages | - | |
| 317 | +| `-t, --timestamps` | Show timestamps in log output | - | |
| 318 | + |
| 319 | +**Example:** |
56 | 320 |
|
57 | 321 | ```bash |
58 | | -unfuzzy.py -w data/text/po/french.po |
| 322 | +unfuzzy ./french.po -w |
59 | 323 | ``` |
| 324 | + |
| 325 | +--- |
| 326 | + |
| 327 | +### bgforge-config |
| 328 | + |
| 329 | +Reads values from `.bgforge.yml` configuration. Primarily used by GitHub Actions. |
| 330 | + |
| 331 | +```bash |
| 332 | +bgforge-config STANZA KEY |
| 333 | +``` |
| 334 | + |
| 335 | +| Argument | Description | |
| 336 | +|----------|-------------| |
| 337 | +| `STANZA` | Config section (e.g., `translation`) | |
| 338 | +| `KEY` | Config key (e.g., `encoding`) | |
| 339 | + |
| 340 | +**Example:** |
| 341 | + |
| 342 | +```bash |
| 343 | +bgforge-config translation encoding |
| 344 | +``` |
| 345 | + |
| 346 | +--- |
| 347 | + |
| 348 | +## GitHub Action |
| 349 | + |
| 350 | +A GitHub Action is available for automatic processing. See [docs/action.md](docs/action.md) for details. |
0 commit comments