feat: 한국어 우선 쇼케이스 정리
This commit is contained in:
parent
e4087c29f5
commit
2b7fa32b5b
109 changed files with 437 additions and 279 deletions
59
apps/site/tools/no-hanja.mjs
Normal file
59
apps/site/tools/no-hanja.mjs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// 배포 텍스트에는 한자를 두지 않는다. 이미지처럼 텍스트가 아닌 자산은 이 검사의 대상이 아니다.
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import url from "node:url";
|
||||
|
||||
const here = path.dirname(url.fileURLToPath(import.meta.url));
|
||||
const root = path.resolve(here, "..");
|
||||
const TEXT_EXTENSIONS = new Set([".astro", ".css", ".html", ".js", ".json", ".mjs", ".svg", ".ts", ".tsx", ".txt", ".webmanifest", ".xml"]);
|
||||
const HANJA = /[\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff]/u;
|
||||
const HANJA_GLOBAL = /[\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff]/gu;
|
||||
|
||||
function scanRoots(argv) {
|
||||
const roots = [];
|
||||
for (let index = 2; index < argv.length; index += 1) {
|
||||
const argument = argv[index];
|
||||
const value = argument === "--root" ? argv[++index] : argument.startsWith("--root=") ? argument.slice("--root=".length) : null;
|
||||
if (!value) throw new Error(`Unknown or incomplete argument: ${argument}`);
|
||||
const candidate = path.resolve(root, value);
|
||||
if (candidate !== root && !candidate.startsWith(root + path.sep)) throw new Error(`Root must stay inside apps/site: ${value}`);
|
||||
roots.push(candidate);
|
||||
}
|
||||
return roots.length ? roots : [path.join(root, "src"), path.join(root, "public")];
|
||||
}
|
||||
|
||||
function textFiles(directory) {
|
||||
const files = [];
|
||||
const walk = (current) => {
|
||||
for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
|
||||
const candidate = path.join(current, entry.name);
|
||||
if (entry.isDirectory()) walk(candidate);
|
||||
else if (entry.isFile() && TEXT_EXTENSIONS.has(path.extname(entry.name).toLowerCase())) files.push(candidate);
|
||||
}
|
||||
};
|
||||
walk(directory);
|
||||
return files;
|
||||
}
|
||||
|
||||
const failures = [];
|
||||
let scanned = 0;
|
||||
for (const scanRoot of scanRoots(process.argv)) {
|
||||
if (!fs.existsSync(scanRoot)) throw new Error(`Scan root does not exist: ${path.relative(root, scanRoot) || "."}`);
|
||||
for (const file of textFiles(scanRoot)) {
|
||||
scanned += 1;
|
||||
const lines = fs.readFileSync(file, "utf8").split(/\r?\n/);
|
||||
lines.forEach((line, index) => {
|
||||
if (!HANJA.test(line)) return;
|
||||
const characters = [...new Set(line.match(HANJA_GLOBAL) || [])].join("");
|
||||
failures.push(`${path.relative(root, file).replaceAll("\\", "/")}:${index + 1} contains ${characters}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (failures.length) {
|
||||
console.error(`FAIL: ${failures.length} Hanja occurrence(s) across ${scanned} shipped text files.`);
|
||||
for (const failure of failures) console.error(` ${failure}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`PASS: ${scanned} shipped text files contain no Hanja.`);
|
||||
Loading…
Add table
Add a link
Reference in a new issue