From f7092c7605279de76177341a51199f19d9b7ed6b Mon Sep 17 00:00:00 2001
From: Sebastian Ludwig
Date: Tue, 12 Sep 2017 17:35:12 +0200
Subject: Close #212: Change Android escaping to preserve basic styling tags
and anything inside CDATA.
---
README.md | 4 +++-
lib/twine/formatters/android.rb | 26 +++++++++++++++++++++-----
test/test_formatters.rb | 23 +++++++++++++++++++++--
3 files changed, 45 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index a11bb49..8618a69 100644
--- a/README.md
+++ b/README.md
@@ -78,6 +78,7 @@ 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 `%{value}"
end
+ def gsub_unless(text, pattern, replacement)
+ text.gsub(pattern) do |match|
+ match_start_position = Regexp.last_match.offset(0)[0]
+ yield(text[0, match_start_position]) ? match : replacement
+ end
+ end
+
+ # http://developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling
def escape_value(value)
- # escape double and single quotes, & signs and tags
- value = escape_quotes(value)
- value.gsub!("'", "\\\\'")
- value.gsub!(/&/, '&')
- value.gsub!('<', '<')
+ inside_cdata = /<\!\[CDATA\[((?!\]\]>).)*$/ # opening CDATA tag ('')
+ inside_opening_anchor_tag = /).)*$/ # anchor tag start (''
+
+ # escape double and single quotes and & signs
+ value = gsub_unless(value, '"', '\\"') { |substring| substring =~ inside_cdata || substring =~ inside_opening_anchor_tag }
+ 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
+ # https://github.com/scelis/twine/issues/212
+ # https://stackoverflow.com/questions/3235131/#18199543
+ angle_bracket = /<(?!(\/?(b|u|i|a|\!\[CDATA)))/ # matches all `<` but , , , and :]/
diff --git a/test/test_formatters.rb b/test/test_formatters.rb
index a63b0a5..ae30787 100644
--- a/test/test_formatters.rb
+++ b/test/test_formatters.rb
@@ -45,8 +45,27 @@ class TestAndroidFormatter < FormatterTest
'this < that' => 'this < that',
"it's complicated" => "it\\'s complicated",
'a "good" way' => 'a \"good\" way',
- 'bold' => '<b>bold</b>',
- 'link' => '<a href=\"target\">link</a>',
+
+ 'bold' => 'bold',
+ 'italic' => 'italic',
+ 'underline' => 'underline',
+
+ 'inline' => '<span>inline</span>',
+ 'paragraph
' => '<p>paragraph</p>',
+
+ 'link' => 'link',
+ '"link"' => '\"link\"',
+ '"out"' => '\"out\"',
+ 'link' => 'link',
+
+ 'escaped
' => '<p>escaped</p>',
+ 'escaped
' => '<p>escaped</p>',
+ 'unescaped
]]>' => 'unescaped]]>',
+ 'unescaped]]>' => 'unescaped]]>',
+
+ '' => '',
+ '' => '',
+ '' => '',
'' => '',
'untouched' => 'untouched',
--
cgit v1.2.3