From c87dbf471ce16618e76a8239a4581fd11101fa15 Mon Sep 17 00:00:00 2001 From: James Leahy Date: Sun, 3 May 2026 13:48:40 +0200 Subject: [PATCH 1/7] poc --- lib/src/models/arb/arb_file.dart | 5 +++- lib/src/services/arb_generator.dart | 38 +++++++++++++++++++++++++++-- pubspec.yaml | 1 + 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/lib/src/models/arb/arb_file.dart b/lib/src/models/arb/arb_file.dart index 9195f17..b110c70 100644 --- a/lib/src/models/arb/arb_file.dart +++ b/lib/src/models/arb/arb_file.dart @@ -18,16 +18,19 @@ class Message { required this.key, required this.value, this.description, + this.metadata, }); final String key; final String value; final String? description; + final Map? metadata; Map toJson() => { key: value, '@$key': { - if (description != null) 'description': description, + 'description': ?description, + ...?metadata, }, }; } diff --git a/lib/src/services/arb_generator.dart b/lib/src/services/arb_generator.dart index 03f00a9..b39f039 100644 --- a/lib/src/services/arb_generator.dart +++ b/lib/src/services/arb_generator.dart @@ -1,6 +1,8 @@ import 'dart:convert'; import 'dart:io'; +import 'package:path/path.dart' as p; + import '../models/arb/arb_file.dart'; import '../models/settings/package_settings.dart'; import 'file_writer/file_writer.dart'; @@ -24,6 +26,11 @@ abstract class ARBGenerator { // File is valid, state progress print('Loading file ${packageSettings.inputFilepath}...'); + // Try to load optional metadata + final optionalMetadata = _loadOptionalMetadata( + packageSettings.inputFilepath, + ); + final parser = CSVParser( file: file, startIndex: packageSettings.csvSettings.baseIndex, @@ -56,6 +63,7 @@ abstract class ARBGenerator { descriptions: packageSettings.csvSettings.descriptionIndex != null ? parser.getColumn(packageSettings.csvSettings.descriptionIndex!) : null, + optionalMetadata: optionalMetadata, ); var prettyContent = encoder.convert(content.toJson()); // convert turns \n into \\n @@ -76,12 +84,31 @@ abstract class ARBGenerator { } } +Map? _loadOptionalMetadata( + String inputFilepath, +) { + final optionalMetadataPath = p.setExtension( + inputFilepath, + '.json', + ); + final optionalMetadataFile = File(optionalMetadataPath); + final contents = optionalMetadataFile.existsSync() + ? json.decode(optionalMetadataFile.readAsStringSync()) + : null; + if (contents != null) { + print('Loading optional metadata $optionalMetadataPath...'); + } + + return contents; +} + ARBFile _generateARBFile({ required String language, required List keys, required List values, required List defaultValues, List? descriptions, + Map? optionalMetadata, }) { if (keys.length != values.length && keys.length != defaultValues.length) { print('Error! Mismatch number of keys and values'); @@ -89,15 +116,22 @@ ARBFile _generateARBFile({ } final messages = []; - for (var i = 0; i < keys.length; i++) { + for (final (i, key) in keys.indexed) { final value = i < values.length && values[i].isNotEmpty ? values[i] : defaultValues[i]; + + final metadata = optionalMetadata?['@$key'] ?? optionalMetadata?[key]; + // if (metadata != null) { + // print('Adding metadata $metadata to $key'); + // } + messages.add( Message( - key: keys[i], + key: key, value: value, description: descriptions?[i], + metadata: metadata, ), ); } diff --git a/pubspec.yaml b/pubspec.yaml index ae84fef..7930df0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -12,6 +12,7 @@ dependencies: meta: ^1.16.0 yaml: ^3.1.2 csv: ^6.0.0 + path: ^1.9.0 dev_dependencies: test: ^1.25.5 From e147f1042f7a80251d18d477b4c9129b4f8bc49c Mon Sep 17 00:00:00 2001 From: James Leahy Date: Sun, 3 May 2026 14:14:35 +0200 Subject: [PATCH 2/7] test1 --- example/assets_dev/test.json | 9 +++++++++ example/lib/l10n/app_de.arb | 7 ++++++- example/lib/l10n/app_en.arb | 7 ++++++- 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 example/assets_dev/test.json diff --git a/example/assets_dev/test.json b/example/assets_dev/test.json new file mode 100644 index 0000000..0f3e213 --- /dev/null +++ b/example/assets_dev/test.json @@ -0,0 +1,9 @@ +{ + "@welcome": { + "placeholders": { + "firstName": { + "type": "String" + } + } + } +} \ No newline at end of file diff --git a/example/lib/l10n/app_de.arb b/example/lib/l10n/app_de.arb index 2b60c71..b645f8d 100644 --- a/example/lib/l10n/app_de.arb +++ b/example/lib/l10n/app_de.arb @@ -6,7 +6,12 @@ }, "welcome": "Willkommen {firstName}!", "@welcome": { - "description": "A welcome message" + "description": "A welcome message", + "placeholders": { + "firstName": { + "type": "String" + } + } }, "numberMessages": "{count, plural, zero{Du hast keine neue Nachrichten} one{Du hast eine neue Nachricht} other{Du hast {count} neue Nachrichten}}", "@numberMessages": { diff --git a/example/lib/l10n/app_en.arb b/example/lib/l10n/app_en.arb index f417729..8b8158c 100644 --- a/example/lib/l10n/app_en.arb +++ b/example/lib/l10n/app_en.arb @@ -6,7 +6,12 @@ }, "welcome": "Welcome {firstName}!", "@welcome": { - "description": "A welcome message" + "description": "A welcome message", + "placeholders": { + "firstName": { + "type": "String" + } + } }, "numberMessages": "{count, plural, zero{You have no new messages} one{You have 1 new message} other{You have {count} new messages}}", "@numberMessages": { From cc546533234e4dbe02633caa3f6a5b42b09ac48c Mon Sep 17 00:00:00 2001 From: James Leahy Date: Sun, 3 May 2026 14:23:54 +0200 Subject: [PATCH 3/7] test2 --- example/assets_dev/test.json | 3 ++- example/lib/l10n/app_de.arb | 3 ++- example/lib/l10n/app_en.arb | 3 ++- example/lib/l10n/app_localizations.dart | 2 +- example/lib/l10n/app_localizations_de.dart | 2 +- example/lib/l10n/app_localizations_en.dart | 2 +- 6 files changed, 9 insertions(+), 6 deletions(-) diff --git a/example/assets_dev/test.json b/example/assets_dev/test.json index 0f3e213..c2cfc76 100644 --- a/example/assets_dev/test.json +++ b/example/assets_dev/test.json @@ -2,7 +2,8 @@ "@welcome": { "placeholders": { "firstName": { - "type": "String" + "type": "String", + "example": "Dash" } } } diff --git a/example/lib/l10n/app_de.arb b/example/lib/l10n/app_de.arb index b645f8d..8eb4e9e 100644 --- a/example/lib/l10n/app_de.arb +++ b/example/lib/l10n/app_de.arb @@ -9,7 +9,8 @@ "description": "A welcome message", "placeholders": { "firstName": { - "type": "String" + "type": "String", + "example": "Dash" } } }, diff --git a/example/lib/l10n/app_en.arb b/example/lib/l10n/app_en.arb index 8b8158c..caebd06 100644 --- a/example/lib/l10n/app_en.arb +++ b/example/lib/l10n/app_en.arb @@ -9,7 +9,8 @@ "description": "A welcome message", "placeholders": { "firstName": { - "type": "String" + "type": "String", + "example": "Dash" } } }, diff --git a/example/lib/l10n/app_localizations.dart b/example/lib/l10n/app_localizations.dart index 8d708f0..c142e81 100644 --- a/example/lib/l10n/app_localizations.dart +++ b/example/lib/l10n/app_localizations.dart @@ -108,7 +108,7 @@ abstract class AppLocalizations { /// /// In en, this message translates to: /// **'Welcome {firstName}!'** - String welcome(Object firstName); + String welcome(String firstName); /// An info message about new messages count /// diff --git a/example/lib/l10n/app_localizations_de.dart b/example/lib/l10n/app_localizations_de.dart index c87b853..c112b49 100644 --- a/example/lib/l10n/app_localizations_de.dart +++ b/example/lib/l10n/app_localizations_de.dart @@ -12,7 +12,7 @@ class AppLocalizationsDe extends AppLocalizations { String get myKey => 'Hallo Welt!'; @override - String welcome(Object firstName) { + String welcome(String firstName) { return 'Willkommen $firstName!'; } diff --git a/example/lib/l10n/app_localizations_en.dart b/example/lib/l10n/app_localizations_en.dart index 27b8127..ae1d67a 100644 --- a/example/lib/l10n/app_localizations_en.dart +++ b/example/lib/l10n/app_localizations_en.dart @@ -12,7 +12,7 @@ class AppLocalizationsEn extends AppLocalizations { String get myKey => 'Hello world!'; @override - String welcome(Object firstName) { + String welcome(String firstName) { return 'Welcome $firstName!'; } From 4945f95da057c213d4fe9065ca78afe1efc0c586 Mon Sep 17 00:00:00 2001 From: James Leahy Date: Sun, 3 May 2026 14:26:31 +0200 Subject: [PATCH 4/7] full example --- example/assets_dev/test.json | 20 ++++++++++++++++++++ example/lib/l10n/app_de.arb | 20 ++++++++++++++++++-- example/lib/l10n/app_en.arb | 20 ++++++++++++++++++-- example/lib/l10n/app_localizations.dart | 4 ++-- example/lib/l10n/app_localizations_de.dart | 4 ++-- example/lib/l10n/app_localizations_en.dart | 4 ++-- 6 files changed, 62 insertions(+), 10 deletions(-) diff --git a/example/assets_dev/test.json b/example/assets_dev/test.json index c2cfc76..014ab24 100644 --- a/example/assets_dev/test.json +++ b/example/assets_dev/test.json @@ -6,5 +6,25 @@ "example": "Dash" } } + }, + "@numberMessages": { + "placeholders": { + "count": { + "type": "int", + "example": "1" + } + } + }, + "unreadEmails": { + "placeholders": { + "howMany": { + "type": "int", + "example": "1" + }, + "userName": { + "type": "String", + "example": "dash" + } + } } } \ No newline at end of file diff --git a/example/lib/l10n/app_de.arb b/example/lib/l10n/app_de.arb index 8eb4e9e..cfcd652 100644 --- a/example/lib/l10n/app_de.arb +++ b/example/lib/l10n/app_de.arb @@ -16,7 +16,13 @@ }, "numberMessages": "{count, plural, zero{Du hast keine neue Nachrichten} one{Du hast eine neue Nachricht} other{Du hast {count} neue Nachrichten}}", "@numberMessages": { - "description": "An info message about new messages count" + "description": "An info message about new messages count", + "placeholders": { + "count": { + "type": "int", + "example": "1" + } + } }, "whoseBook": "{sex, select, male{Sein Buch} female{Ihr Buch} other{Ihr Buch}}", "@whoseBook": { @@ -24,7 +30,17 @@ }, "unreadEmails": "{howMany, plural, zero{Es gibt keine ungelesenen Emails für {userName}} one{Es gibt eine ungelesene für {userName}} other{Es gibt {howMany} ungelesenen Emails für {userName}}}", "@unreadEmails": { - "description": "How many unread emails for user" + "description": "How many unread emails for user", + "placeholders": { + "howMany": { + "type": "int", + "example": "1" + }, + "userName": { + "type": "String", + "example": "dash" + } + } }, "weatherReaction": "{weatherType, select, sunny{Prima} cloudy{In Ordnung} rainy{Mist} other{Other}}", "@weatherReaction": { diff --git a/example/lib/l10n/app_en.arb b/example/lib/l10n/app_en.arb index caebd06..45f636a 100644 --- a/example/lib/l10n/app_en.arb +++ b/example/lib/l10n/app_en.arb @@ -16,7 +16,13 @@ }, "numberMessages": "{count, plural, zero{You have no new messages} one{You have 1 new message} other{You have {count} new messages}}", "@numberMessages": { - "description": "An info message about new messages count" + "description": "An info message about new messages count", + "placeholders": { + "count": { + "type": "int", + "example": "1" + } + } }, "whoseBook": "{sex, select, male{His book} female{Her book} other{Their book}}", "@whoseBook": { @@ -24,7 +30,17 @@ }, "unreadEmails": "{howMany, plural, zero{There are no unread emails for {userName}} one{There is 1 unread email for {userName}} other{There are {howMany} unread emails for {userName}}}", "@unreadEmails": { - "description": "How many unread emails for user" + "description": "How many unread emails for user", + "placeholders": { + "howMany": { + "type": "int", + "example": "1" + }, + "userName": { + "type": "String", + "example": "dash" + } + } }, "weatherReaction": "{weatherType, select, sunny{Woohoo} cloudy{Meh} rainy{Weeh} other{Other}}", "@weatherReaction": { diff --git a/example/lib/l10n/app_localizations.dart b/example/lib/l10n/app_localizations.dart index c142e81..2a760f6 100644 --- a/example/lib/l10n/app_localizations.dart +++ b/example/lib/l10n/app_localizations.dart @@ -114,7 +114,7 @@ abstract class AppLocalizations { /// /// In en, this message translates to: /// **'{count, plural, zero{You have no new messages} one{You have 1 new message} other{You have {count} new messages}}'** - String numberMessages(num count); + String numberMessages(int count); /// A message determine whose book it is /// @@ -126,7 +126,7 @@ abstract class AppLocalizations { /// /// In en, this message translates to: /// **'{howMany, plural, zero{There are no unread emails for {userName}} one{There is 1 unread email for {userName}} other{There are {howMany} unread emails for {userName}}}'** - String unreadEmails(num howMany, Object userName); + String unreadEmails(int howMany, String userName); /// Reaction to types of weather /// diff --git a/example/lib/l10n/app_localizations_de.dart b/example/lib/l10n/app_localizations_de.dart index c112b49..d0ea340 100644 --- a/example/lib/l10n/app_localizations_de.dart +++ b/example/lib/l10n/app_localizations_de.dart @@ -17,7 +17,7 @@ class AppLocalizationsDe extends AppLocalizations { } @override - String numberMessages(num count) { + String numberMessages(int count) { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, @@ -42,7 +42,7 @@ class AppLocalizationsDe extends AppLocalizations { } @override - String unreadEmails(num howMany, Object userName) { + String unreadEmails(int howMany, String userName) { String _temp0 = intl.Intl.pluralLogic( howMany, locale: localeName, diff --git a/example/lib/l10n/app_localizations_en.dart b/example/lib/l10n/app_localizations_en.dart index ae1d67a..bae5385 100644 --- a/example/lib/l10n/app_localizations_en.dart +++ b/example/lib/l10n/app_localizations_en.dart @@ -17,7 +17,7 @@ class AppLocalizationsEn extends AppLocalizations { } @override - String numberMessages(num count) { + String numberMessages(int count) { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, @@ -42,7 +42,7 @@ class AppLocalizationsEn extends AppLocalizations { } @override - String unreadEmails(num howMany, Object userName) { + String unreadEmails(int howMany, String userName) { String _temp0 = intl.Intl.pluralLogic( howMany, locale: localeName, From 8fec6baffc58ab8363eab49ed10c08a0bf876e41 Mon Sep 17 00:00:00 2001 From: James Leahy Date: Sun, 3 May 2026 14:29:10 +0200 Subject: [PATCH 5/7] Documentation --- README.md | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/README.md b/README.md index 7a9a712..34ed2a2 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,55 @@ dart run arb_generator ARB files are then generated in `output_directory`. +## Flutter Localizations + +See [example](example/l10n.yml) and follow the [official documentation](https://docs.flutter.dev/ui/internationalization#adding-your-own-localized-messages) to generate localization delegates from the arb files. + +## Optional Metadata + +By default, if a description is given, it is added as metadata in the arb file: + +``` +"welcome": "Welcome {firstName}!", +"@welcome": { + "description": "A welcome message", +} +``` + +Optional metadata can be supplied by adding a `json` file with the same filename as the csv file: + +``` +{ + "@welcome": { + "placeholders": { + "firstName": { + "type": "String", + "example": "Dash" + } + } + } +} +``` + +This metadata will then copied into the generated file: + +``` +"welcome": "Welcome {firstName}!", +"@welcome": { + "description": "A welcome message", + "placeholders": { + "firstName": { + "type": "String", + "example": "Dash" + } + } +} +``` + +Now the generated delegates will expect `firstName` to be of type `String` not `Object`. + +See [example/assets_dev/test.json](example/assets_dev/test.json) for more info. + ## Collaboration Spotted any issues? Please open [an issue on GitHub](https://github.com/defuncart/arb_generator/issues)! Would like to contribute a new feature? Fork the repo and submit a PR! From 4ae02e9024bdd744b13daae167cb25e084b56f64 Mon Sep 17 00:00:00 2001 From: James Leahy Date: Fri, 8 May 2026 17:46:57 +0200 Subject: [PATCH 6/7] Update README --- CHANGELOG.md | 1 + README.md | 143 +++++++++++++++++++--------- example/assets_dev/test.csv | 2 +- example/lib/l10n/app_de.arb | 2 +- example/lib/l10n/app_en.arb | 2 +- lib/src/services/arb_generator.dart | 4 +- pubspec.yaml | 2 +- 7 files changed, 102 insertions(+), 54 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f98d84f..96f27ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## [0.1.0] - * Set Dart 3.8 as minimum constraint +* Ability to set optional placeholder metadata ## [0.0.4] - 20/10/2024 diff --git a/README.md b/README.md index 34ed2a2..1332c6f 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,20 @@ # arb_generator -A dart tool which generates ARB files from CSV files. +A dart tool which generates ARB localization files from CSV files. -## Getting Started - -A CSV file of the form - -|keys|description|en|de| -|-|-|-|-| -|myKey|The conventional newborn programmer greeting|Hello world!|Hallo Welt!| -|welcome|A welcome message|Welcome {firstName}!|Willkommen {firstName}!| -|numberMessages|An info message about new messages count|{count, plural, zero{You have no new messages} one{You have 1 new message} other{You have {count} new messages}}|{count, plural, zero{Du hast keine neue Nachrichten} one{Du hast eine neue Nachricht} other{Du hast {count} neue Nachrichten}}| -|whoseBook|A message determine whose book it is|{sex, select, male{His book} female{Her book} other{Their book}}|{sex, select, male{Sein Buch} female{Ihr Buch} other{Ihr Buch}}| +## Features -is generated into the following ARB file +- CSV → ARB conversion +- Flutter intl compatible +- ICU placeholder, plural and select support +- Placeholder metadata support +- Multi-language generation -```json -{ - "@@locale": "en", - "myKey": "Hello world!", - "@myKey": { - "description": "The conventional newborn programmer greeting" - }, - "welcome": "Welcome {firstName}!", - "@welcome": { - "description": "A welcome message" - }, - "numberMessages": "{count, plural, zero{You have no new messages} one{You have 1 new message} other{You have {count} new messages}}", - "@numberMessages": { - "description": "An info message about new messages count" - }, - "whoseBook": "{sex, select, male{His book} female{Her book} other{Their book}}", - "@whoseBook": { - "description": "A message determine whose book it is" - } -} -``` - -This ARB file can then be converted into localization delegates using [intl](https://docs.flutter.dev/development/accessibility-and-localization/internationalization) or [intl_utils](https://pub.dev/packages/intl_utils). +## Getting Started ### Add dependency -Firstly, add the package as a dev dependency: +Add the package as a dev dependency: ```yaml dev_dependencies: @@ -50,7 +23,7 @@ dev_dependencies: ### Define Settings -Next define arb_generator package settings in `pubspec.yaml`. Note that `input_filepath` is the only required parameter. +Next define arb_generator package settings in `pubspec.yaml`: ```yaml arb_generator: @@ -69,12 +42,12 @@ arb_generator: | output_directory | A directory to generate the output ARB file(s). Defaults to `lib/l10n` | | filename_prepend | Text to prepend to filename of generated files. Defaults to empty string. | | csv_settings: delimiter | A delimiter to separate columns in the input CSV file. Defaults to `,`. | -| csv_settings: description_index | The description column index. Defaults to `null`. | +| csv_settings: description_index | The description column index. Defaults to `null` (i.e. no description given) | | csv_settings: base_index | The column index of the base language in the input CSV file. Defaults to `1`. | ### Run package -Ensure that your current working directory is the project root and run the following command: +Run the following command from your project root: ```sh dart run arb_generator @@ -82,24 +55,92 @@ dart run arb_generator ARB files are then generated in `output_directory`. -## Flutter Localizations +## Generated Output -See [example](example/l10n.yml) and follow the [official documentation](https://docs.flutter.dev/ui/internationalization#adding-your-own-localized-messages) to generate localization delegates from the arb files. +A CSV file of the form -## Optional Metadata +|keys|description|en|de| +|-|-|-|-| +|myKey|The conventional newborn programmer greeting|Hello world!|Hallo Welt!| +|welcome|A welcome message|Welcome {firstName}!|Willkommen {firstName}!| +|numberMessages|An info message about new messages count|{count, plural, zero{You have no new messages} one{You have 1 new message} other{You have {count} new messages}}|{count, plural, zero{Du hast keine neue Nachrichten} one{Du hast eine neue Nachricht} other{Du hast {count} neue Nachrichten}}| +|whoseBook|A message determining whose book it is|{sex, select, male{His book} female{Her book} other{Their book}}|{sex, select, male{Sein Buch} female{Ihr Buch} other{Ihr Buch}}| + +generates the following ARB files: + +**en.arb** + +```json +{ + "@@locale": "en", + "myKey": "Hello world!", + "@myKey": { + "description": "The conventional newborn programmer greeting" + }, + "welcome": "Welcome {firstName}!", + "@welcome": { + "description": "A welcome message" + }, + "numberMessages": "{count, plural, zero{You have no new messages} one{You have 1 new message} other{You have {count} new messages}}", + "@numberMessages": { + "description": "An info message about new messages count" + }, + "whoseBook": "{sex, select, male{His book} female{Her book} other{Their book}}", + "@whoseBook": { + "description": "A message determining whose book it is" + } +} +``` -By default, if a description is given, it is added as metadata in the arb file: +**de.arb** +```json +{ + "@@locale": "de", + "myKey": "Hallo Welt!", + "@myKey": { + "description": "The conventional newborn programmer greeting" + }, + "welcome": "Willkommen {firstName}!", + "@welcome": { + "description": "A welcome message" + }, + "numberMessages": "{count, plural, zero{Du hast keine neue Nachrichten} one{Du hast eine neue Nachricht} other{Du hast {count} neue Nachrichten}}", + "@numberMessages": { + "description": "An info message about new messages count" + }, + "whoseBook": "{sex, select, male{Sein Buch} female{Ihr Buch} other{Ihr Buch}}", + "@whoseBook": { + "description": "A message determining whose book it is" + } +} ``` + +## CSV Format + +- The first column must contain translation keys +- Locale columns should use valid locale codes such as `en`, `de` or `en_US` +- The first row is treated as the header row +- ICU message syntax is supported in translation values + +## Flutter Integration + +See [example/l10n.yml](example/l10n.yml) and follow the [official documentation](https://docs.flutter.dev/ui/internationalization) to generate localization delegates from the ARB files. + +## Optional Metadata + +By default, if a description is given, it is added as metadata in the ARB file: + +```json "welcome": "Welcome {firstName}!", "@welcome": { "description": "A welcome message", } ``` -Optional metadata can be supplied by adding a `json` file with the same filename as the csv file: +Optional placeholder metadata can be supplied by adding a `json` file with the same filename as `input_filepath` input CSV file: -``` +```json { "@welcome": { "placeholders": { @@ -112,9 +153,9 @@ Optional metadata can be supplied by adding a `json` file with the same filename } ``` -This metadata will then copied into the generated file: +This metadata will then be copied into the generated file: -``` +```json "welcome": "Welcome {firstName}!", "@welcome": { "description": "A welcome message", @@ -129,6 +170,14 @@ This metadata will then copied into the generated file: Now the generated delegates will expect `firstName` to be of type `String` not `Object`. +```dart +/// A welcome message +/// +/// In en, this message translates to: +/// **'Welcome {firstName}!'** +String welcome(String firstName); +``` + See [example/assets_dev/test.json](example/assets_dev/test.json) for more info. ## Collaboration diff --git a/example/assets_dev/test.csv b/example/assets_dev/test.csv index f08967a..33a33f2 100644 --- a/example/assets_dev/test.csv +++ b/example/assets_dev/test.csv @@ -2,6 +2,6 @@ keys;description;en;de myKey;The conventional newborn programmer greeting;Hello world!;Hallo Welt! welcome;A welcome message;Welcome {firstName}!;Willkommen {firstName}! numberMessages;An info message about new messages count;{count, plural, zero{You have no new messages} one{You have 1 new message} other{You have {count} new messages}};{count, plural, zero{Du hast keine neue Nachrichten} one{Du hast eine neue Nachricht} other{Du hast {count} neue Nachrichten}} -whoseBook;A message determine whose book it is;{sex, select, male{His book} female{Her book} other{Their book}};{sex, select, male{Sein Buch} female{Ihr Buch} other{Ihr Buch}} +whoseBook;A message determining whose book it is;{sex, select, male{His book} female{Her book} other{Their book}};{sex, select, male{Sein Buch} female{Ihr Buch} other{Ihr Buch}} unreadEmails;How many unread emails for user;{howMany, plural, zero{There are no unread emails for {userName}} one{There is 1 unread email for {userName}} other{There are {howMany} unread emails for {userName}}};{howMany, plural, zero{Es gibt keine ungelesenen Emails für {userName}} one{Es gibt eine ungelesene für {userName}} other{Es gibt {howMany} ungelesenen Emails für {userName}}} weatherReaction;Reaction to types of weather;{weatherType, select, sunny{Woohoo} cloudy{Meh} rainy{Weeh} other{Other}};{weatherType, select, sunny{Prima} cloudy{In Ordnung} rainy{Mist} other{Other}} diff --git a/example/lib/l10n/app_de.arb b/example/lib/l10n/app_de.arb index cfcd652..cf13b2e 100644 --- a/example/lib/l10n/app_de.arb +++ b/example/lib/l10n/app_de.arb @@ -26,7 +26,7 @@ }, "whoseBook": "{sex, select, male{Sein Buch} female{Ihr Buch} other{Ihr Buch}}", "@whoseBook": { - "description": "A message determine whose book it is" + "description": "A message determining whose book it is" }, "unreadEmails": "{howMany, plural, zero{Es gibt keine ungelesenen Emails für {userName}} one{Es gibt eine ungelesene für {userName}} other{Es gibt {howMany} ungelesenen Emails für {userName}}}", "@unreadEmails": { diff --git a/example/lib/l10n/app_en.arb b/example/lib/l10n/app_en.arb index 45f636a..b55e72c 100644 --- a/example/lib/l10n/app_en.arb +++ b/example/lib/l10n/app_en.arb @@ -26,7 +26,7 @@ }, "whoseBook": "{sex, select, male{His book} female{Her book} other{Their book}}", "@whoseBook": { - "description": "A message determine whose book it is" + "description": "A message determining whose book it is" }, "unreadEmails": "{howMany, plural, zero{There are no unread emails for {userName}} one{There is 1 unread email for {userName}} other{There are {howMany} unread emails for {userName}}}", "@unreadEmails": { diff --git a/lib/src/services/arb_generator.dart b/lib/src/services/arb_generator.dart index b39f039..7db4281 100644 --- a/lib/src/services/arb_generator.dart +++ b/lib/src/services/arb_generator.dart @@ -121,10 +121,8 @@ ARBFile _generateARBFile({ ? values[i] : defaultValues[i]; + // safety check in case user forgot @ final metadata = optionalMetadata?['@$key'] ?? optionalMetadata?[key]; - // if (metadata != null) { - // print('Adding metadata $metadata to $key'); - // } messages.add( Message( diff --git a/pubspec.yaml b/pubspec.yaml index 7930df0..807086d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: arb_generator -description: A dart tool which generates ARB files from CSV files. +description: A dart tool which generates ARB localization files from CSV files. version: 0.0.4 homepage: https://github.com/defuncart/arb_generator repository: https://github.com/defuncart/arb_generator From 04193da59bb6adc081fde7f40e35919d4727798e Mon Sep 17 00:00:00 2001 From: James Leahy Date: Fri, 8 May 2026 18:45:30 +0200 Subject: [PATCH 7/7] Fix test --- example/lib/l10n/app_localizations.dart | 2 +- test/services/parsing/csv_parser_test.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example/lib/l10n/app_localizations.dart b/example/lib/l10n/app_localizations.dart index 2a760f6..34953c7 100644 --- a/example/lib/l10n/app_localizations.dart +++ b/example/lib/l10n/app_localizations.dart @@ -116,7 +116,7 @@ abstract class AppLocalizations { /// **'{count, plural, zero{You have no new messages} one{You have 1 new message} other{You have {count} new messages}}'** String numberMessages(int count); - /// A message determine whose book it is + /// A message determining whose book it is /// /// In en, this message translates to: /// **'{sex, select, male{His book} female{Her book} other{Their book}}'** diff --git a/test/services/parsing/csv_parser_test.dart b/test/services/parsing/csv_parser_test.dart index 857447b..099ad47 100644 --- a/test/services/parsing/csv_parser_test.dart +++ b/test/services/parsing/csv_parser_test.dart @@ -32,7 +32,7 @@ void main() { ], [ 'whoseBook', - 'A message determine whose book it is', + 'A message determining whose book it is', '{sex, select, male{His book} female{Her book} other{Their book}}', '{sex, select, male{Sein Buch} female{Ihr Buch} other{Ihr Buch}}', ],