| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- const fs = require("fs");
- const path = require("path");
- const ROOT = path.join(__dirname, "../src");
- const SKIP = /copy\.vue$|weatherInfo copy/i;
- const TEXT_IN_TAG = />([^<>{}\n]+)</g;
- const ATTR_RE = /(?<![:\w$])(text|title|label|name|placeholder|message|confirm-button-text|cancel-button-text)=["']([^"']*[\u4e00-\u9fff][^"']*)["']/g;
- function walk(dir, files = []) {
- for (const name of fs.readdirSync(dir)) {
- const p = path.join(dir, name);
- if (fs.statSync(p).isDirectory()) {
- if (!["node_modules"].includes(name)) walk(p, files);
- } else if (name.endsWith(".vue") && !SKIP.test(p)) files.push(p);
- }
- return files;
- }
- function hasChinese(s) {
- return /[\u4e00-\u9fff]/.test(s);
- }
- function escapeStr(s) {
- return s.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
- }
- function alreadyWrapped(text) {
- return text.includes("{{") || text.includes("$t(") || text.includes("t(");
- }
- function wrapTemplate(content) {
- let changed = false;
- let out = content.replace(TEXT_IN_TAG, (full, text) => {
- const trimmed = text.trim();
- if (!trimmed || !hasChinese(trimmed) || alreadyWrapped(trimmed)) return full;
- if (/^[\s\d.,:;+\-/%]+$/.test(trimmed)) return full;
- changed = true;
- return `>{{ $t('${escapeStr(trimmed)}') }}<`;
- });
- out = out.replace(ATTR_RE, (full, attr, val) => {
- changed = true;
- return `:${attr}="$t('${escapeStr(val)}')"`;
- });
- return { out, changed };
- }
- function processVueFile(content) {
- const open = content.indexOf("<template>");
- const close = content.lastIndexOf("</template>");
- if (open === -1 || close === -1 || close <= open) {
- return { content, changed: false };
- }
- const before = content.slice(0, open + "<template>".length);
- const templateBody = content.slice(open + "<template>".length, close);
- const after = content.slice(close);
- const { out, changed } = wrapTemplate(templateBody);
- if (!changed) return { content, changed: false };
- return { content: before + out + after, changed: true };
- }
- let total = 0;
- for (const file of walk(ROOT)) {
- const original = fs.readFileSync(file, "utf8");
- const { content, changed } = processVueFile(original);
- if (!changed) continue;
- if (content.length < original.length * 0.7) {
- console.warn("SKIP (suspicious shrink):", path.relative(ROOT, file));
- continue;
- }
- fs.writeFileSync(file, content);
- total++;
- console.log("Updated:", path.relative(ROOT, file));
- }
- console.log("Done. Updated", total, "files");
|