From bd4e1710fba550a516f013f7f5bd0dc5e21b658b Mon Sep 17 00:00:00 2001 From: Chun-Chi Hung Date: Fri, 28 Nov 2025 00:39:37 +0800 Subject: [PATCH 1/3] [Tool] Add tool for sorting. --- .contrib/.tools/normalize-lua-table.js | 121 +++++++++++++++++++++++++ .vscode/tasks.json | 15 +++ 2 files changed, 136 insertions(+) create mode 100644 .contrib/.tools/normalize-lua-table.js create mode 100644 .vscode/tasks.json diff --git a/.contrib/.tools/normalize-lua-table.js b/.contrib/.tools/normalize-lua-table.js new file mode 100644 index 00000000000..66331de32fa --- /dev/null +++ b/.contrib/.tools/normalize-lua-table.js @@ -0,0 +1,121 @@ +const fs = require("fs"); + +/** + * Normalize ATT localization tables into the canonical locale order. + * + * This script is intentionally limited to the simple, one-locale-per-line + * tables used by the parser data. It updates the supplied file in place, so + * callers should review the resulting Git diff before committing it. + */ + +// Keep this order aligned with the locale order used by ATT data files. +const expectedKeys = [ + "en","de","es","mx", + "fr","it","ko","pt", + "ru","cn","tw" +]; + +const file = process.argv[2]; +if (!file) { + console.error("Please provide the path of the file to process"); + process.exit(1); +} + +let content = fs.readFileSync(file, "utf8"); + +// Match only localization-bearing fields. The non-greedy body stops at the +// first closing brace on its own line, which is valid for the flat tables this +// tool supports. The final group preserves an optional Lua comma or semicolon. +const tableRegex = + /(^[ \t]*(text|description|lore)\s*=\s*\{)([\s\S]*?)(^\s*\})([ \t]*[,;]?)/gm; + +content = content.replace( + tableRegex, + (fullMatch, tableHeader, tableName, body, closingBraceLine, afterBrace) => { + + // Reuse the table header's indentation for the closing brace so running + // the tool does not disturb the surrounding Lua structure. + const headerIndent = tableHeader.match(/^(\s*)/)[1]; + + // Empty lines are removed during normalization. Only recognized locale + // assignments are retained; other content inside a matched table is out + // of scope for this deliberately narrow formatter. + const lines = body.split(/\r?\n/).filter((l) => l.trim() !== ""); + + const presentKeys = []; + const valueLines = []; + + for (const line of lines) { + // A translated locale, for example: en = "Example", + const normal = line.match(/^\s*(\w+)\s*=/); + + // Commented translations and TODO placeholders both count as present; + // otherwise a second placeholder for the same locale would be created. + const commented = line.match(/^\s*--\s*(?:TODO:\s*)?(\w+)\s*=/); + + if (normal) { + presentKeys.push(normal[1]); + valueLines.push(line); // Preserve as-is + } else if (commented) { + presentKeys.push(commented[1]); // Commented fields count as present + valueLines.push(line); // Preserve as-is + } + } + + // English-only entries are intentionally compact. TODO placeholders become + // useful only after an entry has started receiving additional translations. + if (presentKeys.length === 1 && presentKeys[0] === "en") { + return ( + `${tableHeader}\n` + + valueLines.join("\n") + + `\n${headerIndent}}${afterBrace}` + ); + } + + // Match generated TODO entries to the indentation of the first locale. + let firstIndent = ""; + if (valueLines.length > 0) { + const m = valueLines[0].match(/^(\s*)/); + firstIndent = m ? m[1] : ""; + } + + // Rebuild the table in canonical order. Values are reused verbatim so this + // step changes position and completeness, but never translation content. + const finalLines = []; + + for (const k of expectedKeys) { + // Prefer an active translation when both active and commented variants + // somehow exist for the same locale. + const existing = valueLines.find((l) => + l.trimStart().startsWith(k + " =") + ); + + const commented = valueLines.find((l) => + l.trimStart().startsWith("-- " + k + " =") || + l.trimStart().startsWith("-- TODO: " + k + " =") + ); + + if (existing) { + finalLines.push(existing); + } else if (commented) { + finalLines.push(commented); // Preserve commented line + } else { + // Make missing translations visible without creating executable Lua + // fields whose empty values might be mistaken for real translations. + finalLines.push(`${firstIndent}-- TODO: ${k} = "",`); + } + } + + return ( + `${tableHeader}\n` + + finalLines.join("\n") + + `\n${headerIndent}}${afterBrace}` + ); + } +); + +// Write once after all matching tables have been normalized. No backup file is +// created because Git is expected to provide review and recovery for this tool. +fs.writeFileSync(file, content, "utf8"); + +console.log("✅ Done: Commented fields are treated as existing, format fully preserved and keys reordered"); diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000000..e680c5c06d2 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,15 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Normalize Lua Table", + "type": "shell", + "command": "node", + // Run against the file in the active editor, rather than a fixed data file. + // Explicit quoting keeps paths containing spaces as one shell argument. + "args": ["${workspaceFolder}/.contrib/.tools/normalize-lua-table.js", "\"${file}\""], + "problemMatcher": [], + "group": "none" + } + ] +} From 40c0b96ef89a23080bde234a8416ed3c8150d1b9 Mon Sep 17 00:00:00 2001 From: Chun-Chi Hung Date: Wed, 22 Jul 2026 00:56:13 +0800 Subject: [PATCH 2/3] [Doc] Add readme. --- .contrib/.tools/README.md | 95 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 .contrib/.tools/README.md diff --git a/.contrib/.tools/README.md b/.contrib/.tools/README.md new file mode 100644 index 00000000000..95f27090558 --- /dev/null +++ b/.contrib/.tools/README.md @@ -0,0 +1,95 @@ +# Contributor Tools + +## Normalize Lua localization tables + +`normalize-lua-table.js` normalizes localization tables in a Lua data file. It is intended for contributors who edit `text`, `description`, or `lore` tables in the parser data. + +The tool: + +- processes every `text`, `description`, and `lore` table in the selected file; +- orders locale keys as `en`, `de`, `es`, `mx`, `fr`, `it`, `ko`, `pt`, `ru`, `cn`, and `tw`; +- adds a commented `TODO` entry for each missing locale; +- preserves existing locale values and existing commented locale entries; and +- leaves an English-only table English-only instead of adding `TODO` entries. + +### Requirements + +- [Node.js](https://nodejs.org/) must be installed and available as `node`. +- To use the included task, open the repository in Visual Studio Code. + +### Run from Visual Studio Code + +1. Open the Lua file that you want to normalize and make sure it is the active editor. +2. Open the Command Palette. +3. Select **Tasks: Run Task**. +4. Select **Normalize Lua Table**. +5. Wait for the terminal to report that the operation is complete. +6. Review the file's Git diff before keeping the result. + +The task uses the active editor's file. Save or switch to the intended file before running it. + +### Run from a terminal + +From the repository root, run: + +```sh +node .contrib/.tools/normalize-lua-table.js "path/to/data-file.lua" +``` + +For example: + +```sh +node .contrib/.tools/normalize-lua-table.js ".contrib/Parser/DATAS/00 - DB/ObjectDB.lua" +``` + +### Example + +Input: + +```lua +text = { + en = "Example", + fr = "Exemple", +} +``` + +Output: + +```lua +text = { + en = "Example", + -- TODO: de = "", + -- TODO: es = "", + -- TODO: mx = "", + fr = "Exemple", + -- TODO: it = "", + -- TODO: ko = "", + -- TODO: pt = "", + -- TODO: ru = "", + -- TODO: cn = "", + -- TODO: tw = "", +} +``` + +An English-only table remains compact: + +```lua +text = { + en = "English only", +} +``` + +### Safety and limitations + +The tool edits the selected file in place and does not create a backup. Commit or stash unrelated work first, then review the complete diff after it runs. + +Use it only on localization tables containing one locale assignment per line, for example `de = "..."`, `-- de = "..."`, or `-- TODO: de = "..."`. Blank lines and content that is not recognized as a locale assignment are not retained inside a matched table. + +To inspect the result: + +```sh +git diff -- "path/to/data-file.lua" +git diff --check +``` + +If the result is not expected, restore it with your normal Git workflow before making additional edits. From 457edb871b5cd83f564ff78046c19b74c6f3742f Mon Sep 17 00:00:00 2001 From: Chun-Chi Hung Date: Thu, 6 Aug 2026 21:29:17 +0800 Subject: [PATCH 3/3] [Tool] Move Lua normalizer. --- .../.tools/{normalize-lua-table.js => Lua/normalize.js} | 0 .contrib/.tools/README.md | 6 +++--- .vscode/tasks.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename .contrib/.tools/{normalize-lua-table.js => Lua/normalize.js} (100%) diff --git a/.contrib/.tools/normalize-lua-table.js b/.contrib/.tools/Lua/normalize.js similarity index 100% rename from .contrib/.tools/normalize-lua-table.js rename to .contrib/.tools/Lua/normalize.js diff --git a/.contrib/.tools/README.md b/.contrib/.tools/README.md index 95f27090558..8f0adffb328 100644 --- a/.contrib/.tools/README.md +++ b/.contrib/.tools/README.md @@ -2,7 +2,7 @@ ## Normalize Lua localization tables -`normalize-lua-table.js` normalizes localization tables in a Lua data file. It is intended for contributors who edit `text`, `description`, or `lore` tables in the parser data. +[`Lua/normalize.js`](Lua/normalize.js) normalizes localization tables in a Lua data file. It is intended for contributors who edit `text`, `description`, or `lore` tables in the parser data. The tool: @@ -33,13 +33,13 @@ The task uses the active editor's file. Save or switch to the intended file befo From the repository root, run: ```sh -node .contrib/.tools/normalize-lua-table.js "path/to/data-file.lua" +node .contrib/.tools/Lua/normalize.js "path/to/data-file.lua" ``` For example: ```sh -node .contrib/.tools/normalize-lua-table.js ".contrib/Parser/DATAS/00 - DB/ObjectDB.lua" +node .contrib/.tools/Lua/normalize.js ".contrib/Parser/DATAS/00 - DB/ObjectDB.lua" ``` ### Example diff --git a/.vscode/tasks.json b/.vscode/tasks.json index e680c5c06d2..013c53c7b68 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -7,7 +7,7 @@ "command": "node", // Run against the file in the active editor, rather than a fixed data file. // Explicit quoting keeps paths containing spaces as one shell argument. - "args": ["${workspaceFolder}/.contrib/.tools/normalize-lua-table.js", "\"${file}\""], + "args": ["${workspaceFolder}/.contrib/.tools/Lua/normalize.js", "\"${file}\""], "problemMatcher": [], "group": "none" }