UNPKG

unity-i18n

Version:
229 lines 10.7 kB
import { install } from 'source-map-support'; install(); import program from 'commander'; import fs from 'fs-extra'; import lockfile from 'proper-lockfile'; import { Localizer } from "./Localizer.js"; import { exit } from 'process'; import UnityHardTasks from "./example/UnityHardTasks.js"; import LayaTasks from "./example/LayaTasks.js"; import Laya3Tasks from "./example/Laya3Tasks.js"; import UnitySoftTasks from './example/UnitySoftTasks.js'; import path from 'path'; import { Translator } from './Translator.js'; import { fileURLToPath } from 'url'; import { toolchain } from './toolchain.js'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const myPackage = await fs.readJSON(path.join(__dirname, '../package.json')); const rmQuotes = (val) => { let rst = val.match(/(['"])(.+)\1/); if (rst) return rst[2]; return val; }; const parseTaskReplacer = (val) => { val = rmQuotes(val); let r = {}; let varr = val.split('&'); for (let v of varr) { let pair = v.split('='); r[pair[0]] = pair[1]; } return r; }; // for exmaple program .version(myPackage.version, "-v, --version") .option("-s, --src <path>", "[MUST] Input files path. Both direction or single file.", rmQuotes) .option("-o, --output <path>", "[MUST] Outout path. Both direction or single file.", rmQuotes) .option("--langs <string[]>", "Language codes, seperated by comma. Like EN,FR. LOCAL as defaults") .option("-t, --tasks <json object/.json path/.js path>", "Task json file.", rmQuotes) .option("-d, --default <unity|laya|xml2bin>", "Execute default tasks defined for unity/laya/xml2bin project.", rmQuotes) .option("--task-replacer <string>", "Replace variants in default tasks, if not giver, default will be used.", parseTaskReplacer) .option("-S, --search", "Search mode.") .option("-R, --replace", "Replace mode.") .option("--soft-replace", "Soft replace mode.") .option("--silent", "Silent mode.") .option("-x, --xlsxstyle <prepend|append|sort-by-id>", "Xlsx sort rule.", 'append') .option("-l, --log", "Generate log file.") .option("--pretty", "Generate pretty json files.") .option("--strict", "Strict mode.") .option("--lockfile <string>", "Lock file to check.") .option("--individual", "Make individual files for each language.") .option("--validate [string]", "Specify which languages to be validated.") .option("--ignore-errors", "Ignore errors, won't exit when not passing validation.") .option("--auto-trans <string[]>", "Auto translate or not.") .option("--debug", "Debug mode.") .parse(process.argv); const opts = program.opts(); console.log('cmd options:', opts); async function main() { if (!opts.src && !opts.tasks) { console.error("The --src option is MUST."); program.help({ error: true }); } if (!opts.output && !opts.tasks) { console.error("The --output option is MUST."); program.help({ error: true }); } // if(!opts.softReplace && opts.langs && opts.langs.length > 1) { // console.error("Hard replace mode supports only 1 language. If you want to support multiple languages, use --soft-replace."); // program.help({error:true}); // } if (!opts.langs) opts.langs = 'LOCAL'; // 检查lockfile,防止和版本构建冲突 if (opts.lockfile) { const lf = path.join(opts.src, opts.lockfile); const lockStatus = await lockfile.check(lf, { realpath: false }); if (lockStatus) { console.error('[unity-i18n]Workspace locked! Please wait! 正在构版本,请稍候。'); process.exit(1); } await lockfile.lock(lf, { realpath: false }); } const localizer = new Localizer(); const globalOption = { inputRoot: opts.src, outputRoot: opts.output, langs: opts.langs.split(','), replacer: {}, softReplace: opts.softReplace, autoTrans: opts.autoTrans?.split(',') }; toolchain.globalOption = globalOption; if (opts.silent) { globalOption.silent = opts.silent; } if (opts.log) { globalOption.logFile = path.join(opts.output, 'log.txt'); globalOption.reportFile = path.join(opts.output, 'report.json'); if (fs.existsSync(globalOption.logFile)) await fs.unlink(globalOption.logFile); if (fs.existsSync(globalOption.reportFile)) await fs.unlink(globalOption.reportFile); } if (opts.xlsxstyle) { globalOption.xlsxStyle = opts.xlsxstyle; } if (opts.pretty) { globalOption.pretty = opts.pretty; } if (opts.strict) { globalOption.strict = opts.strict; } if (opts.individual && opts.langs.length > 1) { globalOption.individual = true; } if (opts.validate) { globalOption.validate = opts.validate.split(','); } if (opts.ignoreErrors) { globalOption.ignoreErrors = opts.ignoreErrors; } if (opts.debug) { globalOption.debug = opts.debug; } await localizer.prepare(globalOption); if (opts.autoTrans?.length > 0) { Translator.setup(opts.output); } // for (const lang of ['EN', 'INA', 'TW', 'Thai']) { // const cacheFile = path.join(opts.output, `${lang}.cache.txt`); // const content = await fs.readFile(cacheFile, 'utf-8'); // const lines = content.split(/\r?\n/); // for (let i = 0, cnt = Math.floor(lines.length / 2); i < cnt; i++) { // if (lines[i * 2].includes('^|^|#N|$')) { // lines[i * 2] = ''; // lines[i * 2 + 1] = ''; // } // } // await fs.writeFile(cacheFile, lines.filter((v) => Boolean(v)).join('\n'), 'utf-8'); // } // console.log(await Translator.translateTo('(?{D}天)(?{h}时) {mm}:{ss}', 'Thai', globalOption)); // console.log(await Translator.translateTo('(?{D}天){hh}:{mm}:{ss}', 'Thai', globalOption)); // console.log(await Translator.translateTo('(?{D}天){hh}:{mm}', 'Thai', globalOption)); // console.log(await Translator.translateTo('(?{D}天) {h}:{m}:{s}', 'Thai', globalOption)); // console.log(await Translator.translateTo('(?{D}天) {hh}:{mm}:{ss}', 'Thai', globalOption)); // Translator.translateTo('十六', 'Thai', globalOption); // console.log(await Translator.translateTo('对敌方1个目标造成30次129%魂力伤害,同时对自己迟缓(魂力闪避-75%),持续2秒', 'EN', globalOption)); // console.log(await Translator.translateTo('对敌方21个目标造成8.3%{0}的魂力伤害', 'EN', globalOption)); // console.log(await Translator.translateTo('<url=0>集市中可以购买修为丹药,点击跳转<color=#D5950C>集市</color></url>\n<url=1>炼药房中可以获得修为丹药,点击跳转<color=#D5950C>炼药房</color></url>', 'EN', globalOption)); // console.log(await Translator.translateTo('1. 击败其他位面来袭的修行者可获得万界抵御福袋,每周最多获取10个。#N2. 前往其他位面击败修行者,可获得万界击败福袋,每周最多获取10个。', 'EN', globalOption)); // Translator.translateTo('即将进入九幽黄泉获取传承,彩鳞与萧炎惜别。九彩吞天蟒,不日现世大陆!', 'Thai', globalOption); // console.log(await Translator.translateTo('<color=#EDD5B0>倒计时:</color><color=#5BFFC7>{0}后结束</color>', 'Thai', globalOption)); // Translator.translateTo('您获得了:{%d} {%s}', 'EN'); // Translator.translateTo('购买<color=#BB5959>超值礼包</color>,<color=#BB5959>大幅提升</color>战力', 'EN'); // Translator.translateTo('对敌方2个目标攻击2次,每次造成180%X0斗气伤害,附加斗气回复效果降低60%,持续8秒', 'EN'); // Translator.translateTo('对敌方2个目标攻击2次,每次造成180%@SH0 斗气伤害,附加斗气回复效果降低60%,持续8秒', 'EN'); // Translator.translateTo('累计战力提升230亿', 'Russian', globalOption); if (opts.default) { if (opts.default == 'xml2bin') { if (opts.replace) { globalOption.replacer = opts.taskReplacer || LayaTasks.replacer; localizer.replaceZhInFiles(LayaTasks.xml2binReplaceTasks, globalOption); } } else { let tasks; if (opts.default == 'unity' || opts.default == 'unity_hard') { tasks = UnityHardTasks; } else if (opts.default == 'unity_soft') { tasks = UnitySoftTasks; } else if (opts.default == 'laya' || opts.default == 'laya_hard') { tasks = LayaTasks; } else if (opts.default == 'laya3') { tasks = Laya3Tasks; } if (tasks) { globalOption.replacer = opts.taskReplacer || tasks.replacer; if (opts.search) { await localizer.searchZhInFiles(tasks.searchTasks, globalOption); } if (opts.replace) { await localizer.replaceZhInFiles(tasks.replaceTasks, globalOption); } } else { console.error('Cannot find default tasks for: %s', opts.default); exit(1); } } } else if (opts.tasks) { let tasksObj = null; if (typeof (opts.tasks) == 'object') { // json tasksObj = opts.tasks; } else if (typeof (opts.tasks) == 'string') { // json file let tasksFile = opts.tasks; if (!fs.existsSync(tasksFile)) { console.error('Cannot find tasks file: %s', tasksFile); exit(1); } let tasksContent = fs.readFileSync(tasksFile, 'utf-8'); tasksObj = JSON.parse(tasksContent); } if (tasksObj) { try { if (opts.search) { localizer.searchZhInFiles(tasksObj, globalOption); } if (opts.replace) { localizer.replaceZhInFiles(tasksObj, globalOption); } } catch (e) { console.log(e); process.exit(1); } } } } main(); //# sourceMappingURL=index.js.map