const fs = require('fs')
const https = require('https')
const path = require('path')
const api_url = "https://translate.googleapis.com/translate_a/single?client=gtx"
const source_language = "zh-CN"
const target_language = "en"
const target_directories = [
__dirname, // 当前目录
path.join(__dirname, 'views'),
path.join(__dirname, 'scripts')
]
const chinese_pattern = /[\u4e00-\u9fff]+/g
function translateText(text) {
return new Promise((resolve, reject) => {
const url = `${api_url}&sl=${source_language}&tl=${target_language}&dt=t&q=${encodeURIComponent(text)}`
https.get(url, (response) => {
let responseData = ''
response.on('data', (chunk) => {
responseData += chunk
})
response.on('end', () => {
const translatedText = JSON.parse(responseData)[0][0][0]
console.log(translatedText)
resolve(translatedText)
})
}).on('error', (error) => {
console.log('------error------')
console.log(error)
reject(error)
})
})
}
function processFiles(directory) {
let translations = {}
fs.readdirSync(directory).forEach(file => {
const filePath = path.join(directory, file)
if (fs.statSync(filePath).isFile()) {
if (file.endsWith('.html') || file.endsWith('.js')) {
const content = fs.readFileSync(filePath, 'utf-8')
const matches = content.match(chinese_pattern)
if (matches) {
matches.forEach(match => {
if (!isInsideComment(content, match)) {
translations[match] = ''
}
})
}
}
} else if (fs.statSync(filePath).isDirectory()) {
translations = { ...translations, ...processFiles(filePath) }
}
})
return translations
}
function getCommentRanges(content) {
const commentPatterns = [
[/\/\/[^\n]*\b(\S*?)(?<!\\)'[^']*'(?!\w)/g, 'single-line'], // Single-line comments
[/\/\*[\s\S]*?\b(\S*?)(?<!\\)'[^']*'(?!\w)[\s\S]*?\*\//g, 'multi-line'] // Multi-line comments
]
const commentRanges = []
for (const [pattern, type] of commentPatterns) {
const matches = [...content.matchAll(pattern)]
for (const match of matches) {
const startIndex = match.index
const endIndex = startIndex + match[0].length - 1
commentRanges.push([startIndex, endIndex, type])
}
}
return commentRanges
}
function isInsideComment(content, position) {
const commentRanges = getCommentRanges(content)
for (const range of commentRanges) {
if (position >= range[0] && position <= range[1]) {
return true
}
}
return false
}
(async () => {
let translatedStrings = {}
for (const directory of target_directories) {
translatedStrings = { ...translatedStrings, ...processFiles(directory) }
}
for (const chineseString of Object.keys(translatedStrings)) {
translatedStrings[chineseString] = await translateText(chineseString)
}
const outputPath = path.join(__dirname, 'i18n', 'translate.json')
fs.writeFileSync(outputPath, JSON.stringify(translatedStrings, null, 2))
console.log(`已生成翻译文件:${outputPath}`)
})()