// import 'dart:io'; // void main(List args) async { // final targetPath = args.isNotEmpty ? args[0] : Directory.current.path; // final type = FileSystemEntity.typeSync(targetPath); // if (type == FileSystemEntityType.notFound) { // print('路径不存在: $targetPath'); // return; // } // if (type == FileSystemEntityType.file && targetPath.endsWith('.dart')) { // await processDartFile(File(targetPath)); // } else if (type == FileSystemEntityType.directory) { // final directory = Directory(targetPath); // print('扫描目录: $targetPath'); // await for (final entity // in directory.list(recursive: true, followLinks: false)) { // if (entity is File && entity.path.endsWith('.dart')) { // await processDartFile(entity); // } // } // print('处理完成'); // } else { // print('不支持的路径类型: $targetPath'); // } // } // Future processDartFile(File file) async { // final content = await file.readAsString(); // // 获取注释范围 // final commentRanges = getCommentRanges(content); // // 匹配带中文的引号字符串(单/双引号) // final regex = RegExp(r'''(['"])([^'"]*?[\u4e00-\u9fa5][^'"]*?)\1'''); // final matches = regex.allMatches(content).toList(); // if (matches.isEmpty) return; // final sb = StringBuffer(); // int lastIndex = 0; // for (final match in matches) { // final start = match.start; // final end = match.end; // // 跳过注释中的内容 // if (commentRanges.any((range) => start >= range[0] && start < range[1])) { // continue; // } // // 插入上次结束到当前匹配之间的代码 // sb.write(content.substring(lastIndex, start)); // final fullMatch = match.group(0)!; // // 判断是否已处于 .tr 表达式中 // if (isAlreadyTrCall(content, start, end)) { // sb.write(fullMatch); // 不修改 // } else { // sb.write('$fullMatch.tr'); // 添加 .tr // } // lastIndex = end; // } // sb.write(content.substring(lastIndex)); // final result = sb.toString(); // if (result != content) { // await file.writeAsString(result); // print('✅ 修改完成: ${file.path}'); // } else { // print('✔ 无需修改: ${file.path}'); // } // } // /// 判断该字符串是否已是 .tr 调用的一部分 // bool isAlreadyTrCall(String content, int start, int end) { // final after = content.substring(end); // final before = content.substring(0, start); // // 检查匹配后是否直接跟 .tr (允许空格) // final hasTrAfter = RegExp(r'^\s*\.tr\b').hasMatch(after); // // 检查匹配前是否已经出现 .tr (形如 .tr'xxx' 也考虑在内) // final hasTrBefore = RegExp(r'\.tr\s*$').hasMatch(before); // return hasTrAfter || hasTrBefore; // } // /// 找出所有注释区间 (start, end) // List> getCommentRanges(String content) { // final ranges = >[]; // final multiLine = RegExp(r'/\*[\s\S]*?\*/'); // final singleLine = RegExp(r'//.*'); // for (final m in multiLine.allMatches(content)) { // ranges.add([m.start, m.end]); // } // for (final m in singleLine.allMatches(content)) { // ranges.add([m.start, m.end]); // } // return ranges; // } import 'dart:io'; import 'dart:convert'; void main(List args) async { if (args.length < 2) { print('Usage: dart script.dart '); return; } final targetPath = args[0]; final jsonFilePath = args[1]; // 加载JSON文件 final jsonFile = File(jsonFilePath); if (!jsonFile.existsSync()) { print('JSON file not found: $jsonFilePath'); return; } final jsonContent = await jsonFile.readAsString(); final jsonMap = json.decode(jsonContent) as Map; final targetKeys = jsonMap.keys.toSet(); final type = FileSystemEntity.typeSync(targetPath); if (type == FileSystemEntityType.notFound) { print('Path not found: $targetPath'); return; } if (type == FileSystemEntityType.file && targetPath.endsWith('.dart')) { await processDartFile(File(targetPath), targetKeys); } else if (type == FileSystemEntityType.directory) { final directory = Directory(targetPath); print('Scanning directory: $targetPath'); await for (final entity in directory.list(recursive: true, followLinks: false)) { if (entity is File && entity.path.endsWith('.dart')) { await processDartFile(entity, targetKeys); } } print('Processing completed'); } else { print('Unsupported path type: $targetPath'); } } Future processDartFile(File file, Set targetKeys) async { final content = await file.readAsString(); final commentRanges = getCommentRanges(content); final regex = RegExp(r'''(['"])([^'"]*?[\u4e00-\u9fa5][^'"]*?)\1'''); final matches = regex.allMatches(content).toList(); if (matches.isEmpty) { print('✓ No matches in: ${file.path}'); return; } final sb = StringBuffer(); int lastIndex = 0; bool hasChanges = false; for (final match in matches) { final start = match.start; final end = match.end; // 跳过注释中的内容 if (commentRanges.any((range) => start >= range[0] && start < range[1])) { sb.write(content.substring(lastIndex, end)); lastIndex = end; continue; } final fullMatch = match.group(0)!; final textContent = match.group(2)!; // 检查是否在目标keys中 if (targetKeys.contains(textContent)) { // 检查是否已经包含.tr if (!isAlreadyTrCall(content, start, end)) { sb.write(content.substring(lastIndex, start)); sb.write('$fullMatch.tr'); hasChanges = true; lastIndex = end; } else { sb.write(content.substring(lastIndex, end)); lastIndex = end; } } else { sb.write(content.substring(lastIndex, end)); lastIndex = end; } } sb.write(content.substring(lastIndex)); if (hasChanges) { await file.writeAsString(sb.toString()); print('✓ Modified: ${file.path}'); } else { print('✓ No changes needed: ${file.path}'); } } bool isAlreadyTrCall(String content, int start, int end) { // 检查字符串后面是否紧跟.tr final afterString = content.substring(end); return RegExp(r'^\s*\.tr\b').hasMatch(afterString); } List> getCommentRanges(String content) { final ranges = >[]; final multiLine = RegExp(r'/\*[\s\S]*?\*/'); final singleLine = RegExp(r'//.*'); for (final m in multiLine.allMatches(content)) { ranges.add([m.start, m.end]); } for (final m in singleLine.allMatches(content)) { ranges.add([m.start, m.end]); } return ranges; }