loco_strings 0.1.5 → 0.1.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b08530cf06fde825bb19978db9b25c6dd2def7fed991f7e3cc7769d24efafd34
4
- data.tar.gz: 7fb65903ab8dcdcd5b20b6072ac6dc7934d994ff6353c857b144549a54a83953
3
+ metadata.gz: 45967a4d7a5f4a5ddc6d3fbeec661fcf7d9c096cade448616b7e096e3d41b3d5
4
+ data.tar.gz: e0f26ff5774aff74719a30811404f9834e26b3a96f0f800cb08a6a3f004a3f2b
5
5
  SHA512:
6
- metadata.gz: 7e3c576ffdca90cf4e046dfc0c5f977538ca34504637d7d8b691063206f7c12ecb2f5a330fd26bb39647625652585dc33013364abdda23bf4833464a33e2ddcd
7
- data.tar.gz: f49f067641e258367ebcc367121cc30b27feb062ea0fb42716f74c9d40ff622e1f1d397e4b3f308a6bfaf64a65ce53cccc27716126b4d1adf46fbc9f52b96d04
6
+ metadata.gz: '08dfd0d814825888c048dcc6ed25900b4dc2c5e85e82411a447c4d17b562ba99b57f98af8e0b18466a73cac316161ec06e6e0b8877fa9fcf9b24e1e257ef84e7'
7
+ data.tar.gz: 95c99ae564c6624e653efc459b7d75c974024912ca68df84acaf548836471752c42ada4e47e73a0e4ebebf19395f51b82ede7a1093381689849b8bf1ba0e42e8
@@ -5,7 +5,7 @@ require "json"
5
5
  module LocoStrings
6
6
  # The XCStringsDecoder class is responsible for decoding the XCStrings file format.
7
7
  class XCStringsDecoder
8
- attr_reader :language, :strings, :translations, :languages
8
+ attr_reader :language, :strings, :translations, :languages, :extraction_states
9
9
 
10
10
  def initialize(file_path)
11
11
  @file_path = file_path
@@ -13,6 +13,7 @@ module LocoStrings
13
13
  @translations = {}
14
14
  @languages = []
15
15
  @language = nil
16
+ @extraction_states = {}
16
17
  end
17
18
 
18
19
  def decode
@@ -44,12 +45,13 @@ module LocoStrings
44
45
  strings = json["strings"]
45
46
  strings.each do |key, value|
46
47
  translatable = value.fetch("shouldTranslate", true)
48
+ @extraction_states[key] = value["extractionState"] if value.key?("extractionState")
47
49
  val = decode_string(key, value, @language)
48
50
  @strings[key] = val if val
49
51
  @strings[key] = LocoString.new(key, key, value["comment"], "new") if val.nil?
50
52
  @strings[key].translatable = translatable
51
53
 
52
- decode_translations(key, value)
54
+ decode_translations(key, value, translatable)
53
55
  end
54
56
  end
55
57
 
@@ -98,9 +100,11 @@ module LocoStrings
98
100
  result
99
101
  end
100
102
 
101
- def decode_translations(key, value)
103
+ def decode_translations(key, value, translatable = true)
102
104
  @languages.each do |language|
103
105
  string = decode_string(key, value, language)
106
+ # Carry the shouldTranslate flag onto the per-language unit so it round-trips on encode.
107
+ string.translatable = translatable if string
104
108
  @translations[language] ||= {}
105
109
  @translations[language][key] = string
106
110
  end
@@ -7,11 +7,12 @@ module LocoStrings
7
7
  class XCStringsEncoder
8
8
  attr_reader :language, :strings, :translations, :languages
9
9
 
10
- def initialize(strings, translations, languages, language)
10
+ def initialize(strings, translations, languages, language, extraction_states = {})
11
11
  @strings = strings
12
12
  @translations = translations
13
13
  @languages = languages
14
14
  @language = language
15
+ @extraction_states = extraction_states || {}
15
16
  end
16
17
 
17
18
  def encode
@@ -43,7 +44,18 @@ module LocoStrings
43
44
  sorted_keys.each do |language|
44
45
  process_language(row, language, key)
45
46
  end
46
- row
47
+ # Bare keys (no per-language unit, e.g. compiler-extracted source-only keys) have nothing for
48
+ # add_translation_flag to read — fall back to the source-string flag so shouldTranslate persists.
49
+ row["shouldTranslate"] = false if !row.key?("shouldTranslate") && @strings[key]&.translatable == false
50
+ state = @extraction_states[key]
51
+ return row if state.nil?
52
+
53
+ # Keep Xcode's alphabetical field order: comment, extractionState, localizations, shouldTranslate.
54
+ ordered = {}
55
+ ordered["comment"] = row.delete("comment") if row.key?("comment")
56
+ ordered["extractionState"] = state
57
+ ordered.merge!(row)
58
+ ordered
47
59
  end
48
60
 
49
61
  def sorted_keys
@@ -19,13 +19,14 @@ module LocoStrings
19
19
  @strings = decoder.strings
20
20
  @translations = decoder.translations
21
21
  @languages = decoder.languages
22
+ @extraction_states = decoder.extraction_states
22
23
  @strings
23
24
  end
24
25
 
25
26
  def write
26
27
  raise Error, "The base language is not defined" if @language.nil?
27
28
 
28
- json = XCStringsEncoder.new(@strings, @translations, @languages, @language).encode
29
+ json = XCStringsEncoder.new(@strings, @translations, @languages, @language, @extraction_states || {}).encode
29
30
  File.write(@file_path, json)
30
31
  end
31
32
 
@@ -54,6 +55,11 @@ module LocoStrings
54
55
 
55
56
  def update_traslatability(key, translatable)
56
57
  @strings[key].translatable = translatable
58
+ # The encoder reads the flag from the per-language units, so set it there too.
59
+ @translations.each_value do |units|
60
+ unit = units[key]
61
+ unit.translatable = translatable if unit
62
+ end
57
63
  end
58
64
 
59
65
  def select_language(language)
@@ -99,6 +105,7 @@ module LocoStrings
99
105
  @translations = {}
100
106
  @languages = []
101
107
  @language = nil
108
+ @extraction_states = {}
102
109
  end
103
110
 
104
111
  private
@@ -118,7 +125,13 @@ module LocoStrings
118
125
  def make_variations(key, variant, value, comment = nil, state = nil, language = @language) # rubocop:disable Metrics/ParameterLists
119
126
  variants = @translations.dig(language, key)
120
127
 
121
- return make_strings(key, value, comment, state, language) if variants.is_a?(LocoString)
128
+ # Upgrade a plain (e.g. compiler-extracted) flat string into a plural variation set the first
129
+ # time a variant is written for it — carrying over its comment. Without this, writing a
130
+ # variation onto an extracted key would silently fall back to a flat string and drop the plural.
131
+ if variants.is_a?(LocoString)
132
+ state = "new" if state.nil?
133
+ return LocoVariantions.new(key, { variant => LocoString.new(variant, value, comment, state) }, variants.comment)
134
+ end
122
135
 
123
136
  if variants.nil?
124
137
  state = "new" if state.nil?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LocoStrings
4
- VERSION = "0.1.5"
4
+ VERSION = "0.1.9"
5
5
  end
data/lib/loco_strings.rb CHANGED
@@ -46,7 +46,7 @@ module LocoStrings
46
46
  if strings.key? key
47
47
  strings[key].update(value, comment, state, translatable)
48
48
  else
49
- strings[key] = LocoString.new(key, value, comment, state, nil, translatable)
49
+ strings[key] = LocoString.new(key, value, comment, state, translatable)
50
50
  end
51
51
  end
52
52
 
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: loco_strings
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aleksei Cherepanov
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2025-01-26 00:00:00.000000000 Z
10
+ date: 2026-06-07 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: nokogiri
@@ -69,7 +68,6 @@ metadata:
69
68
  homepage_uri: https://github.com/ftp27/loco_strings
70
69
  source_code_uri: https://github.com/ftp27/loco_strings
71
70
  rubygems_mfa_required: 'true'
72
- post_install_message:
73
71
  rdoc_options: []
74
72
  require_paths:
75
73
  - lib
@@ -84,8 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
82
  - !ruby/object:Gem::Version
85
83
  version: '0'
86
84
  requirements: []
87
- rubygems_version: 3.4.19
88
- signing_key:
85
+ rubygems_version: 3.6.2
89
86
  specification_version: 4
90
87
  summary: LocoStrings is a Ruby gem for working with iOS and Android localization strings.
91
88
  test_files: []