diff --git a/src/OrchardCoreContrib.PoExtractor.DotNet.CS/SingularStringExtractor.cs b/src/OrchardCoreContrib.PoExtractor.DotNet.CS/SingularStringExtractor.cs index 1653d3c..43e1432 100644 --- a/src/OrchardCoreContrib.PoExtractor.DotNet.CS/SingularStringExtractor.cs +++ b/src/OrchardCoreContrib.PoExtractor.DotNet.CS/SingularStringExtractor.cs @@ -33,13 +33,37 @@ accessor.Expression is IdentifierNameSyntax identifierName && { var argument = accessor.ArgumentList.Arguments.FirstOrDefault(); - if (argument != null && argument.Expression is LiteralExpressionSyntax literal && literal.IsKind(SyntaxKind.StringLiteralExpression)) + if (argument != null && TryGetString(argument.Expression, out var value)) { - result = CreateLocalizedString(literal.Token.ValueText, null, node); + result = CreateLocalizedString(value, null, node); return true; } } return false; } + + private static bool TryGetString(ExpressionSyntax expression, out string value) + { + if (expression is LiteralExpressionSyntax literal && literal.IsKind(SyntaxKind.StringLiteralExpression)) + { + value = literal.Token.ValueText; + + return true; + } + + if (expression is BinaryExpressionSyntax binary && + binary.IsKind(SyntaxKind.AddExpression) && + TryGetString(binary.Left, out var left) && + TryGetString(binary.Right, out var right)) + { + value = left + right; + + return true; + } + + value = null; + + return false; + } } diff --git a/test/OrchardCoreContrib.PoExtractor.DotNet.CS.Tests/SingularStringExtractorTests.cs b/test/OrchardCoreContrib.PoExtractor.DotNet.CS.Tests/SingularStringExtractorTests.cs index 272a1d7..873f17d 100644 --- a/test/OrchardCoreContrib.PoExtractor.DotNet.CS.Tests/SingularStringExtractorTests.cs +++ b/test/OrchardCoreContrib.PoExtractor.DotNet.CS.Tests/SingularStringExtractorTests.cs @@ -5,16 +5,33 @@ namespace OrchardCoreContrib.PoExtractor.DotNet.CS.Tests; public class SingularStringExtractorTests { - [Fact] - public void ExtractString() + [Theory] + [InlineData("""S["Thing"];""", "Thing")] + [InlineData( + """ + S[@"This is a multi-line + string."]; + """, + """ + This is a multi-line + string. + """)] + [InlineData("""S["my " + "text"];""", "my text")] + [InlineData("""S["a " + "long " + "text"];""", "a long text")] + [InlineData( + """ + S["This is a long piece of text " + + "continued on another line."]; + """, + "This is a long piece of text continued on another line.")] + public void ExtractString(string source, string expected) { // Arrange - var text = "Thing"; var metadataProvider = new CSharpMetadataProvider("DummyBasePath"); var extractor = new SingularStringExtractor(metadataProvider); - var syntaxTree = CSharpSyntaxTree.ParseText($"S[\"{text}\"];", path: "DummyPath"); - + var syntaxTree = CSharpSyntaxTree.ParseText(source, path: "DummyPath"); + var node = syntaxTree .GetRoot() .DescendantNodes() @@ -25,6 +42,6 @@ public void ExtractString() // Assert Assert.True(extracted); - Assert.Equal(text, result.Text); + Assert.Equal(expected, result.Text); } -} \ No newline at end of file +}