| // Copyright 2014 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // The utility function `encodeKnArbFiles` replaces the material_kn.arb |
| // and cupertino_kn.arb files in flutter_localizations/packages/lib/src/l10n |
| // with versions where the contents of the localized strings have been |
| // replaced by JSON escapes. This is done because some of those strings |
| // contain characters that can crash Emacs on Linux. There is more information |
| // here: https://github.com/flutter/flutter/issues/36704 and in the README |
| // in flutter_localizations/packages/lib/src/l10n. |
| // |
| // This utility is run by `gen_localizations.dart` if --overwrite is passed |
| // in as an option. |
| |
| import 'dart:convert'; |
| import 'dart:io'; |
| |
| import 'package:path/path.dart' as path; |
| |
| import '../localizations_utils.dart'; |
| |
| Map<String, dynamic> _loadBundle(File file) { |
| if (!FileSystemEntity.isFileSync(file.path)) { |
| exitWithError('Unable to find input file: ${file.path}'); |
| } |
| return json.decode(file.readAsStringSync()) as Map<String, dynamic>; |
| } |
| |
| void _encodeBundleTranslations(Map<String, dynamic> bundle) { |
| for (final String key in bundle.keys) { |
| // The ARB file resource "attributes" for foo are called @foo. Don't need |
| // to encode them. |
| if (key.startsWith('@')) { |
| continue; |
| } |
| final String translation = bundle[key] as String; |
| // Rewrite the string as a series of unicode characters in JSON format. |
| // Like "\u0012\u0123\u1234". |
| bundle[key] = translation.runes.map((int code) { |
| final String codeString = '00${code.toRadixString(16)}'; |
| return '\\u${codeString.substring(codeString.length - 4)}'; |
| }).join(); |
| } |
| } |
| |
| void _checkEncodedTranslations(Map<String, dynamic> encodedBundle, Map<String, dynamic> bundle) { |
| bool errorFound = false; |
| const JsonDecoder decoder = JsonDecoder(); |
| for (final String key in bundle.keys) { |
| if (decoder.convert('"${encodedBundle[key]}"') != bundle[key]) { |
| stderr.writeln(' encodedTranslation for $key does not match original value "${bundle[key]}"'); |
| errorFound = true; |
| } |
| } |
| if (errorFound) { |
| exitWithError('JSON unicode translation encoding failed'); |
| } |
| } |
| |
| void _rewriteBundle(File file, Map<String, dynamic> bundle) { |
| final StringBuffer contents = StringBuffer(); |
| contents.writeln('{'); |
| for (final String key in bundle.keys) { |
| contents.writeln(' "$key": "${bundle[key]}"${key == bundle.keys.last ? '' : ','}'); |
| } |
| contents.writeln('}'); |
| file.writeAsStringSync(contents.toString()); |
| } |
| |
| void encodeKnArbFiles(Directory directory) { |
| final File widgetsArbFile = File(path.join(directory.path, 'widgets_kn.arb')); |
| final File materialArbFile = File(path.join(directory.path, 'material_kn.arb')); |
| final File cupertinoArbFile = File(path.join(directory.path, 'cupertino_kn.arb')); |
| |
| final Map<String, dynamic> widgetsBundle = _loadBundle(widgetsArbFile); |
| final Map<String, dynamic> materialBundle = _loadBundle(materialArbFile); |
| final Map<String, dynamic> cupertinoBundle = _loadBundle(cupertinoArbFile); |
| |
| _encodeBundleTranslations(widgetsBundle); |
| _encodeBundleTranslations(materialBundle); |
| _encodeBundleTranslations(cupertinoBundle); |
| |
| _checkEncodedTranslations(widgetsBundle, _loadBundle(widgetsArbFile)); |
| _checkEncodedTranslations(materialBundle, _loadBundle(materialArbFile)); |
| _checkEncodedTranslations(cupertinoBundle, _loadBundle(cupertinoArbFile)); |
| |
| _rewriteBundle(widgetsArbFile, widgetsBundle); |
| _rewriteBundle(materialArbFile, materialBundle); |
| _rewriteBundle(cupertinoArbFile, cupertinoBundle); |
| } |