mirror of
https://github.com/kmvan/x-prober.git
synced 2026-08-12 23:31:41 +08:00
update lang
This commit is contained in:
+22
-24
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
Reference in New Issue
Block a user