From b5cd295e3a82ddcb5fb4e6540805815d5ac2e686 Mon Sep 17 00:00:00 2001 From: Sebastian Ludwig Date: Tue, 12 Dec 2017 15:26:38 +0100 Subject: Escape angle brackets in Android formatter, if the string contains a placeholder to enable users to use the official way to retrieve these strings. Improves #212. --- CHANGELOG.md | 4 ++++ README.md | 7 ++++++- lib/twine/formatters/android.rb | 9 +++++++-- lib/twine/placeholders.rb | 14 ++++++++------ test/test_formatters.rb | 11 ++++++++--- 5 files changed, 33 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5b445b..a29a8bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# next version + +- Improvement: Better support for placeholders in HTML styled Android strings (#212) + # 1.0.1 (2017-10-17) - Bugfix: Always prefer the passed-in formatter (#221) diff --git a/README.md b/README.md index 8618a69..1e97111 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,12 @@ Twine currently supports the following output formats: * [iOS and OS X String Resources][applestrings] (format: apple) * [Android String Resources][androidstrings] (format: android) - * Supports [basic styling][androidstyling] with \, \, \ and \ links. These tags will *not* be escaped. Use [`getText()`](https://developer.android.com/reference/android/content/res/Resources.html#getText(int)) to read these strings. Also tags inside ``, ``, `` and `` links. + * These tags will *not* be escaped, if the string doesn't contain placeholders so you can reference them directly in your layouts or use [`getText()`](https://developer.android.com/reference/android/content/res/Resources.html#getText(int)) to read them programatically. + * These tags *will* be escaped, if the string contains placeholders. You can use [`getString()`](https://developer.android.com/reference/android/content/res/Resources.html#getString(int,%20java.lang.Object...)) combined with [`fromHtml`](https://developer.android.com/reference/android/text/Html.html#fromHtml(java.lang.String)) as shown in the [documentation][androidstyling] to display them. + * See [\#212](https://github.com/scelis/twine/issues/212) for details. * [Gettext PO Files][gettextpo] (format: gettext) * [jquery-localize Language Files][jquerylocalize] (format: jquery) * [Django PO Files][djangopo] (format: django) diff --git a/lib/twine/formatters/android.rb b/lib/twine/formatters/android.rb index ced90b7..55c735c 100644 --- a/lib/twine/formatters/android.rb +++ b/lib/twine/formatters/android.rb @@ -116,10 +116,15 @@ module Twine value = gsub_unless(value, "'", "\\'") { |substring| substring =~ inside_cdata } value = gsub_unless(value, /&/, '&') { |substring| substring =~ inside_cdata || substring =~ inside_opening_anchor_tag } - # escape opening angle brackes unless it's a supported styling tag + # if `value` contains a placeholder, escape all angle brackets + # if not, escape opening angle brackes unless it's a supported styling tag # https://github.com/scelis/twine/issues/212 # https://stackoverflow.com/questions/3235131/#18199543 - angle_bracket = /<(?!(\/?(b|u|i|a|\!\[CDATA)))/ # matches all `<` but , , , and 0 + angle_bracket = /<(?!(\/?(\!\[CDATA)))/ # matches all `<` but , , , and %s @@ -19,15 +24,13 @@ module Twine # %@ -> %s value = convert_twine_string_placeholder(input) - placeholder_syntax = PLACEHOLDER_PARAMETER_FLAGS_WIDTH_PRECISION_LENGTH + PLACEHOLDER_TYPES - placeholder_regex = /%#{placeholder_syntax}/ - - number_of_placeholders = value.scan(placeholder_regex).size + number_of_placeholders = number_of_twine_placeholders(input) return value if number_of_placeholders == 0 # got placeholders -> need to double single percent signs # % -> %% (but %% -> %%, %d -> %d) + placeholder_syntax = PLACEHOLDER_PARAMETER_FLAGS_WIDTH_PRECISION_LENGTH + PLACEHOLDER_TYPES single_percent_regex = /([^%])(%)(?!(%|#{placeholder_syntax}))/ value.gsub! single_percent_regex, '\1%%' @@ -61,8 +64,7 @@ module Twine 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| + value.gsub(PLACEHOLDER_REGEX).each_with_index do |match, index| "{#{index}}" end end diff --git a/test/test_formatters.rb b/test/test_formatters.rb index 87658b7..51d3c51 100644 --- a/test/test_formatters.rb +++ b/test/test_formatters.rb @@ -50,6 +50,10 @@ class TestAndroidFormatter < FormatterTest 'italic' => 'italic', 'underline' => 'underline', + '%@' => '<b>%s</b>', + '%@' => '<i>%s</i>', + '%@' => '<u>%s</u>', + 'inline' => '<span>inline</span>', '

paragraph

' => '<p>paragraph</p>', @@ -58,9 +62,10 @@ class TestAndroidFormatter < FormatterTest '
"out"' => '\"out\"', 'link' => 'link', - '

escaped

' => '<p>escaped</p>', - '

escaped

' => '<p>escaped</p>', - 'unescaped

]]>' => 'unescaped

]]>', + '

escaped

' => '<p>escaped</p>', + '

escaped

' => '<p>escaped</p>', + 'unescaped

]]>' => 'unescaped

]]>', + 'unescaped with %@

]]>' => 'unescaped with %s

]]>', 'unescaped

]]>' => 'unescaped

]]>', '' => '', -- cgit v1.2.3