Fixed #169 by adding proper placeholder handling to Flash formatter.

This commit is contained in:
Sebastian Ludwig 2016-11-22 22:26:24 +01:00
parent 74d7cb1d85
commit 280914bdc5
5 changed files with 75 additions and 17 deletions

View file

@ -35,7 +35,7 @@ Twine supports [`printf` style placeholders][printf] with one peculiarity: `@` i
Tags are used by Twine as a way to only work with a subset of your definitions at any given point in time. Each definition can be assigned zero or more tags which are separated by commas. Tags are optional, though highly recommended. You can get a list of all definitions currently missing tags by executing the [`validate-twine-file`](#validate-twine-file) command with the `--pedantic` option.
When generating a localization file, you can specify which definitions should be included using the `--tags` option. Provide a comma separated list of tags to match all definitions that contain any of the tags (`--tags tag1,tag2` matches all definitions tagged with `tag1` _or_ `tag2`). Provide multiple `--tags` options to match defintions containing all specified tags (`--tags tag1 --tags tag2` matches all definitions tagged with `tag1` _and_ `tag2`). You can match definitions _not_ containing a tag by prefixing the tag with a tilde (`--tags ~tag1` matches all definitions _not_ tagged with `tag1`.). All three options are combinable.
When generating a localization file, you can specify which definitions should be included using the `--tags` option. Provide a comma separated list of tags to match all definitions that contain any of the tags (`--tags tag1,tag2` matches all definitions tagged with `tag1` _or_ `tag2`). Provide multiple `--tags` options to match defintions containing all specified tags (`--tags tag1 --tags tag2` matches all definitions tagged with `tag1` _and_ `tag2`). You can match definitions _not_ containing a tag by prefixing the tag with a tilde (`--tags ~tag1` matches all definitions _not_ tagged with `tag1`). All three options are combinable.
### Whitespace
@ -93,6 +93,7 @@ Twine currently supports the following output formats:
* [jquery-localize Language Files][jquerylocalize] (format: jquery)
* [Django PO Files][djangopo] (format: django)
* [Tizen String Resources][tizen] (format: tizen)
* [Flash/Flex Properties][flash] (format: flash)
If you would like to enable Twine to create localization files in another format, read the wiki page on how to create an appropriate formatter.
@ -227,4 +228,5 @@ Many thanks to all of the contributors to the Twine project, including:
[jquerylocalize]: https://github.com/coderifous/jquery-localize
[djangopo]: https://docs.djangoproject.com/en/dev/topics/i18n/translation/
[tizen]: https://developer.tizen.org/documentation/articles/localization
[flash]: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/resources/IResourceManager.html#getString()
[printf]: https://en.wikipedia.org/wiki/Printf_format_string

View file

@ -1,6 +1,8 @@
module Twine
module Formatters
class Flash < Abstract
include Twine::Placeholders
def format_name
'flash'
end
@ -21,6 +23,11 @@ module Twine
return
end
def set_translation_for_key(key, lang, value)
value = convert_placeholders_from_flash_to_twine(value)
super(key, lang, value)
end
def read(io, lang)
last_comment = nil
while line = io.gets
@ -28,19 +35,13 @@ module Twine
if match
key = match[1]
value = match[2].strip
value.gsub!(/\{[0-9]\}/, '%@')
set_translation_for_key(key, lang, value)
if last_comment
set_comment_for_key(key, last_comment)
end
set_comment_for_key(key, last_comment) if last_comment
end
match = /# *(.*)/.match(line)
if match
last_comment = match[1]
else
last_comment = nil
end
last_comment = match ? match[1] : nil
end
end
@ -65,8 +66,7 @@ module Twine
end
def format_value(value)
placeHolderNumber = -1
value.gsub(/%[d@]/) { placeHolderNumber += 1; '{%d}' % placeHolderNumber }
convert_placeholders_from_twine_to_flash(value)
end
end
end

View file

@ -5,17 +5,21 @@ module Twine
# Note: the ` ` (single space) flag is NOT supported
PLACEHOLDER_FLAGS_WIDTH_PRECISION_LENGTH = '([-+0#])?(\d+|\*)?(\.(\d+|\*))?(hh?|ll?|L|z|j|t)?'
PLACEHOLDER_PARAMETER_FLAGS_WIDTH_PRECISION_LENGTH = '(\d+\$)?' + PLACEHOLDER_FLAGS_WIDTH_PRECISION_LENGTH
PLACEHOLDER_TYPES = '[diufFeEgGxXoscpaA]'
def convert_twine_string_placeholder(input)
# %@ -> %s
input.gsub(/(%#{PLACEHOLDER_PARAMETER_FLAGS_WIDTH_PRECISION_LENGTH})@/, '\1s')
end
# http://developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling
# http://stackoverflow.com/questions/4414389/android-xml-percent-symbol
# https://github.com/mobiata/twine/pull/106
def convert_placeholders_from_twine_to_android(input)
placeholder_types = '[diufFeEgGxXoscpaA]'
# %@ -> %s
value = input.gsub(/(%#{PLACEHOLDER_PARAMETER_FLAGS_WIDTH_PRECISION_LENGTH})@/, '\1s')
value = convert_twine_string_placeholder(input)
placeholder_syntax = PLACEHOLDER_PARAMETER_FLAGS_WIDTH_PRECISION_LENGTH + placeholder_types
placeholder_syntax = PLACEHOLDER_PARAMETER_FLAGS_WIDTH_PRECISION_LENGTH + PLACEHOLDER_TYPES
placeholder_regex = /%#{placeholder_syntax}/
number_of_placeholders = value.scan(placeholder_regex).size
@ -30,7 +34,7 @@ module Twine
return value if number_of_placeholders < 2
# number placeholders
non_numbered_placeholder_regex = /%(#{PLACEHOLDER_FLAGS_WIDTH_PRECISION_LENGTH}#{placeholder_types})/
non_numbered_placeholder_regex = /%(#{PLACEHOLDER_FLAGS_WIDTH_PRECISION_LENGTH}#{PLACEHOLDER_TYPES})/
number_of_non_numbered_placeholders = value.scan(non_numbered_placeholder_regex).size
@ -51,5 +55,20 @@ module Twine
# %s -> %@
input.gsub(placeholder_regex, '\1@')
end
# http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/resources/IResourceManager.html#getString()
# http://soenkerohde.com/2008/07/flex-localization/comment-page-1/
def convert_placeholders_from_twine_to_flash(input)
value = convert_twine_string_placeholder(input)
placeholder_regex = /%#{PLACEHOLDER_PARAMETER_FLAGS_WIDTH_PRECISION_LENGTH}#{PLACEHOLDER_TYPES}/
value.gsub(placeholder_regex).each_with_index do |match, index|
"{#{index}}"
end
end
def convert_placeholders_from_flash_to_twine(input)
input.gsub /\{\d+\}/, '%@'
end
end
end

View file

@ -338,9 +338,18 @@ class TestFlashFormatter < FormatterTest
assert_file_contents_read_correctly
end
def test_set_translation_converts_placeholders
@formatter.set_translation_for_key 'key1', 'en', "value {#{rand(10)}}"
assert_equal 'value %@', @empty_twine_file.definitions_by_key['key1'].translations['en']
end
def test_format_file
formatter = Twine::Formatters::Flash.new
formatter.twine_file = @twine_file
assert_equal content('formatter_flash.properties'), formatter.format_file('en')
end
def test_format_value_converts_placeholders
assert_equal "value {0}", @formatter.format_value('value %d')
end
end

View file

@ -86,4 +86,32 @@ class PlaceholderTest < TwineTest
assert_equal "some %@ value", from_android("some %s value")
end
end
class ToFlash < PlaceholderTest
def to_flash(value)
Twine::Placeholders.convert_placeholders_from_twine_to_flash(value)
end
def test_replaces_placeholder
assert_equal "some {0} text", to_flash("some #{placeholder} text")
end
def test_replaces_string_placeholder
assert_equal "some {0} text", to_flash("some #{placeholder('@')} text")
end
def test_numbers_placeholders
assert_equal "some {0} more {1} text {2}", to_flash("some #{placeholder('@')} more #{placeholder('@')} text #{placeholder('@')}")
end
end
class FromFlash < PlaceholderTest
def from_flash(value)
Twine::Placeholders.convert_placeholders_from_flash_to_twine(value)
end
def test_maps_all_placeholders_to_string
assert_equal "some %@ more %@ text %@", from_flash("some {0} more {1} text {2}")
end
end
end