-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(passkit): Work towards localizable pass files (#40)
* localization * add translation file parsing
- Loading branch information
Showing
3 changed files
with
98 additions
and
6 deletions.
There are no files selected for viewing
This file contains 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
41 changes: 41 additions & 0 deletions
41
passkit/lib/src/strings_parser/naive_strings_file_parser.dart
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import 'dart:convert'; | ||
|
||
/// Parses [content] to a [Map<String, String>] which contains the | ||
/// key-value-pairs for translations. | ||
Map<String, String> parseStringsFile(List<int> content) { | ||
final string = _stringsFileDecoder.convert(content); | ||
return naiveStringsFileParser(string); | ||
} | ||
|
||
// TODO(ueman): `.strings` files should be read as UTF-16, not UTF-8. | ||
final Converter<List<int>, String> _stringsFileDecoder = const Utf8Decoder(); | ||
|
||
/// Here's a breakdown of the pattern: | ||
/// - r'"((?:\"|[^"])*)"': This section matches the key, which is enclosed in | ||
/// double quotes. Inside the quotes, it captures any character sequence that | ||
/// is either a backslash-escaped double quote or any character that is not a | ||
/// double quote. | ||
/// - \s?=\s?: This part matches the equals sign with optional whitespace before | ||
/// and after it. | ||
/// - r'"((?:\"|[^"])*)"': This section matches the value, using a similar | ||
/// pattern to capture any character sequence within double quotes. | ||
/// - \s?;: This last part matches optional whitespace followed by a semicolon. | ||
final _stringsParserRegEx = | ||
RegExp(r'"((?:\\"|[^"])*)"\s?=\s?"((?:\\"|[^"])*)"\s?;'); | ||
|
||
/// This method uses a quite naive approach to parse Apples `strings` file | ||
/// format with a [RegExp]. It doesn't support placeholders. | ||
/// | ||
/// The returned map has key value pairs. | ||
/// | ||
/// See also: | ||
/// - https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/LoadingResources/Strings/Strings.html | ||
/// - https://localizely.com/apple-strings-file/ | ||
Map<String, String> naiveStringsFileParser(String stringsFile) { | ||
final matches = _stringsParserRegEx | ||
.allMatches(stringsFile) | ||
.where((match) => match.group(1) != null && match.group(2) != null) | ||
.map((match) => MapEntry(match.group(1)!, match.group(2)!)); | ||
|
||
return Map.fromEntries(matches); | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import 'package:passkit/src/strings_parser/naive_strings_file_parser.dart'; | ||
import 'package:test/test.dart'; | ||
|
||
// Taken from https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/PassKit_PG/Creating.html | ||
final _testString = '''"origin_SVQ" = "Sevilla"; | ||
"destination_LHR" = "Londres"; | ||
'''; | ||
|
||
// Taken from https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/LoadingResources/Strings/Strings.html | ||
final _testStringWithComments = '''/* Insert Element menu item */ | ||
"Insert Element" = "Insert Element"; | ||
/* Error string used for unknown error types. */ | ||
"ErrorString_1" = "An unknown error occurred."; | ||
'''; | ||
|
||
void main() { | ||
test('naiveStringsFileParser() parses example correctly', () { | ||
final keyValue = naiveStringsFileParser(_testString); | ||
expect(keyValue, { | ||
'origin_SVQ': 'Sevilla', | ||
'destination_LHR': 'Londres', | ||
}); | ||
}); | ||
|
||
test( | ||
'naiveStringsFileParser() parsess example correctly despite comments in it', | ||
() { | ||
final keyValue = naiveStringsFileParser(_testStringWithComments); | ||
expect(keyValue, { | ||
'Insert Element': 'Insert Element', | ||
'ErrorString_1': 'An unknown error occurred.', | ||
}); | ||
}); | ||
} |