mirror of
https://github.com/gogs/gogs.git
synced 2026-05-28 21:30:36 +00:00
64 lines
2.3 KiB
JavaScript
64 lines
2.3 KiB
JavaScript
// Extracts the subset of keys the SPA needs from conf/locale/locale_*.ini and
|
|
// writes them as JSON under web/src/locales/. Run with `node scripts/extract-locales.mjs`
|
|
// after adding a new key or changing source translations.
|
|
import { mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
import { dirname, join, resolve } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
const repoRoot = resolve(here, "../..");
|
|
const inDir = join(repoRoot, "conf/locale");
|
|
const outDir = join(here, "..", "src/locales");
|
|
|
|
// Keys pulled from Gogs's INI files. Add new entries here when the SPA needs
|
|
// another translation. Locales missing a key fall back to en-US via react-i18next.
|
|
const REUSED_KEYS = [
|
|
"app_desc",
|
|
"home",
|
|
"explore",
|
|
"help",
|
|
"register",
|
|
"sign_in",
|
|
"settings",
|
|
"language",
|
|
"page_not_found",
|
|
"theme",
|
|
"theme_light",
|
|
"theme_dark",
|
|
"theme_system",
|
|
];
|
|
|
|
// Lightweight INI parser: handles `key = value` and `key=value`, ignores
|
|
// comments, and flattens sections into a single namespace. Gogs's locale
|
|
// files group keys under sections like [status] (e.g. status.page_not_found
|
|
// resolves to a key named "page_not_found" inside [status]), but downstream
|
|
// callers reference keys by their bare name, so the section header is
|
|
// dropped here. First occurrence wins on collisions.
|
|
function parseIni(text) {
|
|
const out = {};
|
|
for (const rawLine of text.split(/\r?\n/)) {
|
|
const line = rawLine.trim();
|
|
if (!line || line.startsWith(";") || line.startsWith("#") || line.startsWith("[")) continue;
|
|
const eq = line.indexOf("=");
|
|
if (eq < 0) continue;
|
|
const key = line.slice(0, eq).trim();
|
|
const value = line.slice(eq + 1).trim();
|
|
if (key && !(key in out)) out[key] = value;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
mkdirSync(outDir, { recursive: true });
|
|
|
|
const files = readdirSync(inDir).filter((f) => f.startsWith("locale_") && f.endsWith(".ini"));
|
|
for (const file of files) {
|
|
const lang = file.slice("locale_".length, -".ini".length);
|
|
const parsed = parseIni(readFileSync(join(inDir, file), "utf8"));
|
|
const out = {};
|
|
for (const key of REUSED_KEYS) {
|
|
if (parsed[key]) out[key] = parsed[key];
|
|
}
|
|
writeFileSync(join(outDir, `${lang}.json`), JSON.stringify(out, null, 2) + "\n", "utf8");
|
|
console.log(`wrote ${lang}.json (${Object.keys(out).length} keys)`);
|
|
}
|