Created
July 3, 2025 18:51
-
-
Save JCKodel/4d8a0d7ac720ba153dee1b910e22de4d to your computer and use it in GitHub Desktop.
Dart i18n_extension translator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ignore_for_file: avoid_print | |
import 'dart:collection'; | |
import 'dart:convert'; | |
import 'dart:io'; | |
void main(List<String> arguments) { | |
final dartFiles = Directory( | |
"lib", | |
).listSync(recursive: true).where((entity) => entity.path.endsWith(".dart")); | |
final i18nStrings = <String>{}; | |
final stringRegex = RegExp( | |
r'(?:"""([\s\S]*?)"""|"([^"]*)")\s*\.(trs|fill)', | |
multiLine: true, | |
); | |
for (final file in dartFiles) { | |
final content = File(file.path).readAsStringSync(); | |
final matches = stringRegex.allMatches(content); | |
if (matches.isNotEmpty) { | |
print("Processing ${file.path}: ${matches.length}"); | |
for (final match in matches) { | |
final key = match.group(1)?.trim() ?? match.group(2)?.trim(); | |
if (key != null) { | |
i18nStrings.add(key); | |
} | |
} | |
} | |
} | |
updateTranslationFile("en", i18nStrings); | |
updateTranslationFile("pt", i18nStrings); | |
} | |
Future<void> updateTranslationFile(String language, Set<String> i18nStrings) async { | |
final file = File("assets/translations/$language.json"); | |
final json = file.readAsStringSync(); | |
final translations = LinkedHashMap<String, dynamic>.from(jsonDecode(json) as Map); | |
final tasks = <Future<String>>[]; | |
var updated = false; | |
for (final key in i18nStrings) { | |
if (translations.containsKey(key) == false) { | |
if (language == "pt") { | |
translations[key] = key; | |
} else { | |
translations[key] = ""; | |
tasks.add( | |
_translate(key, language).then((value) => translations[key] = value), | |
); | |
} | |
updated = true; | |
} | |
} | |
await Future.wait(tasks); | |
final numberOfKeys = translations.length; | |
translations.removeWhere( | |
(key, value) => key.contains(".") == false && i18nStrings.contains(key) == false, | |
); | |
if (updated || numberOfKeys != translations.length) { | |
file.writeAsStringSync( | |
const JsonEncoder.withIndent( | |
" ", | |
).convert(Map<String, dynamic>.from(translations)), | |
); | |
print("Updated $language with ${translations.length} keys"); | |
} | |
} | |
Future<String> _translate(String text, String language) async { | |
final result = await Process.run('./trans.sh', [ | |
'-b', | |
'-e', | |
'bing', | |
':${language}', | |
text, | |
], runInShell: true); | |
if (result.exitCode != 0) { | |
return ""; | |
} | |
return result.stdout.toString().trim(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment