From bcb6dd928e2d9b10e21f188000e1f5078a6aa696 Mon Sep 17 00:00:00 2001 From: Sebastian Ludwig Date: Sat, 28 Nov 2015 13:31:39 +0100 Subject: [PATCH 1/9] Added unit tests for Django and Flash formatters. --- lib/twine/formatters/flash.rb | 2 +- test/fixtures/formatter_django.po | 27 ++++++++++++++++ test/fixtures/formatter_flash.properties | 14 +++++++++ test/test_formatters.rb | 40 ++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/formatter_django.po create mode 100644 test/fixtures/formatter_flash.properties diff --git a/lib/twine/formatters/flash.rb b/lib/twine/formatters/flash.rb index e36c403..7a96506 100644 --- a/lib/twine/formatters/flash.rb +++ b/lib/twine/formatters/flash.rb @@ -51,7 +51,7 @@ module Twine match = /((?:[^"\\]|\\.)+)\s*=\s*((?:[^"\\]|\\.)*)/.match(line) if match key = match[1] - value = match[2] + value = match[2].strip value.gsub!(/\{[0-9]\}/, '%@') set_translation_for_key(key, lang, value) if last_comment diff --git a/test/fixtures/formatter_django.po b/test/fixtures/formatter_django.po new file mode 100644 index 0000000..81569ed --- /dev/null +++ b/test/fixtures/formatter_django.po @@ -0,0 +1,27 @@ +## + # Django Strings File + # Generated by Twine 0.7.0 + # Language: en + + +#--------- Section 1 ---------# + +#. comment key1 +# base translation: "value1-english" +msgid "key1" +msgstr "value1-english" + +# base translation: "value2-english" +msgid "key2" +msgstr "value2-english" + +#--------- Section 2 ---------# + +# base translation: "value3-english" +msgid "key3" +msgstr "value3-english" + +#. comment key4 +# base translation: "value4-english" +msgid "key4" +msgstr "value4-english" diff --git a/test/fixtures/formatter_flash.properties b/test/fixtures/formatter_flash.properties new file mode 100644 index 0000000..d48ec52 --- /dev/null +++ b/test/fixtures/formatter_flash.properties @@ -0,0 +1,14 @@ +## Flash Strings File +## Generated by Twine 0.7.0 +## Language: en + +## Section 1 ## + +# comment key1 +key1=value1-english +key2=value2-english +## Section 2 ## + +key3=value3-english +# comment key4 +key4=value4-english \ No newline at end of file diff --git a/test/test_formatters.rb b/test/test_formatters.rb index efd6bd7..6727329 100644 --- a/test/test_formatters.rb +++ b/test/test_formatters.rb @@ -200,3 +200,43 @@ class TestTizenFormatter < FormatterTest end end + +class TestDjangoFormatter < FormatterTest + def setup + super Twine::Formatters::Django + end + + def test_read_file_format + @formatter.read_file fixture('formatter_django.po'), 'en' + + 1.upto(4) do |i| + assert_equal "value#{i}-english", @strings.strings_map["key#{i}"].translations['en'] + end + end + + def test_write_file_output_format + formatter = Twine::Formatters::Django.new @twine_file, {} + formatter.write_file @output_path, 'en' + assert_equal content('formatter_django.po'), output_content + end +end + +class TestFlashFormatter < FormatterTest + def setup + super Twine::Formatters::Flash + end + + def test_read_file_format + @formatter.read_file fixture('formatter_flash.properties'), 'en' + + 1.upto(4) do |i| + assert_equal "value#{i}-english", @strings.strings_map["key#{i}"].translations['en'] + end + end + + def test_write_file_output_format + formatter = Twine::Formatters::Flash.new @twine_file, {} + formatter.write_file @output_path, 'en' + assert_equal content('formatter_flash.properties'), output_content + end +end From 84cf07d3534f27a9fb0c43dc812e8adaa6de172a Mon Sep 17 00:00:00 2001 From: Sebastian Ludwig Date: Sat, 28 Nov 2015 14:08:19 +0100 Subject: [PATCH 2/9] Adapted Django formatter to the modular style. --- lib/twine/formatters/django.rb | 82 +++++++++++++++---------------- test/fixtures/formatter_django.po | 7 +-- 2 files changed, 45 insertions(+), 44 deletions(-) diff --git a/lib/twine/formatters/django.rb b/lib/twine/formatters/django.rb index 981f4d7..1fbf8b8 100644 --- a/lib/twine/formatters/django.rb +++ b/lib/twine/formatters/django.rb @@ -90,53 +90,53 @@ module Twine end end - def write_file(path, lang) - default_lang = @strings.language_codes[0] - encoding = @options[:output_encoding] || 'UTF-8' - File.open(path, "w:#{encoding}") do |f| - f.puts "##\n # Django Strings File\n # Generated by Twine #{Twine::VERSION}\n # Language: #{lang}\n " - @strings.sections.each do |section| - printed_section = false - section.rows.each do |row| - if row.matches_tags?(@options[:tags], @options[:untagged]) - f.puts '' - if !printed_section - if section.name && section.name.length > 0 - f.print "#--------- #{section.name} ---------#\n\n" - end - printed_section = true - end - - basetrans = row.translated_string_for_lang(default_lang) + def format_file(strings, lang) + @default_lang = strings.language_codes[0] + super + end - key = row.key - key = key.gsub('"', '\\\\"') + def format_header(lang) + "##\n # Django Strings File\n # Generated by Twine #{Twine::VERSION}\n # Language: #{lang}\n" + end - value = row.translated_string_for_lang(lang, default_lang) - if value - value = value.gsub('"', '\\\\"') + def format_section_header(section) + "#--------- #{section.name} ---------#\n" + end - comment = row.comment + def format_row(row, lang) + value = row.translated_string_for_lang(lang) - if comment - comment = comment.gsub('"', '\\\\"') - end + return nil unless value - if comment && comment.length > 0 - f.print "#. #{comment} \n" - end - - if basetrans && basetrans.length > 0 - f.print "# base translation: \"#{basetrans}\"\n" - end - - f.print "msgid \"#{key}\"\n" - f.print "msgstr \"#{value}\"\n" - end - end - end - end + result = "" + if row.comment + comment = format_comment(row.comment) + result += comment + "\n" if comment end + + result += "# base translation: \"#{row.translations[@default_lang]}\"\n" + result += key_value_pattern % { key: format_key(row.key.dup), value: format_value(value.dup) } + end + + def key_value_pattern + "msgid \"%{key}\"\n" + + "msgstr \"%{value}\"\n" + end + + def format_comment(comment) + "#. #{escape_quotes(comment)}" + end + + def format_key(key) + escape_quotes(key) + end + + def format_value(value) + escape_quotes(value) + end + + def escape_quotes(text) + text.gsub('"', '\\\\"') end end end diff --git a/test/fixtures/formatter_django.po b/test/fixtures/formatter_django.po index 81569ed..895f0bb 100644 --- a/test/fixtures/formatter_django.po +++ b/test/fixtures/formatter_django.po @@ -2,11 +2,11 @@ # Django Strings File # Generated by Twine 0.7.0 # Language: en - + #--------- Section 1 ---------# -#. comment key1 +#. comment key1 # base translation: "value1-english" msgid "key1" msgstr "value1-english" @@ -15,13 +15,14 @@ msgstr "value1-english" msgid "key2" msgstr "value2-english" + #--------- Section 2 ---------# # base translation: "value3-english" msgid "key3" msgstr "value3-english" -#. comment key4 +#. comment key4 # base translation: "value4-english" msgid "key4" msgstr "value4-english" From a35107ea99246265970549d7aed88b348ec283e3 Mon Sep 17 00:00:00 2001 From: Sebastian Ludwig Date: Sat, 28 Nov 2015 14:14:16 +0100 Subject: [PATCH 3/9] Adapted Flash formatter to the modular style. --- lib/twine/formatters/flash.rb | 49 ++++++++---------------- test/fixtures/formatter_flash.properties | 3 +- 2 files changed, 19 insertions(+), 33 deletions(-) diff --git a/lib/twine/formatters/flash.rb b/lib/twine/formatters/flash.rb index 7a96506..cb770c0 100644 --- a/lib/twine/formatters/flash.rb +++ b/lib/twine/formatters/flash.rb @@ -70,40 +70,25 @@ module Twine end end - def write_file(path, lang) - default_lang = @strings.language_codes[0] - encoding = @options[:output_encoding] || 'UTF-8' - File.open(path, "w:#{encoding}") do |f| - f.puts "## Flash Strings File\n## Generated by Twine #{Twine::VERSION}\n## Language: #{lang}\n" - @strings.sections.each do |section| - printed_section = false - section.rows.each do |row| - if row.matches_tags?(@options[:tags], @options[:untagged]) - f.puts '' - if !printed_section - if section.name && section.name.length > 0 - f.print "## #{section.name} ##\n\n" - end - printed_section = true - end + def format_header(lang) + "## Flash Strings File\n## Generated by Twine #{Twine::VERSION}\n## Language: #{lang}" + end - key = row.key - value = row.translated_string_for_lang(lang, default_lang) - if value - placeHolderNumber = -1 - value = value.gsub(/%[d@]/) { placeHolderNumber += 1; '{%d}' % placeHolderNumber } - - comment = row.comment - if comment && comment.length > 0 - f.print "# #{comment}\n" - end + def format_section_header(section) + "## #{section.name} ##\n" + end - f.print "#{key}=#{value}" - end - end - end - end - end + def format_comment(comment) + "# #{comment}" + end + + def key_value_pattern + "%{key}=%{value}" + end + + def format_value(value) + placeHolderNumber = -1 + value.gsub(/%[d@]/) { placeHolderNumber += 1; '{%d}' % placeHolderNumber } end end end diff --git a/test/fixtures/formatter_flash.properties b/test/fixtures/formatter_flash.properties index d48ec52..a623196 100644 --- a/test/fixtures/formatter_flash.properties +++ b/test/fixtures/formatter_flash.properties @@ -7,8 +7,9 @@ # comment key1 key1=value1-english key2=value2-english + ## Section 2 ## key3=value3-english # comment key4 -key4=value4-english \ No newline at end of file +key4=value4-english From a7ac82aab7857dc0aa3c437e3e3c1146af93405e Mon Sep 17 00:00:00 2001 From: Sebastian Ludwig Date: Sat, 28 Nov 2015 14:37:20 +0100 Subject: [PATCH 4/9] Adapted Gettext formatter to the modular style. --- lib/twine/formatters/gettext.rb | 69 ++++++++++++++---------------- test/fixtures/formatter_gettext.po | 1 - 2 files changed, 31 insertions(+), 39 deletions(-) diff --git a/lib/twine/formatters/gettext.rb b/lib/twine/formatters/gettext.rb index d76c4c3..afdc52a 100644 --- a/lib/twine/formatters/gettext.rb +++ b/lib/twine/formatters/gettext.rb @@ -60,50 +60,43 @@ module Twine end end - def write_file(path, lang) - default_lang = @strings.language_codes[0] - encoding = @options[:output_encoding] || 'UTF-8' - File.open(path, "w:#{encoding}") do |f| - f.puts "msgid \"\"\nmsgstr \"\"\n\"Language: #{lang}\\n\"\n\"X-Generator: Twine #{Twine::VERSION}\\n\"\n\n" - @strings.sections.each do |section| - printed_section = false - section.rows.each do |row| - if row.matches_tags?(@options[:tags], @options[:untagged]) - if !printed_section - f.puts '' - if section.name && section.name.length > 0 - section_name = section.name.gsub('--', '—') - f.puts "# SECTION: #{section_name}" - end - printed_section = true - end + def format_file(strings, lang) + @default_lang = strings.language_codes[0] + super + end - basetrans = row.translated_string_for_lang(default_lang) + def format_header(lang) + "msgid \"\"\nmsgstr \"\"\n\"Language: #{lang}\\n\"\n\"X-Generator: Twine #{Twine::VERSION}\\n\"\n" + end - if basetrans - key = row.key - key = key.gsub('"', '\\\\"') + def format_section_header(section) + "# SECTION: #{section.name}" + end - comment = row.comment - if comment - comment = comment.gsub('"', '\\\\"') - end + def format_row(row, lang) + return nil unless row.translated_string_for_lang(@default_lang) - if comment && comment.length > 0 - f.print "#. \"#{comment}\"\n" - end + value = row.translated_string_for_lang(lang) - f.print "msgctxt \"#{key}\"\nmsgid \"#{basetrans}\"\n" - value = row.translated_string_for_lang(lang) - if value - value = value.gsub('"', '\\\\"') - end - f.print "msgstr \"#{value}\"\n\n" - end - end - end - end + return nil unless value + + result = "" + if row.comment + comment = format_comment(row.comment) + result += comment + "\n" if comment end + + result += "msgctxt \"#{format_key(row.key.dup)}\"\n" + result += "msgid \"#{format_value(row.translations[@default_lang])}\"\n" + result += "msgstr \"#{format_value(value)}\"\n" + end + + def format_comment(comment) + "#. \"#{escape_quotes(comment)}\"" + end + + def escape_quotes(text) + text.gsub('"', '\\\\"') end end end diff --git a/test/fixtures/formatter_gettext.po b/test/fixtures/formatter_gettext.po index b89adc0..c2bda5c 100644 --- a/test/fixtures/formatter_gettext.po +++ b/test/fixtures/formatter_gettext.po @@ -24,4 +24,3 @@ msgstr "value3-english" msgctxt "key4" msgid "value4-english" msgstr "value4-english" - From f8d1df554d855595b2b09eea081d090eef2140c5 Mon Sep 17 00:00:00 2001 From: Sebastian Ludwig Date: Sat, 28 Nov 2015 14:52:15 +0100 Subject: [PATCH 5/9] Adapted JQuery formatter to the modular style. --- lib/twine/formatters/jquery.rb | 75 ++++++++++++++++------------- test/fixtures/formatter_jquery.json | 1 + 2 files changed, 42 insertions(+), 34 deletions(-) diff --git a/lib/twine/formatters/jquery.rb b/lib/twine/formatters/jquery.rb index cf6ab0a..8dba548 100644 --- a/lib/twine/formatters/jquery.rb +++ b/lib/twine/formatters/jquery.rb @@ -45,46 +45,53 @@ module Twine end end + def format_file(strings, lang) + "{\n#{super}\n}" + end + + def format_header(lang) + "" + end + + def format_sections(strings, lang) + sections = strings.sections.map { |section| format_section(section, lang) } + sections.join(",\n\n") + end + + def format_section_header(section) + end + + def format_section(section, lang) + rows = section.rows.dup + + rows.map! { |row| format_row(row, lang) } + rows.compact! # remove nil entries + rows.join(",\n") + end + + def key_value_pattern + "\"%{key}\":\"%{value}\"" + end + + def format_key(key) + escape_quotes(key) # TODO: solve this better + end + + def format_value(value) + escape_quotes(value) + end + + def escape_quotes(text) + text.gsub('"', '\\\\"') + end + def write_file(path, lang) begin require "json" rescue LoadError raise Twine::Error.new "You must run 'gem install json' in order to read or write jquery-localize files." end - - printed_string = false - default_lang = @strings.language_codes[0] - encoding = @options[:output_encoding] || 'UTF-8' - File.open(path, "w:#{encoding}") do |f| - f.print "{" - - @strings.sections.each_with_index do |section, si| - printed_section = false - section.rows.each_with_index do |row, ri| - if row.matches_tags?(@options[:tags], @options[:untagged]) - if printed_string - f.print ",\n" - end - - if !printed_section - f.print "\n" - printed_section = true - end - - key = row.key - key = key.gsub('"', '\\\\"') - - value = row.translated_string_for_lang(lang, default_lang) - value = value.gsub('"', '\\\\"') - - f.print "\"#{key}\":\"#{value}\"" - printed_string = true - end - end - end - f.puts "\n}" - - end + super end end end diff --git a/test/fixtures/formatter_jquery.json b/test/fixtures/formatter_jquery.json index b13cf0d..465e9f8 100644 --- a/test/fixtures/formatter_jquery.json +++ b/test/fixtures/formatter_jquery.json @@ -1,4 +1,5 @@ { + "key1":"value1-english", "key2":"value2-english", From 1d99549849bea52228ed11ec603d1227d29b00fe Mon Sep 17 00:00:00 2001 From: Sebastian Ludwig Date: Sat, 28 Nov 2015 14:59:51 +0100 Subject: [PATCH 6/9] Adapted Tizen formatter to the modular style. --- lib/twine/formatters/tizen.rb | 84 ++++++++++++++--------------------- 1 file changed, 33 insertions(+), 51 deletions(-) diff --git a/lib/twine/formatters/tizen.rb b/lib/twine/formatters/tizen.rb index d020c77..ef559fb 100644 --- a/lib/twine/formatters/tizen.rb +++ b/lib/twine/formatters/tizen.rb @@ -111,64 +111,46 @@ module Twine end end - def write_file(path, lang) - default_lang = nil - if DEFAULT_LANG_CODES.has_key?(lang) - default_lang = DEFAULT_LANG_CODES[lang] - end - File.open(path, 'w:UTF-8') do |f| - f.puts "\n\n\n" - f.write '' - @strings.sections.each do |section| - printed_section = false - section.rows.each do |row| - if row.matches_tags?(@options[:tags], @options[:untagged]) - if !printed_section - f.puts '' - if section.name && section.name.length > 0 - section_name = section.name.gsub('--', '—') - f.puts "\t" - end - printed_section = true - end + def format_header(lang) + "\n\n\n" + end - key = row.key + def format_sections(strings, lang) + result = '' + + result += super + "\n" - value = row.translated_string_for_lang(lang, default_lang) - if !value && !@options[:exclude_untranslated] - value = row.translated_string_for_lang(@strings.language_codes[0]) - end + result += '' + end - if value # if values is nil, there was no appropriate translation, so let Tizen handle the defaulting - value = String.new(value) # use a copy to prevent modifying the original + def format_section_header(section) + "\t" + end - # Tizen enforces the following rules on the values - # 1) apostrophes and quotes must be escaped with a backslash - value.gsub!('\'', '\\\\\'') - value.gsub!('"', '\\\\"') - # 2) HTML escape the string - value = CGI.escapeHTML(value) - # 3) fix substitutions (e.g. %s/%@) - value = androidify_substitutions(value) - # 4) replace beginning and end spaces with \0020. Otherwise Tizen strips them. - value.gsub!(/\A *| *\z/) { |spaces| '\u0020' * spaces.length } + def format_comment(comment) + "\t" + end - comment = row.comment - if comment - comment = comment.gsub('--', '—') - end + def key_value_pattern + "\t%{value}" + end - if comment && comment.length > 0 - f.puts "\t\n" - end - f.puts "\t#{value}" - end - end - end - end + def format_key(key) + key.upcase + end - f.puts '' - end + def format_value(value) + value = value.dup + # Tizen enforces the following rules on the values + # 1) apostrophes and quotes must be escaped with a backslash + value.gsub!("'", "\\\\'") + value.gsub!('"', '\\\\"') + # 2) HTML escape the string + value = CGI.escapeHTML(value) + # 3) fix substitutions (e.g. %s/%@) + value = androidify_substitutions(value) + # 4) replace beginning and end spaces with \0020. Otherwise Tizen strips them. + value.gsub(/\A *| *\z/) { |spaces| '\u0020' * spaces.length } end end end From 7691068e05f805e900ace175b42fa9a1b46cbfd9 Mon Sep 17 00:00:00 2001 From: Sebastian Ludwig Date: Sat, 28 Nov 2015 15:02:26 +0100 Subject: [PATCH 7/9] Changed header formatting to be optional for formatters. --- lib/twine/formatters/abstract.rb | 5 +++-- lib/twine/formatters/jquery.rb | 4 ---- test/fixtures/formatter_jquery.json | 1 - 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/twine/formatters/abstract.rb b/lib/twine/formatters/abstract.rb index 30f9ab7..bf888a2 100644 --- a/lib/twine/formatters/abstract.rb +++ b/lib/twine/formatters/abstract.rb @@ -132,12 +132,13 @@ module Twine end def format_file(strings, lang) - result = format_header(lang) + "\n" + header = format_header(lang) + result = "" + result += header + "\n" if header result += format_sections(strings, lang) end def format_header(lang) - raise NotImplementedError.new("You must implement format_header in your formatter class.") end def format_sections(strings, lang) diff --git a/lib/twine/formatters/jquery.rb b/lib/twine/formatters/jquery.rb index 8dba548..6ac2f36 100644 --- a/lib/twine/formatters/jquery.rb +++ b/lib/twine/formatters/jquery.rb @@ -49,10 +49,6 @@ module Twine "{\n#{super}\n}" end - def format_header(lang) - "" - end - def format_sections(strings, lang) sections = strings.sections.map { |section| format_section(section, lang) } sections.join(",\n\n") diff --git a/test/fixtures/formatter_jquery.json b/test/fixtures/formatter_jquery.json index 465e9f8..b13cf0d 100644 --- a/test/fixtures/formatter_jquery.json +++ b/test/fixtures/formatter_jquery.json @@ -1,5 +1,4 @@ { - "key1":"value1-english", "key2":"value2-english", From d690adb322ca88b290340cf1df52e67cf7e7bdf4 Mon Sep 17 00:00:00 2001 From: Sebastian Ludwig Date: Sat, 28 Nov 2015 15:07:32 +0100 Subject: [PATCH 8/9] Centralized escape_quotes helper method in Abstract formatter. --- lib/twine/formatters/abstract.rb | 4 ++++ lib/twine/formatters/android.rb | 3 +-- lib/twine/formatters/apple.rb | 5 ----- lib/twine/formatters/django.rb | 4 ---- lib/twine/formatters/gettext.rb | 4 ---- lib/twine/formatters/jquery.rb | 6 +----- lib/twine/formatters/tizen.rb | 3 +-- 7 files changed, 7 insertions(+), 22 deletions(-) diff --git a/lib/twine/formatters/abstract.rb b/lib/twine/formatters/abstract.rb index bf888a2..a0ed5e9 100644 --- a/lib/twine/formatters/abstract.rb +++ b/lib/twine/formatters/abstract.rb @@ -195,6 +195,10 @@ module Twine value end + def escape_quotes(text) + text.gsub('"', '\\\\"') + end + def write_file(path, lang) encoding = @options[:output_encoding] || 'UTF-8' diff --git a/lib/twine/formatters/android.rb b/lib/twine/formatters/android.rb index e4212c3..e992231 100644 --- a/lib/twine/formatters/android.rb +++ b/lib/twine/formatters/android.rb @@ -114,11 +114,10 @@ module Twine end def format_value(value) - value = value.dup # Android enforces the following rules on the values # 1) apostrophes and quotes must be escaped with a backslash + value = escape_quotes(value) value.gsub!("'", "\\\\'") - value.gsub!('"', '\\\\"') # 2) HTML escape the string value = CGI.escapeHTML(value) # 3) fix substitutions (e.g. %s/%@) diff --git a/lib/twine/formatters/apple.rb b/lib/twine/formatters/apple.rb index 87fb1f4..64d480e 100644 --- a/lib/twine/formatters/apple.rb +++ b/lib/twine/formatters/apple.rb @@ -109,11 +109,6 @@ module Twine def format_value(value) escape_quotes(value) end - - def escape_quotes(text) - text.gsub('"', '\\\\"') - end - end end end diff --git a/lib/twine/formatters/django.rb b/lib/twine/formatters/django.rb index 1fbf8b8..69e13e1 100644 --- a/lib/twine/formatters/django.rb +++ b/lib/twine/formatters/django.rb @@ -134,10 +134,6 @@ module Twine def format_value(value) escape_quotes(value) end - - def escape_quotes(text) - text.gsub('"', '\\\\"') - end end end end diff --git a/lib/twine/formatters/gettext.rb b/lib/twine/formatters/gettext.rb index afdc52a..27f1a09 100644 --- a/lib/twine/formatters/gettext.rb +++ b/lib/twine/formatters/gettext.rb @@ -94,10 +94,6 @@ module Twine def format_comment(comment) "#. \"#{escape_quotes(comment)}\"" end - - def escape_quotes(text) - text.gsub('"', '\\\\"') - end end end end diff --git a/lib/twine/formatters/jquery.rb b/lib/twine/formatters/jquery.rb index 6ac2f36..4988816 100644 --- a/lib/twine/formatters/jquery.rb +++ b/lib/twine/formatters/jquery.rb @@ -70,17 +70,13 @@ module Twine end def format_key(key) - escape_quotes(key) # TODO: solve this better + escape_quotes(key) end def format_value(value) escape_quotes(value) end - def escape_quotes(text) - text.gsub('"', '\\\\"') - end - def write_file(path, lang) begin require "json" diff --git a/lib/twine/formatters/tizen.rb b/lib/twine/formatters/tizen.rb index ef559fb..082f8ed 100644 --- a/lib/twine/formatters/tizen.rb +++ b/lib/twine/formatters/tizen.rb @@ -140,11 +140,10 @@ module Twine end def format_value(value) - value = value.dup + value = escape_quotes(value) # Tizen enforces the following rules on the values # 1) apostrophes and quotes must be escaped with a backslash value.gsub!("'", "\\\\'") - value.gsub!('"', '\\\\"') # 2) HTML escape the string value = CGI.escapeHTML(value) # 3) fix substitutions (e.g. %s/%@) From 25264bcf122a15be257d8394050a7f56d63c17af Mon Sep 17 00:00:00 2001 From: Sebastian Ludwig Date: Sat, 28 Nov 2015 15:52:17 +0100 Subject: [PATCH 9/9] Further modularized Abstract formatter so it's easier to meed special requirements like in the Django and Gettext formatters. --- lib/twine/formatters/abstract.rb | 29 +++++++++++++++------------ lib/twine/formatters/android.rb | 4 ++-- lib/twine/formatters/apple.rb | 4 ++-- lib/twine/formatters/django.rb | 22 ++++++++------------- lib/twine/formatters/flash.rb | 4 ++-- lib/twine/formatters/gettext.rb | 34 ++++++++++++++++++-------------- lib/twine/formatters/tizen.rb | 4 ++-- 7 files changed, 51 insertions(+), 50 deletions(-) diff --git a/lib/twine/formatters/abstract.rb b/lib/twine/formatters/abstract.rb index a0ed5e9..8e4e657 100644 --- a/lib/twine/formatters/abstract.rb +++ b/lib/twine/formatters/abstract.rb @@ -166,21 +166,24 @@ module Twine result += rows.join end - def format_row(row, lang) - value = row.translated_string_for_lang(lang) - - return nil unless value - - result = "" - if row.comment - comment = format_comment(row.comment) - result += comment + "\n" if comment - end - - result += key_value_pattern % { key: format_key(row.key.dup), value: format_value(value.dup) } + def row_pattern + "%{comment}%{key_value}" end - def format_comment(comment) + def format_row(row, lang) + return nil unless row.translated_string_for_lang(lang) + + result = row_pattern.scan(/%\{([a-z_]+)\}/).flatten + result.map! { |element| send("format_#{element}".to_sym, row, lang) } + result.flatten.join + end + + def format_comment(row, lang) + end + + def format_key_value(row, lang) + value = row.translated_string_for_lang(lang) + key_value_pattern % { key: format_key(row.key.dup), value: format_value(value.dup) } end def key_value_pattern diff --git a/lib/twine/formatters/android.rb b/lib/twine/formatters/android.rb index e992231..ff32e7f 100644 --- a/lib/twine/formatters/android.rb +++ b/lib/twine/formatters/android.rb @@ -105,8 +105,8 @@ module Twine "\t" end - def format_comment(comment) - "\t" + def format_comment(row, lang) + "\t\n" if row.comment end def key_value_pattern diff --git a/lib/twine/formatters/apple.rb b/lib/twine/formatters/apple.rb index 64d480e..9810a9f 100644 --- a/lib/twine/formatters/apple.rb +++ b/lib/twine/formatters/apple.rb @@ -98,8 +98,8 @@ module Twine "\"%{key}\" = \"%{value}\";\n" end - def format_comment(comment) - "/* #{comment.gsub('*/', '* /')} */" + def format_comment(row, lang) + "/* #{row.comment.gsub('*/', '* /')} */\n" if row.comment end def format_key(key) diff --git a/lib/twine/formatters/django.rb b/lib/twine/formatters/django.rb index 69e13e1..cbadf73 100644 --- a/lib/twine/formatters/django.rb +++ b/lib/twine/formatters/django.rb @@ -103,19 +103,13 @@ module Twine "#--------- #{section.name} ---------#\n" end - def format_row(row, lang) - value = row.translated_string_for_lang(lang) + def row_pattern + "%{comment}%{base_translation}%{key_value}" + end - return nil unless value - - result = "" - if row.comment - comment = format_comment(row.comment) - result += comment + "\n" if comment - end - - result += "# base translation: \"#{row.translations[@default_lang]}\"\n" - result += key_value_pattern % { key: format_key(row.key.dup), value: format_value(value.dup) } + def format_base_translation(row, lang) + base_translation = row.translations[@default_lang] + "# base translation: \"#{base_translation}\"\n" if base_translation end def key_value_pattern @@ -123,8 +117,8 @@ module Twine "msgstr \"%{value}\"\n" end - def format_comment(comment) - "#. #{escape_quotes(comment)}" + def format_comment(row, lang) + "#. #{escape_quotes(row.comment)}\n" if row.comment end def format_key(key) diff --git a/lib/twine/formatters/flash.rb b/lib/twine/formatters/flash.rb index cb770c0..9b62314 100644 --- a/lib/twine/formatters/flash.rb +++ b/lib/twine/formatters/flash.rb @@ -78,8 +78,8 @@ module Twine "## #{section.name} ##\n" end - def format_comment(comment) - "# #{comment}" + def format_comment(row, lang) + "# #{row.comment}\n" if row.comment end def key_value_pattern diff --git a/lib/twine/formatters/gettext.rb b/lib/twine/formatters/gettext.rb index 27f1a09..0ac4f5a 100644 --- a/lib/twine/formatters/gettext.rb +++ b/lib/twine/formatters/gettext.rb @@ -73,26 +73,30 @@ module Twine "# SECTION: #{section.name}" end + def row_pattern + "%{comment}%{key}%{base_translation}%{value}" + end + def format_row(row, lang) return nil unless row.translated_string_for_lang(@default_lang) - value = row.translated_string_for_lang(lang) - - return nil unless value - - result = "" - if row.comment - comment = format_comment(row.comment) - result += comment + "\n" if comment - end - - result += "msgctxt \"#{format_key(row.key.dup)}\"\n" - result += "msgid \"#{format_value(row.translations[@default_lang])}\"\n" - result += "msgstr \"#{format_value(value)}\"\n" + super end - def format_comment(comment) - "#. \"#{escape_quotes(comment)}\"" + def format_comment(row, lang) + "#. \"#{escape_quotes(row.comment)}\"\n" if row.comment + end + + def format_key(row, lang) + "msgctxt \"#{row.key.dup}\"\n" + end + + def format_base_translation(row, lang) + "msgid \"#{row.translations[@default_lang]}\"\n" + end + + def format_value(row, lang) + "msgstr \"#{row.translated_string_for_lang(lang)}\"\n" end end end diff --git a/lib/twine/formatters/tizen.rb b/lib/twine/formatters/tizen.rb index 082f8ed..9453c8c 100644 --- a/lib/twine/formatters/tizen.rb +++ b/lib/twine/formatters/tizen.rb @@ -127,8 +127,8 @@ module Twine "\t" end - def format_comment(comment) - "\t" + def format_comment(row, lang) + "\t\n" if row.comment end def key_value_pattern