Files
ArtPlayer/scripts/trans-docs.js
T

118 lines
3.7 KiB
JavaScript

import fs from 'fs';
import cpy from 'cpy';
import path from 'path';
import axios from 'axios';
import { glob } from 'glob';
import { removeDir } from './utils.js';
import dotenv from 'dotenv';
dotenv.config();
function splitMarkdown(text, maxChars) {
const parts = [];
let currentPart = '';
let inCodeBlock = false;
let inSpecialBlock = false;
const lines = text.split('\n');
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
// 检测代码块
if (line.trim().startsWith('```')) {
inCodeBlock = !inCodeBlock;
}
// 检测特殊块
if (line.trim().startsWith(':::')) {
inSpecialBlock = !inSpecialBlock;
}
// 添加当前行到当前部分
currentPart += line + '\n';
// 检测是否达到字符限制
if (!inCodeBlock && !inSpecialBlock && currentPart.length > maxChars && i < lines.length - 1) {
parts.push(currentPart);
currentPart = '';
}
}
// 添加最后一部分
if (currentPart !== '') {
parts.push(currentPart);
}
return parts;
}
const translateContent = async (content, targetLanguage) => {
try {
const TRANSLATE_URL = process.env.TRANSLATE_URL;
const response = await axios.post(
TRANSLATE_URL,
{
content: `The following text is written in VitePress's extended Markdown syntax, Please translate it into ${targetLanguage}, and keep the Markdown format and don't add your explanation:\n\n${content}`,
},
{
headers: {
'Content-Type': 'application/json',
},
timeout: 60000,
},
);
return response.data.data;
} catch (error) {
console.error(error.message);
return content;
}
};
const translateMarkdownFiles = async (filePaths, targetLanguage, maxCharsPerRequest) => {
let totalParts = 0;
let translatedPartsCount = 0;
for (const filePath of filePaths) {
const content = fs.readFileSync(filePath, 'utf-8');
const parts = splitMarkdown(content, maxCharsPerRequest);
totalParts += parts.length;
}
console.log(`开始翻译 ${filePaths.length} 个文件,总共 ${totalParts} 部分。`);
for (const filePath of filePaths) {
console.log(`翻译开始: ${filePath}`);
const content = fs.readFileSync(filePath, 'utf-8');
const parts = splitMarkdown(content, maxCharsPerRequest);
const translatedParts = [];
for (const part of parts) {
const translatedPart = await translateContent(part, targetLanguage);
translatedParts.push(translatedPart);
translatedPartsCount++;
const progressPercentage = ((translatedPartsCount / totalParts) * 100).toFixed(2);
console.log(`总体翻译进度: ${progressPercentage}%`);
}
const translatedContent = translatedParts.join('\n');
fs.writeFileSync(filePath, translatedContent);
console.log(`翻译结束: ${filePath}`);
}
};
(async () => {
const basePath = 'packages/artplayer-vitepress/docs';
const enPath = 'packages/artplayer-vitepress/docs/en';
removeDir(enPath);
cpy(path.resolve(basePath, 'index.md'), path.resolve(enPath));
const dirs = ['advanced', 'component', 'library', 'plugin', 'start'];
for (let index = 0; index < dirs.length; index++) {
const dir = dirs[index];
await cpy(path.resolve(basePath, dir), path.resolve(enPath, dir), { flat: true });
}
const mdsPaths = glob.sync(path.resolve(enPath, '**/*.md'));
const maxCharsPerRequest = 512;
await translateMarkdownFiles(mdsPaths, 'English', maxCharsPerRequest);
})();