Files
tuiche/tool/add_tr_to_chinese.dart
2025-07-30 16:48:48 +08:00

121 lines
3.5 KiB
Dart

import 'dart:io';
import 'dart:convert';
void main(List<String> args) async {
// 默认使用当前目录和同级目录下的 chinese_texts.json
final targetPath = args.isNotEmpty ? args[0] : Directory.current.path;
final jsonFilePath = args.length > 1 ? args[1] : 'chinese_texts.json';
print('目标路径: $targetPath');
print('JSON文件: $jsonFilePath');
// 加载JSON文件
final jsonFile = File(jsonFilePath);
if (!jsonFile.existsSync()) {
print('错误: JSON文件不存在: $jsonFilePath');
print('请确保文件存在或提供完整路径');
exit(1);
}
final jsonContent = await jsonFile.readAsString();
final jsonMap = json.decode(jsonContent) as Map<String, dynamic>;
final targetKeys = jsonMap.keys.toSet();
// 检查目标路径类型
final type = FileSystemEntity.typeSync(targetPath);
if (type == FileSystemEntityType.notFound) {
print('错误: 目标路径不存在: $targetPath');
exit(1);
}
int modifiedCount = 0;
int processedCount = 0;
if (type == FileSystemEntityType.file && targetPath.endsWith('.dart')) {
// 处理单个文件
processedCount = 1;
if (await processDartFile(File(targetPath), targetKeys)) {
modifiedCount++;
}
} else if (type == FileSystemEntityType.directory) {
// 处理目录
print('开始扫描Dart文件...');
await for (final entity in Directory(targetPath).list(recursive: true)) {
if (entity is File && entity.path.endsWith('.dart')) {
processedCount++;
if (await processDartFile(entity, targetKeys)) {
modifiedCount++;
}
}
}
} else {
print('错误: 不支持的路径类型: $targetPath');
exit(1);
}
print('\n处理结果:');
print('扫描文件: $processedCount');
print('修改文件: $modifiedCount');
print('未修改文件: ${processedCount - modifiedCount}');
}
Future<bool> processDartFile(File file, Set<String> targetKeys) async {
try {
final content = await file.readAsString();
final commentRanges = getCommentRanges(content);
final regex = RegExp(r'''(['"])((?:\\.|[^\\])*?)\1''');
final buffer = StringBuffer();
int lastIndex = 0;
bool hasChanges = false;
for (final match in regex.allMatches(content)) {
final start = match.start;
final end = match.end;
final text = match.group(2)!;
// 跳过注释
if (commentRanges.any((r) => start >= r[0] && start < r[1])) {
buffer.write(content.substring(lastIndex, end));
lastIndex = end;
continue;
}
// 检查是否是需要国际化的字符串
if (targetKeys.contains(text) && !isAlreadyTrCall(content, end)) {
buffer.write(content.substring(lastIndex, end));
buffer.write('.tr');
lastIndex = end;
hasChanges = true;
}
}
if (hasChanges) {
buffer.write(content.substring(lastIndex));
await file.writeAsString(buffer.toString());
print('已修改: ${file.path}');
return true;
}
return false;
} catch (e) {
print('处理 ${file.path} 出错: $e');
return false;
}
}
bool isAlreadyTrCall(String content, int endIndex) {
return endIndex < content.length &&
content.substring(endIndex).trim().startsWith('.tr');
}
List<List<int>> getCommentRanges(String content) {
final ranges = <List<int>>[];
ranges.addAll(RegExp(r'/\*.*?\*/', dotAll: true)
.allMatches(content)
.map((m) => [m.start, m.end]));
ranges.addAll(RegExp(r'//.*?$', multiLine: true)
.allMatches(content)
.map((m) => [m.start, m.end]));
return ranges;
}