gpt-po 1.2.0 → 1.2.3
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 +1 -1
- package/README_zh-CN.md +1 -1
- package/lib/package.json +1 -1
- package/lib/src/index.d.ts +1 -1
- package/lib/src/index.js +39 -14
- package/lib/src/sync.d.ts +2 -1
- package/lib/src/sync.js +2 -2
- package/lib/src/translate.d.ts +3 -2
- package/lib/src/translate.js +17 -9
- package/lib/src/userprompt.txt +8 -1
- package/lib/src/utils.d.ts +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
@@ -60,7 +60,7 @@ Options:
|
|
60
60
|
--verbose show verbose log
|
61
61
|
-l, --lang <lang> target language (ISO 639-1 code)
|
62
62
|
-o, --output <file> output file path, overwirte po file by default
|
63
|
-
--context
|
63
|
+
--context <file> context file path (provides additional context to the bot)
|
64
64
|
-h, --help display help for command
|
65
65
|
```
|
66
66
|
|
package/README_zh-CN.md
CHANGED
package/lib/package.json
CHANGED
package/lib/src/index.d.ts
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
#!/usr/bin/env node --no-warnings=ExperimentalWarning
|
1
|
+
#!/usr/bin/env -S node --no-warnings=ExperimentalWarning
|
2
2
|
export {};
|
package/lib/src/index.js
CHANGED
@@ -1,18 +1,34 @@
|
|
1
|
-
#!/usr/bin/env node --no-warnings=ExperimentalWarning
|
1
|
+
#!/usr/bin/env -S node --no-warnings=ExperimentalWarning
|
2
2
|
import { Command, Option } from "commander";
|
3
3
|
import path from "path";
|
4
4
|
import { fileURLToPath } from "url";
|
5
5
|
import pkg from "../package.json" with { type: "json" };
|
6
|
+
import { removeByOptions } from "./manipulate.js";
|
6
7
|
import { sync } from "./sync.js";
|
7
8
|
import { init, translatePo, translatePoDir } from "./translate.js";
|
8
|
-
import {
|
9
|
-
import { removeByOptions } from "./manipulate.js";
|
9
|
+
import { compilePo, copyFileIfNotExists, findConfig, openFileByDefault, openFileExplorer, parsePo } from "./utils.js";
|
10
10
|
const __filename = fileURLToPath(import.meta.url);
|
11
11
|
const __dirname = path.dirname(__filename);
|
12
12
|
const program = new Command();
|
13
13
|
program.name(pkg.name).version(pkg.version).description(pkg.description);
|
14
|
-
|
15
|
-
.
|
14
|
+
const getCompileOptions = (args) => {
|
15
|
+
const foldLength = args.poFoldLen === "false" ? 0 : parseInt(args.poFoldLen);
|
16
|
+
const sort = args.poSort;
|
17
|
+
const escapeCharacters = args.poEscChars;
|
18
|
+
if (isNaN(foldLength)) {
|
19
|
+
console.error("--po-fold-len must be a number or false");
|
20
|
+
process.exit(1);
|
21
|
+
}
|
22
|
+
return { foldLength, sort, escapeCharacters };
|
23
|
+
};
|
24
|
+
class SharedOptionsCommand extends Command {
|
25
|
+
addCompileOptions() {
|
26
|
+
return this.option("--po-fold-len <length>", "a gettext compile option, the length at which to fold message strings into newlines, set to 0 or false to disable folding", "120")
|
27
|
+
.option("--po-sort", "a gettext compile option, sort entries by msgid", false)
|
28
|
+
.option("--po-esc-chars", "a gettext compile option, escape characters in output, if false, will skip escape newlines and quotes characters functionality", true);
|
29
|
+
}
|
30
|
+
}
|
31
|
+
const translateCommand = new SharedOptionsCommand("translate")
|
16
32
|
.description("translate po file (default command)")
|
17
33
|
.addOption(new Option("-k, --key <key>", "openai api key").env("OPENAI_API_KEY"))
|
18
34
|
.addOption(new Option("--host <host>", "openai api host").env("OPENAI_API_HOST"))
|
@@ -24,6 +40,7 @@ program
|
|
24
40
|
.option("--verbose", "print verbose log")
|
25
41
|
.option("--context <file>", "text file that provides the bot additional context")
|
26
42
|
.addOption(new Option("-o, --output <file>", "output file path, overwirte po file by default").conflicts("dir"))
|
43
|
+
.addCompileOptions()
|
27
44
|
.action(async (args) => {
|
28
45
|
const { key, host, model, po, dir, source, lang, verbose, output, context } = args;
|
29
46
|
if (host) {
|
@@ -38,25 +55,30 @@ program
|
|
38
55
|
process.exit(1);
|
39
56
|
}
|
40
57
|
init();
|
58
|
+
const compileOptions = getCompileOptions(args);
|
41
59
|
if (po) {
|
42
|
-
await translatePo(model, po, source, lang, verbose, output, context);
|
60
|
+
await translatePo(model, po, source, lang, verbose, output, context, compileOptions);
|
43
61
|
}
|
44
62
|
else if (dir) {
|
45
|
-
await translatePoDir(model, dir, source, lang, verbose, context);
|
63
|
+
await translatePoDir(model, dir, source, lang, verbose, context, compileOptions);
|
46
64
|
}
|
47
65
|
else {
|
48
66
|
console.error("po file or directory is required");
|
49
67
|
process.exit(1);
|
50
68
|
}
|
51
69
|
});
|
52
|
-
program
|
53
|
-
|
70
|
+
program.addCommand(translateCommand, { isDefault: true });
|
71
|
+
const syncCommand = new SharedOptionsCommand("sync")
|
54
72
|
.description("update po from pot file")
|
55
73
|
.requiredOption("--po <file>", "po file path")
|
56
74
|
.requiredOption("--pot <file>", "pot file path")
|
57
|
-
.
|
58
|
-
|
75
|
+
.option("-o, --output <file>", "output file path, overwirte po file by default")
|
76
|
+
.addCompileOptions()
|
77
|
+
.action(async (args) => {
|
78
|
+
const { po, pot } = args;
|
79
|
+
await sync(po, pot, getCompileOptions(args));
|
59
80
|
});
|
81
|
+
program.addCommand(syncCommand);
|
60
82
|
// program command `userdict` with help text `open/edit user dictionary`
|
61
83
|
program
|
62
84
|
.command("userdict")
|
@@ -78,8 +100,7 @@ program
|
|
78
100
|
openFileByDefault(dictFile);
|
79
101
|
});
|
80
102
|
// program command `remove` with help text `remove po entries by options`
|
81
|
-
|
82
|
-
.command("remove")
|
103
|
+
const removeCommand = new SharedOptionsCommand("remove")
|
83
104
|
.description("remove po entries by options")
|
84
105
|
.requiredOption("--po <file>", "po file path")
|
85
106
|
.option("--fuzzy", "remove fuzzy entries")
|
@@ -89,7 +110,10 @@ program
|
|
89
110
|
.option("-tnf, --translated-not-fuzzy", "remove translated not fuzzy entries")
|
90
111
|
.option("-ft, --fuzzy-translated", "remove fuzzy translated entries")
|
91
112
|
.option("-rc, --reference-contains <text>", "remove entries whose reference contains text, text can be a regular expression like /text/ig")
|
113
|
+
.option("-o, --output <file>", "output file path, overwirte po file by default")
|
114
|
+
.addCompileOptions()
|
92
115
|
.action(async (args) => {
|
116
|
+
this;
|
93
117
|
const { po, fuzzy, obsolete, untranslated, translated, translatedNotFuzzy, fuzzyTranslated, referenceContains } = args;
|
94
118
|
const options = {
|
95
119
|
fuzzy,
|
@@ -102,8 +126,9 @@ program
|
|
102
126
|
};
|
103
127
|
const output = args.output || po;
|
104
128
|
const translations = await parsePo(po);
|
105
|
-
await compilePo(removeByOptions(translations, options), output);
|
129
|
+
await compilePo(removeByOptions(translations, options), output, getCompileOptions(args));
|
106
130
|
console.log("done");
|
107
131
|
});
|
132
|
+
program.addCommand(removeCommand);
|
108
133
|
program.parse(process.argv);
|
109
134
|
//# sourceMappingURL=index.js.map
|
package/lib/src/sync.d.ts
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
|
1
|
+
import { CompileOptions } from "./utils.js";
|
2
|
+
export declare function sync(po: string, pot: string, compileOptions?: CompileOptions): Promise<void>;
|
package/lib/src/sync.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { compilePo, parsePo } from "./utils.js";
|
2
|
-
export async function sync(po, pot) {
|
2
|
+
export async function sync(po, pot, compileOptions) {
|
3
3
|
const potrans = await parsePo(po);
|
4
4
|
const potrans2 = await parsePo(pot);
|
5
5
|
for (const [ctx, entries] of Object.entries(potrans2.translations)) {
|
@@ -13,6 +13,6 @@ export async function sync(po, pot) {
|
|
13
13
|
}
|
14
14
|
}
|
15
15
|
potrans.translations = potrans2.translations;
|
16
|
-
await compilePo(potrans, po);
|
16
|
+
await compilePo(potrans, po, compileOptions);
|
17
17
|
}
|
18
18
|
//# sourceMappingURL=sync.js.map
|
package/lib/src/translate.d.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import { GetTextTranslation } from "gettext-parser";
|
2
2
|
import { OpenAI } from "openai";
|
3
|
+
import { CompileOptions } from "./utils.js";
|
3
4
|
export declare function init(force?: boolean): OpenAI;
|
4
5
|
export declare function translate(src: string, lang: string, model: string, translations: GetTextTranslation[], contextFile: string): Promise<void>;
|
5
|
-
export declare function translatePo(model: string, po: string, source: string, lang: string, verbose: boolean, output: string, contextFile: string): Promise<void>;
|
6
|
-
export declare function translatePoDir(model: string | undefined, dir: string, source: string, lang: string, verbose: boolean, contextFile: string): Promise<void>;
|
6
|
+
export declare function translatePo(model: string, po: string, source: string, lang: string, verbose: boolean, output: string, contextFile: string, compileOptions?: CompileOptions): Promise<void>;
|
7
|
+
export declare function translatePoDir(model: string | undefined, dir: string, source: string, lang: string, verbose: boolean, contextFile: string, compileOptions?: CompileOptions): Promise<void>;
|
package/lib/src/translate.js
CHANGED
@@ -58,7 +58,10 @@ export async function translate(src, lang, model, translations, contextFile) {
|
|
58
58
|
.join("\n");
|
59
59
|
const context = contextFile ? "\n\nContext: " + fs.readFileSync(contextFile, "utf-8") : "";
|
60
60
|
const translationsContent = translations
|
61
|
-
.map((tr, idx) =>
|
61
|
+
.map((tr, idx) => {
|
62
|
+
const contextAttr = tr.msgctxt ? ` context="${tr.msgctxt}"` : "";
|
63
|
+
return `<translate index="${idx + dicts.user.length + 1}"${contextAttr}>${tr.msgid}</translate>`;
|
64
|
+
})
|
62
65
|
.join("\n");
|
63
66
|
const res = await _openai.chat.completions.create({
|
64
67
|
model: model,
|
@@ -107,7 +110,7 @@ export async function translate(src, lang, model, translations, contextFile) {
|
|
107
110
|
}
|
108
111
|
});
|
109
112
|
}
|
110
|
-
export async function translatePo(model, po, source, lang, verbose, output, contextFile) {
|
113
|
+
export async function translatePo(model, po, source, lang, verbose, output, contextFile, compileOptions) {
|
111
114
|
const potrans = await parsePo(po);
|
112
115
|
if (!lang)
|
113
116
|
lang = potrans.headers["Language"];
|
@@ -132,11 +135,16 @@ export async function translatePo(model, po, source, lang, verbose, output, cont
|
|
132
135
|
let trimed = false;
|
133
136
|
for (const [ctx, entries] of Object.entries(potrans.translations)) {
|
134
137
|
for (const [msgid, trans] of Object.entries(entries)) {
|
135
|
-
if (msgid
|
138
|
+
if (msgid === "")
|
136
139
|
continue;
|
137
140
|
if (!trans.msgstr[0]) {
|
138
|
-
list.push(
|
139
|
-
|
141
|
+
list.push({
|
142
|
+
msgctxt: trans.msgctxt || ctx,
|
143
|
+
msgid,
|
144
|
+
msgid_plural: trans.msgid_plural,
|
145
|
+
msgstr: trans.msgstr,
|
146
|
+
comments: trans.comments
|
147
|
+
});
|
140
148
|
}
|
141
149
|
else if (trimRegx.test(trans.msgstr[0])) {
|
142
150
|
trimed = true;
|
@@ -145,7 +153,7 @@ export async function translatePo(model, po, source, lang, verbose, output, cont
|
|
145
153
|
}
|
146
154
|
}
|
147
155
|
if (trimed) {
|
148
|
-
await compilePo(potrans, po);
|
156
|
+
await compilePo(potrans, po, compileOptions);
|
149
157
|
}
|
150
158
|
if (list.length == 0) {
|
151
159
|
console.log("done.");
|
@@ -180,7 +188,7 @@ export async function translatePo(model, po, source, lang, verbose, output, cont
|
|
180
188
|
// update progress
|
181
189
|
printProgress(i + 1, list.length);
|
182
190
|
// save po file after each 2000 characters
|
183
|
-
await compilePo(potrans, output || po);
|
191
|
+
await compilePo(potrans, output || po, compileOptions);
|
184
192
|
}
|
185
193
|
catch (error) {
|
186
194
|
if (error.response) {
|
@@ -205,13 +213,13 @@ export async function translatePo(model, po, source, lang, verbose, output, cont
|
|
205
213
|
}
|
206
214
|
console.log("done.");
|
207
215
|
}
|
208
|
-
export async function translatePoDir(model = "gpt-3.5-turbo", dir, source, lang, verbose, contextFile) {
|
216
|
+
export async function translatePoDir(model = "gpt-3.5-turbo", dir, source, lang, verbose, contextFile, compileOptions) {
|
209
217
|
const files = fs.readdirSync(dir);
|
210
218
|
for (const file of files) {
|
211
219
|
if (file.endsWith(".po")) {
|
212
220
|
const po = path.join(dir, file);
|
213
221
|
console.log(`translating ${po}`);
|
214
|
-
await translatePo(model, po, source, lang, verbose, po, contextFile);
|
222
|
+
await translatePo(model, po, source, lang, verbose, po, contextFile, compileOptions);
|
215
223
|
}
|
216
224
|
}
|
217
225
|
}
|
package/lib/src/userprompt.txt
CHANGED
@@ -12,7 +12,14 @@ Translation guidelines are as follows:
|
|
12
12
|
- Input messages will be wrapped in `<translate>` XML tags with an index attribute, e.g., `<translate index="1">`.
|
13
13
|
- Respond with the translated message wrapped in `<translated>` XML tags, including the same index attribute, e.g., `<translated index="1">`.
|
14
14
|
|
15
|
-
4. **
|
15
|
+
4. **Context Handling**:
|
16
|
+
- Some messages will include a context attribute in the translate tag, e.g., `<translate index="1" context="Menu">`.
|
17
|
+
- Use this context to inform your translation but only return the translated text.
|
18
|
+
- Example:
|
19
|
+
Input: `<translate index="1" context="Menu">File</translate>`
|
20
|
+
Output: `<translated index="1">Fichier</translated>`
|
21
|
+
|
22
|
+
5. **Multiple Translations**:
|
16
23
|
- You may receive multiple translation requests in a single input, each with a unique index.
|
17
24
|
- Ensuring the complete number of requests are translated, even if they are repeated, while maintaining the original order when possible.
|
18
25
|
|
package/lib/src/utils.d.ts
CHANGED
@@ -8,12 +8,12 @@ import { GetTextTranslations } from "gettext-parser";
|
|
8
8
|
export declare function copyFileIfNotExists(file: string, copyFile: string, force?: boolean): void;
|
9
9
|
export declare function openFileByDefault(filePath: string): void;
|
10
10
|
export declare function parsePo(poFile: string, defaultCharset?: string): Promise<GetTextTranslations>;
|
11
|
-
export type
|
11
|
+
export type CompileOptions = {
|
12
12
|
foldLength?: number;
|
13
13
|
sort?: boolean | ((a: never, b: never) => number);
|
14
14
|
escapeCharacters?: boolean;
|
15
15
|
};
|
16
|
-
export declare function compilePo(data: GetTextTranslations, poFile: string, options?:
|
16
|
+
export declare function compilePo(data: GetTextTranslations, poFile: string, options?: CompileOptions): Promise<void>;
|
17
17
|
export declare function printProgress(progress: number, total: number, extra?: string): void;
|
18
18
|
export declare function gitRootDir(dir?: string): string | null;
|
19
19
|
/**
|