Skip to content

Commit

Permalink
add gettext compile options
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanhex53 committed Dec 17, 2024
1 parent 6687880 commit fa1b412
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 27 deletions.
4 changes: 3 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
"remove",
"--po",
"C:\\Users\\Ryan\\Desktop\\test.po",
"--fuzzy"
"--fuzzy",
"--po-fold-len",
"90"
],
"preLaunchTask": "tsc: build - tsconfig.json",
"outFiles": [
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "gpt-po",
"version": "1.2.0",
"version": "1.2.1",
"description": "command tool for translate po files by gpt",
"main": "lib/src/index.js",
"type": "module",
Expand Down
65 changes: 52 additions & 13 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ import { Command, Option } from "commander";
import path from "path";
import { fileURLToPath } from "url";
import pkg from "../package.json" with { type: "json" };
import { removeByOptions } from "./manipulate.js";
import { sync } from "./sync.js";
import { init, translatePo, translatePoDir } from "./translate.js";
import {
copyFileIfNotExists,
CompileOptions,
compilePo,
copyFileIfNotExists,
findConfig,
openFileByDefault,
openFileExplorer,
parsePo
} from "./utils.js";
import { removeByOptions } from "./manipulate.js";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
Expand All @@ -23,8 +24,34 @@ const program = new Command();

program.name(pkg.name).version(pkg.version).description(pkg.description);

program
.command("translate", { isDefault: true })
const getCompileOptions = (args: any): CompileOptions => {
const foldLength = args.poFoldLen === "false" ? 0 : parseInt(args.poFoldLen);
const sort = args.poSort;
const escapeCharacters = args.poEscChars;
if (isNaN(foldLength)) {
console.error("--po-fold-length must be a number or false");
process.exit(1);
}
return { foldLength, sort, escapeCharacters };
};

class SharedOptionsCommand extends Command {
addCompileOptions() {
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"
)
.option("--po-sort", "a gettext compile option, sort entries by msgid", false)
.option(
"--po-esc-chars",
"a gettext compile option, escape characters in output, if false, will skip escape newlines and quotes characters functionality",
true
);
}
}

const translateCommand = new SharedOptionsCommand("translate")
.description("translate po file (default command)")
.addOption(new Option("-k, --key <key>", "openai api key").env("OPENAI_API_KEY"))
.addOption(new Option("--host <host>", "openai api host").env("OPENAI_API_HOST"))
Expand All @@ -38,6 +65,7 @@ program
.addOption(
new Option("-o, --output <file>", "output file path, overwirte po file by default").conflicts("dir")
)
.addCompileOptions()
.action(async (args) => {
const { key, host, model, po, dir, source, lang, verbose, output, context } = args;
if (host) {
Expand All @@ -52,25 +80,32 @@ program
process.exit(1);
}
init();
const compileOptions = getCompileOptions(args);
if (po) {
await translatePo(model, po, source, lang, verbose, output, context);
await translatePo(model, po, source, lang, verbose, output, context, compileOptions);
} else if (dir) {
await translatePoDir(model, dir, source, lang, verbose, context);
await translatePoDir(model, dir, source, lang, verbose, context, compileOptions);
} else {
console.error("po file or directory is required");
process.exit(1);
}
});

program
.command("sync")
program.addCommand(translateCommand, { isDefault: true });

const syncCommand = new SharedOptionsCommand("sync")
.description("update po from pot file")
.requiredOption("--po <file>", "po file path")
.requiredOption("--pot <file>", "pot file path")
.action(async ({ po, pot }) => {
await sync(po, pot);
.option("-o, --output <file>", "output file path, overwirte po file by default")
.addCompileOptions()
.action(async (args) => {
const { po, pot } = args;
await sync(po, pot, getCompileOptions(args));
});

program.addCommand(syncCommand, { isDefault: true });

// program command `userdict` with help text `open/edit user dictionary`
program
.command("userdict")
Expand All @@ -92,8 +127,7 @@ program
});

// program command `remove` with help text `remove po entries by options`
program
.command("remove")
const removeCommand = new SharedOptionsCommand("remove")
.description("remove po entries by options")
.requiredOption("--po <file>", "po file path")
.option("--fuzzy", "remove fuzzy entries")
Expand All @@ -106,7 +140,10 @@ program
"-rc, --reference-contains <text>",
"remove entries whose reference contains text, text can be a regular expression like /text/ig"
)
.option("-o, --output <file>", "output file path, overwirte po file by default")
.addCompileOptions()
.action(async (args) => {
this;
const {
po,
fuzzy,
Expand All @@ -128,8 +165,10 @@ program
};
const output = args.output || po;
const translations = await parsePo(po);
await compilePo(removeByOptions(translations, options), output);
await compilePo(removeByOptions(translations, options), output, getCompileOptions(args));
console.log("done");
});

program.addCommand(removeCommand);

program.parse(process.argv);
6 changes: 3 additions & 3 deletions src/sync.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { compilePo, parsePo } from "./utils.js";
import { CompileOptions, compilePo, parsePo } from "./utils.js";

export async function sync(po: string, pot: string) {
export async function sync(po: string, pot: string, compileOptions?: CompileOptions) {
const potrans = await parsePo(po);
const potrans2 = await parsePo(pot);

Expand All @@ -17,5 +17,5 @@ export async function sync(po: string, pot: string) {
}
}
potrans.translations = potrans2.translations;
await compilePo(potrans, po);
await compilePo(potrans, po, compileOptions);
}
24 changes: 17 additions & 7 deletions src/translate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ import { ChatCompletionMessageParam } from "openai/resources/index.mjs";
import path from "path";
import { fileURLToPath } from "url";
import pkg from "../package.json" with { type: "json" };
import { compilePo, copyFileIfNotExists, findConfig, parsePo, printProgress } from "./utils.js";
import {
CompileOptions,
compilePo,
copyFileIfNotExists,
findConfig,
parsePo,
printProgress
} from "./utils.js";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
Expand Down Expand Up @@ -93,7 +100,8 @@ export async function translate(
},
{
role: "user",
content: `${_userprompt}\n\nWait for my incoming message in "${src}" and translate it into "${lang}"(a language code and an optional region code). ` +
content:
`${_userprompt}\n\nWait for my incoming message in "${src}" and translate it into "${lang}"(a language code and an optional region code). ` +
notes
},
{
Expand Down Expand Up @@ -140,7 +148,8 @@ export async function translatePo(
lang: string,
verbose: boolean,
output: string,
contextFile: string
contextFile: string,
compileOptions?: CompileOptions
) {
const potrans = await parsePo(po);

Expand Down Expand Up @@ -179,7 +188,7 @@ export async function translatePo(
}
}
if (trimed) {
await compilePo(potrans, po);
await compilePo(potrans, po, compileOptions);
}
if (list.length == 0) {
console.log("done.");
Expand Down Expand Up @@ -213,7 +222,7 @@ export async function translatePo(
// update progress
printProgress(i + 1, list.length);
// save po file after each 2000 characters
await compilePo(potrans, output || po);
await compilePo(potrans, output || po, compileOptions);
} catch (error: any) {
if (error.response) {
if (error.response.status == 429) {
Expand Down Expand Up @@ -242,14 +251,15 @@ export async function translatePoDir(
source: string,
lang: string,
verbose: boolean,
contextFile: string
contextFile: string,
compileOptions?: CompileOptions
) {
const files = fs.readdirSync(dir);
for (const file of files) {
if (file.endsWith(".po")) {
const po = path.join(dir, file);
console.log(`translating ${po}`);
await translatePo(model, po, source, lang, verbose, po, contextFile);
await translatePo(model, po, source, lang, verbose, po, contextFile, compileOptions);
}
}
}
4 changes: 2 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export function parsePo(poFile: string, defaultCharset?: string): Promise<GetTex
});
}

export type compileOptions = {
export type CompileOptions = {
foldLength?: number;
sort?: boolean | ((a: never, b: never) => number);
escapeCharacters?: boolean;
Expand All @@ -53,7 +53,7 @@ export type compileOptions = {
export function compilePo(
data: GetTextTranslations,
poFile: string,
options: compileOptions = { foldLength: 120, sort: false, escapeCharacters: true }
options: CompileOptions = { foldLength: 120, sort: false, escapeCharacters: true }
): Promise<void> {
const buffer = po.compile(data, options);
return new Promise((resolve, reject) => {
Expand Down

0 comments on commit fa1b412

Please sign in to comment.