gpt-po 1.0.8 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,25 +21,29 @@ Set `OPENAI_API_KEY` before using this tool.
21
21
 
22
22
  - `gpt-po sync --po <file> --pot <file>` Update the po file based on the pot file, while preserving the original translations.
23
23
  - `gpt-po --po <file>` Translate specified po files to a designated target language. By default, the target language is Simplified Chinese.
24
+ - `gpt-po --po <file> --lang <lang>` Translate specified po files to a designated target language.
24
25
  - `gpt-po --dir .` Translate all po files in current directory to a designated target language.
25
26
  - `gpt-po userdict` Modify or view user dictionaries
27
+ - `gpt-po userdict --explore` Explore user dictionaries, if you want add new dictionaries or modify existing dictionaries. dictionaries can be named as `dictionary-<lang>.json`, for example, `dictionary-simplified-chinese.json` is the dictionary for Simplified Chinese.
26
28
  - `gpt-po systemprompt` Modify or view system prompts, if you are not sure how to use it, you can leave it alone
29
+ - `gpt-po systemprompt --reset` Reset system prompts
27
30
 
28
31
  ```
29
- Usage: gpt-po [command] [options]
32
+ Usage: gpt-po [options] [command]
30
33
 
31
34
  command tool for translate po files by gpt
32
35
 
33
36
  Options:
34
- -V, --version output the version number
35
- -h, --help display help for command
37
+ -V, --version output the version number
38
+ -h, --help display help for command
36
39
 
37
40
  Commands:
38
- translate [options] translate po file (default command)
39
- sync [options] update po from pot file
40
- systemprompt open/edit system prompt
41
- userdict open/edit user dictionary
42
- help [command] display help for command
41
+ translate [options] translate po file (default command)
42
+ sync [options] update po from pot file
43
+ systemprompt [options] open/edit system prompt
44
+ userdict [options] open/edit user dictionary
45
+ remove [options] remove po entries by options
46
+ help [command] display help for command
43
47
  ```
44
48
 
45
49
  ```
@@ -60,3 +64,20 @@ Options:
60
64
  -o, --output <file> output file path, overwirte po file by default
61
65
  -h, --help display help for command
62
66
  ```
67
+
68
+ ```
69
+ Usage: gpt-po remove [options]
70
+
71
+ remove po entries by options
72
+
73
+ Options:
74
+ --po <file> po file path
75
+ --fuzzy remove fuzzy entries
76
+ -obs, --obsolete remove obsolete entries
77
+ -ut, --untranslated remove untranslated entries
78
+ -t, --translated remove translated entries
79
+ -tnf, --translated-not-fuzzy remove translated not fuzzy entries
80
+ -ft, --fuzzy-translated remove fuzzy translated entries
81
+ -rc, --reference-contains <text> remove entries whose reference contains text, text can be a regular expression like /text/ig
82
+ -h, --help display help for command
83
+ ```
package/README_zh-CN.md CHANGED
@@ -21,25 +21,29 @@ npm install gpt-po
21
21
 
22
22
  - `gpt-po sync --po <file> --pot <file>` 根据pot文件更新po文件,保留原有翻译
23
23
  - `gpt-po --po <file>` 翻译指定的po文件到指定的目标语言,默认目标语言是简体中文
24
+ - `gpt-po --po <file> --lang <lang>` Translate specified po files to a designated target language.
24
25
  - `gpt-po --dir .` 翻译当前目录下的所有po文件到指定的目标语言,默认目标语言是简体中文
25
26
  - `gpt-po userdict` 修改或查看用户字典
27
+ - `gpt-po userdict --explore` 用于浏览字典目录, 如果你想要增加或修改现有的字典。字典可以按`dictionary-<lang>.json`格式命令, 例如, `dictionary-simplified-chinese.json` 是针对简体中文的字典.
26
28
  - `gpt-po systemprompt` 修改或查看系统提示词,如果你不确定如何使用,可以不用修改
29
+ - `gpt-po systemprompt --reset` 重置系统提示词
27
30
 
28
31
  ```
29
- Usage: gpt-po [command] [options]
32
+ Usage: gpt-po [options] [command]
30
33
 
31
34
  command tool for translate po files by gpt
32
35
 
33
36
  Options:
34
- -V, --version output the version number
35
- -h, --help display help for command
37
+ -V, --version output the version number
38
+ -h, --help display help for command
36
39
 
37
40
  Commands:
38
- translate [options] translate po file (default command)
39
- sync [options] update po from pot file
40
- systemprompt open/edit system prompt
41
- userdict open/edit user dictionary
42
- help [command] display help for command
41
+ translate [options] translate po file (default command)
42
+ sync [options] update po from pot file
43
+ systemprompt [options] open/edit system prompt
44
+ userdict [options] open/edit user dictionary
45
+ remove [options] remove po entries by options
46
+ help [command] display help for command
43
47
  ```
44
48
 
45
49
  ```
@@ -53,10 +57,27 @@ Options:
53
57
  --model <model> openai model (choices: "gpt-4", "gpt-4-0314", "gpt-4-32k", "gpt-4-32k-0314", "gpt-3.5-turbo", "gpt-3.5-turbo-0301",
54
58
  default: "gpt-3.5-turbo")
55
59
  --po <file> po file path
56
- --dir <dir> po files directory
60
+ --dir <dir> po file directory
57
61
  -src, --source <lang> source language (default: "english")
58
62
  --verbose show verbose log
59
63
  -l, --lang <lang> target language (default: "simplified chinese")
60
64
  -o, --output <file> output file path, overwirte po file by default
61
65
  -h, --help display help for command
62
66
  ```
67
+
68
+ ```
69
+ Usage: gpt-po remove [options]
70
+
71
+ remove po entries by options
72
+
73
+ Options:
74
+ --po <file> po file path
75
+ --fuzzy remove fuzzy entries
76
+ -obs, --obsolete remove obsolete entries
77
+ -ut, --untranslated remove untranslated entries
78
+ -t, --translated remove translated entries
79
+ -tnf, --translated-not-fuzzy remove translated not fuzzy entries
80
+ -ft, --fuzzy-translated remove fuzzy translated entries
81
+ -rc, --reference-contains <text> remove entries whose reference contains text, text can be a regular expression like /text/ig
82
+ -h, --help display help for command
83
+ ```
package/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gpt-po",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "command tool for translate po files by gpt",
5
5
  "main": "lib/src/index.js",
6
6
  "bin": {
@@ -37,7 +37,7 @@
37
37
  "@types/jest": "^29.5.1",
38
38
  "jest": "^29.5.0",
39
39
  "ncp": "^2.0.0",
40
- "prettier": "^3.0.0-alpha.7-for-vscode",
40
+ "prettier": "^3.0.3",
41
41
  "rimraf": "^5.0.0",
42
42
  "ts-jest": "^29.1.0",
43
43
  "tslint": "^6.1.3",
package/lib/src/index.js CHANGED
@@ -15,6 +15,7 @@ const pkg = require("../package.json");
15
15
  const sync_1 = require("./sync");
16
16
  const translate_1 = require("./translate");
17
17
  const utils_1 = require("./utils");
18
+ const manipulate_1 = require("./manipulate");
18
19
  const program = new commander_1.Command();
19
20
  program.name(pkg.name).version(pkg.version).description(pkg.description);
20
21
  program
@@ -92,13 +93,47 @@ program
92
93
  program
93
94
  .command("userdict")
94
95
  .description("open/edit user dictionary")
95
- .action(() => {
96
+ .option("--explore", "open user dictionary directory")
97
+ .action((args) => {
98
+ const { explore } = args;
96
99
  // open `dictionary.json` file by system text default editor
97
100
  const copyFile = __dirname + "/dictionary.json";
98
101
  // user home path
99
102
  const dictFile = (0, utils_1.findConfig)("dictionary.json");
103
+ if (explore) {
104
+ // open user dictionary directory
105
+ return (0, utils_1.openFileExplorer)(dictFile);
106
+ }
100
107
  (0, utils_1.copyFileIfNotExists)(dictFile, copyFile);
101
108
  (0, utils_1.openFileByDefault)(dictFile);
102
109
  });
110
+ // program command `remove` with help text `remove po entries by options`
111
+ program
112
+ .command("remove")
113
+ .description("remove po entries by options")
114
+ .requiredOption("--po <file>", "po file path")
115
+ .option("--fuzzy", "remove fuzzy entries")
116
+ .option("-obs, --obsolete", "remove obsolete entries")
117
+ .option("-ut, --untranslated", "remove untranslated entries")
118
+ .option("-t, --translated", "remove translated entries")
119
+ .option("-tnf, --translated-not-fuzzy", "remove translated not fuzzy entries")
120
+ .option("-ft, --fuzzy-translated", "remove fuzzy translated entries")
121
+ .option("-rc, --reference-contains <text>", "remove entries whose reference contains text, text can be a regular expression like /text/ig")
122
+ .action((args) => __awaiter(void 0, void 0, void 0, function* () {
123
+ const { po, fuzzy, obsolete, untranslated, translated, translatedNotFuzzy, fuzzyTranslated, referenceContains } = args;
124
+ const options = {
125
+ fuzzy,
126
+ obsolete,
127
+ untranslated,
128
+ translated,
129
+ translatedNotFuzzy,
130
+ fuzzyTranslated,
131
+ referenceContains,
132
+ };
133
+ const output = args.output || po;
134
+ const translations = yield (0, utils_1.parsePo)(po);
135
+ yield (0, utils_1.compilePo)((0, manipulate_1.removeByOptions)(translations, options), output);
136
+ console.log("done");
137
+ }));
103
138
  program.parse(process.argv);
104
139
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,14 @@
1
+ import { GetTextTranslations } from "gettext-parser";
2
+ export interface RemoveByOptions {
3
+ fuzzy?: boolean;
4
+ obsolete?: boolean;
5
+ untranslated?: boolean;
6
+ translated?: boolean;
7
+ translatedNotFuzzy?: boolean;
8
+ fuzzyTranslated?: boolean;
9
+ referenceContains?: string;
10
+ }
11
+ /**
12
+ * remove entity by options
13
+ */
14
+ export declare function removeByOptions(potrans: GetTextTranslations, options: RemoveByOptions | undefined): GetTextTranslations;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.removeByOptions = void 0;
4
+ /**
5
+ * remove entity by options
6
+ */
7
+ function removeByOptions(potrans, options) {
8
+ var _a, _b, _c, _d, _e, _f, _g, _h;
9
+ const fuzzyRegx = /\bfuzzy\b/;
10
+ const obsoleteRegx = /\bobsolete\b/;
11
+ const refRegMatch = (options === null || options === void 0 ? void 0 : options.referenceContains)
12
+ ? /^\/([^\/]+)\/([igmsuy]*)/.exec(options === null || options === void 0 ? void 0 : options.referenceContains)
13
+ : null;
14
+ const refRegx = refRegMatch ? new RegExp(refRegMatch[1], refRegMatch[2]) : null;
15
+ for (const [ctx, entries] of Object.entries(potrans.translations)) {
16
+ for (const [msgid, entry] of Object.entries(entries)) {
17
+ const msgstr = entry.msgstr.join("\n");
18
+ // remove fuzzy
19
+ if ((options === null || options === void 0 ? void 0 : options.fuzzy) && fuzzyRegx.test(((_a = entry.comments) === null || _a === void 0 ? void 0 : _a.flag) || "")) {
20
+ delete potrans.translations[ctx][msgid];
21
+ }
22
+ // remove obsolete
23
+ if ((options === null || options === void 0 ? void 0 : options.obsolete) && obsoleteRegx.test(((_b = entry.comments) === null || _b === void 0 ? void 0 : _b.flag) || "")) {
24
+ delete potrans.translations[ctx][msgid];
25
+ }
26
+ // remove untranslated
27
+ if ((options === null || options === void 0 ? void 0 : options.untranslated) && msgstr.length === 0) {
28
+ delete potrans.translations[ctx][msgid];
29
+ }
30
+ // remove translated
31
+ if ((options === null || options === void 0 ? void 0 : options.translated) && msgstr.length > 0) {
32
+ delete potrans.translations[ctx][msgid];
33
+ }
34
+ // remove translated not fuzzy
35
+ if ((options === null || options === void 0 ? void 0 : options.translatedNotFuzzy) && msgstr.length > 0 && !fuzzyRegx.test(((_c = entry.comments) === null || _c === void 0 ? void 0 : _c.flag) || "")) {
36
+ delete potrans.translations[ctx][msgid];
37
+ }
38
+ // remove fuzzy translated
39
+ if ((options === null || options === void 0 ? void 0 : options.fuzzyTranslated) && msgstr.length > 0 && fuzzyRegx.test(((_d = entry.comments) === null || _d === void 0 ? void 0 : _d.flag) || "")) {
40
+ delete potrans.translations[ctx][msgid];
41
+ }
42
+ // remove reference contains
43
+ if (options === null || options === void 0 ? void 0 : options.referenceContains) {
44
+ if (refRegx) {
45
+ if (((_e = entry.comments) === null || _e === void 0 ? void 0 : _e.reference) && refRegx.test((_f = entry.comments) === null || _f === void 0 ? void 0 : _f.reference)) {
46
+ delete potrans.translations[ctx][msgid];
47
+ }
48
+ }
49
+ else if ((_h = (_g = entry.comments) === null || _g === void 0 ? void 0 : _g.reference) === null || _h === void 0 ? void 0 : _h.includes(options === null || options === void 0 ? void 0 : options.referenceContains)) {
50
+ delete potrans.translations[ctx][msgid];
51
+ }
52
+ }
53
+ }
54
+ }
55
+ return potrans;
56
+ }
57
+ exports.removeByOptions = removeByOptions;
58
+ //# sourceMappingURL=manipulate.js.map
@@ -38,13 +38,15 @@ function init(force) {
38
38
  if (!_userdict || force) {
39
39
  const userdict = (0, utils_1.findConfig)("dictionary.json");
40
40
  (0, utils_1.copyFileIfNotExists)(userdict, (0, path_1.join)(__dirname, "dictionary.json"));
41
- _userdict = JSON.parse(fs.readFileSync(userdict, "utf-8"));
41
+ _userdict = { "default": JSON.parse(fs.readFileSync(userdict, "utf-8")) };
42
42
  }
43
43
  return _openai;
44
44
  }
45
45
  exports.init = init;
46
46
  function translate(text, src, lang, model = "gpt-3.5-turbo") {
47
- const dicts = Object.entries(_userdict)
47
+ const lang_code = lang.toLowerCase().trim().replace(/[\W_]+/g, "-");
48
+ const dicts = Object.entries(_userdict[lang_code] || _userdict["default"])
49
+ .filter(([k, _]) => text.toLowerCase().includes(k.toLowerCase()))
48
50
  .map(([k, v]) => [
49
51
  { role: "user", content: k },
50
52
  { role: "assistant", content: v },
@@ -56,7 +58,7 @@ function translate(text, src, lang, model = "gpt-3.5-turbo") {
56
58
  messages: [
57
59
  {
58
60
  role: "system",
59
- content: _systemprompt + ` Translate the ${src} user content into ${lang} language. Please translate it as a text, not as a table. The parts that cannot be translated will retain their original format.`
61
+ content: _systemprompt + ` Translate the ${src} content provided by the user into ${lang}. Please translate it as a text, not as a table. The parts that cannot be translated will retain their original format.`
60
62
  },
61
63
  // add userdict here
62
64
  ...dicts,
@@ -70,6 +72,15 @@ exports.translate = translate;
70
72
  function translatePo(model = "gpt-3.5-turbo", po, source, lang, verbose, output) {
71
73
  var _a;
72
74
  return __awaiter(this, void 0, void 0, function* () {
75
+ // try to load dictionary by lang-code if it not loaded
76
+ const lang_code = lang.toLowerCase().trim().replace(/[\W_]+/g, "-");
77
+ if (!_userdict[lang_code]) {
78
+ const lang_dic_file = (0, utils_1.findConfig)(`dictionary-${lang_code}.json`);
79
+ if (fs.existsSync(lang_dic_file)) {
80
+ _userdict[lang_code] = JSON.parse(fs.readFileSync(lang_dic_file, "utf-8"));
81
+ console.log(`dictionary-${lang_code}.json is loaded.`);
82
+ }
83
+ }
73
84
  const potrans = yield (0, utils_1.parsePo)(po);
74
85
  const list = [];
75
86
  const trimRegx = /(?:^ )|(?: $)/;
@@ -11,4 +11,17 @@ export declare function parsePo(poFile: string, defaultCharset?: string): Promis
11
11
  export declare function compilePo(data: GetTextTranslations, poFile: string): Promise<void>;
12
12
  export declare function printProgress(progress: number, total: number, extra?: string): void;
13
13
  export declare function gitRootDir(dir?: string): string | null;
14
+ /**
15
+ * find config file in the following order:
16
+ * 1. current directory
17
+ * 2. git root directory
18
+ * 3. home directory
19
+ * @param fileName
20
+ * @returns full path of the config file
21
+ */
14
22
  export declare function findConfig(fileName: string): string;
23
+ /**
24
+ * open file explorer by platform
25
+ * @param location folder or file path
26
+ */
27
+ export declare function openFileExplorer(location: string): void;
package/lib/src/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.findConfig = exports.gitRootDir = exports.printProgress = exports.compilePo = exports.parsePo = exports.openFileByDefault = exports.copyFileIfNotExists = void 0;
3
+ exports.openFileExplorer = exports.findConfig = exports.gitRootDir = exports.printProgress = exports.compilePo = exports.parsePo = exports.openFileByDefault = exports.copyFileIfNotExists = void 0;
4
4
  const child_process_1 = require("child_process");
5
5
  const fs = require("fs");
6
6
  const gettext_parser_1 = require("gettext-parser");
@@ -88,6 +88,14 @@ function gitRootDir(dir) {
88
88
  }
89
89
  }
90
90
  exports.gitRootDir = gitRootDir;
91
+ /**
92
+ * find config file in the following order:
93
+ * 1. current directory
94
+ * 2. git root directory
95
+ * 3. home directory
96
+ * @param fileName
97
+ * @returns full path of the config file
98
+ */
91
99
  function findConfig(fileName) {
92
100
  const currentDir = process.cwd();
93
101
  const gitDir = gitRootDir() || currentDir;
@@ -107,4 +115,21 @@ function findConfig(fileName) {
107
115
  return path.join(homeDir, ".gpt-po", fileName);
108
116
  }
109
117
  exports.findConfig = findConfig;
118
+ /**
119
+ * open file explorer by platform
120
+ * @param location folder or file path
121
+ */
122
+ function openFileExplorer(location) {
123
+ if ((0, os_1.platform)() === 'win32') {
124
+ (0, child_process_1.exec)(`explorer.exe "${path.dirname(location)}"`);
125
+ }
126
+ else if ((0, os_1.platform)() === 'darwin') {
127
+ (0, child_process_1.exec)(`open "${path.dirname(location)}"`);
128
+ }
129
+ else {
130
+ // Assuming a Linux-based system
131
+ (0, child_process_1.exec)(`xdg-open "${path.dirname(location)}"`);
132
+ }
133
+ }
134
+ exports.openFileExplorer = openFileExplorer;
110
135
  //# sourceMappingURL=utils.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gpt-po",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "command tool for translate po files by gpt",
5
5
  "main": "lib/src/index.js",
6
6
  "bin": {
@@ -37,7 +37,7 @@
37
37
  "@types/jest": "^29.5.1",
38
38
  "jest": "^29.5.0",
39
39
  "ncp": "^2.0.0",
40
- "prettier": "^3.0.0-alpha.7-for-vscode",
40
+ "prettier": "^3.0.3",
41
41
  "rimraf": "^5.0.0",
42
42
  "ts-jest": "^29.1.0",
43
43
  "tslint": "^6.1.3",
@@ -52,4 +52,4 @@
52
52
  "engines": {
53
53
  "node": ">=12.0.0"
54
54
  }
55
- }
55
+ }