ad_localize 5.0.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +6 -3
- data/.rubocop.yml +5 -0
- data/.rubocop_todo.yml +319 -0
- data/CHANGELOG.md +24 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +54 -48
- data/README.md +32 -10
- data/Rakefile +1 -0
- data/ad_localize.gemspec +10 -9
- data/bin/console +1 -0
- data/exe/ad_localize +2 -1
- data/lib/ad_localize/ad_logger.rb +5 -10
- data/lib/ad_localize/cli.rb +10 -3
- data/lib/ad_localize/entities/key.rb +3 -76
- data/lib/ad_localize/entities/locale_wording.rb +32 -52
- data/lib/ad_localize/entities/platform.rb +13 -0
- data/lib/ad_localize/entities/simple_wording.rb +6 -0
- data/lib/ad_localize/entities/wording_type.rb +11 -0
- data/lib/ad_localize/interactors/base_generate_files.rb +37 -0
- data/lib/ad_localize/interactors/download_spreadsheets.rb +20 -0
- data/lib/ad_localize/interactors/export_wording.rb +26 -20
- data/lib/ad_localize/interactors/generate_info_plist.rb +24 -0
- data/lib/ad_localize/interactors/generate_ios_files.rb +12 -0
- data/lib/ad_localize/interactors/generate_json.rb +20 -0
- data/lib/ad_localize/interactors/generate_localizable_strings.rb +24 -0
- data/lib/ad_localize/interactors/generate_localizable_strings_dict.rb +24 -0
- data/lib/ad_localize/interactors/generate_properties.rb +20 -0
- data/lib/ad_localize/interactors/generate_strings.rb +25 -0
- data/lib/ad_localize/interactors/generate_yaml.rb +20 -0
- data/lib/ad_localize/interactors/merge_wordings.rb +49 -18
- data/lib/ad_localize/interactors/parse_csv_files.rb +22 -0
- data/lib/ad_localize/interactors/process_export_request.rb +21 -0
- data/lib/ad_localize/mappers/locale_wording_to_hash.rb +45 -24
- data/lib/ad_localize/mappers/options_to_export_request.rb +14 -22
- data/lib/ad_localize/option_handler.rb +50 -27
- data/lib/ad_localize/parsers/csv_parser.rb +84 -0
- data/lib/ad_localize/parsers/key_parser.rb +62 -0
- data/lib/ad_localize/repositories/drive_repository.rb +53 -0
- data/lib/ad_localize/repositories/file_system_repository.rb +2 -1
- data/lib/ad_localize/requests/export_request.rb +95 -57
- data/lib/ad_localize/sanitizers/ios_sanitizer.rb +12 -0
- data/lib/ad_localize/{mappers/android_translation_mapper.rb → sanitizers/ios_to_android_sanitizer.rb} +8 -8
- data/lib/ad_localize/sanitizers/pass_through_sanitizer.rb +10 -0
- data/lib/ad_localize/serializers/info_plist_serializer.rb +9 -11
- data/lib/ad_localize/serializers/json_serializer.rb +3 -5
- data/lib/ad_localize/serializers/localizable_strings_serializer.rb +9 -15
- data/lib/ad_localize/serializers/localizable_stringsdict_serializer.rb +12 -25
- data/lib/ad_localize/serializers/properties_serializer.rb +9 -11
- data/lib/ad_localize/serializers/strings_serializer.rb +12 -21
- data/lib/ad_localize/serializers/templated_serializer.rb +51 -0
- data/lib/ad_localize/serializers/yaml_serializer.rb +4 -6
- data/lib/ad_localize/templates/android/strings.xml.erb +6 -6
- data/lib/ad_localize/templates/ios/Localizable.stringsdict.erb +14 -14
- data/lib/ad_localize/version.rb +2 -1
- data/lib/ad_localize/view_models/compound_wording_view_model.rb +2 -0
- data/lib/ad_localize/view_models/simple_wording_view_model.rb +2 -0
- data/lib/ad_localize.rb +33 -35
- metadata +70 -47
- data/lib/ad_localize/constant.rb +0 -6
- data/lib/ad_localize/entities/translation.rb +0 -32
- data/lib/ad_localize/entities/wording.rb +0 -24
- data/lib/ad_localize/interactors/execute_export_request.rb +0 -45
- data/lib/ad_localize/interactors/export_csv_files.rb +0 -20
- data/lib/ad_localize/interactors/export_g_spreadsheet.rb +0 -64
- data/lib/ad_localize/interactors/platforms/export_android_locale_wording.rb +0 -44
- data/lib/ad_localize/interactors/platforms/export_csv_locale_wording.rb +0 -22
- data/lib/ad_localize/interactors/platforms/export_ios_locale_wording.rb +0 -75
- data/lib/ad_localize/interactors/platforms/export_json_locale_wording.rb +0 -27
- data/lib/ad_localize/interactors/platforms/export_platform_factory.rb +0 -50
- data/lib/ad_localize/interactors/platforms/export_properties_locale_wording.rb +0 -32
- data/lib/ad_localize/interactors/platforms/export_yaml_locale_wording.rb +0 -27
- data/lib/ad_localize/mappers/csv_path_to_wording.rb +0 -73
- data/lib/ad_localize/mappers/ios_translation_mapper.rb +0 -12
- data/lib/ad_localize/mappers/translation_group_mapper.rb +0 -14
- data/lib/ad_localize/mappers/translation_mapper.rb +0 -30
- data/lib/ad_localize/mappers/value_range_to_wording.rb +0 -67
- data/lib/ad_localize/repositories/g_sheets_repository.rb +0 -44
- data/lib/ad_localize/requests/export_wording_options.rb +0 -24
- data/lib/ad_localize/requests/g_spreadsheet_options.rb +0 -47
- data/lib/ad_localize/requests/merge_policy.rb +0 -28
- data/lib/ad_localize/serializers/with_template.rb +0 -19
- data/lib/ad_localize/validators/key_validator.rb +0 -31
- data/lib/ad_localize/view_models/translation_group_view_model.rb +0 -19
- data/lib/ad_localize/view_models/translation_view_model.rb +0 -23
|
@@ -1,96 +1,134 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module AdLocalize
|
|
2
3
|
module Requests
|
|
3
4
|
class ExportRequest
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
else
|
|
20
|
-
@merge_policy = nil
|
|
21
|
-
end
|
|
22
|
-
end
|
|
5
|
+
DEFAULTS = {
|
|
6
|
+
locales: [],
|
|
7
|
+
bypass_empty_values: false,
|
|
8
|
+
csv_paths: [],
|
|
9
|
+
merge_policy: Interactors::MergeWordings::DEFAULT_POLICY,
|
|
10
|
+
output_path: Pathname.new('exports'),
|
|
11
|
+
spreadsheet_id: nil,
|
|
12
|
+
sheet_ids: %w[0],
|
|
13
|
+
export_all: false,
|
|
14
|
+
verbose: false,
|
|
15
|
+
platforms: Entities::Platform::SUPPORTED_PLATFORMS,
|
|
16
|
+
downloaded_csvs: []
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
attr_accessor :output_dir
|
|
23
20
|
|
|
24
21
|
attr_reader(
|
|
25
22
|
:locales,
|
|
26
|
-
:
|
|
27
|
-
:
|
|
23
|
+
:bypass_empty_values,
|
|
24
|
+
:csv_paths,
|
|
25
|
+
:merge_policy,
|
|
28
26
|
:output_path,
|
|
27
|
+
:platforms,
|
|
28
|
+
:spreadsheet_id,
|
|
29
|
+
:sheet_ids,
|
|
30
|
+
:export_all,
|
|
29
31
|
:verbose,
|
|
30
|
-
:
|
|
31
|
-
:merge_policy
|
|
32
|
+
:downloaded_csvs
|
|
32
33
|
)
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
def initialize
|
|
36
|
+
@locales = DEFAULTS[:locales]
|
|
37
|
+
@bypass_empty_values = DEFAULTS[:bypass_empty_values]
|
|
38
|
+
@csv_paths = DEFAULTS[:csv_paths]
|
|
39
|
+
@merge_policy = DEFAULTS[:merge_policy]
|
|
40
|
+
@output_path = DEFAULTS[:output_path]
|
|
41
|
+
@platforms = DEFAULTS[:platforms]
|
|
42
|
+
@spreadsheet_id = DEFAULTS[:spreadsheet_id]
|
|
43
|
+
@sheet_ids = DEFAULTS[:sheet_ids]
|
|
44
|
+
@export_all = DEFAULTS[:export_all]
|
|
45
|
+
@verbose = DEFAULTS[:verbose]
|
|
46
|
+
@downloaded_csvs = DEFAULTS[:downloaded_csvs]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def locales=(value)
|
|
50
|
+
return unless value.is_a? Array
|
|
51
|
+
|
|
52
|
+
@locales = value.compact
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def bypass_empty_values=(value)
|
|
56
|
+
@bypass_empty_values = [true, 'true'].include?(value)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def csv_paths=(value)
|
|
60
|
+
return unless value.is_a? Array
|
|
35
61
|
|
|
36
|
-
|
|
37
|
-
!@csv_paths.blank? && @csv_paths.all? { |csv_path| File.exist?(csv_path) && is_csv?(path: csv_path) }
|
|
62
|
+
@csv_paths = value.compact.map { |path| Pathname.new(path) }
|
|
38
63
|
end
|
|
39
64
|
|
|
40
|
-
def
|
|
41
|
-
|
|
65
|
+
def merge_policy=(value)
|
|
66
|
+
@merge_policy = value unless value.blank?
|
|
42
67
|
end
|
|
43
68
|
|
|
44
|
-
def
|
|
45
|
-
@
|
|
69
|
+
def output_path=(value)
|
|
70
|
+
@output_path = Pathname.new(value) unless value.blank?
|
|
46
71
|
end
|
|
47
72
|
|
|
48
|
-
def
|
|
49
|
-
|
|
73
|
+
def platforms=(value)
|
|
74
|
+
return unless value.is_a? Array
|
|
75
|
+
|
|
76
|
+
@platforms = value.compact & DEFAULTS[:platforms]
|
|
50
77
|
end
|
|
51
78
|
|
|
52
|
-
def
|
|
53
|
-
|
|
79
|
+
def spreadsheet_id=(value)
|
|
80
|
+
@spreadsheet_id = value unless value.blank?
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def sheet_ids=(value)
|
|
84
|
+
return unless value.is_a? Array
|
|
85
|
+
|
|
86
|
+
@sheet_ids = value.compact
|
|
54
87
|
end
|
|
55
88
|
|
|
56
|
-
def
|
|
57
|
-
|
|
89
|
+
def export_all=(value)
|
|
90
|
+
@export_all = [true, 'true'].include?(value)
|
|
58
91
|
end
|
|
59
92
|
|
|
60
|
-
def
|
|
61
|
-
|
|
93
|
+
def verbose=(value)
|
|
94
|
+
@verbose = [true, 'true'].include?(value)
|
|
62
95
|
end
|
|
63
96
|
|
|
64
|
-
|
|
97
|
+
def downloaded_csvs=(value)
|
|
98
|
+
return unless value.is_a? Array
|
|
65
99
|
|
|
66
|
-
|
|
67
|
-
has_csv_files? && (@csv_paths.size == 1 || (@csv_paths.size > 1 && @merge_policy&.valid?))
|
|
100
|
+
@downloaded_csvs = value.compact
|
|
68
101
|
end
|
|
69
102
|
|
|
70
|
-
def
|
|
71
|
-
|
|
103
|
+
def has_sheets?
|
|
104
|
+
spreadsheet_id.present?
|
|
72
105
|
end
|
|
73
106
|
|
|
74
|
-
def
|
|
75
|
-
|
|
107
|
+
def has_csv_paths?
|
|
108
|
+
all_csv_paths.present?
|
|
76
109
|
end
|
|
77
110
|
|
|
78
|
-
def
|
|
79
|
-
|
|
111
|
+
def many_platforms?
|
|
112
|
+
platforms.size > 1
|
|
80
113
|
end
|
|
81
114
|
|
|
82
|
-
def
|
|
83
|
-
|
|
115
|
+
def all_csv_paths
|
|
116
|
+
csv_paths + downloaded_csvs.map(&:path)
|
|
84
117
|
end
|
|
85
118
|
|
|
86
|
-
def
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
119
|
+
def to_s
|
|
120
|
+
"locales: #{locales}, " \
|
|
121
|
+
"bypass_empty_values: #{bypass_empty_values}, " \
|
|
122
|
+
"csv_paths: #{csv_paths}, " \
|
|
123
|
+
"merge_policy: #{merge_policy}, " \
|
|
124
|
+
"output_path: #{output_path}, " \
|
|
125
|
+
"spreadsheet_id: #{spreadsheet_id}, " \
|
|
126
|
+
"sheet_ids: #{sheet_ids}, " \
|
|
127
|
+
"export_all: #{export_all}, " \
|
|
128
|
+
"verbose: #{verbose}, " \
|
|
129
|
+
"platforms: #{platforms}, " \
|
|
130
|
+
"downloaded_csvs: #{downloaded_csvs}"
|
|
93
131
|
end
|
|
94
132
|
end
|
|
95
133
|
end
|
|
96
|
-
end
|
|
134
|
+
end
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module AdLocalize
|
|
2
|
-
module
|
|
3
|
-
class
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def sanitize_value(value:)
|
|
3
|
+
module Sanitizers
|
|
4
|
+
class IOSToAndroidSanitizer
|
|
5
|
+
def sanitize(value:)
|
|
7
6
|
return if value.blank?
|
|
7
|
+
|
|
8
8
|
processedValue = value.gsub(/(?<!\\)'/, ''') # match ' unless there is a \ before
|
|
9
9
|
processedValue = processedValue.gsub(/(?<!\\)\"/, '"') # match " unless there is a \ before
|
|
10
10
|
processedValue = processedValue.gsub(">", '>')
|
|
@@ -13,9 +13,9 @@ module AdLocalize
|
|
|
13
13
|
processedValue = processedValue.gsub(/(%(\d+\$)?@)/, '%\2s') # should match values like %1$s and %s
|
|
14
14
|
hasFormatting = hasFormatting || processedValue.match(/(%((\d+\$)?(\d+)?)i)/)
|
|
15
15
|
processedValue = processedValue.gsub(/(%((\d+\$)?(\d+)?)i)/, '%\2d') # should match values like %i, %3$i, %01i, %1$02i
|
|
16
|
-
# On Android, '%' must be escaped with a second '%' if and only if the string has at least one formatting pattern. In this specific case,
|
|
16
|
+
# On Android, '%' must be escaped with a second '%' if and only if the string has at least one formatting pattern. In this specific case,
|
|
17
17
|
# a Java formatting method will be used which interprets every non escaped '%' as the start of a formatting pattern.
|
|
18
|
-
if hasFormatting
|
|
18
|
+
if hasFormatting
|
|
19
19
|
processedValue = processedValue.gsub(/%(?!((\d+\$)?(s|(\d+)?d)))/, '%%') # negative lookahead: identifies when user really wants to display a %
|
|
20
20
|
else
|
|
21
21
|
processedValue = processedValue.gsub(/%(?!((\d+\$)?(s|(\d+)?d)))/, '%') # negative lookahead: identifies when user really wants to display a %
|
|
@@ -27,4 +27,4 @@ module AdLocalize
|
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
|
-
end
|
|
30
|
+
end
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module AdLocalize
|
|
2
3
|
module Serializers
|
|
3
|
-
class InfoPlistSerializer
|
|
4
|
-
include WithTemplate
|
|
5
|
-
|
|
4
|
+
class InfoPlistSerializer < TemplatedSerializer
|
|
6
5
|
INFO_PLIST_FILENAME = "InfoPlist.strings".freeze
|
|
7
6
|
|
|
8
7
|
def initialize
|
|
9
|
-
|
|
8
|
+
super(sanitizer: Sanitizers::IOSSanitizer.new)
|
|
10
9
|
end
|
|
11
10
|
|
|
12
11
|
private
|
|
@@ -15,13 +14,12 @@ module AdLocalize
|
|
|
15
14
|
TEMPLATES_DIRECTORY + "/ios/#{INFO_PLIST_FILENAME}.erb"
|
|
16
15
|
end
|
|
17
16
|
|
|
18
|
-
def
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
translations.map { |translation| @translation_mapper.map(translation: translation) }
|
|
17
|
+
def variable_binding(locale_wording:)
|
|
18
|
+
translations = locale_wording.info_plists.map do |_, translation|
|
|
19
|
+
map_simple_wording(translation: translation)
|
|
20
|
+
end
|
|
21
|
+
{ translations: translations }
|
|
24
22
|
end
|
|
25
23
|
end
|
|
26
24
|
end
|
|
27
|
-
end
|
|
25
|
+
end
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module AdLocalize
|
|
2
3
|
module Serializers
|
|
3
4
|
class JSONSerializer
|
|
4
|
-
def initialize
|
|
5
|
-
@locale_wording_to_hash = Mappers::LocaleWordingToHash.new
|
|
6
|
-
end
|
|
7
|
-
|
|
8
5
|
def render(locale_wording:)
|
|
9
|
-
|
|
6
|
+
content = Mappers::LocaleWordingToHash.new.map(locale_wording: locale_wording)
|
|
7
|
+
content.to_json
|
|
10
8
|
end
|
|
11
9
|
end
|
|
12
10
|
end
|
|
@@ -1,31 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module AdLocalize
|
|
2
3
|
module Serializers
|
|
3
|
-
class LocalizableStringsSerializer
|
|
4
|
-
include WithTemplate
|
|
5
|
-
|
|
4
|
+
class LocalizableStringsSerializer < TemplatedSerializer
|
|
6
5
|
LOCALIZABLE_STRINGS_FILENAME = "Localizable.strings".freeze
|
|
7
6
|
|
|
8
7
|
def initialize
|
|
9
|
-
|
|
8
|
+
super(sanitizer: Sanitizers::IOSSanitizer.new)
|
|
10
9
|
end
|
|
11
10
|
|
|
12
|
-
attr_accessor(
|
|
13
|
-
:bypass_empty_values
|
|
14
|
-
)
|
|
15
|
-
|
|
16
11
|
private
|
|
17
12
|
|
|
18
13
|
def template_path
|
|
19
14
|
TEMPLATES_DIRECTORY + "/ios/#{LOCALIZABLE_STRINGS_FILENAME}.erb"
|
|
20
15
|
end
|
|
21
16
|
|
|
22
|
-
def
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
translations.select(&:has_value?).map { |translation| @translation_mapper.map(translation: translation) }
|
|
17
|
+
def variable_binding(locale_wording:)
|
|
18
|
+
translations = locale_wording.singulars.map do |_, translation|
|
|
19
|
+
map_simple_wording(translation: translation)
|
|
20
|
+
end
|
|
21
|
+
{ translations: translations }
|
|
28
22
|
end
|
|
29
23
|
end
|
|
30
24
|
end
|
|
31
|
-
end
|
|
25
|
+
end
|
|
@@ -1,41 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module AdLocalize
|
|
2
3
|
module Serializers
|
|
3
|
-
class LocalizableStringsdictSerializer
|
|
4
|
-
include WithTemplate
|
|
5
|
-
|
|
4
|
+
class LocalizableStringsdictSerializer < TemplatedSerializer
|
|
6
5
|
LOCALIZABLE_STRINGSDICT_FILENAME = "Localizable.stringsdict".freeze
|
|
7
6
|
|
|
8
7
|
def initialize
|
|
9
|
-
|
|
10
|
-
@translation_group_mapper = Mappers::TranslationGroupMapper.new(translation_mapper: @translation_mapper)
|
|
8
|
+
super(sanitizer: Sanitizers::IOSSanitizer.new)
|
|
11
9
|
end
|
|
12
10
|
|
|
13
|
-
attr_accessor(
|
|
14
|
-
:bypass_empty_values
|
|
15
|
-
)
|
|
16
|
-
|
|
17
11
|
private
|
|
18
12
|
|
|
19
13
|
def template_path
|
|
20
14
|
TEMPLATES_DIRECTORY + "/ios/#{LOCALIZABLE_STRINGSDICT_FILENAME}.erb"
|
|
21
15
|
end
|
|
22
16
|
|
|
23
|
-
def
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
plurals.map { |label, translations| @translation_group_mapper.map(label: label, translations: translations.select(&:has_value?)) }
|
|
32
|
-
.select(&:has_translations?)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def map_adaptives(adaptives:)
|
|
36
|
-
adaptives.map { |label, translations| @translation_group_mapper.map(label: label, translations: translations.select(&:has_value?)) }
|
|
37
|
-
.select(&:has_translations?)
|
|
17
|
+
def variable_binding(locale_wording:)
|
|
18
|
+
plurals = locale_wording.plurals.map do |label, translations|
|
|
19
|
+
map_compound_wording(label: label, translations: translations)
|
|
20
|
+
end
|
|
21
|
+
adaptives = locale_wording.adaptives.map do |label, translations|
|
|
22
|
+
map_compound_wording(label: label, translations: translations)
|
|
23
|
+
end
|
|
24
|
+
{ plurals: plurals, adaptives: adaptives }
|
|
38
25
|
end
|
|
39
26
|
end
|
|
40
27
|
end
|
|
41
|
-
end
|
|
28
|
+
end
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module AdLocalize
|
|
2
3
|
module Serializers
|
|
3
|
-
class PropertiesSerializer
|
|
4
|
-
include WithTemplate
|
|
5
|
-
|
|
4
|
+
class PropertiesSerializer < TemplatedSerializer
|
|
6
5
|
def initialize
|
|
7
|
-
|
|
6
|
+
super(sanitizer: Sanitizers::PassThroughSanitizer.new)
|
|
8
7
|
end
|
|
9
8
|
|
|
10
9
|
private
|
|
@@ -13,13 +12,12 @@ module AdLocalize
|
|
|
13
12
|
TEMPLATES_DIRECTORY + "/properties/template.properties.erb"
|
|
14
13
|
end
|
|
15
14
|
|
|
16
|
-
def
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
translations.map { |translation| @translation_mapper.map(translation: translation) }
|
|
15
|
+
def variable_binding(locale_wording:)
|
|
16
|
+
singulars = locale_wording.singulars.map do |_, translation|
|
|
17
|
+
map_simple_wording(translation: translation)
|
|
18
|
+
end
|
|
19
|
+
{ translations: singulars }
|
|
22
20
|
end
|
|
23
21
|
end
|
|
24
22
|
end
|
|
25
|
-
end
|
|
23
|
+
end
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module AdLocalize
|
|
2
3
|
module Serializers
|
|
3
|
-
class StringsSerializer
|
|
4
|
-
include WithTemplate
|
|
5
|
-
|
|
4
|
+
class StringsSerializer < TemplatedSerializer
|
|
6
5
|
def initialize
|
|
7
|
-
|
|
8
|
-
@translation_group_mapper = Mappers::TranslationGroupMapper.new(translation_mapper: @translation_mapper)
|
|
6
|
+
super(sanitizer: Sanitizers::IOSToAndroidSanitizer.new)
|
|
9
7
|
end
|
|
10
8
|
|
|
11
9
|
private
|
|
@@ -14,22 +12,15 @@ module AdLocalize
|
|
|
14
12
|
TEMPLATES_DIRECTORY + "/android/strings.xml.erb"
|
|
15
13
|
end
|
|
16
14
|
|
|
17
|
-
def
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
translations.select(&:has_value?).map { |translation| @translation_mapper.map(translation: translation) }
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def map_plurals(plurals:)
|
|
29
|
-
plurals
|
|
30
|
-
.map { |label, translations| @translation_group_mapper.map(label: label, translations: translations.select(&:has_value?)) }
|
|
31
|
-
.select(&:has_translations?)
|
|
15
|
+
def variable_binding(locale_wording:)
|
|
16
|
+
singulars = locale_wording.singulars.map do |_, translation|
|
|
17
|
+
map_simple_wording(translation: translation)
|
|
18
|
+
end
|
|
19
|
+
plurals = locale_wording.plurals.map do |label, translations|
|
|
20
|
+
map_compound_wording(label: label, translations: translations)
|
|
21
|
+
end
|
|
22
|
+
{ singulars: singulars, plurals: plurals }
|
|
32
23
|
end
|
|
33
24
|
end
|
|
34
25
|
end
|
|
35
|
-
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module AdLocalize
|
|
3
|
+
module Serializers
|
|
4
|
+
class TemplatedSerializer
|
|
5
|
+
def initialize(sanitizer:)
|
|
6
|
+
@sanitizer = sanitizer
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def render(locale_wording:)
|
|
10
|
+
variable_binding = variable_binding(locale_wording: locale_wording)
|
|
11
|
+
return unless variable_binding
|
|
12
|
+
|
|
13
|
+
render_template(template_path: template_path, variable_binding: variable_binding)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
protected
|
|
17
|
+
|
|
18
|
+
TEMPLATES_DIRECTORY = __dir__ + "/../templates"
|
|
19
|
+
|
|
20
|
+
def template_path
|
|
21
|
+
raise 'Override me!'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def variable_binding(locale_wording:)
|
|
25
|
+
raise 'override me!'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def map_simple_wording(translation:)
|
|
31
|
+
SimpleWordingViewModel.new(
|
|
32
|
+
label: translation.key.label,
|
|
33
|
+
value: @sanitizer.sanitize(value: translation.value),
|
|
34
|
+
comment: translation.comment,
|
|
35
|
+
variant_name: translation.key.variant_name
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def map_compound_wording(label:, translations:)
|
|
40
|
+
variants = translations.map { |_, translation| map_simple_wording(translation: translation) }
|
|
41
|
+
CompoundWordingViewModel.new(label: label, variants: variants)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def render_template(template_path:, variable_binding:)
|
|
45
|
+
template = File.read(template_path)
|
|
46
|
+
renderer = ERB.new(template, trim_mode: '-')
|
|
47
|
+
renderer.result_with_hash(variable_binding)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module AdLocalize
|
|
2
3
|
module Serializers
|
|
3
4
|
class YAMLSerializer
|
|
4
|
-
def initialize
|
|
5
|
-
@locale_wording_to_hash = Mappers::LocaleWordingToHash.new
|
|
6
|
-
end
|
|
7
|
-
|
|
8
5
|
def render(locale_wording:)
|
|
9
|
-
|
|
6
|
+
content = Mappers::LocaleWordingToHash.new.map(locale_wording: locale_wording)
|
|
7
|
+
content.to_yaml
|
|
10
8
|
end
|
|
11
9
|
end
|
|
12
10
|
end
|
|
13
|
-
end
|
|
11
|
+
end
|
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
<%- end -%>
|
|
7
7
|
<string name="<%= single_translation.label %>"><%= single_translation.value %></string>
|
|
8
8
|
<%- end -%>
|
|
9
|
-
<%- plurals.each do |
|
|
10
|
-
<plurals name="<%=
|
|
11
|
-
<%-
|
|
12
|
-
<%- if
|
|
13
|
-
<!-- <%=
|
|
9
|
+
<%- plurals.each do |plural_group| -%>
|
|
10
|
+
<plurals name="<%= plural_group.label %>">
|
|
11
|
+
<%- plural_group.variants.each do |variant| -%>
|
|
12
|
+
<%- if variant.comment -%>
|
|
13
|
+
<!-- <%= variant.comment %> -->
|
|
14
14
|
<%- end -%>
|
|
15
|
-
<item quantity="<%=
|
|
15
|
+
<item quantity="<%= variant.variant_name %>"><%= variant.value %></item>
|
|
16
16
|
<%- end -%>
|
|
17
17
|
</plurals>
|
|
18
18
|
<%- end -%>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<plist>
|
|
3
3
|
<dict>
|
|
4
|
-
<%- plurals.each do |
|
|
5
|
-
<key><%=
|
|
4
|
+
<%- plurals.each do |plural_group| -%>
|
|
5
|
+
<key><%= plural_group.label %></key>
|
|
6
6
|
<dict>
|
|
7
7
|
<key>NSStringLocalizedFormatKey</key>
|
|
8
8
|
<string>%#@key@</string>
|
|
@@ -12,27 +12,27 @@
|
|
|
12
12
|
<string>NSStringPluralRuleType</string>
|
|
13
13
|
<key>NSStringFormatValueTypeKey</key>
|
|
14
14
|
<string>d</string>
|
|
15
|
-
<%-
|
|
16
|
-
<%- if
|
|
17
|
-
<!-- <%=
|
|
15
|
+
<%- plural_group.variants.each do |variant| -%>
|
|
16
|
+
<%- if variant.comment -%>
|
|
17
|
+
<!-- <%= variant.comment %> -->
|
|
18
18
|
<%- end -%>
|
|
19
|
-
<key><%=
|
|
20
|
-
<string><%=
|
|
19
|
+
<key><%= variant.variant_name -%></key>
|
|
20
|
+
<string><%= variant.value -%></string>
|
|
21
21
|
<%- end -%>
|
|
22
22
|
</dict>
|
|
23
23
|
</dict>
|
|
24
24
|
<%- end -%>
|
|
25
|
-
<%- adaptives.each do |
|
|
26
|
-
<key><%=
|
|
25
|
+
<%- adaptives.each do |adaptive_group| -%>
|
|
26
|
+
<key><%= adaptive_group.label %></key>
|
|
27
27
|
<dict>
|
|
28
28
|
<key>NSStringVariableWidthRuleType</key>
|
|
29
29
|
<dict>
|
|
30
|
-
<%-
|
|
31
|
-
<%- if
|
|
32
|
-
<!-- <%=
|
|
30
|
+
<%- adaptive_group.variants.each do |variant| -%>
|
|
31
|
+
<%- if variant.comment -%>
|
|
32
|
+
<!-- <%= variant.comment %> -->
|
|
33
33
|
<%- end -%>
|
|
34
|
-
<key><%=
|
|
35
|
-
<string><%=
|
|
34
|
+
<key><%= variant.variant_name %></key>
|
|
35
|
+
<string><%= variant.value %></string>
|
|
36
36
|
<%- end -%>
|
|
37
37
|
</dict>
|
|
38
38
|
</dict>
|
data/lib/ad_localize/version.rb
CHANGED