Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/twine.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgreshilov <slovaricheg@gmail.com>2018-03-30 20:53:03 +0300
committergreshilov <slovaricheg@gmail.com>2018-03-30 20:53:03 +0300
commit504f3548ac7b1523449029e52e238cdc1469ab84 (patch)
tree178d45be73690142b9a270c93aebb85d71c4519b
parent1813945b2d0d05a75acb328c8ffbe28b70d41aec (diff)
Add plural localizations
-rw-r--r--lib/twine.rb1
-rw-r--r--lib/twine/formatters/abstract.rb20
-rw-r--r--lib/twine/formatters/android.rb7
-rw-r--r--lib/twine/formatters/apple.rb4
-rw-r--r--lib/twine/formatters/apple_plural.rb68
-rw-r--r--lib/twine/output_processor.rb8
-rw-r--r--lib/twine/twine_file.rb35
7 files changed, 138 insertions, 5 deletions
diff --git a/lib/twine.rb b/lib/twine.rb
index ab02f79..c08499b 100644
--- a/lib/twine.rb
+++ b/lib/twine.rb
@@ -31,6 +31,7 @@ module Twine
require 'twine/formatters/abstract'
require 'twine/formatters/android'
require 'twine/formatters/apple'
+ require 'twine/formatters/apple_plural'
require 'twine/formatters/django'
require 'twine/formatters/flash'
require 'twine/formatters/gettext'
diff --git a/lib/twine/formatters/abstract.rb b/lib/twine/formatters/abstract.rb
index 4bd8c09..37c5f15 100644
--- a/lib/twine/formatters/abstract.rb
+++ b/lib/twine/formatters/abstract.rb
@@ -3,6 +3,7 @@ require 'fileutils'
module Twine
module Formatters
class Abstract
+ SUPPORTS_PLURAL = false
attr_accessor :twine_file
attr_accessor :options
@@ -132,7 +133,13 @@ module Twine
end
def format_definition(definition, lang)
- [format_comment(definition, lang), format_key_value(definition, lang)].compact.join
+ formatted_definition = [format_comment(definition, lang)]
+ if self.class::SUPPORTS_PLURAL && definition.is_plural?
+ formatted_definition << format_plural(definition, lang)
+ else
+ formatted_definition << format_key_value(definition, lang)
+ end
+ formatted_definition.compact.join
end
def format_comment(definition, lang)
@@ -143,10 +150,21 @@ module Twine
key_value_pattern % { key: format_key(definition.key.dup), value: format_value(value.dup) }
end
+ def format_plural(definition, lang)
+ plural_hash = definition.plural_translation_for_lang(lang)
+ if plural_hash
+ format_plural_keys(definition.key.dup, plural_hash)
+ end
+ end
+
def key_value_pattern
raise NotImplementedError.new("You must implement key_value_pattern in your formatter class.")
end
+ def format_plural_keys(key, plural_hash)
+ raise NotImplementedError.new("You must implement format_plural_keys in your formatter class.")
+ end
+
def format_key(key)
key
end
diff --git a/lib/twine/formatters/android.rb b/lib/twine/formatters/android.rb
index e8f0642..5ad23ab 100644
--- a/lib/twine/formatters/android.rb
+++ b/lib/twine/formatters/android.rb
@@ -7,6 +7,7 @@ module Twine
class Android < Abstract
include Twine::Placeholders
+ SUPPORTS_PLURAL = true
LANG_CODES = Hash[
'zh' => 'zh-Hans',
'zh-CN' => 'zh-Hans',
@@ -110,6 +111,12 @@ module Twine
"\t<string name=\"%{key}\">%{value}</string>"
end
+ def format_plural_keys(key, plural_hash)
+ result = "\t<plurals name=\"#{key}\">\n"
+ result += plural_hash.map{|quantity,value| "\t#{' ' * 2}<item quantity=\"#{quantity}\">#{value}</item>"}.join("\n")
+ result += "\n\t</plurals>"
+ end
+
def gsub_unless(text, pattern, replacement)
text.gsub(pattern) do |match|
match_start_position = Regexp.last_match.offset(0)[0]
diff --git a/lib/twine/formatters/apple.rb b/lib/twine/formatters/apple.rb
index 5233cb1..5a655df 100644
--- a/lib/twine/formatters/apple.rb
+++ b/lib/twine/formatters/apple.rb
@@ -86,6 +86,10 @@ module Twine
def format_value(value)
escape_quotes(value)
end
+
+ def should_include_definition(definition, lang)
+ return !definition.is_plural? && super
+ end
end
end
end
diff --git a/lib/twine/formatters/apple_plural.rb b/lib/twine/formatters/apple_plural.rb
new file mode 100644
index 0000000..c53f02b
--- /dev/null
+++ b/lib/twine/formatters/apple_plural.rb
@@ -0,0 +1,68 @@
+module Twine
+ module Formatters
+ class ApplePlural < Apple
+ SUPPORTS_PLURAL = true
+
+ def format_name
+ 'apple-plural'
+ end
+
+ def extension
+ '.stringsdict'
+ end
+
+ def default_file_name
+ 'Localizable.stringsdict'
+ end
+
+ def format_footer(lang)
+ footer = "</dict>\n</plist>"
+ end
+
+ def format_file(lang)
+ result = super
+ result += format_footer(lang)
+ end
+
+ def format_header(lang)
+ header = "<!--\n * Apple Stringsdict File\n * Generated by Twine #{Twine::VERSION}\n * Language: #{lang} -->\n"
+ header += "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>\n"
+ header += "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
+ header += "<plist version=\"1.0\">\n<dict>"
+ end
+
+ def format_section_header(section)
+ "<!-- ********** #{section.name} **********/ -->\n"
+ end
+
+ def format_plural_keys(key, plural_hash)
+ result = "#{tab(2)}<key>#{key}</key>\n"
+ result += "#{tab(2)}<dict>\n"
+ result += "#{tab(4)}<key>NSStringLocalizedFormatKey</key>\n#{tab(4)}<string>\%\#@value@</string>\n"
+ result += "#{tab(4)}<key>value</key>\n#{tab(4)}<dict>\n"
+ result += "#{tab(6)}<key>NSStringFormatSpecTypeKey</key>\n#{tab(6)}<string>NSStringPluralRuleType</string>\n"
+ result += "#{tab(6)}<key>NSStringFormatValueTypeKey</key>\n#{tab(6)}<string>d</string>\n"
+ result += plural_hash.map{|quantity,value| "#{tab(6)}<key>#{quantity}</key>\n#{tab(6)}<string>#{value}</string>"}.join("\n")
+ result += "\n#{tab(4)}</dict>\n#{tab(2)}</dict>\n"
+ end
+
+ def format_comment(definition, lang)
+ "<!-- #{definition.comment.gsub('--', '—')} -->\n" if definition.comment
+ end
+
+ def read(io, lang)
+ raise NotImplementedError.new("Reading \".stringdict\" files not implemented yet")
+ end
+
+ def tab(level)
+ ' ' * level
+ end
+
+ def should_include_definition(definition, lang)
+ return definition.is_plural? && definition.plural_translation_for_lang(lang)
+ end
+ end
+ end
+end
+
+Twine::Formatters.formatters << Twine::Formatters::ApplePlural.new
diff --git a/lib/twine/output_processor.rb b/lib/twine/output_processor.rb
index 8924ad1..9d96d4c 100644
--- a/lib/twine/output_processor.rb
+++ b/lib/twine/output_processor.rb
@@ -42,6 +42,14 @@ module Twine
new_definition = definition.dup
new_definition.translations[language] = value
+ if definition.is_plural?
+ # If definition is plural, but no translation found -> create
+ # Then check 'other' key
+ if !(new_definition.plural_translations[language] ||= {}).key? 'other'
+ new_definition.plural_translations[language]['other'] = value
+ end
+ end
+
new_section.definitions << new_definition
result.definitions_by_key[new_definition.key] = new_definition
end
diff --git a/lib/twine/twine_file.rb b/lib/twine/twine_file.rb
index b000180..4ffca5e 100644
--- a/lib/twine/twine_file.rb
+++ b/lib/twine/twine_file.rb
@@ -1,9 +1,13 @@
module Twine
class TwineDefinition
+ PLURAL_KEYS = %w(zero one two few many other)
+
attr_reader :key
attr_accessor :comment
attr_accessor :tags
attr_reader :translations
+ attr_reader :plural_translations
+ attr_reader :is_plural
attr_accessor :reference
attr_accessor :reference_key
@@ -12,6 +16,7 @@ module Twine
@comment = nil
@tags = nil
@translations = {}
+ @plural_translations = {}
end
def comment
@@ -50,6 +55,16 @@ module Twine
return translation
end
+
+ def plural_translation_for_lang(lang)
+ if @plural_translations.has_key? lang
+ @plural_translations[lang].dup
+ end
+ end
+
+ def is_plural?
+ !@plural_translations.empty?
+ end
end
class TwineSection
@@ -137,11 +152,12 @@ module Twine
parsed = true
end
else
- match = /^([^=]+)=(.*)$/.match(line)
+ match = /^([^:=]+)(?::([^=]+))?=(.*)$/.match(line)
if match
key = match[1].strip
- value = match[2].strip
-
+ plural_key = match[2].to_s.strip
+ value = match[3].strip
+
value = value[1..-2] if value[0] == '`' && value[-1] == '`'
case key
@@ -155,7 +171,18 @@ module Twine
if !@language_codes.include? key
add_language_code(key)
end
- current_definition.translations[key] = value
+ # Providing backward compatibility
+ # for formatters without plural support
+ if plural_key.empty? || plural_key == 'other'
+ current_definition.translations[key] = value
+ end
+ if !plural_key.empty?
+ if !TwineDefinition::PLURAL_KEYS.include? plural_key
+ warn("Unknown plural key #{plural_key}")
+ next
+ end
+ (current_definition.plural_translations[key] ||= {})[plural_key] = value
+ end
end
parsed = true
end