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:
authorSebastian Ludwig <sebastian@lurado.de>2017-09-12 18:35:12 +0300
committerSebastian Ludwig <sebastian@lurado.de>2017-09-18 13:26:07 +0300
commitf7092c7605279de76177341a51199f19d9b7ed6b (patch)
tree755a81586928487d06bd4a8c764c98e2ffa7e212
parent9dc3845cae85d17f349bf47beafdbc152c1af53d (diff)
Close #212: Change Android escaping to preserve basic styling tags and anything inside CDATA.
-rw-r--r--README.md4
-rw-r--r--lib/twine/formatters/android.rb26
-rw-r--r--test/test_formatters.rb23
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 \<b\>, \<i\>, \<u\> and \<a\> 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 `<![CDATA[` won't be escaped. 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)
@@ -212,9 +213,10 @@ Many thanks to all of the contributors to the Twine project, including:
[INI]: http://en.wikipedia.org/wiki/INI_file
[applestrings]: http://developer.apple.com/documentation/Cocoa/Conceptual/LoadingResources/Strings/Strings.html
[androidstrings]: http://developer.android.com/guide/topics/resources/string-resource.html
+[androidstyling]: http://developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling
[gettextpo]: http://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/PO-Files.html
[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
+[printf]: https://en.wikipedia.org/wiki/Printf_format_string \ No newline at end of file
diff --git a/lib/twine/formatters/android.rb b/lib/twine/formatters/android.rb
index b9dba3e..ced90b7 100644
--- a/lib/twine/formatters/android.rb
+++ b/lib/twine/formatters/android.rb
@@ -99,12 +99,28 @@ module Twine
"\t<string name=\"%{key}\">%{value}</string>"
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!(/&/, '&amp;')
- value.gsub!('<', '&lt;')
+ inside_cdata = /<\!\[CDATA\[((?!\]\]>).)*$/ # opening CDATA tag ('<![CDATA[') not followed by a closing tag (']]>')
+ inside_opening_anchor_tag = /<a\s?((?!>).)*$/ # anchor tag start ('<a ') not followed by a '>'
+
+ # 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, /&/, '&amp;') { |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 <b>, <u>, <i>, <a> and <![CDATA
+ value = gsub_unless(value, angle_bracket, '&lt;') { |substring| substring =~ inside_cdata }
# escape non resource identifier @ signs (http://developer.android.com/guide/topics/resources/accessing-resources.html#ResourcesFromXml)
resource_identifier_regex = /@(?!([a-z\.]+:)?[a-z+]+\/[a-zA-Z_]+)/ # @[<package_name>:]<resource_type>/<resource_name>
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 &lt; that',
"it's complicated" => "it\\'s complicated",
'a "good" way' => 'a \"good\" way',
- '<b>bold</b>' => '&lt;b>bold&lt;/b>',
- '<a href="target">link</a>' => '&lt;a href=\"target\">link&lt;/a>',
+
+ '<b>bold</b>' => '<b>bold</b>',
+ '<i>italic</i>' => '<i>italic</i>',
+ '<u>underline</u>' => '<u>underline</u>',
+
+ '<span>inline</span>' => '&lt;span>inline&lt;/span>',
+ '<p>paragraph</p>' => '&lt;p>paragraph&lt;/p>',
+
+ '<a href="target">link</a>' => '<a href="target">link</a>',
+ '<a href="target">"link"</a>' => '<a href="target">\"link\"</a>',
+ '<a href="target"></a>"out"' => '<a href="target"></a>\"out\"',
+ '<a href="http://url.com?param=1&param2=3&param3=%20">link</a>' => '<a href="http://url.com?param=1&param2=3&param3=%20">link</a>',
+
+ '<p>escaped</p><![CDATA[]]>' => '&lt;p>escaped&lt;/p><![CDATA[]]>',
+ '<![CDATA[]]><p>escaped</p>' => '<![CDATA[]]>&lt;p>escaped&lt;/p>',
+ '<![CDATA[<p>unescaped</p>]]>' => '<![CDATA[<p>unescaped</p>]]>',
+ '<![CDATA[]]><![CDATA[<p>unescaped</p>]]>' => '<![CDATA[]]><![CDATA[<p>unescaped</p>]]>',
+
+ '<![CDATA[&]]>' => '<![CDATA[&]]>',
+ '<![CDATA[\']]>' => '<![CDATA[\']]>',
+ '<![CDATA["]]>' => '<![CDATA["]]>',
'<xliff:g></xliff:g>' => '<xliff:g></xliff:g>',
'<xliff:g>untouched</xliff:g>' => '<xliff:g>untouched</xliff:g>',