114 lines
3.2 KiB
JavaScript
114 lines
3.2 KiB
JavaScript
import { readdirSync, readFileSync, writeFileSync, statSync } from 'fs'
|
|
import { join, relative } from 'path'
|
|
|
|
const SRC_DIR = join(import.meta.dirname, '../src')
|
|
const OUTPUT_FILE = join(import.meta.dirname, '../src/i18n/locales/zhCN_extracted.json')
|
|
|
|
// Chinese character range regex
|
|
const CHINESE_REGEX = /[\u4e00-\u9fff\u3400-\u4dbf]+/g
|
|
|
|
// Patterns to extract from
|
|
const PATTERNS = [
|
|
// el-form label attributes
|
|
/\blabel=["']([^"']*?)[\u4e00-\u9fff][^"']*?["']/g,
|
|
// el-button text content (between tags)
|
|
/>\s*([\u4e00-\u9fff][^\n<]{1,50})\s*</g,
|
|
// title attributes
|
|
/\btitle=["']([^"']*?)[\u4e00-\u9fff][^"']*?["']/g,
|
|
// placeholder attributes
|
|
/\bplaceholder=["']([^"']*?)[\u4e00-\u9fff][^"']*?["']/g,
|
|
// el-table-column label
|
|
/\blabel=["']([^"']*?)[\u4e00-\u9fff][^"']*?["']/g,
|
|
// HTML text nodes with Chinese
|
|
/>\s*([\u4e00-\u9fff][^\n<>]{2,100})\s*</g,
|
|
// JavaScript string literals with Chinese (messages, tooltips)
|
|
/["']([^"']*?)[\u4e00-\u9fff][^"']*?(?=["'])/g,
|
|
]
|
|
|
|
function isChineseHeavy(text) {
|
|
const chineseCount = (text.match(CHINESE_REGEX) || []).length
|
|
return chineseCount >= 2
|
|
}
|
|
|
|
function extractFromLine(line) {
|
|
const results = []
|
|
for (const pattern of PATTERNS) {
|
|
pattern.lastIndex = 0
|
|
let match
|
|
while ((match = pattern.exec(line)) !== null) {
|
|
const text = match[1] || match[0]
|
|
if (isChineseHeavy(text) && text.length > 1 && text.length < 100) {
|
|
results.push(text)
|
|
}
|
|
}
|
|
}
|
|
return results
|
|
}
|
|
|
|
function walkDir(dir) {
|
|
const results = []
|
|
const files = readdirSync(dir)
|
|
for (const file of files) {
|
|
const fullPath = join(dir, file)
|
|
const stat = statSync(fullPath)
|
|
if (stat.isDirectory()) {
|
|
if (['node_modules', 'dist', 'build', '.git', 'patches'].includes(file)) continue
|
|
results.push(...walkDir(fullPath))
|
|
} else if (stat.isFile() && (file.endsWith('.vue') || file.endsWith('.js') || file.endsWith('.ts'))) {
|
|
results.push(fullPath)
|
|
}
|
|
}
|
|
return results
|
|
}
|
|
|
|
function extractChineseFromFile(filePath) {
|
|
const content = readFileSync(filePath, 'utf-8')
|
|
const lines = content.split('\n')
|
|
const texts = new Set()
|
|
for (const line of lines) {
|
|
const extracted = extractFromLine(line)
|
|
for (const text of extracted) {
|
|
texts.add(text)
|
|
}
|
|
}
|
|
return texts
|
|
}
|
|
|
|
// Main
|
|
console.log('Scanning Vue/JS files for Chinese text...')
|
|
const allTexts = new Set()
|
|
let fileCount = 0
|
|
|
|
for (const filePath of walkDir(SRC_DIR)) {
|
|
const texts = extractChineseFromFile(filePath)
|
|
for (const text of texts) {
|
|
allTexts.add(text)
|
|
}
|
|
fileCount++
|
|
if (fileCount % 100 === 0) {
|
|
console.log(`Scanned ${fileCount} files, found ${allTexts.size} unique Chinese texts...`)
|
|
}
|
|
}
|
|
|
|
console.log(`Done. Scanned ${fileCount} files, found ${allTexts.size} unique Chinese texts.`)
|
|
|
|
// Organize into categories
|
|
const categorized = {
|
|
'_meta': {
|
|
'total_keys': allTexts.size,
|
|
'source': 'auto-extracted from Vue/JS files',
|
|
'date': new Date().toISOString()
|
|
}
|
|
}
|
|
|
|
// Assign keys
|
|
let keyIndex = 0
|
|
for (const text of [...allTexts].sort()) {
|
|
const key = `extracted_${String(keyIndex++).padStart(4, '0')}`
|
|
categorized[key] = text
|
|
}
|
|
|
|
writeFileSync(OUTPUT_FILE, JSON.stringify(categorized, null, 2), 'utf-8')
|
|
console.log(`Saved to ${OUTPUT_FILE}`)
|
|
console.log(`Total keys: ${keyIndex}`)
|