update lang

This commit is contained in:
Km.Van
2026-07-10 22:57:56 +08:00
parent ee3bbc55fd
commit 82f1d51a39
12 changed files with 2677 additions and 287 deletions
+22 -24
View File
@@ -1,30 +1,28 @@
/**
* @version 1.0.0
* @version 1.0.1
*/
import { writeFileSync } from 'node:fs';
import path, { basename, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import DeepSort from 'deep-sort-object';
import FastGlob from 'fast-glob';
import { PoParser } from './po-parser.mjs';
import { PotBuilder } from './pot-builder.mjs';
import { writeFileSync } from "node:fs";
import { glob } from "node:fs/promises";
import path, { basename, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import DeepSort from "deep-sort-object";
import { PoParser } from "./po-parser.mjs";
import { PotBuilder } from "./pot-builder.mjs";
const __dirname = dirname(fileURLToPath(import.meta.url));
class LangBuilder {
data = {};
constructor() {
this.build();
}
setData = async () => {
async setData() {
new PotBuilder({
potPath: path.resolve(__dirname, '../locales/lang.pot'),
sourceDir: path.resolve(__dirname, '../src'),
});
const files = await FastGlob(path.resolve(__dirname, '../locales/*.po'));
for (const file of files) {
const lang = basename(file, '.po');
const langId = lang.replace('_', '').toLowerCase();
potPath: path.resolve(__dirname, "../locales/lang.pot"),
sourceDir: path.resolve(__dirname, "../src"),
}).build();
for await (const entry of await glob(
path.resolve(__dirname, "../locales/*.po")
)) {
const lang = basename(entry, ".po");
const langId = lang.replace("_", "").toLowerCase();
const parser = new PoParser({
poPath: path.resolve(__dirname, `../locales/${lang}.po`),
});
@@ -38,15 +36,15 @@ class LangBuilder {
}
}
}
};
build = async () => {
}
async build() {
await this.setData();
this.data = DeepSort(this.data);
const jsonPath = path.resolve(
__dirname,
'../src/Components/Language/data.json'
"../src/Components/Language/data.json"
);
writeFileSync(jsonPath, JSON.stringify(this.data, null, 2));
};
}
}
new LangBuilder();
new LangBuilder().build();
+9 -11
View File
@@ -1,14 +1,12 @@
/**
* @version 1.0.1
* @version 1.0.2
*/
import { existsSync, readFileSync } from 'node:fs';
import gettextParser from 'gettext-parser';
import { existsSync, readFileSync } from "node:fs";
import gettextParser from "gettext-parser";
const PARSE_REGEX =
/(msgctxt\s+"(.+?)"\s+)?msgid\s+"(.+?)"\s+msgstr\s+"(.+?)"/gm;
export class PoParser {
poPath = '';
poPath = "";
items = {};
constructor({ poPath }) {
this.poPath = poPath;
@@ -16,15 +14,15 @@ export class PoParser {
throw new Error(`${this.poPath} not exists`);
}
}
parse = () => {
parse() {
const input = readFileSync(this.poPath);
const po = gettextParser.po.parse(input);
for (const group of Object.values(po.translations)) {
for (const item of Object.values(group)) {
const id = item.msgid;
const str = item.msgstr[0];
const ctxt = item?.msgctxt || '';
const key = ctxt !== '' ? `${ctxt}|${id}` : id;
const [str] = item.msgstr;
const ctxt = item?.msgctxt || "";
const key = ctxt === "" ? id : `${ctxt}|${id}`;
this.items[key] = str;
}
}
@@ -35,5 +33,5 @@ export class PoParser {
return r;
}, {});
return this.items;
};
}
}
+26 -21
View File
@@ -1,11 +1,13 @@
/**
* @version 1.0.1
*/
import { lstatSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
import { extname } from 'node:path';
import { lstatSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
import { extname } from "node:path";
const GETTEXT_REG = /gettext\s*\(\s*(".+?")\s*,*\s*(".+?")*\s*\)/gm;
export class PotBuilder {
potPath = '';
sourceDir = '';
potPath = "";
sourceDir = "";
entries = {};
/**
* @type {string[]}
@@ -14,30 +16,33 @@ export class PotBuilder {
constructor({ potPath, sourceDir }) {
this.potPath = potPath;
this.sourceDir = sourceDir;
}
build() {
this.fetchDirOrFile(this.sourceDir);
this.filePaths.map(this.buildEntries);
for (const path of this.filePaths) {
this.buildEntries(path);
}
this.buildPotFile();
}
buildEntries = (path) => {
buildEntries(path) {
const code = readFileSync(path).toString();
const reg = /gettext\s*\(\s*('.+?')\s*,*\s*('.+?')*\s*\)/gm;
const matches = code.matchAll(reg);
const matches = code.matchAll(GETTEXT_REG);
if (matches) {
for (const match of matches) {
const msgid = match[1].slice(1, -1);
const msgctxt = (match[2] || '').slice(1, -1);
const msgctxt = (match[2] || "").slice(1, -1);
if (this.entries[`${msgid}${msgctxt}`]) {
continue;
}
this.entries[`${msgid}${msgctxt}`] = `
${msgctxt ? `msgctxt ${JSON.stringify(msgctxt)}` : ''}
${msgctxt ? `msgctxt ${JSON.stringify(msgctxt)}` : ""}
msgid ${JSON.stringify(msgid)}
msgstr ""
`.trim();
}
}
};
buildPotFile = () => {
}
buildPotFile() {
const toWriteData = `
#, fuzzy
msgid ""
@@ -56,17 +61,17 @@ msgstr ""
"X-Poedit-SourceCharset: UTF-8\\n"
"X-Poedit-KeywordsList: gettext\\n"
${Object.values(this.entries).join('\n\n')}
${Object.values(this.entries).join("\n\n")}
`.trim();
writeFileSync(this.potPath, toWriteData, 'utf8');
};
fetchDirOrFile = (filePathOrDir) => {
writeFileSync(this.potPath, toWriteData, "utf8");
}
fetchDirOrFile(filePathOrDir) {
if (lstatSync(filePathOrDir).isDirectory()) {
readdirSync(filePathOrDir).map((p) =>
this.fetchDirOrFile(`${filePathOrDir}/${p}`)
);
} else if (['.ts', '.tsx'].includes(extname(filePathOrDir))) {
for (const path of readdirSync(filePathOrDir)) {
this.fetchDirOrFile(`${filePathOrDir}/${path}`);
}
} else if ([".ts", ".tsx"].includes(extname(filePathOrDir))) {
this.filePaths.push(filePathOrDir);
}
};
}
}
-27
View File
@@ -1,27 +0,0 @@
import {
existsSync,
readdirSync,
rmdirSync,
statSync,
unlinkSync,
} from 'node:fs';
import path from 'node:path';
/**
* Remove files
* @param {string} dir
*/
export const rmFiles = (dir) => {
if (!existsSync(dir)) {
return;
}
const files = readdirSync(dir);
for (const file of files) {
const filePath = path.join(dir, file);
if (statSync(filePath).isDirectory()) {
rmFiles(filePath);
} else {
unlinkSync(filePath);
}
}
rmdirSync(dir);
};