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