Files
his/healthlink-his-ui/scripts/extract-chinese.mjs

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}`)