Skip to content

Commit d3d5057

Browse files
Fixed issues with escaped strings inside the phrase (#180)
1 parent e8192a7 commit d3d5057

File tree

4 files changed

+113
-19
lines changed

4 files changed

+113
-19
lines changed

MN.L10n.BuildTasks/MN.L10n.BuildTasks.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<OutputType>Exe</OutputType>
77
<StartupObject>MN.L10n.BuildTasks.Program</StartupObject>
88
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
9-
<Version>4.0.1</Version>
9+
<Version>4.0.4</Version>
1010
<Authors>Chris Gårdenberg</Authors>
1111
<Company>MultiNet Interactive AB</Company>
1212
</PropertyGroup>

MN.L10n.Tests/ParserTests.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,5 +115,56 @@ public void LineBreakCharInCall()
115115

116116
Assert.Collection(result, x => Assert.Equal("Hello\nBrother", x.Phrase));
117117
}
118+
119+
[Fact]
120+
public void TestEscapedStringContainerCharacter()
121+
{
122+
var parser = new L10nParser();
123+
var result = parser.Parse(@"_s(""Hello \""friend\"". How it do?"")");
124+
125+
Assert.Collection(result, x => Assert.Equal(@"Hello ""friend"". How it do?", x.Phrase));
126+
}
127+
128+
[Fact]
129+
public void TestEscapedStringContainerCharacter2()
130+
{
131+
var parser = new L10nParser();
132+
var result = parser.Parse(@"_s('Hello \""friend\"". How it do?')");
133+
134+
Assert.Collection(result, x => Assert.Equal(@"Hello \""friend\"". How it do?", x.Phrase));
135+
}
136+
137+
[Fact]
138+
public void TestEscapedStringContainerCharacter3()
139+
{
140+
var parser = new L10nParser();
141+
var result = parser.Parse(@"_s('Hello \'friend\'. How it do?')");
142+
143+
Assert.Collection(result, x => Assert.Equal(@"Hello 'friend'. How it do?", x.Phrase));
144+
}
145+
146+
[Fact]
147+
public void TestEscapedStringContainerCharacterFirstChar()
148+
{
149+
var parser = new L10nParser();
150+
var result = parser.Parse(@"_s(""\""friend\""!"")");
151+
152+
Assert.Collection(result, x => Assert.Equal(@"""friend""!", x.Phrase));
153+
}
154+
155+
[Fact]
156+
public void TestEscapedStringContainerCharacterVerbatim()
157+
{
158+
var src = @"<a href=javascript:void(0)>
159+
_s(
160+
@""Hej """"bror""""
161+
Nej""
162+
)
163+
</a>";
164+
var parser = new L10nParser();
165+
var result = parser.Parse(src).ToList();
166+
Assert.Single(result);
167+
Assert.Equal(@"Hej ""bror""\nNej", result[0].Phrase.Trim());
168+
}
118169
}
119170
}

MN.L10n/L10nParser.cs

Lines changed: 59 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ bool TryPeek(int forward)
8686
{
8787
break;
8888
}
89+
8990
isVerbatim = true;
9091
}
9192
else
@@ -115,6 +116,7 @@ bool TryPeek(int forward)
115116
continue;
116117
}
117118
}
119+
118120
if (inToken)
119121
{
120122
_tokenContent.Append(source[_pos]);
@@ -143,57 +145,98 @@ bool TryPeek(int forward)
143145
phrase = phrase.Substring(0, phrase.Length - 1);
144146
}
145147

146-
yield return new PhraseInvocation
148+
yield return Unescape(new PhraseInvocation
147149
{
148150
Phrase = phrase,
149151
Row = row,
150152
StartChar = startChar,
151153
EndChar = _pos,
152154
IsEscaped = isEscaped,
153155
StringContainer = _stringContainer
154-
};
156+
}, isVerbatim);
155157
inToken = false;
156158
}
157159
}
158160
else
159161
{
160162
var _tail = source[_pos - 1];
161163
var _peek = source[_pos + 1];
162-
if (source[_pos] == _stringContainer && _peek != _stringContainer && _tail != _stringContainer)
164+
if (source[_pos] == _stringContainer && _peek != _stringContainer &&
165+
_tail != _stringContainer)
163166
{
164-
var phrase = _tokenContent.ToString().Replace("\n", "\\n").Replace("\r", "").Replace("\"\"", "\\\"");
167+
var phrase = _tokenContent.ToString().Replace("\n", "\\n").Replace("\r", "")
168+
.Replace("\"\"", "\\\"");
165169

166170
// Hoppa över sista \ om den är escape:ad
167171
if (isEscaped)
168172
{
169173
phrase = phrase.Substring(0, phrase.Length - 1);
170174
}
171175

172-
yield return new PhraseInvocation
176+
yield return Unescape(new PhraseInvocation
173177
{
174178
Phrase = phrase,
175179
Row = row,
176180
StartChar = startChar,
177181
EndChar = _pos,
178182
StringContainer = _stringContainer
179-
};
183+
}, isVerbatim);
180184
inToken = false;
181185
}
182186
}
183-
184-
if (inToken && !isVerbatim && source[_pos] == '\\' && TryPeek(1) && source[_pos + 1] == 'n')
185-
{
186-
_pos++;
187-
_tokenContent.Append('\n');
188-
}
189-
else
190-
{
191-
_tokenContent.Append(source[_pos]);
192-
}
187+
_tokenContent.Append(source[_pos]);
193188
}
189+
194190
break;
195191
}
196192
}
197193
}
194+
195+
private PhraseInvocation Unescape(PhraseInvocation phraseInvocation, bool isVerbatim)
196+
{
197+
if (isVerbatim)
198+
{
199+
for (var i = 0; i < phraseInvocation.Phrase.Length; i++)
200+
{
201+
if (phraseInvocation.Phrase[i] == '\\' && i + 1 < phraseInvocation.Phrase.Length)
202+
{
203+
if (phraseInvocation.Phrase[i + 1] == phraseInvocation.StringContainer)
204+
{
205+
phraseInvocation.Phrase = phraseInvocation.Phrase.Remove(i, 1);
206+
}
207+
}
208+
}
209+
}
210+
else
211+
{
212+
for (var i = 0; i < phraseInvocation.Phrase.Length; i++)
213+
{
214+
if (phraseInvocation.Phrase[i] == '\\' && i + 1 < phraseInvocation.Phrase.Length)
215+
{
216+
switch (phraseInvocation.Phrase[i + 1])
217+
{
218+
case 'n':
219+
phraseInvocation.Phrase = phraseInvocation.Phrase.Remove(i, 2).Insert(i, "\n");
220+
break;
221+
case 't':
222+
phraseInvocation.Phrase = phraseInvocation.Phrase.Remove(i, 2).Insert(i, "\t");
223+
break;
224+
case '\\':
225+
phraseInvocation.Phrase = phraseInvocation.Phrase.Remove(i, 2).Insert(i, "\\");
226+
break;
227+
default:
228+
if (phraseInvocation.Phrase[i + 1] == phraseInvocation.StringContainer)
229+
{
230+
phraseInvocation.Phrase = phraseInvocation.Phrase.Remove(i, 1);
231+
}
232+
233+
break;
234+
}
235+
}
236+
}
237+
}
238+
239+
return phraseInvocation;
240+
}
198241
}
199242
}

MN.L10n/MN.L10n.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ Translation package</Description>
1212
<PackageProjectUrl>https://github.com/MultinetInteractive/MN.L10n</PackageProjectUrl>
1313
<RepositoryType>git</RepositoryType>
1414
<Copyright>© 20XX MultiNet Interactive AB</Copyright>
15-
<Version>4.1.1</Version>
15+
<Version>4.1.3</Version>
1616
<LangVersion>latest</LangVersion>
1717
<AutoIncrementPackageRevision>True</AutoIncrementPackageRevision>
1818
<PackageReleaseNotes>Now includes analyzer</PackageReleaseNotes>
1919
<ApplicationIcon />
2020
<OutputType>Library</OutputType>
2121
<StartupObject></StartupObject>
22-
<AssemblyVersion>4.1.1</AssemblyVersion>
22+
<AssemblyVersion>4.1.3</AssemblyVersion>
2323
</PropertyGroup>
2424

2525
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

0 commit comments

Comments
 (0)